From 1ad7e497213140fff45b264282715d626357cbde Mon Sep 17 00:00:00 2001 From: zhaoxingyu Date: Tue, 18 Jun 2024 20:53:08 +0800 Subject: [PATCH] Update GR551x SDK to v2.0.2 Signed-off-by: zhaoxingyu --- BUILD.gn | 2 +- gr551x/BUILD.gn | 34 +- .../iot_hardware/wifiiot_lite/hal_iot_gpio.c | 12 +- .../iot_hardware/wifiiot_lite/hal_iot_i2c.c | 168 +- .../iot_hardware/wifiiot_lite/hal_iot_pwm.c | 117 +- .../iot_hardware/wifiiot_lite/hal_iot_uart.c | 44 +- gr551x/components/fs/BUILD.gn | 4 +- gr551x/gr551x_executable.gni | 86 + gr551x/hcs/gpio/gpio_config.hcs | 1 - gr551x/sdk_liteos/BUILD.gn | 10 +- gr551x/sdk_liteos/config/BUILD.gn | 5 +- gr551x/sdk_liteos/config/custom_config.h | 176 +- .../sdk_liteos/config/flash_scatter_config.h | 169 +- gr551x/sdk_liteos/gr551x_sdk/BUILD.gn | 66 +- gr551x/sdk_liteos/gr551x_sdk/README.md | 127 + .../sdk_liteos/gr551x_sdk/components/BUILD.gn | 22 + .../gr55xx/gr55xx_measure_mux_signal_api.c | 140 + .../gr55xx/gr55xx_measure_mux_signal_api.h | 122 + .../drivers_ext/gr55xx/gr55xx_spi_flash.c | 863 + .../drivers_ext/gr55xx/gr55xx_spi_flash.h | 264 + .../drivers_ext/gr55xx/gr55xx_tim_delay.c | 88 + .../drivers_ext/gr55xx/gr55xx_tim_delay.h | 85 + .../components/drivers_ext/st7735/st7735.c | 237 + .../components/drivers_ext/st7735/st7735.h | 117 + .../drivers_ext/st7735/st7735_config.c | 237 + .../drivers_ext/st7735/st7735_config.h | 71 + .../gr551x_sdk/components/libraries/BUILD.gn | 51 + .../libraries/CMSIS/cmsis_dsp/BUILD.gn | 23 + .../Lib/GCC/libarm_cortexM4lf_math.a | Bin 0 -> 6421864 bytes .../cmsis_dsp/include/arm_common_tables.h | 517 + .../cmsis_dsp/include/arm_const_structs.h | 76 + .../CMSIS/cmsis_dsp/include/arm_math.h | 8970 ++++++ .../CMSIS/cmsis_dsp/include/arm_mve_tables.h | 235 + .../CMSIS/cmsis_dsp/include/arm_vec_math.h | 372 + .../components/libraries/app_alarm/BUILD.gn | 22 + .../libraries/app_alarm/app_alarm.c | 726 + .../libraries/app_alarm/app_alarm.h | 206 + .../components/libraries/app_assert/BUILD.gn | 22 + .../libraries/app_assert/app_assert.c | 73 +- .../libraries/app_assert/app_assert.h | 11 +- .../components/libraries/app_error/BUILD.gn | 25 + .../libraries/app_error/app_error.c | 68 +- .../libraries/app_error/app_error.h | 40 +- .../libraries/app_error/app_error_cfg.h | 20 +- .../libraries/app_error/cortex_backtrace.c | 1086 +- .../libraries/app_error/cortex_backtrace.h | 327 +- .../hardfault_handler/cortex_hardfault_gcc.s | 28 + .../hardfault_handler/cortex_hardfault_iar.s | 0 .../hardfault_handler/cortex_hardfault_keil.s | 0 .../components/libraries/app_key/BUILD.gn | 25 + .../components/libraries/app_key/app_key.c | 237 + .../components/libraries/app_key/app_key.h | 95 + .../libraries/app_key/app_key_core.c | 319 + .../libraries/app_key/app_key_core.h | 146 + .../libraries/app_linked_list/BUILD.gn | 22 + .../app_linked_list/app_linked_list.c | 254 + .../app_linked_list/app_linked_list.h | 136 + .../components/libraries/app_log/BUILD.gn | 26 + .../components/libraries/app_log/app_log.c | 367 +- .../components/libraries/app_log/app_log.h | 85 +- .../libraries/app_log/app_log_dump_port.c | 231 + .../libraries/app_log/app_log_dump_port.h | 58 + .../libraries/app_log/app_log_store.c | 383 +- .../libraries/app_log/app_log_store.h | 50 +- .../components/libraries/app_memory/BUILD.gn | 22 + .../libraries/app_memory/app_memory.c | 267 + .../libraries/app_memory/app_memory.h | 128 + .../components/libraries/app_queue/BUILD.gn | 22 + .../libraries/app_queue/app_queue.c | 277 + .../libraries/app_queue/app_queue.h | 208 + .../libraries/app_scheduler/BUILD.gn | 22 + .../libraries/app_scheduler/app_scheduler.c | 178 + .../libraries/app_scheduler/app_scheduler.h | 104 + .../components/libraries/app_timer/BUILD.gn | 22 + .../libraries/app_timer/app_timer.c | 936 +- .../libraries/app_timer/app_timer.h | 121 +- .../components/libraries/at_cmd/BUILD.gn | 25 + .../components/libraries/at_cmd/at_cmd.c | 366 + .../components/libraries/at_cmd/at_cmd.h | 247 + .../libraries/at_cmd/at_cmd_utils.c | 157 + .../libraries/at_cmd/at_cmd_utils.h | 128 + .../libraries/ble/ble_advertising/BUILD.gn | 22 + .../ble/ble_advertising/ble_advertising.c | 512 + .../ble/ble_advertising/ble_advertising.h | 192 + .../libraries/ble/ble_connect/BUILD.gn | 22 + .../libraries/ble/ble_connect/ble_connect.c | 610 + .../libraries/ble/ble_connect/ble_connect.h | 289 + .../libraries/ble/ble_gatt_service/BUILD.gn | 22 + .../ble/ble_gatt_service/ble_gatt_service.c | 675 + .../ble/ble_gatt_service/ble_gatt_service.h | 252 + .../libraries/ble/ble_scanner/BUILD.gn | 22 + .../libraries/ble/ble_scanner/ble_scanner.c | 518 + .../libraries/ble/ble_scanner/ble_scanner.h | 331 + .../libraries/ble/ble_time/BUILD.gn | 22 + .../libraries/ble/ble_time/ble_time.c | 68 + .../libraries/ble/ble_time/ble_time.h | 35 + .../components/libraries/crypto_lib/BUILD.gn | 32 + .../libraries/crypto_lib/inc/crypto_aes.h | 360 + .../libraries/crypto_lib/inc/crypto_ecc.h | 411 + .../crypto_lib/inc/crypto_ecc_port.h | 93 + .../libraries/crypto_lib/inc/crypto_gcm.h | 238 + .../libraries/crypto_lib/inc/crypto_pkc.h | 237 + .../crypto_lib/inc/crypto_pkc_port.h | 64 + .../libraries/crypto_lib/inc/crypto_rsa.h | 203 + .../crypto_lib/inc/crypto_rsa_port.h | 131 + .../libraries/crypto_lib/inc/crypto_sha256.h | 297 + .../libraries/crypto_lib/src/crypto_aes.c | 615 + .../libraries/crypto_lib/src/crypto_ecc.c | 651 + .../crypto_lib/src/crypto_ecc_port.c | 192 + .../libraries/crypto_lib/src/crypto_gcm.c | 444 + .../libraries/crypto_lib/src/crypto_pkc.c | 280 + .../crypto_lib/src/crypto_pkc_port.c | 141 + .../libraries/crypto_lib/src/crypto_rsa.c | 901 + .../crypto_lib/src/crypto_rsa_port.c | 146 + .../libraries/crypto_lib/src/crypto_sha256.c | 301 + .../components/libraries/dfu_master/BUILD.gn | 22 + .../libraries/dfu_master/dfu_master.c | 828 + .../libraries/dfu_master/dfu_master.h | 203 + .../components/libraries/dfu_port/BUILD.gn | 22 + .../components/libraries/dfu_port/dfu_port.c | 1179 + .../components/libraries/dfu_port/dfu_port.h | 133 + .../components/libraries/fault_trace/BUILD.gn | 22 + .../libraries/fault_trace/fault_trace.c | 480 + .../libraries/fault_trace/fault_trace.h | 153 + .../components/libraries/fcc/BUILD.gn | 22 + .../components/libraries/fcc/dtm_fcc_test.c | 145 + .../components/libraries/fcc/dtm_fcc_test.h | 27 + .../libraries/fcc/dtm_fcc_test_int.h | 550 + .../components/libraries/gui/font_gb2312.c | 24637 ++++++++++++++++ .../components/libraries/gui/gui_animation.c | 213 + .../components/libraries/gui/gui_animation.h | 91 + .../components/libraries/gui/gui_basic.c | 1289 + .../components/libraries/gui/gui_basic.h | 225 + .../components/libraries/gui/gui_color.c | 99 + .../components/libraries/gui/gui_color.h | 102 + .../libraries/gui/gui_config/gb2312_font.bin | Bin 0 -> 263196 bytes .../libraries/gui/gui_config/gb2312_font.hex | 8231 ++++++ .../gui/gui_config/gui_animation_config.c | 106 + .../libraries/gui/gui_config/gui_config.h | 198 + .../gui/gui_config/gui_gb2312_config.c | 72 + .../libraries/gui/gui_config/gui_lcd_config.c | 102 + .../libraries/gui/gui_config/gui_lcm_cfg.c | 104 + .../libraries/gui/gui_config/gui_lcm_config.c | 83 + .../gui/gui_config/gui_oled_config.c | 82 + .../libraries/gui/gui_convert_color.c | 179 + .../libraries/gui/gui_convert_color.h | 194 + .../components/libraries/gui/gui_font5_7.c | 1163 + .../components/libraries/gui/gui_font5_7.h | 87 + .../components/libraries/gui/gui_font8_8.c | 1162 + .../components/libraries/gui/gui_font8_8.h | 89 + .../libraries/gui/gui_font_gb2312.c | 160 + .../libraries/gui/gui_font_gb2312.h | 59 + .../components/libraries/gui/gui_font_macro.h | 261 + .../components/libraries/gui/gui_font_other.c | 138 + .../components/libraries/gui/gui_font_other.h | 115 + .../components/libraries/gui/gui_include.h | 15 + .../components/libraries/hal_flash/BUILD.gn | 25 + .../hal_flash/hal_exflash_user_operation.c | 155 +- .../hal_flash/hal_exflash_user_operation.h | 5 +- .../libraries/hal_flash/hal_flash.c | 103 +- .../libraries/hal_flash/hal_flash.h | 20 +- .../libraries/hal_flash/vflash/vflash.c | 67 + .../libraries/hal_flash/vflash/vflash.h | 18 + .../components/libraries/hci_uart/BUILD.gn | 22 + .../components/libraries/hci_uart/hci_uart.c | 354 + .../components/libraries/hci_uart/hci_uart.h | 261 + .../libraries/pmu_calibration/BUILD.gn | 22 + .../pmu_calibration/pmu_calibration.c | 223 +- .../pmu_calibration/pmu_calibration.h | 4 +- .../components/libraries/ring_buffer/BUILD.gn | 22 + .../libraries/ring_buffer/ring_buffer.c | 250 +- .../libraries/ring_buffer/ring_buffer.h | 3 +- .../components/libraries/sensorsim/BUILD.gn | 22 + .../libraries/sensorsim/sensorsim.c | 103 + .../libraries/sensorsim/sensorsim.h | 118 + .../components/libraries/user_efuse/BUILD.gn | 22 + .../libraries/user_efuse/user_efuse.c | 125 + .../libraries/user_efuse/user_efuse.h | 89 + .../components/libraries/utility/BUILD.gn | 22 + .../components/libraries/utility/utility.c | 228 +- .../components/libraries/utility/utility.h | 85 +- .../components/libraries/virt_key/BUILD.gn | 22 + .../libraries/virt_key/uart_simu_key_init.c | 183 + .../libraries/virt_key/uart_simu_key_init.h | 75 + .../gr551x_sdk/components/profiles/BUILD.gn | 73 + .../components/profiles/ags/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/ags/ags.c | 500 +- .../gr551x_sdk/components/profiles/ags/ags.h | 147 +- .../components/profiles/ams_c/BUILD.gn | 22 + .../components/profiles/ams_c/ams_c.c | 317 +- .../components/profiles/ams_c/ams_c.h | 104 +- .../components/profiles/ancs_c/BUILD.gn | 25 + .../components/profiles/ancs_c/ancs_c.c | 280 +- .../components/profiles/ancs_c/ancs_c.h | 97 +- .../profiles/ancs_c/ancs_protocol.c | 158 +- .../profiles/ancs_c/ancs_protocol.h | 65 +- .../components/profiles/ans/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/ans/ans.c | 408 +- .../gr551x_sdk/components/profiles/ans/ans.h | 56 +- .../components/profiles/ans_c/BUILD.gn | 22 + .../components/profiles/ans_c/ans_c.c | 300 +- .../components/profiles/ans_c/ans_c.h | 102 +- .../components/profiles/bas/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/bas/bas.c | 265 +- .../gr551x_sdk/components/profiles/bas/bas.h | 37 +- .../components/profiles/bas_c/BUILD.gn | 22 + .../components/profiles/bas_c/bas_c.c | 201 +- .../components/profiles/bas_c/bas_c.h | 42 +- .../components/profiles/bcs/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/bcs/bcs.c | 424 +- .../gr551x_sdk/components/profiles/bcs/bcs.h | 146 +- .../components/profiles/bps/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/bps/bps.c | 287 +- .../gr551x_sdk/components/profiles/bps/bps.h | 60 +- .../components/profiles/common/BUILD.gn | 25 + .../profiles/common/ble_prf_types.h | 17 +- .../profiles/common/ble_prf_utils.c | 82 +- .../profiles/common/ble_prf_utils.h | 2 +- .../profiles/common/ble_srv_disc_utils.c | 3 +- .../profiles/common/ble_srv_disc_utils.h | 8 +- .../components/profiles/cscs/BUILD.gn | 22 + .../components/profiles/cscs/cscs.c | 397 +- .../components/profiles/cscs/cscs.h | 96 +- .../components/profiles/cts/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/cts/cts.c | 784 +- .../gr551x_sdk/components/profiles/cts/cts.h | 166 +- .../components/profiles/cts_c/BUILD.gn | 22 + .../components/profiles/cts_c/cts_c.c | 382 +- .../components/profiles/cts_c/cts_c.h | 106 +- .../components/profiles/dis/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/dis/dis.c | 206 +- .../gr551x_sdk/components/profiles/dis/dis.h | 47 +- .../components/profiles/dis_c/BUILD.gn | 22 + .../components/profiles/dis_c/dis_c.c | 223 +- .../components/profiles/dis_c/dis_c.h | 58 +- .../components/profiles/dss/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/dss/dss.c | 482 +- .../gr551x_sdk/components/profiles/dss/dss.h | 50 +- .../components/profiles/gls/BUILD.gn | 26 + .../gr551x_sdk/components/profiles/gls/gls.c | 576 +- .../gr551x_sdk/components/profiles/gls/gls.h | 129 +- .../components/profiles/gls/gls_db.c | 148 +- .../components/profiles/gls/gls_db.h | 4 +- .../components/profiles/gls/gls_racp.c | 172 +- .../components/profiles/gls/gls_racp.h | 58 +- .../components/profiles/gus/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/gus/gus.c | 277 +- .../gr551x_sdk/components/profiles/gus/gus.h | 75 +- .../components/profiles/gus_c/BUILD.gn | 22 + .../components/profiles/gus_c/gus_c.c | 248 +- .../components/profiles/gus_c/gus_c.h | 53 +- .../components/profiles/hids/BUILD.gn | 22 + .../components/profiles/hids/hids.c | 942 +- .../components/profiles/hids/hids.h | 92 +- .../components/profiles/hrrcps/BUILD.gn | 22 + .../components/profiles/hrrcps/hrrcps.c | 227 +- .../components/profiles/hrrcps/hrrcps.h | 34 +- .../components/profiles/hrs/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/hrs/hrs.c | 302 +- .../gr551x_sdk/components/profiles/hrs/hrs.h | 47 +- .../components/profiles/hrs_c/BUILD.gn | 22 + .../components/profiles/hrs_c/hrs_c.c | 276 +- .../components/profiles/hrs_c/hrs_c.h | 64 +- .../components/profiles/hts/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/hts/hts.c | 381 +- .../gr551x_sdk/components/profiles/hts/hts.h | 111 +- .../components/profiles/ias/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/ias/ias.c | 162 +- .../gr551x_sdk/components/profiles/ias/ias.h | 27 +- .../components/profiles/ias_c/BUILD.gn | 22 + .../components/profiles/ias_c/ias_c.c | 159 +- .../components/profiles/ias_c/ias_c.h | 30 +- .../components/profiles/lls/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/lls/lls.c | 183 +- .../gr551x_sdk/components/profiles/lls/lls.h | 21 +- .../components/profiles/lls_c/BUILD.gn | 22 + .../components/profiles/lls_c/lls_c.c | 178 +- .../components/profiles/lls_c/lls_c.h | 37 +- .../components/profiles/lms/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/lms/lms.c | 440 + .../gr551x_sdk/components/profiles/lms/lms.h | 179 + .../components/profiles/lns/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/lns/lns.c | 264 +- .../gr551x_sdk/components/profiles/lns/lns.h | 39 +- .../components/profiles/mlmr/BUILD.gn | 22 + .../components/profiles/mlmr/mlmr.c | 442 +- .../components/profiles/mlmr/mlmr.h | 123 +- .../components/profiles/mlmr_c/BUILD.gn | 22 + .../components/profiles/mlmr_c/mlmr_c.c | 409 +- .../components/profiles/mlmr_c/mlmr_c.h | 167 +- .../components/profiles/ndcs/BUILD.gn | 22 + .../components/profiles/ndcs/ndcs.c | 143 +- .../components/profiles/ndcs/ndcs.h | 21 +- .../components/profiles/otas/BUILD.gn | 22 + .../components/profiles/otas/otas.c | 371 +- .../components/profiles/otas/otas.h | 87 +- .../components/profiles/otas_c/BUILD.gn | 22 + .../components/profiles/otas_c/otas_c.c | 209 +- .../components/profiles/otas_c/otas_c.h | 65 +- .../components/profiles/pass/BUILD.gn | 22 + .../components/profiles/pass/pass.c | 251 +- .../components/profiles/pass/pass.h | 31 +- .../components/profiles/pass_c/BUILD.gn | 22 + .../components/profiles/pass_c/pass_c.c | 263 +- .../components/profiles/pass_c/pass_c.h | 60 +- .../components/profiles/pcs/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/pcs/pcs.c | 253 +- .../gr551x_sdk/components/profiles/pcs/pcs.h | 26 +- .../components/profiles/rscs/BUILD.gn | 22 + .../components/profiles/rscs/rscs.c | 462 +- .../components/profiles/rscs/rscs.h | 104 +- .../components/profiles/rscs_c/BUILD.gn | 22 + .../components/profiles/rscs_c/rscs_c.c | 298 +- .../components/profiles/rscs_c/rscs_c.h | 90 +- .../components/profiles/rtus/BUILD.gn | 22 + .../components/profiles/rtus/rtus.c | 171 +- .../components/profiles/rtus/rtus.h | 37 +- .../components/profiles/sample/BUILD.gn | 22 + .../profiles/sample/sample_service.c | 283 +- .../profiles/sample/sample_service.h | 39 +- .../components/profiles/ths/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/ths/ths.c | 296 +- .../gr551x_sdk/components/profiles/ths/ths.h | 51 +- .../components/profiles/ths_c/BUILD.gn | 22 + .../components/profiles/ths_c/ths_c.c | 267 +- .../components/profiles/ths_c/ths_c.h | 53 +- .../components/profiles/tps/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/tps/tps.c | 132 +- .../gr551x_sdk/components/profiles/tps/tps.h | 17 +- .../components/profiles/tps_c/BUILD.gn | 22 + .../components/profiles/tps_c/tps_c.c | 158 +- .../components/profiles/tps_c/tps_c.h | 24 +- .../components/profiles/uds/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/uds/uds.c | 1423 +- .../gr551x_sdk/components/profiles/uds/uds.h | 151 +- .../components/profiles/wss/BUILD.gn | 22 + .../gr551x_sdk/components/profiles/wss/wss.c | 386 +- .../gr551x_sdk/components/profiles/wss/wss.h | 76 +- .../gr551x_sdk/components/sdk/BUILD.gn | 21 + .../gr551x_sdk/components/sdk/ble.h | 114 +- .../gr551x_sdk/components/sdk/ble_att.h | 1296 +- .../gr551x_sdk/components/sdk/ble_audio.h | 252 + .../gr551x_sdk/components/sdk/ble_error.h | 391 +- .../gr551x_sdk/components/sdk/ble_event.h | 220 + .../gr551x_sdk/components/sdk/ble_gapc.h | 1019 +- .../gr551x_sdk/components/sdk/ble_gapm.h | 1248 +- .../gr551x_sdk/components/sdk/ble_gatt.h | 65 +- .../gr551x_sdk/components/sdk/ble_gattc.h | 350 +- .../gr551x_sdk/components/sdk/ble_gatts.h | 435 +- .../gr551x_sdk/components/sdk/ble_l2cap.h | 268 +- .../gr551x_sdk/components/sdk/ble_lcp.h | 230 + .../gr551x_sdk/components/sdk/ble_prf.h | 575 +- .../gr551x_sdk/components/sdk/ble_sec.h | 331 +- .../gr551x_sdk/components/sdk/gr55xx_dfu.h | 327 +- .../gr551x_sdk/components/sdk/gr55xx_fpb.h | 148 +- .../gr551x_sdk/components/sdk/gr55xx_nvds.h | 58 +- .../gr551x_sdk/components/sdk/gr55xx_pwr.h | 249 +- .../gr551x_sdk/components/sdk/gr55xx_sys.h | 189 +- .../components/sdk/gr55xx_sys_cfg.h | 32 +- .../gr551x_sdk/components/sdk/gr_includes.h | 66 + .../gr551x_sdk/components/sdk/grx_sys.h | 67 + .../gr551x_sdk/components/sdk/patch.h | 106 + .../gr551x_sdk/components/sdk/patch_tab.h | 336 + .../gr551x_sdk/components/sdk/platform_sdk.h | 134 +- gr551x/sdk_liteos/gr551x_sdk/drivers/BUILD.gn | 54 + .../gr551x_sdk/drivers/inc/app_adc.h | 336 + .../gr551x_sdk/drivers/inc/app_adc_dma.h | 119 + .../gr551x_sdk/drivers/inc/app_aon_wdt.h | 158 + .../gr551x_sdk/drivers/inc/app_bod.h | 295 + .../gr551x_sdk/drivers/inc/app_comp.h | 221 + .../gr551x_sdk/drivers/inc/app_dma.h | 230 + .../gr551x_sdk/drivers/inc/app_drv.h | 14 + .../gr551x_sdk/drivers/inc/app_drv_config.h | 199 + .../gr551x_sdk/drivers/inc/app_drv_error.h | 125 + .../gr551x_sdk/drivers/inc/app_dual_tim.h | 322 + .../gr551x_sdk/drivers/inc/app_gpiote.h | 126 + .../drivers/inc/app_graphics_qspi.h | 176 + .../gr551x_sdk/drivers/inc/app_i2c.h | 457 + .../gr551x_sdk/drivers/inc/app_i2c_dma.h | 179 + .../gr551x_sdk/drivers/inc/app_i2s.h | 431 + .../gr551x_sdk/drivers/inc/app_i2s_dma.h | 157 + .../gr551x_sdk/drivers/inc/app_io.h | 485 + .../gr551x_sdk/drivers/inc/app_iso7816.h | 429 + .../gr551x_sdk/drivers/inc/app_pwm.h | 437 + .../gr551x_sdk/drivers/inc/app_pwm_dma.h | 125 + .../gr551x_sdk/drivers/inc/app_pwr_mgmt.h | 131 + .../gr551x_sdk/drivers/inc/app_qspi.h | 955 + .../gr551x_sdk/drivers/inc/app_qspi_dma.h | 235 + .../gr551x_sdk/drivers/inc/app_rng.h | 219 + .../gr551x_sdk/drivers/inc/app_rtc.h | 232 + .../gr551x_sdk/drivers/inc/app_rtos_cfg.h | 280 + .../gr551x_sdk/drivers/inc/app_soft_encoder.h | 141 + .../gr551x_sdk/drivers/inc/app_spi.h | 486 + .../gr551x_sdk/drivers/inc/app_spi_dma.h | 256 + .../gr551x_sdk/drivers/inc/app_tim.h | 256 + .../gr551x_sdk/drivers/inc/app_uart.h | 395 + .../gr551x_sdk/drivers/inc/app_uart_dma.h | 165 + .../gr551x_sdk/drivers/inc/hal/gr55xx_delay.h | 328 + .../gr551x_sdk/drivers/inc/hal/gr55xx_hal.h | 376 + .../drivers/inc/hal/gr55xx_hal_adc.h | 608 + .../drivers/inc/hal/gr55xx_hal_adc_temp_api.h | 75 + .../drivers/inc/hal/gr55xx_hal_adc_vbat_api.h | 75 + .../inc/hal/gr55xx_hal_adc_voltage_api.h | 90 + .../drivers/inc/hal/gr55xx_hal_aes.h | 851 + .../drivers/inc/hal/gr55xx_hal_aon_gpio.h | 419 + .../drivers/inc/hal/gr55xx_hal_aon_gpio_ex.h | 181 + .../drivers/inc/hal/gr55xx_hal_aon_wdt.h | 267 + .../drivers/inc/hal/gr55xx_hal_bod.h | 297 + .../drivers/inc/hal/gr55xx_hal_calendar.h | 575 + .../drivers/inc/hal/gr55xx_hal_cgc.h | 362 + .../drivers/inc/hal/gr55xx_hal_comp.h | 448 + .../drivers/inc/hal/gr55xx_hal_conf.h | 254 + .../drivers/inc/hal/gr55xx_hal_cortex.h | 770 + .../drivers/inc/hal/gr55xx_hal_def.h | 234 + .../drivers/inc/hal/gr55xx_hal_dma.h | 736 + .../drivers/inc/hal/gr55xx_hal_dual_tim.h | 493 + .../drivers/inc/hal/gr55xx_hal_efuse.h | 514 + .../drivers/inc/hal/gr55xx_hal_exflash.h | 778 + .../drivers/inc/hal/gr55xx_hal_gpio.h | 477 + .../drivers/inc/hal/gr55xx_hal_gpio_ex.h | 497 + .../drivers/inc/hal/gr55xx_hal_hmac.h | 615 + .../drivers/inc/hal/gr55xx_hal_i2c.h | 1245 + .../drivers/inc/hal/gr55xx_hal_i2s.h | 975 + .../drivers/inc/hal/gr55xx_hal_iso7816.h | 634 + .../drivers/inc/hal/gr55xx_hal_msio.h | 341 + .../drivers/inc/hal/gr55xx_hal_msio_ex.h | 176 + .../drivers/inc/hal/gr55xx_hal_pkc.h | 1044 + .../drivers/inc/hal/gr55xx_hal_pwm.h | 519 + .../drivers/inc/hal/gr55xx_hal_pwr.h | 484 + .../drivers/inc/hal/gr55xx_hal_qspi.h | 1123 + .../drivers/inc/hal/gr55xx_hal_rng.h | 449 + .../drivers/inc/hal/gr55xx_hal_sleep_timer.h | 126 + .../drivers/inc/hal/gr55xx_hal_spi.h | 1098 + .../drivers/inc/hal/gr55xx_hal_spi_v2.h | 613 + .../drivers/inc/hal/gr55xx_hal_tim.h | 417 + .../drivers/inc/hal/gr55xx_hal_uart.h | 1045 + .../drivers/inc/hal/gr55xx_hal_wdt.h | 323 + .../drivers/inc/hal/gr55xx_hal_xqspi.h | 826 + .../drivers/inc/hal/gr55xx_ll_adc.h | 1084 + .../drivers/inc/hal/gr55xx_ll_aes.h | 1693 ++ .../drivers/inc/hal/gr55xx_ll_aon_gpio.h | 1236 + .../drivers/inc/hal/gr55xx_ll_aon_wdt.h | 305 + .../drivers/inc/hal/gr55xx_ll_bod.h | 331 + .../drivers/inc/hal/gr55xx_ll_calendar.h | 488 + .../drivers/inc/hal/gr55xx_ll_cgc.h | 2711 ++ .../drivers/inc/hal/gr55xx_ll_comp.h | 413 + .../drivers/inc/hal/gr55xx_ll_dma.h | 4627 +++ .../drivers/inc/hal/gr55xx_ll_dual_tim.h | 719 + .../drivers/inc/hal/gr55xx_ll_efuse.h | 802 + .../drivers/inc/hal/gr55xx_ll_gpio.h | 1507 + .../drivers/inc/hal/gr55xx_ll_hmac.h | 1425 + .../drivers/inc/hal/gr55xx_ll_i2c.h | 3961 +++ .../drivers/inc/hal/gr55xx_ll_i2s.h | 1906 ++ .../drivers/inc/hal/gr55xx_ll_iso7816.h | 1435 + .../drivers/inc/hal/gr55xx_ll_msio.h | 793 + .../drivers/inc/hal/gr55xx_ll_pkc.h | 3024 ++ .../drivers/inc/hal/gr55xx_ll_pwm.h | 1971 ++ .../drivers/inc/hal/gr55xx_ll_pwr.h | 1531 + .../drivers/inc/hal/gr55xx_ll_rng.h | 759 + .../drivers/inc/hal/gr55xx_ll_spi.h | 2631 ++ .../drivers/inc/hal/gr55xx_ll_tim.h | 448 + .../drivers/inc/hal/gr55xx_ll_uart.h | 1621 + .../drivers/inc/hal/gr55xx_ll_wdt.h | 415 + .../drivers/inc/hal/gr55xx_ll_xqspi.h | 2902 ++ .../gr551x_sdk/drivers/inc/hal/grx_hal.h | 71 + .../gr551x_sdk/drivers/src/app_adc.c | 489 + .../gr551x_sdk/drivers/src/app_adc_dma.c | 239 + .../gr551x_sdk/drivers/src/app_aon_wdt.c | 166 + .../gr551x_sdk/drivers/src/app_bod.c | 239 + .../gr551x_sdk/drivers/src/app_comp.c | 354 + .../gr551x_sdk/drivers/src/app_dma.c | 561 + .../gr551x_sdk/drivers/src/app_dual_tim.c | 701 + .../gr551x_sdk/drivers/src/app_gpiote.c | 94 + .../drivers/src/app_graphics_qspi.c | 1543 + .../gr551x_sdk/drivers/src/app_i2c.c | 958 + .../gr551x_sdk/drivers/src/app_i2c_dma.c | 563 + .../gr551x_sdk/drivers/src/app_i2s.c | 819 + .../gr551x_sdk/drivers/src/app_i2s_dma.c | 390 + .../gr551x_sdk/drivers/src/app_io.c | 845 + .../gr551x_sdk/drivers/src/app_iso7816.c | 645 + .../gr551x_sdk/drivers/src/app_pwm.c | 695 + .../gr551x_sdk/drivers/src/app_pwm_dma.c | 201 + .../gr551x_sdk/drivers/src/app_pwr_mgmt.c | 279 + .../gr551x_sdk/drivers/src/app_qspi.c | 1550 + .../gr551x_sdk/drivers/src/app_qspi_dma.c | 598 + .../gr551x_sdk/drivers/src/app_rng.c | 294 + .../gr551x_sdk/drivers/src/app_rtc.c | 560 + .../gr551x_sdk/drivers/src/app_rtos_cfg.c | 248 + .../gr551x_sdk/drivers/src/app_soft_encoder.c | 177 + .../gr551x_sdk/drivers/src/app_spi.c | 1201 + .../gr551x_sdk/drivers/src/app_spi_dma.c | 820 + .../gr551x_sdk/drivers/src/app_tim.c | 426 + .../gr551x_sdk/drivers/src/app_uart.c | 869 + .../gr551x_sdk/drivers/src/app_uart_dma.c | 564 + .../gr551x_sdk/external/segger_rtt/BUILD.gn | 22 + .../external/segger_rtt/SEGGER_RTT.c | 1459 + .../external/segger_rtt/SEGGER_RTT.h | 248 + .../external/segger_rtt/SEGGER_RTT_Conf.h | 269 + .../sdk_liteos/gr551x_sdk/platform/BUILD.gn | 33 + .../cmsis/core/include/cmsis_compiler.h | 283 + .../cortex-m/cmsis/core/include/cmsis_gcc.h | 2211 ++ .../cmsis/core/include/cmsis_version.h | 39 + .../cortex-m/cmsis/core/include/core_cm4.h | 2129 ++ .../cortex-m/cmsis/core/include/mpu_armv7.h | 275 + .../arch/arm/cortex-m/gcc/startup_gr55xx.s | 218 + .../gr551x_sdk/platform/boards/board_SK.c | 253 + .../gr551x_sdk/platform/boards/board_SK.h | 342 + .../platform/boards/unity_test_config.h | 40 + .../gr551x_sdk/platform/include/gr_plat.h | 33 + .../gr551x_sdk/platform/include/gr_soc.h | 53 + .../platform/include/scatter_common.h | 18 + .../platform/soc/common/gr_interrupt.c | 223 + .../platform/soc/common/gr_platform.c | 138 + .../platform/soc/common/gr_system.c | 46 + .../gr551x_sdk/platform/soc/include/ble_cfg.h | 212 + .../gr551x_sdk/platform/soc/include/gr551xx.h | 6550 ++++ .../gr551x_sdk/platform/soc/include/gr55xx.h | 207 + .../platform/soc/include/grx_soc_reg.h | 39 + .../platform/soc/include/system_gr55xx.h | 92 + .../soc/linker/gcc/gcc_linker_gr5513.lds | 116 + .../soc/linker/gcc/gcc_linker_gr5515.lds | 116 + .../soc/linker/gcc/hardfloat_lib/libble_sdk.a | Bin 0 -> 4943310 bytes .../platform/soc/linker/gcc/libble_sdk.a | Bin 0 -> 4943050 bytes .../soc/linker/gcc/rom_symbol_gcc.txt | 1414 + .../platform/soc/linker/gcc/startup_gr55xx.s | 193 + .../gr551x_sdk/platform/soc/src/gr_soc.c | 497 + gr551x/sdk_liteos/liteos_m/BUILD.gn | 5 +- gr551x/sdk_liteos/liteos_m/los_port_pm.c | 308 +- gr551x/sdk_liteos/liteos_m/target_config.h | 0 .../sdk_liteos/platform/linker/gr5515.ld.tmpl | 243 + gr551x/sdk_liteos/platform/main/BUILD.gn | 4 +- gr551x/sdk_liteos/platform/main/main.c | 61 +- gr551x/sdk_liteos/platform/main/main.h | 5 +- gr551x/sdk_liteos/platform/system/BUILD.gn | 3 +- gr551x/sdk_liteos/platform/system/dprintf.c | 13 +- gr551x/sdk_liteos/platform/system/system.c | 3 +- gr551x/sdk_liteos/platform/system/uart.c | 51 + gr551x/sdk_liteos/platform/system/uart.h | 26 + .../third_party_adapter/mbedtls/BUILD.gn | 43 + .../mbedtls/config/mbedtls_config_gr551x.h | 3354 +++ gr551x/tools/bin_create.py | 2 +- 541 files changed, 200758 insertions(+), 16605 deletions(-) mode change 100755 => 100644 gr551x/BUILD.gn create mode 100644 gr551x/gr551x_executable.gni mode change 100755 => 100644 gr551x/sdk_liteos/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/config/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/config/custom_config.h mode change 100755 => 100644 gr551x/sdk_liteos/config/flash_scatter_config.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/README.md create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_measure_mux_signal_api.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_measure_mux_signal_api.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/Lib/GCC/libarm_cortexM4lf_math.a create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_common_tables.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_const_structs.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_math.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_mve_tables.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_vec_math.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error_cfg.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_gcc.s mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_iar.s mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_keil.s create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_aes.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_ecc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_ecc_port.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_gcm.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc_port.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_rsa.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_rsa_port.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_sha256.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_aes.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc_port.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_gcm.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc_port.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa_port.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_sha256.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test_int.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/font_gb2312.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_animation.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_animation.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_basic.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_basic.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_color.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_color.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gb2312_font.bin create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gb2312_font.hex create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_animation_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_config.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_gb2312_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcd_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_cfg.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_oled_config.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font5_7.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font5_7.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font8_8.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font8_8.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_gb2312.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_gb2312.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_macro.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_other.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_other.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_include.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.c mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/uart_simu_key_init.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/uart_simu_key_init.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/BUILD.gn mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_att.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_audio.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_error.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_event.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapc.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapm.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatt.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gattc.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatts.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_l2cap.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_lcp.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_prf.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_sec.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_dfu.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_fpb.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_nvds.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_pwr.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys_cfg.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr_includes.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/grx_sys.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/patch.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/patch_tab.h mode change 100755 => 100644 gr551x/sdk_liteos/gr551x_sdk/components/sdk/platform_sdk.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_adc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_adc_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_aon_wdt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_bod.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_comp.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_drv.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_drv_config.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_drv_error.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_dual_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_gpiote.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_graphics_qspi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_io.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_iso7816.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwr_mgmt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_qspi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_qspi_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rng.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtos_cfg.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_soft_encoder.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_delay.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_temp_api.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_vbat_api.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_voltage_api.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aes.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio_ex.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_wdt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_bod.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_calendar.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cgc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_comp.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_conf.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cortex.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_def.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dual_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_efuse.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_exflash.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio_ex.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_hmac.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2c.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2s.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_iso7816.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio_ex.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pkc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwm.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwr.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_qspi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_rng.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_sleep_timer.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi_v2.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_uart.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_wdt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_xqspi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_adc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aes.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_gpio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_wdt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_bod.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_calendar.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_cgc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_comp.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dma.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dual_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_efuse.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_gpio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_hmac.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2c.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2s.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_iso7816.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_msio.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pkc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwm.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwr.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_rng.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_spi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_tim.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_uart.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_wdt.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_xqspi.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/grx_hal.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_aon_wdt.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_bod.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_comp.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dual_tim.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_gpiote.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_graphics_qspi.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_io.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_iso7816.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwr_mgmt.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rng.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtc.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtos_cfg.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_soft_encoder.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_tim.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart_dma.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT_Conf.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/BUILD.gn create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_compiler.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_gcc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_version.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/core_cm4.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/mpu_armv7.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/gcc/startup_gr55xx.s create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/boards/unity_test_config.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_plat.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_soc.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/include/scatter_common.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_interrupt.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_platform.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_system.c create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/ble_cfg.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr551xx.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr55xx.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/grx_soc_reg.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/system_gr55xx.h create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5513.lds create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5515.lds create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/hardfloat_lib/libble_sdk.a create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/libble_sdk.a create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/rom_symbol_gcc.txt create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/startup_gr55xx.s create mode 100644 gr551x/sdk_liteos/gr551x_sdk/platform/soc/src/gr_soc.c mode change 100755 => 100644 gr551x/sdk_liteos/liteos_m/target_config.h create mode 100644 gr551x/sdk_liteos/platform/linker/gr5515.ld.tmpl mode change 100755 => 100644 gr551x/sdk_liteos/platform/main/BUILD.gn create mode 100644 gr551x/sdk_liteos/platform/system/uart.c create mode 100644 gr551x/sdk_liteos/platform/system/uart.h create mode 100644 gr551x/sdk_liteos/third_party_adapter/mbedtls/BUILD.gn create mode 100644 gr551x/sdk_liteos/third_party_adapter/mbedtls/config/mbedtls_config_gr551x.h diff --git a/BUILD.gn b/BUILD.gn index 6f098f0..5382f89 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 diff --git a/gr551x/BUILD.gn b/gr551x/BUILD.gn old mode 100755 new mode 100644 index 482a945..3be0699 --- a/gr551x/BUILD.gn +++ b/gr551x/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 @@ -11,37 +11,41 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/lite/config/component/lite_component.gni") -import("//build/lite/config/subsystem/lite_subsystem.gni") import("//kernel/liteos_m/liteos.gni") -copy("link-script") { - sources = [ "sdk_liteos/platform/startup/gr551x.ld" ] +action("resolve-link-script") { + script = "//build/lite/run_shell_cmd.py" + args = [ + "${compile_prefix}cpp${toolchain_cmd_suffix}", + "-include", + rebase_path("sdk_liteos/config/custom_config.h"), + "-E", + rebase_path("sdk_liteos/platform/linker/gr5515.ld.tmpl"), + "-o", + rebase_path("$root_build_dir/bin/link.ld"), + "-P", + ] outputs = [ "$root_build_dir/bin/link.ld" ] } copy("sdk_lib") { - sources = - [ "sdk_liteos/gr551x_sdk/components/sdk/linker/lib_gcc/libble_sdk.a" ] + sources = [ "sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/libble_sdk.a" ] outputs = [ "$root_build_dir/libs/libble_sdk.a" ] } copy("rom_symbol") { - sources = [ - "sdk_liteos/gr551x_sdk/components/patch/symbol_table/rom_symbol_gcc.txt", - ] + sources = + [ "sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/rom_symbol_gcc.txt" ] outputs = [ "$root_build_dir/libs/rom_symbol_gcc.txt" ] } -module_name = get_path_info(rebase_path("."), "name") -module_group(module_name) { +module_group("gr551x") { deps = [ - ":link-script", + ":resolve-link-script", ":rom_symbol", ":sdk_lib", - "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_static", - "//build/lite/config/component/cJSON:cjson_static", ] + modules = [ "sdk_liteos", "components", diff --git a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_gpio.c b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_gpio.c index 004c3e3..6acc7f0 100755 --- a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_gpio.c +++ b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 GOODIX. + * Copyright (c) 2024 GOODIX. * Licensed 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 @@ -17,7 +17,8 @@ #include "iot_gpio.h" #include "app_io.h" #include "app_gpiote.h" -#include "stdbool.h" +#include +#include /* ID 0~31 Normal GPIO */ @@ -118,7 +119,7 @@ static int get_pin_index(uint32_t pin) return index; } -static void app_io_callback(app_gpiote_evt_t *p_evt) +static void app_io_callback(app_io_evt_t *p_evt) { uint32_t index = 0; @@ -160,7 +161,7 @@ unsigned int IoTGpioSetDir(unsigned int id, IotGpioDir dir) if (dir == IOT_GPIO_DIR_IN) { io_init.mode = APP_IO_MODE_INPUT; } else if (dir == IOT_GPIO_DIR_OUT) { - io_init.mode = APP_IO_MODE_OUT_PUT; + io_init.mode = APP_IO_MODE_OUTPUT; } g_gpio_dir[id] = dir; @@ -244,7 +245,6 @@ unsigned int IoTGpioRegisterIsrFunc(unsigned int id, IotGpioIntType intType, Iot gpiote_param.type = io_type; gpiote_param.pin = pin; gpiote_param.pull = APP_IO_PULLUP; - gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP; if (intType == IOT_INT_TYPE_LEVEL) { if (intPolarity == IOT_GPIO_EDGE_FALL_LEVEL_LOW) { isr_cfg_info[id].mode = APP_IO_MODE_IT_LOW; @@ -293,7 +293,6 @@ unsigned int IoTGpioUnregisterIsrFunc(unsigned int id) gpiote_param.pin = pin; gpiote_param.mode = isr_cfg_info[id].mode; gpiote_param.pull = APP_IO_PULLUP; - gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP; gpiote_param.io_evt_cb = NULL; if (isr_cfg_info[id].initialized == false) { @@ -330,7 +329,6 @@ unsigned int IoTGpioSetIsrMode(unsigned int id, IotGpioIntType intType, IotGpioI gpiote_param.type = io_type; gpiote_param.pin = pin; gpiote_param.pull = APP_IO_PULLUP; - gpiote_param.handle_mode = APP_IO_ENABLE_WAKEUP; gpiote_param.io_evt_cb = app_io_callback; if (intType == IOT_INT_TYPE_LEVEL) { diff --git a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_i2c.c b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_i2c.c index 18b758e..f8885cb 100755 --- a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_i2c.c +++ b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_i2c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 GOODIX. + * Copyright (c) 2024 GOODIX. * Licensed 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 @@ -20,72 +20,100 @@ /* I2C0 config params */ /* SCL : GPIO30 */ -#define USER_I2C0_SCL_PIN APP_IO_PIN_30 -#define USER_I2C0_SCL_PIN_TYPE APP_IO_TYPE_NORMAL -#define USER_I2C0_SCL_PIN_MUX APP_IO_MUX_2 -#define USER_I2C0_SCL_PIN_PULL APP_IO_PULLUP +#define USER_I2C0_SCL_PIN APP_IO_PIN_30 +#define USER_I2C0_SCL_PIN_TYPE APP_IO_TYPE_NORMAL +#define USER_I2C0_SCL_PIN_MUX APP_IO_MUX_2 +#define USER_I2C0_SCL_PIN_PULL APP_IO_PULLUP /* SDA : GPIO26 */ -#define USER_I2C0_SDA_PIN APP_IO_PIN_26 -#define USER_I2C0_SDA_PIN_TYPE APP_IO_TYPE_NORMAL -#define USER_I2C0_SDA_PIN_MUX APP_IO_MUX_2 -#define USER_I2C0_SDA_PIN_PULL APP_IO_PULLUP -#define USER_I2C0_SPEED I2C_SPEED_400K -#define I2C0_IO_CONFIG {{USER_I2C0_SCL_PIN_TYPE, USER_I2C0_SCL_PIN_MUX, USER_I2C0_SCL_PIN, USER_I2C0_SCL_PIN_PULL}, \ - {USER_I2C0_SDA_PIN_TYPE, USER_I2C0_SDA_PIN_MUX, USER_I2C0_SDA_PIN, USER_I2C0_SDA_PIN_PULL}} -#define I2C0_MODE_CONFIG {APP_I2C_TYPE_INTERRUPT, DMA_Channel0, DMA_Channel0} -#define I2C0_I2C_CONFIG {USER_I2C0_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE} -#define I2C0_PARAM_CONFIG {APP_I2C_ID_0, APP_I2C_ROLE_MASTER, I2C0_IO_CONFIG, I2C0_MODE_CONFIG, I2C0_I2C_CONFIG} +#define USER_I2C0_SDA_PIN APP_IO_PIN_26 +#define USER_I2C0_SDA_PIN_TYPE APP_IO_TYPE_NORMAL +#define USER_I2C0_SDA_PIN_MUX APP_IO_MUX_2 +#define USER_I2C0_SDA_PIN_PULL APP_IO_PULLUP +#define USER_I2C0_SPEED I2C_SPEED_400K + +#define I2C0_IO_CONFIG \ + { \ + {USER_I2C0_SCL_PIN_TYPE, USER_I2C0_SCL_PIN_MUX, USER_I2C0_SCL_PIN, USER_I2C0_SCL_PIN_PULL}, \ + {USER_I2C0_SDA_PIN_TYPE, USER_I2C0_SDA_PIN_MUX, USER_I2C0_SDA_PIN, USER_I2C0_SDA_PIN_PULL}, \ + } + +#define I2C0_DMA_CONFIG \ + { \ + DMA0, DMA0, DMA_Channel2, DMA_Channel3 \ + } + +#define I2C0_I2C_CONFIG \ + { \ + USER_I2C0_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE \ + } + +#define I2C0_PARAM_CONFIG \ + { \ + APP_I2C_ID_0, APP_I2C_ROLE_MASTER, I2C0_IO_CONFIG, I2C0_DMA_CONFIG, I2C0_I2C_CONFIG \ + } /* I2C1 config params */ /* SCL : GPIO8 */ -#define USER_I2C1_SCL_PIN APP_IO_PIN_8 -#define USER_I2C1_SCL_PIN_TYPE APP_IO_TYPE_NORMAL -#define USER_I2C1_SCL_PIN_MUX APP_IO_MUX_1 -#define USER_I2C1_SCL_PIN_PULL APP_IO_PULLUP +#define USER_I2C1_SCL_PIN APP_IO_PIN_8 +#define USER_I2C1_SCL_PIN_TYPE APP_IO_TYPE_NORMAL +#define USER_I2C1_SCL_PIN_MUX APP_IO_MUX_1 +#define USER_I2C1_SCL_PIN_PULL APP_IO_PULLUP /* SDA : GPIO9 */ -#define USER_I2C1_SDA_PIN APP_IO_PIN_9 -#define USER_I2C1_SDA_PIN_TYPE APP_IO_TYPE_NORMAL -#define USER_I2C1_SDA_PIN_MUX APP_IO_MUX_1 -#define USER_I2C1_SDA_PIN_PULL APP_IO_PULLUP -#define USER_I2C1_SPEED I2C_SPEED_400K +#define USER_I2C1_SDA_PIN APP_IO_PIN_9 +#define USER_I2C1_SDA_PIN_TYPE APP_IO_TYPE_NORMAL +#define USER_I2C1_SDA_PIN_MUX APP_IO_MUX_1 +#define USER_I2C1_SDA_PIN_PULL APP_IO_PULLUP +#define USER_I2C1_SPEED I2C_SPEED_400K -#define I2C1_IO_CONFIG {{USER_I2C1_SCL_PIN_TYPE, USER_I2C1_SCL_PIN_MUX, USER_I2C1_SCL_PIN, USER_I2C1_SCL_PIN_PULL}, \ - {USER_I2C1_SDA_PIN_TYPE, USER_I2C1_SDA_PIN_MUX, USER_I2C1_SDA_PIN, USER_I2C1_SDA_PIN_PULL}} -#define I2C1_MODE_CONFIG {APP_I2C_TYPE_INTERRUPT, DMA_Channel0, DMA_Channel0} -#define I2C1_I2C_CONFIG {USER_I2C1_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE} -#define I2C1_PARAM_CONFIG {APP_I2C_ID_1, APP_I2C_ROLE_MASTER, I2C1_IO_CONFIG, I2C1_MODE_CONFIG, I2C1_I2C_CONFIG} -#define I2C_SYNC_TIMEOUT 20 +#define I2C1_IO_CONFIG \ + { \ + {USER_I2C1_SCL_PIN_TYPE, USER_I2C1_SCL_PIN_MUX, USER_I2C1_SCL_PIN, USER_I2C1_SCL_PIN_PULL}, \ + {USER_I2C1_SDA_PIN_TYPE, USER_I2C1_SDA_PIN_MUX, USER_I2C1_SDA_PIN, USER_I2C1_SDA_PIN_PULL}, \ + } -#define I2C_BAUDRATE_100K 100 -#define I2C_BAUDRATE_400K 400 -#define I2C_BAUDRATE_1000K 1000 -#define I2C_BAUDRATE_2000K 2000 +#define I2C2_DMA_CONFIG \ + { \ + DMA0, DMA_Channel4, DMA_Channel5 \ + } -static const app_i2c_params_t i2c_cfg_params[APP_I2C_ID_MAX] = { - I2C0_PARAM_CONFIG, - I2C1_PARAM_CONFIG -}; -static uint32_t i2c_tx_mutex[APP_I2C_ID_MAX]; -static uint32_t i2c_rx_mutex[APP_I2C_ID_MAX]; +#define I2C1_I2C_CONFIG \ + { \ + USER_I2C1_SPEED, 0x00, I2C_ADDRESSINGMODE_7BIT, I2C_GENERALCALL_DISABLE \ + } + +#define I2C1_PARAM_CONFIG \ + { \ + APP_I2C_ID_1, APP_I2C_ROLE_MASTER, I2C1_IO_CONFIG, I2C2_DMA_CONFIG, I2C1_I2C_CONFIG \ + } + +#define I2C_SYNC_TIMEOUT 20 + +#define I2C_BAUDRATE_100K 100 +#define I2C_BAUDRATE_400K 400 +#define I2C_BAUDRATE_1000K 1000 +#define I2C_BAUDRATE_2000K 2000 + +static app_i2c_params_t s_i2c_params[APP_I2C_ID_MAX] = {I2C0_PARAM_CONFIG, I2C1_PARAM_CONFIG}; +static uint32_t s_i2c_tx_mutex[APP_I2C_ID_MAX]; +static uint32_t s_i2c_rx_mutex[APP_I2C_ID_MAX]; unsigned int IoTI2cWrite(unsigned int id, unsigned short deviceAddr, const unsigned char *data, unsigned int dataLen) { int ret = 0; - if (id > APP_I2C_ID_MAX) { + if (id >= APP_I2C_ID_MAX) { return IOT_FAILURE; } - LOS_MuxPend(i2c_tx_mutex[id], LOS_WAIT_FOREVER); + LOS_MuxPend(s_i2c_tx_mutex[id], LOS_WAIT_FOREVER); ret = app_i2c_transmit_sync(id, deviceAddr, data, dataLen, I2C_SYNC_TIMEOUT); if (ret != 0) { - printf("ret=%d\r\n", ret); - LOS_MuxPost(i2c_tx_mutex[id]); + LOS_MuxPost(s_i2c_tx_mutex[id]); return IOT_FAILURE; } - LOS_MuxPost(i2c_tx_mutex[id]); + LOS_MuxPost(s_i2c_tx_mutex[id]); return IOT_SUCCESS; } @@ -94,13 +122,13 @@ unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned cha { int ret = 0; - LOS_MuxPend(i2c_rx_mutex[id], LOS_WAIT_FOREVER); + LOS_MuxPend(s_i2c_rx_mutex[id], LOS_WAIT_FOREVER); ret = app_i2c_receive_sync(id, deviceAddr, data, dataLen, I2C_SYNC_TIMEOUT); if (ret != 0) { - LOS_MuxPost(i2c_rx_mutex[id]); + LOS_MuxPost(s_i2c_rx_mutex[id]); return IOT_FAILURE; } - LOS_MuxPost(i2c_rx_mutex[id]); + LOS_MuxPost(s_i2c_rx_mutex[id]); return IOT_SUCCESS; } @@ -108,39 +136,37 @@ unsigned int IoTI2cRead(unsigned int id, unsigned short deviceAddr, unsigned cha unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate) { int ret = 0; - app_i2c_params_t i2c_params; uint32_t uwRet; - if (id > APP_I2C_ID_MAX) { + if (id >= APP_I2C_ID_MAX) { return IOT_FAILURE; } - memcpy_s(&i2c_params, sizeof(app_i2c_params_t), &i2c_cfg_params[id], sizeof(app_i2c_params_t)); if (baudrate == I2C_BAUDRATE_100K) { - i2c_params.init.speed = I2C_SPEED_100K; + s_i2c_params[id].init.speed = I2C_SPEED_100K; } else if (baudrate == I2C_BAUDRATE_400K) { - i2c_params.init.speed = I2C_SPEED_400K; - } else if (baudrate == I2C_BAUDRATE_1000K) { - i2c_params.init.speed = I2C_SPEED_1000K; + s_i2c_params[id].init.speed = I2C_SPEED_400K; + } else if (baudrate == I2C_BAUDRATE_1000K) { + s_i2c_params[id].init.speed = I2C_SPEED_1000K; } else if (baudrate == I2C_BAUDRATE_2000K) { - i2c_params.init.speed = I2C_SPEED_2000K; + s_i2c_params[id].init.speed = I2C_SPEED_2000K; } else { return IOT_FAILURE; } - ret = app_i2c_init(&i2c_params, NULL); + ret = app_i2c_init(&s_i2c_params[id], NULL); if (ret != 0) { return IOT_FAILURE; } - uwRet = LOS_MuxCreate(&i2c_tx_mutex[id]); + uwRet = LOS_MuxCreate(&s_i2c_tx_mutex[id]); if (uwRet != LOS_OK) { return IOT_FAILURE; } - uwRet = LOS_MuxCreate(&i2c_rx_mutex[id]); + uwRet = LOS_MuxCreate(&s_i2c_rx_mutex[id]); if (uwRet != LOS_OK) { - LOS_SemDelete(i2c_tx_mutex[id]); + LOS_SemDelete(s_i2c_tx_mutex[id]); return IOT_FAILURE; } @@ -149,13 +175,13 @@ unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate) unsigned int IoTI2cDeinit(unsigned int id) { - if (id > APP_I2C_ID_MAX) { + if (id >= APP_I2C_ID_MAX) { return IOT_FAILURE; } app_i2c_deinit(id); - LOS_SemDelete(i2c_tx_mutex[id]); - LOS_SemDelete(i2c_rx_mutex[id]); + LOS_SemDelete(s_i2c_tx_mutex[id]); + LOS_SemDelete(s_i2c_rx_mutex[id]); return IOT_SUCCESS; } @@ -163,27 +189,25 @@ unsigned int IoTI2cDeinit(unsigned int id) unsigned int IoTI2cSetBaudrate(unsigned int id, unsigned int baudrate) { int ret = 0; - app_i2c_params_t i2c_params; - if (id > APP_I2C_ID_MAX) { + if (id >= APP_I2C_ID_MAX) { return IOT_FAILURE; } - memcpy_s(&i2c_params, sizeof(app_i2c_params_t), &i2c_cfg_params[id], sizeof(app_i2c_params_t)); if (baudrate == I2C_BAUDRATE_100K) { - i2c_params.init.speed = I2C_SPEED_100K; + s_i2c_params[id].init.speed = I2C_SPEED_100K; } else if (baudrate == I2C_BAUDRATE_400K) { - i2c_params.init.speed = I2C_SPEED_400K; - } else if (baudrate == I2C_BAUDRATE_1000K) { - i2c_params.init.speed = I2C_SPEED_1000K; + s_i2c_params[id].init.speed = I2C_SPEED_400K; + } else if (baudrate == I2C_BAUDRATE_1000K) { + s_i2c_params[id].init.speed = I2C_SPEED_1000K; } else if (baudrate == I2C_BAUDRATE_2000K) { - i2c_params.init.speed = I2C_SPEED_2000K; + s_i2c_params[id].init.speed = I2C_SPEED_2000K; } else { return IOT_FAILURE; } app_i2c_deinit(id); - ret = app_i2c_init(&i2c_params, NULL); + ret = app_i2c_init(&s_i2c_params[id], NULL); if (ret != 0) { return IOT_FAILURE; } diff --git a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_pwm.c b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_pwm.c index 17d8ca8..888d005 100755 --- a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_pwm.c +++ b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_pwm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 GOODIX. + * Copyright (c) 2024 GOODIX. * Licensed 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 @@ -17,28 +17,110 @@ #include "iot_pwm.h" #include "app_pwm.h" -#define PWM_IO_CONFIG {{ APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_0, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }, \ - { APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_1, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }, \ - { APP_IO_TYPE_MSIO, APP_IO_MUX_0, APP_IO_PIN_2, APP_IO_NOPULL, APP_PWM_PIN_ENABLE }} +// APP_PWM_ID_0 +#define USER_PWM0_CHANNEL_A_PIN APP_IO_PIN_0 +#define USER_PWM0_CHANNEL_A_PIN_TYPE APP_IO_TYPE_MSIO +#define USER_PWM0_CHANNEL_A_PIN_MUX APP_IO_MUX_0 +#define USER_PWM0_CHANNEL_A_PIN_PULL APP_IO_NOPULL -#define PWM_ACTIVE_CAHN APP_PWM_ACTIVE_CHANNEL_ALL -#define PWM_CONFIG { PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, \ - { 50, PWM_DRIVEPOLARITY_POSITIVE }, \ - { 50, PWM_DRIVEPOLARITY_POSITIVE }, \ - { 50, PWM_DRIVEPOLARITY_POSITIVE }} -#define PWM_PARAM_CONFIG {0, PWM_IO_CONFIG, PWM_ACTIVE_CAHN, PWM_CONFIG } +#define USER_PWM0_CHANNEL_B_PIN APP_IO_PIN_1 +#define USER_PWM0_CHANNEL_B_PIN_TYPE APP_IO_TYPE_MSIO +#define USER_PWM0_CHANNEL_B_PIN_MUX APP_IO_MUX_0 +#define USER_PWM0_CHANNEL_B_PIN_PULL APP_IO_NOPULL + +#define USER_PWM0_CHANNEL_C_PIN APP_IO_PIN_2 +#define USER_PWM0_CHANNEL_C_PIN_TYPE APP_IO_TYPE_MSIO +#define USER_PWM0_CHANNEL_C_PIN_MUX APP_IO_MUX_0 +#define USER_PWM0_CHANNEL_C_PIN_PULL APP_IO_NOPULL + +#define PWM0_IO_CONFIG \ +{ \ + {USER_PWM0_CHANNEL_A_PIN_TYPE, USER_PWM0_CHANNEL_A_PIN_MUX, USER_PWM0_CHANNEL_A_PIN, USER_PWM0_CHANNEL_A_PIN_PULL, APP_PWM_PIN_ENABLE}, \ + {USER_PWM0_CHANNEL_B_PIN_TYPE, USER_PWM0_CHANNEL_B_PIN_MUX, USER_PWM0_CHANNEL_B_PIN, USER_PWM0_CHANNEL_B_PIN_PULL, APP_PWM_PIN_ENABLE}, \ + {USER_PWM0_CHANNEL_C_PIN_TYPE, USER_PWM0_CHANNEL_C_PIN_MUX, USER_PWM0_CHANNEL_C_PIN, USER_PWM0_CHANNEL_C_PIN_PULL, APP_PWM_PIN_ENABLE}, \ +} + +#define PWM0_ACTIVE_CHANNEL APP_PWM_ACTIVE_CHANNEL_ALL + +#define PWM0_PWM_CHANNEL_A_CONFIG \ + { \ + 50, PWM_DRIVEPOLARITY_POSITIVE \ + } + +#define PWM0_PWM_CHANNEL_B_CONFIG \ + { \ + 50, PWM_DRIVEPOLARITY_POSITIVE \ + } + +#define PWM0_PWM_CHANNEL_C_CONFIG \ + { \ + 50, PWM_DRIVEPOLARITY_POSITIVE \ + } + +#define PWM0_PWM_CONFIG \ + { \ + PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, PWM0_PWM_CHANNEL_A_CONFIG, PWM0_PWM_CHANNEL_B_CONFIG, PWM0_PWM_CHANNEL_C_CONFIG, \ + } + +#define PWM0_PARAM_CONFIG \ + { \ + APP_PWM_ID_0, PWM0_IO_CONFIG, PWM0_ACTIVE_CHANNEL, PWM0_PWM_CONFIG \ + } + +// APP_PWM_ID_1 +#define USER_PWM1_CHANNEL_A_PIN APP_IO_PIN_3 +#define USER_PWM1_CHANNEL_A_PIN_TYPE APP_IO_TYPE_MSIO +#define USER_PWM1_CHANNEL_A_PIN_MUX APP_IO_MUX_0 +#define USER_PWM1_CHANNEL_A_PIN_PULL APP_IO_NOPULL + +#define USER_PWM1_CHANNEL_B_PIN APP_IO_PIN_4 +#define USER_PWM1_CHANNEL_B_PIN_TYPE APP_IO_TYPE_MSIO +#define USER_PWM1_CHANNEL_B_PIN_MUX APP_IO_MUX_0 +#define USER_PWM1_CHANNEL_B_PIN_PULL APP_IO_NOPULL + +#define PWM1_IO_CONFIG \ +{ \ + {USER_PWM1_CHANNEL_A_PIN_TYPE, USER_PWM1_CHANNEL_A_PIN_MUX, USER_PWM1_CHANNEL_A_PIN, USER_PWM1_CHANNEL_A_PIN_PULL, APP_PWM_PIN_ENABLE}, \ + {USER_PWM1_CHANNEL_B_PIN_TYPE, USER_PWM1_CHANNEL_B_PIN_MUX, USER_PWM1_CHANNEL_B_PIN, USER_PWM1_CHANNEL_B_PIN_PULL, APP_PWM_PIN_ENABLE}, \ + {0}, \ +} + +#define PWM1_ACTIVE_CHANNEL (APP_PWM_ACTIVE_CHANNEL_A | APP_PWM_ACTIVE_CHANNEL_B) + +#define PWM1_PWM_CHANNEL_A_CONFIG \ + { \ + 50, PWM_DRIVEPOLARITY_POSITIVE \ + } + +#define PWM1_PWM_CHANNEL_B_CONFIG \ + { \ + 50, PWM_DRIVEPOLARITY_POSITIVE \ + } + +#define PWM1_PWM_CONFIG \ + { \ + PWM_MODE_FLICKER, PWM_ALIGNED_EDGE, 10, 500, 200, PWM1_PWM_CHANNEL_A_CONFIG, PWM1_PWM_CHANNEL_B_CONFIG, {0}, \ + } + +#define PWM1_PARAM_CONFIG \ + { \ + APP_PWM_ID_1, PWM1_IO_CONFIG, PWM1_ACTIVE_CHANNEL, PWM1_PWM_CONFIG \ + } + +static app_pwm_params_t s_pwm_params[APP_PWM_ID_MAX] = { + PWM0_PARAM_CONFIG, + PWM1_PARAM_CONFIG, +}; unsigned int IoTPwmInit(unsigned int port) { uint16_t ret = APP_DRV_SUCCESS; - app_pwm_params_t pwm_params = PWM_PARAM_CONFIG; - if (port > APP_PWM_ID_MAX) { + if (port >= APP_PWM_ID_MAX) { return IOT_FAILURE; } - pwm_params.id = port; - ret = app_pwm_init(&pwm_params); + ret = app_pwm_init(&s_pwm_params[port]); if (ret != APP_DRV_SUCCESS) { return IOT_FAILURE; } @@ -49,7 +131,7 @@ unsigned int IoTPwmDeinit(unsigned int port) { int ret = 0; - if (port > APP_PWM_ID_MAX) { + if (port >= APP_PWM_ID_MAX) { return IOT_FAILURE; } @@ -63,10 +145,9 @@ unsigned int IoTPwmDeinit(unsigned int port) unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq) { - app_pwm_params_t pwm_params = PWM_PARAM_CONFIG; app_pwm_channel_init_t channel_cfg = {0}; - if (port > APP_PWM_ID_MAX) { + if (port >= APP_PWM_ID_MAX) { return IOT_FAILURE; } @@ -81,7 +162,7 @@ unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int fr unsigned int IoTPwmStop(unsigned int port) { - if (port > APP_PWM_ID_MAX) { + if (port >= APP_PWM_ID_MAX) { return IOT_FAILURE; } diff --git a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_uart.c b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_uart.c index e12ab6c..41b1f92 100755 --- a/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_uart.c +++ b/gr551x/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_uart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 GOODIX. + * Copyright (c) 2024 GOODIX. * Licensed 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 @@ -16,6 +16,7 @@ #include "iot_errno.h" #include "iot_uart.h" #include "app_uart.h" +#include "app_uart_dma.h" #include "app_io.h" #include "los_sem.h" @@ -43,8 +44,9 @@ static app_uart_params_t uart_param[APP_UART_ID_MAX] = { .pull = APP_IO_PULLUP, } }, - .use_mode = { - .type = APP_UART_TYPE_DMA, + .dma_cfg = { + .tx_dma_instance = DMA0, + .rx_dma_instance = DMA0, .tx_dma_channel = DMA_Channel0, .rx_dma_channel = DMA_Channel1, } @@ -67,9 +69,6 @@ static app_uart_params_t uart_param[APP_UART_ID_MAX] = { .pull = APP_IO_PULLUP, } }, - .use_mode = { - .type = APP_UART_TYPE_INTERRUPT, /* UART1 only supports interrupt mode */ - } }, }; @@ -78,7 +77,7 @@ static uint32_t uart_tx_mutex[APP_UART_ID_MAX]; static uint32_t uart_rx_mutex[APP_UART_ID_MAX]; static uint32_t g_rx_num[APP_UART_ID_MAX]; -static const app_uart_evt_handler_t *evt_handler[APP_UART_ID_MAX] = { +static const app_uart_evt_handler_t evt_handler[APP_UART_ID_MAX] = { app_uart0_callback, app_uart1_callback }; @@ -105,6 +104,10 @@ static void app_uart1_callback(app_uart_evt_t *p_evt) struct app_uart_params_t* uart_cfg(unsigned int id, const IotUartAttribute *param) { + if (id >= APP_UART_ID_MAX) { + return IOT_FAILURE; + } + app_uart_params_t *params = &uart_param[id]; params->init.baud_rate = param->baudRate; params->init.rx_timeout_mode = UART_RECEIVER_TIMEOUT_ENABLE; @@ -159,6 +162,7 @@ unsigned int IoTUartInit(unsigned int id, const IotUartAttribute *param) if (id >= APP_UART_ID_MAX) { return IOT_FAILURE; } + params = uart_cfg(id, param); ret = app_uart_init(params, evt_handler[id], &uart_buffer); @@ -166,6 +170,14 @@ unsigned int IoTUartInit(unsigned int id, const IotUartAttribute *param) return IOT_FAILURE; } + if (id == APP_UART_ID_0) { + // Only UART0 support DMA + ret = app_uart_dma_init(params); + if (ret != 0) { + return IOT_FAILURE; + } + } + uwRet = LOS_BinarySemCreate(0, &uart_rx_sem[id]); if (uwRet != LOS_OK) { return IOT_FAILURE; @@ -192,11 +204,19 @@ int IoTUartRead(unsigned int id, unsigned char *data, unsigned int dataLen) int ret = 0; uint32_t uwRet = 0; + if (id >= APP_UART_ID_MAX) { + return IOT_FAILURE; + } + LOS_MuxPend(uart_rx_mutex[id], LOS_WAIT_FOREVER); g_rx_num[id] = 0; LOS_SemPend(uart_rx_sem[id], 0); - ret = app_uart_receive_async(id, data, dataLen); + if (id == APP_UART_ID_0) { + ret = app_uart_dma_receive_async(id, data, dataLen); + } else { + ret = app_uart_receive_async(id, data, dataLen); + } if (ret != 0) { LOS_MuxPost(uart_rx_mutex[id]); return IOT_FAILURE; @@ -217,6 +237,10 @@ int IoTUartWrite(unsigned int id, const unsigned char *data, unsigned int dataLe { int ret = 0; + if (id >= APP_UART_ID_MAX) { + return IOT_FAILURE; + } + LOS_MuxPend(uart_tx_mutex[id], LOS_WAIT_FOREVER); ret = app_uart_transmit_sync(id, data, dataLen, UART_TIMEOUT); if (ret != 0) { @@ -230,6 +254,10 @@ int IoTUartWrite(unsigned int id, const unsigned char *data, unsigned int dataLe unsigned int IoTUartDeinit(unsigned int id) { + if (id >= APP_UART_ID_MAX) { + return IOT_FAILURE; + } + app_uart_deinit(id); LOS_SemDelete(uart_rx_sem[id]); LOS_SemDelete(uart_tx_mutex[id]); diff --git a/gr551x/components/fs/BUILD.gn b/gr551x/components/fs/BUILD.gn index 3d26e89..722609f 100755 --- a/gr551x/components/fs/BUILD.gn +++ b/gr551x/components/fs/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 @@ -19,6 +19,4 @@ config("public") { hdf_driver("fs_adapter") { sources = [ "fs_init.c" ] - - deps = [ "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_static" ] } diff --git a/gr551x/gr551x_executable.gni b/gr551x/gr551x_executable.gni new file mode 100644 index 0000000..62fbcca --- /dev/null +++ b/gr551x/gr551x_executable.gni @@ -0,0 +1,86 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +template("gr551x_executable") { + executable("${target_name}.elf") { + forward_variables_from(invoker, + "*", + [ + "force_link_libs", + "gen_asm", + ]) + + if (defined(ldflags)) { + ldflags += [ "-Wl,--whole-archive" ] + } else { + ldflags = [ "-Wl,--whole-archive" ] + } + foreach(force_link_lib, invoker.force_link_libs) { + ldflags += [ "-l${force_link_lib}" ] + } + ldflags += [ "-Wl,--no-whole-archive" ] + } + + action("${target_name}.bin") { + script = "//build/lite/run_shell_cmd.py" + args = [ + "${compile_prefix}objcopy${toolchain_cmd_suffix}", + "-O", + "binary", + rebase_path("${root_build_dir}/bin/${invoker.target_name}.elf"), + rebase_path("${root_build_dir}/bin/${invoker.target_name}.bin"), + ] + outputs = [ "${root_build_dir}/bin/${invoker.target_name}.bin" ] + deps = [ ":${invoker.target_name}.elf" ] + } + + action("${target_name}.hex") { + script = "//build/lite/run_shell_cmd.py" + args = [ + "${compile_prefix}objcopy${toolchain_cmd_suffix}", + "-O", + "ihex", + rebase_path("${root_build_dir}/bin/${invoker.target_name}.elf"), + rebase_path("${root_build_dir}/bin/${invoker.target_name}.hex"), + ] + outputs = [ "${root_build_dir}/bin/${invoker.target_name}.hex" ] + deps = [ ":${invoker.target_name}.elf" ] + } + + if (defined(invoker.gen_asm) && invoker.gen_asm) { + action("${target_name}.asm") { + script = "//build/lite/run_shell_cmd.py" + args = [ + "${compile_prefix}objdump${toolchain_cmd_suffix}", + "-D", + rebase_path( + "${root_build_dir}/unstripped/bin/${invoker.target_name}.elf"), + ">", + rebase_path("${root_build_dir}/bin/${invoker.target_name}.asm"), + ] + outputs = [ "${root_build_dir}/bin/${invoker.target_name}.asm" ] + deps = [ ":${invoker.target_name}.elf" ] + } + } + + group("${target_name}") { + deps = [ + ":${target_name}.bin", + ":${target_name}.hex", + ] + + if (defined(invoker.gen_asm) && invoker.gen_asm) { + deps += [ ":${target_name}.asm" ] + } + } +} diff --git a/gr551x/hcs/gpio/gpio_config.hcs b/gr551x/hcs/gpio/gpio_config.hcs index 50511cd..6064806 100755 --- a/gr551x/hcs/gpio/gpio_config.hcs +++ b/gr551x/hcs/gpio/gpio_config.hcs @@ -5,7 +5,6 @@ root { configNum = 1; gpioIndex = [0]; pull = [0]; - handleMode = [0]; } } } diff --git a/gr551x/sdk_liteos/BUILD.gn b/gr551x/sdk_liteos/BUILD.gn old mode 100755 new mode 100644 index 952af47..66a8c5c --- a/gr551x/sdk_liteos/BUILD.gn +++ b/gr551x/sdk_liteos/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 @@ -13,12 +13,12 @@ import("//kernel/liteos_m/liteos.gni") -module_name = get_path_info(rebase_path("."), "name") -module_group(module_name) { +module_group("sdk_liteos") { modules = [ - "platform", + "config", "gr551x_sdk", "liteos_m", - "config", + "platform/main", + "platform/system", ] } diff --git a/gr551x/sdk_liteos/config/BUILD.gn b/gr551x/sdk_liteos/config/BUILD.gn old mode 100755 new mode 100644 index f0346dd..60dc829 --- a/gr551x/sdk_liteos/config/BUILD.gn +++ b/gr551x/sdk_liteos/config/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 @@ -17,6 +17,5 @@ config("public") { include_dirs = [ "." ] } -module_name = get_path_info(rebase_path("."), "name") -kernel_module(module_name) { +kernel_module("config") { } diff --git a/gr551x/sdk_liteos/config/custom_config.h b/gr551x/sdk_liteos/config/custom_config.h old mode 100755 new mode 100644 index 64cc69e..1973a7d --- a/gr551x/sdk_liteos/config/custom_config.h +++ b/gr551x/sdk_liteos/config/custom_config.h @@ -47,48 +47,74 @@ // Basic configuration // Chip version -#define GR5515_D +#define SOC_GR5515 // Select chip type -// <0=> GR5515 -// <1=> GR5513 +// <0=> GR5515IGND +// <1=> GR5515IENDU +// <2=> GR5515I0ND +// <3=> GR5515I0NDA +// <4=> GR5515RGBD +// <5=> GR5515GGBD +// <6=> GR5513BEND +// <7=> GR5513BENDU #ifndef CHIP_TYPE -#define CHIP_TYPE 0 +#define CHIP_TYPE 4 #endif +// Platform support sleep function +// <0=> not support +// <1=> support +#ifndef PLAT_SUPPORT_SLEEP +#define PLAT_SUPPORT_SLEEP 1 +#endif + +// Platform support ble function +// <0=> not support +// <1=> support +#ifndef PLAT_SUPPORT_BLE +#define PLAT_SUPPORT_BLE 1 +#endif // Enable encrypt chip // <0=> DISABLE // <1=> ENABLE #ifndef ENCRYPT_ENABLE -#define ENCRYPT_ENABLE 1 +#define ENCRYPT_ENABLE 0 #endif // Enable the external flash of chip // <0=> DISABLE // <1=> ENABLE #ifndef EXT_EXFLASH_ENABLE -#define EXT_EXFLASH_ENABLE 0 +#define EXT_EXFLASH_ENABLE 0 +#endif + +// Enable the platform initialization process +// <0=> DISABLE +// <1=> ENABLE +#ifndef PLATFORM_INIT_ENABLE +#define PLATFORM_INIT_ENABLE 1 #endif // Enable system fault trace module // <0=> DISABLE // <1=> ENABLE #ifndef SYS_FAULT_TRACE_ENABLE -#define SYS_FAULT_TRACE_ENABLE 1 +#define SYS_FAULT_TRACE_ENABLE 1 #endif // Enable APP driver module // <0=> DISABLE // <1=> ENABLE #ifndef APP_DRIVER_USE_ENABLE -#define APP_DRIVER_USE_ENABLE 1 +#define APP_DRIVER_USE_ENABLE 1 #endif // Eanble APP log module // <0=> DISABLE // <1=> ENABLE #ifndef APP_LOG_ENABLE -#define APP_LOG_ENABLE 1 +#define APP_LOG_ENABLE 1 #endif // APP log port type @@ -96,22 +122,22 @@ // <1=> RTT // <2=> ITM #ifndef APP_LOG_PORT -#define APP_LOG_PORT 0 +#define APP_LOG_PORT 0 #endif // Eanble APP log store module // <0=> DISABLE // <1=> ENABLE #ifndef APP_LOG_STORE_ENABLE -#define APP_LOG_STORE_ENABLE 0 +#define APP_LOG_STORE_ENABLE 0 #endif -#if (CHIP_TYPE == 0) +#if (CHIP_TYPE <= 5) // Enable SK GUI module, only available in GR5515 // <0=> DISABLE // <1=> ENABLE #ifndef SK_GUI_ENABLE -#define SK_GUI_ENABLE 1 +#define SK_GUI_ENABLE 1 #endif #endif @@ -119,64 +145,78 @@ // <0=> DISABLE // <1=> ENABLE #ifndef DEBUG_MONITOR -#define DEBUG_MONITOR 0 +#define DEBUG_MONITOR 0 #endif // Enable DTM test support // <0=> DISABLE // <1=> ENABLE #ifndef DTM_TEST_ENABLE -#define DTM_TEST_ENABLE 0 +#define DTM_TEST_ENABLE 0 #endif // Enable BLE DFU support // <0=> DISABLE // <1=> ENABLE #ifndef DFU_ENABLE -#define DFU_ENABLE 1 +#define DFU_ENABLE 1 #endif // Protection priority level // Default: 0 #ifndef FLASH_PROTECT_PRIORITY -#define FLASH_PROTECT_PRIORITY 0 +#define FLASH_PROTECT_PRIORITY 0 #endif // NVDS Start Address // Default: 0x010FF000 #ifndef NVDS_START_ADDR +#if (CHIP_TYPE == 1) || (CHIP_TYPE == 6) || (CHIP_TYPE == 7) +#define NVDS_START_ADDR 0x0107F000 +#else #define NVDS_START_ADDR 0x010FF000 #endif +#endif // The Number of sectors for NVDS // Default: 1 +// Range: 1-16 #ifndef NVDS_NUM_SECTOR -#define NVDS_NUM_SECTOR 1 +#define NVDS_NUM_SECTOR 1 #endif // Call Stack Size // Default: 0x4000 -#ifndef CSTACK_HEAP_SIZE -#define CSTACK_HEAP_SIZE 0x4000 +#ifndef SYSTEM_STACK_SIZE +#define SYSTEM_STACK_SIZE 0x4000 +#endif + +// Call Heap Size +// Default: 0x1000 +#ifndef SYSTEM_HEAP_SIZE +#define SYSTEM_HEAP_SIZE 0x1000 #endif // Enable callstack backtrace function // Default: 0 #ifndef ENABLE_BACKTRACE_FEA -#define ENABLE_BACKTRACE_FEA 0 +#define ENABLE_BACKTRACE_FEA 0 #endif // // Boot info configuration +// Chip version +// Default: 0x00 +#define CHIP_VER 0x5515 // Code load address // Default: 0x01002000 -#define APP_CODE_LOAD_ADDR 0x0100b000 +#define APP_CODE_LOAD_ADDR 0x01002000 // Code run address // Default: 0x01002000 -#define APP_CODE_RUN_ADDR 0x0100b000 +#define APP_CODE_RUN_ADDR 0x01002000 // System clock // <0=> 64MHZ @@ -194,7 +234,15 @@ // Enable internal osc as low power clock // <0=> Default: Disable internal osc as low power clock // <1=> Enable internal osc as low power clock and force CFG_LF_ACCURACY_PPM to 500ppm -#define CFG_LPCLK_INTERNAL_EN 0 +#define CFG_LPCLK_INTERNAL_EN 1 + +// Delay time for Crystal stabilization time +// Default: 100 +// Range: 100-500 +// Note: Set according to actual measurement data +#ifndef CFG_CRYSTAL_DELAY +#define CFG_CRYSTAL_DELAY 100 +#endif // Delay time for Boot startup // <0=> Not Delay @@ -206,9 +254,6 @@ // <1=> Check image #define BOOT_CHECK_IMAGE 1 -// Code version.16bits -#define VERSION 1 - // Delay time between flash wakeup and read chip id in warm boot // Default: 0 // Range: 0-10 @@ -222,53 +267,87 @@ #ifndef EXFLASH_WAKEUP_DELAY #define EXFLASH_WAKEUP_DELAY 0 #endif + // // BLE resource configuration -// Note: The total number of BLE Activities(CONNECTIONS+ADVS+2*PER_ADVS+SYNCS+SCAN) should not exceed the limit 12. +// Note: The total number of BLE Activities(CONNECTIONS+ADVS+SCAN) should not exceed the limit 12. -// Support maximum number of BLE profiles <0-64> -// Range: 0-64 +// Support maximum number of BLE profiles <1-64> +// Range: 1-64 #ifndef CFG_MAX_PRFS -#define CFG_MAX_PRFS 10 +#define CFG_MAX_PRFS 10 #endif -// Support maximum number of bonded devices <0-10> -// Range: 0-10 +// Support maximum number of bonded devices #ifndef CFG_MAX_BOND_DEVS -#define CFG_MAX_BOND_DEVS 4 +#define CFG_MAX_BOND_DEVS 4 #endif -// Support maximum number of BLE Links <0-10> -// Range: 0-10 +// Config scan duplicate filter list number +// Range: 0-50 +#ifndef CFG_SCAN_DUP_FILT_LIST_NUM +#define CFG_SCAN_DUP_FILT_LIST_NUM 10 +#endif + +// Support maximum number of BLE Links <1-10> +// Range: 1-10 #ifndef CFG_MAX_CONNECTIONS -#define CFG_MAX_CONNECTIONS 10 +#define CFG_MAX_CONNECTIONS 5 #endif // Support maximum number of BLE Legacy/Extended Advertisings <0-5> // Range: 0-5 // Note: The total number of BLE Legacy/Extended/Periodic Advertisings should not exceed the limit 5. #ifndef CFG_MAX_ADVS -#define CFG_MAX_ADVS 1 +#define CFG_MAX_ADVS 1 +#endif + +// Support 31 bytes adv data for legacy adv +// <0=> NOT SUPPORT +// <1=> SUPPORT +#ifndef CFG_MAX_ADV_DATA_LEN_SUPPORT +#define CFG_MAX_ADV_DATA_LEN_SUPPORT 0 #endif // Support maximum number of BLE Periodic Advertisings <0-5> // Range: 0-5 // Note: The total number of BLE Legacy/Extended/Periodic Advertisings should not exceed the limit 5. #ifndef CFG_MAX_PER_ADVS -#define CFG_MAX_PER_ADVS 0 +#define CFG_MAX_PER_ADVS 0 #endif // Support maximum number of BLE Periodic Advertising Synchronizations <0-5> // Range: 0-5 #ifndef CFG_MAX_SYNCS -#define CFG_MAX_SYNCS 0 +#define CFG_MAX_SYNCS 0 #endif // Support maximum number of BLE Scan <0-1> // Range: 0-1 #ifndef CFG_MAX_SCAN -#define CFG_MAX_SCAN 1 +#define CFG_MAX_SCAN 1 +#endif + +// support +// <0=> NOT SUPPORT +// <1=> SUPPORT +#ifndef CFG_BT_BREDR +#define CFG_BT_BREDR 0 +#endif + +// Support multiple link with the same device +// <0=> NOT SUPPORT +// <1=> SUPPORT +#ifndef CFG_MUL_LINK_WITH_SAME_DEV +#define CFG_MUL_LINK_WITH_SAME_DEV 0 +#endif + +// support +// <0=> NOT SUPPORT +// <1=> SUPPORT +#ifndef CFG_CAR_KEY_SUPPORT +#define CFG_CAR_KEY_SUPPORT 0 #endif // @@ -277,7 +356,7 @@ // <0=> NOT SUPPORT // <1=> SUPPORT #ifndef CFG_MESH_SUPPORT -#define CFG_MESH_SUPPORT 0 +#define CFG_MESH_SUPPORT 0 #endif // @@ -286,9 +365,18 @@ // <0=> NOT SUPPORT // <1=> SUPPORT #ifndef CFG_LCP_SUPPORT -#define CFG_LCP_SUPPORT 0 +#define CFG_LCP_SUPPORT 0 +#endif +// + +// security configuration +// algorithm security level +// <0=> Enable algorithm level one +// <1=> Enable algorithm level two +#ifndef SECURITY_CFG_VAL +#define SECURITY_CFG_VAL 0 #endif // // <<< end of configuration section >>> -#endif // __CUSTOM_CONFIG_H__ +#endif //__CUSTOM_CONFIG_H__ diff --git a/gr551x/sdk_liteos/config/flash_scatter_config.h b/gr551x/sdk_liteos/config/flash_scatter_config.h old mode 100755 new mode 100644 index 2088ed2..a52f113 --- a/gr551x/sdk_liteos/config/flash_scatter_config.h +++ b/gr551x/sdk_liteos/config/flash_scatter_config.h @@ -1,18 +1,3 @@ -/* - * Copyright (c) 2021 GOODIX. - * Licensed 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. - */ - /** **************************************************************************************** * @@ -24,17 +9,17 @@ **************************************************************************************** */ -#ifndef SCATTER_CONFIG_H -#define SCATTER_CONFIG_H +#ifndef __SCATTER_CONFIG_H__ +#define __SCATTER_CONFIG_H__ #include "custom_config.h" /***************************************************************** - * if CSTACK_HEAP_SIZE is not defined in custom_config.h, + * if SYSTEM_STACK_SIZE is not defined in custom_config.h, * keep default setting to 32KB */ -#ifndef CSTACK_HEAP_SIZE -#define CSTACK_HEAP_SIZE 0x8000 +#ifndef SYSTEM_STACK_SIZE + #define SYSTEM_STACK_SIZE 0x8000 #endif #define FLASH_START_ADDR 0x01000000 @@ -42,7 +27,7 @@ /* size of ROM reserved RAM in retention cell */ #ifndef ROM_RTN_RAM_SIZE -#define ROM_RTN_RAM_SIZE 0x4020 +#define ROM_RTN_RAM_SIZE 0x4100 #endif #define RAM_ALIAS @@ -56,159 +41,42 @@ #define RAM_START_ADDR 0x30000000 #endif -#if (CHIP_TYPE == 0) -#define RAM_SIZE 0x00040000 -#else -#define RAM_SIZE 0x00020000 +#if (CHIP_TYPE == 6) || (CHIP_TYPE == 7) //GR5513 + #define RAM_SIZE 0x00020000 +#else //GR5515 + #define RAM_SIZE 0x00040000 #endif #define RAM_END_ADDR (RAM_START_ADDR + RAM_SIZE) -#define FERP_SIZE 0x8000 // 32K +#define FERP_SIZE 0x8000 //32K #define CRITICAL_CODE_MAX_SIZE 0x10000 // maximum size of critical code reserved #if (APP_CODE_RUN_ADDR == APP_CODE_LOAD_ADDR && \ APP_CODE_RUN_ADDR >= FLASH_START_ADDR && \ APP_CODE_RUN_ADDR < FLASH_START_ADDR + FLASH_SIZE) -#define XIP_MODE + #define XIP_MODE #endif /****************************************************************/ -/* ************************************************************************ - * developer must define CFG_MAX_CONNECTIONS in custom_config.h . - * Max value for GR551X: 10 which must be same with CFG_CON - * in ROM's configs.opt - */ -#ifndef CFG_MAX_CONNECTIONS -#error "CFG_MAX_CONNECTIONS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_CONNECTIONS <= 10) -#define USER_MAX_CONNECTIONS CFG_MAX_CONNECTIONS -#else -#define USER_MAX_CONNECTIONS (1) -#endif - -#ifndef CFG_MAX_ADVS -#error "CFG_MAX_ADVS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_ADVS <= 5) -#define USER_MAX_ADVS CFG_MAX_ADVS -#else -#define USER_MAX_ADVS (1) -#endif - -#ifndef CFG_MAX_PER_ADVS -#error "CFG_MAX_PER_ADVS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_PER_ADVS <= 5) -#define USER_MAX_PER_ADVS CFG_MAX_PER_ADVS -#else -#define USER_MAX_PER_ADVS (0) -#endif - -#if ((USER_MAX_ADVS+USER_MAX_PER_ADVS) > 5) -#error "The number of BLE Legacy/Extended/Periodic Advertising exceeds the limit." -#endif - -#ifndef CFG_MAX_SCAN -#error "CFG_MAX_SCAN is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_SCAN <= 1) -#define USER_MAX_SCAN CFG_MAX_SCAN -#else -#define USER_MAX_SCAN (1) -#endif - -#ifndef CFG_MAX_SYNCS -#error "CFG_MAX_SYNCS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_SYNCS <= 5) -#define USER_MAX_SYNCS CFG_MAX_SYNCS -#else -#define USER_MAX_SYNCS (0) -#endif - -#if ((USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) > 12) -#error "The number of BLE Activities exceeds the limit." -#endif - -#ifndef CFG_MAX_BOND_DEVS -#error "CFG_MAX_BOND_DEVS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_BOND_DEVS <= 10) -#define USER_MAX_BOND_DEVS CFG_MAX_BOND_DEVS -#else -#define USER_MAX_BOND_DEVS (1) -#endif - -#ifndef CFG_MAX_PRFS -#error "CFG_MAX_PRFS is not defined in app's custom_config.h ." -#endif - -#if (CFG_MAX_PRFS <= 64) -#define USER_MAX_PRFS CFG_MAX_PRFS -#else -#define USER_MAX_PRFS (1) -#endif - -/* The macro is used to compute size of the heap block in bytes. */ -#define MEM_HEAP_HEADER (12 / sizeof(uint32_t)) -#define MEM_CALC_HEAP_LEN(len) ((((len) + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) + MEM_HEAP_HEADER) -#define MEM_CALC_HEAP_LEN_IN_BYTES(len) (MEM_CALC_HEAP_LEN(len) * sizeof(uint32_t)) - -#define ENV_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(292 * USER_MAX_CONNECTIONS + \ - 426 * (USER_MAX_CONNECTIONS + USER_MAX_ADVS + \ - 2 * USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) + \ - 600) -/* The size of heap for ATT database depends on the number of attributes in - * profiles. The value can be tuned based on supported profiles. */ -#if (CFG_MESH_SUPPORT == 1) -#include "mesh_stack_config.h" -#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1000 + MESH_HEAP_SIZE_ADD) -#else -#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1024) -#endif - -#define KE_MSG_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1650 * (USER_MAX_SCAN+USER_MAX_SYNCS) + \ - 112 *(USER_MAX_CONNECTIONS + USER_MAX_ADVS + \ - 2*USER_MAX_PER_ADVS) + 408 *(USER_MAX_CONNECTIONS + \ - USER_MAX_ADVS + 2 * USER_MAX_PER_ADVS + \ - USER_MAX_SCAN + USER_MAX_SYNCS)+ 3072) -/* The size of non-retention heap is customized. This heap will used by BLE - * stack only when other three heaps are full. */ -#define NON_RET_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(328 * 2) - -#define PRF_BUF_SIZE (92*USER_MAX_PRFS + 4) -#define BOND_BUF_SIZE (8*USER_MAX_BOND_DEVS + 4) -#define CONN_BUF_SIZE (372*USER_MAX_CONNECTIONS + 4) - - /**************************************************************************/ /* sections on retention RAM cells */ #ifdef CFG_FERP -#define STACK_END_ADDR (RAM_END_ADDR-FERP_SIZE) + #define STACK_END_ADDR (RAM_END_ADDR-FERP_SIZE) #else -#define STACK_END_ADDR (RAM_END_ADDR) + #define STACK_END_ADDR (RAM_END_ADDR) #endif -#ifndef GR5515_E #define USE_TINY_RAM_SPACE -#endif -#define TINY_RAM_SPACE_START (RAM_START_ADDR + 0x35CC) /* DONT MODIFY ME !!! */ +#define TINY_RAM_SPACE_START (0x30000000 + 0x35CC) /* DONT MODIFY ME !!! */ #define TINY_RAM_SPACE_SIZE (0x750) /* DONT MODIFY ME !!! */ #define FPB_SECTION_START 0x30004000 -#define FPB_SECTION_SIZE 0x20 +#define FPB_SECTION_SIZE 0x100 -#define UNUSED_SECTION_SIZE 0x64 +#define RAM_RESERVE_SECTION_SIZE 0x64 // Code size of Application #ifndef APP_MAX_CODE_SIZE @@ -220,4 +88,5 @@ #define APP_RAM_SIZE 0x00030000 #endif -#endif // SCATTER_CONFIG_H +#endif // __SCATTER_CONFIG_H__ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/BUILD.gn index 9ce8bc2..6e22cf2 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/BUILD.gn +++ b/gr551x/sdk_liteos/gr551x_sdk/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 GOODIX. +# Copyright (c) 2024 GOODIX. # Licensed 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 @@ -11,65 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This BUILD.gn is used to compile the SDK source code of Goodix GR551x SOC. -# In this script, optionally add source code compilation. If the SDK is upgraded, -# you can directly replace components, drivers, and toolchain folders. - import("//kernel/liteos_m/liteos.gni") -config("public") { - include_dirs = [ - "components/app_drivers/inc", - "components/boards", - "components/drivers_ext/gr551x", - "components/libraries/app_lfs", - "components/libraries/app_assert", - "components/libraries/app_error", - "components/libraries/app_log", - "components/libraries/app_timer", - "components/libraries/hal_flash", - "components/libraries/pmu_calibration", - "components/libraries/ring_buffer", - "components/libraries/utility", - "components/patch/ind", - "components/sdk/", - "drivers/inc", - "toolchain/gr551x/include", - ] -} - -kernel_module("gr551x_sdk") { - sources = [ - "components/app_drivers/src/app_dma.c", - "components/app_drivers/src/app_gpiote.c", - "components/app_drivers/src/app_i2c.c", - "components/app_drivers/src/app_io.c", - "components/app_drivers/src/app_pwm.c", - "components/app_drivers/src/app_pwr_mgmt.c", - "components/app_drivers/src/app_rng.c", - "components/app_drivers/src/app_systick.c", - "components/app_drivers/src/app_uart.c", - "components/libraries/app_assert/app_assert.c", - "components/libraries/app_error/app_error.c", - "components/libraries/app_log/app_log.c", - "components/libraries/app_timer/app_timer.c", - "components/libraries/pmu_calibration/pmu_calibration.c", - "components/libraries/ring_buffer/ring_buffer.c", - "components/libraries/utility/utility.c", - "drivers/src/gr55xx_hal.c", - "drivers/src/gr55xx_hal_adc.c", - "drivers/src/gr55xx_hal_aon_gpio.c", - "drivers/src/gr55xx_hal_aon_wdt.c", - "drivers/src/gr55xx_hal_calendar.c", - "drivers/src/gr55xx_hal_exflash.c", - "drivers/src/gr55xx_hal_gpio.c", - "drivers/src/gr55xx_hal_i2c.c", - "drivers/src/gr55xx_hal_pwm.c", - "drivers/src/gr55xx_hal_pwr.c", - "drivers/src/gr55xx_hal_rng.c", - "drivers/src/gr55xx_hal_uart.c", - "toolchain/gr551x/source/interrupt_gr55xx.c", - "toolchain/gr551x/source/platform_gr55xx.c", - "toolchain/gr551x/source/system_gr55xx.c", +module_group("gr551x_sdk") { + modules = [ + "drivers", + "components", + "platform", + "external/segger_rtt", ] } diff --git a/gr551x/sdk_liteos/gr551x_sdk/README.md b/gr551x/sdk_liteos/gr551x_sdk/README.md new file mode 100644 index 0000000..c431068 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/README.md @@ -0,0 +1,127 @@ +# GR551x Series SoC + +## 1. Introduction + +- The Goodix GR551x family is a single-mode, low-power Bluetooth 5.1 System-on-Chip (SoC). It can be configured as a Broadcaster, an Observer, a Central, a Peripheral, and supports the combination of all the above roles, making it an ideal choice for Internet of Things (IoT) and smart wearable devices. + +- Based on ARM® Cortex®-M4F CPU core, the GR551x integrates Bluetooth 5.1 Protocol Stack, a 2.4 GHz RF transceiver, on-chip programmable Flash memory, RAM, and multiple peripherals. + +- The [GR551x SDK](https://www.goodix.com/en/software_tool/gr551x_sdk) is the software development kit for the GR551x SoC, offering a complete solution that integrates the protocol stacks, application samples and hardware drivers. + + + +## 2. Key Features + +- Bluetooth 5.1 transceiver integrates Controller and Host layers + - Support these data transmission rates: 1 Mbps, 2 Mbps, LR (500 kbps, 125 kbps) + - TX power: -20 dBm ~ +7 dBm + - -96 dBm reception sensitivity (under the 1 Mbps mode) + - -93 dBm reception sensitivity (under the 2 Mbps mode) + - -99 dBm reception sensitivity (under the LR 500 kbps mode) + - -102 dBm reception sensitivity (under the LR 125 kbps mode) + - TX current: 5.6 mA @ 0 dBm,1 Mbps + - RX current: 4.8 mA @ 1 Mbps +- Built-in ARM® Cortex®-M4F 32-bit micro-processor, supporting floating-point operation + - Maximum frequency: 64 MHz + - Power consumption: 51 μA/MHz +- Memory + - Flash Configurations for GR5515 series + - GR5515I0NDA: no embedded Flash + - GR5515IENDU: embedded with 512 KB Flash + - All other SoCs: embedded with 1 MB flash + - Flash Configurations for GR5513 series + - GR5513 series: embedded with 512 KB Flash +- Power Management + - On-chip DC-DC Converter + - On-chip I/O LDO to provide I/O voltage and supply external components + - Supply voltage: 2.2 V to 3.8 V + - I/O voltage: 1.8 V to 3.3 V + - OFF mode: 0.15 µA (Typical), chip in reset + - Ultra deep sleep mode: 1.8 µA (Typical), no memory retention + - Sleep mode: 2.7 µA (Typical), 256 KB memory retention + +- Peripherals + - 2 QSPI interfaces, up to 32 MHz + - 2 SPI interfaces (1 SPI Master Interface with 2 Slave CS pins + 1 SPI Slave Interface), up to 32 MHz + - 2 I2C interfaces (Supports 100 kHz, 400 kHz, 1 MHz, 2 MHz) + - 2 I2S interfaces (1 I2S Master Interface + 1 I2S Slave Interface) + - 2 UART interfaces (One with DMA channel) + - 13-bit ADC, up to 1 Msps, 8 channels (5 external test channels and 3 internal signal channels), supporting both single-ended and differential inputs + - ISO 7816 interface + - Two PWM modules with edge alignment mode and center alignment mode, each with three channels + - Built-in temperature and voltage sensors + - 2 general-purpose, 32-bit timer modules + - 1 dual timer module composed of two programmable 32-bit or 16-bit down counters + - 1 AON hardware timer + - 2 watchdog timers (one for the system and one is always-on) + - 1 real-time counter (RTC), can be used as Calendar + - Wake-up comparator + - Supports up to 39 multiplexed GPIO pins +- Security + - Complete secure computing engine: + - AES 128-bit/192-bit/256-bit encryption (ECB and CBC) + - Keyed Hash Message Authentication Code(HMAC) + - PKC + - TRNG + - Comprehensive security operation mechanism: + - Secure boot + - Encrypted firmware runs directly from Flash + - Fuse for encrypted key storage + - Differentiate application data key and firmware key, supporting one data per device/product +- Packages + - QFN56: 7 mm * 7 mm * 0.75 mm, 0.40 mm pitch + - BGA68: 5.3 mm * 5.3 mm * 0.88 mm , 0.50 mm pitch + - BGA55: 3.5 mm * 3.5 mm * 0.60 mm, 0.40 mm pitch + - QFN40: 5 mm * 5 mm * 0.75 mm, 0.40 mm pitch +- Operating temperature range: -40°C to +85°C + + + +## 3. Production Details + +| | | GR5515IGND | GR5515I0NDA | GR5515IENDU | GR5515GGBD | GR5515RGBD | GR5513BENDU | +| --------------------- | ------------------ | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| Status | | Active | Active | Active | Active | Active | Active | +| Protocol | Bluetooth LE [1] | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 | +| | Bluetooth Mesh | ◠| ◠| ◠| ◠| ◠| ◠| +| Core System | CPU | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | Cortex®-M4F | +| | Clocks | 64 MHz / 32K Hz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | 64 MHz / 32 KHz | +| | Cache | 8 KB | 8 KB | 8 KB | 8 KB | 8 KB | 8 KB | +| | RAM | 256 KB | 256 KB | 256 KB | 256 KB | 256 KB | 128 KB | +| | OTP | | | | | | | +| | Flash | 1 MB | External Flash | 512 KB | 1 MB | 1 MB | 512 KB | +| Security | Root of Trust | ◠| ◠| ◠| ◠| ◠| ◠| +| | Secure Key Store | 4 | 4 | 4 | 4 | 4 | 4 | +| | PKC | ◠| ◠| ◠| ◠| ◠| ◠| +| | RSA | ◠| ◠| ◠| ◠| ◠| ◠| +| | AES | ◠| ◠| ◠| ◠| ◠| ◠| +| | ECC | ◠| ◠| ◠| ◠| ◠| ◠| +| | TRNG | ◠| ◠| ◠| ◠| ◠| ◠| +| Radio | Frequency | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz | 2.4 GHz | +| | Maximum Tx Power | 7 dBm | 7 dBm | 7 dBm | 7 dBm | 7 dBm | 7 dBm | +| | Rx Sensitivity | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | -96 dBm(@1Mbps) | +| Peripheral | UART | 2 | 2 | 2 | 2 | 2 | 2 | +| | SPI | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | 1 * SPIM / 1 * SPIS | +| | I2C | 2 | 2 | 2 | 2 | 2 | 2 | +| | QSPI | 2 | 2 | 2 | 0 | 2 | 1 | +| | Timers | 4 | 4 | 4 | 4 | 4 | 4 | +| | PWM | 2 | 2 | 2 | 2 | 2 | 2 | +| | RTC | 1 | 1 | 1 | 1 | 1 | 1 | +| | I2S | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | 1 * I2SM / 1 * I2SS | +| | ADC | 13-bit | 13-bit | 13-bit | 13-bit | 13-bit | 13-bit | +| | Comparator | ◠| ◠| ◠| ◠| ◠| ◠| +| | Temperature Sensor | ◠| ◠| ◠| ◠| ◠| ◠| +| | GPIO | 39 | 39 | 39 | 29 | 39 | 22 | +| Packages | Type | QFN56 | QFN56 | QFN56 | BGA55 | BGA68 | QFN40 | +| | Dimensions | 7.0 * 7.0 mm | 7.0 * 7.0 mm | 7.0 * 7.0 mm | 3.5 *3.5 mm | 5.3 * 5.3 mm | 5.0 * 5.0 mm | +| Certification | | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | PSA Level 1 SIG BQB (QDID: 119449) | +| Operating Temperature | | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | -40℃ - 85℃ | +| Supply Voltage Range | | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | 2.2 V - 3.8 V | +| Development Kits | | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | GR5515 Starter Kit | + + + +## 4. Change Log + +- Click to view the [change log](../../wiki/Change-Notes-for-GR551x) + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/BUILD.gn new file mode 100644 index 0000000..29636ad --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +module_group("components") { + modules = [ + "libraries", + "profiles", + "sdk", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_measure_mux_signal_api.c b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_measure_mux_signal_api.c new file mode 100644 index 0000000..28bd87d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_measure_mux_signal_api.c @@ -0,0 +1,140 @@ +/** + **************************************************************************************** + * + * @file gr55xx_measure_mux_signal_api.c + * + * @brief GR55XX MUX module. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "grx_hal.h" +#include "grx_sys.h" +#include "gr55xx_measure_mux_signal_api.h" + +/* Private macros ------------------------------------------------------------*/ +#define ADC_INPUT_SRC_MUX (0x0D) +#define MAX_SIMPLE_POINTS (4096) + +/* + * GLOBAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +/* + * STATIC VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static adc_handle_t gr55xx_snsadc_handle = {0}; +static double adc_offset = 0; +static double adc_slope = 0; + +static gr55xx_set_signal_to_mux(gr55xx_mux_signal_t my_mux_signal) +{ +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void gr55xx_mux_signal_measurement_init(void); +{ + adc_trim_info_t adc_trim = {0}; + + gr55xx_snsadc_handle.init.channel_n = ADC_INPUT_SRC_REF; + gr55xx_snsadc_handle.init.channel_p = ADC_INPUT_SRC_MUX; + gr55xx_snsadc_handle.init.input_mode = ADC_INPUT_DIFFERENTIAL; + gr55xx_snsadc_handle.init.ref_source = ADC_REF_SRC_BUF_INT; + gr55xx_snsadc_handle.init.ref_value = ADC_REF_VALUE_0P8; +#if !defined(GR55XXx) + gr55xx_snsadc_handle.init.clock = ADC_CLK_1M; +#else + gr55xx_snsadc_handle.init.clock = ADC_CLK_1P6M; +#endif + hal_adc_init(&gr55xx_snsadc_handle); + + if(SDK_SUCCESS == sys_adc_trim_get(&adc_trim)) + { + adc_offset = (double)adc_trim.offset_int_0p8; + adc_slope = (-1) * (double)adc_trim.slope_int_0p8; + } + else + { + adc_offset = 8362; + adc_slope = -4754; + } + return; +} + +double gr55xx_mux_signal_measure_average(gr55xx_mux_signal_t my_mux_signal); +{ + uint16_t conver_buff[16] = {0}; + uint16_t average = 0; + double test_result; + + /* Set the fixed signal to Mux*/ + gr55xx_set_signal_to_mux(my_mux_signal); + + /* Get the average of mux signal */ + hal_adc_poll_for_conversion(&gr55xx_snsadc_handle, conver_buff, 16); + for(uint8_t i = 0; i < 8; i++) + { + average += conver_buff[8 + i]; + } + average = average >> 3; + test_result = (((double)average - adc_offset) / adc_slope); + + test_result = test_result + 0.85; + + return test_result; +} + +void gr55xx_mux_signal_measure_n_points(gr55xx_mux_signal_t my_mux_signal, uint32_t num, double* result_buf) +{ + uint16_t conver_buff[MAX_SIMPLE_POINTS] = {0}; + double test_result; + + /* Set the fixed signal to Mux*/ + gr55xx_set_signal_to_mux(my_mux_signal); + + /* Get the average of mux signal */ + memset(&conver_buff[0], 0, 2*MAX_SIMPLE_POINTS); + hal_adc_poll_for_conversion(&gr55xx_snsadc_handle, conver_buff, num); + for(uint32_t i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief gr55xx mux signals definition + */ +typedef enum +{ + /**< MUX signal of LPD block. */ + GR55XX_MUX_SIGNAL_LPD_RESET = 0x00U, + GR55XX_MUX_SIGNAL_LPD_POR_RST, + GR55XX_MUX_SIGNAL_LPD_VDD_RC, + GR55XX_MUX_SIGNAL_LPD_POC, + GR55XX_MUX_SIGNAL_LPD_SRPG_BIAS, + GR55XX_MUX_SIGNAL_LPD_RET_BIAS, + GR55XX_MUX_SIGNAL_LPD_PMU_BOD, + GR55XX_MUX_SIGNAL_LPD_VDDC_AON, + /**< MUX signal of SensADC block. */ + GR55XX_MUX_SIGNAL_SNSADC_VREF, + + /**< MUX signal of VDMs block. */ + GR55XX_MUX_SIGNAL_VDM_0, + + /**< MUX signal of PD cores block. */ + GR55XX_MUX_SIGNAL_PD_SRON, + + /**< MUX signal of EFUSE block. */ + GR55XX_MUX_SIGNAL_EFUSE_25V, + + /**< MUX signal of Clock block. */ + GR55XX_MUX_SIGNAL_CLOCK_FS_750K, + + /**< MUX signal of LDO block. */ + GR55XX_MUX_SIGNAL_LDO_VIO, + + /**< MUX signal of DCDC block. */ + GR55XX_MUX_SIGNAL_DCDC_BATT_CMP, + + GR55XX_MUX_SIGNAL_MAX, +}gr55xx_mux_signal_t; + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize mux signal measurement modul. + * + **************************************************************************************** + */ +void gr55xx_mux_signal_measurement_init(void); + +/** + **************************************************************************************** + * @brief Get the average value of mux signal input + * + * @return The volatge of mux signal. Unit (volt). + **************************************************************************************** + */ +double gr55xx_mux_signal_measure_average(gr55xx_mux_signal_t my_mux_signal); + +/** + **************************************************************************************** + * @brief Get num points value of mux signal input, num cannot over 4096 + * + * @return The volatge of num points value of mux signal. Unit (volt). + **************************************************************************************** + */ +void gr55xx_mux_signal_measure_n_points(gr55xx_mux_signal_t my_mux_signal, uint32_t num, double* result_buf); + +#ifdef __cplusplus +} +#endif + +#endif // __GR55XX_MEASURE_MUX_API_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.c b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.c new file mode 100644 index 0000000..52851bf --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.c @@ -0,0 +1,863 @@ +/** + **************************************************************************************** + * @file gr55xx_spi_flash.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "grx_hal.h" +#include "gr55xx_spi_flash.h" + + +#define SSI_HIGH_FREQ_CLOCK_PRESCALER 4u + +#define SSI_LOW_FREQ_CLOCK_PRESCALER 8u + +/* + * SPI Master DEFINES + ***************************************************************************************** + */ +#define SPI_CLOCK_PRESCALER 8u /* The SPI CLOCK Freq = Peripheral CLK/SPI_CLOCK_PRESCALER */ +#define SPI_SOFT_CS_MODE_ENABLE 1u /* suggest to enable SOFT CS MODE */ +#define SPI_WAIT_TIMEOUT_MS 1500u /* default time(ms) for wait operation */ + +#if SPI_CLOCK_PRESCALER == 2u + #define SPI_RX_SAMPLE_DELAY 1u +#else + #define SPI_RX_SAMPLE_DELAY 0u +#endif + +/* master spi parameters */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) //pin configuration should be specified in the input of spi_flash_init +#define MASTER_SPI_PIN_CONFIG {{APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_9, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_6, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_7, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOB, APP_IO_MUX_3, APP_IO_PIN_8, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE}} +#else +#define MASTER_SPI_PIN_CONFIG {{APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_15, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_12, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_13, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE},\ + {APP_IO_TYPE_GPIOA, APP_IO_MUX_1, APP_IO_PIN_14, APP_IO_MODE_MUX, APP_IO_PULLUP, APP_SPI_PIN_ENABLE}} +#endif +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +#define MASTER_SPI_MODE_CONFIG {DMA0, DMA0, DMA_Channel0, DMA_Channel1, SPI_WAIT_TIMEOUT_MS, 0} +#define MASTER_SPI_CONFIG {SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, \ + SPI_CLOCK_PRESCALER, SPI_TIMODE_DISABLE, SPI_SLAVE_SELECT_0, SPI_RX_SAMPLE_DELAY} +#else +#define MASTER_SPI_MODE_CONFIG {DMA, DMA, DMA_Channel0, DMA_Channel1} +#define MASTER_SPI_CONFIG {SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, SPI_PHASE_1EDGE, \ + SPI_CLOCK_PRESCALER, SPI_TIMODE_DISABLE, SPI_SLAVE_SELECT_0} +#endif + +#define MASTER_SPI_PARAM_CONFIG {APP_SPI_ID_MASTER, MASTER_SPI_PIN_CONFIG, MASTER_SPI_MODE_CONFIG, MASTER_SPI_CONFIG, SPI_SOFT_CS_MODE_ENABLE} + +/* + * QSPI DEFINES + ***************************************************************************************** + */ +/***************************************** + * CHANGE FOLLOWING SETTINGS By YOUR CASE ! + *****************************************/ + +#define QSPI_CLOCK_PRESCALER 8u /* The QSPI CLOCK Freq = Peripheral CLK/QSPI_CLOCK_PRESCALER */ +#define QSPI_WAIT_TIMEOUT_MS 1500u /* default time(ms) for wait operation */ +#define QSPI_ID APP_QSPI_ID_0 +#define QSPI_TIMING_MODE QSPI_CLOCK_MODE_0 + +/***************************************** + * CHANGE FOLLOWING SETTINGS CAREFULLY ! + *****************************************/ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#if QSPI_ID == APP_QSPI_ID_0 + #define QSPI_USED_DMA DMA0 + #define QSPI_USED_DMA_CH DMA_Channel0 +#elif QSPI_ID == APP_QSPI_ID_1 + #define QSPI_USED_DMA DMA0 + #define QSPI_USED_DMA_CH DMA_Channel1 +#else + #define QSPI_USED_DMA DMA1 + #define QSPI_USED_DMA_CH DMA_Channel0 +#endif +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + #define QSPI_USED_DMA DMA + #define QSPI_USED_DMA_CH DMA_Channel7 +#endif + + +#if QSPI_CLOCK_PRESCALER == 2u + #define QSPI_RX_SAMPLE_DELAY 1u +#else + #define QSPI_RX_SAMPLE_DELAY 0u +#endif +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static volatile qspi_control_t g_qspi_ctl; +static flash_init_t g_flash_init; +static app_spi_params_t spim_params = MASTER_SPI_PARAM_CONFIG; +static app_qspi_params_t qspi_params; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void spi_app_spim_callback(app_spi_evt_t *p_evt) +{ + if (p_evt->type == APP_SPI_EVT_TX_CPLT) + { + g_qspi_ctl.spi_tmt_done = 1; + } + if (p_evt->type == APP_SPI_EVT_RX_CPLT) + { + g_qspi_ctl.spi_rcv_done = 1; + } + if (p_evt->type == APP_SPI_EVT_TX_RX_CPLT) + { + g_qspi_ctl.spi_tx_rx_done = 1; + } + if (p_evt->type == APP_SPI_EVT_ERROR) + { + g_qspi_ctl.spi_tmt_done = 1; + g_qspi_ctl.spi_rcv_done = 1; + g_qspi_ctl.spi_tx_rx_done = 1; + printf("spi error event!!"); + } +} + +static void app_qspi_callback(app_qspi_evt_t *p_evt) +{ + if (p_evt->type == APP_QSPI_EVT_TX_CPLT) + { + g_qspi_ctl.qspi_tmt_done = 1; + } + if (p_evt->type == APP_QSPI_EVT_RX_DATA) + { + g_qspi_ctl.qspi_rcv_done = 1; + } + if (p_evt->type == APP_QSPI_EVT_ERROR) + { + g_qspi_ctl.qspi_tmt_done = 1; + g_qspi_ctl.qspi_rcv_done = 1; + printf("QSPI error event!!"); + } +} + +static void spi_flash_write_enable(void) +{ + uint8_t control_frame[1] = {SPI_FLASH_CMD_WREN}; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + g_qspi_ctl.spi_tmt_done = 0; + app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.spi_tmt_done == 0); + } + else + { + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_WREN, + .address = 0, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_00_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = 0, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_tmt_done = 0; + app_qspi_dma_command_async(g_qspi_ctl.qspi_id, &command); + while(g_qspi_ctl.qspi_tmt_done == 0); + } + + return; +} + +static uint8_t spi_flash_read_status(void) +{ + uint8_t status = 0; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + uint8_t cmd = SPI_FLASH_CMD_RDSR; + + g_qspi_ctl.spi_tx_rx_done = 0; + app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, &cmd, &status, 1, 1); + while(g_qspi_ctl.spi_tx_rx_done == 0); + } + else + { + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_RDSR, + .address = 0, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_00_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = 1, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + g_qspi_ctl.qspi_rcv_done = 0; + app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &status); + while(g_qspi_ctl.qspi_rcv_done == 0); + } + + return status; +} + +static uint32_t spi_flash_device_size(void) +{ + uint32_t flash_size = 0; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + uint8_t data[5] = {0}; + uint8_t control_frame[5] = {SPI_FLASH_CMD_SFUD, 0, 0, 0x34, DUMMY_BYTE}; + + g_qspi_ctl.spi_tx_rx_done = 0; + app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, data, 5, 5); + while(g_qspi_ctl.spi_tx_rx_done == 0); + + if (data[0] != 0 && data[3] < 0xFF) + { + flash_size = ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) + (data[0] << 0) + 1) / 8; + } + } + else + { + uint8_t data[4] = {0}; + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_SFUD, // SPI_FLASH_CMD_SFUD //SPI_FLASH_CMD_RDSR + .address = 0x000034, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_24_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 8, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = sizeof(data), +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_rcv_done = 0; + app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &data[0]); + while(g_qspi_ctl.qspi_rcv_done == 0); + + if (data[0] != 0 && data[3] < 0xFF) + { + flash_size = ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) + (data[0] << 0) + 1) / 8; + } + } + + return flash_size; +} + + +static uint32_t spim_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + g_qspi_ctl.spi_tmt_done = 0; + app_spim_dma_transmit_with_ia(g_qspi_ctl.spi_id, SPI_FLASH_CMD_PP, address, buffer, nbytes); + while(g_qspi_ctl.spi_tmt_done == 0); + + return nbytes; +} + +static uint32_t qspi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t ret; + + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_PP, + .address = address, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_24_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = nbytes, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_tmt_done = 0; + ret = app_qspi_dma_command_transmit_async(g_qspi_ctl.qspi_id, &command, buffer); + if(ret == APP_DRV_SUCCESS) + { + while(g_qspi_ctl.qspi_tmt_done == 0); + return nbytes; + } + else + { + return 0; + } +} + +static uint32_t qspi_flash_dual_write(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t ret; + + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_DPP, + .address = address, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_24_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_DUALSPI, + .length = nbytes, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_tmt_done = 0; + ret = app_qspi_dma_command_transmit_async(g_qspi_ctl.qspi_id, &command, buffer); + if(ret == APP_DRV_SUCCESS) + { + while(g_qspi_ctl.qspi_tmt_done == 0); + return nbytes; + } + else + { + return 0; + } +} + +static uint32_t spim_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint8_t control_frame[4] = {0}; + + control_frame[0] = SPI_FLASH_CMD_READ; + control_frame[1] = (address >> 16) & 0xFF; + control_frame[2] = (address >> 8) & 0xFF; + control_frame[3] = address & 0xFF; + + g_qspi_ctl.spi_tx_rx_done = 0; + app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, buffer, 4, nbytes); + while(g_qspi_ctl.spi_tx_rx_done == 0); + + return nbytes; +} + +static uint32_t qspi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t ret ; + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_READ, + .address = address, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_24_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = nbytes, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_rcv_done = 0; + ret = app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &buffer[0]); + if(ret == APP_DRV_SUCCESS) + { + while(g_qspi_ctl.qspi_rcv_done == 0); + return nbytes; + } + else + { + return 0; + } +} + +static uint32_t qspi_flash_dual_read(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t ret ; + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_DREAD, + .address = address, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_24_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 8, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_DUALSPI, + .length = nbytes, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + + g_qspi_ctl.qspi_rcv_done = 0; + ret = app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, &buffer[0]); + if(ret == APP_DRV_SUCCESS) + { + while(g_qspi_ctl.qspi_rcv_done == 0); + return nbytes; + } + else + { + return 0; + } +} + +bool spim_flash_sector_erase(uint32_t address) +{ + uint8_t control_frame[4] = {0}; + uint32_t ret ; + + control_frame[0] = SPI_FLASH_CMD_SE; + control_frame[1] = (address >> 16) & 0xFF; + control_frame[2] = (address >> 8) & 0xFF; + control_frame[3] = address & 0xFF; + + g_qspi_ctl.spi_tmt_done = 0; + ret = app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.spi_tmt_done == 0); + + return (ret == APP_DRV_SUCCESS) ? true : false; +} + +bool qspi_flash_sector_erase(uint32_t address) +{ + uint32_t ret; + uint8_t control_frame[4] = {0}; + + control_frame[0] = SPI_FLASH_CMD_SE; + control_frame[1] = (address >> 16) & 0xFF; + control_frame[2] = (address >> 8) & 0xFF; + control_frame[3] = address & 0xFF; + + g_qspi_ctl.qspi_tmt_done = 0; + ret = app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame)); + if(ret == APP_DRV_SUCCESS) + { + while(g_qspi_ctl.qspi_tmt_done == 0); + return true; + } + else + { + return false; + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void spi_flash_init(flash_init_t *p_flash_init) +{ + uint16_t ret; + + memcpy(&g_flash_init, p_flash_init, sizeof(flash_init_t)); + + if (FLASH_SPIM_ID == p_flash_init->spi_type) + { + if(p_flash_init->is_high_freq) { + spim_params.init.baudrate_prescaler = SSI_HIGH_FREQ_CLOCK_PRESCALER; + } else { + spim_params.init.baudrate_prescaler = SSI_LOW_FREQ_CLOCK_PRESCALER; + } + + spim_params.pin_cfg.cs.type = p_flash_init->flash_io.spi_cs.gpio; + spim_params.pin_cfg.cs.pin = p_flash_init->flash_io.spi_cs.pin; + spim_params.pin_cfg.cs.mux = p_flash_init->flash_io.spi_cs.mux; + + spim_params.pin_cfg.clk.type = p_flash_init->flash_io.spi_clk.gpio; + spim_params.pin_cfg.clk.pin = p_flash_init->flash_io.spi_clk.pin; + spim_params.pin_cfg.clk.mux = p_flash_init->flash_io.spi_clk.mux; + + spim_params.pin_cfg.mosi.type = p_flash_init->flash_io.spi_io0.qspi_io0.gpio; + spim_params.pin_cfg.mosi.pin = p_flash_init->flash_io.spi_io0.qspi_io0.pin; + spim_params.pin_cfg.mosi.mux = p_flash_init->flash_io.spi_io0.qspi_io0.mux; + + spim_params.pin_cfg.miso.type = p_flash_init->flash_io.spi_io1.qspi_io1.gpio; + spim_params.pin_cfg.miso.pin = p_flash_init->flash_io.spi_io1.qspi_io1.pin; + spim_params.pin_cfg.miso.mux = p_flash_init->flash_io.spi_io1.qspi_io1.mux; + + g_qspi_ctl.spi_id = APP_SPI_ID_MASTER; + spim_params.id = APP_SPI_ID_MASTER; + + app_spi_deinit(g_qspi_ctl.spi_id); + ret = app_spi_init(&spim_params, spi_app_spim_callback); + if (ret != 0) + { + printf("SPI master initial failed! Please check the input paraments.\r\n"); + return; + } + ret = app_spi_dma_init(&spim_params); + if (ret != 0) + { + printf("SPI master dma initial failed! Please check the input paraments.\r\n"); + return; + } + } + else if ((FLASH_QSPI_ID0 == p_flash_init->spi_type) + ||(FLASH_QSPI_ID1 == p_flash_init->spi_type) +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + || (FLASH_QSPI_ID2 == p_flash_init->spi_type) +#endif + ) + { + if(FLASH_QSPI_ID0 == p_flash_init->spi_type){ + g_qspi_ctl.qspi_id = APP_QSPI_ID_0; + } else if(FLASH_QSPI_ID1 == p_flash_init->spi_type){ + g_qspi_ctl.qspi_id = APP_QSPI_ID_1; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + } else { + g_qspi_ctl.qspi_id = APP_QSPI_ID_2; +#endif + } + + if(p_flash_init->is_high_freq) { + qspi_params.init.clock_prescaler = SSI_HIGH_FREQ_CLOCK_PRESCALER; + } else { + qspi_params.init.clock_prescaler = SSI_LOW_FREQ_CLOCK_PRESCALER; + } + + qspi_params.init.clock_mode = QSPI_TIMING_MODE; + if(qspi_params.init.clock_prescaler == 2) + { + qspi_params.init.rx_sample_delay = 1; + } + else + { + qspi_params.init.rx_sample_delay = 0; + } + + qspi_params.id = g_qspi_ctl.qspi_id; + qspi_params.pin_cfg.cs.type = p_flash_init->flash_io.spi_cs.gpio; + qspi_params.pin_cfg.cs.pin = p_flash_init->flash_io.spi_cs.pin; + qspi_params.pin_cfg.cs.mux = p_flash_init->flash_io.spi_cs.mux; + qspi_params.pin_cfg.cs.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.cs.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.cs.enable = APP_QSPI_PIN_ENABLE; + qspi_params.pin_cfg.clk.type = p_flash_init->flash_io.spi_clk.gpio; + qspi_params.pin_cfg.clk.pin = p_flash_init->flash_io.spi_clk.pin; + qspi_params.pin_cfg.clk.mux = p_flash_init->flash_io.spi_clk.mux; + qspi_params.pin_cfg.clk.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.clk.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.clk.enable = APP_QSPI_PIN_ENABLE; + qspi_params.pin_cfg.io_0.type = p_flash_init->flash_io.spi_io0.qspi_io0.gpio; + qspi_params.pin_cfg.io_0.pin = p_flash_init->flash_io.spi_io0.qspi_io0.pin; + qspi_params.pin_cfg.io_0.mux = p_flash_init->flash_io.spi_io0.qspi_io0.mux; + qspi_params.pin_cfg.io_0.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.io_0.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.io_0.enable = APP_QSPI_PIN_ENABLE; + qspi_params.pin_cfg.io_1.type = p_flash_init->flash_io.spi_io1.qspi_io1.gpio; + qspi_params.pin_cfg.io_1.pin = p_flash_init->flash_io.spi_io1.qspi_io1.pin; + qspi_params.pin_cfg.io_1.mux = p_flash_init->flash_io.spi_io1.qspi_io1.mux; + qspi_params.pin_cfg.io_1.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.io_1.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.io_1.enable = APP_QSPI_PIN_ENABLE; + qspi_params.pin_cfg.io_2.type = p_flash_init->flash_io.qspi_io2.gpio; + qspi_params.pin_cfg.io_2.pin = p_flash_init->flash_io.qspi_io2.pin; + qspi_params.pin_cfg.io_2.mux = p_flash_init->flash_io.qspi_io2.mux; + qspi_params.pin_cfg.io_2.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.io_2.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.io_2.enable = APP_QSPI_PIN_ENABLE; + qspi_params.pin_cfg.io_3.type = p_flash_init->flash_io.qspi_io3.gpio; + qspi_params.pin_cfg.io_3.pin = p_flash_init->flash_io.qspi_io3.pin; + qspi_params.pin_cfg.io_3.mux = p_flash_init->flash_io.qspi_io3.mux; + qspi_params.pin_cfg.io_3.mode = APP_IO_MODE_MUX; + qspi_params.pin_cfg.io_3.pull = APP_IO_PULLUP; + qspi_params.pin_cfg.io_3.enable = APP_QSPI_PIN_ENABLE; + + qspi_params.dma_cfg.dma_instance = QSPI_USED_DMA; + qspi_params.dma_cfg.dma_channel = QSPI_USED_DMA_CH; + + app_qspi_dma_deinit(g_qspi_ctl.qspi_id); + app_qspi_deinit(g_qspi_ctl.qspi_id); + ret = app_qspi_init(&qspi_params, app_qspi_callback); + if (ret != 0) + { + printf("QSPI initial failed! Please check the input paraments."); + return ; + } + ret = app_qspi_dma_init(&qspi_params); + if (ret != 0) + { + printf("QSPI initial dma failed! Please check the input paraments."); + return ; + } + + //set qspi hold/wp pin to high + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pull = APP_IO_PULLUP; + io_init.pin = qspi_params.pin_cfg.io_2.pin; + io_init.mux = APP_IO_MUX; + app_io_init(qspi_params.pin_cfg.io_2.type, &io_init); + + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pull = APP_IO_PULLUP; + io_init.pin = qspi_params.pin_cfg.io_3.pin; + io_init.mux = APP_IO_MUX; + app_io_init(qspi_params.pin_cfg.io_3.type , &io_init); + + app_io_write_pin(qspi_params.pin_cfg.io_2.type, qspi_params.pin_cfg.io_2.pin, APP_IO_PIN_SET); + app_io_write_pin(qspi_params.pin_cfg.io_3.type, qspi_params.pin_cfg.io_3.pin, APP_IO_PIN_SET); + } + + return; +} + +uint32_t spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t page_ofs, write_size, write_cont = nbytes; + hal_status_t status = HAL_OK; + + while (write_cont) + { + page_ofs = address & 0xFF; + write_size = EXFLASH_SIZE_PAGE_BYTES - page_ofs; + + if (write_cont < write_size) + { + write_size = write_cont; + write_cont = 0; + } + else + { + write_cont -= write_size; + } + + spi_flash_write_enable(); + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + spim_flash_write(address, buffer, write_size); + } + else + { + if(g_flash_init.is_dual_line) { + qspi_flash_dual_write(address, buffer, write_size); + } else { + qspi_flash_write(address, buffer, write_size); + } + } + + while(spi_flash_read_status() & 0x1); + + address += write_size; + buffer += write_size; + } + + return ((status == HAL_OK) ? nbytes : 0); +} + +uint32_t spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + uint32_t count = 0; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + count = spim_flash_read(address, buffer, nbytes); + } + else + { + if(g_flash_init.is_dual_line) { + count = qspi_flash_dual_read(address, buffer, nbytes); + } else { + count = qspi_flash_read(address, buffer, nbytes); + } + } + + return count; +} + +bool spi_flash_sector_erase(uint32_t address, uint32_t size) +{ + bool status = true; + + uint32_t erase_addr = address; + uint32_t sector_ofs, erase_size, erase_cont = size; + + while (erase_cont) + { + sector_ofs = erase_addr & 0xFFF; + erase_size = EXFLASH_SIZE_SECTOR_BYTES - sector_ofs; + + if (erase_cont < erase_size) + { + erase_size = erase_cont; + erase_cont = 0; + } + else + { + erase_cont -= erase_size; + } + + spi_flash_write_enable(); + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + status = spim_flash_sector_erase(erase_addr); + } + else + { + status = qspi_flash_sector_erase(erase_addr); + } + + while(spi_flash_read_status() & 0x1); + + erase_addr += erase_size; + } + + return status; +} + +bool spi_flash_chip_erase(void) +{ + uint32_t ret; + uint8_t control_frame[1] = {SPI_FLASH_CMD_CE}; + + spi_flash_write_enable(); + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + g_qspi_ctl.spi_tmt_done = 0; + ret = app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.spi_tmt_done == 0); + } + else + { + g_qspi_ctl.qspi_tmt_done = 0; + ret = app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.qspi_tmt_done == 0); + } + while(spi_flash_read_status() & 0x1); + + return ((ret == APP_DRV_SUCCESS) ? true : false); +} + +void spi_flash_chip_reset(void) +{ + uint8_t control_frame[1] = {SPI_FLASH_CMD_RSTEN}; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + g_qspi_ctl.spi_tmt_done = 0; + app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.spi_tmt_done == 0); + } + else + { + g_qspi_ctl.qspi_tmt_done = 0; + app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.qspi_tmt_done == 0); + } + + control_frame[0] = SPI_FLASH_CMD_RST; + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + g_qspi_ctl.spi_tmt_done = 0; + app_spi_dma_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.spi_tmt_done == 0); + } + else + { + g_qspi_ctl.qspi_tmt_done = 0; + app_qspi_dma_transmit_async_ex(g_qspi_ctl.qspi_id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, control_frame, sizeof(control_frame)); + while(g_qspi_ctl.qspi_tmt_done == 0); + } + + return; +} + +uint32_t spi_flash_device_id(void) +{ + uint8_t data[3] = {0}; + + if (FLASH_SPIM_ID == g_flash_init.spi_type) + { + uint8_t control_frame[1] = {SPI_FLASH_CMD_RDID}; + + g_qspi_ctl.spi_tx_rx_done = 0; + app_spi_dma_read_eeprom_async(g_qspi_ctl.spi_id, control_frame, data, 1, 3); + while(g_qspi_ctl.spi_tx_rx_done == 0); + } + else + { + qspi_command_t command = { + .instruction = SPI_FLASH_CMD_RDID, + .address = 0, + .instruction_size = QSPI_INSTSIZE_08_BITS, + .address_size = QSPI_ADDRSIZE_00_BITS, + .data_size = QSPI_DATASIZE_08_BITS, + .dummy_cycles = 0, + .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI, + .data_mode = QSPI_DATA_MODE_SPI, + .length = 3, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .clock_stretch_en = 1, +#endif + }; + g_qspi_ctl.qspi_rcv_done = 0; + app_qspi_dma_command_receive_async(g_qspi_ctl.qspi_id, &command, data); + while(g_qspi_ctl.qspi_rcv_done == 0); + } + + return (((uint32_t)data[0] << 16) + ((uint32_t)data[1] << 8) + data[2]); +} + +void spi_flash_device_info(uint32_t *id, uint32_t *size) +{ + if (NULL == id || NULL == size) + { + return; + } + + *id = spi_flash_device_id(); + *size = spi_flash_device_size(); + + return; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.h b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.h new file mode 100644 index 0000000..911e54b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_spi_flash.h @@ -0,0 +1,264 @@ +/** + **************************************************************************************** + * @file gr55xx_spi_flash.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of spi flash library. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ +#ifndef __GR55XX_SPI_FLASH_H__ +#define __GR55XX_SPI_FLASH_H__ + +#include +#include "grx_hal.h" +#include "app_io.h" +#include "app_qspi.h" +#include "app_qspi_dma.h" +#include "app_spi.h" +#include "app_spi_dma.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Flash operation instruction macro definition + * @{ + */ + +#define SPI_FLASH_CMD_WRSR 0x01 +#define SPI_FLASH_CMD_WRSR1 0x31 +#define SPI_FLASH_CMD_RDSR 0x05 + +#define SPI_FLASH_CMD_WREN 0x06 +#define SPI_FLASH_CMD_WRDI 0x04 + +#define SPI_FLASH_CMD_READ 0x03 +#define SPI_FLASH_CMD_FREAD 0x0B +#define SPI_FLASH_CMD_DOFR 0x3B +#define SPI_FLASH_CMD_DIOFR 0xBB +#define SPI_FLASH_CMD_QOFR 0x6B +#define SPI_FLASH_CMD_QIOFR 0xEB +#define SPI_FLASH_CMD_READ_RESET 0xFF +#define SPI_FLASH_CMD_DPP 0xA2 +#define SPI_FLASH_CMD_DREAD 0x3B +#define SPI_FLASH_CMD_PP 0x02 +#define SPI_FLASH_CMD_SE 0x20 +#define SPI_FLASH_CMD_BE_32 0x52 +#define SPI_FLASH_CMD_BE_64 0xD8 +#define SPI_FLASH_CMD_CE 0xC7 +#define SPI_FLASH_CMD_PES 0x75 +#define SPI_FLASH_CMD_PER 0x7A + +#define SPI_FLASH_CMD_RDI 0xAB +#define SPI_FLASH_CMD_REMS 0x90 +#define SPI_FLASH_CMD_RDID 0x9F + +#define SPI_FLASH_CMD_RSTEN 0x66 +#define SPI_FLASH_CMD_RST 0x99 +#define SPI_FLASH_CMD_DP 0xB9 +#define SPI_FLASH_CMD_RDP 0xAB + +#define SPI_FLASH_CMD_SFUD 0x5A + +#define DUMMY_BYTE 0xFF + +#define SPI_FLASH_PAGE_SIZE 0x00100 +#define SPI_FLASH_SECTOR_SIZE 0x01000 +#define SPI_FLASH_BLOCK_SIZE 0x10000 +#define SPI_FLASH_ADDRESS_MAX 0xFFFFF + +/** @} */ + +/** + * @addtogroup Spi Flash IO configuration Structures + * @{ + */ +typedef enum +{ + FLASH_SPIM_ID, /**< SPI master module. */ + FLASH_QSPI_ID0, /**< QSPI master module 0. */ + FLASH_QSPI_ID1, /**< QSPI master module 1. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + FLASH_QSPI_ID2, /**< QSPI master module 2. */ +#endif + FLASH_SPI_ID_MAX, /**< Only for check parameter, not used as input parameters. */ +} spi_type_t; + +typedef struct _spi_io +{ + app_io_type_t gpio; + uint32_t pin; + app_io_mux_t mux; +} spi_io_t; + +typedef struct _flash_io +{ + spi_io_t spi_cs; + spi_io_t spi_clk; + union + { + spi_io_t spim_mosi; + spi_io_t qspi_io0; + } spi_io0; + union + { + spi_io_t spim_miso; + spi_io_t qspi_io1; + } spi_io1; + spi_io_t qspi_io2; + spi_io_t qspi_io3; +} flash_io_t; + +typedef struct _flash_init +{ + spi_type_t spi_type; + flash_io_t flash_io; + bool is_dual_line; + bool is_high_freq; +} flash_init_t; + +typedef struct flash_control +{ + uint8_t qspi_tmt_done; + uint8_t qspi_rcv_done; + app_qspi_id_t qspi_id; + uint8_t spi_tmt_done; + uint8_t spi_rcv_done; + uint8_t spi_tx_rx_done; + app_spi_id_t spi_id; +} qspi_control_t; + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_SPI_FLASH_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the SPI FLASH DRIVER according to the specified parameters + * in the spi_flash_io_t. + * + * @param[in] p_params: Pointer to spi_flash_io_t parameter. + * + **************************************************************************************** + */ +void spi_flash_init(flash_init_t *p_flash_init); + +/** + ******************************************************************************* + * @brief Write flash Memory. + * + * @param[in] address: start address in flash to write data to. + * @param[in,out] buffer: buffer of data to write. + * @param[in] nbytes: number of bytes to write. + * + * @return number of bytes written + ******************************************************************************* + */ +uint32_t spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes); + +/** + ******************************************************************************* + * @brief Read flash Memory. + * + * @param[in] address: start address in flash to read data. + * @param[in,out] buffer: buffer to read data to. + * @param[in] nbytes: number of bytes to read. + * + * @return number of bytes read + ******************************************************************************* + */ +uint32_t spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes); + +/** + ******************************************************************************* + * @brief Erase flash region. + * + * @note All sectors that have address in range of [addr, addr+len] + * will be erased. If addr is not sector aligned, preceding data + * on the sector that addr belongs to will also be erased. + * If (addr + size) is not sector aligned, the whole sector + * will also be erased. + * + * @param[in] address: start address in flash to write data to. + * @param[in] size: number of bytes to write. + * + * @retval true: If successful. + * @retval false: If failure. + ******************************************************************************* + */ +bool spi_flash_sector_erase(uint32_t address, uint32_t size); + +/** + ******************************************************************************* + * @brief Erase flash chip. + * + * @retval true: If successful. + * @retval false: If failure. + ******************************************************************************* + */ +bool spi_flash_chip_erase(void); + +/** + ******************************************************************************* + * @brief Reset flash chip. + * + ******************************************************************************* + */ +void spi_flash_chip_reset(void); + +/** + ******************************************************************************* + * @brief Get flash chip id. + * + * @retval Flash chip id. + ******************************************************************************* + */ +uint32_t spi_flash_device_id(void); + +/** + ******************************************************************************* + * @brief Get Flash information. + * + * @param[in,out] id: Pointer to flash id. + * @param[in,out] size: Pointer to flash size, Unit:Byte. + * + ******************************************************************************* + */ +void spi_flash_device_info(uint32_t *id, uint32_t *size); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // __GR55XX_SPI_FLASH_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.c b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.c new file mode 100644 index 0000000..3552dc3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.c @@ -0,0 +1,88 @@ +/** + **************************************************************************************** + * + * @file gr551x_tim_delay.c + * + * @brief GR551x tim delay. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gr551x_tim_delay.h" + +/* + * STATIC VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint32_t fus = 0; +static uint32_t fms = 0; +static dual_timer_regs_t *tim_regs; + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void tim_delay_init(dual_timer_regs_t *timx) +{ + fus = SystemCoreClock / 1000000; + fms = SystemCoreClock / 1000; + tim_regs = timx; + tim_regs->RELOAD = 0xFFFFFFFF; + /* Disable tim, period mode, 32-bit counter, one-shot mdoe */ + tim_regs->CTRL = 0x43; +} + +void tim_delay_us(uint32_t us) +{ + uint32_t load = us * fus - 1; + tim_regs->RELOAD = load; + /* Enable tim */ + tim_regs->CTRL |= 0x80; + while(tim_regs->VALUE != 0); + tim_regs->CTRL &= ~0x80; + /* Clear flag */ + tim_regs->INTCLR = 1; +} + +void tim_delay_ms(uint32_t ms) +{ + uint32_t load = ms * fms - 1; + tim_regs->RELOAD = load; + /* Enable tim */ + tim_regs->CTRL |= 0x80; + while(tim_regs->VALUE != 0); + tim_regs->CTRL &= ~0x80; + /* Clear flag */ + tim_regs->INTCLR = 1; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.h b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.h new file mode 100644 index 0000000..d899d6f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/gr55xx/gr55xx_tim_delay.h @@ -0,0 +1,85 @@ +/** + **************************************************************************************** + * + * @file gr551x_tim_delay.h + * + * @brief Header file - GR551x tim delay. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __GR551X_TIM_DELAY_H__ +#define __GR551X_TIM_DELAY_H__ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "grx_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize the DUAL TIM according to the specified register + * in the dual_timer_regs_t. + **************************************************************************************** + */ +void tim_delay_init(dual_timer_regs_t *timx); + +/** + ***************************************************************************************** + * @brief Delay the function execution. + * + * @param[in] us: Microsecond. + ***************************************************************************************** + */ +void tim_delay_us(uint32_t us); + +/** + ***************************************************************************************** + * @brief Delay the function execution. + * + * @param[in] ms: Millisecond. + ***************************************************************************************** + */ +void tim_delay_ms(uint32_t ms); + +#ifdef __cplusplus +} +#endif + +#endif // __GR551X_TIM_DELAY_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735.c b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735.c new file mode 100644 index 0000000..88d07d9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735.c @@ -0,0 +1,237 @@ +/** + ***************************************************************************************** + * + * @file st7533.c + * + * @brief LCD controller driver of st7735 IC. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "st7735.h" +#include "st7735_config.h" +#include +#include + + /* + * GLOBAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +uint16_t g_lcd_gram[LCD_YMAX][LCD_XMAX]; +uint16_t g_lcd_buffer[LCD_YMAX][LCD_XMAX]; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint16_t (*s_lcd_memory)[LCD_XMAX] = g_lcd_gram; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void lcd_set_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) +{ + st7735_write_cmd(0x2a); + st7735_write_data(0x00); + st7735_write_data(x0+0x02); + st7735_write_data(0x00); + st7735_write_data(x1+0x02); + + st7735_write_cmd(0x2b); + st7735_write_data(0x00); + st7735_write_data(y0+0x03); + st7735_write_data(0x00); + st7735_write_data(y1+0x03); + + st7735_write_cmd(0x2C); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void lcd_set_memory(bool gram_set) +{ + if(gram_set) + { + s_lcd_memory = g_lcd_gram; + } + else + { + s_lcd_memory = g_lcd_buffer; + } +} + +void lcd_draw_point(uint8_t x, uint8_t y, uint16_t color) +{ + if(x > (LCD_XMAX-1) || y > (LCD_YMAX-1)) + return; + s_lcd_memory[y][x] = color; +} + + +void lcd_fill_mem(uint16_t color) +{ + uint8_t x; + uint8_t y; + for(y=0; y +#include + +/** + * @defgroup ST7735_MAROC Defines + * @{ + */ +#define LCD_XMAX 128 /**< LCD Max Pixel of X coordinate. */ +#define LCD_YMAX 128 /**< LCD Max Pixel of Y coordinate. */ + +/** + * @defgroup ST7735_EXTRERN Extern_Variable + * @{ + */ +extern uint16_t g_lcd_gram[LCD_YMAX][LCD_XMAX]; /**< Gram memory define. */ +extern uint16_t g_lcd_buffer[LCD_YMAX][LCD_XMAX]; /**< Buffer memory define. */ +/** @} */ + +/** + * @defgroup UC1701_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize lcd. + ***************************************************************************************** + */ +void lcd_init(void); + +/** + ***************************************************************************************** + * @brief Resume lcd. + ***************************************************************************************** + */ +void lcd_resume(void); + +/** + ***************************************************************************************** + * @brief Set the memory type of lcd. + * + * @param[in] type: Memory type. + ***************************************************************************************** + */ +void lcd_set_memory(bool gram_set); + +/** + ***************************************************************************************** + * @brief Fill Data to Lcm memory. + * + * @param[in] data: Fill data. + ***************************************************************************************** + */ +void lcd_fill_mem(uint16_t color); + +/** + ***************************************************************************************** + * @brief Refresh the memory data to lcd. + ***************************************************************************************** + */ +void lcd_refresh(void); + +/** + ***************************************************************************************** + * @brief Draw a point to lcd memory. + * + * @param[in] x: X coordinate. + * @param[in] y: Y coordinate. + * @param[in] color: The color of the memory. + ***************************************************************************************** + */ +void lcd_draw_point(uint8_t x, uint8_t y, uint16_t color); + +/** + ***************************************************************************************** + * @brief Read a point from lcd memory. + * + * @param[in] x: X coordinate. + * @param[in] y: Y coordinate. + * + * @return The color of the read point.(Return 0xff:error) + ***************************************************************************************** + */ +uint16_t lcd_read_point(uint8_t x, uint8_t y); + +/** + ***************************************************************************************** + * @brief Fill Data to Lcm rectangle memory. + * + * @param[in] x0: X0 coordinate. + * @param[in] y0: Y0 coordinate. + * @param[in] x1: X1 coordinate. + * @param[in] y1: Y1 coordinate. + * @param[in] color: The color of the memory. + ***************************************************************************************** + */ +void lcd_rectangle_fill_mem(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint16_t color); + +/** + ***************************************************************************************** + * @brief Refresh the rectangle memory data to lcd. + * + * @param[in] x0: X0 coordinate. + * @param[in] y0: Y0 coordinate. + * @param[in] x1: X1 coordinate. + * @param[in] y1: Y1 coordinate. + ***************************************************************************************** + */ +void lcd_rectangle_refresh(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1); + + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.c new file mode 100644 index 0000000..4c55223 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.c @@ -0,0 +1,237 @@ +/** + **************************************************************************************** + * + * @file uc1701_config.c + * + * @brief uc1701 config Implementation. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "st7735_config.h" +#include "grx_hal.h" +#include "app_spi_dma.h" +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +#ifdef DISPLAY_DRIVER_TYPE_HW_SPI +#include "app_spi.h" +static volatile uint8_t master_tx_done = 0; +static void app_spi_callback(app_spi_evt_t *p_evt); +static app_spi_params_t spi_params; +#endif +app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void st7735_init(void) +{ + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pin = DISPLAY_BACK_LIGHT_PIN | DISPLAY_CMD_AND_DATA_PIN; + io_init.mux = APP_IO_MUX_7; + app_io_init(APP_IO_TYPE_GPIOA, &io_init); + app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_BACK_LIGHT_PIN, APP_IO_PIN_SET); + +#ifdef DISPLAY_DRIVER_TYPE_SW_IO + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pin = DISPLAY_SPIM_CS0_PIN | DISPLAY_SPIM_CLK_PIN | DISPLAY_SPIM_MOSI_PIN; + io_init.mux = APP_IO_MUX_7; + app_io_init(DISPLAY_SPIM_GPIO_TYPE, &io_init); +#else + spi_params.id = APP_SPI_ID_MASTER; + + spi_params.pin_cfg.cs.type = DISPLAY_SPIM_GPIO_TYPE; + spi_params.pin_cfg.cs.pin = DISPLAY_SPIM_CS0_PIN; + spi_params.pin_cfg.cs.mux = APP_IO_MUX_7; + spi_params.pin_cfg.cs.mode = APP_IO_MODE_MUX; + spi_params.pin_cfg.cs.pull = APP_IO_PULLUP; + spi_params.pin_cfg.cs.enable = APP_SPI_PIN_ENABLE; + + spi_params.pin_cfg.clk.type = DISPLAY_SPIM_GPIO_TYPE; + spi_params.pin_cfg.clk.pin = DISPLAY_SPIM_CLK_PIN; + spi_params.pin_cfg.clk.mux = APP_IO_MUX_4; + spi_params.pin_cfg.clk.mode = APP_IO_MODE_MUX; + spi_params.pin_cfg.clk.pull = APP_IO_PULLUP; + spi_params.pin_cfg.clk.enable = APP_SPI_PIN_ENABLE; + + spi_params.pin_cfg.mosi.type = DISPLAY_SPIM_GPIO_TYPE; + spi_params.pin_cfg.mosi.pin = DISPLAY_SPIM_MOSI_PIN; + spi_params.pin_cfg.mosi.mux = APP_IO_MUX_4; + spi_params.pin_cfg.mosi.mode = APP_IO_MODE_MUX; + spi_params.pin_cfg.mosi.pull = APP_IO_PULLUP; + spi_params.pin_cfg.mosi.enable = APP_SPI_PIN_ENABLE; + + spi_params.pin_cfg.miso.enable = APP_SPI_PIN_DISABLE; + + spi_params.dma_cfg.rx_dma_instance = DMA0; + spi_params.dma_cfg.tx_dma_instance = DMA0; + spi_params.dma_cfg.rx_dma_channel = DMA_Channel1; + spi_params.dma_cfg.tx_dma_channel = DMA_Channel0; + + spi_params.init.data_size = SPI_DATASIZE_8BIT; + spi_params.init.clock_polarity = SPI_POLARITY_LOW; + spi_params.init.clock_phase = SPI_PHASE_1EDGE; + spi_params.init.baudrate_prescaler = SystemCoreClock / 4000000; + spi_params.init.ti_mode = SPI_TIMODE_DISABLE; + spi_params.init.slave_select = SPI_SLAVE_SELECT_0; + + spi_params.is_soft_cs = 1u; + + app_spi_init(&spi_params, app_spi_callback); + app_spi_dma_init(&spi_params); +#endif +} + +#ifdef DISPLAY_DRIVER_TYPE_SW_IO +/*--------------------------------DISPLAY_DRIVER_TYPE_SW_IO------------------------------------*/ +void st7735_write_cmd(uint8_t cmd) +{ + uint8_t i; + + SEND_CMD; + CS_LOW; + for(i=0;i<8;i++) + { + if (cmd &0x80) + SDA_HIGH; + else + SDA_LOW; + + SCK_LOW; + SCK_HIGH; + cmd <<= 1; + } + CS_HIGH; +} + +void st7735_write_data(uint8_t data) +{ + uint8_t i; + + SEND_DATA; + CS_LOW; + for(i=0;i<8;i++) + { + if(data&0x80) + SDA_HIGH; + else + SDA_LOW; + SCK_LOW; + SCK_HIGH; + data <<= 1; + } + CS_HIGH; +} + +void st7735_write_buffer(uint8_t *p_data, uint16_t length) +{ + uint16_t i= 0; + SEND_DATA; + CS_LOW; + for (i=0; itype == APP_SPI_EVT_TX_CPLT) + { + master_tx_done = 1; + } +} + +void st7735_write_cmd(uint8_t cmd) +{ + SEND_CMD; + master_tx_done = 0; + app_spi_transmit_async(APP_SPI_ID_MASTER, &cmd, 1); + while(master_tx_done == 0); +} + +void st7735_write_data(uint8_t data) +{ + SEND_DATA; + master_tx_done = 0; + app_spi_transmit_async(APP_SPI_ID_MASTER, &data, 1); + while(master_tx_done == 0); +} + +void st7735_write_buffer(uint8_t *p_data, uint16_t length) +{ + uint16_t last_size; + uint16_t count_size; + uint16_t i; + SEND_DATA; + if(length <= 4095) + { + master_tx_done = 0; + app_spi_transmit_async(APP_SPI_ID_MASTER, p_data, length); + while(master_tx_done == 0); + } + else + { + last_size = length % 4095; + count_size = length / 4095; + for(i = 0; i < count_size; i++) + { + master_tx_done = 0; + app_spi_transmit_async(APP_SPI_ID_MASTER, p_data + i * 4095, 4095); + while(master_tx_done == 0); + } + if(last_size) + { + master_tx_done = 0; + app_spi_transmit_async(APP_SPI_ID_MASTER, p_data + i * 4095, last_size); + while(master_tx_done == 0); + } + } +} + +#endif + +void st7735_delay(uint16_t time) +{ + delay_ms(time); +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.h b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.h new file mode 100644 index 0000000..3fe1bd0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/drivers_ext/st7735/st7735_config.h @@ -0,0 +1,71 @@ +#ifndef __ST7735X_CONFIG_H__ +#define __ST7735X_CONFIG_H__ +#include "board_SK.h" +#include "app_io.h" + +#define CS_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CS0_PIN, APP_IO_PIN_SET) /**< set cs pin to high. */ +#define CS_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CS0_PIN, APP_IO_PIN_RESET) /**< set cs pin to low. */ +#define SEND_CMD app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_CMD_AND_DATA_PIN, APP_IO_PIN_RESET) /**< set cmd pin to high. */ +#define SEND_DATA app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_CMD_AND_DATA_PIN, APP_IO_PIN_SET) /**< set cmd pin to low. */ + +#ifdef DISPLAY_DRIVER_TYPE_SW_IO + +#define SCK_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CLK_PIN, APP_IO_PIN_SET) /**< set sck pin to high. */ +#define SCK_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_CLK_PIN, APP_IO_PIN_RESET) /**< set sck pin to low. */ +#define SDA_HIGH app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_MOSI_PIN, APP_IO_PIN_SET) /**< set sda pin to high. */ +#define SDA_LOW app_io_write_pin(DISPLAY_SPIM_GPIO_TYPE, DISPLAY_SPIM_MOSI_PIN, APP_IO_PIN_RESET) /**< set sda pin to low. */ + +#endif + +/** + * @defgroup st7735_CONFIG_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief st7735 init(config gpio spi). + ***************************************************************************************** + */ +void st7735_init(void); + +/** + ***************************************************************************************** + * @brief Write cmd to st7735. + * + * @param[in] cmd: Cmd to write. + ***************************************************************************************** + */ +void st7735_write_cmd(uint8_t cmd); + +/** + ***************************************************************************************** + * @brief Write one data to st7735. + * + * @param[in] data: Data to write. + ***************************************************************************************** + */ +void st7735_write_data(uint8_t data); + +/** + ***************************************************************************************** + * @brief Write data buffer to st7735. + * + * @param[in] p_data: The pointer of the data. + * @param[in] length: The length of write data. + ***************************************************************************************** + */ +void st7735_write_buffer(uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief st7735 delay function. + * + * @param[in] time: Delay time. + ***************************************************************************************** + */ +void st7735_delay(uint16_t time); + + + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/BUILD.gn new file mode 100644 index 0000000..ec93c58 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +module_group("libraries") { + modules = [ + "at_cmd", + "fcc", + "utility", + "app_memory", + "dfu_master", + + # "virt_key", + "app_linked_list", + "hci_uart", + "app_alarm", + "ble/ble_time", + + # "ble/ble_gatt_service", + # "ble/ble_connect", + # "ble/ble_scanner", + # "ble/ble_advertising", + "crypto_lib", + "pmu_calibration", + "app_timer", + "sensorsim", + "app_log", + "user_efuse", + "app_scheduler", + "app_error", + "app_key", + "hal_flash", + "app_queue", + "dfu_port", + "fault_trace", + "app_assert", + "CMSIS/cmsis_dsp", + "ring_buffer", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/BUILD.gn new file mode 100644 index 0000000..ab1d72a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "include" ] + lib_dirs = [ rebase_path("Lib/GCC") ] + libs = [ "arm_cortexM4lf_math" ] +} + +kernel_module("cmsis_dsp") { +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/Lib/GCC/libarm_cortexM4lf_math.a b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/Lib/GCC/libarm_cortexM4lf_math.a new file mode 100644 index 0000000000000000000000000000000000000000..101d668ded58a363983a667556bfa2d6f9490304 GIT binary patch literal 6421864 zcmeEv37lL-wSL`RW+tU7OU1-_TN~nX6CFqSF@p5 zsX(n#D@Q5Svq7oLUsUS;ZA$(67Uc}suAJ(hE9clL%Gth0IX9Op=ZTPV{#K;|V;)d} zWzVQUe@q3gEK-37)~movr7BpmDsw;SA{9LEWfi=oT?K#qh6?_@N`O?ce`zjKPrKJgzEA)~kwzEvn*_ZK~qJI#qFRyQ=uj8*1ptOV!W? z�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 z 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%0A615T^c!hJmy5uy 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%0D}#}_86@WGwNp-ytE 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 z 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 z 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

o)O|1<20UG169w`ZZ!!M6Q0^6>jn z6xm61$9?5jf#_at@0%OY(z}q@2W*4Hp4tY9ePEcd9+2IYG2V&no?)Z!8e*dl{%rK| zM$AD_vMY!!CJqX)*+c0^bQ=K=8gLgqoiJ3QM-o`hP|F!xAqmq7+}&+qMkCTS@TmqU z+XPeBQQ^8~bY$w9k*VvbuC*AuNa~tNm@CmagrHwDrLJWr55e?n4r1E~Jh?%rnqc~M zM7UpvhWd4AreD00>=f8Gc=6H)Hph4nuy0FMs*lE6y>+d7P}KNiPY zva(}3BD0L2z=kl!nbF$T$m58@2jLRf+P25O94U@e|+!D+NV)a9@#I5hkJYk%Z8ASPM>?S8ukcOxRZZXYuP~hu> zh^aG}aHe#SPGoIC;02dsy^eL=Ntgc*)8(sMme+vnRo6mdAy_dO^Z&90`3n(Tb{1tM z$H#+oKCh^#uox8bEE^Q?0eJigUi|*#!#7O@LEI@Ur<6E(JscVGsAit!wAdh;JH;T04-mq7)`78nlI@WtD-WFgT~W7F zJ3c->mhChp@yg4#(~P@iP0eH`HZ@j}cv&S>Ixt$p(#0*K_aIMhL1XnIAuVcnEo~C+>Knntt7&RFt^p*x{TmjL-bf~7 z)zaE(ko8*XS}C+FG^kFSTL`xzqbs==HsPTPG?ts%QNDgrQ?>rj(H8t&v z&DLzKqx3O0>vGww4UI4x8f&e_`G?hE#e57czZys8`xEbth3*$2`IrxBsXD4ShH7#mQ z);F~z_iI_4oV0j;U2QE`@fgXPx>l&EwS{qcO_%gB@Fol7P}6h)l8uKYydxuzj@zCZq-+qd`nW4?Q3L3uU7o2qVT3s z-&1P8sL02!Y=^Hrh{8hyik2(zK=sd5JVx<2MZDURau+FHrT7O$;fJA~zpEX?%@5lt zQcNid?+gC@)Sj+brP!n>JTK%sTkT5~uUC9rQTSWPM~Nr4_r9XXTXfiC6(=els@R~o zR*}yZng4Oc=N0*ok$y@}5woyM5K9ziDb^^SqPRw}Ly^Bd&2slBKBgGQ16KNr6-yQQ zYKi_yinA5#6x$U~Q@l{|O2u0hA5wfuaf9OD6l0j+(!OG;B4uXiKR|JgVuNBXUu_`0 zry>OjX^&MrK(SV_Me*y3=PBN!__*R96@@R2`aV)S;hFk{FAaa0+QOHHeURG1mxkS_ z_Q{HC6fal2S@8kIClxm+j=(<8_1RBxrQ(^2S1Z1&7|AyI3l&A<8|8OVTX@s3`MZ9s zcOS)xieFPaQgONB*NNCxrz;9?8u1R=SgugKhKPD^QCoP_i2q9M#}$7|M7|f)eo66F z^$VXG@qeh_!+DGC( zjfy{2{F&mtiVrJNdy4h^R`F@YKPtYc$Tx4yhl@HvS5dw*f}fhFOz)w%i(*P~s3J)| z%tr-8;+~3piAVcL#cIVm#YKwL)nq=Zn-Nb?T&?&G#d8(USEN)Q^UL`g$oGS^sXa=3 zNReuSw4YFXN>R@1@V~7#PHR>K$Nu1W0aMBa$CE8OZ;I##=_xp#d;uPJr#pY^E6(EX zjd8&c$@MbezsliW%?@bb_G1`^1*d9j0v3jg@yY?4Ti)C-4;R|JF6Vj#;SNOjyAweO z(x$)>u5T^sy9V=#_fwopL47=L1Z5Dl8gXLU2m4+Sg0$n{2;xk;9_O}?F*kz{q%D9W z-0pz`u})}=?b08#y8`i`45HR`-7PE0h=w4I=c{mi-xzH60oKRW4(dAx@t_Q%)}yG8 z`$`akv@_ud*LQKKz68>O`uH7AP=<9phx#tx#<+YBY2o^=L4Dj#>>qZ+bbZ$$&iZ&B zXIP0Fw4ZWAXkZ$b+Z2O*!*M~tu?j+v?*TX%55o1xHz6>9Tn`4`Z-x7JQ)qp0`nF*FQT5-;5*!0E$}A(Hy?fowB0J*;_{f4jpMgrL5z9Pazj zzdr|=fI&WRxRsNQ_Yw%7g2O#(q~!c$4);w%q`@?Yy98@f_WI_^s*UI6^8LGvXU8_?#-bZ@qmwpf#U^g_qV~S+^G45ekURd4 z7k~8$>y5m8`;A}Q-8Vat-1RrTAF0S$Wsh?ai&uPYl|8i2&u@A^yW*Rxpag#^H`T`< zFU0<5#y4u8fR)dkfGxQcJ8m!`g0TT_JA(NGit-GkI^V`%J7Y^Kkqizu_0PfK=0~Ou z_i*Q+61gyp#s(wBsbYz=9z0J!;B)Vf8o=l7jYhlhxox_Vg(RmsLy$Q-tZ)Y7yatS> z_2A!O5BS+`Y(UR-NC7zy|M3C|8`0SZJ&6y?V<#LwB8az0+#P^a7d-E?;q#*LtDL@Q zD=QDR#IMPH3(l-n=y3c;h4dR{A4T0oK%6}9_!U{RVJDtpomZ;7ua)4>E61;meF!gj zotDG1Z(Q}@V~pR}o1G`mTRvE`y(dw^=)qH*+v_1>`T0LYrV?+s_b%Hw4_Uksg^YtB zMxM7fQd^8Bo<=vlkvXSHi(aBl%pzmvCJsOuZ)9&{3eVdcmGiz-M4tCKh>1*k7MhTC z!@=txsA8Zu*84tuiFUS~(SzTBX1sAK@g7Y)Of#bgPtLlR(Sv`DE0ocL|1P_>kCrV; zT+g!ms#%gaiDff-@b|H7NDrQeG|%>?dT+8W*>u! zxTxZMELsZ#Jnx^dt6sZz9vhmDe_lopp1fu+tOw6sFQ44Yh2E`R4oZ^e?cLU$g=HqR zSl;cyOd!wOyF)F*^Y$`&@ZV%pKg+5_jgge$d3$#iaLPqehUe|wtz}CRmvR*|dho3@ zGkWkbZpVxs{AKKQMh~9f;d`C+;JsgKLx$(={YF>7@VveC+V1$oEvzb|2S15sXFYiD z8Let!f}bOJ89n&A@GU{*WI0PuPA)51uzGUPup~Y(X!i2S0`FhxFj7 z-R_0-;JIIUVLf>68(vrs{$)DCdhowtm0>;jCf4!a)r04LxSOjxv+}(63T&K5c<=9l z=Y27TtK<%>K(3dvy)%%*mt%KG51yZ-cp*LbB98F(^x(5lZ=ScW?fsTjox+U|o;M8= zh3BzoNDuycRt=u_RP+ZtxCfrM+2I!Yuduz49z3q)EH9)7 zPq7RytOw6604i|)Wb~egS^rqp5Y~fV&K%%*vkBpOZ(^HaJ@||12B zeH(Lx_279^?0qpkcn>`9Q#j@yu!A8zcz#^qeI`A44?OQ*qN?6J>UiLJbK~~DpJTOM zJ^1sG_1~oj&&wh&qX&Nm8xHHi{|V{fdGjNJe)nSg7@l|5*CX*2*?8dlL*zd>*@z*v zl2|M|c_^ow)%QxcvcU5`7`ednegbKcyh!2sK=&OKiWEi)d0W(tYTdEunev~{cl+D* z*kX3A;e0Pc76!Wp-`^iDh6z;|R-MEZyScF}})yZzOz0?CM^y`FISz zQSkMoZw72W5`%9veEsNK0J{!L>IL?tQR?Gso)hSMS$xIJw-z?9GfKIFBhe}J0sp=k zdkZ(DgQmiHD^mF&Y|!2?o<)RDxprl)!H2{1S6F0~L+YJXj7P-b^BVi?m=rHYTZLGp zI3HvU#9|`&=K4&4>-MTrw%pk){o|cPOccoqF<4RoLu&K7`Q1`}3hscvQfzZbhi`*zp4J#w7I{ip4QSz=(`$m z^uZx<^dVan!ZcK6bWwCqiZc3cVa7Y=UzqI9nTvqAio?!{f;?y-j)xAN!&I1{NfVf5 zD?xMKn&KW9!Et1d;&T^enRCAanVK*W3&_;b4n__(e!?t?&LA9v#ep1F2P3t{h;}g2 zXpA_IeVxKgSP<$a1f83i&V-{cLj)aUC-DUix+z`cR|LpEGiH_7g5J*Ik|%ob{2jD7nT@No?eBBHKK#7!i7rY00~g9 zi$okJ8ilp>NKR+JxHwj8TSv%P7B*IjF#*}Yq$jY~DA6q4H={f~Gs?};&?q;1=`KQt zJU87hTbdn*iXx~8AR!X=wgp}%?B%wQ5Dj}*2HsfO+YPG}FIcr|Wv|xe_=M8_>88zL zo$CPldQi@mV?Fz`-Ey`)63Lu!aqF)y^AH;Z=aUONQg9+lgc{8_yVe-nR`xz9EptqE zD${s+IAF4ST(}nOW)L{z0v~%24&m}op>julYUDFg#tqSMN@LBU_S!nDX58F1vZLlM zsHrI(ih>6Os7 zg1&v0>bALZh7xrAs1a3dO;yK_7y~*GjvvShW!AQZgY5X7D1r$UE(42a}C!1a#XWyARg*XU>@*4w!QtZ=7CQPf77bJuc~Z7D~JB`Zga{UYSYWEli=+xLdHF!<7C zi$}w5TiCvMKCmAC`sO90%UYYuYDer&4>|W`IM(b972aAns#|In?v4Fx$=JHG#kHp}MsJtoyQh^0nJQz$^n{oY)E<`NUzn zt7tfP;>?Z>3N5zQ_W0)i1(x~0ky!qPS>jdPZ&ZE$vk}GT^VoN&=u`)kaeT)y!oojD zAb&3Mc=L=AW31*wTWSpF96hr{3Y>@MWh1K^s;y5Z(r30iN%U3!EfRXbIhXFpaBNq* z+Yp<(5YN*`v(GEoUA2>b{=cfpoeW(z@~UzFygsYl)8ePc&WL`)ITL!^@O>FM=G{a6 z<~=4}&C72W88`2XGQr`sQz$qV9{z=bBX9pR4u_xhhXP(&hAdu9=XJ63yV#w3=Lo|) zlf|)$^jl(c6H1P`Tr74v-emaX88>fIaJPU5nd}j{ihLJO|zTM-wr zQXgNdu->tXlNE&<2tVIdF(v60un`Y8#oEO6z$oHb&BnZrzu{jc%|a4iVrD1rMN-yZ;IRFkc;Lv+sBR| z?JJ7rHvCJ~7R_zgqPYze&26A)ZUaR;2q>D{z@>cM0u;?{;1ATkS@9Q&Uz9_>7>|$G zj%aQJ&rw@6w_%IsHt;_6i{>_L(cA`#<~C3?w}GO$4HU^6Ak}SHzsOesMROY{n%lq> z4sA>ixZ{;-Q%;6{(cA{kS6eiwy5zKWHKhbkVfxIpnZ#S;`o zvm5QLrj2&aRsZ>lqS+1q6>49tcoPxpdn*yg;fK`!E5+X`KCSp15&2$G`!&UPiKu6b zrbm&7>+dNRC>AUBB4U9^mE_x1Q8d2M&wXeEzov-8uGEj+S`cnQp2^tmK*hm|!xiN` zf^h`qZR+6<6A_#+vntVr}eo*SAaV?-560mZ#Q9A0Jjx3s|1dJI0X5I z!O1wcI|K9am=pwVcZNw=f-nG<)&%vJ?1H(4%6T1*>A@>{>DLTk zPzF(}1lQzzIUR%`tp<)D&b0F}XATcmDwI}*c(~nprEnl0+vPX}?Y1Buu5Tl5Ns{md zAxLY4qf>o@4F{X`;dGO(?=-}NGKk7|tP>c~5Tu;~J6vBg>YEN9>*Fv6{Ua4HD1)dq z6|Z&4feb>Bc0L^8`p7lrda^#8&eHW=fjG->KV(SZwb##rjSZV=Ty9Vd^8FDzH1BPK z5ahcH4#tBp2Rxhb+zRH)?Z^=B-y@;%!;q)@_Xy(HOwB=kXLqSDXp0yc2J1fLtALYl z@q+sD5oepB>0xc|r)&lI8G`zFe;Cg9Ec*AXfsRi1BS{O;*WvTvE%2 z^0Omb^RvgJfF0QzJyCvkAex7EApZx?gZ$KdYGTRjP|GJXUlkJ_}QniXBmF>mF)ND=4W5Wt_J*UUT1~) z*%j<&n4isAm(PbgU!0%)Z8r63`PtWU6*K(oQ)q6NpM5ENo#AKm`^C@8&*pbSA$~Sh zr?=0~eu>j5!_RKuOwaJM6IP-`2*-)kK#Lwmhewd$q5$zB^`$4uJ;%Aqz{t!Q# zpO=LB*>hPw#Ls?&!x-XcSF-&OKl=fu?}(rM9vcYrv!A0Q%+LN6s|@qA8(8Omm!Hl3 zFwD=U9p-0~XPV|`-;5Q=@U!Ju65?kUbM->}>|BoU_W0TPs5isUUd4?+A;Zs>?|DM} z?5kMyr{iZ&WmO@5_7f}`;%D3XMH>1XaAgAImFMVe*BL3 z+0U}Q9rCklSwong&1WQ?_}LrSW|*JNFTOkRv%k)@2=lY~D;k~n*-tRXzlonsvVEAJ z%?~<0CqJ738&31H!Lxe{>9`)Ff=NGqr4X}u zjhN(9ZzyU|0pnbgXvj@SM#4=zkI%T)ylOsGI_DuR7W(}>v#a<749hOuc^R#Gb@;d^MW(X7B9A^k=HVlsR7!kB^euzkMjyXdv{&?^ z?-JOQAt+_XdEbKOk$7fo(4XL-00Cc|4B}JKHxPLp3-9Qy!EeIDul^h?2t$s=zetZL zNYfu6WoYw^u~x*7=Fr&fcyu^Y63xkwrh7#{1!=m6C2G*Zu0=xwt(=^Fava=LMm6f8 z3*F!)Z%vOL8Wsu1wEJYXG-fky=1-IxdYQo1iA9{vox?sb z!Ivh~V=;Vb##jUi_#XtrNKO-{4KWnd>5<651!U-z9gLVdXAmZ0v8}lTR^>oGMf9oX z7$YJY%eBUEIx_9@$yJxIKWvbd2|-V1hDz|DBY`_P_DNfoG=~~H5&X)cW|YSRu&CKd zR;g@hMyE;2Ov1rfge}bo`-~0{xF}niQLX^l(nJ%l2=(k3cqMF)I309mI{U=MvD(@? zLdLSNu~LjZkj=Jc5x5E{(cF<4@aYrbn=XD(rx{^4!It(y0}kqRX26+8f-ODZW{g-+ zk<<_YvP0@$n%T^U2U&Qm3}rbXljX1=OEjF}<2-SP3=1D5k^$dl!?DwVlld?zY% zzktd-B1~oO;ti(45By$vq25Tm&p2&wt=@tK7Rjenz9 z$>`5OUgq(*GY@(vlldzuq<#EY9!l#QPWC*gOUZfo- zpDR&;ysB|=^&(V-y4l=+Q$QQHx}Eg1dEFQUUI*@%SF}2ITJ&`1j4v;jneS*bA#=S; z-_sZBY%h6i@ap6GqG4vc+0pgFQtu4L)Fi_E9To* zakAn;iZd1GDb^|Swu$A0w+uW*?Q<0`P+Y5cy`u1zk^kpvKcOhRW%yrK`)x(xEyFLo zW#Cv04BHjnGVn09g|`e_c*{WHEdzzO3>4lnPA47*Zo;Vr`!-ZF5$`h~X) zTX@Sr;VlD&w+s~CGEjKSK;bO|x5--u*+zKFNEhBRY~d{fg|`g9@Rnf zP_(a6kMNpd3$GdY4d%z3J%@TSDEO)4Vx8j3D)cO)ex!Ec`BH`DiWGNIOey|f^NLT^cF#}@w6Ske z`?Ki;qydTCq-%FQJ%! zrQ&Ku%EQsm7gEH_6!{8@cA$aHw@|d-RurDGi$~3Pwn~4NA`ahH1pZ)N!<6)3-s3PR zb};`-)RyO(sAq$Y53i-j%Ma2&llJpg{NS-)b;)O|H^u`)Bd-booj8}Yu~{Va$A9L- z=8!O2F#x79@NFWu#V6$(hCE%{T?Ahcf~)e0a0GQTZ7pqXWDP;u1lTy7T119{{VeM> zY!Hh0=~eJlt;XK(vec*e=`S zdJuX14A(cSyJaQe3qp{_<88RU_izB`oM(MF)u!uPjd)N7QL7F04Q50`khThTxV|Vh zPz8LfkHZ-B?>mSGWe~M4MSa(8V_eQdTDZQ^sE_N%`mkH2>-z!XtdDIm9DodWawpcn zG%i0@4D#{E9e9ojLXeO535*9}CGw@qz{&MsxD89Vf8)`=eE8TutWvsv4#ZhW_zhCkR14XgQA^ zO}ej!Pvi$zj2K-Zc|VyS{CrAU>%*W6=VZf!ZT}=D_$x%(_aaD)~2}lj2(v^3)!(1zkkAhBVJ&=5zi-+xbOP)o2(Tb zo4T3W$FbD?@D#vr8{bglvsbwAMbdTMk9hOl%?HTsVns2pfn-&pHaQ8o4`O8Z;NIRP zKnMB(xS<2xoe+u1FaJc`r(ucqbL60s87LEp#&*R9b&||=NY7evxn!b2`&sV5Jl97< zU9_J!vdpl;NysjG&rU@V-#tQK@NejlV{~!YjU54GiyKOi2bOLexvtXj93oyQ|~!;MHauB zN<0BOcBQ)<5J_1Ha+YG(#$FZ^de2nmja}!ksPiV%ZtQ&((x~@*G<+DWyWs7{xN{Kl zx;INNo}F!|0|vGRJhlONH;tK7pW`2SUA9o)$jo!1nubL$ZUhB9M)a;YEjAi#zGii0lnE`sw?o`po zPTYm9>V7SoTG<@+zq00OSu`E$J-^Q6gJs2FM-t<3Omt_cjfsV{VwLs4p0g1;u_zLYx!nIfqxNUF&1$^76GoAe6*r)b`V-t&W!KHB%# z9`v3~`X2r=+TasEE$QQZp157`iOr#8f}ddh;1iqt6a9fqmS6o@)a>u^GXr{~^~Od}5suXpt)(i?aF>o_q3K z=so|8Rqcfv^j`XJ(G1JinE_2A`OxiAZXo&j+S1_{3%{4)hOXec%(f zNPW}&-GDCio==dj&hbgqb-^b#JKRE_4WKOu3!CuR?v)LPqT#D(57s}Q|so(){^iH+lW+dr8O=sg?9Ew*37 zwE&;kIH32;`)3z=&&Khf?cdBC;1iox9<#0NqftG3C1cvt*zAC0Cyy{du?{1_k05!y?NAeq4&&< z+xzPrEAWZgs%ih;piqewuSF~16Vuhl=3zi)HzwFR#A8wJ=zZ+B=;u1Z^Pc!$!vAc} z!ED?QNe7_I{8waf!6)XC&$j#WDYgqfafz6bX!Q3;$Mx72*!@n%Kcn{y-g=x5Fn6g# z{*#llv6fa6i)AMdLF=ejc-_!@-W|E1_e^o|EJ!?`fjr%ghtK76sjR+{g26Ci(Uau= zsrcXDK9s9>f#DP1f?N#tfB~q%zOY~ovT))I!!qDs^nFLPl#hbV3&H`{pfC1Cx#uJP zLo92tq?)HRTJ|OREX!Mlhp-HMie6aPW~;(#bgclRI;#|y_9RLW^d&V!z91A4;jBK)mNp2#lLSZNz47B;1TbWLn4l8$*y53VoDaLxyT{O;;z!hoB?uQ6i{KW z7yHCqB4;A~UBf~+z{0F;~5VV=m1_nb5sSI1UJ)K<`ghg1Rj0`nKZ3iPfxgcesutN_v#-ff)f2U{q z3#w?Qzo3d{`WsT&#V*ERn|(`Ahk_|euw~SY%wdFnEMUzh9D~KN+HL6pS5}F)jIP9j zAt0>A0^+SL9lF@~3G9**Z-d^Ec*{}c5|$~(vkBSo+oZE# z?i8n$UnB3LajVL^U8t<#SM#E)Y51C3$ znz}8E1WS-V9jDuzPHasnUmnXZk7W&!YFUx8F=M4ty|%Y?LP}c-lQ;23;Qx}h`5$F! z3N1}^XggChWsZy*Npg`0aW*u9F|@e3y``?Ixs6<)x@B$khBh>M4`5wu`=T~Hcv;j0 z%~kma0#d_*#=6=hML4UfTcN$WxUNcwN>#0sr%anf ztSS(j`19#i|6i)l{?F4itLkyoSk%yp4ZIlh29sd+G)x?z&Vtq@4Irg0t!Zg%T09>I zr0TXhFxMIu;eXW^7MV>`F?aYa!0-^6DL7)v#16Q3(+;WpTGcG{vZaB&Ll>7dv{|hS zp=~U4ekc7h(9_;2B>SnDmt7|u=DIRBv4?zFshINq?qdYoimc4bO~~(}2bX%h%-b(7 zceQg`Oia%G($u{|V zDek5iXv>aOTR57iZ@SutDb7`_QEX9Mt@wS#tBBZk*DCUdHDt@dO<$HY8+l>fcp&||^oj6`{oJ7C!)nB40k3Hb$16B5WwBlZh z0mqRKSD9X=Sg&}j;_-@dd_=yJ)c(5SHx2cE)!v{Oa2&DwVu z2?q{;)&xzs1}m1toZ&SRAkF7G6!D-8vyvmo>x3W#(K@CDP9lyw?}r>gv>Hj_b{|Q? zf%8Ax#gt69+lF{h22tyM%)=xj8iKTD*q!PdVCFUJ!yzwS-x-JpWe~M`;$X+)T@Zq_ zQ{f2L_iU&>9w#}@?B^v|f-;C&Lr~dmSdSnCX&1r~uJ1L}$MWnShA3U%m58%U1r~-s zfmC-kcT^2b<8qT?kngyj+vfG%qxk?5UPHd13?0FIxfAhl|2Bu#7hOpAZyn;eoN5M0 zD8U6f&j&#W)|VI>25TDfRlrGJUr=8@;%pQ3rNc_hzunSSW^8%w9?oZ_Eb9;3$Om5E zo}-1QXZ{7ezL9$-lZL-%{*S1r*nRiilgSYyMto}B&--?j20QWk%3j}G3FXhM?@a#2 zvhWMKRqFHUyfrYF2N zvP!Hser5IB?Bw-Wf7AO`#l7#?d53ItDj$IkXab%HJ>85aS`mdOTG2cD$QG~Sp4T>? zN}k@wANR+EG-DmLdCtjw1S7QqdoNGm;Q*eVe9vQhvykfWTPA00NhPv?v-dSjg-FCL z!DJK8o^w#i(M*ZPDC_3TX9=SR8i~3wSm5kUMGXoI2gwRQP*=9%w02x7GvgfvyC4pr@k7 zv>qsD`!@AJdHE311N{kxFr)|S+`|fu9;lOG{Knq*q6GPSa$>hVep4oTpbme@IM4(A zAu^@)Ku<)L?dpO49^DM-fi4v@tp|DlM)0%hfqsB0(t4ot*mgz_bOZVo(gS^%W=0S6 zMP|4EaXA*=^_6&nue zfwpq0fxl-4B;V&vKv)m-DCQ68f${@O5BxpDuN&=?{v6f=y@GZ~50w19upVdu>ksLH z-pTgC-+LGSNa{fU7?uy|fj+@u4C#SRWBVaJ(8rh_(gWpw<$=G)-Aed-QC1k%1Ldbh zo%BF|%PPZqpe?N9zpDqz{V=QtN;|9vI*r2!{@%q{yApDXGkTzMED7m>^6^es53~;l zWP5s`ytmBgfv)Dp2Y>IkvTIrXLKY3_f!@ffKb;;ZALfMhK>xs^;P1%~aipR?Z%)H{ zpto`xg!Dl7V$&f#(6dt_B1AUe4fxkCf=9%H|dEoCEdzt?t+uNZY=wj9o z)&pJ6sSW-fs}TMkx%i#*Ku@Iu{5_Kc{Jqs&i?AN(z03jrp2-3J9zVqXcjIcFm$_F^hE%DwGKT_iT z8Q+y1$Bm9<^B*6Z*~@b7fp4&bOY|YAeOD|)@?lgW!f!yWp)A9!s0R6$=Sbc;NIDG5 zZgfh47Ff+Jfama603+XZ`q*sL>4)mds!%-gJtvn&IfS6B$Yo9zlQGg1QQgT|{Qq4u zG|XSZw*H%T*0=v6yG)2k192`;=9WvS)QK-Dgq3Qe?1=8Je?AbVe3=1ob zPAN}n>!d$qb+PK3mYpt*vvF6wl#-fc!tZO9gH+%aja!t2O}$tu{8rzj|SFE zHa`^$&M&p4i>xq)hv}nwbucR1i^Z`{vZcq3#!q0MSz<(ay8EO&ay7VwDUUGO8xR;Jg!(j{eUf9Gbr`|)X-QPZ z&}^u~G9x%WGlI>L&QXDrkA;K=0-lVff z?Vw*n*%JTpb6YiL1216EWzvv{KRlRUKcyoGZ?kc$oe#-ot+Y$ zpI)MqKQQ0KpEEa{&k#2g+h8jODE6@o0~Fg>8K8)z8K8)#8KAg^2pFJnZrkXXM_hH09ii|#O?A6jIe|M%&l_(63cht@Q;gWqZ1 zSM7)@3KppOk$5W2?WBw*%MKZpEURy9Dr;?PX{c!{t6tPl-P!>1Y*~GMdn3rQO^s!( zb%L$%)mFDvhwb|2vYMvGwwCIew!OiX1yu}EtH^I6%WJEbgRk2Nv!M}0O0soD@fCc^ zr8TWes1&|g`rv@wxVp9qn|0Yp(TA;4q15IvAnBrzP%(p|;3O}qYt(vb7FL51EHq(h z7rfspt^-??1_J`8p-5IxgRrUQIGH|6YZju9P4m%4&7!7O@;h5=8)_RGL8UZ@A**UZ z_2R|V&^=txh**eWEX3mZ)hzTy_@wEX`DvJ?pMo-)9#I@_WmFnkYr%BghC-+agNnqb z8NH@Pvv!}BVVV&JZJse=%uc;eY)L~|-$^+ARD{#7B)>Enx}sc-`2Kl)R=cOgPmi4u z{f2YqmsjtT?{hODD(|#cr5(6-3WYBt$Fv0f<2???Ji{>!AM8R5)3h6J1d*Q_bGbyk z#Q&`PQr<|g9Pg5d2Pw`}oTpf)$d@_HC--Q;Q`A0J@dCxQiq|XtOc5`OrM!7cXFhUe zeJ`tD_)@U>?K%B?#XuaZI9c&9MbQ97x@dp`MFSN0ElvNPqG*7^FB+i0r`0bSps+;) z6et>?z%jUZXS)*>MFSMJXn+Dm0~EMQ)6Z2D4N&++0~C0-`X5u|`&!ofk)mjT!saLK z^os%wa1XUb0~B_f+NUat1}OaN)fNp<*dM7a8lbR60~9zEy8!DK4N#zHfC5*mUo=2r ziv}q0KJ|+RC~VOH1&RhJP&7b+q5%rz>vGmVTd_{DUGX%<3l*`R zI0LA^7!#iDlq!xK6@A z*rEXn6b(?IXn+Dm0~9D4pg_?81&RhJP&7b+q5%p_;Qe)Ltlzv2kRF^ZEErzjptM7es!7R8ekzePlU&sV%i@oFO4zfSQMMbYwv{}-C? zVImIBzti+*6rWfB2DM*Te20ksL{Wyw!1l2_3d(UFcD~vJ6$dL0R~)6tR}?INl;V8F zdc`J1Ij$q$O0`!ho~d|_;&&9kt9ZHMm5Mhg-mG|+q8#^8KVOfqKYvhsQE`Lfn~Iwi z<<$xDZ;uZSDDveFZ3=7=Ylz6lS3Ivw8AcmO|Htr4=#T#xLOjehp=&;-G3<(k z+v1b*4MQH53Aei%b`ZE-875%~>ZW}MmQrqH4MEy|uyOfmO;CRYo=*Q6+n1bDZf4fU ze$BuVltI+`BkH;=SjkXYO(@QMD==qH+eW@Bq=nnfA84+{*e=@(+HFBR-0sJ?Ku*FJ zgdnXEj&OZz25ptH zA7a08c04wD(ZZ*;Sbx6a=E{wEmE$KIvT;<+#EtzXI-5T(jBfsTV5)MzEz!MxvVZIy zFZTKq)*Fvm)Y{Blzvg|rVpOv|&PB|rXl=HK_WAjm_hS`5ZQguO-sCr5H5}a*OguBD zQTzK?;oL`Iork?Nm@L6~M9Q&Qogw}hI2=3P7xM={J--M!BQIhQ!Ph;6DUsM>=8L%e zCGyAux(+I7AVg!QASFWnFZjAE#pU*;<;BQTaXgnF3@TsOiMmsfCGs-jrRlIe+lmu~XT~VfY8`?n`h%Fb)6XN27opIR?D~cb6TCTt|0{ z#NEA-O78B(@OjbrRn8c+l|`-^xVvP5WPJ}cg1bw4KK>FqT7))??3y~B_MR5{jCD%DD8lmbGxVyagA$Rv2_%NXSx$ka_M{Yw5++7Y- z{(bmI?rsk1OI(G2;O;VxHmJSnjno#SiFeQfxVxqUUV`d)-pC?j<|d9s#o+E5Q?xg| zQ8@)t5w$n3L~`~e_}3pUSvRyzX)SVh`Sn2JO#B0PH&{Q9^^H?An%IbLg1Z|uF4V#C zYUU=WUJCB6Hl7dy*gk3&C3p}3ch{trB+g?)6V&XJplTnuyCyYhb??jEwl~!y`!B&8 zKyY^%=co&Xa9S2k;qD6Q^I%yq*pUS9_rTrdiaM#)5YIaeu_EM_RfhH^Wx<5IJCC)? zcpuZ9an^o0dsY=UU5O@s%AQnb88)hykdDpo$H7wVO;(&uiV_!XAr@T;1KOL9VQ|Ua zy%uI-E&hSK%QzdF!EP=M8p7t`tjp)a4RUu=C`s*2@3!t*fZChh?ZHf-_NI4-T3%uv zyLo38_fcwZKF6khrl!%}^zJG+Nm|ZN@CL!VTg#Rtc%BD$m!m}O&2wo!)b|(YUIf~k z$8gg;+;@|h0~0*4fV&Sm5q1 zmo=J`IGt zk7vEm-ZY)Ed~S4dcdwLHi27GB9on15_I!#ylDli{T>nx|HE?%L`F#I;G)nI73plG% zdvh7{gS%_eD|~)%OYSZO^CGFy{_$)N+M6bQ5C09?;O@q8Ga5;a_kYXwp}lDiB@_J7 ztRLK6lYgRbGe5YyCjCJFD%#-g=1Tc#{_7l7aCc4q>Aw7;I=H(W9BOaA!gO$VrsQ|%oN#wLki(Z_3Anp7u#fwER7UQu8NsMu%k>9$S7!uT zq#s+tn2CHIg$!7*yK5Za?mosG;O-g+ zv^V2)fV*oP;O>^PAJE=3tvm+p&2vyadnIEE?M>S3l-SVTq}>?U)ZX-&EZX-CWd6A}?A^oaJhoxR{0-aKQh74f4vG%7fQBPG!sc4veTczZ>& zXkdgnOe60>bwc{3(`jNEelbSUFAY-$q+cyVv4HK6emkp^IvL&4s75_B+RdW6CN7-| zp{hyEO;?L4XVX*hP7p{*6wOlcPUVwk+xC<~`g8hQQwsSbP`Rr8sreJ({Cl9Ud2A4q zZ4mO~@~aR6pE)@Y_tg9a$e$MHWd81wBbLcgSZwWzZWd8C)U;h3le&7ObE;6N9~K&A zT_x$(G{=`ksFWi(U^`N!U1doJh6%n((=84Ac0l?KNW5&X6Xn-XdWVLXzq@UN`8$j( zVa#)8!!!>QfDQc@yRmFNojVns*}x+@vw=s3%LfEvOlHhQETjk%7nyhwpi7tl8zf=E zd@P0}%ovLx0sn)LNJNC#>NwcB82EU_wq_8xV?%ItWd|b@u)t54EK#AhvMR?~Vs|jY z(>{zy2P5;0;dEr$odH*uFcCJ?NeRryp3V%F;89Tm*B6HeTNd_MdyCy45BgfHk)<7s z=1aD@69BAIWl$NNh6N1~4#ol*)RQ|HVOQZNa8Vi5U zh8~692PyGTCzx46L|U1E zIOx^Jg}LIfJuV@NuVV)t0V8-S4mar#mpbqOE1W$m5!8X~dExARkkM=e4!jARUO`|p zK~tP{Wm9qGs#70!1SjtBSFDNKU!>o`}$ZP11HD+DPx<~*fb;f{bS z?8BWKcb;2r?-ffqIjo|+JeKX`mk%2y#m{n+<;aueJhO~6V-Sdc8Xq4Jh(R$fbh7Q@ zqT*tt^>$8iK_Tu@)GJ8;Xc;cK8VnXShrHR z4w774&m30wvy+n%O3!wB0t||wYGy8LYOaGyYg1ztg($14TNVg$GpwN5LgFonl+}ww ziM6vv>!SJf^5fFxC!$etnoozHe{O8DMCh{W__51I3qf@8eAVS7aa6dT8A>Rrn_wq` zmYpRqPec7p}qkg zRitmt$POE97*D%1=Qo4B6=@B40+1v5$W7 zMv3FS6~~y@o?BCl$0Dn_<;62YZbNd?I1WTm3j`tOB^A~bA=s(%l~eHD2Z$a1`= zBp#v2`z6}!7x8$-lNC=_6b>5Fzo+(E#p@OCP<&AFw~EgwzOMMT;)jYZ28HeNF)eY3 z;vtI1C^jkzCk*-4sLjv#S?(&upDM0b{FCBaiUV+C#r(q+_fb4ZajxQViYpZPLYCz& zR=isAcEyJjpHzHB@jb<2+$pnsN^zv(eu~o-PgXoz@q3CtQG892B1^1~3I)W0ilY?w zSDc|ZPw`U4>lA;b_^jfqihoy(@v$%JFH$^Mk+1pbruPDE) zhV*r6|3UGKYT2HKXRGYTg^E`y-lq7l;$I_LHz~eD#PT5# z>2W+&p`EQL8ny8EQoEmGiU@zX+9MUms(*jACo3MNC>&$df2`V#iYF6M-&tx4*BJSP zYYhJt^rPR`5OMGgxW#vC{`=LxPVHYS{+@_(FKGJP>VH>pi~3`zlkJOkA8>!QXDj0H zDD_}B6ogxl&(v7|AjP4IBNX}Shv{W0jDaE0R<%)YM2HfL`Y6l$T z8EW$tE9;%BI8U)F_jsxLPf!%?bd-}+!q-%vI!DFWT~|7|6F=w0BnwxW`{pdnOUb6u!-3 zzB)y|xS}oRJ>V&t4~Nk?c(b{(k52cc|-4?~H;dKb~|hF3D`|6*L_vDR0ds{EzW z8D4~K5(FNX7$#!DluU=Uh%Mp4N<)w~0X9xS7LnmuJZk5!Me;fpkmjgPM?5HlsMQ14 zw2xvA1|dkB4@VGZ+KZSo-`Yk#Uf+h>U5^RKU+QMNnEvT@c^nMa*VNszlJEr~NaJxc zT;IH1&3hNthto&8zSW2aWe~N_MST+((GaAqf*r1}8TD}tSRaRx2MR~UuoLP^t}MSaK2~JKi;^kCNtp^xyluzMvj*3pUhRh z0CNUg+Dj#H@-N0*&)X4G!Mpyp1* z_+QB9s7~=u7_TUr!=hgF&nV-(iGR@nJ#U697Uex|oLoHH;U|)@VR^6S#Yh~+Rp`OUE_vUmlPSO+_H zrT$d3mH0M>Dt2w`Wq8SNc5YyW*EuZe{EKNf_Pz>fai@8rnXZZSSc+yKW_3LNo3-HKPe0Ox(TH z^b+?o^LRCL6VGsk_Es}LaR|G%kD5h^4wl_l&5}et%T7?UPvTCN-A~P=)g5OI@SEMK z9`D-|mt(8CU(1$zco2hmPwY<1qAC35-!S=LSux=^CoyH+8ETW?JR7Ua8-H14@S8tG zYin%xXs-ehGv3E^XB&tvMk#7klhP82fr(X5ZeH2h}w*V>TbH@m;l6)^l} zcfGbdK5;qMe5r9gO;6^sKPM0&t>0>-b7N< z6T>+rUg%D)KKadjisHVMI|Z2{sW}OU<|}z}4+4HOrPSRGI@!o?=C)?h%+Jgh^IOQ^ z_qY2ZsTr*$<1;5#p&-WK_rND2#0cS<>o5>4x!EZL{75*i(!Ecs_2;evK19=zxW|O{$e*taq zoB5;S&&tv`IH=Fzu{Y%(B_{}E$K%YP48+-%LWLlM;S2cLlSNsAe77NMf>c*m-Kvr&#o2WGJ$El;#8tWu+_F zo}`(Z`Z#SfnNa>UIOOQhStvU*4ju$m=RSbtf+GZev(5&=0KfUy%mIG0X@&geqftG3 zC1VPHGi`QCZ19_D?-SVMH@o0BH^AZlgB=9FnFh!FM2;Ew&GJAn1%5M+>NKP(@S9hm z0Cyy{du?{1O?(3!y?NAe!Effq?Y)F!1%5MIHSOOU6av3_PqYGlGhKab9tLD~V}h+i zJQn4S-p786ey$@t{8Sf!|D8t_yy1iI~tP{w>mR zJ@x|Zes%a~w28r^kMp7BE=M5$$w_K;SV=6Fot%!=QSbNR0(m{PJ92^F{2tgttwg(0Uz={L&a(i{!3E0!XNYp!*qJTuWvGb0{g9`*kBb%ishW(F42*q~QJjYTyQ`rtq3 z5T`;A)&~*Auzd?MJJ#>f|Ia8`yOUnJBYJ6PIo~kZR5V2m-*hXHT5JoW4%t?|5L+b> zsYNU;Qj2(6q!wE^5UGV*MQU-94Dndw*yMQJ5R)n4Txx@GNy%EjC}xPpS-SUdK!D8@pE*HE=v7dExD zCCR;RKD4FAh|SW1=q@CLNeqV`IFyFrfH3cTNbfFcnh&mcc)#M#w!E&IioZ%cZ>XyS zsaptvZ4Ha-gjo)*Ac=$A4VQxWy`&A?aBxY3mCD)5=~-@C1X_VvBerSYHYCvqcKLK zQ6sTJFqThE)c;!htn=p1KopaFiTVEC-`rVe?{m&R=bn4+eYdQ=@4#wTY|i4t9OoQn z&BkG_SB;qIC^Uw>Txx-WSE0uwD9)>^ty&0P;^LZM*;oYFwP>b?S!1Lw<}D~Z@&6I# zCYbd9e$wU+)3p6>Hh-M)^MGBpq{#ji2Gi-VSW1d>6fFjUuFM6xt_~w7S|y9 zbFbV%qo+?MS-fIc#T+nI=Pt}GuQ_57Y0|m=Lxv0*Hf$Dt-1(mH@9{f%oj1B!@%q>a z(Gw%lxeq<~K(k=<04S?#s^=^UBE67I3>jB3IVi{^C#Mm!pfp| z@KcUdsYG3 zj{MHH=oiO?8H*%6i;^||H>RsK6oH^h`W(ERLJ`X%9DjNga-&02$u?13Xd0_ zEIdniiSP>H9YVgqV>^!t`F@o0X5q&|a=|JP!056vQ zdZBS@pf^qo(6}(bX1KCtedE9YdrRI`I8k_jaG`LO@Fd~c!pnrbFQVNCgqwtP&Z9nx zX-sS(%nA8;oBD%=hY61p-Y$GtxJk%2AgssN2*grhCt;;ZxcQw{Ed*$ zs%V$5S&0?G-Gq~cvxG~8#|TdsUL^d9@NVG~!WV^`g`WyDxD#Q!9fTFa-GuuHtAxvh z#|gXQ!6EDS6YegYBCHY~Ej&edzVK?{Z-kqK9|-?hZs&<0TCjiT3a=F2A$(N$g76*T zr^3DPbd>cE5S}IEm*l9wM_7ahhLqb1cM!(&#zg3B;PNz__F91Ll3arZ-u`nLjSttw}o4!H!djBpG$8XP^4RuBLL*W zeqj0<^7oE%iLhK~&pn{8lsr(lt8jN=jc}20nQ(>h7~yfkQ-t3Y@+~^szd(4I@Jbl)v{2_OjY+QfH10>^gf)@%6^9Q2U_w(xwwO>Yk^M4T+(f!u{x6={7 zR(wQWYx#xyj?11{vHS8%96}qMNBrXR#z2A7X)sC|B{+HHIF}#;>|BE>66}lB*FiGq zfRhieJN)94HBk68^V;KlHx~2FFFvmtig3G?oxt})IkwC8xE(~Ei+mj4@sngp#329#k$zUDq;V-}VyyKw>+dDI4kLO))?}teHIy7=7jNQJS z?L8ZLVS5+D9=DJE!w}`|Z9tm#DzS2z&@u>4&eZ>h?$zmH;#h4_f;V2{5qe(_^L3=KnYGuwso%lL?|wbREwWzgGe z0U7P)m)p_5=krp-KCs6_aD8-NL)($qsr~y6-a$TMNl$CA5g&2uEr_1lY`{h^5#zzz z-z}bs*r)LU#t!u~39yj*Q_z`2@jP4spjn~01Y}SJD zQ(J7j@M8?n@F{P_<`&H^gcPZa>`ZCz*)d4b%60{(&fa?W`th&7zAq-A8{2qfDF&#R zZ`w!WXypY!c!?TqFCRmdpGZc?&vt}pf>+asn`#%Q2cTAbayf6J5jWMYuX~|Xd`g>T zrb<4}!l?v_35c6YXM~2hsUuJ%`Y`?_6gQRpkwov7dors=+f63*RPQHWkDR2o-gDw?MULNa!=F=Zx1d>-4 zZ-Fw+5Uk0oT2k+#<5eJK-y9~FFnMX3gtW|aw7DU90)TX|(`n%9#9vKBtknC_x8yZ3 zR*f?Haq{|h>^!-IQMA${Bo=2Z2HI{COEUA=wUH9bGS{;1 z?h?y0{QgLKl*INKvN+PCCFZ$=>4~X#*sEVBkh^yw(;W4`((>{H~6ddDP@}0`9+j;Re>9Vc!n3K>FTtj z;W;j0dd^N9EO7~GxbP5E=BgGzZGr$U;Zf*$D!nqrV8NN;_?JGS1=DP(8N0d4H-vf2 zgP>$6`noWEOR5Mp$t6tRTB-`<5~gqSGl5*f^zD)ymoVMHCA^ePHRckg?`$#OT6SE* z^j)f3p1F{lc)yJjxrB8TAM9{7x<@V{@0`;QcleEoT{COg>qj%6nAkHDXG4#rTk*E9 zi{lcepHxGROPKzZHo$QS(;L<9h|G^@>gg8ktnR2xXNu3X;1}kjT^yG%{acwDo4JYI zcwTiUWe(yjexcAV_rWC`%iNbrcgCQROUS$R^sB|yC`2ydq1>X^n(+u`tW@3`r#ES` zkxR&Z&8n^JA7@LeTK=OR`(+Tanlr2QpYX3|JUu&_;^<`O(k{4!EQdXsZOy>|m+*Ak zgn0HO=7US<POUTno6kNhW+6R}=l^>hsLz*{TW?aHyv;i(5!#9dc$V0*Hq+ek`LOaPsb`Cq~ zX!I!&zX1ixBCkTj2^uO&mEWH)SRvNqv~4Ja`T-Oc8EmGnlESY$!2MA z34cvf4Evo1myiNYP2|o2m(a-tS+X$GO}T`xqOiK%W@8#$!tR&~MoUBt%X0qu(bV;< z3NE4BkMZm-+#qlXS(scxMwv{5OUR!IatS-IX>bYMR!qpwW7ohXB$onAUgHv`!6p2G zb#-R;8g3=HgzkV_n59oa8eBprJ1$`wTtX+W&hlYf8eGD`XrE_v;}RmAX32O{fJ-=# z7QiKB4~$EABob+G32DN(gio$b!4_<6!PAVON7qAop(Xa zNOcJxu62hphqZH(rRTKZgSL5)r&ISkbRjag^ctjJ!TJK$F8nfBq{eie(9sN5$10p} zL0fNwd4>!(+b)5P2>kWxT1Z2>IbS~EJ3}<>25=XL5Pu5{k++PQgBTM)#rd}-Gi^YPS znLU_UScAx#5;H{yJv#HbGQlqEINa~V+DEtrvF@nS+hV6~jula;uyCn=j-{E65x)}9 z=S|d)eH!Z+xdyse@7iVkDE6TQp+AKY6wvB+8JCS|mazr`<~NMXuNmW#K}$RTGeJ`G z5lve}N+UCi4k-GTg|zL?sHO^}+9MPJwI|CrE{dB*Mn2s+Z^;K##ZCS8qM7z?91j(N zQ^Vm=8wF5h092c%JP&boyilG)kmiBdWU+%fu;81^kmcB*OtDJi@TaL%BGHHxs#8KR z&7TxNOI%jZMtF=GN0Eu)PB^-LED{s3g8WICX?l=9nV9c{R6P?*olsog&=KAyH(4e? z1|yT;yFNWsgQr1TaCX!Q11Do7BODnlI87K`6Y)@)Zl#~Kc;qhP2ati&Rx86UQO@~XZ4FXtB$3be~!4Fkf?K))Gey3S}=F6qo;1eU&XF( z;IHC9<@eB06sbIa73n;G700RPuR<;UDlY0mjMYEl>d+XgiFE5ktd*y&f@YdVbW;*Z zXCYE)``AYo0JZgiG9Rk+GlVydB|64VU-9mQ$wf?}-E&0?Sa-HeWC zlufF*i-X!cwr4IH#R(+OKl@(~e46LaRsAopT)}2*9O|?RaZ*=;?&jWwIiBD4$*mTa zk0D)M_*8s*X>sk+1v&edr@tA$uexq-12wOzZv0-8#svty3MyWeOM5OK!nH11jUck~ z=hxMMQuj?*(;W)y-QpZ_(04 z$i+#6vt>c`k|otf=|n0tFKjx@0c{QjaZXvhh|I|)D;Lx5ev>eLfZ}!59kB=m&Q)`l zhe8PN0245DUaXqG2<%KuXb|<5u3Y9#{}Vw>zY6X3>&tdMd_X_jkzbYbik;^e?_X=~ zYooVp*ynW%7O%uCs9S-FbXe8mYMXI$R@APV3mrn(iaX31xzwUolZXs1s3Y#$4`1N+ zWuueYe>#S#i)8GhVSnuiuY7Ru_xP^7-W>g37|%3(E&O%lxANA2&uBQl4gA*72@&Mh z#z%*{9V5?%`-`zj`7WEtcmG7Zx(}kbE$K!?p`E24Dm1+@9&k>MYR{LUnCsE|I_lvfCk7yeMVQTPYpr$UR`gL;hD!}>c5`5J}t1mSui zU)fM^!F+)CO8%9QPeGZ#S@<_0Kl(=fIN^RmI+0VqQh0*!Y~cpsEy4$dzY%T{ejwz# zT-s|T>?Y)^Fl%49pK!i#mGERCzn97KBlt=JxR>x-!Ue)r!n1^z2yYVpLbzG@sW5|M zk#;)>D}=iVCktl@mk5s$o-X{6@Ot6B!l#6<3f~jP@f@G+wh~qg4;Nl5yhHd~VV6Qz z&v>n-(!VAB z2a-P)ekOey=QP&O2uq0^cgdZE{e**rV}%oh(}?Jg#WDq2EK{JxGKGDMWeQxS@<$0z zP(6!nit-lQ6!;_MUn0Clc)jorBFfz@d`|cx5$l^ow6|IKF%jFv&zljsus#kyLp$$7 z=2Ix@y9;*~_7e^g+W8*k#z>wgTqvv++Ib%3j+VSm_#NTt!gGY@3x6!!AiPd^lkiTV z{SLtXFC{-Nd_}lP_>OR^@Dt%@LcWsWc6Sq!2S$0Ia982(!imCtgnY-x@&^d*_XP5M z$$aV0{KJKOolJS1@MPg>!n1_u3Hf@6Jk6F`is7U2N%r|J)b2Ot593 z(1S168w#emU%9Z{3QM_v+^<~5V)b<>Uy1cw+{s#e-YCd8tp!9bGj|Gtt=R9pP6gQc zjQyI5)z?8X_#C!2V2=64=gon_r2Cfko7);>et+x!^7`%O2ve|erf%oqF$@=%Eyfv_EyC_occZtc|= z29BP(ZtLAiuz`bn9>q0>8{c^39Bh2?zL+FyaKx_mBO;7`jA4uC`M|th2d#AmN=C0` z&XDpcC<$)xQ0x+LgBiFlDsJ#1=EM_|kQ1GQ8sG*WZK`Af61c&$U;*6V!RSB}ZtycG z=efbHke$f290OGpZ-2=XHp1^?EK^y=xddKHE4D&{GI+wTGAI59{uhixg-CQfdIg>^ zI~2VT|G*PwI@t}m6O?MtL^}o-nIMb4*{~?pf3zPxy4`FrcJdG-o<`9P+^v=0KI) zh=1e>7a=!84k~!UOoL$50?+lq6aF4bpoz?5=q7l=PE2JMnONq;;ta2Tz!P?&=Lxqk zLyS4P0ojH0MB-J2Z5!JD1SZH6z7@L6arg(Gurm;3K1QqH2|F>KA)f|3VJD_CTUdC6 z#NrHZS<|~oEXkZfaiqku%pI(|yTtO$DXcq6V*AVs9E{Nt!#rW~P&0In1W%Z0j7Y{v zW0TSpV_=nKDzVeS6Xu3Nj%F^QJWVor!Y3f745e+8!4oEl-FU*YY2C*AkW!{;{fF#X zRe|5;%h>Pgw4>POdBPkl@q}r(@Cf|lsun<7gaDrK&761O3G)Nm8Tz<_C(JY(VthF8 zgw+ss&j>VCav=Ijo^Th`6i-+c#1mF|@r3=pn9gqAk>)YVn4_1osh>$~)}m_8`~W=R zW3A;pPuSHh&s@d2_uD9ic*4Ix_sA1wSX=OfH=Ecs^ALOeXr?sD+@6_1Z0NCcg^78d zuxlvK6LuSr=Lx%ZM`Yfjsi#{Eu)3o%lPNyaVvLD-p0G1DHuE;S@w|?MNtt6XOyCJ` zvF)9jsb%g%DEl|_(ggH8Sp0L}XAiF0A13cjkwh8gWR<;6F7 z!mfTv_Ec^Zc)~BG+3&LKaV!s>u*j!j8u~Fgt?nfhX+phh}f344yDqxa0}n z&-TF+cBhh2+1|7dp0F!FHfuzG@Pu9dgzVw051uf|gV8RNviEZs!4r1nr)DRyeei@i zIOGZcocZ7h+d~QPgn3+%C(J|1c)~4c5IkWXBgPY^X9jt~JD~;R37ZQ5c*3(WWX2OV z_X6;QceWDmBryIw6x>dF9Rm{DNhY#$D8w7LMEsX1P!{1$CMRg9C{=!czGsD4kJGlH z5bBphVLV~ZLOYnn6W-U$IH@n-FoGw11GcLCPIS(A!u2R&VJy?&2~)r^o~0W(dBSc4 z5#5sm0-msD1X|>VC*m|;P9GKH3BN^CWTKNNOo673VpZ^jom}9^zTgS(kL|!A9~3h2 z2@0#*jwj5}l-ZMzL!K~y{b-8LKI93z{TRJ13F`p(yisf$dBU^+p0JU}!4sZf zB6z~@!7#4Jc1M#t-3Mg@Px$+=((#Ar=-S+Ou$4g$YY@rN9}RZzg^E1k`6vaR@GhuN zo^UBn=T*24QtTz zQb_)8EQqWv>V{j3$Og{b`hFOUac}f7a`lE}KWh4SgMru;$zlq@0KPji8n%^o zB|*cc1i{g;t>iZ}?7hGsZrw5xYgUvPUbL%7);JJi&78Pb%b^(maw}2PP@+xCNKr^^ zn{6bv3)ja~Y!&HIOu}>rP>%C|Shji-r~TC?*klRKdA>nAOhzZW{LV$nAR+d9pRPt5;Ekui4=LK|=N}q;2CM+YT?g zVtc&oK8<WJJ-u}WhicLc{=5RUGv(`qn{wRw7p1p5<4VT}bx#Os+Dj}>~tBuh>s9EcS` zd!zMCEObJ=o(X$M5gcAn-_VI^P&Zj7LI#JL;JZCNRAag?j$dSyvw!SCPm_Al9tdAVJ221akJ0!ou0s6i^T0WfFy2i2v?H0*+(~^2P0(*PFdTK zxJ!|PF(+^}5;qg<7xV--hTm!!!&Q;c7_N$j#&A_E)b3Q&wIyn%+aetaW=Mx*08VHS zR*t{vMR8;t7K zV4%5mI+Wq-M)=~z#s^&Xi8u{4EK$ExLZcQ>d1YfRyVr(_rev4no?-K4WgWZZx@OTU zs&ZIErGp3+TtmtzB)?&QZ+Lk0eev)_%?8V16PtxM5y!#5z<$h51fyX8?~Zaqk)~Zp ze0k;eu#Azw!sFI0{;HLdAN$rwb7cME^{k)sN+9(to6`!gg(J;%I9869Uxp&#b)&pe z81BbX90K3C7c_}MdGO*za}EZp|6sg4s90LNw5EdbArH2|lm{>R7x_*EVTu@DO?)lf z3pU}VQtkzc|AMVe{R>Vw()kyB#tiru06G@Ler)~&WpFl# zy|B7ZpE%tVjX$ZS^|F>;|NP;o0$YiKPGv1yA=w8ZUo6y{>Ja& zAM$&s+IQxRJ^Br%(?Feh4b*vt_mVjX04>4sx-DqCO&ZX>tLCp zzKE=OH$0-o^FUlSt>2&~k-e>G6^^>q{i_x+u6NykCeU}Ix9vfd5BvRp+Y#bF?)tF9 z-a2-fftc-e%WCE>n!l)Ko(tz*Q?+R6{92s#7gsN+!>oi)#rsO{h|0+ykK-fOtFc5nQ zrw9)b+Ith^uaSJF@O@OTGoGM%^JWY6k@J8Vq!v7H(69{&@;$E8e2MFz1 zJ!D3G-plD%)l0?7<>L_6z*Ckjs!{y=z%&|-a~{C$#N z5xz;pzTGT*mx#XnRrv)tcTp}BT1;=)X)AdrVHYCweI)l64v~Hj$>W9Q3jw?43jtgt z{Sx6Z!sCSB6P_(RpNRH0NWMyVo%H4d0lVe{0epyhZ0BRbUkU#}ME)Oz?+CXFKOv&t z=R~Z{aSmtsmcsVJoN#9%%J(Ir{O;0^5i(>F_0uHpC!9@0y&B~oAv{s~Qzc(OMEmu^ zD}~nzZzRJ0&m{j`_y`g9pH%+y(!V5pUHG1@u%D2>vFx|~P6EeBo+n%=tQFP?*9ealo+La~_Okx5RuAA$#AF z@yhqUCDSDDC$!&Tl=r?Ri=-!Sgm%q$5$JtO)=TewOYHX=`QEq0ey1UO-xB*~2W0PC z@@28$Uy=PyLi>G3eeYZHSLwZPNs7P2$oIY_q$*H0dJm8^1_B<3(5Qrvzb%>M2IiYDCXhU5%H(wsNp&DTC?sKl^6!Q33qKN)!@&HU zum=(SB9npo5yBb5nL;udn7>ZQcY2gB6<$q*9a0*ozgvi(chmdh9HQkT+YmpShW>m| zF4<}K%hK9I7!Hta@6xZ9C5aAo^YXXv2eBUXyN~g&k*h$ z{@Xtw&<^8+L)h+r0FC@6DC6+3r4#A5&szdT*xt!~oKFhv z;ZiPdZ#~k!4wAt^uy-;OT72F*$YFcu!QKtf(OxlD-#`9-`Z`Dke}ui|ekX?V_OWfsXwvRXOgLhp}SwmH}+p3VY!>&33sEL(?PZ+Bw)EpP{jse<+$?ygf{# z{IS8z+2|kd-TmUr_3hVxK>u9B(r?hv!Tp8~8QgzZE>~%4_rG6d<>0}Cb2)ye4uIv$ zeTJrXwbmN>3@y9)oYdfr^_wf#AgsN8L*T@q<;U@ZlUvR_@S`oSuQ`5?1zS#9!*2zQ z-JDv}^5fX!$a$1Gv3KJ!=8fH)guWoJce(=T5>0f8HBZ6AsKCBA&}HM9@Gz?1T)GDK zhSOeTIBVXwIat#Qd6CMzerKnTtVu&3&Fh^ux@Os3%k~WJ!Iq6^h3j3n&*Bl1W{VeK zcI?ixK$9i01O(GhJCWlaPwP$#y@$zj)_1H$jz%-;VzUg|Huq7U3{S z^lml{n&@TBTyE*)U(j9w{EF5=mx?DYk0sD#nzZ-CmBr6OnI41^iK|*t@0jKEaw=kZ z`V}QEP45Odvl((?Lz1j!kcBhXVyF^VC;n(6{EDul!E0iy8ci{MeY?w%N57(3&|!dn ziyFG;Q)Ua7P}^gq)tS$nbmB2SlSr~ zG8~QMaEb8@w==n`#8ig#@#F}J#hI76LAyyT$xLBSM@lTq+{e1RODs1BrsODz?K5|< z?r4d*ptK`Ory|LTDL$*p`~v$nxp$#Gx5B7@Ov{tf6v;x*(A^@rk8K#_XvUn&rb)&{ zZy|3G_^``18Gc1^7&tSMoRz9Xvu?Z(DP@}blpfc~ssc9z7;yHxIz8BOQyF$FIcFyh zmi&rnxNtnOxvGUkd=dos6&;DLrIIUCYanKL-J3k31=DQkGj@BGZwR}G*KZ}?LSGjq zZ%Ms}KGLr!d26XE(61X$Z0O(irT{hMD`vb{4ThKos+NC73 zkcID3-SW(h6z{iDqF)hz3X>0Z_&yFL`V}$KN%G+icbnKXb0{$RXy#QDduBQ?_p$V+ zCOW^O+j-M%|_)LqICOW^O&vfQiji1lP?th+_raWrZ00}DlNs3(y!=oimw*$g+lZzTFWhZtr?GCet%#j8``AF zM!zENYgTP#|2SJ(aW}N09{Z&OvYIoi^|ScbGoG9sO>uOxyy!~e`vW>$%xfeGzoM14 z3GwWO%!gl*lT+DcY#4q;PA<-#%BcpwB3Hj8`)xFugkRBh_!XvK5reNJ;aBAHE3-dC z^GWy>*@Lq#1G8N@`0y)o`9rg3QHEa;!;jOi=rOhrzan=k8I|RO>m>Y&T=}uto7q16 zid_DL>;bF~zasa2gGt%TIE?Tsa^)IrSHv5jB>al(fgb#dcw8mnSHwff z{EB#on1o*uj}h}L`V$rKE286r`4yc@lkh95#E`|hyqw5(r49HM(Gf!5AK;#b@I6*^2sq*{tek;U!oVE>xQ2z}m%&&;E&<c@=mbZEQ#+A@WF1DU&%LAcAJgKbkfl3m7MJ!CeqFqrg3BMx#Owg~0C%+{8iriLA z$j+cW_!TWTdsDL$SsvdXI0~)fc*{P@y$ru1cfc*oUd#62SLEbn*$S4&_XnK3I(sum z34TR8**=F~(G(WI_Xqlz0)9pPX#svk>_LovMc-u!_!ZHF`4w$toA4`g3iuUWKn47Y zoC1DDd~K10Uy)P5uZYh#lJF~X3iuU0$rA7@a;?y>Xco+~S2m{bE27L!nGC-o$|Jo@ zzoI0*Kd=ajY+K|c;a5a~W4@YW2EQVE2;K#LMLerhFjMd=T8Ay-fh4)@)+D|^a2*uw zc-Be6uZTOh-MJhq_!Y5L*Z$9aCHNKbbEEJpqN;s_rvaPYm|%}0orv>5*LMlHjnL3V z(S4nukaMsQ_es_P`2RHH7QnBFXFm89@u^4>ensUb!msE97{K*d98K~nki!~8a)-en?EVO<6#R+?qZIs#7@Z;wzoL^+rupH}CI5<4xHDV|5v+oa85Wk5x9En zivJ+RTjs~h+v5PbKi=L_MmL8kqS0Oj#OZOGrjZOi`b3a!ZBfyvXb!ZzV7tmf~) zo?Ywo1oln-4!)c8cVKt9(%%7K3qI2BINa z9X~rH(MiHjBYqZxgw2T96%nzsv!0f{iqz#an9g0hfy%rhQ37^zx|&jEA{2d{BDQ9J zqU*p!hT-9zs_XpiN&R39k>q2s=8bvKwA!^#q68f9ab}x_Sl9)34>h`NhHpv5Ex0@0 zA#4-Zy@5HXfatYLt4Is2vQWWbnuelNI~rO;r1Rwrj?QSp)r+gOP?Ao(Vo~kVin>g?A#s{4PO%&Z+C$CQ5^SDC-e zIQ3&^EU8|MU*@1{C4Vb|J;#h0p6j{iKKtcn)YdMp%gwJ{o*TVgsBj*X5e{iS^2vOIWUdWxrv32bAl%yat~@sH^FfJ81Ou$$fD?s~A=>2L$T5 z3vaH8-4;X>gm;YmWi@S>f|gnTSb`2pc3;d?@c z5Mn-G-w|`dDZ+z=jN``qh9~N#B8b1i-VwmnMUn*qqLdy0nb>L#jM+tu@^r_cO$S;X;a)fgaQhAro+aehV5z@HScC_Hl-mk- z5n4=l=!Zx)-ZJE=lJ^%LESxJ`E?h7Ck??XN_TAM&hEa-QHU2XDBl&)z#d?RH5sz5z zx5D2Op?_WS+rq8V8^0Op&!snBGtw=|0RVDgKQMg_?K}yYoDk~Eh4#z?G9SKDKTycm z2$bzS39OO4NJs(+^H&J@1dZ}>!c&Cb6`m`+KzNz(N+I84vi>c?yM*@&9}zwwd{+3p zkPn4f|2^R+!q0^KHD-QyVL#y@;RxX<;od^?6G6TGB_Al9D_kI4DqJo+MtGd?J3{g@ z*bh5D13gdmXVQC~>cf&fPxTqe_OuE0UXi>>*p#38vGkt`3wZuTJs0qk6YDWZTkDg9Q-J_@h|5R#`{`>c`jiaoDnPD{AdbdkQY^Kj-Ptw_-~K@ z&iG@&EL?Mb0QMlbg^5GPf4C($<>y#yw+4I8*c@N8V9R&be6Z!-HScaI`Q({t=EE6pGIC?0f#l_;#V z`iHDM@=+?d`Uw-}i*D)ieFbbrb>+#6pnB&ECtUMfN&!M3S z%49Si=bVj33jT)NXe6~aA(}9U%4o7Vj`P?7C=i=mKGTXPX5;vb9e`4?DQyljRq}6C zk#!SWP<|{`sl-gQ7fmIzXj`<*XgoQBh8W^E-n-=_rhkrq@yfC)rjJ2?<3n2-AtV*= zLuD@dr?**T7=IRV}Fx3Wwm|K%|OTo)pc3OVbBK&alCP4aw60WZB(=o)ui3h$4%j z-(!EF!E0iy8f(Y&_3a)+QBpL`FDR0F3pJWE9b?eVRBIcklFLx2Jk>Y#3EQ|5MN<7* zGL1G!(M*%ca@mR{F#MENG#5fiJRI@VoByK ziX$bK8PzehyTtO$S*$xsVteBOrbbK51*Of|QY1Ao#oO}C``CM_y$kIY9izSr#Yt(3 zM$znyou1mqHq0oRb(E(`UJs7d3T$!=!)==kisoME+L@8mtQ2qR-FP2TYB%_>ekpra zRp5pop5c8#sye+NN`k$Vv5w8ziGwAICJh(X;2&4Dkcji~04SQ*u&b$+DS8)W7;`ms zL<{pY;%2a$t9(P)J)CtVyP~fPQ@5l@j3Grcb!(|AkfNEo&Cdi^>cI}?I1Gv=9jQ|fclbSe z3%XY3T=x3WOoX@B2>nhrUh1)QdlMZ+Gxekzaum(fue1SlAACjHhNt zQyiV_Tn-#4nmSyvdvGv7(X{W)b%|TZZOCO#PGv7*!=Pw7x!3}Qr$Etk^-Hqz(P#=3 z%_nf7L5k*dmIp=C1?vqUp9`f_;)81&ZbgX3vFwPl2Lo&*VVSe35$@6is))EzG{e_CV2evJ3s50!7ow ztFw%~kOD<>H*^+fa2NU=EWVP-rT|5A9xZ^P$sWXf==T&Tnlxb)O-`{CD4I?Iisp6f z1SpzL0gC4LSppPIrvOFsah3o@(p>=x+N64?ce^v_v`) zkKlhH=U^`+tOKA@{)JlriYCu|plBY)hC$IBVq!EE?}xT_x*bv?!W%n$TcChJ6FU9~ z1=r@*WAlO>)*zCzXH-FlSD{LSo4F54ftyMCGK0FGk20X&LMV^6yotge@GlCEW-nm# zOHn!z|Bn5?0slKi7NczB_l~F;N196{Qw$Q`K`iuU36#Qf~T>?PjMi6u*k{G=fCe`jeOGlB42DXioBgK#=GEv{~lto&ze8r zizU(P1lFJ@t!+iZ{(Zt?(MWSfR`^T=+7yI-UbPhp{Uaey=|OGOvFfJua?vobqe-s*%wQQ8yr4KY<&Js#dG!h(0uv)=;k*W2*J~A5W z>NI2E3`}D!9$b;&0K#clW5JQ}dM1ADgj78fuQ_2`5-iO-W77$(Q7#h9B>3J;5A}vO zwYFF%A}Gb;L`RT~@DY_WcM#!kmcKs%<fE}tkJJeJ(JuXvSo=bU1{CqBYuQQC;SDgHOR)@A|5h?FeAC4&$dJ6ARFA{ z74=M<b8u*IKV3ePLH5!~bg*XXoD)?ZZULQ>9)w!P1zREomc(l^QbyyopQaTAM z?feLMgVMyCu{M;Xbf>HO6OrJb?zF!S3& z9T&DW11sA(A1m#@j5WN3?RPKvfIM9= zz#?jc16>E2c0nwYOQZ^VpvaN)6YYBhCOZ_&;)hQ6K69s!G+8cf^fq>ME zZoN}M?2IJ%-K`S63tG-Z6zfcEGpX1Gm0wWf)Fw6F{n8pIHL3Bzm)1BwU&A7OzqWcN zy4H$O!(+`DKzvrDpwEaztRU87Vkppd5A}M1w(}>U?fgT5-%hi5){!etev>+#zvF);jXHhKMxV*msG8;T}CqL z7ctwv8kHTK7p;I+DU=l1^_HhTqVnY%5lUOq2Z@o!|a z&t1G|S=Hf#2k4Zy%{ef@3>iF-tYdl_koInczahU{+;T-KZ%Tgua?W^@pBWwDRY%k; zC&f4KT;j)lQQf?{6~P?-w(M)JC=0z8iVpx@#Y5S4)Z$vWHtcXH@O_uhb-}|?9Xs_u z6!tsMhW{qeH}-KggSgLMYK}|vN&<)6#lp8M2L*C(5+ckSt|)Pl5!lF+)oXH#p%XhMTbP z5;OKngC>UWUWJz!zUdTRVgX-uHZ0r5^Ty+`&=NDIOoJi@wouy!(RfQeAoEU$`zg<- zZ*sbHg!-zgYPvF1&F{Z>&9=W=Q(>d96gQ>9+lB84_dp}eKUw&skR!y{u6%Mt?kagY zMDm)5pd|%SWOgHBIC@JzKsa1DS~x*CS$L3ews5JiPI#P*Vy2(J+SRCu3| zx4kU)obV;#Tfz^8#n?`k)j*d_)+FFaH4%o z9=H?sBjpOA#SVqMx8wtbi-ZgS#qyq;e~#qKg`S&#zvQQde-y@XL&o}itw`)7wCGBZ zcbB|W$gd@{+$q9~g%({5`aemI<4|I`mcq`$e!@{gMxA20Q-$XXZx=G!74x4JZW6vP zjNuNE`MU`x2@e)779K4;O?aX3TH#&7$A!Naz9ambuox4b?X?&77LE{35*{pEBD7fI zsAsXnffq|Z25*RHZ>sPR;ZotT!V82~3GWa-B79#M$0>^T%7k5o1BGLSGlcVmD}?KX zX9+h5EtWX!S}bv(#S#ZvEODU45(io=aiGN#2QI|9f&E!6{HgF>;Y-4u3thQkLeI&c zBAFpdXlJ2tsc?nxDB&r>bA^`)jeC#!k5R_H{FTsi@LyE9H;7o@5n60<)cc!cp5mFG zAVOavxlBloE%jX`_Y@8lju7rGoFbe_M89ScalW*e;%Mh^0AoM;6{B9`gdmn`6 zl3NPf3hnm}<$6foMc7|BSh%}zjBt{0s?dDaU}u)(c|!AHgZ@&`iD@EYOu!n=j{3HchHbL?}ePkOV%g~>9nx1cR z%I_-l=bhe?hYCjs{roPYjLUX!?<@Jfz&*JSKDM@^4?L3*4x_dj{^<6o{J-A;rX9uw zhkX7HX&}KdSK-~{IYVDDATmv@T(ur2QJ*NxU>jHVde6- z&W?`V8fli{%J%lg>idAC#q96JNuma~91~i6TPq-k?Oj;m zjw#y1Pki3qsYv@eNCwBj-UKGJ_`H)KhwWVpd$XaVy$n|0zl)Ieb&w1mfxXZC&JN}M z5b3bJ;y!La(H`%fy}hechx38U!?@ABnL9!Y+v0k&(3d+Zw|zgE`&15K%SSo)Wp9br zF4Md&2=}iH{ll)a?d9FO@86S1WAl~)Y?<0=$NXg0queNToX;h2yKVMppKXSQD|kTj z8ERWl#TMRwhs$+E|9H*f7hev3GDE(apUl8vE=Kp4`^miT20QO3Q;x0Kdh@xdr5pdS zx$02o8Iwwk91mZRL*W~8AiZLGY`J{REqSk)ty^l=Y~3;*J|ZWr`4n-o;TbbL_FnT? zw~taI=nu1_r3+9xy2GX8C`})j%k%y@kKeOu%Zcd4LydY78QJZls61a%iF(BMhUezn z$&%8ovFKhKH^TGf51YFkxM0hML+R}T&zD2#>jNL4L!Y^aTeWq|p0Ig&W1GW^*6o72 zY=1+(eJg(`${)H-`JMM(*AnIF=dP?VHg`ITM=ro*D4vUhW&(bAFZMG;2w#=IB8hO|eAEq>m8Ve%E-Re@@k=npqC?83 zp#a=h?A|__{1bByplWjYVT5>scl+^5R-Dr2SW_jRh6*k#jI9ipmC@*ed{yE-kdEbA zjzhWlCny!`-IBg4ab9{OocMCqPsKk+#W=4j5KjClsN}2C5{*RS^q@gFakd^mpP9=o zoqP}F8BY8M&{;TfvNqBkVG7~IKY%j5H%cI!IQ2o{Nc`gky3sZjPMk!Z%zMZ{IC0Kz z5KuEe!$=~WxLxDJS0(-s4LVV*3mUod_rHa&z8S1>wZ$kdk=}`xfEEndYeTvJv6LDU#Wo`IvIZS7jn5LGp`y zRobF!7EYWO({8*Qd{utLo>djNuEaB!u-}b+RS-^`gS8{RD&I!e7*3qTG(EI4j#suyEq)n8JxW$@!`voVXp3@Kw2xP5n%w^Ho7O zal1E=uL{D6ySn8W-U1_>_zIhF?K7N_2q*4+Rrml8;l#bK%317ngRjaiY^brX3c`uI zhVtRW-3H{tiMw`3WUis9249ud6dU`hAe^`}H8%58cH?>Vc~XXtp%G5p`>Kp%ZiBB1 z9~vebd{tI*iyC}Y$g@N^an}v{sxU=Hc7xl3^Hrf9`(*^OoUh6skaFR~^S&w!C+;i- z+1)r8Azzj6v)z!d%K2Z`(V;(1?{U1F zeN}k(yVDuyTOu+9wirj;d{t^uaBXfa#xlrZ4I;TCxu1g$w?f4@;__A5jJ$L+`KsK7 zN@+N*Tn=TD{A-+Vjz6OCjfKdWpReI`Yauh%RnU!h>RDXryIy@}HRyTBNLQ{6r+WqR3#`$7A^!ES zZOBEeI2{xDQmuz=gp@}>u^20sFZE?Iz5W% zRx+yK+&y3bcXD3;mE)^-D~jw_z>ali0<$FCKl!rQG{G@~WB(Z5goylpOvySNOT2)i zzUlHB6!0V=u*fzs*bz9~7UYM09{5@bk<$s|vBrXxtLvHI<1Pqm>Y2F22}jp6@wgL? zt!IL_n2}&V0$aA~Oytl7m?iK<3<9!8>zO#(3GsR+_^Jgt1=~0|ykSA##qcXX06`kzfYFjWQfV zn0U+dQwi*5ELaw=XM#P0kgE4xgs^>&AJpU$iI8@%-K8tEgR#O*V;|yhtPKtwlz5p( zCywdBc`m&VaUs@*l9U#^+$rmTyvCV!CF+`^tZiRU4fk{@hVa99uMZ~o+DSFq*MA6o2}TGuClmR5?OLA<7ZpmzSwV|^kRFAV ztrN#$Z74};f^vzR9?h@|*xuf~c0!w-&EaRUE3-Fo8CF<;GtS<~rL@B3?t@Ng;o-Lo zYs4INOc}LZz`?f7q%Y0?RQ^v8I&gTH{-|jszZd>qB_7VdY+A|f8t#O~)oz03HLM+j z4<@nu=!6^6V3(c|I45qWQ#?bkN@z=B^lGs<2 zzxcz-j`ItL#SaZfmD}mJl|##|@LR(14KLyT@=I<1kZ;j9-b7#IP1M-)stG@_ z-=IF`TeOWg5oUaYHxYJ>yor#?dlMm@_a?#&^xi~J@4y!zUda0vrCXUVQ91%IBXcK$ zHxb;4^4>&nQQ2!7Z=iBiPZhLCl=tmZFcCgQ&9`wHqG!#@M5tV!fyMAMgl*t$u@97xB^O@e3ZyYwA`mUV&Ix<^o~=8nfi9>+qF_B{ePpe^uT1 zy(W#r*BIu3Hecn^-qC7VZQY{PaI~5~zpe%i)GVo4zMy95+#>^qc^}hn$UhUe9qv7I zm#y4wZtZd~DJqr>guG(m$|ZAv^P!)=?1+ICb;~N|^&3nLITrsJ&!D`+k0rkO&V|1A zGJg@hGw5yOCSTRR;ENZdr|;PhHsN5k1kOMIw;Xt?s-}s(&uj&4@6K7K;%#OO(p=sgcV#Lr;-*ZA?Q z&tJAT+-h+1zK-9)Xp4TayBzcF`0dyvYWNUF19uQt1;#h~M|^I0i$$*XXd!R6D9;cY zw;J+n$xDTG!sCP|3(pYpCYyFH5b}jG<(~@g6Fww-PWY0L4}MtwLt!z-gt9%q0FIRW zjn9o6my2=p!tpWgE$|zk8#f-`_}sX0_;2yK`CXyw?`uS?-uGs+^dCv@eQzRooxyou zOhlgdy=f(VPI~WqGf=Ykz1dT;_q~})xftIOA;RuFCYF|OMkWG>x4HGQSWZ$|5EzLg-=QUd&w^g|3pN+KP&$e=|2;iPY(KFzBm|{Qk3QR zloPRbAR?cZ$kb+ zvtCk2Ivi!bBPNnhL)=3+UTD8l&`*<0eg(@NEF{N^viXbx?b$hyPj{&|A5tJWEtF3a zo+&(6Nd6}CFBe`dyh(VgkngWq?j_+S;hVz02tO2lE{x&v8tWAcEp{nn|NW45(svd1 z6!sMk5SkAw>Wz}TmvFL>FVor1nZomg7YeTyGW;mZ-6|ygk}`Qr#D|2>2+2dC{$=57 z!gqvQh2)N~oPDPXSjgX3U^5}9oRr%Ndkf7+7J9}gX8w5LA;LMrLxtu;i*gK8&hqPo zCksy#o+Ug_c)9Ru;Y~skDro0X;giB=h0hD$5WXWMKY{h4xJ)LJn?TG8$wr_&L`WtA zMTBcs@w+WsWNcu=41xA+ikpd9vyG zF{k{l!lviTq0)~KP7qEKP8Hg9I{GwI^1;G|!o|X6LcTWPcC8j3EnFvDFFaY;^t^kP z^cM>+6TYGILmB0N)HiB7eo?r$=|h*Pc{OuZF2EzB`L%)4)pO?Hdye5;Jn0XM)p)46 z00BKh^|#e5UbM8vTg1n0gFbU>mn^9PyFFBE{_^T2D1^^R_NiWh58%#OxdLW)d})WG z7@mK-UsUhyv>SeH#ktC5Pps^pU+#jiSFx8G^2R^~9$PRki+f1+zZDY8f3d{kJ~}y-1c>l3@Ta& zL5>M6K99#j*xuGY?l`7BTngpworJWngJdun_HJN8i_beAa@bzb7Ybz39*5EQkJl`| z4wAvAu=jnOcm3k?&W56qy-K%zw1=V0+uMLN>mb{fGw=X`BxJuZk1P8eE;p*v_Whmc z$Ha1exeMh6dI9L?%NYw+vv*)+Y9RTg1@x2)cIOvF`%S z!2H`qwh7)|3#3EC8kD1dysq<$F9(08Vf}IqOa8k+Lvy)GQ@j8DDk}#M9-Pbd8`!Tu zvao!)ztge-*4j4yPRlkHclg8RLl2F=jW0Oi8#zGgDIchrRcmw8HA4fA?BV#|q#e!AsPhqi|Q zmul?1_p;XJ_tay{2?wHv`8|c(IH5_ePhCdur?3xKcx!I9ty%m2kn7Lk<^Px(9K>#Z z#v|8Z@)Xmto);8X`WYpJf7G9lg!|JzI96iz4booOF;w9dERIb0N=-$**n^m!@Rh>6 zMB!u^a_k#FaFXJ|0w<|itbYiK!b$3QQzavmQi&s2HI?j*E;RYB&%-DeD=Q`OHdcyk z_)U@B8tcgxd$*j&G;f38H?;}?zo}i=3a{wkH}xh|iTI!KzhE>fL}GiOSMZx+hwK|a z@S9>f*$KJyn<7KU{H8{rtu(K9;Ww3GdKE0fZ;JY$a3cOqLaK=64CffNcOlapb^77KZ;GP% zO)+#0{HC~JkfWJnC{L5T9v|sA4LSVel5H}+@k2JU`AyML#EthMrA*WMjqF)ff$NI< z#t;0amRPR)#t;0aI9T$VqT#}0@QqG_BZGI-mZ_0Hu?>A)!C;X=FVN*YoYf#>A%3>xo z_)WRG?i)Ywo8l<>Z~VY->JfA=if{awYu>{h-Z!yp=Ev;yqnS2I=Jw3&!-gJ94>Zwz z;|G3IuA#i&l-q#3-;`^2MCNvydb-7Mt2-*Q7sY2zq!{YwIUv zE}-~A;RhJ9D8BJ?IK`Jr_rjp@8$TaVe6@I;ZPCokp`5p`HM7SP_{PslHnd5Tjeb+? z5UaMbe;kKa-{n8*v0r8&t2wh;^Ml6DZ;GR1-}s^5l-r;nJDY<6zo~0&6Wlj`=r`r$ zRQ3us48JKS7iX{KRD<7?t6!466phkvY7;J0;OUs~3-*nlCutIXQwuO;u`Vwsvh)R@-&8*{0-8NHjuVT9k*ZP=Ld z+t4}lo4On&vUcu<-xLKLICk5 z_)SruDLzc0-;|RJve$6r;5Ri3y)(ZlCL*|mRkz!0q~Fvy?3(Npnu6aHf6Zv>SyqML zl-rN-EMxW1Z;FNSA+zj_+z0TRvgcs<#*g{a!EefK#f0psvBjnQwa#uWI*&mvlY-xPZg z^WXTP-xN*QH-0*Cc;GkX6!^x^BgQE1C`aY_6yc7l3<}ShJ1v#uiBsUME1cSeWihfh`Q3~Jq>4Ey` zbkx48lY9;Z=|puCF!>Gz?>EH{>?Gnpw*SAx|4tD;HjQj8fKhzz)&4{7JQK}E-fhJ= zXd{s^6l-UCyhi>~@&t4zLOzr_`rSv~D}5AcKJVrQUzh*K-j{&KRh940oja3EmTA+b z?F70oH0eec(!GTiy4#kPF0@djkS0yq2HGTTk}gu9?1=0XMMMLLh=^>0EV9W`q@orD z1yPjk$0o?CEF%B+J?A|$C+R||sOZ1X(@^?QEGVk#q%iTSk$$BjQ$5hNlF-kJxrP+A@Dc(o>l-iVQL6k4%}VC^Irsri(3e zGLlcgZrf2LFD92`kM!Z~vTb9O&3^ctUA?h{i**Y z{i$szPW7=mRc4vsT){QK>Q9;foyc)TMDr~O@kE}?$WvqrwEB4o611rZ%xJZ#ToELA znW^E!4N(~_A0shO8awr%05h-~jUER0Mj66!Eeu?1h2vWoc+3hXv@pOIGEn>>JZt0E z8y_lE@}zWy?1SAXT@65Bp^YaTg2J@ z;%5`sRik*t0DET?uUt2c;uUA_I_#*4V5b~4q4f5)9VldB#!zZM>{Op3^6w|BK1FGQ zO`Wv>$Uh=kO#Bx1Y)(p7*wk6K0l8Bt%7u;2OGYJ&v74~_ zvE5o2^91&ek>;&bvOYk3Crl0MoJlOfZd<1k6{T)Ab=EN86dRsFoQ@qiXHqq%XA7l+ zZR*S=z_m6!owy#mt#dkZQrcisXYu&(#;SFH8FLl(ZS@!3)iwjT8ha~^B6m=X5|h)5 z8do;1w|B^S;$PLapgTr8Drm14zpzEw^-Hn0Y92}ESn{ZCUDKV2^qeim1Z_xz1Rvm#w!l%@cL-Az?j*spiXTy!A$dRCHbjF8_cA-6}9KqD~g&_nE~)f zZo39|jCWK6dzsmyy;0X(JD3FkGAA)Ece(Y37{y}7drPydOOVSR2q}x1uDRul6uW#g zojw}**J8)48^tiJ?bfPxSnHY0%*fSj8^GGmq_|#pLjaw@#=A7T-G&lw<8pONmh0JV zT#ar;a=E(g5(Kz&eO>D!f$ms3-7E?G*tWGU#9E!csIn3r!* z&X`@#SR6-9(j{Y^R+nr{JOx#F%4(5$CGDtoP!uIS{j;q~8YMg`u9?=LM%EchdiV|#3+D`qrx@6mKhyb>GsgTv z(~XF}8PSZIA!yH;h%|r4fNJq?RYv<4XrN^j&Y)Q`%IKLv$>#H}clK$NGkD(b)=yhe z(MCV5wdUbS_`reHVx!{-zfEfvH#)~n6{{t>>oEH(s!W}(%1RJ{YMaX8!H3GbX3ecxyev{tTVI7X7B8=Fr2bfA zb!~NRT`l?qWnR2as#sdNVnroutwYGuV8p_WR8&>6&=TnSF0X|nsEQTPb3`TcXTaAJ zQ10OxSJzf^6x(u5^_l9cWlpC5u;QB2&vX+|TT_E+!n9W|&+2(L*EKiRU|#BK)?oTq zH{p-$_)%Gj%}QX}9Xy(#FWnd7xT3k}G|;8>;k>kt2tX z9(|D_wUM*N6a=7iWzSSBnN z(o_-C4aXnYEcryC;qD{;a>+js-XZ+0@c)FyuLkn><6}6`_`?8BmOM|mShz}fqR?>a zk-tT<;m||ATQWcQvEHYI#;*lrU;bX$*h3^PsIkp}0y4YTsaF}qCaGtPQ*d*lVYL?>{NFuooM3Ov+ zNATM)aG7wm@HF99g+CPjMEI!i8DU|<*3(TmKsZJ?L%2}5T)19%mhe*HwZglEzYzXW z_=YgRCsp>pqp(ysOt?XKp73YFCxm|$PRO_Q%n?=zmkMcmlI?5|o+dm?c%kqL;q}5h zg-;2eBjVV;D14QO{j>4|H4y(CFkgm)-@ljP09Eku-iQt7lm$#z~AzOMMTx@a+!VYws` z{n>+vaz+OY*i-R?6mN9U5I>4C_OVJQC!OVH3g;^RD9KeqT$au8!f9_1(FTizB|`J^ z5XZGla$n&A!U@7@Li4|a{D(w$jc2EaH!pTq#^8TrO-Dt`nXl zq-A|GKf()zmk7TlBte4to)fn9Gxd?;1OA^PU!E{2>@3_v*hff1?aV(^I8u0^aH4RI zkQ_PYKT=pJZ0l!=c7B=fWZ^}^uL})_5$U%`zDxKMA-Q)f@BB$UCHarS7lp41-xq!) zjPw5<<;g)Jb`W+JmJ0g__Z2!Fx5<*teFw^ug2H-e#hAE3c#4p86UJXHB-4cQT|#p| z0{J<~uL#Zk3F65zVg6iUcOjY9jGr!aI&P$$F#dGmIl>EsWS}tpdf~&up9|aSvK8>Y z0%`P=L8Og&;y@v3E0imQON2)YR|-i6Wj-=mi028f5?&*`SNMSNHQ}2=0NCmL>|^Tz znEEhn29adYUDw-Q&(lgT6P62y2}cRX2&W2X2xklD2^R<#3Kt2hg$=?c;acH(;RfL; z!ZUe`L;mEQh4RqZ05CtW-Kf4Plom)jKVUbOL* zSj&a1&81C%jN9DEIK>a>1w|^H7}T-Csf9NP{N#@hw%A=61S9itf3+=LJFZnf-`XOa z?|2Syn@d}S2*2G+`-4h}2H7s#bM5jO+m%5ua(XHfNi(3$rPV|B>svV3p4Y4ow{n^K zPD9w0K``=N)OQ;L+FaU6kp23WvpyuUK2D?SAI~9I2Ej;033UDO|KK*4#&gcEZ~YKE zPS%I1%+z-!!Yosco!fwJcwXj(N*mL-^PbMn_e#%g>)PF^d;qgmm)iFnPUbkcaSr_c zor3=1&~2q__b}oxyas^TE=7IAoB(8>xDlf!WPi3GAKz2(eN;#6Y?t-3P1Kj&u>SgG zrA&Pt5a;LHi2m_?iQ8Pe=4(Rj^5qpPhYlW8zi;}JbnQlu7&Rx4PR)=Jl| z{N{@i9k(3QBi287vnbr-$r-t+M`8JT*movOd^r}G_;NH7BL1)N(-rSPA6+?Hg8dSU z!Y#o*Qx}!obH<`_=!XrM5{&V4|LxHiUo_8xrny+K0)s2O4x{hSGqTMFjjtae8hT3j zLI}1*ya-bZWiS32J7upqC%=ZqMO zgy*1JQ0ijQ@Fk{Q-}Ne_QK^fX0GO;>5!;^Oa2oPLsjC|48Ko}X=_h$R4W%w~*Pn5Q zWm}9T&qOz&)Mdp)vab<4S+OuV8s(wXWksjd^$c4srBYWjLix17@g{aNHnjbHR6(UK z-mNDWu$IT&r7ns_sf&Kgq145J8KtiM zaNUAZmzAm1H6JN7gkgpZrLF`jFiKriImws(l)7v~8Ko{efQ(X?ZFh`SuKIO{kgw}X$0c)E z^J5)~jhIpDvQTV(QZ!=|PN2T{lpCws4vmQAVkY zXK)lsT|?N=3tDVc>SBjjw6po)Jaj&cKa9t5;qyv+CUvEM3}2TSD`tXarxkRS?Xl;?f_0Bl)5%xm?g_G z0Hf4Zj~pp;?S@hp1)SrlUve~1>asH!OZ|-#0;Mjk2(-w7$78I%%nm|GOOEGsjD5PF;&Q_pwzVi4X~=Ouqc$e z>~V~x_(6wCUCd0SE~8inr7r$WM4{Bxg-t`L%Z_4dYAWl4Qr9X|UskE>Sku)7DH<=L zQkOm9mZdIcdr<1Ka#pF!%4<^>aF(Fd)x#WfPpNB=iGWg957q#sF7_bwmAY7kQR>>l zHlfsIBcRlEEF+-QWh0=}Rl!j}smn${smo|EL#fL~K&gu_VyM(*Tfu9%{3B64du8Sn zN?nxMDI-Ivi}C?Zc1m5fh)BJIp3)f>1PHZXa!1LjOrHfGGJCW7T9Kl<1wD--GbK{ z&oLtA9TWd7e)G8o^YP4LIshH4mym%&5ke-azQSb4HqHfm+6uueywcx)vi_YPiQ z8}s-+H|vo&=(!MbFh7r3g4v~SqFiuj!SRr$BHJkJrB|Zr;IP6A5#~)HZx73U%6x~L zxW7Yw9y=mB1iji77liG)wws^RA($H!VdA3FH^OsKxLXrx6ehN$82*+DJk_H;iUVK# z+<0)+Nn&MMg^ncF=~4*nkHa9K$R##oMgiW&GQE05v9#2356jpEYcb>kCo8o z8GsCUFvL^i90J!O)OTVn42-ctqJ@ERRw!&?LsPJ$1Yw4WZ)|E|V73+3dnyNrF&qDi zpua<44ODKLYwBWWJ;ffLb>{4$VowzPMxR|&3<0X-4C&RvAfJq(-ohcUTB-Li$meU+ zNf?3MsQ0)LA)e#mF7+NaJgWDMLp1kjq}&_ne2$doDioLqv#~>gDaeeo8zO8+*)h9u zVE*RIxVJ|IkMpt;eAq7OjtVamJ0wU(cC*MoEsNZ}+W61-B>64=)WYIar?~Y+vNnk4 z^`#e%i;9bj!PidqM|d{K&CNm17;>`P5ArzKz2bQ}$#}9C@{}SE3dgq*m5L_~^Lwz( z0*-V(S_zLL7hBnTBe*ZJ6$6=#t>N3_{|o`zxECdK}{)CbCU6-eF7>#Hi4w>q=f(z=>ToMWFQYZ))5rQIOz^48vOc01fy z2A4bOR!&GVgk^tW@JN2CCQ@DB4En!u0>r7Ut7^tEwq$bSafm`=L(SsaCABrx&X1D$ z@CfFA<xS}>zEMAM%0N)uPpwmr}&TE$)_5Qc`)!^-$+jyHczFp#!=&8Y?e0tOX zaryJeTP|`PHkiHbr1*K{DHo$(ys_u}W_illyEBlKTP;*P*5V=EemjgN@k*I8kl+7^ zdl12E>qRWIKBO5xROwVMr9589TX@Rzgog{43hRW;!jpw(2sa9^5Pny9yU=ixQUA{* z|5o^#@O|N4yy-{2K|;Qhqf9k&;vymSaVf7Bo-Djfc)jp$p|J~&{2=9Q@CU-Xgg+PlLHL^RBOwhRvEA-M!|j1QR`S6@!|_2pxdzOCqOc4vzbFqD z9w?k8tPrjjo+-RUc#ZIJ;S0idg;2LN^>-Hb5)Kzm7S0#e2%Ckc3BM-1T6nu~v+yb5 zpM@U@r{N7B$9K4JqwsR!J;DOKNnyS{g*5s^d5CbNaJq1|@KE7G;bP$`q2VT@o^vSU zn9=+b@vB6%eW~(YBfLfNw+ru9{KJxIr-|i$rT9NcenyDPgsC6P(jYEv26??_yCp*N z$^mkj># zw94W#7oxd!*gogo_Moap7)sCDU)LYze?KAY^TY>Rz=NiZ$Bo-W>^O9p?JR_-XW%xM zb|4~fI!DGSVd0*U$a|=S_bFID8J^NCgk2eCZN$CH-@OPItZb979@if7vfbu_w1nul zJ8v)85kex{#icXTZUe%u41$ro_K`@M0c|dAIb^@S*xq(cvpx=+^TK*h#_q}>80m-l zxc1%V(oR5xUtcG$K3>yYeHS6@%CL^nsP7EiOSsLYosS5=zB1Iu{;+>ItupmpjxfuV zW9Rl0+&CV~lT;hixL+%D`NrVH{F3qzTt434G3>V6kk6H2oLeuqAnf;Vz~0&U>!^I} z?ajY_|wI+eCetZ4B05IwNK4W0_X@ z_KrlzA95Sp_bF@-b5;Q_+v~^II?6SGJqF09#afnSUW79 z@H9k)GfQ~VffqI#Dd7T^n6(EFWHgrhAu}i9%TWV(VI+BEd119IydR^|#U!?bJyA3^ zz#0Mn8zN%movK+)BG!X7?}MLs&pkFHDjwT{-<8NJGcbE!6$ z3y#=Xh)cwBt_r)Ot-Mj_O3u}VuOl*V9cs+^UNPe>D_|f(1*`>2ja0~EEB#h0kau~QIBa&aXp^DI>cPnpM~oHc(?t?@wE)Tr z1aQQzVOJB)3A)Nik`<6x-GN~<40dykYY2y@98DFiMPHXCZb=lNBspSNq1 zx|KkVSmHKGi6s9^61V3~1dt;}^_0XN5-mq8@#79lOv^>d)y#aS%9bP_r+B}aC33_r zqxfKVqwxTa*bpAahq^zG-hwZZq+(}cbCSlBY502*8~RyZXFdv*T8>!a7i!3I#1g;M z04zr=u|@5UN&bLU{klU}Q+8bP0E&-w=x;>J5lj45RZU7h!*2XeWnuW6OYy0EUY=?A zyOF6+cjU@&hQAZf7FHrtv~)r8YaG$@?RW;0BSzg17}vH(m>e;NShTbG;cDs3d)&^9 z$8i~sr1nhel8cgkV~Iu41ZO989_xkSZ|1`hO&!X~07vX>GlW>`UZ%tFx0MsAOW80u zVpc9p-NdB^j+iZ9l=>bTO@Je|3IAB+h|OVsaKvnSdFoa4Apwq<*cE1$&Ta*V{WtMr7x3kZ6@G9=ib|Ti3FRY*Fq|;1LUS^UBeuVj@jt@nn*=yw^k-IbBRW@@C=C*) zBS(s~*#tOZ6u2TfAvFPx7#qVsMCt&J9~?2Q2(-w7$78I%gu06D5(fr}U$Lq$p_d78 z#3-;TT4hgwBWC5C)OT1lIAYUH)!>LR@GLT`+k0$D!0>l(9Lf}xw!z&g;lCNH+QOpX zh}q*9OC7@jfg{GuNI+r}+O38d1>{69JCc zV%7kT7<*tiVplN-41co6``8I^#B2mOVplN-IAS&e9I-z!2RLFj z0vxeI_5&O-+X^{i&8VKeGII)!7-e?K$l!=kKGezNh$Ue7`$R;fh9V^aju-{b`IVeA zaKz3xGB{$qs#7pkfg{F)!xKsJo^K>z_BV>YfJ{J|Vc7@LQ9ZUObbdwv^5gSmOk2GZCF zcI=RXZ$p}nETgcOzRR-n3cru={n+oqUY2COLrq*974RZib~Ap0!}IvYicgXovG-yV zcv9d^4}O-!YasXj34VTsm|tM;O$Vs&An*qEKFrnk7l=t?S#`sX2R~OuZeK{j(zq!; z0ci(dH^r+FScJU~bC}|^aB&uPZ2KIJIgH*Pb`3)MQ0;#Z#RtMdBXIE12g5@4c>uno zN1_jfW&oHt&cSXT+%$Yp>0(%J@%;++kB=@05Rpno!gf}iR{Xi}Ff;hx@yKAum6KKOzQeLn{kAHEH8=<~ zK|5c43e%>R{^|o}lv6waM7)HXQL}EbFoDj@_XHa*Bu-L1k>@h<6autmIe54*D9)aN z+hO5FeHLEKXW`{|+%&_&n~wTm2bM4!dl+eq87tH5g=ZfYk~ZFrZf6Iyk;3!))2}6_~SkI zHgjf&H=p^r1@R!@K=SD1hOAMO9T!(^oC3GGvG+g(`^1@cv&~lB#(XXh^SK_m zbfRDHi)eJ0_>Gq0GOcd$^5*KA-E7B!J7PPwepP4qjeL2xqOxh(pk+Ml71cFMDq&5r zqG?@2O(WuPzhF%=HbKCOpbndnav!Zepj1huY)l|Qt%GugnHEa~wI!o(7vLZjH zHMwVb)e>vc(eQClF}PYohmg!8*4K^<&NfsoKBlJnP-`9(hr7O+_6-~A8?Bu~n)0l# zKc*H0p$WB1EeQEU${n#>H9Nmlcgurp=g)S*u2WD{RChoUz zej^Uf!lUc!D(jlc2QOS&+q7`v%tNLfQZd}(!bykBUO0PI{n0gxn;I8>VdBI{MP)Ts zdqtz+IW9F;k=>;tbD%34Z2~{S*B?`{ywVsWuA)h0cS$zZcX3r*QfDsMJ7+yM!^7N7 zz2q$epNM?hv1vwX<1OU)c7>;er$$c$`*M@$m%I6w<_ou*CEi*WWd(#nV<99P6`C)^ zzTC;!x#hDQ=eQ03(%hP~;$PxA#QVH|hJVR7RODarae_Eg$VW@ci-a}8M&Xx)CkoFM zZWLZ7yjFOJ@E+l#!ruy?6Y@asqA2-O1PYHVqhYKeO4-r-gR|+=>&lMV*u&D0`lKC>8^*patbELSx$vva#U?MUEczbT=o4&F(#o_t|@BI5Uy+(X!hi1r5%v5!&wIN>zmOyOK2_9G-4+p%cp zXv(OkUg^gw{RH6|!n1_u6R}?+`CG!Pi0G%W84J8mGA@6newk}y!e0r0FZ`3xT=&s#9|C&udSE?zktyI_L};VEC6@bF;9! zG6+VF!2;ykcAHD9M1%`7?YVYv(7BC#WC!@|(q7=b$j5fs9>+m!!0y*~J_w#^#JSC- zEk}f3-@@MZn$P<1SC^^pWQ1KA1S2=1z6A_ub7|ya`SmSFeH#$R`Y`lNeHS6@${-lY z>llf=x{dLk&ou1guygw}>f`uWAEqc%-{lCiKAxxC-oc6eLtYfLF^&7RLYMEmSdjeh zahuE6me*T`KR%xOZgcD97DV{{d&iqU3@OvUO$dh`uXjP4`q(ZvqBjkZvyd;1$S#P- zl$-jBfNT@>WwvXv{?ZvKJGU(3=Zp3EBwp`G(t1D9&g0<0Lxzt?bNggFk41e=$1=R$ zJ#aVi#?ANN6pLPYQ%-E+E0M*e6La1}Gv!dMqDeLMB<{^UWqT_5fFMs9BV zN&TlhngG{#QetS!gbyD5(W~Rzce!WsdxOV49Jw))oJ8JlY)deu@02(0{P=JGxaSRU zes7HQpAvudw490W#SZ%6gbyEm^~K0N5Aj~dbR`z>Ij!&{NNaJn+Wuu{FPg&P4f~~r zbMo-%0_!LY5_6F=jK*g$Et=Z}kx|~=i1!=D;)fz7x`??f?>CI)hLjRZm zmv4jjI~`qdyx#`YnBo1hI|I={LxJ&mzi+Y5EbsS8Oq$30jlRwbE$=rvp5fNKUrbyK zv4-~>y#gV}`@I|0W_Z8%q0;U0eyNk^@qVj~nBo0?5q-tRMP-{bv~is82|-tX<0lPvGoTuVIOZ#T}E$NQbl@o$g! zOCKg#-tXx=_#W@~QWo`izdvBrJIDJq{Be)>`vi-6yx++jkjMMIg2%w){noQ-kN0~v zyXNtJ`*WRnyx+fZU3t7;zDV?WzqmhZ#rypQ+w*z9yd!PJ`#pv=_`KiKnZxJ(c4r@b z-tSM@37_|S8*}))-~VF{pZD92{rHS{znwX!9`E-?&e^WBCx+D84X zc)xu87`5+v+=Js24|tE5;r(tz{u9#IVA3OL?2#b71Qmk! z`!u3F-mmf0kr(ZFA@bzDg+kFbyx-x-?|8qfSQEBj1MXjY9)}8pxe4-q4@Kl`>^%=a zPl7}8$$Y&S@=1(~p;obfhoi{8*h@PzpJo59gj~tEi;!9D-@ieA4SN|I8p3$&5wL%c zf!ym-{H($1;TMQr=R&v&fy=P>X0ATpL(KD#p2m(pjD`3K?m}F@U~U}7{D$rcI_1%b zjCP5E(t9gX`ZvrO8Nsb~0fhk^SF|KnKuYgGL+RZ!=2LnH1;NiTDNkTn$gyoZm#vLk zhFP)H;{m#Vq zxoH0R6EMHqA@zDJ-T|#Sz5`oxd=uSt1PSgEOoNuV4V__2$Mghkk`*-wUSiMa@w4MRyJkkf755Ez0zh#bm6aLz|PW3)4ni4BR0%%C0HTmr|JL#v}h_cZgn2r_y`umj{FXtS{wcBbaJnc6F|5|rY^ z$K%TOTp5{Kwl@w}0_5VAkx^xqWt^SId2SW-Ff?RSrh#Rk_lP15nIenOjGd3n3ro+IkOKY{bW%o@u$*%frMEsMh##B#!&Z;Z2I7a}gz z+Sq-!xn7S$1e_u-YdOX$u;*3<(lohRn9i774Z{2}=|O3dg)2!G z9>2r(VCm}LX+c$dz>#Z*89LyG)gx;LuIRs{Aw6(u^_t36O9l=}51chLJ#a}~{Xl$qt6khQ zuyT2AWn*pKQbaCkt^={TzHVS67>mG0#L@bXFE42rxVXNqX;tOorm^))V6KsTUgVGL zECHRT`{#rNoF&bU1euatTC>7nR}{SD`YQ6zm)AFfXj#!%U0YpSR|}FjXzHYqFRfg$ zqSDaf5%P%QhNWIr$wEt@w6MI^us6w6uc(+mqrPq_&@g*3X{&2N23@llG|w#Cen~Ct zVXmlILB2SQ2=5{r*fYB7pEoN&BsRQWXLobPtceFz%tI&0@dY~-_MI@sMq|X2Bgv3} z|8uNg=p5jJU0YY-CIvQDjmE)lbF8~W1710jYkWza(Z!)+$8IyMTXBI0n0o{J!#l(A z?TSu`of@7NJv}%k{~<#Mo=`Aeq0gyZR(?y#ZrM9z#)XE(l1&ZGmu_F?SKsUwM(|$2 z+rkJ4UEUT(TDP_}?-!58-nKPQxU*pn^SO)jOqB0<_+6<`2UqRyajJi$p3vz_#_eQ;(5t0 z313tEdy@Yy3~=dY{z4+^DH3*8d|Gmua3B$DZwL|l1jSDg&JrFXTtLKLDVYX5*v@hy z>N$~!_P;5-SNMPsmp_w_|4__tuGc_b^C_1I&D$QxWs>^}%Z21jG5;9hI3ZuBG5(9f zN@0z#UTCi0$ak^iONHMSeph&_@W;ZR3m+9eA^g4YIpK@K*M)Bh-xq!)jNwm^{Y?nl z3yX#Pj>+`2kl$P=({m|toN$uxU?HgwOy~C)BERtyY0`|A+<1*@G9mlp?#g)#dB;7@Mn}qU^UM0XU}qlglzA`e>P9ef zHTIw3I_fr;HUSZSeFIS6)mW3Pk9~3V@m|)IK`_#Y#di+YtJ_>!H6mP?X#sBclWy={ z+9HJgb{{LX=Lg$myla=&TED(_xL;2r&TTG@*Ji)IJA2#nhxKvTuD;U{c4ZKZ3_^XQ z7|`a@PJ-;$_Xz5njX2hazo<-o7bEP-AQ)MK`fl0Aylh08Utc#Y40qfxMVb1pM40t) zJ#g!ahmd=DAha=!`}IPX@2Rfa<_zDdd;qhN<2z1a0_TO>ZP@+(m7#w{h~s$qMCRu2 zVT5rw8vtgz81-?jy3Nf6(VK?IBgj{d$Q0uFe8u`$Kil+{N96C|r1V0Z+gyDtT= z-;8`=d8Zl7o{0UNH9UzQ_?{_oY2|3{No$=P9Bky7gm|s5Md*Kioujlajz5>xO(&v1>|ICP4pYJT{ ze7>K9FzxwHMser!onhzmos&?+ag^llo8X;?^Z9P>LNY$zZHuua35@XhZpB10VZ=^W z%=mn_qVxIwFk3c0->E>APpzsav751>?Nd<&eZJS>@H(IGwt|e$cPqw{ccGi``EJFG z&vz>pCLh2tfzNj<7Fjpk2T1Icyn_;LC?se7{dBv@+l@CYz787njC=Z5q!RLpke7LFvvL;Au9EnA;X^UOK8pbd@n)3 z`Fv-X$Fu<%;q%>gC6+v!{jSXGVNx?b-#J;b=gW%o2O*ieT8PJnL4ZBqYIKc0->V=x zpYIH_q37A{HLfA7V_qvWKHs0hAm#I21?2Nx9h1*@EA6Duck8&mC^?N|x>KvTBzXbF z`^_xTo^LJ12fNdrD1E*^gYLrT`*)03mYmJW-JINP#Ej4P7mS$k`EDD^_ zeIAos%Bp_d;Z;+1T$0X%;q(1NBW8TQ+o~od*YlwNPJPb!e7_2Pr9EFV^5FCR0|4#$ zl2Zjcp;+oTri0gO>3hZF;#e;Yy$HMnSkV>+{{FXMMiY$R7Xtj~9wKkM_|re}S=Tc7eX zQdOKr@Oo|j*(oZL)8{)Uhd$qrqzqoKQCx;SU!GU=`OZ_RmCtvcBdvVC)8MGF=X(+l zI(WS$n6i-eeCd>kKHr};IsP2S{PR?>2dM=U;vFO-vUA8pXC(3124v_I+=Lh|P%kT^ z-0}Rr$;5J8w%JT5zXcJ-o-bFSIhke8w*dXq6*J@Woiy$eGER-pcWR|)e7+kMby#uz z9!CRSubsiH&v&f|w8(+SW2`>w^Zg1|H4HtV&vy#ATx5K{TRA6H!I^98^PMX1>bCXy z{#V?@rT)RJ;Pvv~j8&aU8N6P59J4;(nVI%{r?A)H_404R_xWx|F*UUxy9QqG5>sE+ z=lf#Q)vV8Vd%`VCeU0tGp0Aa&KHsgpHnocFf!CX3j=AUay^D!}J>TxE0lZ%JAf(TC z-cRR(*UKte`Fyt#p3iq1;rV>G5uVR?8v%R1bXGv0@3s}%^PP<9*()=ru;)veoiZ}) z`BLufWasmJ4k9u>-zjj;$*5^B~1YLR6q0e_7 z+^+LESFq>HR&D!Nxk9k#I~lEj*UPAG0WSk)bz_0ugm65@6J5UGIYz|LG`RH$pU*Y; z7DUql@NZv22Ks#Gl@IoOX`O;T-$4eW>B?B_mq^F`*ej5Gti(^&=Q|A&>@^Dccj)uI z2Xeul@8hT@uY0sZ5yW`xaQyBa&|*gLWoyEBD$=BiJmvEl#U33ue4tR zaU9b5=Jk~6f~|2kv0U~9LsY>P#( zv!-s%@y8z$o@b6T&oonPI7Z}ZV|;d_dv|P%CmNUU_T4VHqRAT zu9FQqCzA;$12@ZRZDnv4rv%R9mCo-whXL**p`8iNCGfkYarDk^vLTiL*ONistD;@P zFzoPfA7pxscy^vUOAH=l4DE6V^aoG0;qpvJ@$hYqgnjOYfQ`fPH(#du;Vv0N-Rt74w5UfWMCyMd zhtN?5IlNEjyS<{ivA$v%>;i+8xswD}d);rCMB*oXkRJmU>FTCdmXjBQrHjO@?c$|1 zP2kzq&}Q;(!=nFNKHW>a+cDmajc*q_C8&ZwcZP@Jr?LjT?MToM!T89@17}8ZlDRYU zqWL);W1WJ|K`JZ>_6YV2x(3~X9?_n>rEazP5wXadd|1nD_~Xrl83=X1=psYJ_*;lu zVSc~KZoK8qZl7m=?ws4!_C)Q8=o1AIW4?cW8eSmp+sR+yp(5@l94}`@&wr z5yCGB7YJ*Gg?tT({_Y{{BOEFGg0Nb+N_dj+0^wc4p9}vW{AcZm)+KEJP7t0ayj*yb z@P6TA!WV>t@sf_?8!uch{Ic-7!ncJ{zA!`nVxjZrzL#WYPn4R}%y)orlJFqm7lqEA z=xWM1R&?J*Jf4U)Pf@-Lh2K*A6~gZ-{wB#k5*jo!AAE(_8?MObae4UsNcMI-#eJVazYc3c6{ye*kyX`t+YK==d zTp}`eLVPjjZ#WEQ<9z_bJZ{{WZ>kB|A6)*;HW9zB3?uk|PY$o!T-t$%z-e#JJEj%k zb>~Z{1k@mYEXZ(kc>cLE2u5ar`1E%#!UZeaCIeY}3SG6+WU+uM5#hPk=4^AYyzyDe?U$Nr%UnffkAm}Sbbb2}a6q!sR9LuMNH zYlSY~J0L%O32|<7`EEx9!)|N93CuO*HjabaE!h43-J8yim+!{icsC)8TNWM`vt5e% z{I%-ZBI1@Qvu#1XG$Q$GeMcOvH}*ijOsQ<&+j6wFAk%NQk&o{Y7S}hdtAJkK&TzB_ zmyaqRmFD)zb{*IDHVwAoXjQy&LE)iW3g7&A=)jlX2*3@Wpsj7#@zy(U~Q42(kDcND231u339jo2cAdm^l%j!8_nY zZW0Y;eZ-GJmhks1GoW}f!{m8^N49`P6R{UjCVU$|;E|CX5Rcu4U-8KJ#T+~`HXNSI z#8oDo`#7p2k8A_t438|1CiBR5h+kdEwUjp$Ilv=hyk!z}MyP=K#UmrVB>5<0@W|Ey zNCo;KCMSMP{5d0nM@Dzt@$ZK$8n$Qn`mR?YjXbg=5r@g5$)NTOhYd*2?P4aR=t^WF zkL)S7!N-!^!Nm-t4f=)89ikRv$uFau;E~x5B$9oM*vX0+9+?##kL(#!5&goGaGzg` zpEt3avEf9&233$pMz(r#F54cR=f?L(^ecBii7~^X1CPu#{v0!pkyx0d-6!zK)Od0x zyLN!YPDx(0z$3G%CCMXLcAUg+$$MFLyhNWz_85D02aYOuWDIlGpJ&Z8@+gMnk-fy^ zgU!GoN0Xy*%><8(1GPM|`3R9LZ-xvWSrio*9$7h>wex*cM}}GZ(Z~oMneAxI_!I|^ z%+i@MJTgv}cx0?Ne+mk7R|}xEKmd=7-`B|_qf7YY7x9z3x&y;(=uLKejcW*phu8BA zkL+#qQ9Lpg5RXh96OYVFTk*&)VpDhIjYN&nQtKB!_s1QqbNdXB%pHqMd1&s>=PZ#& z)=2Te?iXMdqu`N!$f_RdewPu;l1FlKHz%JpV&7yLQ-7BCkr6XIGTTswM`j0*;gQ*P z$0VCr)vr5*d^{^1m*it3cx1&!%<#x;Rg;q6;6eYL&Vvk(jF$%T$Oba?>5hh=3Le?@ z6rU}eW=6Cic{E4#d^?`O%0N@l-NAvK&?j`;a_G43F$Jwg~%>^jvRvWaqL<@W{$BWrj!AlXZYcMpxBgso|0F zRImr>R!oR@kc`OA;UHC`Pw^P-<8=x)BZdpq%gQKsJnuJ|SdPm!n+fG#LWJRwaTS`A zSv;~*C!==<@G!wX;W29J#L0Zw*2vRXuBcw`hf=f`l)z$05{Wbnv%QKVq10*{ObhbNL`%OkrE z5nXxJA&-m)w`&vU3Oq8lYTLit6#|cJE?NPPj8Wo?@w$Ztwiz*CWTLzB7tb*w<{cAH z(q=x_U_NgDOb0w38EXKKY(F*(9$ASI!6SPT72tmCZ;*Q&kDn}$tO~X4br|xWkY0;X zM$*_LL7JpH)cYMo!T4wC2;>5f>`LUzgGtEKk*EDi#KmLwm#?Mv4#-^%=2=SFuUHSZ zpeI@X!Tb)i3|WPUN!WWDUfH1?PDb2Fv{Z_{=g-hqaG0?@`4h;uGyWl#J-qNjl<9>P z@FC(5v71+h|F{1gUfK3dEb?fZ$8OTa`1pN1c7#ia8*JF%&59>-<+Y}lVd-+i0BsS1;rt~_{GJ1b_*g4`54M(Wm}QKqp_n+!gB23 z-ksptf}G30NgiUB0I7~a9&M89h&EjA9r%Sj@K<4n1xmuz*uzNk2`vn8{t!>F!G#2l zS3P3zZtUn0;a=>fM+|Jjj(7s6SUqC!7ueY&BG*GSvSXT`yA~s>*?gG_$h&ENwF^fN z8Zv0`LiiZ|OkB8&{oy>q8}eP|b=QA}=J#9NY=p%r`Zv!R1S5rOVXQDwN8jSb#l`XV zIql=gC6H!=ir0*sVfzKfz+g@=C}(;cxJ~S2{ z#Yk1e;J&u>_Jg7qrU%jBVf*PBgNK<~KDj$X+x9Rg9VJUQV^-}y>(cyRMKv_ctQFgK zVE!*B7*^D*s9CkNrf%`N$QKTtpPo2)WZIlvX;YhF=BJBEn= z{8={K7Pat`$za~qp`xzl|8M{1pMf32U7;Q}9I|Th=fQ@d;~)O3OcwgzUUst$BNfec z&5bqH=CVkkv7u&h?UGu=Sc{3)qam2Ol}j6k{5P`=3vu)3`!MG_Y`5{2@C)rqPRThn zep>AG@Cc5ccH{xd$!Ip-M;qIdll2hqiR z<{ZQ+XqOzMdBVemONDj9X5q=gGlUz3R|vl=yj^&Y(3osMJBD)ud`JX&bDG01}4v#pjzq@dNaDU-+;o(B#`xW_(ttjB> zioZyBrSN9q1Hu=C#-L6gO_+d-HX&Jr#Z9wR(ac$<)p!`SZ^gzpHczRmcK!o7v% z!sWtagQ@CU-Xgg+Pl zLHL^RBVjVfw%c7eP&ih2u&_edAUsi6hL@u3_h8|H!db!!;d%4i`=q&KK4Qn}w$dzb3p|c)M`3@G0S+g&zs0;mt4GKU}y`c)9Q%VL`sl z=QxP{B|8q{NXb+oW_`1ThYA-87YkPj&li53h-3Cm;pIfM{b@Oezf^s{Q~9Tb&nfooZws#xUMIX&_+#M%!k-FBSYY|bg})d6N%*qxHQ_tL_k?^c#`5Gv5ZiJZ`KF!m z`wJ%srwC^X=LqS+lKBl69O$@;h7%6?lYD`nsq*Itzb5>K@Jiv;LcaB9dk+fnQOC$z zgl%mDzM%M*h5SOm^8JLvgrkH93MUE=7LrK8a_0IEJW}!!Az21YUny)BZV;X#G+cG$ zb3VZ@R=nY^BmUcxzbm{>c$1Kyc-hW9!cD@>LSsu1>5ohPlaOC*S&n{+iO#m*dy@Yy z4Eg_o^ju*_VHcsXzk~Fil5tu6H*!uhw>!HzrVG>mu~t_DuJ`UT}cQV4R41$rdsE_|GZgXiTAi}S2tydralU#ilA?(Vqj+v;BpT6DZ z(#}VOU*8$1kK<$i__X2byBuMb;r|%7NuBUP!X0eLOyhp7(B->(Py68l(Pne`c)!lD z+eUS@UuT`ncDdbx-S6Ld-grAA&Gl~+!Z=JkEM{Ae`uw%(+9G<>5V-;Q(unMWcubM0 zkMqtpz2y5ySVhorfEGUs#)Pd=O$ zcD#MTzfVQTIUT>{{_aQY`Nqv;oVMGFaa#IAGE!sx(@$RZW+GlVB~tqC%h9F5&`T#j z|59}6dt#S95(!>?Bq-c+!~2o)f(^lbxd=te586P6=?(A4%D=LKp2Z8Ngi~s!^jOw= z(NW8mEDFYkZzjUnn~B)Fk3MCXq{&SAM5cU*5X)OWDV+}5;}Q#w#iSMf6i4>xxb-w< zhNmC!NsazckeGzj@H|X@II?6SQo$`X8dA~R1Qw>@mdXz~xTW1uT{xE|tRHgNC43iA z;FgX@4d9k`MWb!Fr2(VT#U#gtbl@sKzcK}ZUj{E!=- zsq;hL8L7G8nVyBZ6S17D!tQ7*kA_N}A9C7g%J?DY*|beRxVp~$MH6P$iXxHHA)yixX<1yLNz5Ezi{R zLr(g#=ZE|rmL0Fm8J=lkdg9N>mwXLJ&+|iGM$z*_-W3Pk_d~vp@{atF2k2VX54oA| ztRM2@*|V%4@~?5syX=RY46BSEa=r`j{E*XZUMoN3Ty;gXA@tl~<4Dxa5r@=V7uHS34`K8jgCnv)FnX49rz(9@6-1~emdI)&-84*Q~-a^_;C09kgwxX^ZbxE za8TfxZo(*H!jk5;D?+Kv%Vkl-?BaMOf8e$@=Oz7aq`*}sfIiDLw+P{@codlnek@1f`yr>@?pA)tA7hTs$Pf7k?4aj|oJKNt(GNMVIvGFYr*p2r zGd+}d%=yhYa%7d8r3#)Y>F=MFAM)2Z0@y3$l@B~q>WyUmkb`IXN2KF^Y#%h)<3{AM zJkyLHa#~hCA-w`q8cAc11nEP#+#=ntM3m=;{86Mu+eM4X`)p6*Xs&r@-O3qxJoZ&2 z>>X5dcylc2lyBO&1y4Zju_tx(gSj29L$;$3ISG5ua(4WX4p$?Nw|gP>o}1BlFt6kH zk-i!7eb`HLna{c;AA}_l!(PTpd4G>2Bv!?%AoqF)Kjd8RkGJ#9e z`glm|v7?I45Lrb*8b86}_{FTE43Sg8mgDb<$^k3xJn4nHVm8s)kW+FAHu(RdsMs+qoWUmg+?$RR~`%tzkwO)Z~U7- z6y{ODpB!gtz$F-Z^pdb!z{t=R{)R1V^M6zMck^<0J3s#f=jU5_OvmCJ6c~Tyu#VZM zFl}7h%Ep!CIO7p$xeXT)>l9BsQ}IMzE4D`yHVjjo zYFUafPg-zu4+hM(LBbcYg9sdLVW7$iu@(l7wn9#ZJdDCkh+B;v7AgrRnJkU576#ZO z#1qal!P$gMu$%fBxY7!-76z`hLJq$12KQG(;Ioa-`{%rSAf42LmA7!`NrXU8yR{{^3r3Eu|j!ht3 zmq|dtY`FTN6o2q*_ozvTdNDQy(YOQ}My>e5_V6y8fLJywb}oYlV@GE=U5DBrVF7kS z)Ma21c4Q%N?nKme(@3K3(TL_wqHZ0KQwe%9;dm3APdE)bsKY@Er;$6d5IA1-h{3O# zl(~e9v72r%a2a-VgTN_PHyFGIJG(*T!twdS(O@-V)?$a#di0bU}p2%U5drKOC;>p)hmE~0&m8|7etQc8d zMX17AUPU-#c@_7C&hjdvw`ptjvB)+^*dxG&9%`My=LDVO(NuA~D_%y%!!DiT(GutW zed9X1h3^*L3LbXY8QF#wBh)n~lXJGq`L%WQEWd^%?xgh+-a_7sUfBru?kj5GTATjc8>dX0F&RFdJK>j@H4GeQh0_xNn=^y{e|Nx&lXY?U0Jv zO3bb1uVFYQdd=cSBlilxiz zt16dQ)UIe~UR6`k&_p|}=)$@hW3hEf_43-P6&1BLH8^61Oq@NBEa{kQVU6Kn<8b15 zRjxJX)$$R;D(&gET`u^}Y805ix~)%Y)H@NEi;BA1`l`mr8XN;$67XxyQ+sA?cUz{# z<&2lhI&=BkDXzHxp_wP!e>-s;_pF83eeQVQ%zdnV7MqgwdEb!nbbqjAjqm1+xASI; zclt$bWU?r-TWDAizTC<9U*yv*pBmb5#?2YtiZhPOSq}33Gj?nFBtvfK6yZ$aT;U>N zjgTJ*nV(NQ#1n<*3O5Qb6Pm|R%0Z>pM>Pzv9pSQoIS`xQsno;N6sQEbkL;BI4r}ZD2CrQK21My zdK%>aIs46jB4UZqydi^JCYk^9OfMJm4H#v9P$O0eYlSO>O+vmYW4;rGrwY#zIu89e zB=dzZ^Is*rMtGx;TtuedExb?ou<+-?$AnJ^pAo(wd|mjKkRJnC@7_XZ=XZeQp+d)@ zA18T|@RPXnHOfarcWj5W4x;1GA1C=l;TgiSgck}OhyF6jjzj+g$u|o5A(Qq0Lio7Q zxEnazAiMnQ%L7WPnI|K+JR#w8@uh0r%Ik7JWP0m(EJ}FAIW2^XNAyl=)WYH z%qpgzD&!Y>${U4_Lw}j%D}~nzNmpV1TZN88f1hO14w(K+A-Q&xelM#$ z$dpeK@_R95^M4P#O!>Z}`0ojCP&~gTGynZUem$oAgpePQDgQ<=!nS5=pJDn7t7Ph_a3{ZUA>(4mFPZCZQ&JfNP&J!*WE)*^k zE*Czp^>6xv+jVz6+%@~zR+j;{;k$JiFu&X|y=Lo!U#LV8 zn2`O!vNPL6{JJuXcpm$>LWb<-(hh`(+k(hA8y&eJjsHGWPL4g6ulXLteznzQD8qj! zuT^ey^;IImg_-uP_GAINT-mg?x(xUBjzktAAKPVnEJAF+?$@^oAHLIwbDK-!diBSV z?r;CYSs!kNGWDH|uq%ULbQ@3H5P&tPiJEroPJ&W_{(@xjmf1v!FZJkeSB)TA|B#au55AiDiDUjmR#D?|_~4 z6=7$a-gHIIOCulR+~(?I89(29=-+Q#CZNlgeZ@4AstoDD!$*x6JZj{KAuy6%p5|tM z2bY(R7%>9rLxv6pVEbfUhJ^!6gInn`%rv?Tu%A7C+u95#8*PSy{sW%u`9^NL;MI1C z#}d?QD40U6hUcKsFmdwxk49c?7vA~mr1o9!>AGzEd&A0~i_CiEtdO>@OD63xsc_4A z)N*K`mcx1P2jvGfP|M*w=sSF+0hY8+WZvYI$g5`+#$Zi5cFbh#)u{Dp={UI3iA?Db zA(pl}4(}JZ;}r||E})PPx`*QmFx8u62BZ9E4Ev>qBOC@f&m&71B!&{A@gxd`(OjBS zj2_MmGfQ})hp~7!q(sLvm(_6yW4TnT4ioVytS^x}2#rd|0creL9DN2qu}&TPFpdA$$O%e3XC7t#uqod=H|%aOz0MA^JTOb2<(&q;9R_&=Ivb9fuL$Kf_~)6;R_YYR`uftsqHR>$E}XcU z;TaAntK%@6UCZh?@IvD0IGn_?C=Y_b%%=T*$5_niCgbd`aHxdO8lYl-x?kfvc`)E~fmS z*Ks(PP3^3X!;d(`td7Ik6d&w<4Z0VFE$x4>s;rK~DeQGt$AP-CyQ<@GHLJ?%I1He; zT^)zbTuxaX2cAxzjss0TcsdSz8|UdboWc=hbsQG3p5 z)a7i~({cD38}@V@&f-$@bR1~V!`E>*koi3whsU^@JROH#Y|qni;KPuwzCKyq{| z9fw}5<3Fq8!1K`8aiHw$I8<;NVN3gBjIQJo3?QrHV6G*ej>AVBji=*K!U@@)jzc%p zo7Hhx#)A)A+P}h6CXF%kiP+b1IEOR0b2<(~Se2*aa65~7Iu4ULAWz3(8GG&NIM8{V zuj5e1`gWk>@G~A|*wUVldZVSwQk&S`4s;yuWqYutJpy-!A-p4`c$W)v%SBU61Z-)~ zU=6;G!-dS@>o~m0HepMfZHA?=rF|(Qd>w}k9EGpra0he1mbNVdTiU;5j?YNPp)=>y z({X6woWYj%`502P6t=Yamq5X&C%~5WSr`#5m`L99jl}WMklIdNdDY42IIQ7ZZCA&E z>V2P;jssP0JROIzY#6q*jpjfQ#$q3!!?+*ofhK!ghAzef-Xmso9KMMBC!|+ll#w*{ zNRVEF3ZdiBf+$bNAs^+Vc~N8U+Uhv`8YQFK)N$aGn=`DviIrjtF2b#B&lJi8^NXnC zFddP+bMHy_Ey1BhWbf~brunI?=Ywb*#&HzMLqq`ii{*Od_X zzNkI+-ptYGZp6%iMEwzL{f@>@v`Y*M3XdRVpN2UjBhgf>fI@%sX0#+$K=p$GMnPfE zn6IEP@JvqRpEC*yrtoW_DQxrqWycB%T`b$YU~~c5=3!Z+px}Ul5D%*{1@ZhEZ;x0e z=M*D16{T}k47_#5CsIK{!F~n%qm}?-Ub0oC`9UzPnDGUBN2V3;i(wTOx5}UN^V3IQ zJ2r?Z>y7-lJ2J+;z4|*Kf5J95t(f^cX3T-B2gRKuebCKLor6Aww(ZVwQ`dj7;c(7i zPbmkO!xi1W>F~0xbPZU#*Jq}nz}eTa$L)cyuP~sszQVxm=qvDT2=xz$SJ-d~k>__C zy@VXB@GQBXVJ9Q6J6~rnM38$9-dY?V>Dj{YBJ2q(m&RI_LE@+lSoPoeb>?lFF*aYVhxP$(`zJ&qy8)^ZBt4(k=;U?^+eg^KeLbQc}2dogb z0NqxI)%uBpoU;(wx#vVywi%?6TMcqfc91LmK|J*u#STdy`m_1}s7c95ta;jOl6#DJ_%;2c{W2ZpY)2?VZ$t!<)5+OU^Mnvu_l%ndn{XY?LytetqD!~>7%K2}2WLmZn4*zDH|3lQgK zWjp05n@c|Ey25!z*3$d(_-y+8)&2xl&=3(u{*zA`Kwv3f&mIbYhsD#X{ z=oakvM81&ZjhG_%<>a!#_TAQK`)bo|%MOIX<{{b^*?dIT?mqbU4|~sGo`(D{v++~~ z0a-Y2H%nh^;XS?mvxcqwtYPHf|IJqot-6+90~&vS`C{Re7{6HPIxNp{{d+>{nm59J zDsbNleiN{QA2;9=f%UNy#+WYv{wS)RVJ)3#R(hwFrSUyNmibPA-#UQx@A#SD)M0(_ zRX{3Z%WoY9qfw=Usr@>gU^B+-n4c>s<$2_a;iR8C?-xiTSJpWx>cT1y$mje(rnU+E z*h;Yf$&;ke(-0EtXFRNQz!A^(V_34FvZl76p|QTItg)bUX;o=MRn1~3`7uBvT@Q55ad@v`&NCy@PFrS(_y*u%%YirEcH#n5=VTV^T zZN|j?OXlLckNPTp?O{IL@EVq25d`@rr}@_k_$cSQ{5)Z^|J7W)L09tS-%m-|vc|9b zDMS0$3G%I#`HV-tAk;nG>@%#RMw+v$e0j)^QI4tb>~#71pD29&uM*7XN&5G|vwlTA zPS!QmrAzT;3;gEu^9XO>i4*rq4&bUEb8BmtHY6)+>yzW_tCN$f7gdy(Zx!!Sd{VLf z`vfyy?cXPuacKWO!HmPD=>~tLc(>w{imxetq8Q<8AslyI6iXG4QoK&_4#hty=4YC6 z)~EeMm90uKJ~3H{o7T4r{W(J zA5xU>?oglgrT@I@Ur~HR(fZQ=MCC6Pzfz3h5hvTiBlElC?2GExZ)zkYQ>`zk5)WZk*{rO??S~(iMU+6Lgi}|Z&3X$D*syX z_p0a1UfOwD@dd?~75TE4>7Ob7Tam9IsBihbK$3d2gR~c>4^)&jY@pv$W%(`<=|!5K zZ;hFMp5g+!+rW9kFaevjO_}HU|KLB+2AjrLC-~d-iZtP*Bwj;dK6HT$;PjVv@&C`3 zLDc&fCLq6cvcaY;gu=#|b^>k$Yi*;Pv;~N}^^VyE_b$lCdN~fZ-dd*&qTWY%37%v` zgRSdG$gaJYb~DEi?cvfWW$y&UZ5c$pTukiwjA*cFKZNYs+X#EBprbu>J!S95h}$xV zdR4GD(e6Yi?Ht5idrNmW{iHn{Rw;Yy5T`vJrwrF6@Ve0MY{*RG_De;Z?~vZDe^_C=jL?pW-g;qr?+xBZIT8P(obXt1`g4{}#5VWyEMOKe9heS`03%ENu@U4ABkw!-k|37j zzZc8pw*wg)!b>_V^!JKxn7CyBh5TmV#3iRMl)k&HC*zC3882vb{pOfKS(JO<+pC(T*hZ~=bXp-1?!n1J-RatV*P?RjJH_7fb$|; zm?wV+>5;!7U-%RJMEZ9B2~whwb@)yD6juB&>2A?M*^^mfH52P49(xI?X;`PA5xVq9 z^y={Yh-7fFpXjw&zh`_HazuaLnR+jiGx|T+Ixv429L?wz8U4|)_=Aw6SH-FU;8n&? zrh#8X9}zL)g-=DZqQ4BYX!tdz{i?@Vh?B!V8O1RuH$mHx@i33jSXUW@9QLDIY>)JN zSqEMC$A)xf9ChTvsZ?yJ))_G)bZO!4=CQGcD5r)5wi<1_vOlc!6^Acx|+<6IS+rSeH|G(HyH<;ALWd1tRv z2nNpaV~3@aQftQh@J@_#pK_(DSV@{0f=K*Kw!1W=x1^@W*|6B6-W;rOK0YvxMrb&5 zFp{}x4bjMO2%Y_$GBhnc)|Adm&3FNRV#{*nvXk9lvzOb7V2QIXX9(K5Bz9Z+i)dqR zNu3wFy^|KmEvbhOXFC&eOO|`F->8%x=QF$59T_75q5P~kKYfk;RzKC@U!rJOM<#W>8?gbA*uqdcM<>A>@Yte| zHp)xzvz-_?{DM$Sr9aPYw4H*+l~!5i5a)+x9E|AJhn zfb`ZFIQ%BPFu_$XV&L%01D*WgiT|=ZIQ%AkRHBCUW1WKEOZhR0>sUWH{N_|rlnB#4 zIQ%C6q{LY)4-UUcpOP5H^5F2_C*`Ll&f+kF!*BA>OngZh9DWWChBWpMcAK~w(x z1dprO6`{^Nl*0KBg%Z3YjA5Mu9wXuWM?;CbsQ`zczSYC|FGUl_vrAZ~pc{rPoc~HR z(U&&B;eSnXY>Z<3c_^5jL?X1alSE|Wkco>2L?f$^AP!48Yr=SDcr)SIt{4Prsa|hM@&9aQG?Uyp-VA?=h@XVC1yK z;T$<|_{X6X4tXz=5xP*(W_RBZTNR4^0~fLhE)E(4hoApuG<6zfaQMxBj3oGNM+_W( zX6AYt^=vgb{QR2;<@ZbEuBS_{w6BG;Wvs~{lvlS1vvahvEEOd#~k4B8wEK0&oT!% z{HB&ieJ^t|%(GQ8rrnLqMu{9V@-9|Rc-=pYT^x$df+F!L8wd_R1&;Y)95ZnE<>4$j z{5-2u5L4jrbLa3tQhBEjW8m=fOwfa8o!I%I4&1ptj^|i`!_Qhx{a4#USf^kTY5|9z zs-8Yi12VfY!EQ!88sUN7)91lwj|DDy5{*2J-%QTIj}egufNTFYdw_Kcc;>@81$(h# zaQHp626V|toq~5D_pZZ_S*HNsilp%Y^3LVRe_V2Z^wLXW^ZX< z`C)q~;IW6BGu+#0?ci;b4BlNi_$uzC6n+(ZC?#J>-aSdAXQ^JGcV}Dj_dZ$t7NBcWf%$eGfP6jUm_ZWhfC(|!-zQ7Tg1o+KR<7U4FG{;`0u1!sN>V%bw%p2) zAdWMDw@~C`bBLT_&57fNPR%(2&)EztBDbaBbMx-B8#a)*8`mTEhB6! z^aNI?%w$HVOUi7*Ol-nTW`xXHG>*VAQD(9o9x{_TOx#@G>^()sk32pgn!cHs`DI^i zI2HZbCO6{k4BO2yYz_ZuznZe8P30B%9nnt>bX0)p0ofl~_}&Zp6>_!J+M($ctw9Q9ljj*=WW9y7E3U+7TSvIO(l> zY$-Yf1lJ}%EjgI9+m4N!l2&POQ|fG>O;KkZHZ2;H2|hgzuM+DNdPQv=UE9{yl+gKb zNooCJ@n_svTfNBoC9bC%YI@g&D_zovn(>}+FI6dICqr3+L+SeZn%eJ{l-d>>RlI8( z7rErCw&7v>JLjdg`_zVu<#tA@@dRF3MZ)Md`_A4&|-R@|ooA6GP_F4?cOSAETU+mfkAGrU%Z0d&L zr?jGUQI+QpL^L{ba=`&!T0C|@Mkq6_QzXyt;wQr0{OFg z6u(fERmx$HYedrST*Wd)KB}Vr9L2SYTymItu8>W9R51;g>y+`4y&yg`7u-{Evf@0& z3dJVH)r#jUUZr@O;{A%xD!!@snPQZWd|1C?f5j1s`zq205c5?jX7RBnzA1e!(C#?JNs9X`9-?@(;_*c6tJR8J)Rer}KJCCdUl;ZP>e^Gox@omMA z6hBk^uOilhl6LXQD%;mXk^i)m<-7{yQ&!4+XGf$DBx0H35sEd6O^Qb=%DMx{f3nJF zDxRx&iQ+oNYZQN}c&nnUQvf@6sVuL(AV041Q;KpPhyG=iahMCwj{om$Hv`emhc`4| z9`(35vGd^@_`T)dZM)xF8EJEk!sxEpa7s#Dc@3x13D^x1c-_G`_ZtKAl}pV0aKAB3 z#AeG-z6jeZIOc7zY5PEd(}x__OuJ+!&-)xkx**Q!KznQ#k8fKBQI9$CONA?_6SW_9$uBy={|w53oqv)3o!SFzjH-ie6Y zGPH3N?77#rHtjg1x%RGf?BRiY${x>8whW@)@vz5h85?Zcxlp+FZiPMell|p2zir=T zh_g%~Himd7JRP(<8#2?lU8iXC9gPF?80c)U`R;&%aT`8GK6h@hUWVJSx$RruCm268 zA=SPI5XU7FcZ-Ap-J9F9brGFm@D?Cn63VX7lWWF$Iqs|z_EKRb=3g=;1#NH1PkXda z>wa(d7&2@~A=qX%r2O8t#ZN2TbEwI?Wq#TvoTE4_%=it!xiI1V_5Ji?X5Dn-M*o;k zKiKz}k3PuxV#-|~BIb|&^vQeP_l~IpzwE28j{E8z{@+S*tcQwm$oeIuNqWK+z5ak> z_5{?RQ}rf>Z?T$}t;_J!d&)yg=SE$Bci^4#(_#41&usdyWQ` zV@3x2rW`Z!>J7(?tD#$t*<~=B;+XN1fHpa1zd$n`j@c9uQyjA*4Bpq}nB5N(DUMkw z>kc?(Z=qcd$Lv0e0mm%D9t0e-uP6o_vl=!n;F$fKWdn|xFu4Mb8GX#Q%`qcC(czeV zNXrh#jQ0pG$E+BWV6z;vd>9BgW-{IZ$LwehLBKKlG26Y(9J3#yX(^7`57^0oWA$LwG>GvJur&Z^qvn9XG7fMa$s#eieRbECsC>&ej$IA%w1a08CnWLC6| z9JAwTD&UxPqSz+Kj7(IAV|FNKdcZN8&eVWoMyIk4$80fs6mZPOv7&9_n7xQy=5Wjw z(yqfX<3}tm$Lu7gI~=n*R_t)h8adS*ju{_fxEwRy4~Qe~TQ%tq3J%Q55qcQcL|d5z6DW*`?g=a}(Rux1>ySDC}*nEit}z9o*? zmu#TJF{&ivW^F30}%>vPCpt3>J|Z2b!H<2Q(o*Nbbg zLD5b)!<|mbsy!9)Rt70uP8CE=`feRckKl&cyGxdM7^*^%Ppae3JiuSAxd2VtqUfyAYT@+uG|tFW(y zG3k{oF0HOE6*?ed#x0(Bhy$C_D_K;^LY1IPF2&gxRmvKJpVN#Z|XcrdHO6_T+s-x zlNF?pc@y_qFt4GazG1-;wKb(RjfF!NEUs!?F!6vn`^_oY)8K+hb7n4pzqljdw6b9V zJj=lkVmWqeNdv1XSe3UVt*pu z>kU%9aG;RBm&)T6rzjqvC>$u{`R`KsS;bcs zg#(3j;Xnc9T|H1ZP(a~80fhqv6b=-Sj}O@{;Xna}0|mTV_44i$uDaG-#~fdUE#3Md>Xpm3mo!hr$`2MQ=0 zD4=klfWm4SKL!^vf@0&3dJTxJ}P9n^A)dByiM_b#b*`Y zRQya)I8dw~cZ*WLqHv&~7Y-CqI8Z?0KmmmV1r!bxP&iOP;Xna}0|gWg6i_%&K;b|E zg#!f?4ir#0P(a~80fhqv{0})%z<9dBUWx^ZV-*ijJWNqIP$(xHD4=klfWm$uDaG-#~fdUE#3Md>Xpm3mo!hr$`2MQ=0D4=klfWm$4)nBjjO^Uax{yxPgRR6T%pH=_5%70Vj z!vk_&APUNP53-#1fW1}USCNm$n164@35vyvd;-DrIf|8vM=0{yE7OlrJVWsuMQIQA zZH~$S$d7fdm1)d22n4H*yDAJwf9rRZ5i6=0(-+kjG185E`;dX zyB7A?9<~ofQucW5!7_!|7^a|cr|>}4z%*_*E82Wd;G&YpxeYcSuU#0oVOqlTl2!oP z`SLr&-S*w+^w;I(Jc@jn%XQYoQrL6nw5^Ni41>20`3j-rwXd~@u1THt*r3e~cq+RG zBO0tdo-5saccXnT*-Sv254@aVO0*HW&6apMLkdTXH2Js8%Xz53RG8xBbO$qM)NRvx z7rY-jJ=*J>_q{cPZrQCkzxZRYbZ-4%@fyR@xe+mc?@yon>-(M7o^=QC?+6oZMaWq^}`=b!`K=W(Qh?(;f!Ip{v(7%>!kmC8so4a)FGOqtQW zgxMpp%P6Hs#ZhESy3ZJ73E#?}!aVu+Nsl~_y%T;DKcM?uhLmW8Q#tJ!Snob&r>48r4-j?1>J{5!+&SmuX>!1G`f_McU^w^@1gC;cz7oAg6_jX zNV$}Hn02f~7SMedM;+=?%G4N%FGDjy_c3C6oV2Id&^#k%#fwk|bRQ#Hmr@(V5M4@@ zBbGTIKd)euzM*b9sUqEnE;!=6k_X+#81Uk6p>d%57%}Bi%82RldzpERre?)AutQ^2 z%!!K&ig7BYTuPa;-QskA3YStw>>1~kJm@|~bX`iZj`#zZJD~e8&QX7eot~CKF-(_I zpE7y6bPRGRJ{gk$bRTv!oKKfhlMs6vxuwf+DfKC86S@!Gn3?fDypy;zgLOJ$1>MIq zCFN2|+?nR5TuO1U)TI;+XYL6@+_Z*hglH?rIe9UE~Uo71YJrsv8vx@7%}Biie70Pmr|x|%B2)X z$#E$~GEN9CrQWBh2YX#7V!t@=Awc(eQp5pqp?p1(u~Ed7ODR)P%B7U)K+2_*sdr3# z6-_;z`>~WQisw>%CN~sgy(yPc#?++vncV3w=#e)qu5_R4rN1-dJ2Ca;PCka4E~S1- z@wF_DrQ=eHM=)JVjb%k|>SUu!DK>~jyT}j6p-VA;sK+or|c5wK09Nthv`y^Yo?O!^N!>Ymr^_w%uc!*1LEu?5!pEGq&a9) zG{P&GJpT@8I6~w@*&EP(%m_w|6EL`x(iwpo+3{$E=DVfnK0l|a1JD%GeJIcr z9VCf9muTBHZG<9gKNJ;f~Me7ivMObbp?xp?ql|2Bw^`3 z%uJV3v)O9UefT#)mr}i0HRwL37gG{*Xb*IsYOxo%lsZD1IzK_biKP3O18zy;M%D+H zQbrD3N*Q@Y;)kpcbf38F^HpY9XwrRpi2^RANaiKohb?I4Qi>+TrPQBTCtOMy1zbv< zKm}Y%83kNQRk9awDPZC=y?yrKI~%;FvGxn1SxIL}a*>;z^N$n1V|w?i?OSDjSzlJQMT~mx*vG z#hu%ulp_JU4{J5`UvCS+rPSf51uuK4>gn?|AhR12jLQkYbrhQ0)91lwkA>Go|0I4h zIS2oRh%^ASoWHXNp!@L52bWUfy%Kbvn26x{gi%*-KEjInyg5kulA44T9+#Yt?s-XU zUW(_l8md-!J_C_QeMuQFQolz&|E&%_c{vO#40!$|+za-tszKslGI)5EHwjz*FQvfV zCm?<%w$<4BJ%}IwZL#|>q7Pu}-&kGe`R|DC1IX`ESGOPRz1x-ck{F$AZ2fLQ5B&GC zY3~ZiXH$1DCX2sO$__-d7q(p{AOqX9>uf~kAhH*>0ikn>!k^6==4q){t%en6;Vu*A+n+%Pijg zBc4M%#KgN1`J{$=A`dad$yC}T421@?Cjzt5&(us=K=(+KKwx=UHyF4{Fa~D124*=1 zW(5Ws{k3jsKCdt>K1UXNHmy8oW{}61@Aqgq1ftXk;CP8Qt+aV?QbY4`1Zyxcj2-(# z$dl+if{D&1a3tW&Dk6@;c9Sf#38pVH7{f(7kHCth`;1IAdi+XAXXU8|1aWo_G% zcP?QU(as?Zz!vrzjuVe$rU`R`CdhEII`}Co2AEpsau4yD2|a8P&5#9a|3Z}t))+Zw zRI+b0gQ1)?8+ahLbnmmGfuGGB*mo@@T1RS;t;LoMYC0#yYU?R^@soP=6P(GZWnk-U zI39C0?EM7;w1u^EHzjqn^U}1R z($e07Pp@cahCFc7;7DtkAMFtCkc|4_rew5JICF3`i_W+95aL?;xM&s_Y3XT&z#QN) zpsTHbJ1_Y1N~TRslG4^Wnu{#im5A>V&CHHQ_l$OhBAPZW+5u(!A%l?;UXj#%gQK~F zquEn6cW7IfZriC7FGGg{H^g08w%wQ4|B&HUT2|HsZ%ZVRwXZSzT@lsjE34U=%?$Y0 zUTijC-+j01%(lIDEP4UP7o2bzM}XhRQSlRbTS8MKOZPWj3A!0V$S%X2SY@OqV z|0%A|+)i}+&R3N+Tq&35HppI|0eQIw|6V6XP71FMo#ju=?iQVy7M&HX%1oP?HY+=4 zJZ^utM;;vCeFh;S7x#@Rg|!R`CJF zmlWStzDpIaSA12G{y~`jAH^)(+EDJHxSQf= z#VLvhDOM^jQ{Q@l^{X~j4mkTE|O5Fmy36#FR-SDd6cSFv2NN%3UG3l*{Jp_q|r@_$nvU4z;=j);A9qT(q;Y(G`xS9p}K zB%+Cjxl^<06lj4ht?bvaDSTnSteS7zk!5@?1`RH${1*0=b{c0~8Athb!{IILpmcJV^0S#R|nL zMLEwRKmQY1jt|j^a-IcVr1B+-S1bNP@g~LF6dzW6T=6-@7Zg8G{8;e|#s4ZMdEP|5 z{S^6rin3j6c7)1yt=aJ^^TizVO;;2?G-NrC0}oSux#AMVTEzy%m5Qqr`4WJ3t*^2h zRK8j94#hha?^Aq8@kzyJ6<<<(MN#YRQA1ewU8+!R40s1_z16!^+%NG*V7bwdA z3godWPgdMdQT}I;eyGZ2ii;H+6iJ1kU7Y5?(82j$_YXkycD`=Z_TrLZ+xeUI6-x)> z`>Dpkn_Rr?=oHS>^&7{Lfyb#EFw7GA;1@&5zikOE^D&KKS8UiFTg=Dv0?WAd@*2_x z?mq@z0(@4u+FKrSbLW`Wf1kcz~1Us z`uh{4x%M`|9`_U5$GZ+|kLPK&f%AdkC%DEx*-i?`OykD$x0^4yQ|nyMdo&+F0)6Zi zX`H}%8Get=ZQq~KKAuC^KHl}%_C0|(=6oGM!b`B{&V9Ctf#?i_mxCK4`m0Pp-w7M- z(LU?6#}K04Ld-vsIBc-?Fs#k;y^Z$$)n)?PeBgTSIV>53Epa_ZkH81D61L3syta>2 z7&ZMJ09rJ;o;{1Z6n8G}TTI^Oz~W@_oo|mSLi{f8E?M_pibVX?XkgZ-=yd}Qu9g8r zOgfYT5%T~-NLKTN-!;;#K*XeLp75beN%>tPg%U(eVO*udpA7~y66HszAZd<)`S4x* zN%>u)bCfWinv;mhnHY_%!*3dSDSmh_)MEXvt!ARG?fE|PZ|Zj~1E!+7w&z&n*s|ZX zr)V=++w)3H3)k=3)ikJn*SL!}^}F^2N*KRurAW7a*RF!ul;5>8k)=()Yy2k2@w+xe z#FXE){V{l7*YDaNVIt*st&VjEe%IbbyBxo34^a&KuJQiQ@w+CBy}<7p7v*yNu3gWv zf#0>GSvK&yb`u9_-fADo=unpoAtYvi>3vB*JQi{ziV9F z$ML(yi_&fPyLLUAn)18G`(MZJS^=B6iQlz}*oE8RcWpMC8Teg0nN_vvcWpmr4*ahD zh+^P(t%_o>wr3{yW8in~VzxT)yVivjZKL0{8)+)=yEdL;n|{~sW;24dJu5lW1HWq{ znHuC8zZBMR6>H1wekyFj_yLJpa<*e-~ z{;iy~JwM>Ycl@sPDc9YfrN% zh?x7JLasr}8(Y`!S}j}c_+8_w#jfAA6KQWVe%J2dUUvMhy~6r7v$m%!#q0WA;}v5w zziXAW;QC#wWe#_3&$n5pyS68vS~gqTb2)qAuI(v&QP=Op4RrjjUBfZk zHot2;>!kdy32C)WziVe9>$l~1?GyGO@ViESWi!8PFCZO!Os+xO`?uIXE&Q&PBL8to z(oMZ2HqTEU#Odbsx&SJNkNFDHHsg2gWSH@X2dqq7qf3AeP`=&vO;zWz_NF(I1&j3g*Lz-h(ZlkLdl;LbvS4CuFQ-Cv5%w znPKqH`unp0v-^lLHJIybbQ;zCV&( z-Q4QB2~Cxi74=@pgsR2jfQyu^<>L3N-neKB{5vse30#eRBch#JEiqW4i}48sso9Er zC8Z5zjaAhZvS294Fk9Z>oFR^h)5sQrx@22OvD|m97x~jY~%iFEt0>R`K$hyOjHybU3#; zauYbWJZC%=1A9$t$z^F5bzuDN*0<#6(*K7Rjw_wt5md*tEucG_*; z)&z>}k$2Yz&BOJpTuYO8$Cn^B@IBKMD*!3C;N7)2h;@a|)-TnhsQsI6ern<$H~4tm zI+?5e-nd`G%|34W4PTSK>-a8<*hP^S@gd#|6ET5!N6z$NihC)JS7cw9et@EIMIbLy znGd6xzFcvo;u^)X6)#h~M)4NKyA+>Qd{t3=+re&E3^eWUqBvAheA_`kTjlokJf8$F8pq{lMyo0xRHD1=KCW^QpZ4NgU$B{6pY(22?xGAS6MH^gV@~m-Ixse z+Zk!LeSbzAmnL-p2`gIIvvm=jVeqa)z9J~m%+0Q+xe*t(hZxiHYwckeQpXw-?oN8% z+l*+i`M~8G^>w&hLkfqF8nu;NuAKf-Su-xz)LRPP`EcJ@@tWeU#UO6?|L5DG)4q5+ z8kBbz?i(h{-RP2A`O`NzfXZJhb{_qs9 z?~D(PREPCA55fdCV;S+uanAZN_QruYNLvPQ!d`_MoG>23;Dn_kBRFC7paxD@CrDxP zw*pSs8_bX%l`luqV__I?!3nz+bp)I+`sE9MgrDY|us*QqhkId~w#EsIAazqt7(ZgM zoG@|`w#*6R6m>XZbO7XX!uWNI<%IDi^`@M#>!CHAutmsgIblD6*%T-2NMvb~6Ltcc z>2Si5BBnTDWUqf+PT2D>k>Z3+XWaoOj8^~-C+tp&0VnKcW)9Zkq)TjPEzV*#Em({5 za+VD^VdRH9oUof&woOjh^VoY1C#(xahZ7dVPIuShq%Z2ta>95f2{>Ug-T^0!Uq*dv zoUn7y)D$Od8ao-R#hJrqZo&!M6}#}8bHYwxRo@OL>|Zn$aKcuy)d45$KOC)X7P3zrzW8k`v$Igo)EMhZA-t>vuR|yuf!kVgI7+aKhHGerGMt z*(~pH!j9oEI%{zbVEqm!tcmFkCyd8cGfvpEtia`jt*64}gxx@sE+?!9ZEWA1u;JWI zJNr8=!EklE5FH3OVR9~UIAQ-`ZyZjTkmTT;@30vD^YYU{XzqqsG|~aT-9EzZ2{>U3 zx$_-P*aGexhZDx-54VyNwi`{sIbS0xAieB%7IipbJF!E~TAYWo)ea|Y4_580#aT&v zo8g45<6d?+VfV7W&2Ylju)fW5!uF$u&2qvXV4W@}>?kVWoUcDR7tV)sz7_0+%LzN1 zIb2TI)6DTLal+o^vF32X)^N$Cu|ricGu#3 zg0m?-(iK(q{u!Fsf)h3q`HxE;fg$yh*gQYEH}(WLVHZN>aKbvEXhz>qrv#q12pKCH zF+Td}_thU9u)!A53W7fk*P?wNl++Pqbn)3W?@9YUCb}8al|w$9x;sTz@&m*#!gda} zd@@u0LUG9V66B|-dtG$BSeAdmy|Cr~16}ZkWV38NWPZz+&kw2nq0-RbL%tnbzq;{I zb)_%C9HeGr>sL1cs_s+`f;a$M{{b+=rsMguk0s8@6L}!!DSRWqtE) zmK&!2`skalr4PUUfgiqIEHNzI=E8(wz)^;S=UBl5O*~0lqE={Q@Pr{bw%{?zN@4N`DvO!k1jdRN&S%V#rG;jWS zk%P~}S;_=9-F7#GM=|U+pJ^e!!sO70&myFX$^NnFMD8ye=7-qdH(kG_=GYzC zv~=mBQmpH^w4w^DL)Mp6ju;MZ1_u9oU(t22@tl_j*LmU`56<)8GOt58V}3LvZKycP z%b?%9M4CT%YP8GLXd)TyGC10Cel&A(v}6Aya`lD#yrV(NOAB|H%7tIyK`)v{pL>2< z=TLaNX6bzcYMx;u!G&;1RdroceML!KBiMU2`0N}Grs_*;%7>2v3eWG`XX5?eT-$Z~ z^n3@m&mgbuR|D?aW)^ED5u>%kp3ca2kX2k;rRiR@RMk}0@;ED9+yD-8 zRYOVHic+k8Tv36=ZF$m_6EKb`&5q$m+L5w8@^-ZhY!34?gtAhacZQIeG3oWZnq4VSD7{@simFUa0fgf(?{MTLDO! z7w^3E=KdjvuLNiV(}j4~#wi1gy^@kr`cf__FRxk_2v~$W5V%Hjn|~C1jv$12uZMieuMXiuKX-4u6K++C5&u&~@XMSc@ZZW{xU|8hkBpA-2%K;$DCBL5SKe0EJ7 zp*U7?yyE_fGZf1emnf3M#PZ}k5&4BE@p#3H6faS{Lh%~Kn-p(TT(5Yy;!BFJDE>|H zJ;jd||DpJmB553K2iF55@?&cvpRE(EzrCR<(=7q@V-?3M@;xv0(-r3_T7P?dF3#_W4-v+u=;Mb|JE(GbX{&#rR;T z!!4l?ewhz{ixP$_T3{N(uGsjrc1!sRk*8(7JVtHceq`V^Bu*Dz5jKWVH~}PqU9m9_ zH`X@?n{5N4^3Li|oLg+LX*?ge_U6Oh63jE&YapvRN zztdXDSB*5c-n;vlxy^d1xAm?<+^x416Fdo>4K{5h6t2Aw^Ubk9d+fHgcOK%l45Hrg zu*YM@2Ag&^6s|p95Hla`;k2HzcNOBc45Hq-$h4r9{$7SO*Io|naX-;sM{KrzJde^| zAvT8haqUg_Nj5Nz+j>Qt?__WdTjNarQS$*z*eRGhRIpx#`?0z0>*n+qm;I^sJ%>2v zaveZI5$w5hpKW6xI>X>KBHuzNx5Sxz1_xl7STH}<9&Sle#}HEnpnY$dEb?pf?J;Ed zkRiz+r2OB(%N@S&Mlioa3JXV!fNn_Pu%TPanXE&d2+cT?Pu)~^8`nDi>-+IF(c!)-&ch#&vhDeLs{*KBQRmyjAltNzHgg z{PpNe7XSF@^R8t8FY+y@!He9J5Qjt(UY*-Lg}&n zV0W{;$lYmyzOkC~B6opJKin5nu{B;~XQXb*i{!e&mKRwMi(i`;`6`CQO-=D4e*~Swi|oQ?Zo-SKMq9r* zFOs*#-x4o!AMVG17s=In9bTlcwYHHLc@a$oyvTtR+vG+5mCXoz<^7y9J>W$yWop2S zq-)H!d6Dy2(Kh+Y`xv`(GrY(ej{0VJk*Ba?hZlJ_r<%iyyosH1eC3T{euo$N94EfR zi!5V(4lh!8U7O)W(l?sRi+qRmJG{t?XwTtA-pyfjc##FH-{D36j_D3BlE+muUL=o# zX1vHARJgpzTWHedMbgFAcFv1DkHctrkz61l;6=*0#NkC|v3m|L@<8^#Enei8IJX46 z$O`U!hZlJ{i#ohWQm(g>7r6&bIlRcd3@=hR&zt2%PN#*<@*=sad^29;1~$UwMRG0NX1vG`n8W2oc4xo8C0^vG z{G)Jqk!N$vwv89bvrdW^c?;XvCNFXsYWcQ!k#DmH0Wb1sR@@3NvInZ{eL0%gf){xK z@*kJH5rgg}v3Y*-Czxj7Mg9dUhZo6jFIxD@GrUN84)re&c#%_R1;Owl<1p`EF1*O8 zP)@?ux3lP`liSGqt!31OMRypvjW=Ms7F#~uGW%BwFY*n@FHko@bi#||*Ck}r=10*h z|0>}{u7F%e-8Gmr{?)>ZycO~d*n}5(weTX}h4{9pz>B`U|=fM4?L)35ecRt(vyCo zolD?zuCRwimV?r>B|Cn&S4?18yRa|g%*-W$Z6TXxa`Tss9DxnFQXOMMY~w>XtFi5U zB+oLQ<|OpQFHSTFoF^u52DrhM`2k!z-BH%|9sNI`I}RHP8V&aA_fB`bTvrO-lRg0=i>S`ORR(K_~m6Z(@;A2!&SJW@As3|+z+jsiB ztgl#B)lgMi zlN>s7M7Bn>0SCygE z(yG#is+z@6RyNhZk7I330oDN~Hb7Ti+F0t!m30MWwKa|PrDcs{(Q$7_=1{g%B|&7X zS`5lD_cEsU^0Fn1xYBLyqSB?!XvlOYdUQo82+4NtS5;KNQKQh}0@t60ZMP*Sg&-d7 z;428XyBzfPoj7r?d+y~?{?hUjdhmp4aSaIzZ zECIYJ&jA0ta?0op6Ddw2US0}E2Jf5su8qYSg1&!Tvrt5wdU+fx=0IUO0)6g_8&rP9pTe zNrWt%M4)gIp%+dfWZ@(Ng_8&rP9jh^i9q2b0xc&|*7HMo`d;HWGLVyo!$eTdzmR!u zr@ot_JUfBhPvrrM{GVn%@<)hM6{joCQ#@F)OmVTIoOe-fmCC0mp00Sl;>C(LDBi4i zha%k(vHk}YA5nZm@omMwD}JK*h2nn|<@^mh9e6$lc2bn{Ib^#g@G#Zyr8rJeC=AF) ziU!Nec^-J6%7-bID)N~*^Vv0kPgMC7#j_NDr1(?CwTgVc&ho!eY`GTj2Gu{K$cOLD z|A8W(yi-n7q{9NrovfbYf@9Ur2Z)kx=SwqAB3}I4`LgYP99z9s7))1>^F#v*QBT(J~4;)^R9T-BzUrByW*o?65Wv^Th{wz|3kpJh3!!c#=Cd65$5F5j#c+`F=cZ3F}aa*rw z^NqoU_c5A>VDtS^<2LCx$T!IfK#mK;{n*_0t#JC=8EJO>of&_!l7kH!{Ad_r||D-W$U=et4(r zy;1xZOLY-{9mb9S_ugH9L1+7MWS?(81Bh8Ky5%VT1x-!)ZoC0m+TO<#|E@n2)FIvhokT3wDJ@0nbVBJYhh z%Te431_F+vjCa6M{5e||a1=MN-2q3D4f`4##Tqm%#Zg?!0SbIKe!ymL!cjZ|W4sL< zMPBbZ>-k>8s@nA3cm^{E>-q9ogtMOSbrgg3d`bLpIEsgGa0B0sBUsTkaun%k%;6}8 zD7MK_QuBRCIZoGm$dLx^>lTiMG_+VDFO&mq8KI?E4FQHv$ zJ>MxD42Pq5H`5n~^3+pbVj(MbIEq{j+~p|p!y=cXC@fZoqxdV%7>A=su8qr4yq>bd zQT#jWch>VAL;H^JMn0r*Ig0fx?{F09pV#Fm@?nU}Q9PUJ4o8v4RWpuaHyU((Hwt^r zu;Zyb(dAqS)_jv{?R1{}q4oGcDU zaV3j79K|Y*+}5q>NAbrj>Tnc!bLnyvSFqI%M{x$Lb~uWYXwTs&(n((I)X+|4 zd>E8JKk+)}mBUfIjP*Gj#hJ{1x^b%*%3qNXPNd6GEMtZIYugYVpm#lIf}fG zZ?>Lq2HWWRZoHL^a5;*?z;%5$KE)g^NAZ2y_?9?|1sqd{qqu})wrw0mS@Zh*P=}i_ zygg3gzG;)AI0LnOTO7qc>_Na$Jb)Fu97TD=kshH_?%qGZPYaIX5y*dBat(&mOAf=2 zpZp;Vf}{9rs2q;sJIL3n??&E2`2_(-aXw@QKZo~ve}fgjpn!ZtK0BI(tuNV+e!NfYq9lv237in!ae*F@+Z`tj>+H;5$@q=v~viy{5oiadU!gd z)3EjDYX?@}?tjtC>*DX4wO?oYE$p(R(+s!Zf3c;nMfzWC>8EjP{4ZkK;Q(kxGtA>n zw>V^2a9>Bcqey@(#R zyEXjId471VT3=gt^#9PCVS)8#m~v*g49*N^iz`D?`!c}e1G6uhR~hX(IGP7PhVWQe z9PQZ8`Y}|BpYdZT48JicH-=k9Z)-jVDf-Qd+Bz-(T3b_6v7)N6q_loAi~iDS!E3hmetlCSp_@WzDRMqC&YFZA0~An=VC3Kn$p!3 zm}zj&R=bE3Y-w!+=GPA9<}kGm@s8@?u-!?a@d3!woSbfXYON?wmf>KfV^+QdY*+%i zZnD{l7P%XbuEYC3oQiRJ#R(G*dWAF0d0oR3^Zywqg}8po!sc@K2JoUv1Fy3tWapg} zT^%_&e2TF5lBL;sZz2l59vN66db`!-@1 zMZD%~UpE-zA-q1I@cMwl>jSp?8Z`4oczqZT;q?K9*9R0{9}tf&WM1`G+*5I~;ylF) z#U{noisvg{rFfg-{ff^jzNz?`qVW1yKPEcoweb3Y!s`PHuMgPnYtW33@cJ+wJDRV- zZ|Y<4zj(e$AAwvWofsox4lxkrkrGhOlR%!AsqdyJ&om(SQ+{j=?SH}{{^A)JX5 z>m82fwq5z&7gpJ`1T)1!_@*0YHxZ!d|9_3<6q{119?aUVj8f;oI zWY^xmVK0gKM0=b|*4}}L+cJoHzl5#U_-jjAB+ZoNH|q(W@UbL007 zwhW?P9Y|rwnhG|p0UFodb$!e+z<#jXwjXN{w`CCZ&VfC-hNOUC(@sX*wYT1}hc2b; zUE-8M)LRF8)6BzLiYa>+A@16H6!y5E*gh0V*}E2Twt?qGhK;!3T+SV#foa@sQMCEW zFbR&)JOrEXZjDpN@Cx$rDYXq87l!rN-1a@wCm288PuTH$3~{{Ossl*qxs^P(naDR2 zjUvyD*U+@bac7;dmkR4J|0boRVEkCd&G!b{N4Am;>@Nd&ZhIPEdWP$^MV{NJAwx~h zE%V%#_LVA{@!amXX_Wfj>j2+-S>k!`#t){5*FE~&^T*KZ-X|%qd!ww^Ju&62>d*gC ziAVg!=tNdW^l~5$z?LBti97)vXl?f)6|}Z6Ar$S2kp!*nPn06jT_A;X8K2Re)YMQU z_6KH2kIsi((AwgtBcQc$CWLS0Phs91W>1fBiPUfuWk74Y461148vLex3XLx}kD#?p zV~N#Fte1G~Riu*E#y6hnk?7UoPZ7z`C5i86ya+i!Yop%F9EqO@8q$IJ!(LW;^ooo@ zkmCjlc;P>wZJ@QWXjqpdCf|sz_ohLILHRXGbYwg%G=;7* z2suANCeqp-W*tq)0$Lm6s3RBa*2IQtjgdGV+JM$(8jv0zE@GY$v*P@-2CdDAIk_b( zyx6b~!cfo8!$6fIIdeXKUcn}P!yLaICP-^zwQ(*$1zMZ!-(S%#(Ata`iSt?nv^FEA z$4NN@t<8v8@ek2?(Atcc6F-Da8>eDk{BoAvN5yV&S&g+w#h&p;S$4dNNv{*nI6`Z? zm#tcl`2t!S;~aH53k0o=VmN=5AAgt0)1_mOL-D%9=UhH?dq(O!9bK?6k^Lj1YE&d~l_hxdG zLis)8RTS^i{A8RyjzDX>PQ-rk5)SUe@h3$b5Z5J%H;OnYx1?#27kgYQDujp* zJfR&J1ra^ip!JT4FQciab3c}{Me!KLXL3WhI1J@a%*D$UFZL%jH7R~QoAH8{ofe;q z#)8&%z4UixTlnKYvVBz&VMwN zkcDGGYx@gIg!5mDCeCG-Kx^9>dp(^0N;I(tZGhJHj^x-F#rX43FgxjL42ZLnL}cTT zX%5;HjhuoEdHx;HaDqBnsj~a?X34~IoVGzGl>ZYHa`xvel!G~B-Z@WX>GOW zX162I0im@WjvNU&cZ1eO0Vk8h3+xSOZDs@`3A-e*&Ir`Vjz=Rj-;K9wLTmduO-)2o zNNb}&Q_HxsL2EN|TH_G2W`j~&92#LSG7T!LK5g*SQ&JFl%MaaP5cjrCbtFYpq+nmq#C((^L0hv}}TZYZ>+0JXu zXL}k=^M9Ppd_34b!Pbu-{rKlg14d$a`2U*^KHK@iXXDchemUO1C$h5oT|(y+g+H5# zHt*{D*TNjPb_aSpKC^8L4)nH`+2-f^LvTB~%bF8>FO+%i1RM~%+Es?P)|noUCa~GM z5r>+14zb9@@!K-wKmjrvff)_U%@%2uq=99v&pO7Lnf~l-A)BVz z0c=;H$u-kzc|haHN5BEBp~yyBk;fr(JBRIi@>Q35WcxpJQFm_2MO`xz+ax%ln;y+H z{^_D!fStio+dZ0{Z@kmRxd3mb_@)Er4Zi6z%mTd8cHeaEOY#06aU-{t1hlV5i~S7&$4t+Vwj(H|2Nk-uv!<+}j~IY+mt2e&0m)h8UAPUr zs&39%lhbeDZqB(rGhXJ*JKpco&)f_&iT;%4DlSs2Qmj+_q2h^(=PF*H$oH4DbA#e< z6(3N1Ns&)Km@gZ5EW}=l1&YFpfPRL`2P;-6(!&7D3GV@Tsmj+YzN#pGf{^|nm9uc4 z!E!wmcT*g#$Zu(wevo3N;xfgP6wgzpjZj6!%v=M6phh z&zhO56<`!hCg#o%xIu za#C@y;yA_WibpCQt$3Q^#ftYSKBM@C;-`ucKFdWt{BDlePjR^7B*nRk<%&&;Co5j4 zc&*|ciVrKksJKyaREDWXY8344W@PqfFjSbGN|Zp$F*{S3ASP6O12T0HoUY7~+`AbpQ#U z!=5{*ZCylX7`#EaKre!le6&v3STDz&b=qSCQEw^c-(W^GSbG?TX8F$O(>foGH^s|J z>r0LrHe_(^9$4#j&ru_Wj2by&=m@(CY@yK4Qft8u8Bu8XYg^`{)eV$JMNNMPc-?XK z^amEa^Wnbd7B7AN)Z&why*^&D}6|H^KY-+Qg;o-afGoX^t-&G|gCv{R=Mos9O%?$k4&5SeeM|)~$F7jpcleFTF z#aDhA@%{HE`srV0er!?-cbf6;hQh_~`F_#6Vb{LTxBD{&y1eH!ss zV8>+r9ea)*Kw1Xny@3Tc4LQJx8-pBR(xqV{gETe|MZlz6h&cczU3VzM@^^kfw@T)V zL~D@}Cf5k8x}!xE>i{V{j3pM!izMaLg@;ldRMfMoYDRME%={H7J7upgd)27qM8y2EEPv0mb_-H}R?9eGSbvg18d23;FPug&@Z z$_x@lK(eFW@D+GB)q(kyWH%3T{7J|l*_{EvoAdZpXc4k+>}LIkbZj z)8ogY)v=*@Mof|HjA%)A{}Mwa*`0}4CePp*s6zV20~bR>lHH}y#fA1WI>Q+7;!3hJ zVnis0AlVr)J^m~kI!48;_-<^=SQT^PS5O?MVqW|@bP*&wQ?^_D7?v$kv1gnv!9lV! zsV>QGBU|-fG!Y~_#yRSHQJj`RQAl>YzX8dP9TSq>v6N@2jGNBPYNY%dxuwe>*>RC& zA=%N{ml^NFJ26h{ry(OqcBUzj_=RkDX~uL(O|5Us!BUbP4QJBvAvdi7d`1W$+3`~% zlI%$Eh%d$uNOp{~qCMHn<+dX1p2?gFmSo3+L`im9KuLDmFeTX;DMhlI1`{ONUCye0 zn_5!KYM|vRHohe<2Bu-&E zNOnd}Ph7)_L9#P)R)P;i=sV7o&q=UmlI$M9KPgFe3z#1yJCk0R_y@ZMlHE&^K0L8I z2OlImlRheOEoG4GK9KY=iQ8E}NOtB_5|Hdn{z(a0%^D;-lRhO;&GI1GeJbUrCH}-w z1x5*-$ZN=~%{C;vU9f8s^e9G>9skW}>O~d>$eQ=Uw#})|5j(?jZ+0lfM?A~FWAlVrONOr;?1?pHQB7uE-$S@uWyWOo3#_ox=l3Wka%i0E!+w>yTu}o!jGKjul9Dtku;2oGk>B-37=B zk{wk&eVztnc4LCQhIll>1HGrugU=odS%^m?eBzbKIoKDXG{7O*@yrL39aq~R$&PoF zzK>5To<{?4Jw{4`Yelamm%_rI*C!`N`?19d>Vqid?(t$mRR7 zFOV;zbExxq$kXvO=wgl7FB#oJoqq{UG(uH0asht(_`Q+WUzG+sAjt9u!SBoGwEpqA zHz3O>D3aLvzKKfw6FRL${Lk2)qK?nM{S$MqWgU!S%kRbBtd@LSo~005zlNr2&p)~2 zPm%AxkolM;->1D(M0X>aM<0>-eD3U@(wq67g!}|`f2QtK$;TpGDy1LZ3;U-@*D9cz zg$;Rf{r=gVJA|`)WY0^>^=JDz7{*XPuS17%P-0GZb=;HTT31tWoB99P`x3w^s_XBW zH}hWJBzYk#FYFJ(E`cO0f(8s*L}bSW6^$VzB$$mXfM^x>rCPCCm%79StX1p2i!0(@ z#8zuv>VjIW3NF=ZUF!GyoqHykAg%bXe*O3Rm}K7Xo^#JVcbR?WoO{AuAjF8Ukt~Q5 zr=l||8y+Y8XxvUo*&}7olyNDX*v*S|(v)o5X2Q3WzKAP30*?WyS)Jr#LHV)hTN*3G zwizgKXw$Q7CoQNy1M=-AXq3+siEu{?vU03JXlC~R1Cz~V*qL@o1XImncM1o_H59pn zj~;nDm{g7v&9#q@%5e{nS2CO#4&`KLMmj;hzt|yJK!$8turG1pBR4GF2>m3vkiZ97 z$7*hAV}b`Fh?Q+j9AJo}+n894)wbpnmKuIz8xwp9U|S0bCkp>)w~dJl3=wT(f-f{2 z>*&m`5<;2X%govjRm1fh=Hw7Gy}iY0S2`QDI8LN6C!7&sNafs_;f&qFxrO2M>ET|7g!2>OUc z&OOHt52uNi5wvlA*us?)7l$8gZpClSrHD90EhCF)Yxn>DtculsAN@eFor5Gd&Z}$| zE5`pXgC%1>7&FSZxkQjb(H4>$Q@v#6Y1H4_#5-?wVT<5@?qI!s)5%4oOagdh001Z!FjD$QtlWXl#6 zqg{V;zZtV9?_0JXHcwMc3v4pY`0C_*QYLA%Aw${rWoGZ|7l)$e!tu1bDD61~7Uo1AqG$O_JMaixU{Uipu8ZhNkAkxO~Q> z&tEnQk>Zy&{F`R6-?EEM1a41xt2#L?abonOq?043gim!(b54hS?EgwTSbmG|SUPUM z$@|}E_sS=Ff8mpCKc4`S9*LEYzuX42ixoTAjx!o;VEuU;YZuonuWR7ZR8F_3vR0oF zJnLCELJ#L_d_s{gB7Thd8fQ~43@!M0MLa~YMv)KQKEH=k9)6O7*u4cM{wDZ$D*dS99~6`E zoX2u;#es^W6{jf9S6rmHOmVg1S&D6n{7gf=oYaK)l;X>Zoalo56g)Z-yDJV+9IMFh zkIZjTJVEh7#m$PZDt@h)id~K6dMNTkFX?fL(-cosD&@#gi0&p}0=*HpPvK&ndp8_^IMQo41i4WTk$^{S~VeIhPdkPgT57 zv6!Ddz~4vlK*c4BD-_RFyh8D2#fKEPDoQ+N=#zNNz+O?KU*a)?9eU6A1HpJ{BM+YXcGfH zQ6lQgQaY|Eah8!Uah8DvDz~TR@1;0J`4Vp#auRPDxIp<8Dz`*&x#B8CoVGgId8R7O zYXJK_R7;j=`$5CP`p@?bM!I)SBf_(`th0XQTl$xClog+ z%Jl=~UsReOov4p5Gl`jsT^0K&%Jl{LMM{rRoTON)$Y~^~=Kw{y?trdRx=B&|G{8Sz z>5~P$0_nF8EH;KLKMFa zpj@|rM=AeU#h)skrFfp=FBLCWT&H-Q;*E;y6(3N1RPjkgPT|3JyrhWJz7@i`+CLsa zN%P} z{=#j?Wf)eRs;v^NT>AGh+qo;!l;O(yO0oL7k+c#ZR^$BbFMi%6FoOCRULtV_ev6U*E|{`(>!&*U-n~#9#cpbMK~ zrthG?d{zkRI~w}9o!DPK2m0+>i!}9df8c`e?ACq$P63*ETyIeHEu6MY&@PlwHJ8);_G9Xpxn7=9}PVG#g}V;fGixnb2ix{VV#}e^4&JsQ$|Q_-?qt~ z*tN9ug|c_gPK&`Vd+KH!Y^84LqS6(mS=Af9++e$3obZYJUfz^w(Y(*yVxMF0Mc!7} zTW?CufxUI+=JkKK3Ycr}(Q`@)sF0zC_MGB^a)s(SCH&DhV<)L~b@@7_3wd{AL{J34a6?VNcCjn_y4< z2*w-s)V%9*+%Vr9!mRob?29lHz6K@Te%LA8-E+$z02Aw*LBYhj9s=%pV7W7M<%Z1- zKSH@XSz>m#GbrpP9Zu>b^3}xp3pCEH={AG~=c4{_B5OX=r$8_~EUS*`H1Z3wS2KMl zy;fEHUVv0oj>!d5alR(D?;U{Tb z5fCS}p^CCtd5Xs4Mo>H}v4mB<-))QO1taceD%B?q^7OU1h-1 zKY>uLHzJycUdP_Rk5`z*H0q%JwO6Dyy0KyCh*y+i8W4>=iweD>Y(u8T&WB>JsD~lN z{@NRvGDH;7{`y{IC*Oo0ddy1SaB`$kWq)t?=qB)D58%fer;}sCM40;aP|}UXN$#m+ zG&Y$%C{{8xb~M{EUdi;>ha@K`nH~EIUG(-+GB-wJC9g!uo?_(dO;j>rW%5xXYJ1b8 zJyAz&KDMg2Z!*&y^|LqzGdz+GCpqPWlin=p80b*!cckYkP5bLh(C%T7mM+8o`WiHC zjqM#8T}kaS-iKu}P3^C+Wn~dFhHmUxw!7RrMslMuHq2Ypn}enH*HoPRGyHJX8p7_m zAYgx;jHX1r)+i10W3S`KTb{u*D>|LcT;W%Q&BMJeoleo!-fhu6(Mj50d$(t50oq@C zcldh(?XSH%m5RpBV!Q70$PldjOSTzgNzdG zuWux|vDb@eUI_NrS5noZy~4QRge_+5Z*27wv7tf^j?s$Hd(xXKq_MyDHfcr1{@Qz5 zJ7Dauz0F#0aV&;H-tRN^m9izVOR4$Uj6;Mp_SfF?s%lDX0yp}LT6RY4X6}kFVYVT* zYEF!kNqVnj9t!n z5Bb;6)HhFA}K zu)j9)bK+NUSYdz7!J++iAJVYDen#4h$t_tw?5}w!iT!mID}enqj}fuIo=FDmug9PU zvA-V7F2VkKC5BAwulbVBgZ=d+kr4Z99tvh7eFN#hMiP>Z!$!IeZ3?@uK_DA8a+VcK6u*=pEd%ft$>zrKT2!~WXzVp^P|>;>$vD^RnCNlrINuNTA%DG&Q=bHG){ z>G&ZE90YBAMCHIP(RP;ao!GinB;W1FkpYZffBI4W(&mr`gTgd z{+cSp{`x@H3Hxiqfc-TMvOU;e8wTvJW8AY~e{C4BzfQ0S?5_<2_Semnfc>?ph4$C$ zpq{OgF@^m#X*Nn|*k6-A*{5lL?O~GBo4|-qM~;U{PDya{xfmM{_SX*z4f|`J)k%md zwZGo+z00&A-Z5EO*aD%lbrI*2m9;SIpVOt=B=IBUyndO z?#I@k%HDDOgzc$p66~+9ftEhBt3EdI4SH!M#^T3L$a^ZQ*BE3Z!~XghNWuQPFV&IMmY+xV7bDS}HBidi3;=9#@ zsKGuugYR2ea{_C>8uEUUxdG`vVBJLC-6(4xlkpbh(veKYn%Bhctrj`nr;fvF46={w z@+9Qw%=Q7+0S&DEc;V$eE9u_MFGh3sz?!#^^_|e=kKi2*x*n?-VxK5|{0GRdC{~Sj zz^p=FQH~IWYFmXxhH+aY$)CD*Bd|5RT>)@UsW+TB^|2 zqAq{Nu*{X&cd!g=q$ki-Sfys}=?{=#%|2mj-i_^^!@^iCdsDWQegVSI`K6OMkXWU( zPq3YqQDIs6VaSGl>GZTYjLuM~9KIeULKiuyBu2o*#R^^Gc+AG`!|k0<1q%+UP_$wUjIFmM zrBTirQCr(&Id3F|mmT5hS1Mf=db{u<=E*kw%OW&ZIk(EPM`X zFTH=nl*Q9dip{Tw`NPpo)4@Th`(!0V>u_zj4$}zr4^R^BHR3LyWMSNQw*Z6PE>d?3 z%^yj34({z(P$Awy7>9zZO*)tS_QmF|kI8>Kxf7UoWU%D#3OPCLSqs}weAc`KxWlo+ z4Bl;Hf~Ol0N6VDFr66D{PnaReg#_{7#%Z^W37%o$G~l)|(PW5-n9W}S0`(HuT(}?L z_gf3QU|Vwu7f5n{!dk;6n6kX5*>1rrJ2sABN*+Kk;`4l2Iq{)|<^;&$!HO#bPgQAH z)w6&}GdPD4im}3#fKY-}TnRV`)3JuFR=N@}c>q?lfUp3oxDs$ostljNQBhX{COJTK zB_Nt~LEB|Wn^qr&lq@*mLJZB6g)O4b0dWtkwzXdgfDJ;Du*M|){s$ctY?+gs0tw74 z^4WyXhL~Si@UKKqd<%XU@>_fZBn#$@1&UjPwt-a#ZTb6y9)s1l-7i6!4e{yykX{s^ znQjcwOtb&Kyx;O*9mqCIXbzClFv(Yzj7|bXkzo_ec(hB{AvQXJHDZ078hCe)!6cV! zK%r}s!F~mpc8FI(D*v_)a>y1g`IL2!T^_Q7uJfF#u=LRPwVcZ+CY5G4Lt_ARKs81w%!vi2YK^KIrvzn2C>Ds0&y5cFP=q2Q z+tqxnYVPTz#&hmmW;@GQJc|w1#ku0x z;fdZM<2^Bd=8TCmrs(lFzoE6MqH@Iimhu)%U0hSqTnfwc7EC?dJR2*&8X&F;#E z#!6UJH`JHW8of+Hti!-PIH_^dsIjm)=5)8TmM*U?>ttcfFCsst>&24VhDE5ermnHI zsj{rG1ySE8)hv-(X%D_ajO<}KPxponGiPR1V=$~`g`>sDx}u>K4TW)iIqffLNX~hn zgIa0%Uq$2U!Z9q-1jA}{93keZ8lM+BW{K`(qFq+rj1jJ@lu?0Qbm=}brosk&F--Z( zOxhpnT`n0dP309W;~T1EnE!2;3~p^v(o|W#xC|S5Wl>p8IfngzgRe&5a6^ll7uVpl zU4z|fCng~Oq5U@6cj@mrFZn<5;Q03RVuax7mcFd@9bGX94qL~w~f7=zKwyAPSS?eyB zjD+zZksAs1rRjY7tE!jV6J8uJkiIVtj&Ytu>%~jNYz#T0T4gBRSXoh1Ra3dxY_v*v z^Hep^@u_@CGcGc?1*%wy!??MU8<3}Ab;|O^c@$Mv!r2AK65UwJ>g&pDvHhW&)miXT z*&{J{?^*jN_T#;1qN<@OF|nyG@#DK>e9I?;_wW9~`|!zWxhF# zUHst@bi^vAgXLKMTNA@`WLkw_eoiM&ITZ; ziMWl%3w(UOBI30dZE%P=irt8KE*(IG&@knXROF*R<)xZtuHt2i*D2nq_^{$;#g`S|Rs2Aa?@*{u>~?`!O7~HuRRi-UDlSo6u6VNI&lRs$ z|a4wD$RLjn16zz*tvqfTxqd$1%1ELw3(p% zpA=<2I?()(Kz=G7t%&)G475s`_G-j~6sr}_S6r)ji{j&od@N(RE{gez#ftkX9<0bu zER^RITEtrwHz>ZYNXroBf1{X&XFJlI3x`M>7h;uStKvzDzffGKc$?xz#pe{?Qv6i$ z`}$o};s9YgIA0s_Bt=egM4Hp75jl?>@o~jkeg*|C^OFN*GA`ix%Kw$3%u^1&%%}z2 zqWq5)d*Rrmo_xjeiZc}tRjgC|iQ<`xmni;5@m|GEimxhusA%JpBJ0ak%u^htI92g% z#mg0CIyjVLTvC=#N;WuO(f7A#R+`f@QSMm9pDSLVc&XxA#cLJsR`mTWUQqh4ieD13 zt;L@L==)Q|a1LXAxkR*4<{1a}RsJyLi$4YUqm^HxeDS9Me;?)Vr+o3J0KZ!4TE%55 z_Y=iam4Alf*~-6I>B|&vP`pL)P9oa9LFq>oHxtpn=M-O1{EOyqRs5Uc7m6;<;VkDV z#uWPz(T{ipz;8ca-9>if3v5If@r6(&m`$__gA1 z6xS1>=RqR+@>}IUqxhoYD~fL`zNh#h5#_!nVm#Ba5(^cNP{id!>cMGA5aNQo_Okx5 zip7eP757%0r8rOVAjLx!s}z?iHY=`BJVx<&#nTkeR6I}dmx@;^{z~yi#ak8cQM_OA z4~j1;zOML|;`@ppDt@N;r6RwPa~!f2dnn3v75srp4^`y%bIR|pc(~$XMX^IgeuL6- z{RO>B=@S%BQIzX3^3PM6hFa8rx#Bg7*DKzpc$ebCijOI7R(w|RWyRMN`K_P&zgFa{ zMbe&Px?;AX#3ey~AEgH>N}Lk#X&b=uC5p5QAiY{~jpDhAmnp7Q+}`iy0p&lexLNU8 z#n%+yRHV@X>kIMv4y3^Wv72H-k#nk&Pg4WpIK>hou1&N$Ab-9hEelA?eFgAHrD*|6 z{)t4CqwN4`x$gkdNPzTpiZl%%{fOcVihol4i{e&A8Us*1MKM#ct70$3zKXa!OFR7I z8Kjg)wjeHpg4-YW*~(8S_E${N@sxagpvzVM|2+PI_}Spy!LHZ`7)n`i=*cn&zuZ39 z^srg@@tNa# zTrd2^&zl5BP+vOrVV|cyw#C=SYlB|~N$Yg%H^0MvnE1QWXWc@3b0`uOeL9~WFg+x4A{v|olQu7f^~ zy}$T*$Ab~nmkxa;;IVxiM!$XhzUr4j(s~*Cp7A$!An#nHgZkz`AGZ_rb;0WETZ=UH z`EB|Q9%dO|$X}Sp^#(;>?t#Qk`q}jD&-EFPPuuXS2EA&c!~cM*C?0?Js`4{+oj;gg4u%*at-;M-?Qve7B!X z3lBbgtTX)`jPqvPvWJv>{L9rJ-il|J4=-D7AyUDsTj#FoSvtIQzpd`U*;}2Z`)v&^ z&E9ISTCr{2Dtp3;Z6~jCKT3C3Y`Y4aQ&zqAOvZgnF4^|0Rilx|b}-)_w|v{6RgARo z(lcYHynItd?=@)2?vNg|ElFDX)0@_yJ>=NC`MjjfYfu+>2M^d5K6u5plUCia&05v6 z?a}EUu15=39S{enq#p9K$YK+hl--YVS)p|Asaxc%cV0LPQ1e zH*k{}=^Y+LbZ&uv5&da2rh>+6aPERygj1ML?NOH}DCd3rAcVr@V1?aZ;WzRUwBWNP zPL~LwFoPvdXJ(V6lO97ZLns^to`g{N1PL!0S`b2EBhxg0M+gP-&2+{t8j?bJ4WTd$ zbnGe6;dMzZ0D56)2!-DXi4Y15-i8ngEb7=y-_YY1$fFC7_;YIr1*V-v$VUhT4njI@ zQy4z;_pk%hVQ6PkZ5zdYA^%X)W7_w*VE|#6BBwToSHjdg!)1w>Ms>iXvAcO+b9Ccdx zBZLA;8hpn-WA-fR80b)J8g>GNP+&)$Ji72qLF)IAmM+7E=S$QkAr$%`VaEHgOs1)w zFVql1!SD0W+2?X^faJD^P~c#x3l9}1^KO@`)_^(DLBNG)HJZi{3iJk#&A<;rD2Qh` zD&nObAr!PCY@XdwRr(~fwL0mxC=W9Yp`Zmcgo4Uz2n9p6hftUR6%3(p3ah$Xy;Rym zD2xX;5JJI}%{5UXHpnQ^g{Pi9-q?$dQ6aeSd_q-^_PS2U{;^uN`ia;xLJp2~W$u&S z`$D#dP%ss>hfpvbXb+)a>Mf3)Kvlob_*lx8#Ii{~o57p?P+ofo1*2+8>|Ad27xl=S z5v#;7A%wzjq`z}w1DX3urj6mI3(plKx1^4RP$+Lftdc!?GmS?uU3f}Z(ObH+(S?T% zV$mG=;og!{${+HvT~d+Ng;`zygdY<^fuj@WGde>km=0O-!5j>@@GO=tz%_#TaN#j@ zG~UFD;lg9+)c7&n)!@Qo%BRO$Q7J}RL>9!w@Ch|crVrm z7ao&8Hhv~)xbSS0{NngctRF5s=2TJ==d*VbTzHIpM+gOzKP^6w<>A8fq?Df#U&UdB z3y+bX6VG7%aN*(L(1oX!`EcP`De?>AJgyi*frnD35DGj-I)za96H15+&!toe7oI*C zGAHk~aGdk>B*BG;?*pAYapB>iU^dcK7?8k55|WL>Mw*W{h22vikZtpV!5uUpN|wJp zZx$hz<8Ip_g!0dWA(Pp2FO-8Brw<;NnLdry&E_z|g@;!Bxu>855<=lHNW|sb4Hq5~ zIGMyBWN+ZYV@A-8r*nkh!lQcxYGlXZVS(S=ROn4hf(y^DscH_I!Vn51sA?gL!iC4s zk@!&@Ik@mlMeD?chl#r&tj#td6u!p&ZM-{G!G(ucGpf3ZMd89@wxb*8H;p8?@KBg8 zJcqH>aN*%)f*}+}uxhyQm|jeaA3%L@;i(gS9U&B!N>e*RD3}ATI(`f5gA0$LJ3=TJ zdS(1{)(01!m~8Vv2!&q4fC~?!D=~xuTj1nfX2+Re2nDL>6hgr;;KK7W9$awYF$}oy z(6Njm6bvH}LcuWL!n27IaN#kvJOvk?8Botw$(X{0hcp`{G+cN{=lirDLSX?I@xQZy zaN!}rF<-?og9}f!&~V}5Ns)x8f(s8f4i6-yO$Y^^33~9X!w?GGxIOAPR&e2At)~9p z_=VuYQ;u5T!b4V1o2LQUyRn0Dx}&hm1HGrsgU>$}-Vi=rhmyGu{v8Qv09<&svIlVC z;h7IEJdAn85DG~`;zo=?w0fTjDs1xsh_MqmSyG=l5Ii=q6y38DSS>qo0IG#TzPe%T z1iBW%cZY8hy2$UB^oqqlR3jPQLDsrvA+H=~NVv!w& zI^eMa-vokRVs4trZ3Rg4783di+!l0B0PwVrB*6^t{?y2YCjoFf zE$n>6x)dh`GajZdYi1L9sY$k$NB@Sv1G9(pYa`9hgse5QxmDyA7HNM+@b$12v#?T* z$Y%I?C@zas=o3Kd^<|j85i83R`RWPj8N`Q8dM1%=@Y}MZIv|3DTOw*Cr*qWI?z?6> z2S{5vT?EY!ccpKQ(`CrJ8Y^2tWUG>`=0=Xp^dUXl{8ob3;`7+r^`^{hB3m4_KAmMs zkb2DI&LF;Ma`!d4TR{EUBTf`hC=$pDJ zp`YfsfgpR#C4{u@Biu7^Y!dJ)4LeUui?}I`GQ>)Whcea>N4GIiY=~Mpa^`@*5k*)i z{N-*N6V--@wjV7x)=~q9%N&2}OUxC2U?t{?zx_cR-NpgryA8Nr5O^?w-zZ1bi^88n zcwhL9ZW|L2hEQX)jR_t}AX4Q}Dq+8^IRtb39MEz6unV&E#IKxQ+Fy#AeOt2yxF7n< zMjUXvB2LhiWZ@6&meJXX60f!MJkmWcjbmL$$V>DUA1sRE=AkH?zS0ve)S4_VOrvL#UB6eY6Ap=pc z9jTG*aQ3jma55WOkR^1o1jEP*XQR2P1>qoxm=)9pcL>w8Wze2L#0$^`)C~5%QZAY5 z*?5Ga2={Bx@*-Wr*?HlAlFJH%S&oxzhjYNR_YG(D(a;qb`#A{&xj?6+8x zXPpDvgIYMwZab8lk_hLZ!)SB}lQ8{=0WVCLi>mnujK&BCZ~}p0G>zjW_CQC70vgUX zw8D(G3N8sW)2*t9w?aij!x1$o@O`{1%22AquR^>l%+&P%!owo)&19FCMcr;yjfwmv zi&vC4Rpl2Y@@J1sW(v^M&}W$i%>^a#T7(YQ~2BM%qu)HThE zQBOxai*I{F{8z`MU?0CWosN1-qm)Sd7}Gnd%!7qp`40Exu1D|W?yv!g^R?rOim zf>{oZPD_n-`lipD-YIG6C%Pv&Cx=e4L#HJ_`pCwI)2yi}`=(hBZ+zs@$sL&!M?#SV zPq1vhT?_9%HGifRi6zbSLdlU#H`~s!<4&&K&F*gZurb$9s9)fg+T29| z9p2jq7DsQ{eU^h;^5Ej&W}aX4Iu=*_6Be|qaXYe*a`0pxTpUI=4lItmJLzCJcrXht z_+lF*p)YMaI(<7jb32;e3>}MOWs6?}o6GIc$$!Eet?-}dzc_f4%+e98v`J-aIF~ZD z5@DVq*o}zH0Yn(I3{yTgALaH?oTxZWakk=qii;F$6dM(fQ9MEMY{l~wuU5QX@ovRO z6kk?+M==e3XS;eS<|}fZBl7uSgm{o5KhlwIQanrXQpMjWzOJ}UQEVnrE)`FLEHAc^ zK(U1c%G6@OX_|kaqRa^n{&J=9?N`d5qj;s_EsA362>C5af27FWm-Tj06w?II`zp=Y zxy+Zjy@CAfPx^L6PU%GY4aJWYZS3acrz`eRJVbG+;;D+~D_*5|o8rTYzgLXmaG~Cw zisAzSx>)HMiVGEM6^~XtL-At8>lD{3KBf4w;`@qUDW+mam--clDRSyI@@FZQDK;w7 zri%Fq#o>w*6lW=Naxuz@PXzEZr7u)`Sn*lKHx)lobfczxwqk$9QHoO(_fuS~*s6H4 z;`xeKE8eB}gyKtz?<9qD@;O@Ht-z^`|T5C_kZef5jonAEoqIMVyX0+1|?e75(H{o&C*Kl$S}M`zt+I zu|Scp*(hJESfY4<;=zjLij|5Dip`3rDxRTuj^g=>mn*JQ@D*86}ye?Co*E(W_qWHRjZdAHO@hHV( z6;D zt2jV0U$Ib8t}iG*Ug>=lXDaTmc#tB$6|%mcD4wQxrs6LYFH{sCJ;>91jOBi#c$4B? ziuWq=yCdaZQhY=4ZN(21|EkDul9U&dCg32YcT=Qs67%;`+}rrs=<@j8{G`AZU%JJOn zFWhciCSeV*VdIE<1za=z#m}1n25vd563uujfhpdwZ}7PUAfH~?u31?9GDupRaG|B& zlE3(QhlAm#nfD5=@qMXC7e8+y=wQA52civHFY9AJh`he~WstPK$+D~j6T0|$M}Q9M zTfCdur`ZqOUbO2w9%;V}l2#w=*uf`2KabB#L47R&eZ0r;+jlO~eiwaeHrE}**SlM!f{1o6I{OA-{8ifQek+Mz+kHz z&W84o{J(s-_t~YjFPw^)9%y=^?A;5}+|pR-z|EOIV=1zTYOY1{lhV1#DM~BV-+^x;b9Fu9dYrBz8NqaBK(gWa6i2ae)GZ(QxdTf6A zbE}|7=9|#)MytKYhA$mE13b5bH_-|T_uE%O-t!~HV+*GOrX(zS>N zV!t=pj((Z^vB??LeaU;a{btIPcPEzYQ;PT?dqe(ydIlhU%H=7z21wsso4%H*2jPHa z5TNZB*zU)W4@-Wzop6)nuG)@dVMm5Hz(^EcRuSCrOyoEd zDK)#>k-|#)3t1T~p@Be5q!A|_QqHg}-kv-6@uwiWj&Lv<>Ws}=jWq1jXi4hu76Fa| zPk|#W9R+CfDUJes*WvZRUKqYQbsL!85@>{@ z0Qpw(RQ%*4C3Ewtqrm>4W6vN1jso&T09)^i(X#M0;V;2utPh8ut>GxZqE05$H}qgf z=qS(%9>$9%vt5{WRwEyd0vwa{wfLc~5`d$CA$>=Izl$O|3Y>{l@^Sc~x2p6Fb@MKSjslm07hA--$9YD96?+x! zf}?;T-Poff_f#?(`y+*ml}wFA*_QE2rpJyWIYG(n*mW$smy)@$Wh`5wWY5@U4#q?! z69Gp7&Sw!z!B&N%fXr=yQP0K3grfjSaTFNG>{-$=aTH(>4LAz0qsCF74k=EEAzg-} z0B0K)M}cXm){OUInM`B6W2@P+vWVYjKJ39!V3y>zI|^{H)KP$nlMh2SSFHg)86e;& z@DQ3xM}eP%jL~)yjsi@xqDgG#3cn(39`1GNg=i}s1yWE_9R;+2ItpmR)KS1t?T!L7 zpn{G9>sZy@o*~;E1*)Xx^w>V^(|X;Db7L2i+>p#sqN4yGf8i)_4Vp(sff3w}kM?>_ z$o{eG+3F`^UkEuk#%B;X3gqyWOkTUAfT^h6QNVPd-BG}_xj43ws(zo*L&}!K#QgZ# zjNOE6cN8$HrWoq!hZV*8=7a1@~J3S)hgvyrc44#l9+QQ!@dTT;uVM+;(0*`qhp zcm&f?;CR;imhNnH6kvl`G)I0o4mmt0=8%u=G8$Q3nANopN*YH2j!wLSdf_NwI%LJi zaWLR0aHe#@ji17NI0_g#8o!kl!%@J{sqv$@tHDvgluwT@Mx}HVcm!8cIttWK9*zPg zzaZ|AhNFN?u7Ow|!&x631x)_fI3LL9D6mb+7sqdB{csd8r;?I5UpUZFz{pRD(|J4z zu|7=xv^ZaU(ox_ODL*657n5`pF!C@6#~9F2fP+Ivfg70*M**4iBX2>R#}yp~cqoaZ zz?ZB5u|9Z=h@${s$tEGz2ZIraqrhua2}glx7&3>B0tZkB90f8(0)E)NB>k)Fl? z1U8b8Y#fA+Mw`O!jS$GTw}8VPG$2Zrzdc_PA(rEA+aZMV{30P|f9{2HFvC$`DkS&x zX|#?(5a=jy0lJw>Cnj+e;EXPDId{WRK&E$rdAK~T!BN1Bpd0VY5r(6H?h&Yw9fw~L zesg&l5l4aFQPt1UN;(RV!095sibdflVCYEvUXC0b1?HoaI0`Va1;W~F<0vo?n=-zT zssgb--eFNV3YhKa#%T>mM*#}cQQ$&u12_uEqy}&lC}Gub6fnJ*7QcY{0!yItcaZa{FM*%~3I0_hgWqc#+gQLJ0)Xy_|oOi-Wi1kq_3^)qR zpawV!um$2Mz{@5b1*k$C1$Z?`LaYzNfTO@q$$+DPVZc#I-|xQ!Bs^_5AbQ)N(&}{^So9Z|1u6Io z{1I{lopc1Yi-+(Y*Mbvv$qKvY;kU277CH7b<2>*_a=F;Qz^!b*Y0zTt zlfhTqbHE&nwck6a$ey0rhV;i+-zAUF*Y>^{S3_bH$E+?F zL2fcC9f38^rM}t1`xG=^%jF#^yxx?f&s;XvyqCzEBXXrk@-vf!`Isx+y9Ok8#Q|@k zJ<|Ar_FU($_B_1Mv+XaD!`0i=J$09x0mBIVx4IdeH%S6b^y}nQ5V?bQeR(_ZE1<7I zbbDWe(~h^{YVwOosf_6`@N~pv3MHRC3H#ch;TD5doKlkJ$8x~V#0A>%Txa4fyk^n~ zB6l|Oi9B+UP5{~$So^C7fSNdC=jOuadsz1p`blyjfltk1WX!|_L#%9Lg5Oxg$e4-6 zSYc#LSZer%@e<9&S;Uf|Q6BigFDv=njHbiRMn@F(9JM?xiZ+zhIkPeC0L}~$n zh3G6XH&A>ocsp23zvdBM!)jXx5#EsGT!OD_UO*R)*6kMBe{)2snZ0T z*A;8nT4@yxXk*gUdl-Rl&=9(Ta5z>8-N1pW$I222-N58ASP{B`a6DEC-N11>&+rKx zLJi%(BnOfH6-1LR;OS5noMoVmf0$bvfBwP-1w$H;9)>ky?RSp5|2ZzV`IrFB%|0VQ zAC5E|@5?j2GC;HGX9Q?A`?3Jdc5V*P{`L>H3E8?_2fPJq%=*+SSY;t3L_v?whO~Fm zwkSY#U9C^ya^Ma@42e}}j~_##T@qI?41`&BGz6wgbIx(+p5rpjO8rO>|FVhPA)wmV z&GcaWa2R3bPnaahd4y?LBXEU?j2+m<^Z_P|z)DeIIp9=D&L^CXH3Cl!7GRnWb2#P* zmzpe>SxjGTvhXWQPyCujxymueSv!Hm`vGDKc9>l@`Tv(}^8NRo{~4S7Cvg*LA|)WE zfd)!Al7SKinJ@|cXdjLU28fc-WG7&Uo`$s3I2@^Tnu*U2M~Md8dIk|l!95yQioh`~S(vYl!g+`~w{=Z?Z3 zOn~a_1dZ=A2cbX#3$(yOegJDRjoBH2aAt3ohB8{*)65=994Fllj|Rty6z0G{o~HM? zGs79Xg>wtT>C?k~4oQSZplOM)JwEKPbI$tC(F`88=u-D%n#5yn=@w&=Zj9sqBX;p( zIQ&oI4eW|D@S|G5`ym2k6VMWV*_e^^c%UiwkvnA%?}rlze0s6U8b`xnVns!>7?d~r z7Ugw|I(#h5wCUmoA=Nb3EGeT2zqn$wG_0ub3&9p0fj0`QI+&r)uA0BBwHy&AI2$^G zyGTn{R8(V9^oB)r(Wq^px%+=MoWM>P%**f^OZo2#A|S)Mtf_^cw9ICyYrs_fJZ>en z!+*6k{kOvkz%3!sY5sgfAehVuD)q93SD@S2=)Bb=+ zdktbYB8F-J5kkY1&$csP?Dc^Ym7bv{*bBb>%eySM8j?Q{=6bC4dR-CH1 zzhaf*3dK_uFH|hX2LbBaNAW<#C5kH)&sDra@n*$`6t^mVtr)|xNWHxj^A*P{&Qv^9 zu}<+Pif1Zbs(6Fq1B%ZmZc+TJqKng`jE`cu;xfhS6gjC9<(^l}OE$FF>w`a8X-cSU~4qMV%nf&4yAdXnNkiZc~yJHdS4A3&}TpsSS6k6_F{Tk&GW%M`Cw zyg~7H#k&fToJBsfseyS*jOK1n*QnEd+Vi(0MMe!p;zCXu4KiE-T zV(b9Lj|_N-@|P&`J0s;*DAF8*^eKw`f=v2+#fubwrFgC49g6oTKC1Yn;`53xDe~hX z_5NLv9}Y>&^$p06hNPz}ieDON8W@pJJ0fDeA}s?*AEU@GjHItu%N2mZG`AfW%Dpcs z^Mg$*3-6tA39?Fr!t_gh%=YUFnlfBjUny2!H!82*dB=kh)OTG#A1|rC zK3=>0GSo32`e>fzFMi&+U zUOTpFU$1fiSzd$O6rTXHUM_cH4Yu#$K!4Gt_VzuFG`iOakfnd`owI3Q0J%A6cpRnp ze8_q^?yNH~T-MdtpJ#yQFYGH9mI=x|i}uk##$SB7_7|%N&(~=V{n3d;L4u3IDR z=|f*WG&%gm@t=m@>o+x8IQMgRn9o`Nk)3*3Dft(czVnRr-X^Q-hmMoE`NqHFklpj4 zFONShXG#jFP{Q8LP%bF9V8fRuoYrefL@d=yO7~G~^$4ufU8GO?GHla&J<fJb)wED=ZExkqx2^ksi=EmW&aV9e1~c`1{Je`30dEe23k=nNj}3uI=BI-V z>-Ay?I>y2rli0UnUxgX=!zk(UxOaEYmD|KnSiH4DNqh)$m!POSGnYnYFkyd@a=&AV z+1<_%R?;d`G?R0ePGrqz`f><{hh^0<{VIOK1=*{aei)qz zj}@aQm-a{D;_No?VNZ1>wcdcANWX4humq-20>Ots+r0^`OB$BOhPjvEC#gx&NxwvH z6!z`h1EOxyRSxgFQL@z3+VjjY+@GA|Lb1;^$DLQYcUR_M|JllR(El2c5Jo zX##*I%EPGOn(%JOqJ6tNpGvNESk$ErQ_>ARwn3Ek?dvFGM-K$I3)8L(S+A=MSo%f? z<$5EcdFXYF#-Ltd7SpJM_U&Gg*67Ac&=IdF#WWxqdxuJjvJIIUtA=8)sD~lNzTF#{ zGDH;7zWrWgC*OphabQW`a1fV6V}Eb==qB)De8u36(+SkA7%j=XJ(P4~@1U99o=Qez zoSNAyRx&lVhHV+IWO~eHOD8Cq9s4cI?xkdIjQ4t8iIP2Ihq3HLC1Kyry*6rl)1y66 zN30H8)!R3jX^#4@sdGGup7f>)Y3$p*O2+_WsQ82wNsq%n^iSSplM{lO_2&R4eo2=+9-Pvg0&TY-2Ir783C8v!) zq@fPMSD(gipE3+BVV-O$l^S9Tco z?S@W`zr|e*_U)#8dYlh}9_-uyhN~*=+j-;Q!M@$(7sM+`!@iwHsUg_6-^}`8-){29 z#`$8-gMB+^nhxa^$N3=b!M@#`N=o8I)DQc1BR?fRisfP7Zt|zaKOqhK_Wn|SMtm%X z5%%pyeomYdV|cJ{=it!3oz6`j?AtkyHUbXBd0ct0Z|9*T_U*?~A?(|EjEH@E6&bK^ zAA=gizMbZN9_-s!Vray^ovsNU?AvL@rxW4xP%sl8|g1Hqv!yQ`mhC0@-#Z z(%eA4V4R5k8HR`jOD(!M^=5bS8H<)R^k! z+0i>75tnl}?AuA;WD-AzBLw?)GlFiMekUI6+jWmXjqG^XrTW~V(3|FAB7DA#kAK3E zfqgp(s`>|u!oJ<;4&O|1Jwb|V^d#gi9G=q-cM^V_f^J+#_(@Dd= z-E2oUKA#eWa~yqfKJ0j~Z{Hxj zUJ&Plxd;1pbHG){52QTo+YQ|qA4vJ1`t-{9G}Z_E_A1oRGkTmAd9ZI^E)3YWb1rxf z_U+6N`}R{P0sD5U6#I7iW_Yk~Hw@Ufhsc0^yJ5h-oo@6V?Ar|k_U&{>@nGL>7_e_& zO$peyn_6h!z7FcyDj8GQx07b0gob@P>63k$_U+zo+z00&A-Z7S-i1AYeLK&5uy4Pa zBM$ra!-a%>J8!#iKSocV-i7!H+f&&j*tcH;Eq&;He{6#9I;;fSYA05+fYoa!8k_$}0fE zAMyu_jp@Uzew;wSF3orkVmx-oV(qt_yuC9wApI=Xr^tJR8m48u1-Tp~Q?TZp!R}2L zIl6xwh}9Uo@7v``$i>l|7}h)*?%OkjNB_$OV{-a4Ire*rs2lb3B@n!TBiiPNQDKI|KB| zSP_gCy-y%v^QRwHdr9gzXc*K7852=rFRX)yfj9(-gRoiyOE_XkxcnK)GS%6PIy7Uc5Uh{e$8zt#CS_m^Ib^rp2E~jQI|i( zEK`^LcfaOM5P1r#)Xdx5Ka*h1K4EGe%Kg%Q5d7VIH-TZjF&Lp=Iz4R;r?Ut0@;9S& z=prYT#PH?iwN~g7M@AdF6Sw~`XtA7E;I_oK&dyB`8`02MNLJAXa6lB1C=sH(qJqRM z$`;gO>qMQ`l01$?;fj%vdp#+Q8VXm8fz|q!q%_J|!)t4sEa#1+@G4|k$yCH<%i(5Q zMYjC`_6@F~mv+Xtp}&=qG9ksmIl=8}bxgyLU8W0i=ot{n0>2monxp~*Kc%m=PZqy_7(A*YJ%ni-$(?*7b_@7M3>$9yP7xgLglNlGHw@iHhO4)Qk|U7I zO{io+92#U70)uTV)J?4UMLXktaXt2bdRY*84Ac99$W!@t-WN7b!dN?dUL+s~mj?pR zTySw9@KyvN5Zu5N^2^K=^7D)kVSyy)5UQ|Zs`gMD6D@{t+n6}U5Ro>&QUAohA{%n3 zoWQQY0^RSC@vrD8J{Q?LSQ6mDYk^=C97woHxN`~AKwa|!O<^}=!O(D_>nhclp~6W7 z$C*sFq5c(VAQK{S7-5Pe7ZPS*b*!W9HmW=TYuH*&hYBVS!wO@0!eXp&T(M=Knhc-7 zq0)dA{;1KRf}_VZgn$*a+u&BUMIRE>#4I#ZmIQt&NG!pM$P;W88-ygm49xyFBWd=J z4mSp_7G>(l5ExHuGiHlzpr96q!7%19R5Ivz-&gw<+&HsQ0~&2R6|P+&Qn9d=NL z7hR5Ou$4g{iv;q9VvSe}&T$Vq$7PyVG4bn|e~vuPv+aJq-w&VmI}_9iaeoOdL~12g z>>C7*Cbk8BW#Q=cLuxEmNDx>7lK9o-D&RF(1A8t9-i+8Ufg`^)V&5@1J@*>e#)5pe zHt1W0KefI!nk+zJ4*mbAHk6aa4kdu>am4zVGwF3KA#%9}I`7(K1UHW_-;om#w?jq9 z=OBJtJGnZ_?K*@J+}Q0oHbv!TrejO=1S=#GxC_yRyRp9Ib9FTc|qXhLYr=rY8L?)5-13M1QWUad&~F9J+DV~I>4WdLqDsVXWjuQlDeM|fN3e|{ zQel2gc*t(y{Ji3DdQpU-9uNm&ggUO=(Ajb28El3w&Xvaw?}xAa^k11jbH>COQ((7V zwHSM5UD?Wp#!8s6H`JHWy1%TvX^A)tv^3N$@(ur+MvaA`H=Z5J;2Th1UR$=PwaV&b z8(vnssH(YU6(_i_EvJGX(3@pRZNnneSyR{8+EiKA*wXa<0zWJ(94*cX!SE0N%FP9b zK;amcXezH?jE*BLMKh0-BXCT>Bwl_x_r1IsVGimlWmMqtP`b~Isc^Yi+#Eb6F(QWV z4?E&n)U3p?S5-Avw&)4)JLaJmLkKy%8|O)ztg_0w%BCfi^%X~2d(YZGF}ZN}gq&9r zJRcSo6pc;{hABlQA`c8n95Qj<%n>{@j>}(!u2obgnktvqG$T$!qG7$p`KbKn#{9*FW5}s(C`Z(XMK$BA%bOO1QQlNh zJs$d(?_Qbz77~Yxo$!?5Nw8T=j0;D@a{<#IO1u#`!@woR-@VIPeT|GjQidI7 zWl>p8IW`%d#appY|Nrbm(|$O>rRO`tPkaw=nzFKq^Y;D${AlK4!#2)usxU_BRBlI@Ij)kohn6 zkimN`+)Vv59~s_u@5o1Hzg<2u!KV}4=+gSBV{ydNCrIP+1f%$PWHb-F&ubO7{$;X^Eu&!xT5MBHuTV}{u$ zXnTz;vBCbnJ}}d?+-$}D6c;JhDAp?;t$3W`S&HW>UZ!}R;+={QD{fYNS@B)P4;1-; z$o|M2>cA|e`zVf9oTw;sokMQ9(kCnaT=8nfn-%X;t7gBSG-)2Q?XIc{fbX3{z;M3TQQ#>V2P=C0weO{3UN%-s$C zTBUDM9TknR*cA{-ShJve7eN(f5IAR+>|Rv7TcUf3A3e;-!jf6|YsiTk$Ey z7Zk40_Y2QcbT%|8iyj+onE7WtN;;oAJDBiF5m?Df} zME>`R&ns?G{IlXV#g7%gQ2d7??I&1o4@EIO13gIT;fh6yVuFPH@k&oolo(jx)AoY; z4pXGv1!=jD0Mh1y^n;4eD2iDL_^&HXQ#{Ijr0Dw~*}VRPA6Cpz%u%EP2lGcO7Aux0 z(wKw!wEHCv&AiqqJ zh8(0@6lu#r`e%wX(I9=L;x$C*p|uA2e#{P)I~V%6 zji`^q=(q0zr2R5TTCYRkDt}`K^3Fv%sPAFu*8`scRXKVd-x0U zxZa@X%iY>{=X{$A`WeFnUmxq`awpbc`<_Dk(!pc<_;$f>-{VN5dyN2DTA(kuPqS@Y zh=JY1x*BpNV8+4cb3gS_KkEz(m-S8_o+H8Y7hfOC1m#{v`(E&cfWDmnR)V23cgnY^ zplFQocKUALreXc1!cM+T>9^%?4gK`^8?#I8Yv@gM$yPi0wrvk2f3z+Ai`18H+g2i} zo3=f0di2>7w_2x%ZoK#X&`;Cvwes=~|NL#1`0Lvb^FCQryY^OeB=sN=&)|fg5N5{@ ze1{g{poELdwa7)t3%PQHlEk6N4L^oKb?!orGrQXYl!E_JBjuvuKVazKhV)Y?chwEa zP2z2#AwXktRteorc^b z`2Dni7j+|7Ia`tN_#HiRb?SXg)9)wp>n!q(4er-Sq)?uIKanfF0cb^xE=!ShNp)bu zm{(@?k6aUeQb@$L*o#W8by(E7kjii9@iV09_cIkGF(`b`(1mG-SMX?88H9A+J?2J7 zL>cKVmd=dAEQ$JN{C=WETB94Aj*di&QcMGk-%qqi!hbNF!5t_cE$U%%#qTFNGUajB zoJYSO`XeRJ#ScBhq;J^4E1|J}boXdIHgAk`HAlyJe*bv)8QnukHx?tgr;^cF9UEG# zWNPe8bUr#>$@CcCU_>V ztx?|Q#ookEba{r{@}Z)$nYY5P2%CrJ$@Cl0*6QeO(U;Ih`u#+2&(s3+`+;|XHjI8h z(L0rj#?EHD?(%jAa7XCF@w{6}f-))0L*<4Ylp-%s>;RW&8HkQ@C)EjuIjJMM}vC0`}|HGV(QS2Djq zTj}?+l)_t53n2u5l-P~z(VJ;Jg6a43Csy>9?rik?;gGUuj{IHv;rCkr^X|c zhu@DWpC0E!R1|(c=i!P&zaPFti^A{6WANtk)IMD!Se9?G5OQtoVXwgzn_Pt{EYY{4kP@2jQpJV zm89YK!@;57&v?@C`&lOP3*tPkqVW6Sp(K7ke0qt(?}x{T`2FzlCJMiwKcIy8{fuCj z;P;b@p=tN~iNfz^i%7iBxE4GV%tmU1bYLS1$;Lrw2HF&MS3@A%z8M_upaD^`{Ox(I z2(cV@+YTX=-wcL$U~n&#gBhm}9+&hL(lch#dJZG}et0g=&4gfT6n;MkLLx5bZutF> zptr~I93lAqm=Sd2SF``{`_VlDHL~Lf-GSd+`V*x^;rDX|Rc(dhDExj%P}L_a3cnvi zN8%CY!|!JTS|@%#OmIpeZFaZK(bb`(zu^Wh&JH8qKrXLlRJA+l6GEA0JG${J*dh4+ zP?&x{1KDc${qQnDzn@20HT-@|FQ&!+%JT60sS+@5j)M@qEg|@5j(9*N}KPBMz zLlxrpa~$i0-;ZIy@24vn@cS_g`2D1F?}XovVZiT)-vFZU`!Njo{cr-SDExj*E%f`D z3iWK2j4AwnNV8Ew!|#XmK%b`HPZWMXbHRvLAtwsI9}*n%IL0Olzn^lU;rGL{Itft) zzaMTK9!N@e|1b)_AD#(%@T?Ps-w!u#kI@_n`2Da}Q~yDL1XFmA-@ChjjzaN^cNn8uM zso{R?d{o&x7e8Tp2$}@{vIr-9>ci+$$0kB3WhJm$c0x`wRxi4f!>KEeZb`P?*AxqV zWjp79kq}eeKDCfJwhu3&$Ml(vdVbQU7gQYG=Na&i>cfvctE{9r8vqNmgHSGsf%ZbZ zLK*2Gx?F~zuxoyQgLFUp84k?e5eRiWTiARVoyRXR_OzTkA$B-27h=s@MBYA`M_@5k zHhv>a4hcAo4Be5_2z(KPZXx(q={uHiwDbR&7YKG+JX8Keo-47tG94x2D#Ua;vB;!z ziDQ&c9Ba~1;uMq41$0_?uMU%U0!8RLF-J}>K`A3NHz+jsTSBR#X&!-^Y-_)E6>zmM z2R-i+kiiBOn! zEA{hbb`*d%st(mP5tIt(xrshOckRBT}HH6{j4K#iK%l^BgiG`6T1 zjT$w^SYnGrqcKrT{GR7s&z?DhsCf0>|IK$+(z86!tlO`B$<)D^WW zz(FJh)hw?!8EEGSEL#a;<2;at$xNQN6a>UM%a$!#hzuhZ&UdUw*oj|l2HYKC+4zp` zhXSeGF8{p`zU+Iql#&B*_JHBe- zK{z_9rcRwS^_%{8z&H4}fSTFhwc}vG8E5gr1`@kL(?{!Pj0aC2sPzpEs}|ybT0O^p zfDlr?=Pg`}th+;LZe-}$>}DUkzXi|Z!3uoyglA4PBTZ{*L^E=8^WOy2eBIvz{CBaL zxi|o9@tTJD#`JGkfoZa+W^t{}r`g$mzc6w*=i5?SBEyw1b#pUwu=;@~ZLEdz8Wv#X zMDu?pAhoTqA|D-71*dWRc*9nG@I1bh>u72m&D@roP-s|QH)r9zg>`cs9lZ`KY341{ znR~7~$J!bjoNKY7Yt9<*+Z*agQ|EdWEpZ65q71|>vTHczB1&9RyBG~YIV{>cXynNK zGTpg!WIC7DW#%ob&kV0$lBrrUyACV8=4K|>FPl@>(6Fq&A+ysWyB=R>r3vl`c-xxI zZ|1FM=tjXayZ|qM&hkeT6vie;V^f0R1?4kx3kpZ%OwO57kQkn~$NoQ`4w~G5mD`Lv zf4dbYm$_Y&I{U`B_fB&5EX3_2xXoE#4V&EtxWkHLoLlT}|8w!sWzSQ1fMPiLZ~Qh% z{Hi==dmKT&(aJwTXuK?h&z8JUxLSC$@HFAs!YhPV32zqieIDz_k9NdA2}8cJ*>XmB zS9Bud`wNW^1$nCEBZP~DrwA_=UMb|;9O`*p_@R(1Dj8lXG+q+RlRR8FSy&@nCOk%X zhVTc%>x7RA&BihG(#jmmGaJXi1Ret@4;GFR8h;4k3ngDJyk2O$AjH2Q`E8-`gb<#@ zLjv`d3#SX`2#*(@BQzcm(*I1d@qQrF6btp_;Q51CChQ{Q>q&-J31p`G*US7M?1+O8CAog7-p9 zUn1N~*k0IQNP8_zH%vH6I8L}wxJJpGldrjuMplNe2|E-HeNH(Z2P0m z&ncd^ddS0lQ@CB>A4&d~kQ`vv+xX5%Uql($g9yESh}ecHe1veEaFWpY%}9R)W#BPH z=>384I^hjM<0m8jZpk>ESw0*-hIU?t9=`ddKEAvn+Up)*XUW}#e7nT>fkM9OpZxx2TSiaF_`M(vC=R%pE%ZaZF-w^VpH^Xfm z3NXp@Es&G~;?De79Iju9KN$8SU%yjdMi}W0^h zraXw_FLYtt2n1y7>kfV7lu#e*66%`@f0zeeuM!9CDY#yTE{vOtfY8sl2Qj~TWCeuY zS%}LncS{Fw=n%IlrKIg)?3m|6e8`8;*6ZN4Y}xgzME%edYcFo08|(KF z{Fuwj0p?afU-q01+e^&q2JdQ?i@-1C6Si(@I|~T)?aU{fjQa6B8@ezZpA71kH1KDM zyT>Q&H(dYq+;Hee>H-tSi5J*}Gn4zv@OC=qU5|uiLfO zsu}h1{mRRK1*32h4(Od7=!F@?H(5Dvfx{i8AAz)BDmGwZL?ZEy2#kIUd4mbg=6N)B z0%D?zkqWHEdc=UWSPCgxjqqT8`FaK=Vn4(riSlPA!NOKOTq<6sqqJKa?Nu_3{wKJr zD4j>(vqE%8$x-x^Zyz06dItRXraqa{x3L4q@nrUb~c0S z%^x3#SaKYBcpAr%YdVuhqEg^E=FtBGXavWR;a)C36p_A=$MoVj@-uPjRmk8t@+bpw zA@wwB367&J80`ex=5Z>yHel9hEtOy2`e`I3$MH;rp*t%O+JgS*z3_qK$SyOhmE<^* z*`K-vJ8&G0<=@D0bS1*PI7$G=(TNGOCk~FI6Z2Cf`her;#E|1y1bvRI#lySUA^nfa4ezegLa>fW*Sobrgq5 zEKTtt792;HxIA?^3#ydZCRNPD!zE^O9HS^B700N8<48YyeI#lOjw8i@9LIeaJ<%El zIg;8yd5UCm9M_}CrATc}2FGy`N;8h*ENZv@KBAa@YQLT}tI2T{jixSUy=#;6EVhy3 z$j%bSk&1IyVaH7+#G*$-0LSr{tSUH;*Fa2NhaEVM^s}I0tmf*lAk1UVxV{ja+0OUBn&Z6#+*vN4_)=Dl+jbY+DHH*trKcKkPdWjrI zUSh#dB%3mbWrx48Es|Mw-~jadfIirO31a$I;~-pW+&9a2&T=dnczzdhwITl8uHk6>~fk7c>9X|j>yNTtkLW;@Q7vXi-EIL2iHqFOMjWozVg z97py}dJgr1FxtjvrY3!1OUJ4;)7qKP3GQWpEs6+L*S@A7c67IJ#3w zWtuOF$Z>S(N2On6`QSLZ_|ax7og7DJJAHimCH5*fjxPP=^ua7297lEzIgTVBlH+JU zyMt|W9#`Zz@=!94<4jfv97i4_#&JB50pK{2-((!e7pM{($64sIpwmmS^y$G+*?P+9;R<{x+jnv$7`*sGt-@z9vnw^z%59>$MV2&bn@~v`D)}iI(bd{U6u!q<3yCt zGrIc)2{?{NSO7SVtEmATN7f+dbh)4AjR851RAC&)F)R}tM;8E&;~kvb;5fPfa2%gy z3UC}<0631t3;@T`1%Tt&jr9P>(Un4ucGfe|7yac3!vB7;-(l-9x+E zJ(jR>>!a;_wku%V-fO(bhG_C;$XM#^SD@D1B9HB{aJ|REbt5gYxnXNeS+WnwN%V{S z3rFNr>Yl|#?6E5@;@-`)sV24c@H7*BOh!fuh>YBgf%Ac*hS3I8%M!27Mt%KLYQvhtD_s~ndOAU zMtbHsA%7z)#>YeyM_?V18T(y0SC=V-CD?rL+XQNGHmT`5%Oa)_oUU)fw+qL&Hn5aS zU_ZgWHQ`kAP9cP9r&<-AF5a?-j<0@^O*?iWx-S=^tL01r`vrv%_QMu<_3Jj$!)`)2 zVKlZF{uK_>)b#R92y@5;7G|cY*?DXQ!U?mm#Vtp_HjRBrgwGsK ze!d@IZ!R2bRx{gFGi8o#jyL)I=#=xL;aC@gqE2(tZr=_zkvrPZcSYJv^SBk3(CyoG zw3JM>H@23|Q!?)FQD|b^Kx`eG$2Y9VVVMHyVsEnN!Wz=gc@WBB)3aNJXy+ocuk$4YJ^?%5karpM| z{|!&|aoo-&OF&c&(%`BFYiJ2Lw@=IuR`r3s-5@u^&{ecOoaLvtI9M|_LzBh%8Kbkp z0&rh*X8KWJOkNOW0HfH8z%WAXFoH5Wv!L7liCb@@%`D;NS6~u~=EGH-dU~ zfNkX<`1fiwYaFcy7YF0|WHMh)p#3U@+0QUw|Myr1Zcc$U+T_l}SL0KGqxJP|0q%SP(iQc!b5yrW) zd!#h(CdoC+@@tkw-`%2eH=Tqq=^Kng+Gsa;3AlVq#VB<=KqGour9cm?nYVH&n08BM zo3-JPc?yy@%xqVHM@RyxS*C_{T5$Q6%_gaP@iKB+YZ~S*ge~@kLuQ4^NW0w`>%3bLk)%Sbi&5xJ&pl6uYG}`W4zH=o6h=K_Ip<@ zp1W|>l4WzVQ<&cwn8$hVNMxto-VMO7W4D(Nm*jB`7xIyk@+2W2B`MDq&KIr}t`(jl zJX836;pM{Xgj!`qgx?X``55Vrm3)Hmbm7^;i-ea7e=NL8 zc!Tg3;a$RC2_F>xM);cWP2s!34}^C9M!i0jyfg2$l;>Tk#Cvk{=NMRY=2U z)c2{7uYD=E5S9q}RgB^MXEd==XzMf}kCQw}c(CwLAsJK5S0}`2_X~N>e^$ShGF?H_ z@$+BjE$fDB4{sSg>KwY*TsQ1-`M|xfa|4ATgy|{}KtIQhj_J-ZpWE@=N7oA*PR(8= zHo7f%Z(a!GClsdP#`3DMg}UMO?!(4)1ECA!Mj#+t--FP13g!~^u`Z!Lo;$-l@OmfW zBwUYq9l9`XE&@V7(1mf! z5Rk3!ICOm2FKl+GZv*^c9_lz1`j{?sVcZD_$kumGmOfmf8ueWQf0&0lz6X6=e-*kg z?g9j4>$@EKI8JPD3v6NiHo?z471-!bEc3hv!bt&{aonyKhUv!Q;>YKP(1q#lL;(Gv zyASC`g#wV}((xH0yM9+^wHKdA8|(KF{1~R?0CNd&QnKfCSQas>8@!=NSBbzh!tsb@ z`q=L*Gi!QyM`QjCMOf%Ueaw@cZVT%7`!EqOOxO655kFenEjy_F2ln4x-ts0MeE3l4 z+S}c0g*%VlZ~k*6c+1JNs*eM2dC<0a^>3=ZjMrhm1<~rf>U($GJMx$XiNW{pxPRoG z@A>(e>Q>e7J&}0(p+q}yl?%6R`N+$Vt$c!?3%2r>k0P1!ySIE4tzZZl%P0Ev)m|rK zEa!o-TUhgCzZ&#G{bHGt@r)je^s!zg^XUI0cCm_5(vyM< zku5f)ZL0xQUDGxJnX2!G7nb_rYZ1pj7L^<#|emnXvgU0wzN*E6FXV@JMUmnww!yNx{lGMgj6ubE5 z_$CB{n3Vb#Y8k&K))S$y%jgAM4H>^SVAkMURDONy?MO-vv)u^!iS7t(L4R-ue94y9 zZ-w_GQF*d&q7(F`xRf*5uY`V-QB*zxYi+J+NfF1n_3a&Y1?grzRSF1c^gDezLo)VH5R5U5ej zK1eeOZ?SBo?NAN^zLP($u5Od!WSf6xXdLDgiQq7oBXz=0 zj!m>d8L29aYI0mI{p@v`^-GRVQZx>81EVKe!;HgxALS{M$zi?>&FF>H)?{#)=cBZ9 z{N&+@HPmkXeMB++)cytc+3na_;xJQj?pfGzQwg9{ zLI8*P6I3;kT$vzYJ+%qD(hga0nE%M4?vUs>%*kIA*%9BVFm(tM->JOiscR^1wO%5J z`FM)=w|x%Pi-5yCi$n83+gO}p=hPdl^~0&XP3)dp%7PwAR+-qV2u2CKDRjITW8NI?P1JVNO0HRijcg6PSEXdB>;t+>v}fmvpvB zr^%^{8T(@Kq3ASnm|FmoFXx|Yu`^R^*rHbpcm$Kfd?yQfO_PlrW{x$pmf4Q8rEDX2 z49B?CA*uzVT7C;TyGN6=A_?|Rnh%LdaG046Bbq*rodFKBE#ifp)(aUA4zrUJ>Fq2S z9A+oyr^$p*g2U|c7p7Tg5*+3aaYZDD`NvET4zr7|Nb@C35*%j7F&>y+$@0KqcJV{f zf29l#Ga16Ia9}r5}~%PbZS#FuVBCY0@f_;4pW#{NvMqib4j5 z*`=SHW=AB!VP-waVSa(};4s@u4se)xTqVI_=AmR9X1-NRg2T*X#5l}cex3w}c@Ro4 z4)b1Y5;)9jFzNw0%x6#sILsp~h1qH4q2LCIGbU@0Ol0LSNY|lGvFJ-kPznQfAh|$c zR#FCq<4J>*P9LXjQzGQAK!Bb7IScJz#_6L91uP0>oYYB;PlChzAR1F1pv3$n?6lsF z6lpt`fWu6IGh!%v40c*sNm}k*!1jZ~tQmn4+3;AD>dOZ~Zvl+pCitVc^l#WR;4o95 zs#};99A+oyr2j$H;4s&iYH*n8DMn&dyVbTN?6e+?sg&kVw7@Mb=hcj=I#NC{QtZYt znyz7kz+q-$a+vSu7=XiU56R##pUk4cVRo$;o&GKJXK|Q$Gn52}d8@U0X1X=ggTw3& zxCLn%<4uCY?BwO?u1pUOvy<1P-(z{;FwaBz#$g`D1mG~QvH)X3DIT$>1J&^B zILsUz9!Qe+dN&C>tsf$wHP1RpaF{u`t)F5Y!C_{pu6$CJEfYA*e?U@jm>DFlGS6F> zV8sZDMR}mN@p*C=F2h!O8P?U$9LEe^+m8^G3l8(KNCgh_zY!NHh?HCl zZ1Ho1#iJ;JtmfMh62B5vCZYLp2(c*RV^K1dJNSP?h(DTF0IbU64$i+E&!ioXMbZA4 zqPLNZH#G}(bY~BP*w+8ZTY>v=8vBk4U zSH@X|%?QnttiJp-!L?tV_JvM=YKupZ>{`ftHPmGm!gx3OC>}sNwWaQ}ZN=Inh?O!tR^oMi3a!`+o`AcK*!H+Xo2g1WyMFuV)F}2lMf? ztMvu7P(xR0nUl}|hjqIdyCKLl2wRVPAWVga=W16nlLp-F%{+7S_^&W4c|MZx1(TJ0 zJUskbVkL)yD|zo@nQ;ax(KF<3_p%pamj-Qoc2DpaRQ5g!O^shW$5Wd@KQXSX7B8;%f>+|P0z`SaRK#lAA>hLpjDHWtgInbJ-C>ls zbOuWE_Jx5}Joa?PYxH4x0S?<(3wRlpQ-UNz(crk!#$4J&+Rw{_O;%*3P1aVWJpPlew9N08@5)A>Qdi5yl&CuElvdf+5|&-wSejC_Qe`FXrM60Jot+=&CzeRP zZ81&-&P?r?k^}SEY3-tD$IkX^+jmF0HW;;xdC=+(yRv9|k+W#qaTgYCJEp`h+)ey+r}tZgK8*3cP3Vs;@Q(I34uOZS!D7%4QaZh(uz~wb7>&(H>FlqAT{wX~ z7PlNArH9=|Qu-`Ja3d+56?WC+cQA7SG_!s<*O_CjvWeT2J7NpT-SqEm^7Qkg)6S2w z+N^OHPd~dnl*1ykbt2k1(7;E)$LfNOAJ#gH<&93W`Na8y6iw4;hEu>jFSDz#VR}%c zi&~3WjWX}=Ud6HAKL-D!qV+#|9QcnOUE%dMS}N=Ue=qE_+xOWRl-m@@q^w1b_qTkU zahjap8GcvI#<~R-klkBh`oL#W#`s=i@-`47mLh6>@&wPHDZnSnI94Fy(|`# zlj6RD#P+B~QLZaQC_y-jfD^7r%5_ zZy2CmIA=xg+QkcN8x}5|PqI8%cKc>{^Ivv<(l`5C zF72YTAKW=~e%%TjLv=LJ?frL|mj2&wRQmr1Gqt2MLY=dG>rd4IOzKO)Pr5 z^UdPfe}-m{^IWs5ls6aI$+KSz{5m}Q0mx6j=zhZCLOvcde1h;W;cOwF2^qgq$a+vd zMR=z0d&294TZH!sw+UYmz9sytkWXUN8}jVU+!^Hd3O7C`^`4JjWbJXv_L@G9Yb!ruyC7XD4x7B8`>r?>C`;RNB~!X?6E zgl7sb6aG|qm+&#+ABFDm<|s4)b3k{Go7@@LJ&=LbD@{^uL#Eyn4txC}XTY6$ZFSkxy^-q7h#%xs9*`5#hZg zR|xk}c%|e~!Z8Xr`_a%lQ{l#|hitrh;CB_iPI!{?oh|u%;Uz@W*X&LMH!Ix@ioZqp zbA{h0nRam5uHO=o?-}9q!nYOwSK&W}p9o{P_%nY}SWbkVw!#j=ev02mI7~P~IG%`n zQ-m{wb&6jotQW2lt`m~W%6gndgq|yi7>`?ozZ14V7{g}@zb(Y+-tyrzVu<91yiQUd zU!M}~-5#*BE%=75-89itsJrcHuvTp9o=h)$-eQ5PC9_I}43Mhw#3V$%SBf z`w8v(2)Rn~B;hn6ztuAR(ZUmjCkxLK+I1A^zAxD*5Rl24Wd3lS!mX0Sbqe=N{ILKjB##kJ5PnN|xNxCxiSSh6nZgT% zwtfzJ`GK0{UoRvTi83v}5&3@6eRH3Hf=MGT%)TM-p)@ z;g@F0;ra!BQl`8}$PdYs*9&nO`@(e$d8$__(-kxwXJ2z21MXM%*k4DNn!}Ve*A07I zp7|Er+(2OnVY&(g(9f}>W4e>f=XN|t()GfIQ?6Hujc!2)$HQ+4KhtnydDYlL-S8Su zy$Cr`66)h;oG=f(UR%r?vV}qy#?3`Q=x5x!IGJA%Ha;tE z7W~=e4#7!%CepE7hKJ?yT%E1&Buv^2!a^6u@!X!R@0^}Z{esJ8qrMIBhk2-D6ZD~q zjV_Ek0U_D?F3-}(ZVc;p3H)ImD!B#vDtFP|3lNvB?*{1OII+Ea3Jvvbf}i?0ALu?v z<0}Qu0ik0Yx9f#rx{uoJ-a3XA?cEpAP#?>s+k!2-ep|BIi%<8B^?L|@G;cY;+!p8? z7z)6!FNj&w!}|-;RU#10`NDM!y*l8zXBYZ*UdQkt>i7Fyqzm7D@jsNiw~nD=U`2-R z%k8gcP$pcnbqp1^_I@XF`k9G8zSHN>6K}|v{qcG^3UwI%QPN6y=R z<&oXC$JegfzWK=c+pk(Xczf5iUAN~PxqAD_YyF|Cws$*}*4STp!h1VbScDZ0W!tvB z>%fB%)+uR1gZ*>`eJ$}z|hlPSfwpR?CLx6fbeby~mus@z+*-;?{^_QH?zpTBi` zrTK2$e$Q#~r%rgsJ1w~3uD?W1uehsZ)<>`V=W%_6f9c;|XQS-jDD-$ypU=nn-^I*$ z78ey9m(3iOJ=p(y{KQR&#Zrf#BO#VLkeQ9;4G%&J?m-N!v(H3EES6Z#bcxtim^N5Q zF&WCWr~z@jg$sU%9qh2%?OY;CLTo_u@36OiDPm&L%dyY-F|_!>W|RVZ>s1H|u4Hh% z`Q!X$1nsS_K$zKEe+Qmq1B!&b^WtO9yR~MX1`aLz4b1rSn7QQ!ruB4 z00@Ywe_{&5-ufdZVy!|Um0TMzYj7l$U*GyH__ z?XB~#>#09MDeSG&k21JcA<Lu(uu-K8!6GDltEG z1R4)}>nhyYydEa8G_{p^50qGL3j|dw5wC1R}tPk9MHF*b20YgLO;g}rt9 z+3Odx55^}clG&Q#`gqt|XTu;zQZG@SBAIIy4nWLrklLDzwF)<)G_$u}juyE7KBAa@ zYJUL$4%IZp9Av z*6C+KmoRR1SP+JXv#yZKO=xeOwye2UA#q!=GRWS#DkgjDPD-R^vzk9o4hGQP`nxRZ z4vCHS*2ztbV66fPDzLZi@|LG=rnuF5iE9;3qj-PYwWwYMYZb2H&^*wVM;6yAL~*f! zz4eDp?4BZ95%$(!GtsS8NIX{L3UX@|5|66^jrP`ExkFQ}sp`q1w=HjF>N;TJsiGYw zHriWvsz#;0%|U-obsnGkF=yuUxmQ|yC#SZvk}nq1C_C3G9LdBl=l4S*+FL)KEqb+p zM=;kaJj;S!(`4gX1y+bz%WTKlQg$GB49B>{psfX?TJlYiv$xLPNiU>ctW|Ig^3vzB zGq6_Sa5Rj}^dB-FYZaWFNawP_SgYXV{PZ)NYFMk_@)xFQ=!5pwFT$0UYZdNhMX^@F z#aEnwg?dIQVDS_KzBB>f>}tX24>#ScwC%JQ*R!JSGf)78|EwF)l%s5GzC zw72f!N2h;58EX~H&_bv2W@(xB)?NC^>1)`nSgXL!;aY_QC}XX{cdWdbX&zU!x6VV! z)+*FeA=WDJ7_qeqqZxp;3Qr@4tyLJrCSk1t4V~Lsg;%HpYZYF$6t-4@hk_fVjYyp} zNG7s!7^Ly2Q!IKM5|sKkA%qh&D=CA*@x0a&F(0RGQzGQwh5$SJa~9gcjME2?ORjIw z88dz+yAf*@_@1@A6%v}g^+S*%ZRc*RRiJ=lJbfyA2x}Ew4@T2RvHe)9pc#P@*>D)b z#=e|ONzC5*kEn`^f@p7@0#)75tXQkyKS3&2{1*LiSZt%3`{T7^F`1=cFK z0IXHuk_y^ecL7+dFoSasYZY86T&qw8^{kckDb^}bW~EHVS_R5oLpij!J_P~JhCS9Q zP+*_a{(k~%6>3e!S_PifDVQp(Rp8+8K$7h2t@BLKnr9u_Tj$`m-iJMbwF)fNm49WJ z32PNTLQxNMP6@GE-+WR^2+`vZ_>UHcd^AKN~IY{#^3i{PW%KY{S?w*MK1 zcC8nG13?k6q`rlGai7ZDMv4j{w749*Sk&!*3V%occtrc_+`@(jSp=NFArEAKe!cLI zE8Bu(Ec@HoI?>{ge|+(G;pfY?4;XeWHJng(6VmZO<;%3rC$KM0vUF!a<_D%O4J(&; z{`wLY-WT<3kF5(#75W=2=w^uD$JUi)^97stAv`?ty5EB| zHzNQG3tFRMkxhGb@Yz=Z1NVmR$mYFLEU)KJpgD5oUM*NjuNQ2$V_3K)m-+=Bc-CDC zO7en&)&(*JeAWb2nlROcFW*QHpVpv>u)xBXM>o>5#tDgy^qk~`{EfiRxN8ss5)&M~ zy)Bu_n?V?5-syzV*aB~bZ+&nu1m*yLp5EEm&{c$a*o;5F0G?GYoWM?rc@18_K8^iD z_B{KE8`<*!b2#5Mx`=!&fjQm}qZH}q&_%p+#)U%&{{#*t2M+#;MAjJoNkk4D(-YZi z^xp<#N6`-mUE}l#1Avjeu-ls+ltXmoH(;TZI1*qIH$WB;sQ8FE`|+hvCGdU3ipuocYh0M09<%JOOX$FqHJ3hm9=*ou2SBY@9!CT5NF< zcL3O8q}kOBv6x0hs7fWfhC;Zvz zAU2cv9KFYy{QsaedA=B!jjVe38(H-@=Y*_!1dCPA(|oLv zReypH!o0I44+HJskvrS*LGI94Nw6jp^Lv5F4&(8$oQbmhPIh`}zkcAFujvCb@jVe$ zQ4(tbEAqSY!%F;j{GbID$fmrJ^;_)|Ag0}}CX-jKTJSQlci3W^~rH01hIsJ^x?+5=L$E=9l zFc2}QLOjPU0Pus4#`#p!BKUMbrcVTxTKq=V>aIBU!>3NDnJ|3%=$eVcCytp|?d^hd zzx#B1N3w5JIc>(skyX>C(VF*vm39ABDfTR9CFr&_+1z><4X+i2)ohK^H2A_L%U9Od z)hu68?={tT%%N2^6UIzKe~cXMXx-n475l8O3aDB2nDJErt$SF$tYP6AuLcI)8|qeg z%cs^gtXvGHf8CP0`uTNB=N#o7G;u~|WWT|gef#w9(=XG%qTjy#D*Eq}>0V#AxUROL zu1DrD)Ssl?-uw2RjRgX87G&z{RxNA*`90Hr@Zf#+-S_ZJ?NyC*5NQDfaNg3|`uPnWmu1z>&A3Y2#a%<#Y#GBId-she<}c*o^CozBLH zda&U`&ywfWVjy z*)rZbX1Tz_Yltit*dOhi0=^0R_hnGWM<D5L*!u*@c*LJROD)P&}U>DGwKp7ETZzCY&u?C|oV% zvm*1KCOlhsh43mNzx6SlJ^KRrZJqL;gvKR=+|qa9U4{LHX6F#`QzaiETqHb2NHZ|h zd!_I>;p;- zMSW$$E<%0|V0e{qhLB(N8NO1uUU;E!v+!2o{leb~Ulaaa7{dg&@`YW5{C>yqgM>4M z#sNWiK0YcizLl_>aIo+o;ap+8@C4y`!n=fz3jZK{NBA#cD&fj&E9@;iKsZ5oxNxa( zo$wst6~dc@TZK;vUlaDjG0*l57alD%oAn64O7i={NUlp?BHT;ZUf5sAH__BPOgKt7 zPPkCGOt@0`UE%SOtEbsp;l{~_+(qHW#fQAF{5enIM+zH+tA$4sk^W>N z>T#veY~Dk@Lo!ZxmJWxPp`EvpuTXNi&|Y#OytCx)!V2L);ZR|vaI|o|(BAJs&kD)> zw8VO@6P_YGLwKRk)=DAWk0f6y{HgFpAz#o@AGu7#`-Kk)e=B@i_($O@!cT;}C^ElY z2Y_S%Q7#j<5@v)U*PNfkm~Mn{jF7fp8GeZHFyU{#G zDt*W)|E1)6g*$V}pH=t^!q1im7fU&$H% zSK<4@9l}qAabDMuE>Bn@Obgo!I|+LV`wH#)iu|@_4ahH@)MsnffU_je6)qLl3rU<{ z`eTGA2~QF7V=3c*B&69*%0Cm{CZvU6hT}4YkJnAdJ46c)&j*MydFS&&sls6q?8^SK?z zo{nRP%e7aDjjlA~^tXhcX}GbxYHXoyc#SHs71x*0g>fSgkgcyx2A?-E2dR&B3H42d zKgA1{{B(3*+V@AoMe?3iIpXu<==Ov*6Dz_cvV-fWlZV!^3hL;Lq0A0?#uU zgoQ4QTZVvU`g*wIhx*v;P~Qgl!#wbMeW7m%J#t~(36Qh(y#Rfa5k`G@L~7J`3H)Im zc)j`1*MAr7y#R69`g-l%G;ZjkMtz&$r#{XHy6>UD4!C~|9pkuNFAUS&0S?OAFp=Vz z?oRo`sDbU=$J0<|ztC;LmR-Mrs9zz%*j_ZLv3?K1kLE20m|FvV*>jp@(h;+!hj$&) zRU(iadOnY{T0t^dmb~P3-#^Hp&y0%eIAE?`Lfk@_53R-SoHn&88WEfkimoS z(mGR-p>z9w6%~U94a#Kt_3Jmtg?u@O{#jSCMh<;BTGRW@cPFjC;q*l0yx{!$Z9jzN ze($}){Pxw~elt3A{f^kRlis>?pHp@uPOW-+(azUiI%?KdNHC%tv; zek0#Hb>!H$EU>~-&MTcc_N74?t7K;_?s69@TuJ3H|1Z$xm!PvBEKdG~o3e(>)302h$(8<|i( zg%FMHg_yt=Wlw4~*Mj1=G3Z51lF0mWd!>+wjii)_(_(ECAD_3m!5^5oS4kE9yx$Be zN@o%lU@`_nN*2KnUf3JRAAEpav}3D>5d?B2_Brn%vmdm>c`w$hfE5bPW@Nqj<4+?t z2R!{V5SEC>t_<3u_+$%ciCvw)9f8S#ND=!<3Bw&Tvp0NsOi!ME?8nI&kW;+9jctyv z2Y`H+x&}3iT@y3LS|{-IucN|i17^i9rs2Q7H5)>n{z`BvX-#e&Rd_RfN)B_avmzYRB z$HYS==BIwg1|1-=Fg1}i9VW3fbsh5_D6u@n`_Fi##5SqhnRmFvMxK6rY~nAh)lXuG z9hXZ#d;K+P9-pKbkf)!(pvNa#!yrdeq%+5-NG4Bz37Y%~Qd^V3(+{BF96x?|Vl;|% z{e46+{nUOI62@zCTo*)B7qi~A$%z*0c>3|#?buo3=~Hp;5s2od5@J!_Z-S>k3pG!~ zS0>Jbn3{rJd{q(sEU1XpTpbpK;i*7Th2+jIh~JvXLr(Ja6b zq(q9>_;?df{|pw@oTnfEMbSJfxiB?`iSJb2^3)F~Zna(_PrrfU{cW#7^&;Tue?nCc zwEdllom0oK)(@vXHnDq(T-W#`$ueB#BApyhKmM2sayBqOJ+@YxpsOrfg z()A;qDpP#*6Mw3xr-_cIAAd%wMy2>O#`tr}J3htdy!i9EPou8~RcI>)G z*m%lJw zk3!?%>Hiv6R`T?RFgcebG{+Lp8m0>Z*saPFbYVLbiqEE7C^7XY6A z_ZR@4z6$_PpO5%)@bp~(c=~+D5eHA-1%Rjj8>RqH-<3k1{z|B4t*lSM)2GZznGBvj z<%2_+JpDNSDR4Xj(h zzbA=BKSpdW=U_*ORsrzoKV%n!r_VDVc>4RZVDR)SOvFD0UPnCc$I>XW-4X;k!adf5 z1D8aer6ggyZ zHv-opBo@60L9yufvG3qNK|OUj(1QbAO8^za0Xn4`@|_&E?@mz;2k3tzsGo*!EH zWWp8;2e+IazPb;*<%x~-JmrM^jbSabEOR4Dj(3V6nG=}Kamkx<@Ud$r_ZDO@g9%Ir z?)c=U^t@>`hqDKgu@kTn-DXD_qxe=Vi%ec@38xWGG4Bxso zUOBzDSj-dx?~elSJL`<){+J6VutS&wymETqz(!s<(fKQ^n|Oi*L!IEp_1x+3n!`Dw z(Ww=Ja)f8wRi|8mEysgl_CwB(j)s4{$urK6&OARl3;yLMBOWq`{J1Rn6!_W7FhBj* zWyx&kud`&f@1-m`Y*d*41H`d4*>!|yP6HE)z**SlVuPK10xK8sj$T9LJcR$~a6ZDn z_;Q3@iOu(>6YjtkLFR)6^y}2=Zvl!X*?#@`>pW%7q2x#JYV_?MdhOd$54Syrg8|T!J=Z#?Tym6)= zgJzek?>BJk^Es?k}*Q7i-rumh2O2*C`WAOp3K@ zMgvcRC*3ZSiIorR8EZ!(_F6Ks!4Gejk`vLxPg7wjY#?j-Z+ zt;v1X270MiifBF)@^OS*>d)L{f<4Wf!N&QGbUE0_zhQ02hi03J#+L@Rq6|_&7a|h% zQv3kne!}6xYTBne_Gg8xQ}p@aGG$o z@H@iegl7vk3V$lRQ}`R<3qpP=V7bNv1MY=ee#$+BLxg676yYl*pD6sEkUx%PzCQ~8 zCCtb4VYnH(0PZcBKSF2tXyHl1^My1$#Q1xJe4$VIMd3TbPlSVT7%{#|I73(`Tq#^H zyimAVc&qS!;qQd63I8rM-ZaW7!-Qvf#+wH2Be_aALpV>kT6l`^d%~eO+^J`b&aiH&!o9XG5GK4SDuvefheIXfI-boh5e{RtN_Q4;3CEtP?I2 z)(ck&*9lJ)o+0F0B$mt1@x<>7Hwmv6UN5{^c&G3l;X}elg-;8g6WaL}`rnuQvGCu* z1kaO*&lh$Ob`kaxRtSd(hYIwZh|t>xE|sL;mvjBwr@nB)nR9v+#D| z&iv&^6#lr-&ikl`t)l_%%wK*_>HaSKm(b_=8tD_le4(wcLHHoa)xxnt`zp_zkzbdL+&Oy z^ERtQ( zr}>@Je>(fOHTnZxWA}f6X1qqq7;bYNuxC1Sw>h4tvK`~-x?#hmB6t++|Wu71Se~8e9ag_+b>DnXGCECG{`N8{FfW7u+y(VJ|^T6w^z=@h`3qluq zXCol=Gp+%1hWAdP3*&fx&MtR!C(k<$=~ynyV>^i7!4~F$*Lxi|*cp1{!nh@nv-LgL z)p16t50|V)eJ8;m=7HCXKR&sH`hEmI_3^q!w;vK*%7avnaom0?4AVV@3At8j2w}QAnwvGPwft;cTmNU4BeM=dN1i=rR~h=9bWU+ zxryG}POAQOHU8z>?S+4OlLuDsUw!|M`$xX;&*io zwi`aefw}M29VgCD!XK&dd(hwJ?i)UeR?v6vo8Ek|Xpg7f*IwuSmFv@}e;pc}e=nr# zc$Dtsz@Z(CIRpA9nKuC$w9&!kBasSx+Or^mPdgR~f|Ur0PAET|G11tM5EER09MMUw zIKZ%5J(T%tnSXxyi401_?!+(zx!6S)w&Lsuw{|Ql)5NVEi@<>An^>k~F#U6&B-X2B z3jOb37po|pOaH~Fer!m|YWlaLjM&i9)8GfkV-ahz8oQj1t$0TSq7?MytcD^#Xh6;5 zy$V?A;9BhB_2!S8WnFM?Hz6z$jb9l|K%V3&sA>G_{C4!;361felrY?}t`3JUkLk&| zjsG~wyC4{;L8{I1%Mc7AO^Qcz{F+!#go07!1%0XH+JISub&R{d^>!pB=XNvG_z7Nn zThJf81YfeHb!Op{NK~Heo9KjAr?@;R*{_6tltIpIvcF1^NH6Dd|KIlCP@OPpIO z&OHk|ZYm)by#N9@w|_=e6UmhcQh-uizmi;4L_Z7SV{meHSP+JX=j+0ysOy5{t%?1S zlbqY+ZNZtSQhciDFcTf;Hu;QHjY{psL4Qtp$EVKa z%zQqV$0Iqn1{?$P9|NP@kS<^y69oLe0(=_}b8;N03mZZIr=%y@8aot#M1 zC^zJGPR>tn;Zy_X*5xluUx7lC;M{(QD<3(xXEHrFw=TXS-HkFhwHGIx{~_AxpnDBrTO5H1n1Vpk52Q2RT7-r&X#|C zns<3gaBf}t$!QW~li=L4bI7^f!ScYleZuNHGtJ{F3C=AKCF9(#qC#+Pd5jq6_HYJ( zb2|tn80R+1CV_Li2BU7ATP^`ef^$2IH`XZx{~1BK8VJYzk|x+Y4E7i}x2^}HX`UmJ;M{6PphPx27Nz=fKA#uB@OXkRjnlWWXTZ6o zKvmB%D>%1K&Po4?s=>J(i{_hcY2bqCynbStI@=hn%~(_NV!oLeWaNf)vy;M~qb`8=bihcN*-x2r4woZF2|0nROJ zV4T|vnF5?!sxZziU&bcExpe{H+Flvyd0!MUZpA(Y9vO@ecKBLdPr5R(MwmI8;5GcyU!?XOG* z=ay%63Z@F2TMiBnB*}Zdn*`_fLj<(uStkk3EeE&t`>Z24w=C6_PYSJN0_XMtBn9V| zL2Z1V25fd?f|0@=i}FBktBfY%z*#_dWt0=QbCd+iReuJ(oGH%e;YBdKuQ$&)EBauWfroHMjkC$f1*S_-~@dj^{` zcfF_u3uNLmv6;E+#a3S~nSxmUbp-)C7C>G>ebvHcyC!CN18E+#f@l?fRS>Eebdm8m*)bQyCT&r zzMtG&=N{8R$ZHsD_q>>S`79o^rK^TnO7JzVN9;!5EEXA10%O#%;Mt@6Xb@{3yj0-Fg3^{{lg#oo5?}Bgnx1YGTnf5# zP{s^>!>H$#=MTy=z#@{t>9De$OB!`h*at<=L&l(8wvp|S9NjktliX|lYzy085S12N z`T*pj5$7aB+4C9}uBAoP#kDYqYP8J({XyHT`P$s+U0AaHDs<}a^xKEk*lij$8rN?S zbHJqZ+<`;LIHYB2yizp=s_mK)H*0De=B!w_q|W*XR8wc>di7lP!XA^?D`1YhA=7)_ z*Pv5>6_Ti(em<9fO>@FVCa$lmom+#Mv8I2`!di^e{}p0(60sf6qw5Q<5*Uimae;!Y}aoCJBe$+Q^!uqr9 z?8WtU^J`YRBfiYuuj+@ zTqE2dJYD!b;Z?%xgj_PZTVd=4*&%OA~0^HK5tj1TIkg#llU(n}rVvNhYD57Q)`bp~7*(Lxl^4 zYlOE5$w8o=KMCIzekv@$vkT+f3h`RVgchKjk3bQ9?5!1NmafR|)SEnk5*-zbyH0!mrD+w_J zUBbtNe-yqe^zo^I>5GM(gad_D!gGaJ2+fQU^1UfJp6m2X6NVh?2FWxl!gAIL&l6rE z{Go7@@LJ&=!jN12d&y>F8v1;^eIW-kCQK4hC*w{dzMbTbLgP>)yuai@!u^Q|A0wQu z@R`B|!o|Yx3fBowA|n6UlFt|ZfQb5CA>;Pv;o-14=Tqd;Z3(_4edA;yd;d#P~gx3nM7v3f$ z$B*USCwx$7*BOMrFZtg>nhIii+J7RZgk%CyE*EwXb`gdg^MR807ak}aEgUa2`#aEg zh-6zU1bLoh(qLF#y)fjYA1irh?)gs@PIeRXk?KVJmGDvF6T&|T|0H}z_@0m-^_ahf zkRS9YcNO*)_7n0`9^n1@kzMY)T~IdCv0U~;SnhY=5A(q5?T^n{8G7Wx zxFwLY^_|k)aek=}m&8VWC&3@)f!8|>`Z)JP7sefjfNXu2Wa;C%JFFkimth`wy+zQ+ zbrqot<9L3})^|1Zv7M|R4y#6eKZ2imDzMRQXbB@<;b22%9Jike!*na#?j9%mU8D>1 zK!ue{|-v_XvdCLLjGWgPyJy*l_60?Tgn~roD1fn@#$jM%T`Pb2@ zwtc9N&tX~J>fM9-kxLP}FkRNG=fR+4XBzD+4-73VS7hiK?JV~nI0#X2U(U&Xmj@pX z3)kN6I2We9(-X^Y>AKB(`@|ft%jADX_wW1hi62aQYd|O9`<-?K(>m{n?sLP4_nvSZ z?2C+pU9uyXk=%CCM?N^%^tZYDBJi>4E1R|a&gBQ?RJX1EGwc{Yfn&_|VbtduseD?Y zJq}0Z=&;qoNCl>2v`2a$$bp}ehxrot3G!?rq!5CSJ&7@qSRK*@Fr0`45#Bj~kG+sF z(bx*aL>3?i_}IKh2%>SasDec75NHSz@jj@4c-M#7Sb?m<7V>)>FIq<=6n zf`ffH{acx)qLlL`NJK}ll!@4ZYyC1~qHkcIGY%R2$aK^STx(V+ayEA0TGJn=QN9GY z)|Wsqt~H-klbuj4aIHz$Or8ae;94`>%VpK7;LBrrajlm?PQ3ydTQU>L`Q8#bT02wIv~i} zhO%Sm8gi|ABo zBd6n9vv<;S5KXSNYmnzSrr=s{wkA0H#^hQ%Ig$P~3kKKP$@%HCIMu+lcKHj_ESX&E z7n7`LX?iKsgKO>LE7CjIEO4!z{o#S>LF{~RtzG<(^bM53wI><%4U@&LP+O8ODQaZHvTV z-no|?9W+f z2Qy9|JT9k&GEV9>>_%{{+1=&8LgkEWy%8zWb}j+engWjTG#9dvYwdb4nx?r1a;-HZ zP$C;1i&A}g8T1<0`Yo!un1f&G7gM0BmCOpRwUcwwd^<<3^}(o}ajoh37>QMF$F&}Y zsbr>-$+hOyjH+H@R&cG|I7ZV|Y!JBCOiZrzJsd}Ht$CRs*LpOI2G`oP;{RjsO8~2= zuJ>o&yqEW~yb!YR!s>&BMIkW>I|8ysP>|iNk&qRF*~kKcqTq&0v7%MGslmNftJWWN zEADHp3tFwVT5DBm6+x-pw6*@f@7y!*O~Ru1bN&5uVe;K`?z!vSnK#RK&&-Hi#-@R5 zeXf*e{2P;NeS!lWT1bxMdOY(aE(ovhit>b!t~FcW(*V-t+wZ4G80N2_mz_osu z7T{VN1-RC|*bZ>5O)cbFpNHbvDj8F7ttqonB75hX<0%hHL!_6uo)YA=jEaxA)U*Be>SA)zrVs%>=IXPhbkJ zHC5`znCC4_FnTZ!_<5i!2b+C_hRZ4p6FZ4>a2!Nw0JzpXWXQE<3E)~^%!JRWo_?AJw4M=z}?Hp`C6a}=xZT~Lv0T@5R6t;Zt2 zFA>Cl*mUFP@q&Lq%w=B(|Tvn`~#`4VKZFo<=t4} zxiF?Hb>Ui{l*;zJ0r53#xmUy1t{1ZpAoH~a%nHfBX4X^;KHUI7R|H)qbvclElnr8w zc~5BbPZ}d9r@Vycje|3gFa{Q*unmbqn2!j*%4r>ZJtUfDlJ~7+aPp19(P+o-OP1p`$!jMa$xepQ_?`W<*h&ToKW3NwcK(3+8 zbqEz=&5w5cMyv;oKmx53`6r6aK0Wzv)>DRrw_(GJ#=#3Ae2fUa+6+FzBMhmBz+a1W z&YNK@jfFV;lZ(whBUwt~d6cdOq@;<6jHkeoTp^Dofv9;Wr`J2+i*vZ0d?*iXoHyF? z?R1hU6bN7ZT_=&rm{d;!@*~LOJO#e^gU~q~wnK$4{!~zy-4MV7e=2x5lOYVJFq=Xl z*C#mJf+-ZN{H^GobB$XLcb6&W8dHw3zD})+{y$%!OHN{X{@!Tkhjt{E7j&eZ7b-noCt6YG5_rTQ@MPvv%;%eU3UQ(8 zi9FB42Gb%I3~$@EW5jbghgx$9+(0E?+s?=kY#@vi@+EoUoFNzp$~0$`Jp;L#jbxF^C}(tp zq|77m2Td5|Zkv^9&Q>d<-0c7v-9EW`B6qbLj=*ektdB6$yXf)-g=6zpjL0+m_S%~A60p=u@Q69D zzM;MQGQ`b&F8chpo1UC(O(a?{F|0>J)V`}q06s;GjFF`6m0osVasPk zh5!C880Jn^kKvgv`~6I1zyFsBnHfC*2PHUH1Sw?(A_>k*ZQ$HHxYDu{VwCycf=y4F z{WU_F&&+TO`b#<8-kjlJ!q+$CHMca?RJ7!k)z*|X z*T4}p=<%)fSVYiJpVu7sKweqaQs$LAQ|N^a4SR67LDXJdS+?4Ow`_Iq+Vp zd+CDX7EUP~Wqsbx$V=zXna`ylAdSm>T2-+Ot!gO8l8B1hhGr}iDQ&K-sjR85!8!}9 z>Y+pXrDb(>WwP7^G0$2HOiHV?yo{Nu;rzL_26Xh&I;_Y*A&X|gjkZf+uPbd{S%Z$R zs%UCys4GXgWi8B9Q_K1ei1~gXD-L)D-@h|+@B2#AlGssJ2gZGuWAkNLX(Ky{69!Xc zWlM+UMitA-nlNr$1z?sGEv;(7u~EgPMb^}DC5xJ|cA;c>Lw#9&OF?1D(wdf%sk0Z% zTu?gFV9B%vb4%tnH7v)W)m(DK)Tvf!StTY)X)~)SU0U1938IUmV(TDEn@s|a)s}{n zN^8qx-j%mBtg3LQ7Mfeec30PzHDS>cmr7MtMzy(Ib%jM&`}9}7Vl)qp>iU+|ja4`< zWc5^KLu)w;Y^bhgV!gDlwZ65vs#2CCS*2Kv&{$PbQ(Xg%sU9=Cx&Z}o-4)hrVVPY; z89> z7eyB~G}Jans~ei4lbh0a zl9B>B=>>on-zbqxR9^rpf6KwP+X^Y zzT%CFcPT!u_f&gY*jo{@nXem6mL^}RPjZ{w-i5AOvZaG z*55}lPjR*4If@S{(t8o@-&H&e&xa@B*kt-w6B-SF1J2M^@WP#HGPueTt$~tU!n3+Md8$= z+*K;O-1_gR>~iYcRlZ8`Mk3n(b4B6QLw;D(f2H`W;%^mSCBkky5!>HY|A8W(*|FaV zifKgHXAxmDQ1u5Z=Bs|R%7-Zy6Or#IO)pWb()1cd`XQp-YDGRgrhJ~JU!eFS#mg11 zQ@lZOi{c%M^!LMZ9##Cc;tQJolHwbRe^K16_;*Dc`-b~{q+)~O$%>aL-k^w|52+WY zDM1t?$m;>NhfnT^@&pi=tMU-V8H%$M`5c(`$0{yStW-Qnu|aXA;u^)%70*)Kqf~D%bOX4t#IQ*zFSf<1g*7J0)=3y@6>AgRya6ev;iV*mSP91UfhH z{K+sCn_D(zp1+>Qxz-JC8t*6Yvt>=vgt`4OH*wsMgO6z;uP@my5;5I8h+0*tmi40B zNl#jtCr-Nw-7RaL+bK^PiO}A9mklw;1nXse><6(Co44NYVj@PNbAy{!3x&75^+V0u zAeM(qlURADBktxw)Vc}f9mj|UH;wm8-tsn~Jhp}9@mO=)cQN8_9z?AK7#y{i{*s>L zEsyU(**}(tp^TMx1>!7^$0@@+9MFH@Nk9YBxZSAe+T|a#_q7gpsvSVWPhjVrgYJC! z1ya533!!~!(6N2#*xdd;f;hUzp^)%$r}Ee~2BK$rSZPt~Q>}F<=np&Ob%R?TrcvzJ zU|KfX_gmKp=-S1f9aax7^7@}2v5&P51tUflVWq>TS?iEFP%7-O)}dg_d7(e0h3)(^<1%r*BQhPJ4Ovu4|VM-W6Q4a@RG>m+rc5&FEc&)(qN}uzc07 zv)0(-SMC~of`fdo!zXI7_^00rHC&~Cg#8Mi^gRTEPgCg+420w)Gd`y$ zj}7>t|0NAVf#b02;ctE-3Xl7n=TC>Toqq~4XVE<5e;;Cia5Yzj0Sfn-j!(Ny8YvoVsM;_{_rj|GkBPaq42vj9#YedWqAIrggJp8zbL&EgI z9Q<|Sb`i~*hTv0Lky+Cad|EqT)-(jSX}#mar0fTO(|w2JofQ6<5oQd1r;s00UUTv<;Od?o!u7;#O*FKGN)N+FEsKYj^&^hPR=V6JHx z%6hl!WaF9!?rUbvl0Td+SzPy=MLqTlpKEnvQjf&Kb~b1In>;o|Nf)-)LV zX^}@c)v>0*q|b=dGC$Td$OECAS&{QNj9AlP?B_=QP8n+&I5=F>z?CFHtZ7&w^&J=C zaTUax1|CYXrh&}VAl5YS7?Cv%bm|S4&?&z~4q4N14!eXk4ZJRNxTYbWWnfLiYhod5 z8h9v}oz#v2@$4iK**NSZE=&*j*TW#wz7-lyP>(59?*6<%jF^wpHg1Ic+n^Bt@tlQn zFyr*W<1!iT(=%qUfy0P34fJ7>-GmOL1mQpaSXe~l+>JF26mX13o?~yYrooJ$KXM2M z1Zx^}MxaJ^9AtC+%^rqwQ-kmye_fq5v`Lo z4UF6hV{LZNZNc@v;6HF77zwZ_tZCq{8H>7rS+S_>luH|{~KX`nIJG^}8&v8I7P z6I|0UlT~9)gXzVL$Yhp>H4W8Lo>|in#F~Z*Y3gwiI)@2jO@le$mPIaSeOS|AWV5Cr zh&2sHZi`&T`mm-ULH4<>X$WFXLl044O+zkAz?ufOK-M(y*-8*=8d!v^X>iy^tZ6U` ztZBH3jlh})qrjSm3u%Eh4Mu@A4V;xhtZ6U`tZDcYEwHA+)WS6l(@{KIC1Z*;4V2j^ zk+G(M@*r2{nuZ|!$IpWz!a{>s(?Ee^Ud1uPnuaowv8I7%bqZ1x)--VE@IX?z*Ly+u zkLQ`7H_tjjtZCrR?Y*93g*6SV)zp8jn+aPtPV~=S;R*EL9hoz*`_P9R={Ku6u4lw2E2fB?JLv2jre2O9>SKxH7E8} zStr2`>lL14u4}~NW2C-?&8%0rHiK32y7oeBvR>gjQDtL_nCspy*W`E|`3>fgf6gp& zObatH$iLbvK)s1Ei?VHncg-2>z^QIKBO{E^*3O9B0$I&#+Zidw z26ii97B=K)Y-eP?=;sp3Mc?ReXQaspp>{@2F+xf^utS&&3500EMr?+W?ONdYW3c52 zq|#cY$EIOVK)&?oy{%rI-A?vy$YMP?rufA_88coAbB^< zAy!MgQE<8Hi7SoXPh6vVq8Xh=J_nM}2Y=0|$Z&{`eewpc{0xj8xlufDT5^|%?)`b_ zHiS0Uo4Ln%GoLDnzwSL;a${e_U2H1J$W?>E z30ZrM!7T4O`AA*hkG+0bxO4R~pvOd%E~ zq;Q8jdfWyVv`pE1B&*hu@mW*X*xFQ8+So$g89wO?E?$?Jmf-`=H7x}sEq;v{!k?c<>~A!qmq#%C z`ICver?30Hy1y>1Y;Gt$Kn`z*_Zr~feghc2`(*Ndg(O~{uD{m2UA*p#1zze+P7R&m zJJVh#oZaD2lyQZXWgm=aVD$97+3;W&oSg_CDe3-9JIjtZ*>+F6m)+ZjUj*L(xgm%Z zh=^C=w|4UuI~MTui&&fyM=wTQr2~yOIJgVpd%1Y!DHbV;Pf_UU#);{| z-vyqe^4W^tSG-p7_lj>S{zEZ<%Vd_5shFc!q&QiT9wBH~s@R|?d>!aFs(h*9jf(WE z$b2s;3LghDA8Jz{!W1U*u{?2_BEPdtxkhob;?0UrD!#0^L-9k!L`-$&&sJQh$R}*n zpQ^Y?v0d>d#k&>xMQ7S4;8uVL=Kz8O6-O#gS6rl6rP!)?rsBnl*C_r%@nOa16}Kz? zU6GHYrGCYMilY?i?2GC2i%G0eOyT2Y$UPMYD~?t?La|b@N%1tr3l;BHd{XfbiaQlQ zQViqfne~YeY+#Yr15L-8+)|5OydFX9Yr2c~TY9$K2p{5@m3JlX(GQhA!u7iE-(D9Y0lVW=E>WydT&mcl zD9`O-@A_^&P4$}*-y=X*{6-}rvUg~m6Y5czfDL-JbA4cu=GJl|l~#ln4v z@jC!+aMLD1fm63dWEh4MR|xx`*L9o@EDzJe;-hgl52DunC@T$f$PI2~Hl*e&l8#N9lIT0ci&WkNsr(@beWb z?@Gj(rvMwnh78MU;X$f_Y21FM=-PdV3vfPScY|wp7Zi-Up{19(Hg{$AgW)!8-u4ai z^fw)8Zhs#|9G8HN012B>9$y`}!L5tv83yY)*cCw81A4bS43*T0@?yb{`8O~o#oOMQ z4>=y~<8PE3+6c|4}oxCGNIUG7ILsy)nf<&>B4VUum^lraX40fDOg*$Xu-hMCo~r5KSz0eYle#0ZU-o;Bm9_1ae_3;{nX>iXVa45g*<-?x z{c~@e^3c8AdJQYKhXf#p(l$aqqBx~EbICzV?*7Yrr_U*V6~3g8!7*$0iQlFVycDwI z=J6=+6u_5!8EQ}i;Y*5q$^O{=K40)%NKPq?eY3OY5&Qvqop#33YEI8eQ3ao;aVS8x z8Mu?ZP*ErDPkPIO5DAz+LJW9Mnz`Q~!;8Fe-%ESe*0FRP-!<@-NESdJoqa?j5{0e07 zC|3hOjtKu4Lj@k?>mq_jc^M15!C_YCpG>>CH!rHlqdXBh4Avvic4OQjZxlSrN~EX# z9Dm58e2I1N=NUXo#!-jzC{2z2@K4c9@FR2$|}5b!8X0ao}Ov*QBrj1 z8`_7R4jv^t2H6)rf$}_+F`7w>kn#qsrOV(^_C(W!M@bf-8SlmEjI;E0Fa(d%?eo=a zcUhvLAjWu<94zHgvf!j*Wag$dfYt>8Jj(B&spL_vffyE=-OBEavm&}*2ai%K!tUXD zI*mMH@+jX&8Jj$b`<`|FCrl@IQvaP|RGsfQQm{L`f}!mXEXJc^mGh2d6aaZ z8hkBfCXC3V5HUpOzQC${4qRA zj!vY8<$_0P8f8UDwk40URl4AhT*P$nD2*J7oWY90qcn0#gbT09qcr)`A}dfSd6YNd zSC%|Vx=kgI(xeweo_LDml*r8$*MiU=(l zJW69fEpip>2anRE&k!HLJHP~~z*cD1WtBFHn$N7@Q5rcRvVkMlnMcW`+}dozqfEsxMuxE{@F>@# z%Q*8ye$K4mQJVeekMIVZJW3jqM|mb&4IU+bCdi{4$g07kG`*M+S;q3fqimA$;ylW4 zqjnr`kvlmG;8B_bZdv3W)(0M?k>fl{Bez9<&icTk>?ix&!=ua>1$dOxSOR#IY=J}H z&>IjTkCH_QkMfVK6Ff?z0FUxqD!`*O3h*fF*$eO}jRHJMA-#e}X%yg5-c1YeC`~Qo zQJ#q6*(w=R@F*#>Q6hs!NqM3xyFAJoC?Yme$fKmdG2h5B1CLS`vFCtC$&(@lDGEHw z_2>}~B$W-1@+K&H^Q=Q2C3kM`i#S%`QLH!JW7@T9_0zF7(B{s5y7MUGt$AM?2an? z{Q$~1kFp%49JC7d>!M50ODl@avZM06-0FKCROC^Pf)#j_55X=G&Y#bMO*axF1Ag=O z6vX@6epYv;;Za`CauDnVxJn%`6dCOe-T9Pn9F$RP1Na$6`>gcuA^s+|KVi$^b%A|$ z_tRl#&(B#0m3>YoORyK@((ShW9jP`KW_)5bkkkeHI}tYGR>&7(%YBn|ZIp6(eNcxj zm*2v$H}+y(ypa3{b;q;x^Tm!U-X>#1f5fDVh?((?CSrc>4t+UqMyj!) zBtosxH?}jKgK(?oxYznzf_jSy;QgVv|oz|dti&d9YnmrJOY_Vpq*p2*`5r% zU2_A^o9>1#4}zZ8#kO?}fj#nBjg7>KMonOspl%_~GHSwnqi!RzLnve=z%*tNfvpE) z6Ms!$%_zzj|LbXs8ECc$9MSzWjE#fEe%i=(!eT$oZ8H{xQzW{GaJJDB_%I)=Rf6fn zLV}6T;~1NLu@Er{@H2@Fu?;;;hkgJy+d7_u!;9pA)n*Ov)y^oZ!=xar$A)RNuALE6 z?_2_Re*pOk^J6oC99Op;7hkg zLPJeKatjEZPHHp|%uuxM2X}N)v!ay21sD&AUU>20!0%S00`r zOxCoV`~V)h1rkPpx$1n&P8d&O>cL)ODhdK2m5kC5Fqn{&5l9ooB;;ta6Ub`ayA64$ zxndLu6naac_ue5U!Ew@UNpceU2a-{)-9M1x+`KLy=glvWs|t^#Rc*%irE%f7SMF-# zOk)PRV4PL>MKMx^soKRuEw7mX_nMVaIKXbIST+IA*H@0N%BvgN#Y6q7Jk@?FJk(D` z43D3+OATe$YF^gR)Dopj-o^z@6^0;63HM!k?3Olz#!XMCRw?}#qWo@e}!A!3mHKNRz zfto5lRPkm=d=4Kdi`Dfm>v_Y3E*vyknQFQL04-@#MvNyM|GfkYS$Q~hv7K8d2;WW{1d-iJ}o+aTgn#d^h7#nTmei$}YQ z6t7ggPVr7f;jqGv??`DcoGjo@l|N7vUwP2y^IiqW*G$AC6_+T|6ASgiodTY&@@B=G z74K2}tK!FssknV&{=SOC6c1B8Qt^1jWs0j5&r-Zt@oL2_iVrDnSA1X5hdVLW+g&lL zI7hKW@g&7l74J}dRB^lF-xM9(2(sLCMS05&neVizuT}iE;tv)1Wn8A;uK0+ey!eLx z4VC-hc9?c~iW3xPE1sxWr+BjBd5V`Q{!H<1#U~a2ptw`e`m+=VDvnf~uDD3CO0iXOgW~rU zf1-G&;^T@hDZZolk>X4|5oi6!D_*2{h2p)6$w|geIIOTAs)6faQxArbrRGDUujkR1CPH2pS}?^3*1^^dFklp?>7$o{xKYu{D*Lrwp$Vk*vU zEI(Z_LPWj+Di2Z|s`^nXk5fEc^+&3Fv?5MJ9XNw>enr31R4?aE$P-nbt~gV1zTz>8 zCn}aHE?1QEDaw&G0YG|H;P{=Pc(&sCihMNB^h*^tD_*B~gW?uNa!qJ|zv9D+PbogD z_@?3x#lI^4L$NbwmTw7+@?Os=WTXC1-KNLSyw0Ry!eXG2rtDKGd%hC)YR70 zS6NyjKHy>HS2WbsRpCa}ldHO^tPVz#=g-bBYrzM3%3E7d>;Z(Y6G!+)PrGq>B4G;t zV%NpOtB9R|bGjScG@iHdvtdorgjf6Gc|PU|ubTleZs^g7yLo6j4nG9+U+e}qZ3z@^ zoN2Q#XXpsY4Q?8r?|bVVlVe%0!jARgr#x0~1LAHTM6FkFVIO5ggPV2|WN&%dgUxRg z%fnA(ti00@ck>`>{TJo&x6BQ0+9^eKNjOK%&a-tcd zQJ(WU|HL@LbhGLt!{(DX!kn%yM>rAZsXaNu`~h`2!b?!%Cv$}V!!qL>;rlUty&Pe# znshnBeHq__Bm53>7>+Q1WnGT&uTX4^BYZtf_Q?^x4bAj$gt_bzzE)QwKV59rV$=?l zBm4@Ah;f9^W8HC%a1zUlbA;bPH6D)eZW_lq!vA20;vC^MY+9Tn{0#HPIl`APZ=56i zBJ+M}9N}JQTAU*+;~nP+U&EHgIl^1n?$3uK%eQ|`zb^Ht*;TAUY&cvwz zPK2vi)mgegGq@l3$q_DMMPCL-m=9Mx9O1J# zGvgd#A+W_c!mraf&JpH~Vekv!2%pMwJse>!uJ&?-dC|2$j__tqH4jJl`|Q*KaD>OQ zJ`YEj3^^}H_$Aiw;Rugn`5un&uUNl_BP=XR4@a1bwfDynmIVtQjxdj_4jf@#<#gZ( z|C=@Lmm@rfWqiFk!b0WVJ4aZ~B_572Z>PK*;b9z*eQ|{O{C3|Q;WlR73rF}!>}2t^ z%E)Kq2$L)9+3IKsl$JphjIJ*@A*IKr26YI`}t0k+Z05$3AH4jkc& zXyN4uKSc{KM|dYKJ|~XwK^)UBfFmrt{V#ZKhpQZ5k3R<>!KSl zq*fH0Wk=4w=ph=8@EE3?)sZ9oI?A@s?#K~7 zA9?L_T#oSfng84l9N~?7;RtW+$PxZG>pHI^N0`oM?ejWvg!xF)-qghr&awvM4mdN* z9-J~WgY4R@fHf2F4R+T0_2&rt_Q4TeTzy*#}3sZ66$ApO+)-k1<0X>y!i! z9dt2|(T?E~h~VN9uEqAhpP2FN7m3 z4P)c>$q|+|vYq?n2upL@j0NEoiFR>>&H2BJBaBbD*S1zxmDH70EaPMB|Fvh^=GDyy zQb=u0dCAg>iV{3V%d2mwugar`wi5Z6bBVU?K#J>Fj9b9IIKp^j_tkKO&+Xy}fAJjQ zPtQ7(dC=M8t+I%}3hwZV!jZx%tY~P(Q%vz@3u@!OJ=x+}XW=O3=<;aW#U%c!n8dM3 zSo)=KiuWW5d)~x+?FhrI^<*hmRSKKA)MXEUIo@x(IKsm5t}<`_;Rd>FX>$=Af;X2| zw1G0-Tvb(R&Ya>G94A^e$N3a#Cy8VFua(=|E{-s6VjOv!jfe(E-nzRI)A7u}6C8Q# z9alIV-on$KZ=K`8>ExZ)fp=b7@Y&Jz*gA5Af5iT4F8{xX(r8`?fZXDk!6ZsCF z*pmp3#6Tj9hN*tI;uytZ#o3Ar6^~b3s#vess(890Us#V(Gp8K*9e zuo;Igj<6YrE{-t90mPXujxfdnFX7JM`4TASRbUrK*o;RPN7#%*7f0BP!#9W{jO#TI zTeqgZy1`}ic5#GpZEOPHMRmdt&F?0QQF;z%?)_BDZ#v{aJAsyBHG0fHcoTg zvE=A87i@(m;QZq8#b->XN8wkVd1{(r2wxs!2&ak{;mbd;g&~}(UW70Iz$Xmh zVtNs7>?dA?z5at&qkAa}a3R$bTj$_=3a206!4ck2J9fgeFmY`0dg}NBTy^RAg8Tr7 z;}6K%OB-?ZAME&p^cd)b0$k1Fgn|)Nq}*Vnk&WzooW*9QAI$juj2mvS6Y{^xdf&mH zj@)1_$h3VKIM=EFVBdwv=5m9dLF%5|;E#N;Q2)UrVG-j7vk7zpoV=b@TPdNyRf!WI zhsn0{aD#uq0^$N=5o6rosc7SYa)Yl$5ixFXCF_oJgWp2CJltU6_s0DPKStv?H<;f+_HcuRrT2M;&+Ojfl|ZtzSR z$GO4n6yw}rF17J+gSnF0!wp`|R>%DZCo=Uja)URqsJQ>&{uKA=KUlui9`_%-m@_@j z4L+1pBF+uIfnuB+T+JTExxuqp(P#1>{0erb$A54s%k^-Bxp>dZ4L+CY9{<7XSh2@{ zFc-~xxxw}9l!qHUg7zN&!4Ghvd;AA;@t~I*{2j_3|G|8K=;a27S-yuGEZk%dH+VYp zd$_@;a~M7TgLhE&_zymXvWFYY2jA0!I(kdF09)>Ztm|GWmtXBG#g^M!bixhhYHzOmHvWSj5W6Uv zl8tTu{)2m1PU^Vi!;;4)lRE31lO3!C#m8+ViuY83Ziq5DAp_Rq@kT1B*#ah8 zC}Jlkn^MSNO$>J^G|9FNKR3BQ__>GT#a2p22m7$so*!*XWrf%qgM`nUmSH=o-txP{ zKIAr<_UU2~h_@i4iyN%_)R%Dk6wI-KBRoTb(g9nLzF@Xm~2+Yz}Yryb6?Uah+nxa1Kl#YpO3j4HEs>YUJa?fPdg>9 z`Gu2U!g_2V2HWk7Y%+qcosmn8;PBeAL*UC!u!IThudswY2E3(qH;l|7NaABF_>v{a zn^&uGEpdub6W9|_gHI;THEII81NA9HHXMbt09Z9V?-JO`PwhUKubJ5%kb3viEH(`m z`)MIt35)$ScBQc(@OKW4C2TNS!bYPdm@X_NnCLvjBy{!|%=Qn$1~1AS4Zf9Df5D8h z223ad$;jd_m=ROeTmtv2`U`exIHzOi`QOyZG!DsPY+65WtPpi`!$mL@ z5_Ag4dwn*TnTboViR)iRs-|0Q_; z{qlIbAU=*!C!nRv8d{scAp5k$-7dmzm+N29WgD8|h_Tn z(ok29D&S-n`D2`3(pm)5p&3h0DcS=H2BgWZQzlK_WSEe$7?)|Sa6D{pC7RpCw^!;{4%sxNC= z+H5JqxdI-(!KbaF11#ggxdZum#b}-@tLs}j+|Z|BwkAI=mX~S z^6rhiTi%cm4_7Q!oUOP}v5U`Z#;MEauNj9fpTA}tx_thcarpn$=dYYU@zXJ$=SkpH z#Um8?432s^j{?7?GGCigU#GZ2ah>AniWewetayduHH!bEc)Q{~iVrCMTJdSc7ZqPt z+^zU`#s4VshllOs8v){AMZPAZT%}Bo7>fD= zMY{H)JVBAJ#VF5EOyGRPrC6FfFBN(9M!W60e=;fK0x#RO%Wqy?*HTsv-@Ld>5M1WQ zTB_RM09U@sl3(5o54u$3$JS_${-)Dydt(eREFCzn5Mu$mNCELgxlIjnC%2&EYqSoCgkMrIQZraIEc*|??l*fBDx4iEm?&e_`Poli!z4Z5dqLU#52JisgXYK zIadE|-`{Di*|O_Rsc)Lp7X~9Y3wl!$%XrAu4@rdH)En1V6+eJ7`Yw6z?$+Yx-n8zW zg7@=gKl<&p*cmB{@Pm+vt#k0%2~R=ovqSurIsEqi7rP67d;dhGKR^3JOT z!Z+`YltO_?v(iA@p@K7my7aa*7Z`2*KFI}u4tK`G$l@;WY&A7}v|mwNL>_m2=sroHlU z2cltNPBrjx_~rO5@mLH#F0(rSWZKQWzl(UPKj5E^>==|spzX%E zQ;EvK$K@cTU57v9<37kb&VUK{xQzR9tnQ^JfnuvQ`okO0Oz?3{143b8uN7q)F(q7# zJmBLRF|B)Pn-v_MESG0FnHVU3E_+t})IIH!|-eP3;rj!n~7Jj9Tg4 zP*cbb9vR|y5W5@Pq=~N!+qCa6n#0-@VhMP(Z1J+m>cGYeZa?kT*M(^jvDy5+eIAKy|lI5 z3O?1{R8#;F9e7$hFa{!euubb79~O$*Z@TZ0ypzJ&Ecv(sQYnJ@sIArm=DOuEGzXY%oyD_Q9?-4V6T#inJ7dhnPnz>>{4&h)d^(CK( zi)detKXNY9!N)anD6*0jgO6+Eln8Gy$j3GL(;_QSDfzgU;MdTXlNlLGd+>2hdO_qK zPIT~bZAk%L$teD#|2F_H5rgO7WUq>qodd|Y!XnG{K5`QYOk`)QG@SU>ot`7yf$K5jOK%*lB*5IKltf{*)}SiBR!`14ROJEtT>--wF*UsK=BlcYod>M$E@)8#hA!ZBQifIOHspgBhm}%E@S- zo-u<*aTvkJrSI+RGtdFy;~oo(h@88@$EAQ{Jn}GmGsxBv^heS;Lg3@-j6jX-c)-u% zvqLCX__$ZHsD)?&`M4BV)M93ZuU;c3L}qg2z{j14)(Ib%ky~M`&F;A^xZW512QDrn z{a6(ExcoI^QCBf5__$_2`Xf9}$j7CzFDDc!XRE=-<&0K9z4&N)u2I}*NB9LE@^Ot~ ziyfhlbn+7BdvD@+Z6Y!hA)rj}Ed9{x( zMjJxzD=Y}X=4ZnOgxIhIJB!TOanMGw<=jjApq>70n$64McdYD?oplmy?D;vZ)F#@Q z%x^Eq?atv!wli4aZY2E)o8jXo+r6pelCo^Pk20lqj1*Xc;l#jQgZCzlN4o=PAF z|CnMg2{V7uFfPkk|rPk(j&|%)>daLfl$(81KIk}hvxVJi4o*{9D zBc93G5)XTDay5xh4nU$Lq+tVz(%;TVKhYmckUJ==v8A06UM0e)O4k#E8$wvukyDua*q*0?TkEYgp~H*Bk~G1x7=bU8=lWMomi!+v6=M@a*Wtu#kXX z05r@E{X{B|S=WR(sIzPg%RtmE%C<`4eJbF6hy>Ylvj5T`yG0R6QFg4Bwe2of8A4n8 zT4-6ir0lK0K1eie!x>w{D{f>j^1(P~JJt(mM;Af&OCjj;G2K_=gZCUC2(TF$Spla< zRv?nlGhjP)`GHg?B^pR{5~G2jvnoH}Bot+3f+rhDNpM=K$R0AY5-qyRmCz)j)roO z8ozKx?-xhorIYC{_HKQp(4s+bh5Ofvl`S34Scc$Q+6u7ib}@JH!QdKFq@zWnM~@sk_C#Do;{LJ&cb8Y4Zs67C)YQx~0%!U+ zIA{63%S+tJ!||t#Uplbl(Me$R^t{ek zGIq-(dKG?a_s8Ber$Z{QXye!Cv~%#!8yvii<@=3zh+i#J_jTm$rlVaP1CDP8-mW<= zJj7inU?cb1A+xW@#pU~CBHzCgdlK;kU?34YbeQV7tC&7cakAnJ#o3DAQY=@jQCy|S zTNRdbuHyNMS14Ym_&*p6h68~dwMDkRvfK(gkq&)lj3QL7b@PZ_@v?=6n83qq!`9A z$ol#!<|$54oUM4GV!h%z#Z8J=DBi00pyG3i+Z7A(V4L+#R$Qxij^cHS?<@L}jD3b; zFU5ltixlaOfaOk9oThk`;t7hY6;C5#Uu{r4mxwwq()7(LU#<94)!(7`sN!!GUn3&_ zpB4Y9_-{oE=Q6f0g$TPe#VpnLS9ze~A*vsx@;F7DcBI{y=7RjKV?X$ShA8Jn;6#lDyuJDF}#oj-olY%Miq`3J*sGg%iJx9GQ{}1 z1*1k5iRP2}yITfIg)#naPcV4%-ulZCrEg!5cy{rI;tPw%ZUdv%d7{{gTKyNi{P@3cAMuyJoW=&hiL$=?fZ}%Sw%WKdmi$DcS~<-P64gv^sE$BkZw(R%WwIX zX3OPPC{Tr60}k#4RN9Gy`!S7&WlTp_XBYpde_XO`oG}?ZY{3Odq7_*Y;O0IK6$n-M zn~;HeZKn^Wzxv8`cw6iG%KaDY$<5seop5veqWVN~j=;@jU5UrQ0^D5c4I7JBQ^~Yf zZtfz;VH!p5N^WcoPnGBZxO-GrT<`XbD7l{!uZX-??D>5xvkJ)5Xso>#<+71 z(p_J<&%ub?T&`9M{{kl9=E};Y7&q6{=ns>~3~sIwLxuoblxf72a1HWPapQ_&y(Cz=Uvu3PzkXgprU zl<+^UuNFJRm=`w!Mu}H>=XVS^G;UL%gud4H|6=5FpT$@&gwvwBhjGW5N)eOqb)rKiI*GPMCb8li*dvJ64(M-NbNg{WKHB$r5p%=eW~(0$e<e_V4g5nr z_RB~lbz@QwP(_uS%h8Ecuv~C+X@@-;nZv;VH}^d0f+;p)JZY~c6vy-02fOvM2h-@5o5*LgF{I|d$(|!#aPEe02Rqp88|{PYqbTwKmVIhd83dzdSub>h+(+}t0aGufA*al*|#3lQ=y3DB8A*s3LNuuIA-AH zULZ2KxjZRSkfOlN<<8-Oq_W}WJ_1E=o^{C0<<9N>eU25lxvbUH|64Z`xVep}1>9V! z`q(@T$n3@hBh@|N=YihG=E3J43n_>P{2wAUiF0rOL}>uHx!LRixVb#@ft!0GD+V{0 z7kI+WO+-4b$Ffjmze}Nvb92|Al!Mm5eqHne^wNrAv+O7b3+3Je6}h=b!wTHoM`4$k z;mhDtwr+HM8{~?o#B5&%?^^+4Wd1OtYN#f`%N(6Bf==Q z0dJrZdr3O!UTz$w%WZD0v+T-lKZYG|TmJ(c zjJjyG_yLSL#Z_8t#7m3ibL#AvV_miQ>S(p_KkU+KFPV~p{jUUC@k{KIYL!Fl)sa^l za|P_>&|<1!{+=xNx96I86c7u0FlaG(Ovna+_(qYFc zF23p)&sTLHOMNwj)j#1P0)*9o6Tzw&l0HFG%?E2$XsTqaLc0pu1W%mNZqDi>$q99m z$mPr|LcTTmR20D0-g~4FMlJ9TO9rfywkHKOQ3{~d8ZY70t9I$79dwS9YzKOSNSb`fQwVzA!RrDZcxyL@nbJ_R}$};`_R^u3WukHdU2@r&U+pR9jW=Izfc5 z&W2WcG;C~WCQr1wo&>;#hLdXGRdGtqQdACV7ie{>D$7>WFJdztb;ikKOzQF)+t@mx zx^d-*yynKd%ED36ygFgt=7AwK0q!I#p(tyrST+F0k7?$0wh4kExYY%iU}Pmqd;U)`PUSF_aTg!Au1nAZ^BfBfCFt0s znOmjedPr!w<#452+fWYXxtF`m18;Q|eU-YtPiv~GaLkHV)0UdLD&eV@w$`^cSIM4U zB~(!CI_#UWwpEqbwY8&0lo_+~+LOeUDc)M>T#=GaGJbG7u-#!gl_!OIAq%g$ca^Y za>UV#q6-@uYMZ0g4NcL>O?A=fb>&r+l~t8dPbVT$Rp6A= z=;@&|gBudg3Y_gf$2phm(yt@8G|kg)@0Bgp4z7#6VNV~hcnsnR4v9^k;8-9zd4ki4 z$?6ExGj8Bm8F2wIN51|LS2=j2>$PCpbFlI5h+`h-n#QjXKsGHc6+UliZDq~Mx(4;R ztrk`r@+IK~D0}L|eF^S+g`359qU31t9WwDiIjF^&k9Q-?FK_;UOI5B_T%&lZqRTzK zNaf9nH!9wx=yFh>QTYYM*A?GY4DkK~^>$Yrtyrvhj3OWA&`!P+4m?d|lA@{qvEm(y zk1EOsGmxHyyB*p^6bC7eRGg+L93t2WX9y@evVKVMO}K+yk8<*kZ*gUEVbR^;b9 zDbuePv6muO3sM%&4sfZ;EsA_P%yce%CvH>xqvA)3DY)5VdT&KKHK9CKafad`0Hl7!MT*sms}#>x{GsA_JOpLFnTq0M1M*UpS1Dekc%|a4iVrC6RQ#-5)H)oy zY{$up=PB}81NAp6-lzDC;%kcUEBbLtqkWcQnIgSFP%my?fOo3=f?`gRNq0G@Q&pzh z1?HQhSgyECv0kx7@!N{RK}EhxRlZH}9wPST1B#Cj(S|29{RNd@QhZhQJ5+vG@o%dC zSY?O&29y&bqTURZBZ`9+hbrRqBJIF57L@ZQ+QoA++s7v}L_UHdPFI|%I9E~5k4QgI z?&)coe}iIY?&*(If4SmyiZ>{3QM^O(e#M6spHSSU_@?3x#lI^4L$Na#m40K`?-a%U ziUSpgDHbToc^UTn^egkp`50KOvb=1Dyh3F;PebNwJldbBc#h&GMZO|sIyo!Es}!$S zyh-tP#a}8up!kU5Gm6hE{z36iiY^Crr^LsTB6I8L!x@kqsE6i-mB zR$Q*QQjzYOSkDHEl*hMx zERSt*%UgiBn+H*AH_H0hqi~~Do$TJj`S)3O&^&2nhot^z|FPhvoeqt+yjwiwp-Zvyeu%i6 zhlTtVg+0EP{$7kUZ+Z8jJa@l!Lz>&ZYY=C71=tw2;wIq-?xcXsG;X&jx^@eD?VZu#yZ_&2vLhXQMXT&-SU{nYxg4B_j?*>aP8uc6$(do;C1fHFKfZ*(M3^)Pv&(l z93+*+c%Agi3QlLrds~KV^A}fvZ8>;Z^)lzfv)*@h44&$IxZ!YYPwp%{1=GxCDcSixhu=U$uAUGRK^r+^O)FO1>ogrA|c&;A-|prJcB%HdWD#(J*%oLRSB$ZmXxpuSMzz~FkDUEZH0Qs z;G|uRVzWca)#MV8PzSDNsK_Pzgt=ZX6z6J^KoN>_HIG0WLmjx9q2bA&z}4hkR&GeS zn#)*soU6GV?Fz-YnvYV9b2WcY<2YBd8`~1+YMxFp&egn;dE;D7-qVKST+Q7aj6JxT zp(8`W)!c!-7m9N=2UGNLHG5*Ghdf-(<&^iw)f|qdZL&irhJ>pr;~nQ}@-90R=W2eR z?e56c43+o$v|PA7HRrLDajxb7HggZICVd+&3&pvbq1)0uT+Pt!?o1$8GjxYa zhN~I6GjS?fOFya`S=C)C8b7L`Uv@XVN5j<&ZPmQl;Y-=YI9IcoVw|fvjQcUp)%-47 z9p`HHWd4g$y`V)+3-h5sD9+X7 zwSOqi)#S3*P@JpzSBi12=5qEZ&ebeuMW2bQ`7w6q5PxWiFBIcyhCEzNF1!eNxSG5u zfE?p$Uc`z$T+MHDs(HAYP3)A1t2vYQ9eD<;78TvYCguj?BQziL0hO3S2F}Zs{Bdy<+MefV||^u znxONg#kiW^VhLWZ=4wuDFIST;dqZBX=69&@ay3t8FT7k$u9XaVxta-V$N!G28G;{G z;c9-!270)fmvYPwh^rZbA64OM@~jhbxtiCrjr-(ko{m~RFRtb;_8`vHs*Fu#T=W5E+`BX1g^G)RR zfxSthWk;^&?MSi93|Dh83q`Q6z@_YfBbibze9ak9j=`4mA5;V$<_$EOm$MwT+m*u9 zwCCq0p}}^wq&sd>ZOn7bfB4H zPrH6vy+#A~!Z97x*DlPMZ{IN`nZ96;OFlmNSn))QOX$K3<)IE45sx1nvtN{8tT8>4 zZNBLknhzJW#`)~vl$jY(DQB41fh;DaHbGp)auy>XD<-+|5_^n^rx8z3J(0&UYqJnE9CFs&*gfn5Y;pBACXs+QPRjf`U2Vzm(B& z*w8k@cx-61Ee)Dw^aO4JkVe5IWt8nAlay%U1)f%yKr4YKSU*oA64)YAPKo`nfxOCA zaYzs)EHu&hu*dzEqPucJV-C2&jc4Tkl3??>uGl14e|?&#oLKOsAkKDl0)3LEow_q0T4PN{07?saTFEuo~ne`R5t(8?)#ki6d z(kDumR#fDX_fX$ZUzJA}SYSYOAWf8XNG$=^iUpL^l~pXOss9`bYF^!ZAg!sbDQBBI zwMuv$Zrcu|xV?4`-cXuA0F!6+cseHZQqh#PEX!ZUJz82>Rb2++V5xjI89Gc_5>`MP zf`FY(QkaRwOrV7YGD43dQ@+S-OzKRzJh9+d4an4Y-Z1o1_(RPWkEdXhHs^!j8UBCl zT?t@R)zyA)X5P$XnIVvb86bfn37e9Tgk1qy11QMiQdA^_ED+6R5+G0%+;FK{T&q?M zTDMlK{jFBCDq6SJ6{~h}uZjy1m0A@=%m01%o;&k`0Yz=KZ63UQ_uPB#xy!rn&Rf2B zE*Ydt$B;l8j`=)JmiHPu1kKEJJpI!BwvP@(y_;6pNCH>%7b+&n`==EomJT7qluT2V z?@E&|f=r;PKD)y9wiJM(id2u^dxQT#WA2$1HXO5(g6eoXq@V7a3#++`e(E^d*=f?g zPAXzpQIh}@s(8&)g()GQf_WP5Ltmy{yt8Ati1>H1PybD9(&LJTD;`>T{Zeqv6q{1h zPVO%*r}a_)bEgxnu-gCo!D&4vnre#QeRb>OGjQdP70@;;ycy5)^nP@B>CZo z9(*8darwaiKu)UM$w=e8`~uyzeUYQu?m`|HXY8rO=2f>lZkZS2iS3IVRK8VBY+f)z z_^y}tRqW?oIH+nuGY(JXB2wQq2ERVnln;Q&(JB#~DL7YfpkxyP)xNnt~r1 zrgstSBbX~#ENJ|jav?Bs`X&ob6Pzb{^93sfs|A~g$k#%|eu~7OE_k-YUnKISf>#mI zp4$X5?I}BaP(yqC#US#RfoQmY>X8oQJc;My8m3PZoFRCK;12}(J3+lgg2xKh3oa8> z^ELF;d<{HR;?EI0Pw=OLe5XLW4+%aZNMCM@|Eu6Dg0Bm<3BD(|UGOu(0Djz4I|v)hjdD;|mIw$5+P0m4YV-ei_$QeXD?ct)kDj z8?<9MuJ?#+IIeuJ!Sp{1zC^@jh2gSplX$+oK1A?GZpdpJ%;hVK;dY zw2r|5q7PlOnY1!Qm@v~m#dGZ;9q5rs<}UY{9Ml1NESKf69mEFgZhM1p2^>S5*-Tmu zBHZ>e`ss6k_VAMsw|6qaCJ%zvbl59oKsJ-M8nWA79_)=r9PRPkG4;C;VUq_zYX$7R z-9dZLMVi}Q1?;hXw8uyP#@>|()1Il*BAl39pVn+l<9?%{(F=jE$vN9>MvpvEhRt?5 z^mq+#HZxvsLxj72HLm{Ss{vC#&hHqbJS=Lv7xvs^)s#hab%XT}=*1A(9r5TQWiJiL zGGQ;iWnlcp;!>jS%;VNuh5G%e1HHs7Gm>=DgrCr%yYmw|bl9*Mw=d_DUZ1B5Y{w^U zxb>`H|4mlgDSj(=_IBSvlRiD=gUKHR`ejeX-%0yU{?$ZpTVDCLr@$n&LYpr7#2Rmp z$_10u9(d6w_W0<=i?EL-yMKKS9N72m28`P9YAR*AsXflII92XfCPO=Ny0(5BZ(KCH49O&r><* z98G({0G$g9mlSDZklFJv{`fMw4PuzTJHjRP+{1XyCG`eXvDdstWG{EsAxI#`)RnOf1%9;m-Ip!NN`C#520}2`;IRbxCkZn<(yHXZ#gU%i zk{-g;1ef$#io4~K9>{{e7MJu@9L_y(Nx2sNp17p+{paSAHgl-CxTIV#$IT@zqP~ku z`VdExi%S|}c`h#Ljg@GHF6njbMi-Yfo8`N>q*pQB#Us#wE?8DHoUY24;0}N$GIZ%_aR2 zYwhBa(tWF&OS+Ku_P{0mHIK53OS*yO?SV^5ir}8Pq~mB|k6cnZ@odK>J%tf&F6mF$ z3OASZDr&g7q<^Qzx5Opg!QV<3m-Jlr+1KNea@L7+NiStz?UqY=EK2#dxTJh+;^LAn zWWjMRsn_Rw1?jjROGA;p&qEa*o7aeOF6r^mUmc@&b1R13vSZ|6gG|`?EaWrrG?%`wY7| zdB6#Xo#XX)+g1GH-x*(REN`E@Exe$FovI)a4C@b2-3Rk3064#w#G}*SN zr!zjKuQfe=2Js!K^ zFCL#d8{tDGp2!mqIvo9G)3i(5_IjBSn>sD5*#z!b`F&L@0|T*xy-6rg!NUnWTfNpY zyOn_wEqGcPI8Y1TR#WgU)K7JS@sGV*+9&G?5+{osj9uuR4D#86@J&Y`h)U`jOxE!P z)*+w>p+#Bo3X$N+ig71zGf_8&)W%tln{)VlG)Y!A({dv|4QS}uZTTs;elx?Y$AWiyj$NAlfJ{<;g)cQP`+GTqe8 z$Q=0{5i(!H#e-g;K0(N&)6Y=s3yjR|idorxXoewB?r0&ylGMu~P7fd)g*yJe?jZP= zE9?P?B{^~#d6wbW7gm~2+J$GC#P#gKuAKKJB+H&CGETBg@*b@!{9nbi1i5RJB3O31 z@BA;ISblFwm3u*JMHW#BDflaCqyv6YpOwXEUl&M+0xR(X4Ka$He|}$(xzqA z@Qk>;TsbK<9!#sM)e7iefqB^>lhXBc-p#6XpEY|=ul#p1E4k|Xf4!^Ee>a)(xRIPP ztLoH84ETP5oLl4Q74&c>{!3kaY9{r_mSKuWjgKS#gZzE+qHsbu^%U=^p0)Pkqtc`9y^>pQ;d}g6iQ3;5xwz1TPo7Qt$!6-wQr1_-DbF1YZ^0D!5H>yWnSn_()T=i~dbiKM0bx zLAkGBKS8o37+)l~D>sr4)R{hCkd7KCFA-Er&_Qkzd2hLqd^%5izYyfJc*+|EA0mRg z$j9=G|Er+-T}8Y(&S<_$=M@C?-VnVE%6QOj#=&0s$J~XZII?psb9S@Z(7kFKfWNrB z!L^#+h6x%ldV>+cFpnEI>djXn{fEbm+eGXp4`rS|>v67|&7_S(gqxc-9w+!h9Cuz< z0pi>={Y=*628Rw4M3a7ssv?cOg^)~`2|vS_dCL`Hf~>Q<-1U7eYdaEIF8hJ)AaZ^% zc@VUIgn=4kKsJ-c`NVDS;#@tZX)hVOv3C-}CJ%zv4Y0?tZ#I*50wUb@u6Nnv+-U4^ zJ~DY|hJ_tRpi=+71F7`}WL{~S!(Yp1OIEpch zzuu;@Kx1!Lj^ZZN@7WIY;!i=Uh8BMnpO>RY7LOuB@vCqY$LFX5+i?^NZ#_Hs^46@C zQMHQs;F3eO`i@NB>OJO=t)64jx7sV0zkAI}d(858*RJHc<;&l_7BQ!-Y=Z|(Ck?zs zZ+wpZHwGMu$>-Byp%4ZNGybHlq+R~Fv&@VloS^SiCqF%46#jjW0K zE<;txXY=nb`Xg^0Fh5E7DFd&x1uTIB46 zG`53lk>AfUu7e8JB4-$7bj3INfnq7q7rGMF#9HLK0>KcepMl~GEvANeC4jZawP@BN z|AR7=fsQ&Fp=5q3!Cz$6Hk5rAOmHpoIusi^l4XxhGVOaA^}<@@TJ(kPrntX|!4O@F zVJ&h~_(yEeSP|1gm8{x05i>$pG4BB)MnmPyJ6^=B&|jE$f`~Dz8y_(Q?ZAP-yPy}k z1xFQYku%I*f0veLBvJHoE%H~Ge6VU5WKW1xF04h)hU&G*`Oyd$eNautTI4-pK&?ei z5}EGr1>G2?^+qUSEppT5vsv%5q~0nuz7{z7 zK@3&m57r`Qm<5r^i?zt5ARHdfuW7uf<67io@XA``l0nuY7kycaTuWbAi+nwc`odb| zBUH)pwa9heXo%kcVJ&j?X${sQucr85_Db}k2Wye1v$r44rZY-UZeED4j<6Q_BT5_? z8p47eP1>x)_*&$;p!izkx&iUE$aT46LNzq?bk{bOcYNq`_Qx|_cPKHw7P&SxIrM8* z<2gAGW`xx8$ zuyHMNR)|?M)gSgl<^lY}cpMi873;#J?j!{c^aU1rg6y3LY1mwgTsO#yOkiigzva=m z$mPn@$1@%NEwvns9ED6=i(Jd8ky;Kla1wR?vEpnY+82JTz z2%JQ*}o8^O($j;$f+y3CvViWAw7HsIg#Ri*KcgZ}5Kpbt_jI>dF5 zl*r0Ki3}pgw+0Fs_AQ9v0ClM{${bIAhoS9p*d~;ae-k3qTI3vs>SUI+$Wu^1nK1+7 z*p2XSxdg3?HlP7&Epo0}5>azEIEiWr6Rbe}3R?qCqV7RogiFeBEpizVD3J|!d^8^= zjZLjZeicoPMh&c`9qPNF`JKD}->{996)Ymt*q#?PJB zFIQEa7kPn48Jt9Y!Yzq#rE0E4uI0p9%zolOtbJtqr-BkqEBF~`(a1vPq zZ|-_K!fSP|MNSiHEpiX*2>+Hk0&9_T)gP`!t|PD(`MJ~pCs9XWE%HaH0ZyWhz*^*6 zsR2%+F6A+-MLq@QSu542Sc{x8E2U(tMNYZDklIP3>w&wY)Wmv#Fg z73Spf;fH;B=CRNK1@W)cZ&hiJBmH*lnu54KorP6Fd7&zzbIEbs1pWte0YOh~=L^z* z`$U`)U)w(<#tFwPcTLo*(cvJG!;$fcjqVsZ?v!6fA?T$c8O%3A9(J|(I0O4=p{139 z0xhhHdq#v>P3suMPQ;GvgoBk*gRhkV-Zy|n7i?ut+#GNf@BEEd15Eq@j?h+=Fckz%Y zejCLxmvIA`aCFE=BHztA+LzmkSBG`9jh{oVn$4B6)4lLom^2*ZwwYwl6&4m^rEExC zC_B`T0YjxzOJ^fOuao^nCxytZsB_|Z5H1RLjWNCnkJ3&Im2X10Q*`Wuob*0UDi-!0 z;_>0UjIU1HQs2O(XY1=qxe#z^S>s~0ws3QO?IJ_kX{6&mu6~Q9Zn<`8dxw2Bi>egk zLNASK8CPfD#p>3|AK}nqL!jG@Pr^=Lg!@)C#PSzcEH7)U$}f)P&l(!bud1uhZ)$F= zE^p2+tEnz)s;*m%NG=)OTwPz658r~sCd6?8WVc+^kY8S3*W6fE-aHm;8|~z7cfJU} zI`K@O$p7OjVY{F7qGP`oApD*&g2xM7);1P>Fe6kIBJs^Eo!*9hJw_@Lmk zf|~_D6m&4aRr!Mb1i9E24IurL;T?)A1PQa zxLB}3P(6}|KA$4d{)vL83!Wu-q2MKgR|#G#$fugj|CHbhg0Bd^DcC0XcfpSYcM9?q z5$%Kpy9xFX%obGhC-jV;KJ}^%@^DEXFF09{uV-j?wjiIlQa(nIevv2}F4{>VuNA~; zhlkCH;{j3WV;WJ|&c7Yr9-HI!4Y*_c{p<8^$BxE^!=SbS_>04U>l?id6EtA-1|x!D z9ye~(<8Qgyc-**6!fx_V{uTDOa88=dq#b|=Of}YcNw~fz^k9V7As9AsPSY%eO&+RV zoPsff-$b*Sv@%4PFw?HbwaZ1W2opRSY3_2@^|7q=NMyO}2eyOA^V#G<&>Dv^7-K*- zlU4)SZLhGe9@DhPW*d7aBW&^@Xf1#}&P8T3X{!<8wm05ok8_x@$N9tLp^ZA&yR?IT zITvYed$VDW?PL8g-Nx-*i7@RIV&@j@249=zU_)ja_ZtO`-b$R9D-mZlqjv`)7&hBK zpvN&}HnxM?ZP?xQo7Xqdf2cydeh(pxG0MZDwiqr{-DB01MRaw8btv?>UNWzhjXm}| z%QRyiLF*KZzgz}nGxm1njxFiC2mf|uEv3f|E&6Ky?TU(r6@oeTRk&jV2dYZ7usbUq?_ZC50bNO=SZdwDRH*>9OkK1mG&LH5nQapGMYyYw7fVh?m62h+}iJhddXBx7Npg?GR8{>igSUV*>7!*R~)W8$+< zM#rXd8R2<6%XitpHRF<>pj8zUJkBr-6L8JQ0`rza*)uabhv0K2A;mkMTC;josHgy^ z5Ae>8!C?jOtS<`Mg?HA4W(KEEfx4FzFL2Q2F>BD*mDaNH2OP9p5aswb;4c=Y!65eb z!D#>v8VmMb#>7Sy4g`@(4%!;TDGr*0B9qAB00-?)h)k-2MR3pG42WoCbuH4!K|308=&a9>qYJ~{bC3=W zS_RV6{tti1L3^HMaB)a*&=^J;!a>s|`a)!kfrF;SVCYCCW@s@rG!uEiLDQn)p#4o5 zA_r|LLdn(mvkkjy8_IqWCdffsi(*6MR)K@24OpQMP%m)MwCD>xLveo*gCUzO7$ah8 zD9E~u6)`QehT=F8GeUPT?*Sr4L!>Z*gQhKKg|^Vt1QFdFv}ahW=W+DFL1UP`P6{J9 zXcWEVpe5m;gM-F~LH2~`Q3@P1EyF!h@?l8f>aMEE;Gpphw&I`_qFCME3%W5(>+A<` z&`g`JX1&YQPysz7gsB^}qux{!4jK(7mmo8DDFKui2;iX6Ul2KHDL?sE$simwshDukwDbiInqnh;frECiDml(U(|MzzpR-N( zt6uVegT`oZ(9T2k$U*DJkM+Z?kg8hx$`|rfa$q;~X??YI5iaR^vH2^JawjJw@R8-R^(821~_O-RTF%X3z!ZLnwEnRI5<@tG%cq_PUKJn z2TkWsi?pCna?ozVFCIB)iiQLZnoci_JdNVXLDL+uVUg)94;(a|J}UAcWpL0)GV$b& ziQLcf!9mkg$@oZw_Q65Z`jaE{B}NXKPM;Pzf%(BfBQeF3J0o%{yAd2Ttv@>g$2y9G z#?B!JjZQkrK~p!T;GprmA_tA9lH#D{(I7ZzJVz7*waL_(g8j6F)Q$Zi3+tGopgQP@O4hM<+J;!%36f*2b5W@lLQe~7mp7$#y=HswU zC?Wq_h)^6fjzV=Z3kNON$fzBkQ;~zV291ecf(9rKT0Jx(YVHOHjRMYb&DsM8P4}QL zGKTF32Teuw;-APl6P!)2}DA3gD%nA;gmi>{l*>k&c&>n%ZR9kb< z!sy1xV44C4Z4H`CQ}k0u4w^oWzQ`yx2plvjlY@3Kj{!Jn{FwmnG;$P+1_w>IVp?Pg z?SX^VsO%*;Xg^d{ofmnJ;|d%!eZnn?@IeqcXj)Ei(6rnV;acA0p!HVA+{HmFP!Zsu z(PJ+;Xsm&k9JI9vkb_1Oii5`0tI0vr5#XSm%SwQQrX#>XyP6u{py>#3&|abjIA}To z95m9~$wAYlkb`zK%(GUiPr*T>%t|R495l+~jBGe))rg1$kwOj{1@`$_>@#rCRwx-9 zG){^Xlqqn~)}Tc^kwn%Uw3`soi?a?nXgs*R=&O<(G?uE%zsF<(2dxREfP=;;;hJ&Y z!T=-73~WwRD$9NsVRJ70L&cNunanYmjQb!}0dU1WLq>AYXaO9wS{4irT2zT1pKmMD zaXl7Ak-b|Hnc$!;f|WjJLVtDaBDB(qVYlqq5hxvYpF|WnXd|En4%(lgmxL9SPlHYu zlFA&P{(Az#eeFA-ZLjqsD?WPTA8hs^xJu0#hm7`VUHMdMKSai`=X^-*)0L0CHzEHG zdu{{r+Glh<8G82IT;88~7ZAM&#mAD1+dD!z55ASSc zcQr;0$-{XwSpL~P&xZ-#o_xf(BWQ1((mM!oBqgIgN~M$Cmi`~jZlk}xoNt}qhB1V5 z;&^rM%;Al27QnSBUYm_Uh}#FXVVrTpX@|S^*#zD!gOBEGWgthzFCg%y8}ZGp3{2EQ zODh9&wXmv{fhz217 z?(HH7wl#-9J+IYbyE5>0&1`I`+0o?wi05@NR^lbFAs*C^$j88lCa_6}ZYIvq(S*4= zx`oIFL30K?moskM*%Q6d|=?DOQvj-_gQuh|j@pTSu^Sc#-T_EnE|t zK^BKWL0E$wgJN|n1G?PV1Rj0|`LHH5gDjg=L!u5Bx{fhtMz!(x2&LmcH&%e0M0OT$ z@UcKME5mzt1dS=%nrE8iCNT1(P;H90g{d?-AG_CDx~i3dg<5E7Wq{UIN=F8>kf2N5;&7+B;4x;sIC*h$NCQj46leHoYT1TqoX z#Yw|z%X^AEARTHp)C!y+a}MJ=&PUn)FRP^OTa~6rtX_*093Gp9ks$ueY16lDzPHm;x2MuaoM%d36D1%zq)PvbwIK z5{n&|!qb`NH_C#t?OB!$)3sXdqDD9wGxSY3q~c{=X%$vX){e5k@GP&dKeifP+$L5p zRzBUhGVSt;vK3~9W@~A@C?+kbU)pHZmbDySRzn`zS6uzMlWFgeoba*)hbp!av|5CGL^wqMs;%`1|(NV zR%G4fiR_-m^JnEE?C-BQH^Ejt1)gdeyhPyUR+jNTc&8p2z}cw2^G;&x0d7k z%NK_3&^_U|%Cp2dE2s0ncCqJ9mxLH@pguR(A6r^erut12W8sRch!62e{eADl6yH+ zkWZp0PY^5-P^UuM@mOaHAmKky2mz!2)g-`4hoD z=me%02=Y5>$_ENA6jYob#4An^kne!0w_fmO!FvS%F1S-LjN2#bXA2G%++XlO!6O8h z2=aX(^PMKh6~`!FEqJTo1A?0cKM?fbPK^5e>YW%9oFzD4ke}Hz{Y1eHf)5LB7W{{x z7dL{`?6p9@aM z6LI$M5rP*8UMaXyFeO>*Db6MI_Z3-jE+LN;nV)6T-fY3c1?LNv3pNU#D|iVJ$Lw;! zD~Txk21);o$ae}V&LzrGoJ;5_&L!|^(f^y^dxD=zzJCga@m!qty9q{!u$Lopf5Ckv z-mLk&pTw)RpP_%C$Oj8z8fwQGO~~U!o+3D1aIWCtg5-uVf0^Jhf@(fR zyyCC}`9(VQP7yp^@W+CDG|%+Q1lJ2*CwPP4t%Bs5Q2#!`2L+!H{G;HTf^C9-7yL+Y zr=XYfChYO;1970>5W%5>`wJ?!5zs3US=+hUgy}9%U7xc5xDC?~|BJ(~w!Zj_F61y!+pc;{<2C?0e!{*~kJqit z<1Y6`$Y#UkiP|ROud&UDSFj(6Io)g~jq^5sHmvcI@JhC(4U)TxVWQq|v0evbH+c}W z_QMZBH`7R0+Co5kW;1EW zBEoGiiVo#(6z$t2k%-iR}svBx}az1gVWvqlMM^x_Z0iiWr62p8{W4eW1~BRuXCk8p&O;~e3_PlCb` zF8svr;s_UhLRPTh2p4|h*)2yns5ruZ2y2e;J)gAa2;cLGryWQ5o=l%&eaNl{{oKiTK3hyg(JM3U7X+ulM>sGBm6c8-tIZV)zDuZ zTaGTZV%RM^rk-0_**77|#Swl6X-VPTa)h}KyM1y;9ASPZW}niYBm4|(+o!hY2=j56 zz1DDqm$E9S8IJICl+NgYBYZ}Cj_}hg>&*5X;eAzH2OMF|CFZqlCr7w*HEiW5v!AR} ztrjSk)vz)2^gZsk#S!-Gh9kVv%@JPJIuXUr#SYr%3A^D4x9o-^>~V91eQ{=}*E+%P zqJu7A!`g4;<9>@A;TArg;A5%w9O0F0+6)~{U@Ji#UPY|Y(aQk3GXD~eu&Nj| zsw3;UTaK`*Zj06+@G+BZb#jFDi~dfIu($}FUt3nbq`I!s`o?7ArWH+lW2B~f(fq~b z<-0g89bHgdP&D7TFa4%<>d^lwUku=p-FL$gKCP1@{Qckve;3SP3_I{R_nIFJigD2h z5MH1Dwz0AaYe{3}nZ%0I?P+yoP4GinTdCa8f+JcoeZ~~5Fo}&ehKtnaS<^O$)_5 z@oB>1%4WDDuB6XtYtnx64{NGyY?^;eeO*~yb79f^#nsL8C(S%$`XQymHO`-W$n5#E z8|#mOH{+)HQzuQbO3Ny+NPTG&i|KUHYN1Q^iw)$|cxZinO;fC@zA-kTu{JiPc2Q+T z1!&Lcyz%3!nz+i zIl{Uh{)afixL)hz2xB@_8?SM>f%4eN5yqQWP+~hd!svrejxag_n>j!Bnj<_?QG{bf z!$*xM8Z~l6@oqW7g~Lb0xGhXxJ!M7-ygBKDRoMgM_(y17DoOhXQLFzyWo2B9F~1|w}MEP9@$*^F+37=Dal%?a=-ExEPMKxXA z-~~#IbA##nbZ@!A&%;EV8@!BVC%C~oP%jrZ_yvjyZt!zdPH=-$S(gMi_!No>Zt$JV zo8SiX`z#kXn4j(Lo*VoWj-JbZaEPMIf3Ob+-R(bEEwjES|H1tDH^B{7{hi%g9q_ACb+>XSnGuUU|x%UU2gC?no9T&?n`mE{)7L>Y9zS9 zbPDO>23IgO!3}&_kxxpLQjV^9*jOAkud*eU&*GzYDgLz)H;|71u0^Ho-*BRmF2472)ZvVkY z(8hP`KbYsC+kY@+xBuWH*^S13@Q=}eg#TbQm$;9)G<#SK>LvG2iu z@b7t)UEJW`vb;U`5B@#N+aou40xh`x2cO2F?dAr*%QD^mgZYJTJ8tmtY=xT}d^shTZnNLO*CKP5o|4!%5U2J<}S1YG!2Go!sEB&JDgAgXOFG55`Gnwf7!u zD`s$i6~BPMlOhOa=~63aXjUtwl0-~#Rx2ewY8RcNtX4`@*!?fJ-NST$(u zp@ys_H1<&0Wm!RFrFasbn`*ZLF6_1HVY zAq+tEWQX z+7q()k3~kS;gH61orBW%$OACl9b2XJ*Q~48ZjJ&+coM2xTBkfXFGtlmVN^8Lmo5RX zpY7H;|I7Kj$BksOJ01U;&m;E8>E$Kle~RB<`j$#;zC;kA@1x&ezQe`!x4K7c@AsFp zoSV`+ammp3HD0|ZM1X9^xF*vaSB{nW|l)&0=P=hgkt$>-Jm@W0CERr4pF z^o-#=37jOT2po|4436V$zE+U0XDP21JX!EuLB2+1`jvv$2>x2|cENiD ze<%2;;FE%X5qv>#n;>6g(EewF{NbU@Hv+@~g39+gLzG+eYBDhlU z1VO$&XZqQK7YJS~c%|Sqf;S5OO7ORW^btfm4+|RKzPtMHeNWOq5d2i|pMvy+rTR%Q zCYUEUSg=rVwBT65$%4}a{Tz=0?U$5xxeS)t7l%r1eeoCFhihNG?W)H#ZUeCMi?%P*8w?%hahL0U#B8p(Cx{+EZJd)j z^2a+C@$`v09y_c4O~EgiRg}BB{h})hi zi)hXP>duB<43XUtMi(i2?01&w>MpAR;}5Fw&Ddiex87x_-!pNoL>tXRs;Z&IU(p|L z(Xhf8w=d_~KERU{ucmZ+HP_bOwsXw;w*^W{w_Fzf_#Jy?`KItT+n-VR8@^cYm$ucn z@*nR$ymH&SX`fEp`2M?7SEg__q0c+SaWT zt!-)6V^0Oz!jUX668diX$yRISt?$06%6mYS7Xl+U6Y<&-ZA>=t1CtQ1%T2^rmi!Jj zvKPL8_tKJQ-n2GO#QS-D9DO!@{-^#4M`4`&NVxhRZ?ycRjd|=K7k-A{-hmi0@Z0+W zC7&}AlD9v@vwF-!K94W(Cn^M;{bA4(4D^NZUHtam2R-m{XHY%pb7-L}{(z6mcY2O* zJ^uQWVAJ+?#VGWxmv%GYc2|g~fdig62KJGaPhf(P% z$c|2V9I;&(_A1Ai-Bl-~T?ZxdaqnjtYEAf}bcV4IcvpD#2oy_+zR<5wP4IDb1%jc2 zm6)N$)DX#>;NxmBt!rtE6&RYLF3)l^&{1@jm&~igzhYNy!=(2pOpuRThnj`>2Yg)9 zz7J3@@Nu>13q3+{e-VSBKT>&&h^e8+(RlE2rSMQQt2R!=jL^-@dw_`15ZCVkA6F}9 zg>Giv2_nXb&J7(;^UGpqx*Y7H-^#Qp|z}8so%7jLkxV}-YPX1V#NZB zdb6Lrxu@IcR2oh$Kr(kJ!SRv8mTsrDplamfE`k`Ejz8ezGR%Uuv)ao|L9oO*JdI<6 zd|c9`yOuUsf!}nK3|&hbt-$SOBy=rZZUr`o6b#K}z3xb&Z)^JMJ%vTxDPr7L?+8_L zT4*|z?~=UH5PxgH$7L^hahU+TtX*FCw1hBi@rHMK~!XkMs_EqXo7 zGuV?mKQx&IZI;1SVP)7n*36oz{;(f1xo%1(<8fRZ9H=f#>i#T3nvcugiSQzad|W+N ztVln027L7%jf-ect}k*X)4|8paxk)t1%r>P<>ilUDGRMfry$HXCp4^Pc zzSIXFSEm<7?%;?4ANNL;J}lCc<-u34P9GIHlQQ_Y_o(zS5#y^@PbK3cBz%&OtMw;G z_&EXjxH^4WWES(oSMLKV|BMJ1r6M0!>(7p)v3&4x**WOui1M)tKJIZ!e_n*=75TV4 zmAtvX_e4Hq0pR2E9P#Ep=83$(2=Hh6&>O_NJ?bopfm$@a(ru`kYV3~7!FXEDx=Ktyg?~3ABSy13Hdi6BAMqQ zN1-~IF?~=@LH%UL3~=on@^QJ=Npv+Dp!m2yfJQ{k-QeR=z&RdykF5b8SNEVV5@HX7 zk1HbrC9>g;kLIIYU{~>RucE0#Q3LXEDbSSi^bJ0)mi>_?_8j=Q<4`;0tCxXWpe)ty zu_>^|6Zi-hmyzBy1wJl+&1mWhW(6NtA4gwg6dMFSE|opG!N^&xHTbyvnegQ1MR+4g zKCW)Xw8)XP2R?3b%IkJj&qX>Jx5BKhW4^|Yu*U;ud(yhAh|}#z5iNj^%Nlrd*V~a*)BqosCcU{=+mSa|Ciu8I z;zm1iE+fu05x3eAE=5B=uGYBAj@(QQ@Nsp-19s#AYJiWcOTkh_$x~pSwNicBL(8m` zk^@@qZ{SLM1t&7@Np@y&re{Vfsb3JjuS6-}<1#AC<}{#2HwM@(2s=KW=vg*T zK65U-pyD6F-(-%#zayY30N(6p>|*e7IrG_eb{Pu>9~YD?h#sHsHKgNu?4OW(pNc<@ zJqR)6<8tw`J|{qbb&OvfSuyOE9XkT0!!G^ElaJdQTDBc{8)-?|o~~&SyBvW(j!*xs zLb$K(utfn|6LMdoA#6664a+HJ#e#MwnX~&LHikX-PFS~->~24#+MHZ|w_zvSna4uM zo}0Uru_<;2^V^5yJwq{Mr?bFq2>%Vc=HrI!UW{CU?5uVk*9Wk}+Uy}1H++_qH(p2f zWLeK3;t@vj?Ty`4YxY59NWn*&sKfYv;dJnAdxa14ceUr*X=t4%LBjR6r|06wSb6-Uz^@Bhg}Wi`ifSrxatx$WXGZt~nki<0rztE%Jn*NZWL z^Wu2*EQcc;;S7$J#72T3Hbi*hA*S-l0Z5dDH0&Tz`dS(2t>S+`7^CBxTN&V0B9vN` zi{4|juu73^Pl5nTgwu6=Ln{NkeF2Y^aIK18?rUY>9xVi08Tg|XQd^%x;3e$Hfxl*B z#m#QzAa)pbkG1Y#BC7>1Z3FQ@i6^qEh;Jq?RN-|86IpA-w-8xD+Bpx%Ixq~-o9Zsy zc~a7U<8@#ZyNPu{o>_aUldj*oS$nFVuIsv4d#Wq%BUl#kDjhzUc#Fgn@057rCW$Bh zQR1HivU_Oj$+Yas7${@?cfhJsyUGZ)iV3~*~@Q@1cmO)*U zqSi!B3S9?!0W{QxUjS6hY`v9Ks775Q!l2HwGPHr9F=box6KyKweTdpP(A9{Ew}q5k znj}TpYc;QGHC$x~Ev>5%OY177BZFB;)OEv*E!#^b(1AP%bGFy|GwRVv(EYdg;N@ew z@5Tr3k36=Ml%AgHc)Mph5q}TI_SP0SVQ*^8N%AJeoPc+Ef#dZTXJ$A_wv+1jHdm3O z+XX4n9z7UQV@kPb!LNh>OF zQki#BJErcKJur1=rn4R^karUD<)Pw@wm*hoF5-3VXgT2TNYQbM+G(XuMMiJR7-a=D zilX)G4O;U0hd3!fyRVb#y=ip}^Qvu^8vn5^^$nGE@E==OTG>+FT&k9S2T`)QzIG87 zST7@cuaO>Wxg301jq;V*juVGF{_mEzOU7R5l6pL)=+G^%az{I~*f4u*tI^o%+J>c# zm8A{Mjo|WCwlu>fW~XD`s)ktp;)>;EjaB)@vHV#>WBFBe_4!TBjn(CF=UY=<)>K`$ z7?D*=>)@KWzAnEB&P9Puh=Xs^GPhjSkY8S3*W6fE-aHnbiNTA+F@nAhtf(kkfrC&7 z5iD4H54 z`v?{b(j5WqjuV_Lc#zD!4)LKEVeCpAh_` zAm0YC+z$mw>7dMKh{PnpkRZLcF}{ajUqQZGVtl@!dL<2cw8-kEJ7m6SqMqUM^2Gz? z;{{I@JVWqY!3za17ravN=Yqc!yiM>9!TSUs6ntFpDZ#%Az9_g^@NL0uf*%TgE@*SU zM!mm`yW3av`U&O>776kl3+?+W`Ek~`S^%!>b-nn0 z#N{cH6tPzy6J(J^ZA_?VW_M$%CNvci7`^k=abz35ampd%$InzhS0+7a(l% z(1r&$7Wo~tcOBB)_MU+~wv+Wk7sc(ZN0{~sv2z;&g|p4UhRihX{C#rk-PNmO{w{yF zsAslOxVbd88E3}Jtq8m8_kydvXi~g>4R-;^T{l$~80YWyz?Tg0 zl{@R<&>07xanRx02h3iT71*{W_3U3AzCCYz$_0;o5KK+oW(U0&R!pp&c=-0guN=O8 z;KJk!GuoV_SzBKJ;Z-G%zir*{^BvwZ4r<%H(#rE+lzh2&NAe}twuSvKB4tCH&$qtq z;n}m^_Xeul{7Gwf1QsL5;>N z=bgwOyU?n&!}ky5os7J>xsxB;5zc)?@wQkPHB5hwKumUE8gOi zg`r>F{nq=u^t5j4bDrIZhXwlF@Y!$U1Wav&RELZ0T{qC0$qWY9nLh5|p_rZuK$QMJ z%oyMV_eB=pX*g@WBcqBF?QxFB6z@xiP4DO)oDxBxehSLIIm|yZ%2^F$>eHw-4!OOv zdYr4G0xw}w^KHgV>0KPXno&XLHOx=GqyVC-dkjL9kIW-qEPV#UQJTohAd}I#pArA0 zfx+pG4F3}C@fBvA%J9LMynLh5FJ|~%W*U=m1H#UB`~eH-JrwEV&4rWGBMX)E`}nLX z&<&NdedS#cF*wXx`*>mKZ&cyn$0#cRRyHTHB%l9UZ$0uP*Py=s>r=-w{3a~=f1b{G zD`g7)tVSr6`d%v(^#3gBI>_N9G{}EVK$Bms@DjAu{|jd(lEA{Wd~cv@{Wo}-)i;{P zZ|+5JiCuht-^0|ggHIrb!>}(4y20+MH`9(pRinWnL5v_P{0Fo@Sd`8%=v-uF2aBad zUw9T85-d*96$plJL9K(u8CpyYzl!Pwi+gENv9g0hQw~ywGSE>kqui9I@#iQ+skY&# z>=&?@7aSRUpJgA;vPTP>*9!9)NN_(9ec?x;65L1hzM48Gx|Mf2M-L6Lk+?|$AAnTl*}-CB<#nb z4$erT=mje~JP8LqcyKZs2H6vSit-$h!OBkAh?Ik&t(pv0_7YTWogF+ncqy%`{$9|H zVOl?(H7oV&KJs4wntSYvsH#fM_M|@dVhFQ?ztmbl45DpJVUD|Um*lMG~K2X8kcfvoJ{29bi{ zebL0=9ZBk>&P@%U$fE8PQM0mxzwNp~m7Esl2@||a@G2zrS}H;iE8P1)onIsOmgB z{5MwerEaUxX`l;-Z>I9Asp@mm+Ou|=-=evC)g;kvZFW~$jUyR`e0@2^uoxMJP*LiE>P*iBA2o}u(Eaf zsK{eH>R@G$SLtIS*YLo?OR}Cy#w*r#5UgyiKRLp#4uX}f)2BsJnIEj|5|w{OWGcH6 ztZc16JJN%r8LVt}4q4d~nGROAdX$wrFT(RG2v#;vCB@4Ahy{R^&2vPtviXoM2v+ty zl%QDI#cUE-*_R?gv9f3f>uS}LZ74tbM4?? zp%GDY30T<_aE?dbXAgmut$WZHY2*@qeM ztZddmv9kH}C15Ugy@1id)x1i{MY!R@sl`wFaVma5Ai2pyFvY6Z67 z$k=`#qq1yH18Q_*fDJG5mhA~?iQ_A0>s3-j$!~`QO7c}nkkmB%Z zv)@OhlqZom9AaPg1J*t&l)Qj<=a-UJzX*vH#6*e(>crV6_%4P(0 zeer?UGt?Q2KgpweF+p_Lk?}Tdr%oQ4n>@A`6GSIJt`o4FEC@Nbq05pd^kRbO%!%uC zv7GVLVUHzG>BR)mSsK?t=TuN<1CCbm^j=JWP7f4+F@mQ5PNxcgW|L=TF^g?hS>i;`TM#RTYliX-@X@rET@esd`XzR zEXsIM>5WN2St+%gFv2+}vEeJDj2D#&MrEVr6j9|us+)|pWzhz@Tn^|4B^oO`MB8}`jP zQ6`AahjATr&g<0S>!sxLqD+9!TacnST}}T55zd*$&bcVccv0EksG$G$rOL}ZnwLfy zFDeU+3i|J0s_=nT@)c3Wi^_>c1^ss%Rr*ooswm?{wQD(KA*&K%V%LJCw$m#51nX7WDISV{0vr^94JSI=d z{FCzxeh`wMmYF8!Hja%y%bb!!5Du6R@AY3F+p_J7@d)p(?FfAY-qCGiwUB0wb7}!oC~NEVKchey_g_6zc)JX z;qX)EVAdzY?!^Sr*@~b#wiu|+3sjoOQJNoD>S8$uQRxK^g@I^)LTL?xsvpzQe(LPUgHnL@Cv>hh zIyliTpw2!Vl0(scrIX#4qi9sSF8i~|@+2OFFiSeKjJ10)LF)Gzf~uvrqdVHDbS;O# zM7tMLM5!+_Dy5B3N`sJnCM!7A?!^>QDltj{bjNTian?_sVfSK+C>?8*UJhH%kyP5o zLo~OTPtD{E>7t!| zEN3W$>~q<$AKOu;pkXuFl66K@(`$=6&tm3jVEZnxqf9}b1~%xzxcCXHdUB7W?&Qww%4${FXKOYTNyz>&M#+b&z)+U^ySM zHcxV-UT~+xTlc$`nz0EUtv}?YC4)VsW?I zQKpE}wzv|8>MK;LWW6`oQKpDecf1aX_lE-^o1f4o-(^Rcg8sOJ9e%etI%*V5M~dl> z(ab_BQ}TUwlnJoQi;`NSgZ?<0I$NppJ3Gn*(K!#ncz>KoB`&9v{E!`GiYVP4S3-YW zOC=m*{F2yFrijuDaV7M}qg3Ljn#qsaQKpEJ9WlkBKi;QOgme94c9bci)IY9-@sSB3 zyE{8zlO1IW`eP)L%rch!{8u~51hIR(OQ)7P#XQ+ww4+Rb4ljhS zLQwSw?rNNKsq_HPg;(t?rih`3-AccqQXxm|8+Mc_P~vEO$F1}{m5O54@=@L&{#x{#@>%y8+&+4Z^E2B8{KA)P|_l#F2LUZ zP4u@tO6B?y%L_`^p#_7B1%&>8zwT{R?C~;VtLm3RAJEmvTtY;AI$w@1mEt`CnVtMs*J^&T`~iShePm{tP!a z{(UVXclo|HPrjv9>gLngc5&#^{%)J1Gyrk&Wr8GbpgS%LgKAK=U6el8-Y_wRAN9^l zIU?l;>XYJq9IGf@GVR-e4#s2wJ{{H{4Rev97*2qEREs6bhsPYb>IFML=H)oX?1)L| z_&nl340Nw`{9jana|II+-)^gbgpV)@RPk9K*t1*PX+W6BGs~JwFiLadO30-)G}WS+ zWW3^EZcWY08kN^dc?tFunl+J(Sc5&xNc^ALPb)Ky=20Dl;v4NU3%>9rP{YrhQ~SlM zfO;uf3)6$v@-=qyPP=ET(GF>CJWo{7(9xUCYz5dysOBvo42E^Db?&XJ8DLT9z*|>K z27>yo_h1D0h6RhetO78j$2xbsF@W%)CO`W8P^hR4YF@9!%vWK@N2vtKJe#On&v{vI zKA&nilN{Le_i1JDV(cu=XeE$!YQQe_qBqU}6#XYyS*;Y#!j5%$2&`WcZKAFItX5Oq zBvjXr79+}-wN;aqRn=qdWfsZZZ_PX3cf|QVQ-w6^!{DH0*2g119u$myJSZWgqB*J?*_Ecf3|C-R?QM3qm$B^W z-dJr24a}i|Rl2?H^r*u_n)gLLb9h`m^LuD=_gjaY??ZdHAk5uw%{||TD2Cs~o(^m6 z+Uh}D(Nw*8_bt*ERjTUvt!A67I}HX#njhF>#*6aoRqlV9cOP+SGE&_G7S<0rMT zveGEmmMOcKmsv`AeJwuTD{U^r(it?(A>rVXUkwfK2zs7(Ro>ch8yLZn4o0KKjiZ;`saa>8(Bhrf$#SPVgkBXMvN2 z1aC`>X3{g#oiu-j6O1|j!H6hKPj?FZ_^5fX)6LsVW8ne{nS}+;{sm6jzWBm;X@S$1 z(fh}of&wRbx)U7Z^c~{#*+Y z#PXA%n~RRgaC)M~{yt8=x23@8>BR@&`Rs_GHwmI@ZV-l5`-Y%>D9+g*?I}3W$sEHb z^vQP$Q2%@T>XaW-ta{7*O239$JRXqDm8shXh$O#@8Z^o_-I8aypGN|aP zJGuGJ;J))z3tm~ykFv*je7G&)(5u4dvh|HkbA}d`4lgR^(3n`=JhyV$^ty`5mP0u@ zii$^d6b(}EF5h$ipt5@LlIEt;;zE48-GQNDg`-F8^3iwm^6Cn#VKS+{vZ}PGuy`2H z1b%nx`V!owQZiy#DT>`ChV@gQi|-Pzs^N-L^(sBCXgJQH-F#Q>)@F6EC`bq}O*Q$PXTW+kXYGym+Lt2;WoTA~oI|^THdub7R6CW_k_wtox z_zbdkQDaSIoqWvfE)$i~EpNuBx6SS@R5ht;z)(=@t2A|V2>px%I326-wJo|6QY(3YCkKMHdZ!a z4z!kZy>2N8ktG?UUf7Ma!Akzp83YN8-Z~EmN z;OWG1i8>dJV8_a*{;tZgPt`~$9*zp=MuIEmGN1;q`dnK5Y3~7{tO*~&*H$Xu2)kHS zRctDmK4S__rHUr2il4+=?qMdibLA^VZPWlMWk2gWmnsu(B{WI2sw!%#7uA+x*i^T) z8%@Zn?BEOhrvGQ}O5md?@AhtXC%ZW|1PE-91lMpYLBfq7f`A-?f_RID5CVjfL&7Cq zc%SvCTCKGn_53`l^{Q4pDyXeTwN>h^_4;b7#Cldy>-RkW_nF;E2m;!}er0~yJoA6w z|9i|k@6685JoEf(T2D0FRly3~0PuX_Z#Q<<@QM)w({}6glAV%Tv}kp3n``Q77SFG# zuf}8xoK|>No4D70sc{vDBQ9cK| zs(L|cam}(?z7X%n+ewwzRW~l(wYp*PlA0Ceb%S9qS+KNj4sagQ=QS=HT;9}JKDS~h zQx-K;LBC*5?XC-|7SBaO)#B;}yQ2PO!)nUwcKTJ)bOW_n?G$Fx^#D^>5XL{IP0zVZIsg)o*Uh&LoIBZhja=YY5wLq zRf)_gl3zlUmw0HRhVmO{R5$FS$zU zX4tm^MK1iZP8XORC4WET$g?BSs-Nj6+xHV*!pD_o+hFlc zx+?pI$C`_$W~Wc=;1@2=qTYTGFq*EVJj$AYK#z*wY5nq!2SWdYp$Q?5TSWBDDriTdz$)v7vOdTfEB zM;lezsQbIT#qsHsKU%fbde6E^&r7A?KJlkcAkDrG)8Zk44DP^IhgN!w?3$ykPGd~l zNY;UxImJ+(q>|TUc4*r)kn%`iv+SJUE+P~`F#Q$SIJ35X|EfiPNWskBZ+V=4-EQWl z`Jo6iyBEiQ(*k^zq&O?n({t0CWEa~_(6r%|YiLPLU1M;(-2o8XBz_C?yg`i|i~tV3 zId%bM)`L+;AD2!LvA`F?4dXErC(*Q}u@nPGi5 zJle>%=4{sS}gN7b>6{dw9y$3 zC68oe1ulAcg!vIE)5kWCQRpQ33P-pO=KS3Xg_|~-_fKs6r6B#A;C8vIXlDKgi{juR zXXq;|;ZW951^EfnQ}J(7@&@JZ1wBs8IVpZ}?3C|i$1CHNC zjU2E~0!!2$^YE6vTQWCfX-9BVH@HOXZP83h#NO5n+IX%MSn!%tz+!!P;vHBbreKpv zh~QpxaEVw{`%Fp%Z>r+?D;_+!8^+Yk>6^*MopUUhtHF~wZel`5r-z-fg6Wx~l;2A3 zDMl8W=N40Ig8QEDnu9B42)=|N+o!fpPa-z2pV9{j#|kG2rwL742ldUCT`z1B9w$6m zc)svQ!fS;$3hxrG6|NJ$CR{K4Oqh>Bv+WUf7xonn5%T#v{SFXT3r`c;BO~NrC;N8c zqrzu|e-y44=3aEU!kLxqckM+#3D-YtAsxK3zVJSbm=Lx%NK2=^8qCae=4B|JlTvCsm@ zp!{31Be+A(`Z@@A5DpOTCfrMSs_;VLwZdNr9}zw){FCr+LJ~IFUQ*awI7~QEcz|%e zaJldl;f2C$g?9=0`U>lRL1+OpV4npR2-ANo_`kxBgweS3D-!M|+*?>F zY!I5}4(dHy_GQAGh4%}e6uv6_t1ygn0sGZK*j+eSI6=6-aK7+1;TqxJg?S(Vu)e;+ zrNR@17YHvAULm|)_)Fmf!iR-V2>Hq+>u(mCh7RlmPR&doDLhPgobW2)Bf@ut?QpJR zxj{m{SVQ|r;ibY~3EvdPaBigEPQtx~O~MO>_XuARhEay)dI%>9Nn>RC*}~g|&k8>m zcEeW;{l*IC3QrNn)rrJY2X+ zc((9T;Z4HT!pDR!2>&enR2T!%lI?UB_7qML9waHO!V`qo37-&t zAj~Ru<#UNRHx~#y5OFM*D8IMtorD9FK3X_g>C=S!DE&~`Rl<2nKV0@w;Yy{SB>Obs zMZ!yjHwbSQ-Y0xe_&eb`;fKP%3BMp>ykfYZ;`ZeUi-_3%F2Yh_x$-N7Bb7czI9@ni z`TGhFA)*~FtQTLihB!?b;_x#>cMOf30KcBH`wB^fWcjheNy4eZIl_6uI^p5MGlXXg z$)I3;R|;}Ms;h%)f!ViSGyv{;>1;P?xN@&-0$e$p4s&KmSAmO3HWx|!h z1WrAK)z&4`!%7j)%91|9|=j`q#yNu zh<+U1QrSBS`wNE%M+hegrwU2@WIZPd&lO%Eyg}$|YCS94G#*hd%IiR&X*&XoWLqRQ z*ga(T5$-PBLwLB5fqhudal(^?KNemlTqAr$_`dLCVVKvCsK*mB$RO=bLQ+_1j}nrv zN_&4HF3<4lrPCo|Iu|0c4a3@goMuB=_|Ei?m#vDQi-%kNai@Pt|5iWJwrO#3xNX67 zx1~4!V|S2WW6NNn55C_3BygSkj|=^RdTLa@G7sP8!>us-(1uWx^>`(>~idIcI$KSrJY;^!?ug1^qZ zBf246ir@J_-dwB)+dXhxD3rn=v0bM7?Jf_L!D{G@GWc;ti{Dlg>|lK>uwnd8V12j* zPSFyHtFa#J z-{pbr#id`me@|c?o7V`i<#E&(oYVgH5(Co%+5jA4=i*Ma(~{u$HIG?A3pe&=Jwu*S@U5$5_x}BH0zxcve$kXkN#nOXqO)%PHxsaCwdoPeck%-c0X^fUO2RQ z;*`Ui*Bm^wIeW(#$}MfaI=4r2uPFnYC+^tPyu*}X&DASEZJxifsX4OaQsCg`*;9Hn zUvu#C=2-6H<|}rb+uVCfS#z%)%bKs5Qqz3g!M&TqD~B}CK6q*Kg9rCSe}*-WU%9mT zDxkNrruo`~do}l3*t@y+%4*=y=AQVRvJ(AXI3H<4nlhlkR^Xtu?NG z0P%VoCsySR9f^?|&(V6Z-Q-b!#+Qtn3(@deOt}23aT8z!kD^u!qyyfCqc2VsjdjIt zg+|p;xbTBQ5~Z4=voT|`(i&COIJTqBm_S)+jViul99_VIX^pBn{s@l7Zbx}&QLV;t z7ri+f>$P3%@+}@a7Bxf}l0G6ys=wn>HX=!?ThYttGbkI8Bo*JrkBllh59!{M_y?(j zb?}dV!hdC5K15P>^fUaAy^T`gXn!2w2nc)(Qlcqr9|8h%J^lo884wtU5TvIN5O@#t zI(GuPhk(FIu0Mg65D=K@PHbdj4lEKlgw+< zQ}<)U5D=I}qj{|S=B~W@r1aFK^a;n8umsnmA0t23xywn&FQlv~0|J)-3mPz9v5Jmd zM;i(V>{^T#48evVAh0vz1s9>$v4KU-%rCeX)Sx^cWDB;w}ZeQHFrPT<2!& zz-})08^Z3Hz^QNtav2bKFs>vO5Lg8i5Lg{kKwxLZ3;22n0s8aQ~ z?a#KB3kycjd9`M7alvG6;+kBJ5~ZhJXYNC#Ph%V?J=Ko;@sZNMo7tn_0rvXQM0f0a zN>5R}4FQ2io0$#>>>5f31a=#c4hZb}JgVSXR`qoI@m6+B!4R6ywBOgvbUrv@dI9gjAt3Nf3>u}U_&$2<_59Oqiw-P!o?G;00gqrxPaVsK z-qK{F^b|Y9qMhs?$DtE%+IM0)_RC?&@|e~6R7^w{5SXKrq$dLcyA28@ui;=odg@Nw zglLlDcMJ&Z?0E8FHVo-0XXhvTa;iak%9Srn{tq__(o^s8#0%-EN%V*Gl*=EGq$(=| z0(&^pvbqmWHnBZOPr3Zz$*Z~7Aw89}{87o%*gmAE+^J+tvIhH~0fC+W_#}5C0|LAJ zNlB`wGazuOm7kiVZV3YdJOAm)_h>_U%AROIda4g?NKY}IXci=gcw8|cFb^e@p1On$ zKzfSDh)GYKzywH7?Ti*odg@CYAPfk6I5Hv(2z(yvfb`Tz^DyZt9tv(JQBEkZlgwo2 zu#>LFzQ~R~4~HT|{KVTUs4(ElB!7QKk>%>+w9Po7d|xD()D&l-9n6xRq7c5$nDNgz zjF6uC6|nd=Y=8v>z6BmhJ9k5RiUyAHb46Ayf=1Dl8PG)2+VIY zR@IgB=!C2eZa+qoKja2MdWz1Jo@&otLwbr|6O^91iA_U#%5BA@*|5Y*+2#ab_d*oWFNK%=_zMB=_v*TcJ_+ou51s|QDIXsYLyMVy&A)zbJIt&QRo!d3Vv4ZpzTXpS!KgcXHy|y(65Eyo&8am^q3lBZ1NuN_sxMQXL`rs)|MTvH{V7&<;HXh% z>Q6ArPDVSBnPLXs>3$JeUC|fYp6x?k9@fjA!dOCPis^D0?YrPb^!{|Y8s#7}#dNt; z`7XzXycu-45<>%-DW=QiMBnABkhg>`zhEsxx-wlZ*J0K57jNiXNT2Tb2bn2m$mj92 z54PzZ`h1B&gUl2&N0Zhr)ZFEhmq`3z6{U~qcV z$8;$scVz~A_+0D|toq}(CtY|G5;9Xvm&-A}3&yXWF72_;ATz~uxm@A9VEoRd%g&e_ zkeOn-T-N$77(f1aD5L%uWTu!d7hd6~$M0GCJjd-mw8Sp`U4KD2$;^q*>2o{hL{$kh zRL_9455{kM7-fC9Q8gvZkk7tpAB^8P`W(V8*Oo9tJ}c5b7{B@SxrJL^SHcYVJc{xA zF;;E-AaQdBU2exdg3J`t<#M0zvUAA$8C^!R$IFVDE|=GQm&%a$JG%72p$eHPrpqOY zd2J2dAM!q;%SgH$Q_OU^@GNZOcP!>#5=PlE+@|A;nIWI4z7J)RM$(7!laQHWhI|^+ zK9EVOq|fo3>!%kpLq6xHeW3qy0)2S57&24Lkk4Id9}Ld5^mz><2AL^lz~?SlFJjdn zzsKkTfnUl@F4(e|Gvsro@5Avsl0JjzbA2&0M!T7DA&jyb1t;Nic&!=f0jNhN=^CnJIT{mr=YEGE?p-E@NDH$V|E8wQL4!`AA1*8P7V9 znbI-H?|{z>wP!I*?_j-jIXfQ;cVz~~i9XxohL%5v+F`x)7IqXeQ_PUhINt{{Q-kR9 zYi=lHrkEk0`Mys>$UA^OuXDFSW{Mf|Im7pP54)c}z1bhgOff?~w_w%g5oM+>qZ64K zl$m0VoYtkC@I|neP7IksnJMPTX@l=XnW;b1i5vmSOfg4J+v6UfHFtkIh}6L-J)S!Q zGE>Zv(>Sc!7(r%g5Pdvu8)T-KA)ooa4-T{g=(8gy7-XiHfeVB$*g?ol1%~WmzsQpz z?{pU7{Y}bDF+aq49*zHOa;DbNEfiJr_9tR+^~h*Fvv_X2OBn*TLPIWXWHp? zWU$PRFiQ95_CaQfIVjVa-y)EilDU>$hRl>Za!Yq%mmxFdzQ;>V*A6mM?$|9|%q@V- zlsmA~GE?s8E&Y;11(~V9mo5nkZVPq`d3UilOX&oeDdwOzSF&@EnbKDC3*rmp*u?!R zQNetUg+v+FOJ}m*keOnJd?sMkwTgv=CkFdjePEP%|E+dFo_k&mYw{&;-BB4qDTW{Mf8mlq`id>@QQ3hSk&nhKdI zX2@qhtft3fJe`)aZOBY9M@}o#P8g3`I^ozcnJMPT>9VvF#^WqHHLy#NnPQHd)~1~> z9=FlyOYUpPOfg4Je@;7LJf5S|bDW-#nPLvcqZjupWTpZ$ydI-$rPU6 zgMkym)0{P<=YtsF@ZRRipR)b%>4oUk;k}Dk`U#j1;nVYNwlh8dR;)LnnZxnvS!ZcQ zOgk0!$@ui5)YJ^C?HZUrwIqm0&1lcs@GCj=Fq0@XHKP-gC_exOIFjhqg-OGa#AmF% zDK)i^)fMIQieBTPHMNgbRE6wA@#%Rfw`HdJTnL-A)}Es=)59}6vZ`ybas2&-gl*DL zxF^{WIz@S&lO+n{w4an7m8ldB$AA@^M_$IGiv+CT!2;V!|4L@pV0qjw=oIdqPq$KO zFj>7$*Qr|+ZI8~&%bVOWQ~UOPpodk0lV{3Surqh~2GUS?Ced01s%IM_P`!eJPi+Z9 zm0$pD!Pfx}-J>BygPUxaoLJ8%+Or#^2bW7>@OnEdbk5#H`YaE9Jf`nQeWQ5dc2BqT z>d4?Ka#>3`eol7on0DDB@4xkhLXGLul(<^PcY{0+8n4u@v?NnvA3Ffkr#YNZDi4u?Y=b)NLl z^*xC6#QH?Pe3oe;1-!=5%k9f$QGZ|NgqlJFdn|Up6kSoAEFuxB{&gg9WQZ*6g+89x zcl*l%t?l8r7KQ$k-&QQNEc!{brQfV#c3b9Yd_5FB{z#jDCIE!T# zkEQr24%t3mwcE#g_bow*Za|dnR(2V4c`DwH``7xw>A@3cw~zPii@&mx%b3qLdxc>Fw>RqrxuNkhY;rdji=tINUk%18}C%YaG;<%bXcIw7K2byd|1YU}?2a!pM~ zG;NLM6Z9k4=T`DarqD2}_8%l6)k=}7#p_Bg>^JtxMk-5LL6s%!8mTN{Ev>SI^|ZK7dlCix&0yd zGk|hTOT#epQl6JR6|zDol)amm0G32L_xJK53+Y&aDk6Quk$w9|`av!!asU%|Hn&_V z2kqR+E6Q%?bsE}l07Qy*+7nqrDOR*o1w@?|_xDO8iT)n`Dt7idM%tkttc8YZC z4>hJa)&^yeiYVqpaic_}5XJg?y?6EsBaN=P3TP}LwFEYiqD+y)A?QSdszypLWFq@q zf-YHRNhY%h5>52)D(8Gxd4+2n3ROj(R|GjJ$Qq6I3c7jW0eGYAzfIdH{U$VCf(^bI z%6GS&R>3yOqktw1U#I_9Ngnz7MH}xHzCOH7w#dZ4IDg%{?Av6EoEjQmf8Qos)TWM{ zCQCq$VdGcxDX_z1i#kL>J&P6!C)*T={>=(R{rm5XznKk77gyKpyg4~IcfscGbzfpe z>O{eJ9H<20D?FHr#MY}7&9iEqa>_Q*qIv1d3pbqGM2r5}qD6s=h4k3t`*E9sQ9xqu zh<}%YQDEo%XDJrpB)O5etErrBlPTJ?hTAroqNYaZJkG0y$gPuOf}q;G2HxIiJ(>O+ zWQt6yCa6=yn|=Pmn|f0U@=uJMly!1A>*$9c!c*`66kVdC^bN|)O-pXqcUhN+tCgufR4LHL&NW1)u|vTU!HaIkQk za35in@EqY!gf|NLRGjsYzE6zf5V3lNLxkgnGlg@6hYN2Kt`@!^{Il>=VGOsAS$}6? zPhq97UU-b~Ea9cXp9$|1{#N*kuvz$bVF4yQ+p}OwK)%RCd$e#b;bFph;W5Iqg_jF| zE__f}gC||AZ?SNd@Eqag!h3~}311YxBV=qa*273w#G%4Hg!>EU36}{^7XDCpjqpz4 zBf{r|e->^Kl4im7N`&RY(ZbV(7Yo-3N#9{P@CpqXr>)van8guJBIb zi$XrZw{pVC!aCtm!pnsZ3I8H&hwnC)A1oXv+(%d?Y!n_VJWKc!;f=z3gpUfJ7rre_ zfHJ}MN`zyD(}k77dg0N+Glf4EUN3x7_=+$KG&R=WOSq@7QFwvym%>+t&B6|yUHPHH zLxih@R|_8%z9;;-w!eq)d%|;scL*O6K0(Ae_jkf|L>#jW8OVD6BK%aC&3Ceq z-ku1*PQo6-KEiS${D#XOB^;~tsj{aFD}~j<#lmI6&FK-{BftBFYl&$8N!d>epHuo9 zvi~H+8L@@l2~Hzsbx6Epxf_JH34bBPWdh#MC&|P40n8tlLxy4X3y1wbSPzHS{r#zwGq+~W z()sR}t=6mN%s~){U@m_C2F)r&ikM%6uveM#8>cKHw?Z{S9y!#XftL`IDOd^tI_ltr z7!>`hmMmFZJ7?(RSNLLTwa}#r7RT_}vIG9p55sN?kEh_mJTATQ!S2|sACJq{ z?eaI7zi|I?>4y(4g+gQS;WBHes~@LP(-@&2+na(xVBg{5r~8`Ok*aZ3jT1xnm+{))@}l8Y*w*})aH5Xm(|Uo# z%XvtK63KduLsphY1*NR4*fmIu90YGjxy&F$y-%1Eja^T_xHp_u9PhGYheSO_JU|}5 z!XuBu0eUSHSSlX<4g4bO@DK7V7bD4wUXK6SufQoBc@nKao`nrWe$LFrwjNu9T*|X7 zL0X*hEbFn7L%}%6vyiZuL(yQ!voJlB%USd#K6&(ygz_oR(i0s^`~^1TS?T~;-9w4X zFeH#?dCbgcC~^fWydlD(kdfv$z(ci52K3Bnna-;qpU;vDYu7u4sei8^!^@+{Zb_D)ZfF!z-X8vu}JNnAzq_52Fk zq5~5PxkYal@Cb%HOJYa1`<5mfZYK=K5R5ad~IwEV%zB-?{Li_0ILq(BhmS?;s^QOW1nKIB>4sbox& zH?Aqq;{3-auVwp?XL0$Hl2ch8@+@nu{M2M4hY|8D&VPE6g6NcI;oxAHli#Bad6vV? z|G*@VE6TI*P%?QIsw+^Qg~y1=vpmlP$g}(bB}|@WHa7|KEX5cylV_nwCgoXpQ!LUQ z@+@AIhl1NlmtjBxJIPFT4o*|iCoj4R4n^Txk-`ZYaAlIeKW{K6mgBU|IHCMgNU*a% zXQ3U;IDPQA%tQZl#*7`nVT3%(0&HgSWNd)Rvm5}Aq@BAV&q4#oc#^kp@s*|#j3#qA zLXc~`a zv%2l%Sw6vqSn?F)P@aX~W~^!fi$b2o?Z;@6GoJD+bf!GZzU(#RS@<tfGSBLpp4^G`L!PDDx_V%eKNu;`;tse4$)#)$@+{77O!8WT@+{6?kzB?0 zAkUI*`yBEt9C6CCbhZS@vwThu$g{8qCeLyNJs{7*Domc`4Ymn+7MB2dma~`uc@~!d zd6vc83dpm#1jw`8NDs)fxCF?v@P{VlSzIglxt==#)w5SNrd^!PPMIBZb}!%dN$9yiw4Du{hX0Hh4@}x+^swxfTa_8_slI`SKcqZt|vkv81xO2N!b0i?o z!d6}T*Z75sL)m+xm9Q6OQc0Mn0h`^JV7Fr3i}FA(3G?9dkA;^k-QG~<9HdN|bpUEA zVQvBBS$O8dyN`VLi1I9Wrv)bD{XReka6QHs*}LtHe_psRQmE20B^NKn?*ac~Q**JE zp%gx$aOyBrh;Bd!7Ch&{Rn>4WH}N(U3%m^lAHG;GIkg{Ae8f)-1Y}y9mBW7 z*osijqrMs4VeG(A&SSnAPoB;?9?xyhk~kK2*t0Q|^Ms#Wyu+Tgp`73PX2}kF&JE=} z>6zFdOw#wY9OP4R@az3iscRYvJh_ zT2`?67X~|rA_aJpEpG(gXu}n3k5FFT=)4FHJFgv9nU>uVE~9X(D<)ri9S$R=m*`NG zFU#fVB|6oV8xBwI$n-pW6%L)s*E@LfPXzt>(jGMJs8`djSBR|^reEQce|z}H{hrdl zL;5v9d35X)qNYm`U*B_Wck-;R|AZF?wRJYO+`6*<;ob86UDG?ieYit-Ozwrd+k1)K z@t$CMD0qK0RKjV15B8w_=Rc+gm!SPQCQl^vGN*s|^MV9sJ&!H^jtp;(+qgCF%7AN; zd9TNRJLbRc&7H>Dxg^uqEMaUrgc`yq|7+ge3B07!AFtaK;U%0sv%=Wf>5ytG8X6e@ z4*}H~TC>uEm9-3GZ4s&w6KQ@u!X`6dTZ<@Vt>a8v&_WlT4x!`f8yLfL(}A89jn9G% zGYFf7cqSv3BUW3Fg7wukE+Am=tp@}>cEOxC3fAnuvygc`p=E?*OW#BUWIxn#CZw^k z7Tbu%7Yt#HfS(!Wf2E5&oE}{lWw=ryg#&SZ|BDFnX*Rp9v|_F!4C4w0E}g?DvCFH| zQDQ4y+*u1Xi|P0^F=V$ocx*ZZtVNd;N4j#O=&hWM&=2_9sH~M+5r7q25sbMC#+e0B z-GbPsHf}DaX*vw4o5u(e8YI?MDhg=j^2N1F5PPu7!sTuvUZ)*m>5~!&|n7yc+JR~ z$z`Pw9h%y9mb$_Ym$Y zG`=G0nIpSa$md(E|0v<TVNc;uAypKaf1t2dn2*Dl>0N}qg~Nmsh19L3pYalb$IJeK@Lu5)!k2~X zg zIe`8hh1&_Y7Y-Ei2Q&Rf3&#to?aTCog_jE76>bpn97CQ*wvRl%F-C<%q;nx+dKtdU z;}Lcd?F8nn(zhzkQ98y^i<4%MUt#YnY?9US9iegjyEq*EFy`0|_FV$7=i=Da>4p1> z%Org0=PzTh(hK|9U;MoBNWioUjZwxIczAv}D#5)d`?h6$n8qP~$M|Ki8k&c?c%Jqb ze{~)b{B`C{!#qiGMT?&|2X?UCOK>lT^N#JZJ-=PvU-rvjHB^WC=;tqf-clq4>$@>f zAEtY{zB91ymth@8qdxN8{l#BB1qs3WR--=li~Zwx`~ABR>ny`NsQeNaV5Z*GFWVs4u-dh552$+RD_&Yn!0oGw9#rZTRh6F=WtCM~<-n zo8?jr893azZ=Or>$2PeXC(J(KxW=+_u|2+_+RE6#H4A(hZ3URAm&74e<8%ZgIFpa>wtz@aVq#^9|3ZP z5pr2gzm6nL;C_BKibgu%ANUn~YUV}n!vE}Ua0*A-VTyrY!NwxIj03-d>oJB%Cck18 z4C7aLXfmfKng_q)4@k_Jh8n@IV7hyv)(LBQ^cTN^521`D0Dc9JKHT+B@XZeJE8Z{@ z{EEj};SCWMjg)Zx=C0QukNk>5k%qx~2PN8ZJ#sYi!LOK${KBj7kNk=k*@jUMDmro< zZHQmtT8t*{LN~#$aArI)*32Sj<|js@4EPn!^!XL9Sw-Ym@cC_SE&jcak8K;;eic=a zUvV;emN)?az^`x>gc2{IU*K0bGwL41kCYit{FTn5WacNnKNic!s@t40{j!3a)e18Rr`O3Yrn}D?X#Wmu(pAti%*d z0`M!ip^jg%AJ*Q4w{0@`6+577#;+KFX5Dxn)`9D+oma=;SNPk^6B+mw?lFIwU%|l= zzk(I#k~+bUTEOF87~oeNkFJqlu@YutKK_AU!F4v2#cnS58^Z1xfTjwEqOasve26}Z zU!elxSEys+S2!!puNa3a$glV*oBCyrGt>Nvy{zRlzrvL*PF%uGT$9UD3h*m_fbNlB zu^sp0Bc=D6*(1T1X27p_-ON6T3O4ju4#jM5RS z%TMqtI@5fneMd9X{0djq_{3A}#tS;~rX~(TXTh%^H6*M1^u$EwzS6-Wpo3rWCe7FL zDItuoEIz-2M=<#nyR)IUG}*|nV24<=ll|j3bmBAgPE5ysDMeO0W_5lQ{~W)9qm$-W zxD5&=$8j*guUKlE5OvSB!LM+3Jh_AogJ0q7{NzGTHSjB3`NCus8YREtXZSWDzrw=f zfM4PA2PD^^dGae9|6y>Flr-`yT>kLnt+c_f-~-gG?xT`-qWk1mxKqiPWSsSbU*Y`6 zC;8$T`4ujIQnHTa!LQ&$*R1YSlecgf!LM-s(~~{fKKK<-4I5zmiUxQj?c5E11q~eI$uBq};8(a2j3#&DfPi128G#nL;a-&0 z7xQAn_!YloRr{cC7iGWZqlfLoB{4`uQzoSorUID19%0k#KzMK{~$0e(e)O8~!OBx?Y_f<1_I zzdW4e3i%bR!uS%VTl^xoy}e*4vc>A$_QxQLG&b^YbMDJ+PghJ|V^`eodlwkH;sM_*G{{W+%nHg-i#)tuT{|9oB4z}>ToA^&D}#jf8ec7+HPEfgcShC6XMMCb5y z9z~Yo-3N$~RndYt-6j|mctfIMC`;gNvblqY18bU=E?QFgJ@=TpjYqlLm=w_YTT@py6rL-W)huqpeo6C}>_EWOcSMX<&on98xS&#mCp$pC zF*V~G5i$JkWGGW6BWYWLF4xq64Pp{V+t?YlPydbVjFyzQ|Ie%oJ{#B+=YkhY+c+2B zoO8kPYm0MXr|pe77dRWZ=Vaf8b1@us@LB2}!fC>NgtLY7h4n%{k7BtKgr^G67yeXu zt?+K4&$)O^_OrtE!q0@;^EW2yH!Ub2?}*d3-=4tPvKI=M2~QASF1%TIpYQ`ApNX-) z0^BTadC&HVA_X?j7zARiX{8E^}-3iuHDl8Z7Dl|NzxEMHV1{5;3aWSwTg3rrg zhHz@MrJvThuei_;(=EN=lwivw{P)W+VH7{u&;H`)jYk5eVQ7pps2jxRpyV82YNVg( z?~8T63|&{Ct}WqWRD$b}VgW6F9dlp@+kL47^Ac%nm)pbbAo6yxUk0n8V^JUd{Kd~} z&Bb^(P#>m$y1p~8?w4U5XQRF?;bMG&`q&@#4~I^=K0d-^eSEIL<*at0&>8;Dfz3RA zek%0+x`6AjC0va2;g>>LfARP44M+%%UlhCpfBcC4_^rk|zJ?n8^0%YD;M`*0xDfF* zm|ot7-oIg750C#T#P{j20Qo7b1_`R$W7~7 zXs&s|9=v`)&-!O?ENM>xJP32jc;L5k@`x9*@S15*han<+px3 zwkIl#w9vA^{d`^tMBA}&S(oF{h!;H-|Fb_uN;vvw)E4PiFaar1POHdbTaWS0>nQjY z3y_8?u8FL}N)F%4ja-+14cDi@Bl15TneO-%Z(${m{^VCguFT;JsR`0AB3H+%kc@{W z30?(7uJ>*;Ga8CAY<1*@2#ZE}oTm9Ur~;d;8(nd679Gi{UP$b&RwP=zwk!< zEB1DdQ|U8t6I{HCj;8wQ_!ZtjwHQrYj&6Db^IQkw35Fu~1{OIpKd~I;y@6ewY5WRr zP~Ojxh^Ms}s0moh9f5zp!pF7^ZT|{Y^zeqo_eZmdbJ+HXoGSE(+gA!dZx@--#OFx% zM#_vQKBDs|nfZwg+@M`$7AEGhYolcrC2nWg-DDOge#Ek4WR@iUmu1JwO!@j1-jq16 zI};?ddVA*DH7I)ZE^D5eL(}*b$gilS`B3Q`j3W6J zNsjg-rQbKRM`98O_tC_yX7))8VMCAQJYlBeS9rfwLylkJJ*f?F{0i?WwL2=oYg+H= z_D@^cF^Ru&Jf3O)hMA6E;XSLW#v8H7dqHKVCVs$~`C{%_=qvdZ$*Bf@g)3i} zycmso;8z@jZzb|8BJ>Bp!sQQ0@<)aTeuZ5GcORS_#rD9jaQVZNzoHF(1z%q$zv4r- z4}OI^m5fP_W&Pk+IREj<$Jsvk6)t~L@?@3=zryKbOif~!#;;h(O#;7yuY^Rp|Itg1 zU>)FB@PV-OD|jflopcHYB(RgrWaqGx2BS}2bO9WS!jv`Q1P!<{$={#nnG?%#+Gd5H9wywAu8<6jH56Ah-D{1F$@GINg}A~)QNvif44nG3w#!g2mcOZG#O2Y!Y9VnbEuuqgNy&dyFAz>#aM zU%{Vs>UNi>yj5ATS8&0V{DiLHSMb}6^OUSF5Bv(ZAEU`R+#v8P=uCdaQS3GN75thY zzk(bm5Bv(Z6_b(!*){Mh4z~Inzrurl#hz##$6NAs?q%>R+yS>BX;0t5uW+{GS9s8` zaQ2EMf24chS2Ux2p3zOe!h?Rr-z@?Bicah?_!aDd@hcjz;(=emDvV#jmpwf2D_jEj z6}Pby;8(Z=@GGd1G7sGu~ zWj6FH_@jIKdiWiix)fU(O5qa^a{w{fgN0z8O#6ind}eX`}e!%O0t$xM1nBox&;r?&XulNrM7@HwRxJVKhGDU>NSvnmN7VGJVusBNnh_Faj z3|O29_zTwhRP3;7RQ`H0+&>E;9{j5Oi& zFusO3v5hcMwRm3nz*PC(gTRBRZz#uW^R?AW%BvRDRw2^Kd?e0WT5m*&AVK1vNtpPK zb07TKo_^wQ6aGI{kK!AV9{vgH6C~CcQ$mcTmeLC?bSEn3HZ@c(0ME%}Ja}FWRaP%s z(n27|X_Nea*PHn7VKlgV?3>~=@M?AJApEN$@iAnV?%uEo<XFa^VK;*P0@>L?@p2Aw;3gIcj9}2G)-Y#qwekn}gM>y*%6_yKk6;2Z# zDy$P8E&RUlC&HVA_X?j7zARiX{8E^}4FtB|O}Mj=a;Hq6A^b=f=ItV+w-atJ+*vqP zc(8DxaHa5S;T^(ip<9YnSzleT# z#*4?=W`A4V2%ZhMaTVONaGVls2|iC|0*2m}ep=_g;zB=6iS&X)-wF zZ^~c%yzxlDG_!o>EyArEi|A(AeD? zOvm6TMnsVTw?Fmg?0t^kaMB0Sg(q$}{)4R9CvG_L!;?0g@Zll5Kk(=9;GDY$tZtkb z>ONrgn%NP>>X?ZG%#BSnd(XhJn*S(S1DDuOMW3Be5I6X)qQ79}Y&+ zu{tI&CmOS_?6|jrR|4@^1uAc)D^Y-oqUl&2#V8f&fq!0$SRG|>3P(C%+GQ(N$5m)7 zTd_LGuZX2%b!0162gR?l6|18XHD+%zR!6pCbu_ciOstMqF#y?tSRJpiLdELfl~MLa zu{v^*>SA?Vg0;9}bv%k{i{pyb!8g3)En;=V2l`^~i968EcqUfIOf%E5I{0d9yhW^z z_@KPsAklFhn7vV~j+anHkGNuW+`zUou{yp$zv7u#9dFXi#Oi3rEy%>`ApazuiPdog z%}lJ0-?MBcRtKMc#xt=x-epxA#p;MFRtJNK#xt=x7@IU6h}H20?Le%KX_y4@uZz_& z2wgiT96vP9paKaS?@X)?UIE85u{v&Kzgx!Yh;MnUj+5B6xMFqiQF1&JtHWbAH;UCk zC4&X=OstOhogL<&9G>@(>k$8iKNHAxh~Fj4aUJ3rt^=QX$6In8;w@u!#51uv9^@vr zjMWj(#OmnB{g{c>aX5ROiPgd9z44Z@I^w@oP!Pv;h(DO z&6cq`;?Jt8@rftcjZCbL6`bjrSRDs3HxsLa&*S1PV|Bzcu{tKOp>GtcgU|K)MC0H( zq+@l&!F8y^0P=YzcT_wOtAk&lu+yOu{!v;J06JD@i1po zAXdi#Y%dV2gGBLoAXdjqY(EgIgU`0(fmj`XV*7zu9cQw9AXdjs9L7Mbj=pR^5UYdF zsN;cH9Xzh$!B`ywSz$0%M;9gpV|84~D#3L~$LiRNb$qvDb}S6gAcgln~K#@jCu>=;5z&iKiZP}ap!~UK!cNu+_-okR>vw<-J0vb za1IJN(B-K(xDFPpV|!K=h}Cfei-PO08yX}7gCdvlK&*~)xeo%dIw%SWt)XxD96{{l-u7kzu;8`c` z$LhG8ecWWMj(KS19~G+u4+%r@OstN1Y&aOJ;}f3s;?X=b+3g4DqT@Q`_^~=pfd8?n zt1#%H6h5JFisDY-Q2Y)_Ihj};e}G?ZI#x$+AXZ0i%UB(`En{`$24ZzQ!a7>U>d0*w zt0T8%td88Ti`BtaczTb&VWS{2aU?Tm z^xR%o%ebi!3XjY?2tO2ijYL|n{`l8>68`OhobmXC`p_4D?jL`)puoi_(3b@cfz6BN zzAV^?m3n-vf|Iav0zR&S4p<5EAAYig!lUzF^eea+_C@$u1-@Yw@K@GN_=I+34_GdX z|F**i6>(jjViC$DE|xS}Hiq8x~0;{Xdj)5{B0;D$@@!GNsnU+j)~(1%|8gzwrt zuca$4L()Dww&4>B?bJVP4I&l`1IeUtH1t!%6@|VjAMCm$6EhR@&OS#Q_HgTQVlSl= zcT_r&XM?N|xlmfdJl^>UhxYN)LSYYFy&i69{SGvneoF_&$kF8^4L(zsn_?bigYky#5H>Z|IP45*kjzjn#2anoi_ zo>@7>;jHm9r_Y+cxM3lrVwz@695?P;DZzZliB13Vm^#K6oVf(Sa`sqMHUHnMTA>v{*Voi=_j!SUSLAxU6PB_&AYhv2=hIO9yzl(k+$_Y>TA>d`ao= z2>G%w%UdiRAfI&7wpcpAYT3sL$x&dw#nJ)(Ot!_+fo(621G8}*Pd~meMx-P(afon& za6e&RR34$xxh04KTEtU@Oc-}DwS}Yx)#nJ&KT zHz>VzEFIG`K%aOUh2;hkv2TY8rxTICukbLXR}1G0mn;8B;fcaih35({5MD+^J68#> z6W*o#)xw8_zY+dk_y^%1iKyo-;h%*cEB`Yg&#l~!Y+*ZLM`4PH?Vl{fY0v7#VP}YB zL*Bw+dpwt%)TRA_5Qpj4a^VVjo`gTYr?YUg*5BT5&V@^VC2lbl4tFquyt(g4 zL?yhFiZQ|0REyX~Fw+Z$&XyhUpME&?+rqgJT$snDH$FIRY}T(Id|I~~tdnz<%S3$q zx@j-K=KxM%Eq>lO*f=CYW0bxY8^*_Zyfy)(IaV{V?w6tK{iy3SeO74m}Z9<@U#^hczzU5*2{gUDmSFN4+4WE^}cu4wV|cf5_u1s*T1Z<5FfVb9~)Q=U4r@7hbvnA z`dB9DcRu>}g6{HTXNA+p&HllLP9OYWL(vCWt1_%R7u6|r|B0ALZj7SgUtt6CNj^RT zN8O~rhH({~yC|=z!tt5NjrimSA`SJ3 zmLd&6hKXUXwWE;OhrQqms9c?h)6F7RV#b|;$is0xuGoCoi z%pzyzCn`|}96e{69uYWtpIJrJBll2snDqEJ^SY zH#mCEgdS0f-eGX`$fHOY32)C_u5;9fd&r!cLo>p7Pdj3#gQLd{gPoN)lJ*SQ)FY}x z&KK~uO@F|??l*+pGXPB$9)P}*qnC%0)FT2% zPX)x$Q^&;7b5=Z2&2HYEGY-IbPY<%Gmhqmz(VJ&27bXs-^J>kh;>1lf*VrggkLX02 z50zez?qxxbXc+h7Bc{iRsucLy*;u zS)Iusa2!33PLdZ0b7C^>o$2Cdd*gTRPqtF z500KYm5i~tKIG^*|MAJU**-XWE`L(;`z#NR9)rLz-jnen!O?U6)02C$eQ@+RIMgHh zHTMZPdL|AE9U2~2g+`(W4fL=@I>oRf3~82}5RjM8>uR zN3Vl5gMV!q#J9KGMOsuR#la`b4hstZ{Z96e`eCx6DOTgQ8P9nR{u$J~furZ_#$e(wBQ|J-VW~a=C9ue*ReVckjb9f-h-tMpD=sk>tt~~3IqsN`w^#S$~96h$` z+W&)J2zo^4!xbDoCMm8H&s&&ajOYZ}D|D(P%!AKA7V@#~MHyTzmvgWTrgZ>ZI=)*> zjvi}(9?{`!7#zI;W-#**Shxrq1l zLo=hvKd}(vJ<(P1o^lcI$$4A6r(DE)a;C+5%0;{M^}?UFYV zl(8^=btj>hL{ghE$au@O*gOKPye=KXc>(jgq2RQYBt4_w?U&t(rze75@4PTs>U{#7 zy}n$xD>cGSZL;(FZOqOqZ^_QlI?dfQ_amo$XDEPPUQfsPJ2BCpTt3nOvm>7_ zCJ!(YIW^JWc!6Ioo-)D98DwcEBvRQMk^gcce_Kq7pj8(6D&HuA9WxX`tVYAxk#n2E zZ4m=2+9C#KhIfz|Xy&$!?W?3!cf29Tv8#ZLbh(lB5b=8eacdc$%yrgDDdEH>xOBO7xn**GO z^m&cT2A4NAmd~vi$`nS*D~AZst_!Lb&qYGj;_3yvqW)#WYRc<&n%9^rpFel`Hp#Qf zrn$9qdHxZtI8-^ms;;ie4i~Hiq6XT*^6k~lP>l;vxRv4FzDpdz%;^VbnEL7(cM5V* z>%JSY-i&5gF%C%$$?9sioD=YtZ)rBrL(luU=7w!}&##8u zPUJy+4zzK6XCMw_UDYB!)~;O2ubU9)!n>sU@C>+bL&Kt`)Vzkpsj-XeQWNUt)Xbe* zGdBfdadk~oQ^Vq>)QEDP8_N$L>|Q14`)y8`xMhaxy-o25c^xPo;r`orguF6#OT@0I zeT&z}g&6~D5xcU^Bz+x^kYn5ikFa%!IRE<3uJP0H;lNYbS{~tWv`2o+9>Qrt{`z40 zY+;SCNw`vYobYVn`NGSEHwu3#ykGb`A>S@!J8uZz6Y@n=rt_6r;xM6Us=?l0_8cL# z0qDoar9{(K1O8a{UBX9%e-P&4_YD1$!d}85!tuhH!a2gjg{y>oHH!6ICZqs9?bX7^ zg)a&Dx-|3o+>yu|@I;1UAr2SL7cLQ=ApDW=DdDTaFNOJ0S5H^rj=~YbNkTpiWP9fc zd5f7gZ)Xyp6jH#SHXrv8`E-&vl((0F6NLK-YlKUMCkZbQUM;*s_>gd&@GarT!cFlB zhu}x9wJ+qo3EF%qnn?KtB6TN-KN61OEpgbBg?y8r_I%-T;rYU!3U3uYC|oc6rhLM> zxNG-l;rE4?3U3xZApD*1b>WA?DDD)q|DA+Y!o!6Y$^!X!%YIha9XAA6&gT)1lWpB@yiyj}Ysd;}QOr{`kD2a&O4~kcjsGCgdBQ^lMK<{hfu|340OY zzoT%FaF}q6aJ+B^5!<~|h|{3ei^I$i$%g!9VSBu@Ox#kQ;UxJ_6&@n26!NY&>sux~ zT6moBV&SDi-r}bJZNjy}UkhIoz9r;MYWi;w@;)`~c0wGMU&}khG&g^L99nOGO8Gs6 zc83u4^R6J1aU$P2c+q72%qNMpNf&u@1L*8MVA4PAtTJ;fC*ejc|kSl@!~jyK2p zaJo&`cM8`1GFT1Wh58QUiWWcb1lYm)R-it%!TLCie*aqY8Vhl;`9E!p%LT3KdmHs} zJ6Rv^GyC;jjdk{606tvq#?yn<{?3NYJbrEw`hH8d+cI9`U*X3&<1cKNOKV=^UjyUE zd*FWm9>sbjz-#OQ9%8UQfBcAnVF(=vzZ4QXBc0ddtgjFsjxp*>FDo$r`lPMQzG9i6 zA8+8l(1zd66+IwjJZTB8L0L~)g73gTJFO+?NlP$=COv5h zl33|&QcKX2mf#nxGovMV52lS5&=Mq3$di^}lIt633H~oiI4wbvf@0DVd=AwX$D}2A z6a@Etm5v;=va#4=ifB!0#+T7rLM*^HLpIV_ve5`3A1v5}TwOj?3# zv2SA;EkW{@VgW6|4`>Ip1jk_##J)~TkV=&2gk#bYwDHbp3Gx?UETbj(82jB)OE9+O zT7pNSYw?)01ebFoGg^Y5v)dbK3C_ciFNkHd1Y<3<1Y<3<1Y;R3!IRm|jF#Z7Y^tS} zU@W60$cw{RMoaK1ni(y@YiVY*1WUOeGg^Z4Ik*`u!G3J0rIuif}=SY0WHCMm>Ol=8Oqw z36cgF3up=6MLVD+_!qVx&=MTZ`U6^ml+BCc4`GA(-r5wh9mLP-6#{yb{KVp7B zOOVG^ET|<|zzTy}f*-TRpqAi|SY=R4a5vWR-PRIp;xPJJg2!V6@?*Z1pq)zsT7qwK zYXVw=y*MD7(h_9+fr6N?CAcSdK6r|D=K@4GvYcZ9Ex~0Rxv$j{jIENEU?)};&=S0Y zMZr__wFD311_iVPk7us~T7u;B#{yb{6u^(Q(h`gXv;?2$UJhspl2RFKr6m{(XbJKq z*jQ^V!B|jBa4>5KY6;%NsU6f3{EBS`wFIwcLQqTaN^V6^OOV2kv7nY9+48Y(rzIHk zwFLWeOaoeiOF3p+r6m~iwFG(AiTPTB=W?tzsUZ!2}Y3* zo+4>C-A+Xp9ZwOOmD#-cwEYtJADg-WLmEoq6AGuuEeHS6IP@7U!Ca)~AZ}tI3U%p` zgSd$=VvW?q9K=mL2yTw9z?w%g@zx(BAD=j!!OyNxOmq9oWMM5v}=m>va zkN|l%jCKBW4sVWwu}y%@JvD7b;;NNAog2Qk1=w7OBMkCJifh;%8O1dm*iu}>T3T@p z>uJR`oF9C}H6&*uHj*=t(O<*q(U0Fq#kC@@1bnFc{$Bh3Ud~{zePm^SuTKRNy6of? zRd_i&nQmGRoS>i9DZ`V3a$5GZwir_1oDj9SNk)=RWm>q-joZJ4M8!yPjyqKe)wQMI zavABz{ofYvaU1!mcF6#;I1m@m6Esi}k~ZKijm@ zYUlhTDNkDw{?X@9X7&sCpSDl7nDn%b>Gc1F>9jG|De%b1uCKm}aUqNRi#|hKIs}$~ zy*?Tqcm)>noP0erUY~BvV{+g9t@Y4&1mZ^^ehj*OLQNh%10nL65fM@rriIj#h~G^8 zls-skzpUUlR`wpkeTDYC8~Jl&*9uJ!4e3Y8K3#aW@CqSsYO)`<35~}Dd!6jpgr7fBXQT?We2HW(| zfTo8AG(9w+>7fBl4-Hs}i&OT?^w5B&hXy=T>6Zv^6q+6y@=Xs7XnJTs(?bKsammX1 zh6zm%4Yui_0Zk7Lc)9XT4-K~Ip#e<~4fu}oO%DyW>7fBl4-IH~Xh73L10IK|&vs1@ z4QP63K+{75njRX^^w5B&hX(9~8x1ViQ#eF8LAal=Mz~aXlJElI)xtZ34++-^-x7W- zH2xCX$3(aGg{FswbkjovnjRX^^w5B&hXyn~G+^(T##=a1XnJVKUo880;SYqShlczo zWSbruY~wEhjlTp;;2328Ob-oMF5C3bU{8~6dT6js4-IH~Xh73L1DYNh(DcxNriTVJ zJv5-{p#e<~4LBALN7=6Fp#e<~4QP63K+{75njRX^^w5B&hXyn~G@$XAfTo8AG(9w+ z>7fBl4-IH~Xh73L1DYNh(DcxN|Hs~Uz{gdb+uy4#mR9mwwq@@cNqFsblfiOtV8B(b zV9Nze6|ybc!dAhO3#Qm~Frmc+LNx&bp@bSBp%Vx_l)y^}3B*8xF_;$MQ4+%coSAd) z-d(RlcrWk$-uu7YpH}C7Gv9nO^G&&T@6J8LIfm;*qQag;gqwK^KIHGYjORh*OiX;2 z;}Xbun(KMIbt?Z!ek@Lr|1dw+{}e(j{0z>A5XNVKtl!QlV~R0HFZ`z-rT}x;-<%}? z7{{YOKInemsJAC{a`WX6!QSCrHK!uLv(30xe7GLXJG{6_2;gt`;}vlp8kO51;px=h zT{l7wyU#r%(DhCm0_QY&8Tv_zCptX6ddR_i$5h&W$9(Ar)`PeXA1@6~o%>*q{nI)U1c%s9zm%GlR73F){Qv!N=Sm!bP z+pO~#Hgfb3tN+dXRpBE{hW*!Gd3#C>`ykXZtc?{ zU+H*@<{xJ$9rW95t!97Xtp4yD^E(geV$+LfK-*8Zv0?TnAGUvUo|&{87yEf4?YeK3 z*74JBTrm5S&zF32zPEkqZ0PfRhnF{2RXktv+uJ_fxM8;!I?YT@MR-f+=ONd1c%cMx zs;cn$@l_=+#AbfD4WTU^UMQOR?zWo(t!yEs{o$=;5QuzNeM ze6#R*+y>bq$@0o)^g7rODBQ|t1CY}PHx6Hvz6EaKA$M!f739;^{70Mw)7_@(~ zkwM`|3|d(Cb0E@V-OnS)DD?XdIB)F1nG0)xmSSXQ)&Ox4irG9gBo4FVFgb<#l+A#0 zv0{it z3-RS>tQg{XVGClpV(9x2io#ei#2-szvrt&97~-rETZ^2qVu;~R@eur*jk6N!hj1H) z6+>$w$A5yE1S^KlM=*ZJitmjH7AuDM+ZuRloKQzxW3Xa~NkiOk8!LvkLbX#k8a7`c z+`?O#g6E-8@HJKpwIaT>Gt6?uP&X7gei^)n6+=8n9%MGdiXoe0IQ|}&hRThhGC1lMxZ&rbx~WCaGbA>V8u|Yi7kw? zU|2CkXBlR*XqbkJH{u^Z${`v)4FZ_W4#IbGt{7s!iId3-D~5Q^j6P+t*LoSDd4{kn zT!tp(iXreZ7-lo97*YZs3 zoJ-^U`im7qHf=J_efqFsh+YD-S$toLzo>i$r3JHD{8TpUY7g2nv^ZrJ( z%w||IWKB(ucV(l$qO`N(F}MdShCVm-ofAKro$a+Qvk(f(t$2Sbzfp3ssnNnXUmwDX zA&y`$o5klbqd%#$k=cv|V$yErAN|mci+8#)9PM%tq9Tmyei)j}t{9?s64d01A?l$; z6F;Uiuwv*IQ-yG174yZ4AuAUqE@8%4F=XYE#DUP`iXof6G;tB~;EJKQVTa6S71YOy zAsas=F`hjJD~A4N;zuObGe4{tvhiaQAG6i5Vu(M!7o^7}_Cb4d#gLs!#wTWRdccYy zt3Nq0hXWWZhHU(_L_em-ilOc%{j9`u^eR>iS^YVQOX*gu7@~8?Z1xo6v0{jmJ{aT@ z99LX1#Gz!E&0b~(STV#gVwlYyWB^tS4L}Zt+3Zma5UvD~3iGjU5sA zpF_bm(ns)mpplHo!a?Z@lqnki6%@)qM}Su`U@)M{Ag?{YGD=LxZktg;`rZgIvp;*G z8O)eII4%$OWQ^xm=tisYS4Dm8SX0xBL)L1cO zYcVZx0_|bN&?aMVPU00HR}9^0in=gyHCq`ghU|b_p7?~%f zaK(@f0J9kvhH%A@4FI#*cbNn$hHLiN%C$Va>dZw2q@>Q z!xckp-148(S6DH`Ty6fJdx?^8I&uLOErTjtP6MWQql1NU9u0G#SGXK}-dLzM;T8B_ z%s$8mGo}Do*~5o`TrtF%56osC(c@S#G}nk=HoFh;xF7oqO1Jw)v~Xs{&}FdF^L!L^ zLyAv)oYZ*yb5ozfC9wMyf$g4vF@!NWx- zmvlF;xPhzi2S{0TN=di9pvu_qzixm_XQs-j)i;XR3gmj+v zbx@~!sKX5oV*8XcLOLJ#Ivt$IYt%Ud{WmtDoDtGtZ?SoG!fFi&=|8YMQ_2}3ozcDy zoYT+fphaWT%NYTkG;%%!r=I_2P^B2n65GFm;Zix?Q-S}QsB$4yYAYBnl`B0J`0qTb z?1RRSEvR6)R37nE;6F~n=^FIU*ufPHm&!Jr`u_Vhbs`ugvBN7EA)R8R^83V>)VYd% zqP~I=(i!aQz<;|#NcY0Xi#1d*LOSz&9r$k|br!M6jTMZL&RSmw{#!~NlKRG)Di{Hs z&hXzQI5qxDIFU_MIRa&htx7UnD))OTgPq8asnUfdUXx_FRJM95bx!1Ysw`l|*C!b+ zl@LaU$>>2R@-bCTpvnnJhD)VCPK|Fip#OD;kUo`lIw{Er>CE(WunaY_7j?F?z^5e{ zA)OXq2jr_qQ0KesTbq)Mkj`dbr`U;{L>;cZjh&NZgmmuqb>N(9sYBwy*mskRfX>(G zjj!O;^WRfc8Bdi9lMI*2SDp&|_a0UF(^Bk`B*UeW!k{-+;J;Fwr|;wVy&}nQsZ8=z z;6F}e>DQ@pRg&RSS%y>Je+N>ho#XD>BqOAAmZwAit*6eB)VU$a2%f0kQ0HX) zi`|@Lgmhl?b>P3BQ|Dv)`1T|tr1P1t1OL56otN33cO@C&y6M;11MbySm#(7Y9@MOs zzKPN!n!wT{Sl7ojSEWzpEbz2urSuD&f1cC)lfE3YbnHdVH0eR;XtCdDPDvljQS^IF z4e68Fi??bPNOxmd{-^<;J``7y*xMT0>08iHu^k%4X>QyS`%vRG-IrEA(a21H#lHBt zHwJkP_!5>(%fe0X;Joq|EWG2EGXj31&hB`Z&g(;QoL64Yf=1kOMo4F(r!(4#45Ln( z-8JTxGeSB`J)IUOav*i?f}dlZ+;T=pXOpM%0h*sWd`~@A=9V);I=A4|^rJsu99}`C z-fXuXZaHJ5^pdZH3&A5)x}Dv6cek7|Qu@MEdJr?&+f?FkjHTUj#z<**JO($}J=n>K zbc9gJTkzNb)E|PBCgRlis4MDEoo8sM8uicUEcJ9S&<>=|Kz7ODsK3#ve1jh#E$Sf zRApaw!Np$Rsq9HNE%)kNxs9G}@_Iz&NcQtpUgKAuPvx~o$rxW><75gds-nnj)F{oIWH95}{ z&GfogFijPN%HOgS7r05rAk8F>+wb`z-vo|b>}upzo=wkP;%Zn|c4VQha5Z)-xs)Kb z#nr&BoK3%8?P~N^4y5I4+~7s`3BNS^Igz_rnycu~AGsBbL234<^RM@7%?rd|5Mw&- z*G}YJCi$2%)Q{aHBhcj3>51QOjLrrp(h29453t-fyGce!XEIK$_b}duQ|UJLo!i|c zW2DsRE1?%Iq|$|~;~j32F;Y6mSHgHZo=Ut8j@|7h86%}Td?j?%tEj|p?XjP_NybR& zWnT&Yc$`Xmb2_}wO)>`lxR?&V-)kMy3yKpNfBc0>_=aihVK>PL*yT;hU{44B=!x^n z>#6f|H^~U;%*Uzkk4aQ&VBU|pNybR&7+(qgSWYFhF|H(Tk}*=c!dHSn&Zg3V%_pGINyfk*B;|;`kk!M>lkx|W6yvO0SIE8P@N z(Lc@6k6+Z>-Ce_&yaqul@hN;1IlC!0u@5x+^Q~vMms?s0;c>+Bm&O4D@DHo9@tG@gE|VtL$6*+v==M82%nMh#YAhQ#Tenc$^4PYshWw=>CVYEau#CTari-uZ8T>ltMed&?#9O&nQM%E z1^EknoIT%SpBbKQgzrkaG%(y4;4_dJ_*erYje+wZe+M5Z{>Rz6`#F5eCfdmD5$B9REjVAyJ%WGY1iLmh#oQZ|VRK>14y(0Ld# z?jWnS!Umjqk_%$B?@cV(JP{tQ5;Zq6_Ve%+k6=L+=FxlS+FA*z; zYa8YeF!N#=#>eiQEj;UQBM6)%Z3NE_un~kgegw}rL&FsQ=Q(UXwZVL91Nqbj^Qqm! ze5|=z&labN;DPHpE<;1M5Up`uk(_=CCfX{@^Grt_W5YMj)X?$|4u2As6Z_cnLL#U7 z93pds*n`=i&V+0)?P((jOmE$X6LVm)gGF1|ol;vB`~P1>`nF!`jRa(%C-QQ(tA=C4 z!u13;o^2nV4YUyirqADSc~e8%KY|UHLMV$w{Ch=Wkx?W9?c1Dr#-4=;!mf*yH#JiD zN3cjFlwpyGywvW>ODV)5X9DfpBJnKH@0mWomr{t?DK*0U<6lLBD^mFE(o6gzUVsl> z>>YGCk6dKm;NcPqzdii<1`rnw>7ytEn;VF~3AcU?cK;P)vwJZ{ghLTrc?j5e z%nAzio`J|Csv|LcuMG9TwjiN{DO6TtP?c5lbWy6H3%bSPmNrZ+*oR|PTkY_nbt8uk zb1>j1Hnz`gSTntONyEDN9P>kmjma0x7i&E_{dFy^4b9F$4UNl|x3|>|8-mR|@)#O1 zWGvY3vvvW&h7xuAPnbWg?tlpgOh2H;X#+I6h`OVP56#&sB%o3= zYD681krTr5n*Bs_!cDOPVWymRTYz0{JQCDqadz5?Bu_2tmNu?ySW;&z>u*#NaJBJs z(6X80=}xb%rrK&u3ptp*V?`cL=g2W z+1(~$1UPjQ8<&|qG)P;pc1is)yUK7Bx`K9d33`rQ%ywCy_aGQ;`UG7|2d>Ur8}*)G z6J&d5S3C-NJi|h=98HbQc&R>9yO;YYGPc65KUrPgE>dAVnR@VKx{t`(tS55|cQn#6EAemM+0YQsBpEX=_~P?dj99 zbZJ{ddzMvpS@emZ4O?4IZ(b!aK*tOnYvxVs3zQ|h!92~}3D(T5J6mVfGh6ZmGw1aD ze`t%IK-DuHjjp$J4!A9z)zEC_8NWZzpE7TLUCo5)vlh&qVy1z`ym@YH_P8M6Tdy_H zZtO)EHFFylH@2F_z-(&=Ok2a^tS$#-@0z9#&vBmJ%x0t=!zlw9Vq1~M<|SE;%gKn{ zFHo&IPOdp&nc0k^(JQXs$8xXDRJT_e%*w0UTh=aa(@b1v1_PqaWSg7Ln`Uwb5(jdy zfTq9GPk{kwT~SxJrhet>hQRbm=e3S(%Sz9Ii6P`S(5xv3OvS~1%G|lL=VmFI!D%n` ztOhFMRig=aAl}twG4_ellx7@_*`#hMzFL}#5G(H`!j@v#XlzI@3%?KHLhE$`3`sM1 z=W#w#pt;`qj3jwxRT|<@4Eo8;R~haS|C*AeWV+DKv?f72rbECD0e7QQ+Crjk*aYhD z@BL&4MOLonHh`Thi!*5FZ{~(F$h3D>zs8r%x}_jXTG`l!OK{WbmH1z`U>2rypeE9` zHH}N0w#H^Ni0mA@cCl$iwZ|^JnA6+*7NU32L02|7t+wCVsnYEFW@dNKzY}nc+0_*q zSI~fGGvnkR+0rUcc}?RjP z!rZ9~_MdXVd<~nr<@xUuIZSg3kjXG#jWE{p1Z!rnoz>huv^3|ni#{L7t_}^uUS_WI zxW&V$&5E|&kRyE7>`620<~!WV%3iA1u4=>%fSLXSrGR0!+^#wbt88a@JQ-oz)Y*aW z&q@<8dd!8ucmfyntiJ8EEyq4}=4Qkco3nuL^?B0|n7Uxrgt>pmN9G$)+fq=E;jSjw zrgp#vDq+0C$}g#J$1YXa`*8Up;{h{2+e=4-ncFm^8XFoKf)@RoDZ8JQf8SKMx_NaQ zx4dd@SPROeHSL%zF-+^%@vfNOimr?qe}Y#IhIQ*p?a1MD9q0}6~i4z4`i*M1ZD=Wqt)F|W~q zzK=+IFQ6_JxW@oz755a&liYM>a}TqO7f*i%UDL3NyC~*Mq8#(iB@9Gn##Wx(Fa=@) z#zefLZY3Td@+uj)NajhPyo?X?L^HcZ=HUSDyq2|tsS6#W9s?a;&CH&jy1TcRX~VFW z8P?=eu;VT3TR>LlF<H+aZiUm=khqln=|<}$m~#>eRp7n3g@u@ z^fqO{K4Tr62~7Vl;R^r}++4V1V9!3=N zx9LlB(wEwV`cDq8?DSonSF_T0$w`kD&w(QZHjM1_Wk!F#uT$oq@g!t+Ny!9-vPLQ6 zv3e?SgdD7^3LGK3_R$XsIX(Szo`jrUIdVEj=1u#6M{7;vD(L9ND~}rWDkFEhqk?9J$E;dTUZpzfX=F?*j(W!>HQzdVXbF8}>> zpCy@uxFToYZ2Km0q25&#zyIzc6>dIu6_w{1vY#2h$LuPd`A)J^c6skDcKR~8^Vdtc zB;Wl3Z%=Uh6S&vOA7V_{d&_*K$o|Gf6FY|(6S@`3XCvP&)h@m`@{T3X%?|U;^Mx!= zkSPmq8h2rZQ8_-z6J%?|Z_T?fV{TV-?BokGhRpZcT^KTPIfn9u8AIl)4-DlQCiYre zFif0@!|k=BV1&X)Dtwf}adF|bxd0bCUgHYJDts@=drQW}1SXtBq?-o8T{Ecv%@H1ftbabXm2>T013k}C4 z;t!I%Ot@BP_Q*xN*&`QtgTn6>9)U4N`zwUU2+tH=EWAtjsPHA>ABCN8%S}5yg@c9r z31R#+dkFgr`C1~wCkbnXb;2g$u|iU7Q2!#~4~2IK9~M3*d{u~> zW|OXuaGG$X@I2w2!dHY}3;W<&%Y3H^R|=06ZV^5z+%AmcR-NgF3nvO|g+~fogeM5k z7G5U2QFxE=N#V=FZNd^Y_Db6HQ-nte&lUbe_^9v&Vqb7l3*RLU zbes=_pAbkZovw`g=ygcBJ2#8JX*Mq!lx5) z&#}L-R`Ev)mk1k)u+uJioiNV(SM(=LHwMv62GIo!_80CU93~tk950+KoGF|wJXmLM!gGb2g_j7g5dKJblkjoj)4~^pzY)GBd_(w-@O|N@!Y_n;*uimS?&sl` zBFaF%>&fwD$R2@w?nIee!x4uHM+*5OD8p-o3x$UXxiu)`j}jg&TrK2Fql`DSd_cZr zP1$@;0P=-Vj#KkJ0r*qN_X!^rJ|WyH{G;$);RnJmgkK56yw8W-LLuKgrQBOsB^)H= zyQduQlY}#ce4fQ{^L+$(sARsF%J8+q6NKE`o8g87AIQCBDPJVKRA|1hApB0r_X!^o z@-H9)@OO1+qnoSc-q3C;H%$mGOe_&{N`&~WV|e46Ch zLc_g}aJ~`C`NweZ1CN$W7AuBxyH4VXLcT6bneRapuMz%8$W37xewXlm;lo0{TFdy~ z3CZP2`7I$|uH`)TS7DgnlOPugONC`ZzIn^|A;QtZy@gYR(}moEnfhk00HFE425eUN zYT+?LzNgFi@Lb_V!b^o$3$GLMC0^=3B792ttng*w?}cv)w+Z>eFVnjbi-p1xq4|D@ z^WK#4!ONEhtA(S4dkOhYF!c@;9xkjGt`N2e*9g}O`Tj7|Um(0xxJ8JseNMpuyrfG+ z7;Ya-`BOyr6;Y;rhY-=<#t<<+#uG7arxAPES2j7H@t_^J!C)Z~{=nA*gC-x?#qFK3 zZ}LO`sh|u@5s^F3C=H`@*N&mqDtcXVXEmLe_fneq;ne-LKM0ojxTc4sj^$a9FWzg+T4BI|Cc43=R+vRCz3xWqCDSfuYpw!E32_St-acRdbrcV6tnR_ zw$4t^)AQ);{A4|k($3G=^C<27v^|efp6Bj)wDLTG&!d&+S$rO??1%M6VM)WH)ywQJ z^VRmee$k>;4Qqm%H{j>{p!h#!w+4KVLf3Ke;kf6){u?|nOw55UXY?>k%#o`{8$5U) z$1(m*dK@pg`37xbxS50F9K*@XFANAzvtzCw&-Gz`^YIDVTMjv&J&wnqy^4T6`hYfR zZyi2CdzV4ZXRjUML3<+t_GrhmcX^Jz=OJ^h@(!=Q7b75OZ&tuw3~`>lpW{4OK607n zv-d!by(IyAB>{Wea_o(VJT)-ah@xAhOMEYR)j@yMj-uDLWT@bKW z8nDOb+d+H056xG;!8!JB3fSX!53hWDP9C)P2?VyKcX;((kYn#r*c%Te_P;WGJbUY9 z4?*Twj)8Lm2bT`!#bZs5z3_D0d*T@z?couEZ|}4mdvDpUYBEUI24Zbi~&7+SLfIpcZj{#(H^Vq`Q@G*dz+!a zG3Xthy}NSkeFyf=gA(nb>b^bD<@#lyjW?n2M4tNc`$(|96^Gh;6WZfy0k3>7%ia(g z!*L@foO^J6_6|gw{NBvbYuGpcJ|%`=#!C#`3cX-~y?(VLr+iCLKCixMB=O3}?@1y1 zvzD>CRll_vAz+&240I2tY&^cR!3gJLewU`bQhewW*z=D^Cp*r5fdJa!K^Fvqolj7{ zj)4q3J?v95YD6k?3>`UU)X*`bM-3aAN)0i=_W#f!Lq?4nl}ZgAGiHvbb2#v zl!_F7lnUSYQE74Pqf~6S_rk~iZhQF5Ti>60!-wxLyJ6mr#2({orW>o5z85`fxAzJz zWp49!^w^_zN3xh!r|zg&F>l9idobM7T>u+Xca$T%A}hS0rnqKE%~)fv+j|8!&f8IL z;%j&8W^4uHQ!4Ge9mzc=Zx6e*J9-!$&t|?fo;|M|L3<@$?Jsrro{ak2I+w;GAC*SJ zAC-pP%^N=1a7*ac`*+07y8rDD&vhO|58p4-CI!pRf6qDV*3X@X&@vlOzP03|uSaZ# z$A{Hys-Z7z+syTS|FrSF=cQQ+e;PUC2LHpeHm2Ruy<_i&jQ@*2O8Nf(w}Ag^cO;4@ z*32~i`rfzj|NMWz|7G98|1;6~R2LP@9;?2(+r7`N~eN}$QcOcOG{HjnLbIAaProXs@h2!A>a@tRXGyT@9_ zggY#tR2aDvGYz(InTNbHTe!4BCDewPP_pZ2o^NLQK4rByk6g=uF!V!1%2wbUCELJg ze!a(zEx$%kG|cZx9nL})Zit&=V8@mvO!ja1haFpZUf7IS?%2Y|fM&-QK4*(9L$27d zuP{?$$CeHVH9NK(L?btb zm^5?*jo(uK6jZrm%Zb!+3%UL&!t)THm|({idZ?675xHZ_*NBL}1*6!ph3CjaJGR&y z!|}nW2zG3-Vqu(*D>@7-vtmh{tIx1wixs^cTg*0+Y3|r^F`|pl#y>K*o4O%yGLLb` zmKzWjf0B8REwTojIG;*l#}+Gwl^5USw$2>+_B|K zMjsGk#UK~Nxsd~QY_T#HC=?%qm_iiRR2e(A@Zpcyv1L92t-p`x!gE@Goh7S_+LDFi zud>|rMP~g$x-iayVaFCaOFOpEa549&;72(`!`$HoJGNAyDBQ8-3W)Ki@DDq-@SGW4 z&tk6iG9pnRY?rP@S-E3N0+sAs*Xm%$7A4S*Eh?CHY_U>d{4|#9XGJpr+_9yS{=7$G zymQ^6r4Dv%S!HrAjUP|t`_zk*@i!g$#CVdEJP8;@vtx ze5zvSe?|JJ+pV-jaV~Z{GxcHtl^sLJGNN4B=LK8HSE}8)0ZZGj7+&>%dc?v#vNOp zXF;)Ji;W+WIEpfMY~el*1?drqlb9cNY_aiU5?tKE9b3LM@#7MIW&YT)#ZD#T6VquQ zJGNN;$q5owa>o`MKP~Y*W$f63beldQ--ZE!?Sw zJGO9KamN-8C9`A892&%qEgU0e#};lS%N<*~AP2K!%U-M!c5Ims*M!nrBZ&uS13R|t zZZyn}EgTBAk$wm5KqDEEg+n8qfigwI-0`5y<&QD!paE3|dF{E)C@~$oZAJ;{xh1Qa z{n-o6V8-+@37S(q8ROY()Po&c_zXRnhB32a%VuaK%-oF~TPR?RCzjDe*s;ZWFq~*& z{jp<J!O3Olx#AHiU1BIT0{y4ZFMC-|cgcWj|Dcb(uvZ0^{?%LI39xqw+? z#}-?QX^F3y9y_+2iX1We5_LfC*s{eGbz!2M`q;6>4!Grs+0@65Emm$#R8k*1wpe*x zVl?x^jx7_BKWFsB5-MQF7H)9EX*O{OHLzm~OJH_vxt$u=v4tkgjx7_ICw6SH0obu+ z2L~5+Y_S2@u_ex)g&kXL0CsGNF$s2Tu>shzrHLBYvBl#T z#*QtN7kRR`W6RkHNbH3e?$|d6&Wtc7BnI9XS%BhIpRxR_O<+_EdVTik>R6!?l4#J{g`=4!V_e}W=p@~P} zDDIhZErRLEVJIi}OkpJMx)S^eiF>A8YvjVj;V2UKOtJdhGllz?72bjVz&%rLf?)Sd z;WlxJgJ~Umrf?q_TK^H%uxE-*U7C0ZxpL1Gn;Z5_acLfVro@msLKD5*t6{@^EDC=( z4xabX5CVICz?h~D^L}rg6xyA?hWg{yw?Zebu zHX3~p4by*B?gh+ljrGJv6mT-@#_cZXiM9QB#$R0d>nlC6t{Xk^b4dKX)q3I>6ZU7w z{4I6h3KYNV-7uR(^-J*?*uHkI;~v+QeWeyMe;GyCbc7`twgPe^K7GDqM?Job4RoWF!EsM0W2U!3yxs&&bleRl=u?QCWe2Xq%ed}Flfy!EF8=0-Fyye&Qyq=+adEg%)oUMsn?rf&p_tyhy&Y));sQr#@^eI-?Cwg5N7OgvmyRgHEC$X^k{yz)E~in&*D$+lZR8e zFKC+42ZkDA?S7lU*<27ipM=f*Z3Ot6Z5;WWp=e}7=Pc6bKyfadXev1n+4$_*9-VWw z!|I+sKJJl6qc8G6Kg45X%T3(do+pX@6i(br;Y3~qc17xnD0AS~Z9D;=L!c?wnNR3z zLkTo$nO%7{*hUbT1Jnuo*iZuV%qD_GK-OV%tR;B1Yqw-<*Jf-Vl(AhKv|YO;%V3UR z?a$5B=)g>kYJ)YJYjPckCfB*aT<7M^)#f%YSetpq?w-c(Jc8$wd3h~B z!7RA2mj0_-BG`v8*Rp@~A?}7x$T|KQbFvDT9SAQwJmHUGCWa>)@nI5ZXC2mya|l$~ zRS&S;$24&>R9)u~f|nwzU0G1Gump|6?5scWLx+wKE|d5$n73)@i3FM>r8n^qQ}FX| z+Q5@md|YQ9f_2;jWMI@;xH)_s$TwxU9P<7LS5m+c*r-h4@W$M4$Ce?=6&$z$c0= z5!)d1oCPbiayppR>P%6Y4eP*Gi8^yOhif;7d2W-Qhk)}Cf&g=%QbwDxQRl$T;e$4Z zzl(D^5w4mG?Rgn(*Et7qbn?y)W{gth(Dhx}p49HBtmr-fCY zF09(!cW5{mH^1uB0|Rl9oVZ}RXfO^ogXx$lGxuiW;7BS%xEU`zIStM+BZ()QtniFE z;jLZ1k+eHfVL~QQWmh99Wz=d3Cz;bj2wsY;k>ujQT}=nCTbbos7*!QWFwUf1NH`E5 z^yI=VJfShut$Ffid^%!JfVudJQi1+9zG4f5c866Hj3CC0so26GP7}q{R`3=EoMUv? zGuY_D1T2^XH(wZ5{7%#dpOAwA%S@Y*!U#NJy#k{*j(8^Mk57SfjPopzIplV=PT6{e zEHxV;&&ZC)u>l4~o^cXw^W!=Pd#54im_oD7fc4BVrCWG%Ej}eEK*li)VR0Cm@e4!f zhFB)lcS}Gs;1%>PGmS9+6h5wF+Pc}Cnpx8p1k*^yTluDuf?Zo!4`Z20gc41~*aA^I zv1Cjio0&FBpyU}XaE>;`vn@dr_Q35Jj(}ES3bM2c=_Iv7&a@Fjj2ldsW&J9|(v`XG zjC(#DyULBJlv~bp!@Ncy_9%R!4kmld^?^Q;GXb%$aiGvC-UJxX-f2q8#O*vK1>!Iz z1*e^e8E&?`Oc$JXqQSVFsf-hO0X}wOGACx(@N6Tx9*=!3`2RVqc;t&e4Hu%2^LuFg zi^P3c_0Yq>+PHG{60mOVby#~#%gVOHmMva92um~vHMcZ33~H!f)HrDDpkYIXjvaLL zi2pc=`_lhj{&oj%IEYEQw+qtf!ccNXq;sgPI?^q)E){Y2NJWaGy}E*8I#Se?M> zJD{vQtmhs0|A-LLIAz?lCkHj#ftsVJ#dzAhH{<%hJehGb1HE5ir;W zER2*agfz5k)LrTngx%<@NC#r5vx|2o8BoUmgZOVS|IOjQ(7L5oEo#ELGOVlgUBwKM z+|5tg5UDVUW7Re)w6pDGRL!WB49u z`XclcdUdx@DbHG~vpY>BT!vQf0mWmg(dfOqf}`Jb3#8boTc7~ZA>=c6qcc*G4$;#i z#nG}sgXfsGj}Ar;EQUimMA6RCZiCUbA-1b&(-7M;#I{5?Lu{mINTgz9q=?z}ZbB4W zjKZ0p%u^q@II1PAQMC&ND94IMvA6HdJm5jRYm%(pmHp< zd`6^GC|PZcf^6k8%;!ySyy{?DZUHN3t) zm#?AS1P5QsqBg_5Iflf4i&wU^k%+NvNh8>G8xfM1X4ijJ!@PljaTVxcqzx7EuBE2V z5axmuGJ6z}KerLeH7n~$pqr0K7d{Ab=Ym^srRB6Y{$|!WthkF;HqmnujqJzVj$hv*=CpaP8Y}u`|)>u1HM{ zg|%s>zfW&k=aH5&1JRY{8T`9oA+7sI*+=ahVP~m-4#Q|GcOEcIp;5*gpf60S+r1_?0|M7d*#CV@micT#&t;6Zj zGa_e(H-*kBILDnBpB0(YHB#FpGPiSNUTI{0r^teM`^nW5JCLgzFj<9)`@;rSX4t|HG4mmKh^`l0g@6FgF z>YW%Q=Vi7&9}s4a5FWAw4{}rn4=i2{ipZZ&vNA`=ya5oD@q1a|2<7A+GMi&&6n5r# z?2*OdSPInv8Flk+!pIzXB4k#deYp!BQ*z}mW%j!+@Yj)&*+;s-AFF`gLHnd@3(RWv zUKI3!APKCitLOJ=TrQRb1dz*TV%o4|G3V-;b4$9Dd6S`kku(n*V+s4-7;!R+M4UxT zT28YVUcOl(`4S@J+okuI@HNH1Bl&NVWAFp*bs@rDZz9qUlf19u50K0sDHy*uaKTsuBVj$uN7~~h4lX}*(+aM`SFo0%QujS@^T3j9% zlIIH9Zj5ghnpO6Y&yjqIkneC&?@{54!Z(E7@eq&kY2h&81mPTEov>L*PEe*ZoC!d# z*r9x*@Mpp&gf9!<78c?6H0mdW{e&ZhhT8z~T=Y-9jly$3u!v8x5uOzG z7mgAd&H%(4jsW0!3g05UU&wViwDUXRJ3?;Q&G14zuOvuZ5-fU5EMi5;h5s z7yeZE3*no>!MHRs-M+%vLc{Hb@MV&lgl)oOgd2tD3hx#g4mYI#jpS{@zX`kHM+D~E zS2$8wBRp7GPsFD|*hs|X`8eT5;WcOB zd_EC&FR}7S;bJ24SwTcwvp&aUkSGg|0w*3hHNq2!sMkqCTz*Y|$24yc-N+#CAvq3kt74G9W>fAX93bTP6^8S7KH_}g zLSdb7vG6Eivv9TW7~#pn(}m{0|7vHxd_7n1cj`C2U;iQ5*PV#u+RN+h^->GN1gM~*5mk3t~TZH^soBHd8{60XL z@4gea2>DJrWxg&$yiLe=8Y$l=d`)QXhY-G9@_WKhgr5t|YcS9Y@jeE~_n?WLg-KzB z(A-xczQ5#Zp}EgO_+-kMH>U~B{TAf;k`EIeDQpxr3D*eM3r`lFE;RRLu(w6>wL-p} z#(cT1n)sOTm%=DrQ_d<}_uTystQcOlocRB)m{~iI8i^8Go11 z+^0f*UNYB?Gk%BAtQ&`H?pJ|aHO}}xLarI7JYHzHi6I{*nd`+FzfQ>I;k*vDVD_3jovB;=;;4F9Fj-2dX7Yt0$HUHGB!6CqcgGrm-4xQ-#0OYSY~ zC*-Ph>dz9+6B-U=gdZV!k#L2uMYv9QobX)XX5qC$!<7tshASEPpu)Eb|0sM<_>u5S z;opQ@AJ6jg6-r{I(7ZeenQP@4zK?K)O@d*8nnt!I? zoZ%)O|BQWvt)o8V<7DsmlD86}{~zNp%XvnZ;q1zJT9=8~`MKS{c)Z|!bKsW89R2a1 z?T$;LIYtOQ@bq}^%X9WA9@OLgnRl=c@z@g|bVp}AK0LM};gvu<)-(N#ddzP+K0$lr z@!6Qi-W2Es?QI-t`EzKGW%2AS%CR>M6&jB)@9@fZ1OkHgN{89;Kzl5gXYT}@2a4mI z0effRdxUp*aeQVNv^NCy7QztiVHo=MHsRb$gHxv~zLy+_`z!D8;x0pgch0zT@zApu z4e9XWz7IK=?-_gH1uEr>uaSPfH{#q&Lld|5v>b*!=i$X&hx4Glb(0(?g)r8G)%N`I z0M5NMICZwdUWz9=ytsQH2km_y_SlDLkI!>Gd(Y$COM_EmY!l`X@9^TDK|s*n6R^km zhW6k}-yY{0reR(@HuZI!y>b2W4#x4bP3YBbGS;l9$J^w_xY$l=c?e|y`fPD}siOMn~ec7Gu;f8dWcO^G~<fr9;$jSLD$hC>U4Igj#@MPcN2jQmg)hIK(> z56&PU&p8zqGUPcEkvPQfAEA^b&$$AFALKbRpd8`Y50$eddv-mX=MS(5ub#6pmaQ+7HEu z@%963I;A|n8##eZhv81~5d52svl8lyO@}lm@fXn}!KQOQf(t;1au+HJHXZY`2;P(o z6_r4~F~p>ym(bC{rn42QWYf6_VQ@3=up&GU{TZ2qO{W#{rKBGqn-1v<;@dI!!KP!W z3_La+n#kC!5Y73|q13D1q2?R4}pWSgA1Hh$@0jXA(@1P3IsCWU%R2 z(Pz`)EkQxLG=3zN?^7>M#y>`7z@|elkxi$a;x8(n;del=>D!1391Y(_qtj;(;tren)IE*`=iH`sK{m&f$@_)J=Usq_BEvd^Yt zO-+uU$d3Pt$~-I1Cj?;A`P|fZPW(1@w%5AMLMUin;@_k48zm>38ZC^kV2%D5=Lja7 z&W+6IPwH%B(_w*_w43=yKXg0a{6jd}PBf)d$uY=xY}WpoDE zbZ#+K2q#G30J+S{g^52iW3cI1xg>EmyBgSZZ2D5m83HyP%a&7?Xs15dbZq>P#0riB zu<85_1CMMvX#0PA3u<4W{ydXU;F$L{SHXS>aj8ClKa0Z)>)t{Vr8q*iq zbZq>z#2d5+Hl6M!J=k>UMzHBv{W*zQ9C%>Up>qtI4&%Y5^N1pIR44cl0 zoFTxb!!csmbe1y!Y&rvwgJIM8pfdu%rgIcr5h9z;No+~5>5MQMJ0kEuhk|V+KBovY zk`Y-rC|!XvMZ>>>LYd3Q!R(*`RR(pF>Q_dI0=sQS3F&(yz|8*ag=R2g`rx=c+>6j}s*>rdkMvJQ0mQ80G9G?umpxphfkQvrb82kO=lJJ1e=Zx0Gm#dof~XAHUMlo{E?GvIyL}oI(#}p zHXR!PHl2rg6#|=%&4p|_7r{JBWqb-Y9m*_}k-?@zd7USFY&usXAi+nkWYeKQpMOc8 zflbFeB1wZyhm#@&V+w3KY#a_G$(Bv$Z3L8a)*+h?8@GHn`U-41%+==qxt9oRI)80XP22YQ9e!RL*IY7<_8|HbTslW}4S05+W%YXCMK&U|3g`3pS` zHXZW(yDr#teuoO+eyks|-2L#*m?GUO6p5rdoCkYu$3WhY`Vyy3su};>)E-C)yI-Ik zNUGC{DA(;}lNJ5d4gCoLsX}Dq^t>J|v7zUisPG9ryQ3V(_q-Ls$Mu{CqsR6vKuOm- zh2KK~ioykv8mn;NN4mb zGWs+!WB@|IIE2$^xU)G=oBwyi0N8!{mlR(PIq?t_imFP=ZbUF!wg{K8qJbq{_Ch4b z_~F2!JxaRGGIC+!2sB^Oo}PY*Q}`f?Uo^5LLduf}O~Ux(lHxCMW{uZ)$}&E+q|10? zOvb0>7@zLx!}y^r-Q1GMEi_J(FkW9$d=MOJjW70;Wqe6Vck?s9SMr7&<4Zk#81I3` zDQYQ+l)xI6Wg6ofONxKu8wcspjX}47^oWtZTR?i08AX-r(fwjW%NZ_}Mo;ByCvq@V__JheWI4m7ayCwF zdGRL9anyMM|6*gy86ln9d>z#3O6nYjQpffwXM}YA&DZJRL>{HizrjDT3FVBC4u6cd zd3ACkZ&RluW~JDaaz;p}6640|z&Rxl(!YbVW7EqS0UdVq@i_JTH-svK(b}>7D;O@7 z#hwcM$Dx?MmnyXt442Ajo(lZ8hANzkVhbu5E|u#&75MLBs{8~aHFj_X!=>^|ocjK| zk2*(TE{Gjo!3gPmc=2}y=ar6cAwQ>P8+e}ARU zRMzRFBqO9V)YJL8z=@O920zA4EF=^W$h6g!dS)M=n^ z&Pg&tI+y!8aL#wAb0Rut?7K-uK!=m=Lpb&PcPmvEQRTuU!=>`3rvm@INR=zu|1L=~ zTq;pqiHsHa@87AyHFL2mk_?whm8Sy#aaY8&!&bN|$#ALck5k`&HN&sf&YF)onGvtwV%P- z*M~l#&igDV-Zf-|bOv}jqn$_+=au}@5R19xjF8SOPp8F+jHAx$Fc$0NmNP;+t)9*Y zXnyMSVR_2jaz;q!dpI@i_6Ll^Q>gSRTdId!&KN1(<11kzyPitFVYlAhEoY3B{@^L$ z?jiClmG(x{$I@;&W26+ut%%9)!A?%(V=D2N(AWUfA2CuIfK%h6uBboGD?g*5YScfY zGt1M#KpRJ$2^{vrQGcUT`7THJm@JoV@RB^|M7XDBC9=oW%q?exvc3kVrhIq99h<3C z!p=F-EoY3BxWT5a1eAVCrKxoORJWWlQhMK0>Hv4VN~IrQu*YV(<&2S1SNs%Vy&uP$ z-ViFw*yC#5a>n4Eb`y(upy!>+D_N@}ybe{_!1;Tz*LNx%x@oyr=gL{^=1pFYs5~3h zjji$;zw&Y_ul1U_asX>^oY$b0yx)kO=rvs>`CwwF`Nil?Q=42}TPnM9q@U%9=2El6 ztJv2)oyhN4v3B;obKN9kP%%Cmi=F3*W_nF^mou2A6NJhz>vw^hWDL?gzzTiO7aw7f zFLpI@D=((!E^#%iE1zIDzQWbmt-O^r*y3tnR~}ElUhQi1R`O@?*fnnOqIdkGV<4NU6?Of~A4E%8_9sNR94|nmJh4BZHe8eOR=;z7vL&a z+^7HJs0^fk2Nd`9q+c_xpC>hALMiU=N!--Ccz`F3ga3-FJn3k3=Hh{##OeJ_M}Tu(BdJURE7>wJk*maS(ag*w1edw?n(R8$_P)I zfJQ4G=}D(D-6&7u;+5ht{X5v)ucS2AlNPX?dwJ5nl=k+di!lz1$9d8~^upqOJn0dZ zdS6dUvn>00(hKy&cu(4ai+=IM{x={2JU@y)o8(E?p(TqadlGpxi>G+fLCmkllLpa) zQ$1+}>oCoe&ZN!hp2Vlz#WN)Jac^V3QMbh9Lk}L;Sa96G;Rn;cU_0&Lmh*Hz!sp=A zkB=SPLbv2b2Xroh(<_GhYRv zpsYYbgrkvHH8eC!xv9Q=IRY`nxaLk0E(w$tw=^}iG}pD)FIs6b@`Ib(+Q}xcdT~4R zM=+jw#8GN`+{yK9qC3=ooJs($L~c$V^h&; z7d%m*;VA}dYRhD4LVa^Ak|1!OpKJT}}vVXNY}r!cDOP zVWym{4*F5!vgUjYKtXL52Lu|~lt6i$3s#bK4NK~5WwHCJ5Mw2euIFe9MZI9hFUzl*i4isBIFDKxx^^mPKg9#-`TQs~YNB z+gD-0*RNz(nuxLBcmzwqqN(GXo?#eR)*50S%axSn4tR@|FgXTGYPRq-ozy313Pzhs zGeco>tX2FTp?#REIt{z0wSRpHV7czomXB(_{gIN#Wy!e=`XpZmyLo8YW?`C@0F0La~ zfa8Mg%GTrX9Od|Zeg2er^XqCROrN!2?v#vfX8MDLK;!K+&sl@s_?_FZxUto=VJ)v0 z9AqT(3U*T@$jl?hWD|S^YR8G&bjx5EHy&q)_N(LL==HhOqxjgo~xeCK4P^dai2SM2k4|+7v79i#vw8rK_94=hn2yIM(xPJ@%$=Y#$QL+V9Y)s@LUEL^EFm z^Yc0}949q%mG@cN@-zrdbEXJZ)Xb%87cUo|o9|ST#_$>x)U`c!C#JV774}W|%`a)D zZw5o@FBC?1hJl91fU#ADhrlD})Ge!TYN|K4TsX^578lH){nyU+i|WZow-mSWD;wJ| zSA!J?|MN1%wKX=I(P|TB)5h(>jX9mzZ#25sGR@_X%Xt?{&%qOLrJ|Q|@3v_v|J6M> ziIHJ1+s}cUFy49wd_s$MSc9bR8yW8M6v;HZ*A=~qE0BS`%A1;Vs0jnnM=XKCXxno+<>XQa1`DiF&r!Q}RbzXDlj*xi8n8#F z@2Zp1JsuHZrauO+C>ht7YUW`p3>IoB^1@JN8~ZIaZ~6gK7tESq=GxpoE)SZy+~+(D zG@+dV0+lhoqidGbx7TA3W4>Bss3(yz2Q_-#F=Rsw77DWv3#FcK7#-0!8yY}No&B}f zHY6Sh)URxBY-%vfu63)MSGP5QQ|s^ZB?gO#+V3o$s83PEY}YQwN*YemyZGb{AZZ-Z#-aoQ^^J>W*y5#cSHLIC0H2FfeN{ zw_sAwH=F~4;WBAj1>w1U$9{|Z=decRF|V$f-(eh2V2Wfl^CV?E*}jyYV=`Dtuksj( zS;4kpOy9_pg9=Aa{v-UwxzEKslFK}n(L-^;#jVMTx|Q|jYPpE_f4WV{lR!n;)vX_k zxaivwW_nj)bWg|5I9cqOSv?=U#>}SPtxujA-(E#?`wv@*%BWM|Hl1^eN6zWbh1Nca72gk*HsZ05nRFWP*k@@=z8)nf zn{KxhM7M3(w{B)qFp-UIb&JPKDql-OIuc@Cah{oO=()xfM=siQgc?dEN*CP!z05~4vT+P zYHT$g^`=PekA5*SHDFZ(?l;;Rs#1sIvM?A91o8hOly33z)T)LxjctuB&8cCdM~@sk zmhW%zM})6&V6(8};#lgDg6ti9v|bYrpW@DsfiQDI@xd0H|1Er(8@-AIem-Cj`7(nC z`7nb=$h-lW2?=4tnBeiB=fA{{)q#V2n0yBlkI>D}8|14T6o|*Kl+KhKnQiACjBob@ zAmvRt@>MzV&vNAFa^yed$eDrV-38;BzvaX9$EX*R(aqc+d$Vh1G}}7`Z!X&@JZF;D zjRhttKf8=^@3NI^B=_nkBRSU@h1!`b*91rUM)-o9Pp1&EcIgZvR`Gm?*xkN6UVsH1 z7f{BkhVK)xdf+l5UM9Yhhz4e_E5J|H9CPHN#Bc2eVagzqI0cC8OT-V{dn$amaE!1< zI8%7Aknf?>?n+^sknbQfobT`w&lX-Pyi$0R@P6Tw!ru#D7k(`KLWrMOj9tF_OZ)wW z!-a;c3E|5nuM?gkG~APjzeX~bD$&mU!dHZbYYE|oTM4))f9L~_6&g+?$OlPYDqJnZ zi-tyjv+ye6ZNi6z&k0`>a?e=i^EY8n{AfjakkD`vL7pl35TW57LimM}4F@IUdnNx_ z$agqtucxqD$gS5IK1+D0@F?N6!aId83f~ZZB;;>sw9`q*U0^92?j9gF6sNpac)IW+ z;dR2hg^vq=BittZOxOV(o%RgZ4zR!E(ZZ=h!>PmkC9f5pA-q^ zuMi$1JX3hF@Gjw_!k2`96n4V2PdkQN1~^#qe!|(pI$?`&gYaD87U3CS0*9)H!ejx0M3qI4079J|xAiP>gdI9Qf z7na}xM0v1qo^Y-3QsINbH-#SwzZUXkMcOGBRtZN7rwHc>>xC`C^a zuFU5xVGP$~%GJWT!ZpH6g%1h;B#hx2ZqfhxW{0A{e&ZhlZEqyi-boDHww=c{zUkQaGS6g_b#+Q zM7Th>Ubsd0sPIMMXToya^DzB*VS{j!@D|}q!Z(E-aKpoNdkE(UR|_u@UN5{`_zU5S z!q zcfOk-+Z!&A)z%yTaY<#2P!g_}h8f0DIL7p-emS5X^P7O(E&~pYSFvN&J7=@wnAUCY z&#?CZ#v$#oEVjKFIJVQ^(0B{B$n$D%cHBY)*vE`(-_=0|A;O(7|%lQ zaRlNtj5SQOy<{Nsw8sz*jSGf?Z<7bI+4gYx7Nz$v%J+_~1hn<~^c&pw&MX#TEak*azA zu6)Gq%ilE-g|+#+NaY@zzv~0^To-@WcNoxa{;tE5APaw2XByv!ziR`!zvk~60$^*mhu)A_r|3ermaU2n2ko8|914ZZwl;qThWjvwLg zB8!ZRzpH_rEyCYLLWsDZpTA4-UmXB{*URi`F8;2kSg8Zx?>d{#cky?D#VLxv>v)bi z7k?MOta0;qrEmbd_`678Q(tBAdzP?^=ox9^vm&bBT+;E0-Q~@pl!o#hT;qIuXs&JbzbzHjazGt1~ig zCH}5E*e_iCU0jaD&EK`1r9J@uu2b2{2f*Joo%yxM-}Nf}*dl+|1I*LS-!+G)Q8$0r z33Q;Fzl-eTQT$!oIDT4*zl%#H{5$x&NGkL5@ONdg1`+0Tv%_g!(=l&?zw6g1 zfWzNKma%C5F8&}L&ENF}6GZWM^+mrrQ2s7Is?-vH*G-IXiNDK2&uosrOBrv0ze^c! ziNEUxjMe7&yOi-3_`8(xAIsmRjJLqwrHses@9K%R-5>t08`0iB3x5|0Ra=3-YZoq~ zV)1vKhF%|wzl%#wv<81yd*=0X@ON=7x)}UjFJq*};_uqbddJ}JYG9ve1^%vuEOHF~ zEPmk{_`6oqv(55% zJxt|h`MXGUzu){_GudNe@ptj96c>M24r>yNzl(2zxcIyH;!pGZT@TQ65&o_q3$?%e zU4NmgV)1tkqEdvv>vk3{27lKG&bKl6ySB63vG}{rV&7>M{;s*qE*5_md9Gvfcb&uO zFv8#U0v#TMzpIFIdkp@r*QpbWziSQiZWaEn^O;>N{;rOk>tpeEeZ=k=;qT(>QL*^D z=F`tV8-Lf|IjCdtcOA=d8sYD%N6jPrT^(Q{!r%23;~f63OEIBD_`A3;bA-R^1dNpk zf7cc0%n|-BGV$&of7e#b84>=jcTvy?e-|i#T>M=mG>!0gB{DyUzbi~D4u2OHe2egR zZDKlyzl)2;Mfkfu#PI*={9RwO)DC~wAeP19@7hIAIQ(5)qAwmzEar6RfK0s`7&Jl6jT*7>l236`VY< zU~$R9>e|_hD(6vac9hm^^-uOUm%=?EagJHe(ymA1)p(<|3ca=vU184JvHo z@A9_scP*YLpPsrt`sA0J_~@!pi29bjc3ldRDWr|j3;tYh| zJP>mIf+dUR0V@z*QL}VlL0wHjS-(RWLejVbTpAn>{-QDjl+>0kI2`BkrGv{07Wb;C z$tjp$wydPKqM(0H!Epm}3M#6q3qTuCS&CGPDoemcG9Q6tI;zLF-31`MBGw^{#2s$A zqNbp1mUw*z8Cckk08=*iz^?n+k)Unzyll{r|uM7NH$b+y$=7EzY5uVW>4ZztkMoM(-u3 zCtMY~Jl;m{-Z4EE$!)^3lq!8lm6>e^DZQe%jrKyu_o|MM)Oll$v|9?;K<(^p7 zwXiy=hwBux7|#FuxUG%9tBt>FQF$AGm$CZ?_g8OT=gUDI>Xk3$Y#ndZSBLo43|~Tm z>cF-641Pns(h0#MZr9ev-(?sNy8MBspvKll@&}FNeSf>dZ~jg4cQs-pm3y6i`MdNf zWnca-32*$PrVeh*-xYmcYJ7vW4}X_dZ_M8%IW}4xK}@&tcNuS@FOcuyUBNE|zY%QX z@6!Hh;@6vu~;@6vu~v(2gcvke~8kbo3LW+gd)?lM=r;3 z4`&?H_AkfrzhUVy+{5UEU+%m`cYU>T#c{j90{6R4D`(6d(2()kU0)g1-5ZjCE5lu0 z42{3)!fVfZX}fvQ6WCAO<2$Bi95hyBG$6h@_+s+-Pd^%wpVr`gZDoGki|xjL^igtt zupuYkd@*tSyB{65>xaHNOw<3`L9L@9M#l2!GcW79pCy>sacOtT>v#YdBIh&)*e7?7sY6aVV_K z--R_GjM)5LFXM|47k}4%sHmI2i=U6!{9UhL(%zT9YbHZ~fgb1m9GTnvU70ZJ@ON#; zmmbaXcMXS|UHn~Fq0}z^t|#Ev1Lg0!4i+8$t_tQoG;k%li6_qplDpl--*qaA>EiF2 zgSxo*yE4%xF8;1pShNU#*I`T>;qN+!8AbTJdg5!W{pRl?>Bdju?+T!35&kaa?+Aa_ zYL@KZ!r%2KTRawj7wIB?I)B&k=!mVv-*pX}wORhIL9El3z+gDdlh->1YrhzAFQi<6 z#`fg(g;-<6ZB6~15{E#nHR2lLbnhA-^n#@_?&XxjRoW53W5602_e#n{C5}$PO2mt0?}ivp7Sz`MVY{phfsnUG#ov{|c0Jb<>V<0vPhPjs zP0acL_`3$Ol@EZwYYg*ik-v-N{w?!&)iO^ve^&-Ox0}DK14oCOzblVP)_6KD zNi(#LXQ5W&?<$~Auk~c!giLTM4ejOZcAY2V9wjd~5;-YSNctsCw%JA^fdfh8&b#8y z^mso;K<4?Nzm2=vljuW@GP~1P*LxC|BgRPNmBb!9QHBxsE^;ybJ_co(oCZ3O*UIqw zd^q;|I-o(b%pMHqB#e+k6`qCvi6>$<8iNB>0Pt)jum%zSE`D(u#ozS?XZ3jBA;_{z z6Z~EO#6Vt=vlj+!{;pmq3haJ_c8JB_bv9aJMc2Qh!e@5vh;rEcU2|ddw5}eM6#QLR zqW}(n*Dx55=I{CiJQdB~^)3@c@ppAWzdBIy>?;3=P#p3V! z3;fd>{9S)S*Z5iZyEqrc;P3haMrthnu7#KjV)1u9%0AHw{9WBJhGOw|t-@RqgTL!H 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%0DcX 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

kr_Mm1FV@@+s0Ti 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%0A!RlD2*=F=K%^Kh*GPw{d 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°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�}zA;!WbM;yvO6 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

D%(mf>eE>Q34UG(MXW9F*?9qu%23A@> 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%0ARbBV( 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

3kmN10?%A&Xtmv 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%0D>U2i&NG5~2=Dh&t%UqT=njpR@2|y=6RX#k0v% z-1HDq^Ko`U8)yGm8)3x9JX1ag{Gok?=SZ|Nn7qRs$x!dK2mjE7Q4LOLaqy3|=#B?> z@}j*WH+Csw^LR$QQXa~cN_#QrXFuJAJ!N+v2gbP(`t#(i2>lu1Ha9|l^67t!*58e! zK-_p1@9^R0Mzqy03DFg;AEVvvM(9T>TK|N;^*b&aHrjT$_PWtZ`0}A>C5-lf8?A&? zw0;TEN{)+$U3Mp2Ef58L8^#wRMH|LwkGj!@k&0H55N%jPG{?Lc^3`~X8*2c!qv{MG zce=68N~k}ep+5FUoR;{XcR#)B#yE@HU;R0YWS`K_GfBlhD%w12j&}WH$s1h%e3I7(5Pu-aIY;?wLo>Qnr~5$8 zBm7H99l_-dBVD$f?-o{?GOLD??x>e7_ePz|aT$Z>40qv6L*kNXcgLacSmu@BKdQO- zZ#~6-A{J>Kt4P_P`GC7=jIiQAXeVN;HE1Vd%St;Dse0{1r0ca4v3Wi1M7X7$hz-r# zc4YDO2;ZUx%>Llq74no61I;G}Z0CZaKz1uAyQLQu!J3-~d9=(tD2}DU?@UH2*fJ~N zWCbEnLTi+TWGs*dMKq|NMf0))5u^0huDl}8xyi0Be*&Ur&W?+UUHL?6o^|@EWEaHc z(x_4Fr-~-T>SEOT7@n$q|2n%+YB7)$bf($R0n9Ci#M;z~j%I;2pwqe>c~mCsl0YZN z#_Z@XO^HCJbLEO66mxQlkUp=d3m1qCo>ye5yLyRT0-2C;v^$|#N)a;8`G?GGWd2a4 zbmO0QOnFF3W(IRQIT41M&nyHE;)i))PIFDS*-mUW)kHY|KjZIWT594pga}DaE(cl7 zc1@Q$Wl0bcoj3FKA8pZXA*WMML{t|sl4cyq^nd7a)QqI+KjZJxC>wL}KQR*Y9ETD& zNlGvWlVvv2e`@yY=d_X846#nw%H0uuQBfx>UMtwbX`C)KajfYcP~2UzS*H{B_0Mrs zrZ|_|)WEE7p?>RmTk)T>3*sEU$PN}kpRmTJAfl6vlR&Z!8OS83$ryxoW@C3b?hwih z+NKw#AJ}hGoXGLL@Mi9(XpT*DzQ}5X&fq8xIC;g;Y79CXp*k6LKD6DlPE@Cb{}{XC z#J7qA9D}nVPH|r}h*nYcd;X{O)EKsu9fN_E;4n{#WU!a$@8&cjRChe8Tb2B{W#N<-@j zXTl#&LRk_*l|iUqViYOWP7+S~+-`wjtA;4~5UBhiUm(!gEyPw?C;*L0NK?Le;TUY@ z3yR$HC2q)X(3PwgOj|NuR zDHTTHYhp#^WY(QtRW)}W1PMs}?{1LZef7_;_bzqnL@h6?4ri0OdF9wI2Vi z@i-la&4TG|^Umovd@v=K@xudCpdCDQW?t3wMYDJW<#p}Vt4E(c=ep0vBx*cfmhcgt zpWuH`vr-En z*!90rJ2EX{ZulibChRfzSnMu-i}}2Y;@Mt`{NJc0$!CRdvB_N2KUPc9yy_e$BZ(6S z7Jk~N77d@N;xmRBB4g2RLgJ>HLJ|*3b&$WC$Zr-|?o@HG$giB}A1lrf=ZXu(OU0Gq zTJa9?9`RS=GvbTlo8lqyYw-kLeM9@^DlvG9>~e9EI9psKUMg-9e<40CekOh|rs6UQ z+i5O#5Kj`z#j)Z{ak0qzhghF?Et9+>hkRJvDSjv#4HD$@svpZ`h*?Vx_oDTrX}B9~1ed7vsDx@-7G3EpQGZJBlZZgT-^j zIpT%lwc@Sf&&8+2m&JF)L*ln$6gxWGZ7y~cPZo!W6Gh%~$?_MAM!Nxa7hJ-o|5S0P zI8j_K@}?=4+aPWgUl%_VzZ3(wqRR4(#6q!$I8YoVP8S!7Ml%8RZeN}1LBL~ zyW+l)xr0ZjRpZ&B)`!jfNiu0zyb0bO#;|PlK?bYl89rp31Ay- z0&tGXUqHgXP`pHbqbUi$(Ub&lmj6zbyGMLX{I&R^_^SA4@h{@%;@`v&Uc1{mSCso! zHotRYy(BS10=gCakp(&j@8B=2P>@uT;K_)&Vp zlf+W-bdh()v;0(Xwm4T@C|)4)rg@g%Dn2IuT6|V~UVK&jgSc0GSNu@iFMcL|C7So6 zNPC)UDSUqkJ6+@>Vziry1)`^^)=4&>DPg%&#QtKrXx`5vpZEW>++1;?c!79{c)7Sn zyjkS4n5=(?_zUruA|EAS{u|=^;zwd!{7n2t{7ww={V(b#iJ4+!v4z-5Y$q0p<)WvZ zHcs{gu|k|JR*8#5KH$Li*NL0OE#fxuVev_EyZD0ml6XLji{FUfiN|ZDW%B(u+HWkj z5L=0Stb+Na;xKWfc)WJnO!+ItYH^9kCo&k%(@-;?6JXyj|HI#C={G<4` z$cH-^pTA2%riz(jQ?Z5ET5KnF6?=+&Op0;(i{;`Fkq?eAf3CPlTq<57UM^lIdYWr| z$b|K`iI0n(=9+m_6ZtR5zgv7wG>=*$f1hkVpu%|Hi9vl%;e%Q9XNrx*7Gf*0omeFD z;TF~#Bp$EHHc9?zVx>4=Tp}(P`Cts=Z4mDe?-tGHF62KX`w8)B@p+NYV=)dNsv$oT zwX*h*|In$KS--&OYU zns8ix&8_qqv1pwZ==o968~8aZzs*t zUG%^_E+=BesrM(#bwHWp+fB!I_7-k8F8#53v1#*t)(m_W_7*Si6gY6Ivr3dvjSItk zB%0Tc8J6+buOV2yI!Idg;bMCuZ;%OjlM>QMTHCSXJb``9Tf7+K;Ye(EGcH7@qkn9d z?Ro9;^Rib5No#3K%gSRyiL;j(;vyiG{6PG_uK-fxTF?cqVH zg?U`>6TNc3Lt?4Q5MDW6KVaHhO1roZfqAyKzdQ^_V*lPw7%w(;egB?A8vF8mum0PJ zm$*-RZIKDPhn0>CCna!FzYNdrnRw|S+w_hNB&}iC|5`Gk#f!)9H4@8xivGRs6#~6- zow|4J-XpJJ`6>OfuATez=xK`ow0>DG4+0z(?s(haTo|)D?ms-#Up8>%6*DVl)@}k=@6YHJwHvR_Uh6+-X9o}38L=Ca*5<5ETc29{V)M6}op!+XrM7?ebDwYR zGgiKxZ?($-{jIXg(vSMSgyh@dju#I-{C(H#qgGyWo0893U;IFeMd90zg#C8U-ep$H zFZTQL?Jf`Y-}i|xzwQrd>(e)e*EL&WAN-k}wmNnFEw~`N!$&J?ZR1-~R}VdGg?$Gv zwZVvW@KWdH{k|)sHzco4S%WW-4*%_9C?Tc3ygztl^2T@ShHbZwq}$L(vPz-NR8}^$ z47thvRo3e9b>ZB|YHR)Y{r>#3pswU!|Ljp~#ss9^LA>opeFNzQq1ooU@*TuGNA`re zln&Oqm-qYO^=)|esDqLz9fm=fX?&gk8rU09W5YZ9{Tt4Ke+Qz{XKjpZ7y+%ea2YJL z6E60zLN8Iyw_yib8wL-!Ap^>554elHPghK$f*ur(#z8tCBJLi}!>##5QJ>rEF+Y8eW}I z76ntlCZ)+6qN{V(zfiWP%y-a9YP9jZU%s!u>N=~&YL9)s z)qpaqopt!Bn(&eDyC%0Q`RwtUEk}Iz8DYE2Jx9WU?qycqm)zGouk8PU+1DRG*e}i5 zeRf@!&ShAA8$$6Af_A}3t=+);midY7~6vQfrA{`sS+`PU4@zHhPQdwZ~r@`D>A>t4Yz5IN}he+?bL z)ZN$$`C}1zWS##!)H=uR^W4#3{@+aLGHxR~edDuf&6e~((9c(1=Wm~S@X}QO#tj2k ze6j2oFJoq!ZFHbmmcEgiW$R|P-W^_V9Z7R$w>YP1i}ov@vD=}2-{3!$9I%~pLTBu; zp-^TOjKIDy0!NhH{jUD~k?xN)wachsc6d*CqjNBj6<%W<45U-TEM<3i1NF%F6U^G97y=zGkbkT|C+z8L)r&L(H0>ALE&Wgmw( zw#9xn0yEnm>j=zdf2=r8!7%6t{e$d2UJv*0`8jmZ7W2BjIo5zrHIxOb{ z{_C90*G-4NgW>efx)f>Xcl2isKGh06wQu0UZ=R!x;612pJCwYKo*Fyq+|0}>lMY>h zThxgnUo?xODD~9L1$aB`hc}IB=Ql_}PmL3pen0+EPc0wu zJUun0(T4QY+!p;&UI&DpnrnumucATdskvrKbRq&nPt7$wJ+-zb5cSlaLUz)F_{Xd7 zW^8DCJR(w0jnCLbuf{*92+fSy`obcK3q&%%t}hkwvhW10-E&!hU)dy+yT_< zsk!YIN82;hA2QA~bxWc~rRlW{st+gVskxy_ql3B8_v*+S6y?zfJvH-nT>h{qZ@Yk= z+Bg)Vp4wy`lf}Yw~wg){mH@|o6Q`*o|GZ)$N zi(_xIedwvVr;?Hwzl@}wnp?g!_8!}Zo|>C~dh9{ghn`x2i9g6y1B0HLTYgyV0ZuFQ z)HpfRQ!AnkJvH+K4baizaYa2f9!f?}jmHM{)JUVJ#;?Pur`8iK7(F%qRtojhmSAce z>Z$R8aq6k{Hzkao8V?0`BYlt32^-0n>>M@{fAlHf=cdhu=m~zT2>}y|(&cT>WMsMV zxZ5@qLVbReH)ntDh2~(!>4V4Rd7h2l%|k5esl9-~3ry^F~Q60>b9$=HX6H9>De z8^HFUr&fXXc}B0-Q{&Zbo@QhG8j5;q?14i)wTqFUo*F|KJ+wuox zn=Ao6HP-<>H9o;kJvG+>J+;={_n@cdwn9C%yAYneGII(&HQMZyv7x6%o0r;+?dhpK z2uG|ba;T?9gLBR=bf~BH8)HLHjVDDKrYiK*xN&$O$#(VBzJj9}&pOmoKv?Lfh_U%`hh08b8N9^nc2=?eIH9Uek!85zmEld0uk zRLRKVMIFv9U`4VsvL7?HFLoHci8RW{d>54{yS5oEMjB^i{?XWBEA%ug#4-XOz>&s) zt!&;nXm_>wf`Vt0(I+l8e@Y-9QfuApwoI18SBACVXBeE_-OgYO*T6BG&O10WJ?soN zb1~xZo{a+jIGEkj&U_UmPQ<{t2@2UEySJUrlGSjWPA7Y9_p#F%^HvmCkG1exI{UgM z--hE!tgYuSfl}8=uJZ-N=MR3ho)6&$zHi4I%#scz5j!mf8a*4EHu!#RnA*$b23k`+!vm*8wf z=X&gwbFdcj`(`+s)A=@{zJRr`f^$(~7t%Qsvpx+g1_KGS0q$UU*Vq-V6B=j(?8cm+ zzr(?w5JpLepbfBd=^TfPiu_KXHEWl;L)-=XY2!oXQg?_Qu+^GkZOyu+c8tURCG2~! z78*Ubf$p#~a8=R4T4?m#2HK4{7n|X@j!vWJHqdTH=gc%5Cs?sp_C>e;t&R47MH?+@ zIpMy^CqWtQjI7?+kgbaBQ&T+ovlCN}5lf>mT76+p80`nd(kP6U>IGG~*8hrF8uluD zV85_{+=t@=%4eJE_0gEYJBWE6G8rgz%+eGV6rBjS%<4@m5(}8K7#hHF?Jho_ZPN9g z0{9{0Lu|nc{h?b{yp1A!Q8WedTeYiXFzg{DOB+*-~ChgDyN z(i0q-&stqd4nsd|YaGD=IM&kT2_qTDt;x~U*Qe3S^m`n7bIg(l3rbG}H?H6M+#bP? zp+B;C;%#0w$BqRizkFNpJ3r{+l=NFdF6@MoKNG*gc{~bBZ~gsH{<1uskg| z%!N|IgAt(GiLW(CR!^IE4_xS`w;nhj;r-gd!p>W$22EnmW6^)`JPLvR>yS8@#O zA4)fL?fitUouAM(qXoz5Mvu+>yZxD8-yik`!L%e=w%Osi10`9v;oYvgm>migg4XCY z{fcp3U@Ztau$aoSTrxG<(iG^2vle?{G+L%RBQ1t>J6@Bi8u6-HG)%&m4=F z$25->=6MH8Vl3~dN%VPR3L?St;1H}hObML_2O-(8Xv4u_mQ5T5hlHSiQR5wh39wT&+cJpsrZ)CW@dQAx<53ZNrIs)YI@ii&a93 zO!68Sgd&Mou;R33o7d0RTtC5APYEe{FQmr{DSA7A*Ew!{zEkq-hLip%p8HQXQ+O6p zjuqWpQOg8(0(77A#f6rcOr$;X^>31~&nDhB)3bVudHs9eOxp;8n;mEUEi0J#&h-;~ zD`oslq`1>LEC^9arn_Usn+}3+N6>kb zCU}^_&&|LoN0QAPz={n`@KD3puc`k`5eNp&SWv^flJX4gvo5M`I8$F_&eZ8B0RM85 zJwV!=sySCUZJWvC$dIl-`SQeL7BeQ!7+(s^gDiNJB_B1doxg;994n@o;7bF}=%!(& zv2Pr{DCoWtW}*?-?w-rE+nM>MGn`&@%*?mjnTzT>6SArA=$;=My0Of3!)T=+(c+bZ!~Onaso$;dVSQEU91UPcdEuFW)e z8qa3>8m!n>hc9A+O?odv-ma6_fN2^3ILjz%7LPyPC0-v!6Q5kf{ygCsOvJHzFFs6v zX6&(R{NvX6nP!JgO(s@(1{3SBdc$Cv`=lx9?Uly(XJf!Vio@7F!Z;8F!180$%8iMT zbr&%)$u$m}0d4kjxP70;8noO2F#WEVNh!m=SiMZ9H9EwE!2txVF>Cy&?2W;*|Jg8d z>${EtY2jHbaY?lK3|{Bm5-Sxm7l1SxbDF*n}`7{(~61??@TS#e&q^8#eLA74SK zD`)1aKx*)V@<8YVO5pl!2zQ0Z>_B5<+JS7cJP=hbRM*&rmVwL@0+AVk%rhVamPBbU z$mCJeFbi5}sewp$$Yw1?xvqhvwy;{ZK#7)6JT%g2mq2q6YJMFlo|aufLBE#NbvqB* zgss7)MV(t9%Sg6$Vxdl`$k-gf0(*uNt?1}f=Q*iG9XoYEq(;VLSBnP(<|e&l;9c5G#?D{kh*iUZAqjRPsY1IjveZRT6W8ho#6iNq9V92F>b1;9fcfRF@~M*il>FJFQE18qCgaTM<8fp zY}8n*vCBCSBh{9IZiF*A&dLw4JyH3MJnUa)pV{>jdsLt-aBLIFK_{IGm(GGQkjON9 z3{@)^aDJWia!3SnD`b{CbGdD(t4KRi?kqN2z}PrgoWQuivwY*bS}*6i19jCn(f-^xH;x##K_X~%+9$0 zlWHcK$0FuAJS>oWB930?Ez1;8)9&tMdhz4QdL2F=KB?Jr7tR?uc|Nr1JV~YhcD1~T z^*VO{{knOcR8{@!MZIPfUO4`llHRfEc}9ru-_*K z-$lKqcbwC{Vt!u78PgU|uBzzRHLv5)Zh0Lm=FaN~wXIoGQLA#+&<>ot(>=j8f6Qn&6+lA?yPF7dh&d#to_5zYW7hGMb3gc-Hgd|=1evc zlt{Vyah3Bhr3fl@NNeI0D0D%;3}R)Kvy8sk!b<9}jT(f44F~XoMYAB6ws z#Lp^bLAMP%{ePP{-b5bOX0w@YLhN!1TNpHSz?l7RjmP5C1~dTt2&4E2fh0y5ffhFig-e-4!azNyLjr%DVW;Ic~hY4Icv`R zg;moh&abXQ4kZ3Am_C`QifNUzrp%c*Yx;C_-)O{D&zdvcsDMsfICtTK>C~R9-?nq7 zFE)~QQ2KzzUm9+ zPsik%`Sf-#oGv)8bBz?ByLF7FsfA6oU_L%HRLq(_&E1OAv4d7XrPXM*LceghuK*=2b1o>(jAo=PrFZp5Gnk)7kT? z+UE5s>RQw#kIpWgyY|RyQ}tib-Rqq2ah0D|e^7UCVCp8@nFSF&D&$%JD>d@?m1)D$ z@QIwh|BV`W-gA|l^J6sdjyoek4DSce`M8*Xo49bAy_8L0m81Bi=7QF76a}i*Jhu#J`HXM$PykF-tr_ z>>>6Ojm{3rFOq$^c!Rh_d`Ns+d{O*F{F@lW)gZRd%S7a9BCo~LHaa#S@BX5Fsd$5U zySPn!MtoI#NBmUe6(`2wC3Di~%77=y<}(-c^Oj+9rg*c+JJRU?rO5mCX!DB_GEL+! zhtf7WEuhh50msQdOI#v8Ebb8B6Az2LOOWyS(pkv$%#4E&`#e2k^ z;_t=x#m~g%I5rulqj<77SUgvpBVH(8E8Z&pTzpD=Mf|hKA1GxzHg4V{jeZ4~FT1-q zP+Tnnd}v!(NjQtqoaWGYvnikcJSXN+vwaO{{hJp|B3ju_^lYlIhg&<5L=2y*AD(3vipce&kp_Iy^^dqL^OJK z@K2OIRjd+?ZUV|Lqm6P`$bYrCO8#49ZxZj4|3TT0h|i0>N0a?{OEh|Run)`rLiD3e zmJ5qHVy?*hI+@>D>_KAfCwrh+F8^rRTr}?s5NC&M-lxR=ydu6X@<~Pd z`8_z|^ibiJ_Hs0hKzhBG{8;PyN)?z2Io7h)8MI0!eA@VzXwmVupUf-@#{`uks z;)UX6;!2S>$}`^WB5x$2eZRgyr(>5c+taaYF1tYF zjUH@=cX*I}#d2|oI7%EVn!9ySewys_#Cf85ABFtoviaZv<6kM>Al@Y2D&8)>AigC2 zL3~r(C-NIg#yun+5x*0e$2B7I5h2=*#in9Qu~0l-&#sUBCyU4H*$tI{gvdu3*iMaj zrFgA)lej^=Q{>~otoMNUkm%{$JtO;hahK@n+`TD#pZI}zNIW8bBYr0a`2G*+h?prh z7Wo(k^G_3pi=)NKqIutma`RgLd@y7K_CJ;%TDMn?|`2vj3xccNePO#p0FXwIZK( zVL!|RdEm>k_lWO^?}>-RBjVTMw_=3vqY)=68hvZnO=K5}ZN)y~$>JH}VA1GbqyAXg z)5Tfh`J&OqM!BEKzEZqPyjR>Ndb)RfiiiDuSNu@iFPhH<$p1q2QSo~*jQ3!ypCV?7 zG11e#YbCq0Xg*J%UVqtT;$ZPCahy0ob)6w5VY%aDDJBZyxqZ5wuC9+G!GsU6eIB|klAas9N8y`cwpC*?;v&-dxB*i0NXkm?yRs zJBmHUz9Jv4WSmNIxmY7!DPAkyByJGz6z>s#DLy7{7k7%g#n;4l#P`HQ;t}y%(Z&S< z_7iV&EFWI`z3T%ojUR8D4S7=}%VpEXTzS_I{_}c}i5K?&?+ZhE-(PSZxpa3?{~sSu z&C(M8F_rvyYL?^6F^|iMSn<~6C(Cs}8P-W`cMP_Zw{ZJ$ITNcFoAxy*!*hzaczLJ6 zfwv4+i86NL0#G{ki$<^+mhsrHv$1-0khDS&_iOD9G9hnPLYn0|B2W|VWLmr!(_tsJ z`&u#1r6|XC*`C+#5~RI4NLpoumX*hZ7B8z-i zuRiYzg!*`tTu6+!2=S<~;w@etzaL7BSAcjNC;NxPt3KYnNV867tXzg+ zgY&m+yoGsO9~QlG7eh~RsaHsOEcY9wy{x~ZT&ZV(-v06w(uw`+kTBj%m1BQj!HRu( zK46v-?9hq(G~47tChQ(oH45dy*%6~ScaswLmr zzwVE|jrN9SO9E?B4-QBPZS);1_1QN>4wgo!fcHraRO@cZDQjBRq-;jnqO!u7Z`4`a z-mJ4Wy?FGwmb;EV*LgZTet7(w!rj9?!@WHJrh%XAiQIaBY3jj1Qux;C4;Gabf9+e= z_iNv;yMOIFhoydt+V&}*@A-W))b08Q)~6o4IMw%gn$N%ft>gg*N(Qv7^LKDQPjgz< z`HGX9``0)d?UNj64*H-uxbkCrV|m&77WrjezxE}ggwY&a|8erhC^QEzagx`hY_!^s z++9B>8?u)K+xwvjSn}CrH4*3nUR-l$i*v&Edb``{WzfUuO7%Tx7oM{QGxG4k0crl- z_WC|w=jXMo%g;;NcuRQUZmU&r-G^2dw$V=i`DMH7tnH`GOr06-{QS|E@`ua}cX|Hk zZ}YF||Jk14x;CZ3RY~j8@vvZccks3@U;EDNi81dy`dq%<`)_-E>my4z<^lav5B4)7 zPTttGCTZh@7QT(!!nHG-?mpW5&V#8={}!px@bkAT{?lm(Qla11d(Q($!ggP5za!Lj z?6$7|`=9s**6j%$+#X6jxIMM;VJDcf`{}Q(&L`E_r-YF5bzW9u7v(E?FjHb&MNJjzZIYjjLX)?>WLKF*eRwC^moU@!Re}Ia9PG9)_ zLz`T0T%mX9dYQ3iV+IqW-XAWX5Z^9V~5wlo5r*=5M?8c&FrQ(ha)G_DLewBj-G%bkuF(GLy(4= zeUYwe(I4eC$w=2^w*%p5KVxRQW=eEB;zYVOb4{b!7wMKf)&!zv-yvity@!9Z;4)*w z37_JN1(9Ci@7VTd_!sFD@y0iS@%qa2M@wj)Br_c4_3}uu%#`R(4(Mc=>Cto9wNqqf zM+;f^RGB$Z{>DwDL}qTZmUa8d%(F7{Fz;bIQXU?Ja?#hZZ6jwUF^w6C@^?QXgCaDk z@Dz<=qeq6Afx-4g`TG@-vt;8L%cPgl_IQ*wLxyHw7+qUsN6roN3coww6Ee-!end}) zFETOcPJutlFRvn#BM-m}Ijbl;7Maq5lO@eQ22Oe!|G27!fPW_pX!c!$u7)EE!+eN4 zN>Rheq70@v4E{_;Bp&A!N^nW{j|zQ|+Vos~??rywyoWIhqF1rkyQ1dWX?~k1zx#;17+Gj?UCqA8D{9Eq?2Ejr0l1odk=<&y zIC?un{UKwSsas-X03)wuTy4w&851j~;0RTy(kO4ri0oC}LD7%c=eLr20zPQ=oyOdE zGp_=u+4nn|@2C96H>Sm8Plrp)iDpSiFLt*ArHhi0E^hhwYQFf{vIJ0+IP z$%AH}TR%O}$;nVbJV5ndPC`=jL~gz04gSntc@7qGlg=j0iOQ-2C3LrEDLX zeM3xsajX;LL9@?2m6XJ;q7BVHw|r@=lJ%k4=jNXt>%sca>@z=S5Dbi^6 zZDmMk_VG7k9BTFzGX^yKcyZFn|1^O4=b_+kq)sT6u#t?(&Y=*$j1BntF)7>bk2H7C zgranL+w&w-i1oPJHWWhrNpP66Kleg&Fyr(w03|niHcsmN9ykKcK7P-avjzi5iR9bi zk5M9K&fSG}1`QnJv9CB9X!f}?=#Ra_@k6sudjwkKzyp4U&$$F~QzNI^;jVaBADatT z1o~Js80u7R9BB5rb})7YXAYWu=0%*EeN6O6VRgI7?nsRTOedaYke^`vFGm(|P zrk}$Pjm+5993?dS+yicAj9&~zpxNiz^J7IUf3;^XiQUKcpxJj5+UFTPHjxFc^`+l! z9MJ3=$OzEvV-JjG-=A3mntcpuH2WT9o6ziY9nkD6q+_+`fM(x090fG{+!E02Tgnp9 z>~kH^?Bfk)5oq?gtx&V?b%bZH%$!2Ak2X7HY-sk;e$=z6*%w*w3%v(NYyom2(CnkZ zIp>cgMWESt#Msd6|?8L z`;_1_m7v+T0r$Qz6)wet8$ z(aw956|Cl$!IcEfz6VeWntkQ;ruwp8MVYky@P(d6O&?VJK87cBl=~nA{Jw_~@H0Q) z{|f(`r1*jv$-LDH0)D=5hSB`vL~~wzk&J9A{`vBKG4m@{Ng0{uTLYYw&A02x8JUex z6+62XDrUiyj6h2`(ipIn-4ELaa&^!v_mD^v1@Hy#-MzH&S5DCUkA5kE6N z2;P<3S@bP|uL`Tt^eeYx^zk+K9;}7;a6Zno)57Qte@(3^)S_!QcKi4S9K2D{)#@8;H|DU<#-2S8YvK8B=OrZg z-Hqb(ME)D7?dmuEk#VlFQ+6}X8OVAMC3z=ahtV*OBJnj=t1WA>tYiM~Wv#32lprpF zn_B6ZxKymBRy!oxV0HVGN15&Zfb!&qbmVYr@!B z+c7cTXPoQpR9^5maV|y4i&>RpzZHp%G#G~)e;d|>IJ*9Yqm(za+4tJ1?|N~5i;~Z= zD&xF|#Gh#}&R0l$fi)oxYda6reZB(u@0@^SqdG@CjIK0Fj4^rYR2oBAw#TdJWZ2mkityCZb1{Ba z%y}=A$_PCd_k?8S`=L~pv$|GRR^e(*C~zCHtX>Rc-d=DMXV`_QS;S`)dl5L-nMSpTj>x`^Un6{LxW6DPp%TwGll?~#&-x}rd5k1RxQWN86NDS1( zXZcK1BGAx-tVY&}=w@~!`@|Ht?M49;t8slvbe(;QsqK1U(VY6$RHBJGE3>J_DzjN) zeZ1LYi;UYmQCsxX6i!+TKgMxNGN;lN9c8%_+F-7DV|1QLVAL%&y80gdPfDGhm~4*< zvR`cy`;SvtbGu8{aQpH80V=JINgf+G+e}}(fYl{S(y8scBaOq1kgH>TwNb%_N=0l0 zNAN#n;%F?w9J#Y|VoIKAqD!K3EB0`7tX|v|M_^)wGqT(&-4g|1arDHz9Y`CkXW|s& zFyRi0BZUjzVc>=KLc?q~T|h1}XPOK5nFIxbP^f_9yH&`%?n9YlmsT*L%SX6nAfA<2 z0*9oOtUyQ$A&yyc@gGu7#6>1Kwlj+IT|1<-2sb&L;FVN}nfYp&;O7IVR1vF8a_nY+ zE0x*07F+;LN?H$KP4YbXzS_&t@^x4dp5RkVj&*^rmWfTS-*n9VCwWr#tU;W0r0M8z zf-*>uj@(A!!CD#}>K$EkYiaP(00u~~ul0p#OmXvwR5T4C&p~7+RwI3e?*4!5oe6vu z)!qJQ?%X8_xgmkX8}>^AC`&>@KvAQHEwTy{P^xGMA%Q4aOv0uJxG&Yp<_2o4d#zTj zb*;9zTbCAEwN}O5R>WFRTT`+1|2$`&xp!FHYG2>>{WG6TzUO!5>~m)3-nqYdhJ(%~ zC-TwYCvzrt+nD^{&or!p;7-_8j@2gwYNJZ?Bpt6sP(+*t9ODLwIanQQS)h%9`K}Rc zV}M@b*b+7k`w0wWCiwIh#IA@3utM%G*v0_c;nNy(+d2er2k|K4O*96ANB1sgXW2Jn zxJlVjmVkxx1~<9QVj>wk6zic_Q=s2i+-DhfIxUu(ZY}s6OT>-ktQv_GMPIkv8+&7T z)5e`7l-W&AoOCmBOdR$_chu^R*U`!GIyyOCi~QrY$Uk0-!fouAJ6=Z2#(kDDY@h-a`GL0AS}b>rUz*dLRg0j|)%CHSe%!I`R!fzRA{ua71@o5Ll5 z9PU86`~~7RVzsSf`Q5?o$gynwXINA5>-yS2S)a0gZ8XzO!N+p2f9ux4p=P_(432Or z1R#}%rrVfl$ZZzZ?|#{O4uqE7OMqMJG3^MliiowyGIhc>3o|jBo0+5k3|1&ua_rxA zgC7G-l!}8u)zfsFJe_0ewsWR8T&dPVFJW@frn3|-93xihR_*O7zc?HB*hZ|Lpc=z3 z`fP?-rMI2ocAw2K2glp)?Jj>ErYWW+$=2Wmj~LEIe@fbqV>P86xhBZ)t3I1y4zstN z;hEUs^kTqF_>pJ_ z;%5M}-JsVJ--#n}s&LR0vm_fZlMQ$nD|Dm@&UVMbc`-Tdk4`pVCL7Rhk}M6hG2k{} zX0ib@lMR@O?Pf6zFr6O?dmb8!3*!`$S5XR$l5V&taW!R{?$snt-wkX zoaTLk;pMHxsLduXLQ{AVnt?ThqZt~c49>!e{YuQniv7L3jR8vhBA(z?oH>dM6Bl$2 z6EEys16GmwjC29QXfE*s6P$VpaJ3suUd*QOV#Y_j@EM2LfYs>6atOG1Q`EKG3pU3U z>4_rr6DR3gmNPIMD?aGlvOHYey^Y49STP_3$HpXN;21Za;M_Fv-sCWbS6dj_Ei*Uq zmC_5NiI_HtLj@nT#!^n#n~SN|sxqnRevD*19x-%8nyCvz%7A-zJ&LDCKGNrv!te&H z7`r!tcfC#6K@7K>O;dq4h47NIQwx)k$tn|f3wQ4& z^S`-k8Og{*J4}+DE@p^v7jtUjrOnq4gc0FJ`r5$=&hOpZ;cfAi;n-f}Zl6^g`ze(2 zj4A2ELv|iSZ;Nl*C2tU#LB!?GYrA8!5PqtFWbvLNkMbe|iJODFmJzU@L;e>{8Ht(h zk4%)2yfL_I8J7Jq^1H`uV#@j>6Gvgd=2xGeV#R^)H7=AIu=$07E2b5nurObgn9Q@i zw81?U&>`TM0!F$S-op(OQwP6Up#Woh1z7ga5X&vT7T6|&CuLtGKj*W=@mRfPFdvh7 zwpVI!PX%Iby!CaIGuDHBL&e zu7&@j8k=hdd$HeE|8-`4RrS2OhHozRwX~i2g$QMvP&^S*+z4lJJk&Q%3CaxUn>r`OA*Bkz)Sc9Bsiq0RTc~rU zhMkVkB#q^C&X&$?m(qCL>2*4!F`WsekhmQ`9{Q@cgj_{Zh+$Hh)YG_)yBfF9H)Sj| zPCJG7hc;#!MLM06YN2VH6vu3aIOe_(*IW{Z{A~$SQMWZe7=ZTY4}*42DA2ca5L%+n zA5O7NSWLhk$7IJ~<^}TsJ6ndRdFR;iX+Stj7jcc!^tK zxUewX+f@3tDZjh35|#rs(?G1ZSJ*q+bkXjc-cew$-?$35D_aRemvmG|7q!2OAg|cnVa8yzj z%C+r6OrDN*D7Sa0fMv)gWa0Gl{DK7&B*PGk6Y&4GJOL4Do*|FBa3ZP(PFn}I!1JFH8gyTihz zX7Xa9BzM+k9IZQ5bQz8>O5nQtBr6ViTN^v3kGo%n?6wbXH9EL2TQ-jM>_MT_zM;%+ zIP~+VKyAwS*v#F31~@9Q&Y^Bj4|Hvx>`)-r%vDUNO&X6+aTYPtxTG`2y&GnlQcm$w zKDQJHKb)FTFcgVX$D2y1P3u#vr8cgqc$c_PND-XG2?5;{=b>e#p$@~aBb(#B3e5z6 z(ZV?Gs)9^qVON}3J0Ck8)53Y!!da^?iY)T=v#-CO{k+!i*3Z7|MIRpism^mt<8hP_ z2s`IFocO-(=Y|WB1Ow%DKY$xhc4cM7q=_RYj<)^<&E4H}X>dENZhnr5iEmP^XD zW$^!g*v_zUo}dzdzy#%q*FDg5))$akjgr0zG~c?hP7BwV}^)(G+2f2;oQkvNGpRrp1Kjc%}i zzwTMwH!(N<7bJb>H`mOqT!4|7I;O%sk?eF1ac3XoW6jK1gnfa@g8zF3en&09@wQjs zx4C9vT?;hQ<3kQOVAz2N9%p{V<`2F2y=rMjderE?dSB%ErGAh4zGE|HImNb-_Z?A! z)K&Z@YuWwzb?<;N1(U3BG%_hQkQVL~%(ipvn3HRFvAf#cY`m*HkmtX3VXE>+1g-7# zCQd94ZoT*yN4HMAIEPkQOTPujQda4_T_kgfwr&t@Uus4U!2A8-5Xxk zxN$_nJqXTjhB;yv5;wp4l1Ma2@!WMxKU^#qCy3t@j~C~QCy8`XVg574)#9b%_2SLq zz2c)He?4aYS493EOZ#JyyPh_0h>=~zUShGxXA`-7lsH+e5l<2?6>kvl79SRQx0B`Y z{yzDExI@gv{$c#SqS5|?eS+*oB7YlWx{Jl@#5=`@#ZBVtqS5F>zRzVxF|}DvcX5zd zDjp}EDDs&Jraw>Q^Nh5g5T6s@68|omH)bLopJHM9F1^+u}!J7H$l& zoVYkxJXGZ4oZLQBHiI0m$8x8s2m2I@oU|)gzTP*iS;yvOM;_tS~?v*Kp)&*DGDj&Q(dy>YQvG@4w9uaG@QTp&IqZW7be+;WT-7V;UbEAR}( z8%-+M*UG+GyiI&qd{X?i_?-B%_@4Ngn2K{3+kcQaUOYxTQCudTLt>76U%ZG!AFdT| z6mKC>?!B@f5Fb+fv$8jdMjHz0-<17FaVv@VPh{^9c|vA==miog zl6ah0CGuecmb*YaOFU2f0g3w8$u=5L90$eUruaL>dlmnv>?g%Ph?_;D{e*Ii_7nIC z<57=;mF0B#>3mWT(4W#VYDf zVy@U-97v*^VsV&QuI=N+3h`*MibTG-;)&u?ZC@dtCtfICBCZpEM53JA#5=`Dwf#wP zllZ*&s`#e3okTgGh&#k|d;sM*WQtwH9%4UnfOsH@atz!LtoVZXlK2|Q^MLI4#ZO6`15!J=+($e> z952?0Z6ZGIn)>na$q=VgLky>3u4sNZMmzh;?k^UL!^H985h8zkXaCISdGK`EXNwn# ztHjI1E5vKX8^xc9KNWv2{!)Bgd`jFTJ}3NEc+hu=OUjTW&3|8z9iBc zm+`nW@AglOidmxho`H1TW%m{Pi$g^7{R8O^lRZl0kM*qQ2ywb-#6}Q5TXwC;XIPou z(=0dNUtpiF_%-6C;^X2|;)~)d;s@e~qIpah<(cm_U<$u?fa#+7egiu$dx%K&8m2o$ z7se(3AWFcT`M+gotbG%vhLh)4bG|_y|L;fGgzF0Kh`w)MP>>I>e#XH3NMZWQ#{di3LmH1on1#z?Z zhR8fz!(vo4-zyQ$mEBz&D4Oq?2=6cZAdx~mEN_fBQJf-Hiq#??w`O`zll%qre^Uf!f(=2kH&>kh4`#7+VlWp$bz;2dJ#RsN0_isRoKG6Q5NZkk8cZ*Mmo@O`29k~4+ zk@^m_KNYFqK-;@dLlFns{YC0H&^}b8QUh&Ii+dJrj0Z&<7~djNn}PPZBIOxqUn5eX zf%ZKjH5h0=BT|Newx_{OB?j6%L~1S2&J@l46xil|3P{BTZa++W4M=TPD zio?ZHajZB|oFdX=o$Z<-&J^c~^Tj5yRa`7C70(qf5Lb$8#mhwRd->I}uM=+?@eTl2!5j7XD+4V*3 z9y6aF+A0yR{I&|K8|&-gU+m9S+gw$TL?fn7Dy(Y7Yr$tPXhpGKf9Zy#_)2bmKV`0= z{O4ORd}is5|4fIkXJ*+o9k+4W7c1x7SEU<-G`rTz-+sM?^Ows6tX|o)+mYr?+%xhP zZ`Uh};M9Sy)*f%jX#Trja!R^Uv!OHkoor=JBVy z7wzLyS>EE+3r+F^OXA5zn&j|TiN{^-arb|5QPKYU?;npB7Y!Re)Fl6EP4cF`rnZD8 zc^8}&+wa=ECA{>39Up!i*pdBc>wWu_kM9{OpFMiSiczyxTfNJNmw*1rKR>^1R$)`T zy#2w(ZMN0^-~db@cWi?8%V>D|Ef|eSydv$gK>YbdL_3t`3k=LP*AhErUqnIh`4ePv zZbbILfnE4ORUi=A%ETuzJSn%12!?EAb%rs=;L~nY+QcmbLWB9?vi}ot;6QjlMG;&9I!JY|aB{1zyBd>+vs`*X2z_g@W(m zf7oc{IoX)Lp+OmJkaI6LHk+`~ZVp4c`7*?%1VcAC!%$`_H6}wh!Ra4is=tPQ)S2;C z8hg*Xv>lk9+RdSBQ|n{5H(!scxsjZYUBko=C~t1`F`AEpNe(@0?=;0fqi;9wZNFJc5~#{s>s!Dj{HU)aJ8Ew8&z*+7TNdp` z^SLbZ#=U%3yE*cE6*W5g6sOZm$~!UoB&XubX&;#WPB9whkyks7L?UW8^Uh`D&GaQm z1TER<8usYz3?9MMZa$n9y`#xS?Pl(4X3a7GI9qbg;XlS>zt9h;BRB2yHpXPXU}RPx zg`*QYh2=uKS%*vPUJeGdo3A%L3dU~dc4#-dc1r9tRt)WC*G`Yoktzc1W;cIkjE}-b zpxyi`u2j@+E@XOWH@n-5Vo##d2(+8cjT>k;-^%)+-Ry239vjGA1?}cAK7|DGOJmd> zk3hTGJ(ZNj=CgcgH@oRa$8wn;+Rg6vv9T?*q1|j8XrSHP#$kkZvzvZOtQYHtb~6Wu z+Rc2)Wdz#I_nG$2i1E0JK)acTlF@En!UCb)%wxo8H*-q_+RZ)DLZjVGU#1AOn`fb` zM!T6e#Us#e=1nDOH}g<%chaAb+P9O8$;M$PtwozcL5@(i{V8HNL48RXL{#-8jco8MzmmG~Edb~6nY^%1i|yV7m{19&qzw zydfWfcC%|Y#fC9Gw3}UfaqKqM2kqt~P(RP;v9U}5?dIc61hkvWSOT=0*#am3YCCof zQ$V|!MHubo6Ids-o81U#H}hA#2(+8s2xvEVo2LOYyD`D|{>V^}2ReM48P7fqMkm9=9>1R-E5H?D&1mVD+Fv zdX6_1(mU6K*LC^r>?&-Wl*$9EBf&xPjyU-7?7dTLfy2fn*8ZxT{vb*54V_X=R8 zW@lyp*w}&C(dbNSPF5!^wdVY-=Vp*Xu66D)ysMJ0z-DbnF`jf84(3oo-{MP#AN+^H0YU8ELCVqQd@#7DYkN zDa&wc#T?^;V-@SEhCDtH&Sm_rOCBPmEm>%S(}^K&EWykaJDkFUWe-ananKtgSXRJl z3XnYL0?Z?v@Y~Dpaqi!dy5KkjycNL7fhPu|ulS+yUtFb3{SG&M&aUYYU z+67MaQoBGXp>~0ALhS-O+f%zhwA3y_cn~Tnv4IPB>Ffn~u(_bF;ZQRjLJ1{|$1FUv z-Z=+C6&dkRry-&6cs#hhUnm~#M@b841@PH(s$ziQ!Z>6MI=V(E%`ndhDmX}FhqFWJ z&b&CE5#OhfW*pc4ul2AuZktz58Zm8bYbNcNb?@kn6F@4mi zF%=bjr1f8YaC^6>w0CdE6XBUDq6)1WAg8t&jr12v;pO`VRB=A6jKJG%E2QmyEiGN^keziEg8#flHTm zgsDU-5<5No{nbx>SF(L4n)-KA?2sA(A8dEem~(4dF#9)Q)W(SZakr;y0vBI;iE=jm&{?eTUZU0H>gVCNmeB0 zS7nR40YC4yHlA2HzY5a}mkGb{ff-KZt!=1kp4(zcV8m^%xd3aQ?>r8BAM@VrF>mvG zr~f%`esJ{`en1_Ok$Xn?%+OiEvz>DSaD4wye6G8P*I>is2X2~9;#Yh(5#B)S2K3)C zzfvZn9Nq=+Ee<3<{flGahiu>Cm|riG5srm#X}-n5liU8q!LPz`MDPm*$CuA_KFB0KrS9orZ|~G+>Fj_a_)RPgRpa9(ZW_72Yx5bDEZQJ{n^`SBtlZ_ll2-zZHKkZV~???hqsV%7lLKZLDN}(RK_pKmRbFd3FQ5Q#OAZVEk+12Vx$+5iowRNHIm)lf;?gi6W(Ex&1uxGVw<7 z9`P~pIq_|gzm73KU))9Ji{@Df*yh;>aEjuWix-IN#XH1z#ZSZ>94;)EH>JoDain;p zI7_@j{IO_!_mS^K*?$uMCWi3shvjCAysJr@Z<;0R#Z$!##Vf^I#RtV_#m(ZM#eaxV zOn8>dR|}H`;vwQB@i?(wTqa&5UM=1sPQyJymRBVz>_bg@QUAf6>&EM70(Ej}T>C~gry6+7U*G|M+W)?k6`CE|JFqoVhW z_g`cmj2lnPKVCdmoGtSGZQOpcxI#2O#fZN^w(%*3eTVFO#0N#=JB;nWlKmU;dGQsI zFBfEey>JdAjgK&RnCvOy@!|<2=1PNTe1OrnvuK0oiN@y_Ru zm$Dxb`F1+S|4z2?{Y5#iDE?21H_wP8ew*UGXT(3(_8{&fv%UDi$&|-e60uw^jK^VS zh-gDzKN!ECI7loJ4-k3lf$2tywcI6M6HV+r4K3Pn6v#(v^nW z&GiGsY2izKOl_XGkuIC*GX6y$OFB|QU9Gk73qKI}-5%>2Y8yS*$p0E=%WfDS3~l05 z8b1^H7Yw6WdgDLS;j(3xUDI(JmwmC~RQHwXijZd4di`bcxZ=X&2ZyIshLy`Ud_ZRT z`(R}nuC%9N_1b`-c@JG-Iz#T_ZJPqqUtT-PdlB=5<#A4V<;_Ca%Y&eG3Cfz{4Tf)9 zvoFka^btSLm(dG0V4J_*jd_-}0vlN`AzoC~qyoULFLki%=f^5{tKOC1U*L&GMDU)1BA88xZ#Lu#h$s#^+VN#oKlbBK+kw zp*(ND@e{mP-cJ!`o+7MVLiqU3=fb>&+qga`dg-q0x@Vuvr<4vbOD-n3mxmFom&@Z= z{q0+f_Mt0gfAAZG*FJv!#hh;f%rX|``RA$EU(z=W)>77s$Qa`JnV;pceAek5LkL>8 zVE&C@K#Nx%^Z3)9i}wA=O9Xo91`jP6G9>Ae8UNq($(;H%d@{RXkkV_>0e%qNb@6;M zufhSjvrnco2Ll*5Aa^pdz(1334|d+b7{EVswuv(SnefT%&n-LqWa543_zD)vU5c7Bh6_Ixt=Ot};9Jc{uVmenWwD25MUe8MM_ib~Gs`1e&lnSB3%=aU&i zk9YUUd>WN|KAF=|;aB@)PG^}(pG(Z)KAGc;nefSc1?7BGpUgK3u$#ne5az@X7o$^ZR@<7jUopd@={KexFY!Z}j+mGG{Qq&nL4#^ZR@< zc?06hd@^t1cArlskE@-0GVfyrexJ;%8S$k)nWI_8f3{EN`y9qS`(&DPiO(nVpX`m# zCvy|~|3yBTSE1Z5_Q~YksXh5*nrkq9G8y>Sd@`S4hkQPn=djg2pUltM>M!xhtm1Lt z^T|Au>A!(bCU0=<tw?tuF6HG0$ba79*SIlQ{&1o`P3p7@y4X*pTqa4B*_Eni1&yV`SfxPi8pj zlbN!MPiAUXwz)NvFQ3e`q)%pdv?H~H&nI&ficd}Vd@|Qzvt9NjKA9u-;FCGB6Kku( zT8WiDnWOgLlR0{4pG-Ey9<#Gg<}VpnzOzr}YZw}P>^JhsY(OzjU|exGaj#D%zJKoZ z$>baC<)^vVCzJONKC<`vWa4DY&$ISdIH!D*w}0W*uJ5g1a$Eer{Vpv#aP2S_{v%`E|w_ z4lj&?Ygt$a-?~NB=IuhBhih#eoh$i*95bIi_rb5@-MNR;3cZkcN}-$M z|B&D3SNm=z&oBQK9-17iuj!jvIj5zuavuE0%|6@fli6V0L|tcD<5zE0!lSdPrn;`S zu4azwR9oYU47u-<8v=LlmdfhIRaVoe#u~i*44)Kg=x9r)d^v%8+2~eXQvVMEDb2P?>zCcsO zqs1C=zIc+jTs&L6P+TuwE#4yT^~rR{cdt*TI}TUk1{vquUY|^N9QOKTy5q3dC(|7V zoHmWmAMPa^!ez^lemC?5+)o@NmWT(4dwnw9ar&?J$^1VcfC<+z-sRlulc_P_@l4;r zSy(wP-m=#x(;b%^Fd+VM+3S<(&Jd0XZdNCj@6ac6Sn)UW$t-bwIKNsav$U`2&bQXd z?1YP>J2pZ4K@3znAJB2I?z+Gylkb&q%*#6xI+>gKQ8W;`2ZyFZcju%|=4K>@ALc{c zvX!YOccJqv^e@k(l@fXizYfC>a|UuH{V?gi?X1BT&kwVW`K67ynH!6;=dhTR;P<)Z zQv8GOCB1z^!HxJIz8$68P8hDk(8D~AIq2I7-%Exg{OC;I%L`x_JxqE#rk;Ze;d}W3 zB2)j265)Hvcvk_f0HF>{FFj1UT}F4nhVSKB0OXXS=`7&p5M!a9WI6OSfbS)QNA(= zzL#zRR)cC0#CNnqs z1}iF)**!Xuc}K|f>tVjnR#AKqdYBAz)URX76H{p#J$NTtB=Iuo&eH#+O_tI^5FnTxpT$OqRQbG{R)5GLo zNe`0+ryY;YTvbCTI0pvwFqfcd)Wcj2GfKY*=wUL0#EIniG1MZr@rA6*cdUfga{H?9R}oUTKHbN zr;@VR5$F_sFWvN`W7*6P-%EG<*ce}gMc+$TZ*yXdFJ_|erJH_A?0MSI!!!?NK@YQx zHheFCXzH60<8ejbOCCx_4|4$vgzqJf5u=AWlM(Q}q*R~L!@LyZNIguxQ^@FHzQQu# zdr65t>0$CvaCg#gklMGCjLF7fC-Jxm1#d@!Z2L{baDw`hGRoVZFPlWn$7!2Pg!~pF zjQ%BOp*fhPhk3APqji+tr0?Zr=uGYk6lU}=&q0cqId{YNk_Kml@sxw_B`c%8-i7Qx zd@nU4P$N4Y3bOcI3jZ13%ipr7Bk_-Vm^4__Uzinon64d;4M)Yh>0!Q!#A>#yhuIIi zCf1onK@XExGZxjxtY-u|x%)8~Bk6m|#MHy&;}!J1oE?;CtytKo8TnK0^=Fjes8J z5~hG2rdtd3Fc+YBw#tkt^e}0&QO1TIChem<+tb554H2=!u!X*tG&ts`a34SqbCt27 zhsl#74O0~KFu8MhAjx+1Fds)mH=cE*8hT+33`~bkpy~}jOuRl zG+<^oCfJ(@hk`uNrIX1%B8Jkpu3Baq=U^U8(*XELc4rUZd&x5&^e{i>;6M+v$e7T> zbg&(t$392vdY+AcNj*$HeB6s~g>x*bXYVWLl z-ZXX!^r+FR)V!?F2Z+eGe}RTj50fqD;yoE=Q_8{B!(@mzp5j>hVx=A?YpcWR`Cg99 zVtekydMnnxY=k{3hi!NV_G^q|L+sHxY)1}yYVMN+NUC>b73LV7)XjPIeh@+~Y->z*csBUa% zZLX?rJp^u{$?@Mw@p8}pc{p}m|Gd3gn3dnwZ}OXXOYZfF{06F(-_9p;4-;Sh?q>2s zMf1B*vHaIu>fKB0UIonm9B<3L{+9nm8kp|k^Mx9iJpR9X4a`~iWscu$Z_$Bieln>awEDh=buif4*z#5=?d;%~%PMgEk_ z{GW;Dr)${!IfL=M-AvYq3&gX;i^c23yTr%D=f!u#zls$2VYxYCU(v`Bv3}Xp#aeNZ zc&>Q4Sc?0AERXjCNxmnCoGUI8*NWGOKNTMq|1ADPjKZ0Q<@68>#6!eM;&EcVc&d1z zc$IjYxIx?`zA1hr25}FX_2!6G;z{ByBHs$dbiWt#ac7eD5OI{~X<$y4?P*}nlieV; zil>N|i*4fd;*Z5I(!_jJ+c$|3+&^WzV&cByaIsvRN@9*2B_2bfZ}s9y;zAPTohIAU z#9Sl$Qt=96Z28U|3>kiCgzKZe@pS6Cg%IJ(cTWYXUz6=6mi-! z@i?pu5p9?$?k5fsOT@kYmF_tGU(med72fxP@V%OsnB)6m#VHPsLhj=I3M7+vP0dn- z{|w{wZWgBVr{!_Qg~tz04^|mgF3)@e&C7jwP-^k&odVlm-g7ALNgUtQiey_@FWWy0 ztCt5sYZ=P=I+~Zi&iHzomsjLjUrY1yXq-^uY=9Q8O{c>4_oI6s_{$)U{lFO0N<{d}8{{hwr@cgZHz4fgVHxM3u&<+eS&H&Fu54dNtll{P6k(QE zgq6#mJ6YEGxHfwWw{d+?^wKT*nwpm%Bb}FrWwKr_k7M=sceJm+_}wefK7QWCTy6r) z(gzO7{(0(+1&NP{iDd@TeI3oqbHAqM!^ z{*@CM5{uw~oiVELGH&zV;{@4nkZ+gFUXOZ%coU3|yL*WV4~xBsrs<^9&@ zUDj=}z4a`+&#L^($^2E9Th`V`0{vGNTpnK?*m_3T+Ioi5_mXaFtp3)v15O`s#pG>P zdU$(gnzKDKG`GB}{Mq(-SJ#%mS#E95%m{4H>~MAYE#+4JvsIcWYf>ZOYn=wb^TbwZj=xQvT46)O_dS9_0s@Bjwy<+cVRTZ%<#Edhw9*4cPMR zmhSmo*Y&t!s>z)`b4GjmppI*gEH5g5WJjuv9P7HSKej!6enoqF>9g&bE1zxO4{I6L z87p&EZQc^FAKnqMLkOj;+q@;ier!iz-Qzm~$eBI&+4ezKvxG->1m+%$9^@id5!SI- zXRX}4C2ie|_LTXtH8a~&O1oZme0$2$tW}Tf2&0^RhE8cunc4kP^bb}LrDd)=7Tde8 zdu&H|D9e8W>GmzRub9yuoH?^SI4H6zy7t)iVE5zOgA==4x_L`FYM*%Z!#hHAH*e{b z|Im(5ewXsD>o;%7U02Z_EPZ50Xk7)yBaHHb>!z0q|K`uPgJa_cw_6M$xuN+z) z*y^MXTEFJb&F$yjj(xWBs&Z@XA;{D9vZ?LCgS)Mcud~_^nh;-&J)Cl0`7!OmZd2NW z1G}#-$B5f=N0tvPe{_eP-~FntE76}0)} z4=x{D@J4AI3uREr>74qKLRnyN#oOL>0z^!DJ1*qalqyhnG0^X&t>mw&toNB`yB z77tw4r;Ckad?dE!tqHFmxO&~lpoFMd-45{Wj)ZZf)=AoY3>w zu002y`%8NOj`zUCKa{;^JI6-GZnC#$I`C)N5}aGHC2*cS^!kw_5gv&!&Jzw>whirq zzjx=nHP+TpW_Rqb^o@Dz9@uWDcb@0W3U92KH)DwGnKlv_sxLl-gCYLpHC_oXH(G7Oe;2#cJXYi>oQgv{GPQX(ZN zE$ItC8p$2{4|~4weDAI23r__+XHaM3;Qlrfx|+n!8R(cZyz?2XDkXS0b5!6TeB?hx z6dW5-MR)-++s-{`EqvtJQ0G!^Y&PM@bZn)M{B?*kKJt^0Cv^rI0w4LF4F3ov!bhI* zu9qa`_c}1WeB{r99sPu5ULUy;Dd-20IY_koJ+X=_7w7x-kf;O_$*# zzZkU{ANj>B-Hi9~ofu~6KVr)&!)_;oQTnsNN1jhS_g4c| z5Agc~y|oQj;Tk32^wb|TA#kG$I< zD|QwK13vN(nl1!mJQLDK-nCO=eb{06$h&rW>^e?0_{h8YGh-K`QtA``4c}z&R7-3V z8wwwJcY9H+iZ*=Y>DU^8kGv6Bg^#?ueRym;>xYj#UkXnj`Bzv!eB|9zNm;Bv%ZHD= zn|^f6Jg5R6d3XER*xk$zA9=n=K9D~#W^)+fBk!i45?e|eKJpwK40DV(q3I)UUgVQM zBgW&3KJq-2jE{Ud3xtn6j}hY|U%&|X$nTFDjF0@G>=JzB7h`CQkNjmU13vO2O$zAS z!+{*tx;u&fxW1iaOg0XQZb6$u!Pk)>8}G)(GY=@xmy}W7{_KEFZh4%x$wbIsgb3p! z&sk^=X8FjU=-FtUaVdw7{FCTR?!Kte_{iUb6ftuyfsZ^59OE&*l8XAo?g$2Be2#`b z@|qE-ksS{OS$uA9w9)v;^QCIB0HWw4PlH8mU{?6ZyLLGC8jBujcRC8)$02W}G0+K# z)oj;Cp03ofM>)vwk-yF)wPNM8;Un+v$6$;?uk?{;V*1Fx%zXeKd0r;yBYy#_hL614 zi?Oj3HVr=VmzeUV#CS85`oxbQ9?zu2vX~w|^6mjQFIK_&;3MzaO|iaA|9#J19HTom zedKFVKhNl~;YJKJsn^eB__x!37_A zHv&HLuP_CCrp&gWyTaf^0e6~W5Y+D_Sv58 z`N-dah*(!_p^rQb?!G}BGx*3qWNi4z^Q1__6a^o7?i?OSvRxnfzagR<&pPyx=g#eB z-U0w0dDiOI&*x1{CiuwnX$bhpGpf7I(}0=Xm|%S5BoyR<-reTG=N${BCVl|^r*RHW zMZlB=U-k_406y|O^T9{{b`B1Fsh2<9{)9Z z>G{YnM1d%G2cqaBzYM8tJJJW`rFIT@lf;N$oYPxq{> z4h6U!)*GJgowJM9c#a)#YJ#{H*puB=!IDOHO+<|vB`QMT0n*PeoQsa3}q1t$;8^Pno*rOl$;@d zMO5FPu*2g!K8?6di2D`RzG$drPcRMU4`=p_b2vcTs!QKv7!sbmOa^Yp)barKQAF}2;%nPkgSD$t{Yc^ zxbBSm8|*(aj#;Oee$B_-+u2zAG3ON1ulr!$W}=XBN{n5NVxRp3QGM@ZSC2GZ{Q=_6 z$J+N^6PLs8KMea9jC;_;bz|J$V1I}eQ|}9L0S0Hk?A)2lOJ*u`yUFx>Bvi+5NYl^boV$uJivI@J(A9x&X8oQ5OBu}(cVz`zWw+(7c@3bO%;c3N<&8((dw5N?`PE0_BdARm_i zX05vf0(>=`FQyL++d7iC39DnRI(K;)j^6QDjllq4vV%m#R4<+ZuC_ImILgE~2iq8! z<;D~Iz-Y>0;BO}W_%sXv*A(j{tEA5|E3b`KC&qd)`N6iQU_Xb|wvImm{V-=w>v+Nq zP9<8gIu@#B-~y~@4!Yr6)M3TU0+EC$LSrJ_y#%euF*muzk#;sh9M0os1u@?=w{ zvPIk_CY}MdEtw03cEoi%?FiIo#j)B}1;I3YuA+k99lu}+@Tmja-CfA&E=Ze;wI5d7 zI+~b;HEdzOhx1byz5x3dja!k}i|DS`I}<+(J>&fq#1rb|3e(AF%y?H2DQKcePr?7; zp25IqtmyFy)EI1|F)%4ddt}#YSYa0W+G38h- zi`y9ZscS54V_*YT3?tzVbxYGuqc{MAz=5!>qX_MedlS0@eY23)U35J7$C|$#m19K{ z2^|$@CdL!}ICD8i)SdlD&q7eM{LJOaSw1rj6>)WE`O@8HIbwF2LQ&3D`tbbvBTg z4_*W9RI{*wrkO|?3`QbpI6W(d4drb($6DOl#z2E>EN)|f&SKcIw2gszrtLEb_6zY% zZC(d$>lm+lj&*XdjUD99MEop(hdqMqn%g~0N1w6SZ!9&&3M9pJBvxX@oNa1L4#*S^ z$jv4myN>~PKoWZdr+PiaVayI5V>&gR;C>BYUz2VJ7n=^InSFO8 z;r8!jU;kQs{cG{{uf_C_doN(MEG2n+0n^mmaRK}i%>Cx}sVUJX+w3koaS)|hbO>`7 z@96Nyc}IXh&N~$Rab6i=1b8Yt0xJ$ILZ`9^5~ni6VI#-TENBwLXJh4A3%NM6-P6=` z;uteR6~s)en5)a%7~ssu9DWIKFVPig=y3+t6srZ7PYpacaE5*9Ou) z|GaA(kKq*4>f?!Ytd6zJZsW-3VNGQA4n<^Mu}qn{Yk!IrXL#agSRLymyDfPFp3W06 z9VbK9QmdqE8-s_MF3luHVs)&gwz>L^b>j(M`>y&67ta8{T_T>~xe({~waXc3!itX>Wnqj4!(mYaO2GqJEO zyk~>53AR3f;t_2x=Yp_zVhvbJebOD$8=*Wv9YUNfd@lNNcjR zQ%q?KO$nzgCEc_0DT&g8?qUk((0C2R>_Ionx_hU8*DmeumF?QYyXT_J2CS|upS{fW0FlYQ8NXEoa z{9Qh`vdQtG zsJ37G}Mb0_a0Q#6G?h^&dJFRb+AKeVW)X~ zO;6MncCuST{lZSV?Q|>+r8zZ)h%3&{&dy{_D1_aN5aLUnXdyPxEQn9wMg(9nI?Y*#ZBB1{+%-NK@dn7WP6# zPI}?s!GoQX5Yq!z$ML3=!3Bf4EsAC^DH@4PrAP>)Q5B%siGuruJBA8+7NLZqP(iPv z!+RGLjm;leWXg!MJ#2?bjvjUn^(#ORdJhWqD@HEUy@J8tTOJzuy}Vu+!;$gvrG=r9 z4*o?jgcy|$&M%hR;lje&R_yqa_;`+f=Rz~Gku@B%G&`^7A)$V~P->{(L8x$1sjtEu zG{2`ALbShd@W9YWG%ODdH6s}xi1J(6&2-e7k9;ulR@kKuW@;)@qs&<8hwSG34>5T#Z=Q@}&YF4nldqViq4Hg-=n!@? z(Uq{%G9xD^#!*8BX-*6GiIdrylUz74YiuXA6oav-kUPB-$AweSN#)E)jU%2$Ert_O zvXH2721aovcUvD0eLk%3+2J^P*3s!%7-#iStsTY4>~5l7$MP1!uEdxo-$LY>(9 z{7`B%6v{(Z+aFQnMlg#>VTZe7Xt$nP8cK0e&4E(ds~7e?1UJ8E@1yUT7$)wY@!CJ3 z6r5d3Lml=tyNQ$QUCSg<{VZy5vgSPpi`~A(3-R&Pwi_1IPpfLeyFDsv=ghC0U0=Dl zv8e`%1&s}rHH-0z8YA0)7vZ!v*3b6dgTt3#RetRkS@C^2B||FliV#<@p|XB9o-l63 zn{=9Ms_;6I`q|C%YZ|<=@dA;?1xQ=l)Y!s2wGC)nbz|d+b;vNXZZ2QtV;&D*G^c8b z^~Fyw<0{4qTKIOK1&J0=kYQfq0=%FEWiCKbMy$ata95!Q^NN#N_jM=iuv-|sljif4 zLgpV{pn}(V;q@h^RaGqzA*ipZG%s4IY$+c%aSUD|G>2o$7P#-gs&u2h(MB)p7Gt#W zdX*ZEP<>7F+?s~!B^KY6GOGB1Z}ajK$SPDfEjXmQvAMNoaY6l1*sb#x)XxTM5ntQ1 zaA-kGQ^B0#{TV~mih`>D4Mhfw&Hh8Vueo=qv~be?C7!v2dl@qbZ<48Nm}6B{Q`%vz{^`bF1p>tIUywkZ+!Gdj0#}UsXN7rmA5<6WU=8`O1Yg%`Fhm zFhj@#(;NF;UrJRu&pU#Rt_gGS*f#sl91b{gF?Lqv#L1&3R8BM9b|?L!<~khjIIc%> zbSmmjMk05_td@D0o_ax7bG6%Nb{B($V~>ZIRY^$?L|{N?V~plE&c+M$e2OY&-Ylsx zdrBvhN2A#v4K<6fQx>*jhokpZi_O70fB&IX?lC-j{)sJY zE6ybvlP`St6q1@9*`40V3HM%Mkb{O(!!mB z*>;W{b8_u2c2~Qb4gZ=z9=?O`y!a!6*7nc+TOEF7_bra@0(emlzUBKD2loeh_#=Gx z3mEP2zMyY$a7W3%IJm*H*}v(uAh+}c0jm#0dkl1m3NhBJi_+s%ev0R)Weos7J zoG+dv@(w)fIa6FM;`t&If1`Mdc(3@VxKX70CChnF{ELViEN z^?W9qw{Tf+fq1aU+q#VZo;XjuRJ=~SQ~Z_4>BW2<#R9QZoFE<})`@geWj_8iK+;p4 zq~JWcP5fNUz+7g04{?xKEAr6;Za+)BSiD}mOMFaxUVKOVtN2Yd7HV*Su-*mYS>h$) zjpDuHuf+K{O)%dQ(Fi)jzEt*&;-jKbWybb5Wq&AsTaAS)acr|4w~7ynzZPE;w~02K z&6vKEm@f_$$B3)MABsj&9Qn4$j^H%Naw+#Ar^`w#Bn6%z$EcV5^bF$&J*iNl(Sg&QqgECApQc`E5(aR#9uA@I`Kz} z|C#K2#RnDtr0i$JO^Sa-_Uqy{@ng}!IhgH^h1K-b>!rP1G}mF+=gYoS zG@3_2JunxS#gv2s`#d8uHPtUhiv`~$a2l~92_aTT%05xDIO!kw25Oo?5Y9JW0Gpyg|HGyhFTS z{Dt_0__X+2@deRnNTI&BWWOhVAbuvA&pk+&$_Ej7srbg;?d$PagKPR*eEU*`B)UoJwrT4Tq)A$ zgWK1OZQ>2$&ElQnJ>mxOQSn)EllY?eifBGhBD_WRHt}QeAEM3Afe7>I0CK2UDwc_d zixWgX#>4bSi#2<;big$_kiG0k1pR zuF<{&`G6Ab{$i0hR6Im9-{X*OyzC>yW5r6*e2+uA`LY*?OGG~W#QH81+r(?dTSTLU zhjjPJHs9M|KQ8+z(P-fz{`a!^AQj91RJ8g11$Icx5Y77&5#L3253!#(Ks-P^SR5&u z?{COIS$2hJzONy^N%mrKsd$EXj%dEOA^jTJ>qYbZ4e@;Bi|v0(`?7bB||=+$n@E?k;nT!X%)6C zsc)^C4YoGBoacq`J723+Xnv6@oZZr56*8jm3vc@F)z{;oW5H0HWncWq!cm@O5Fy#Y^|N(s^4xL%PwP0kU2$4`cPWZ>+Ds{I$nx-|rB{9Bl&3Qik8k{BxD{ zav^=w!)iskI3o8!d=^%g$8l$!C@-5TpC^z*dFWtO<)^a;z>$p_vcRjxXPfS2zZBlt_dCz(K&f9lK*c#0L{VL}@*B;z( z!n~A{l%XlZ2JMJgc{?JrFB`LUQ{;*pMyGBKhQn9PyrbmrfnyK-d*GCPcZ96{UFO-P zA8m5hPZ)hw`G(HcM;)z!Q1<$5=fFoD1A+Ae+XI8_gFCQCP)4(%jJEnuH*XJECFN=5 zL;fC^5N{7mrZU>Ke@b270m^8nJE?2Z)>{K7ZnW3ABapK=JTSEV^OB{1NF8|cAAa2P z*c7`Yy?jbJp3xsN4O(DjSl6K6cWoU7)w1Hh=f?-M=f_jluTN>(7+m+Nm9h1aP!mQe zHgDQIdtS8+>UwHB;ZYt>q{#fqe0t>m_s}foPuWgnL+xRDnk#EHQouS>^LRq`FWwqPu1fx5i z`is^3_|^7_A;f&W&s}Yo7CrscU;Mp)v^pl7VTIsK^KbMehO);ptoQ8WQLkgW@AvgW z7w=>XuiaUfxP8~4L_@+(6xHTUudJOkojhP+@RWspf8P1Ru6pdWX8-fs{KRE+J9fUK zaMalE*=ZQXN2_NN?BIh)b!xHb`;RRgCaN$GGtL<7tN!B(`A9uJhy6YzXE~ht2ezLp zs?f`{;>}Y3*us@m`2(NRDhqo5xc1kHD)b;caRhqga@}!0#J@oAyo&(fogiVC^9cS0TkwGGLk8O+ zGfb#Q7Hj1^f`6fUiHCUUBn%#~ZqSAOq3=4v1I8PRA>{#+?}NHLV8dWWGOtY9lLstx zXXFydF2R5ucEBT zNh%h`{>Flas0i*U<~>=(xYd@_9$`B&DqMszV)tNFBWWJ6_vqQf1NH|ddw9SG;rJOj zBo7#y3?8tzP}&+ha#mP)z@)#^JYc+A9jOYMF7U^G%zC%v0gKG+%$JA`$pdCeNb!J8 zN7cd+ofbS`2^RIFidk){X4Y7dAGP6oUE~27zkq3-peFn0mDWMDx81)#J zY9tvRu;(#k$M_@Dec`tdE4YGw!2?D+3{b&)>JYcNEp?JWk#~^(Z9xye{M7NqjKQs^6FgO$*Fz(FY0i#TkBsm&jQNNho=<u*9<^ii>gFHN7<5_DD z57;i&8a!a86(b8O=np(#w@T3!1>=Dc4-eQJ+Ix7w*0Q`-JYW$I4;XKpM7%s;T*e|^ z9*?8wUGT@owl+mj{fbY4AH8s*E%b*cU7<%a{8Y(C~oq1!*6c!AKz0 zk_XHeO!0vE!Yz5ge33SJ&(amXcs&%o;LAw!fca6PFVn*Vh99SRaU%LBF! zM|W=aHv9}VJYbCR+DQVTWFPz~57;%3mr?f#Dy=+Vec_5vh?ZPRyP<8#XU1pr9zf{I zx+o9WA0YpNI@VWtz?x7rU)k;Y8}z91fbqUL@3Dh0%cTLk8&h`!f`pGoO%?{NQ*)`h8P&W7!7zgrP}K~Pr&L`pfP8EN)(epNNLkl* zq7w?OV^Q-?2!^6;jPQH$cGZPO2jZ?V!tWKvwU5uC>&koV_E_nX3!qzua5TEdvQHBo zS;xjn?2kx!9--^AsG2=4Ur6Cl+dpHE==v*q8P|!r%b;6?(Di3*|G2KymE%G;AGSIQ zFG$!Er1ED&tVB45Om9(yvvF~(>wWb7NFgU0FUs?yHC@-!kJ0htH2hGFbqwF_=3^!| zrgA+hxp)blm*Y(?qx%iyUo%%Xo|J7vj_y)U)RruKT8dZTkClQ{Y4s?>54cBRACv!E z5wkDM%EqOlo@XGX5E=MbRnM^y_#D--6ox?H#rGiyrE?%mLu3kqaYrYP#sAys?xL)- zU3Uv$a}I*IyATmRIwkIIM&u?0arb>h?n3~HE}XxNh@qExh3>A1uBE$nNZAgXZ3v~s z5Z*@QEd-N^rjEt`JDBOp=ug~C`(X1&H&Z5hDS}`sPE$uRyv9t|WMyZgB=$obHk}cq z;{6cmLxKG;3Xzcrz1R=N4Kq6y|G!B$*Je#|-BiJlSLek|BO>(_=;jJUE<-SGdUI4h zL1wercV{JC7q`La7UtrJJcP)D6zJk5M0lybjG2rdOB{U$*^#U3_B~l2xsJ#-x0iY8 zD1_b#u!rcVGa?-j$_hP>I1-yN6T@=J(0(_1L=Mb33JI7Fr#Y8l8H(wUIOe##$cEgD zY<_DbMEkc{b^s!1S$VYL@uYm@{@?%icrQZG9ey;^bmq}usnDyOWUJxZSTr@ z%ys$_jAW$QsNX<%2SJ>EhRCM~ren%kua}V7v8KZ-s6(=Bth7?G2zn^QUZRgUB1IHf zu~CR55XzWGd${}s=|Kc6 z9PC{>$+Wi6$q{zod^%zGz66UGn2#yay`Mq)RPyy<;YG-2W-aqc!I2y^0YM6mBT|G= zwu25>@F++l5wID$!M^h7@v}}x+xZ*P`+b77$oHHR6=5s7$@jby<(l0eFLhbI7o7+N zWPTHHTsc-n-v+11rqW^08V4JV1C!@g%`@P~SjwGOLPywKF`a>n>dGjVQG!rT;UpFM zP#8<$*yA`>J3>(k=%6-s*R0%3C#z%D!V@WcEruro7FR#Nt1aqxP|ut94{eddwYskyzd+D3C**yEmF z+MYM8vsfU`Fph#ferD&|PL|g{?){}{{b=7-ECT5oIPR(T2o&l@OExojFI^K(MEPSbKlY{9@Wh@xGd&|Ut@!01eEpB;~V!mK5pn^w7 z<5F-xC5+Vh+8@{Zz5aiBF!lGs%kFCkXQ0(0J* z5}5>n2}GW+f=QA`xz-yG9iW#X#3ee3U@}~PKQH3y#>EA0xPd+|6$kGT9gHtRI?rnn zC79?0!TG+b23`GD1A)!&C<1Ys=kaMcMWHAWyD6K)ra5crgCt=PA$nRsJlB?1juxOeLe0W?GecI}}^AU$M+QhBV7)_aoeY@U)9 zBESQo5FS8}SqkWDqJ$F>K!)W@GLkTYKgq~xMhHrE`Rpz-6E2qMM8X;buz2~CjIf3t z&Lq?UTPcF+!zqMqs0XNs9$&>SV5>!-AvehIz=#jfx@EnQ&=(<$8TTX5ioTKHzEk}C?lqySZ~>Ia1HY4h7<%&;5!h|*94xCVK*c2q)2ET8R4l7^n_Q8 z-j`&AvkZFv(qnDl#VrPt8d1ZS$X_BNDLU4}NaL>rj341;1Q}OGJ~Vp5Mu3q9cL?ELGW3Pf*Nlkng&&}6?+jP*7+EqAtghON>bd901h+)kf~sTlT>#UNb<)) zU_iWy$fjt`ISvt+XfBGT{*&mETU4ryftNnt0VEe9QR7X-HxbZDtR^cHv6i|n-MXQg zNRZ73QxpV8{Lj{JM*x9UdIYDs!xq5;sg>j4F$dWH*t%^Jo$B^~1l)aUm>z}6%)*Ub z&O%Mm?%0#Ijzj-|xSB|ilXy%lL`?w`39lOig6W=#?(ouulpqD93$d(C&^(Ml3!?m- zwJHd&Azd#vR(2{AebSULNJ9)Abe>I2&Rw; zhblz(bL`|O4%;S#hY_%k63pH=$(^^3)#y)hvc4-OlUNSN57zFyl~sE$bX@15cMJ9I z^f-~_6$78c$;NFnf+_X%bg7eBDyN)dfryn6)4Iv&Qm44n(6N^KlAM5MiJdYOg_|XI zO1c8(0S6fQQ8PnI+#Ava*y1o(LF7tBx3jD0i8Lmm_is#V{0OTw=IN&k`cB8`bvN~!SqKTUIgBSp-mgGI9(8 zI)lJ|5hF&18$Dr+t9M6TjNFo$$SH^GU~pvOm%HE2XMSN>8K>5%;d46bvvkfh+58o6DI2QlLJ*-gn(5~Ka4UHTI*U_zK@{z zM3kv^dM*m4>lL%P9Bf7K@E@j?JffyHn`Xu|)hN6=Q)r*$RW3y4F4!Ja;dM`q&(-vdtDTs9K&Q!`3(Dbj&LsmI`s=4S5lkryPAT%)m8e%RL=uaN}KtO zGUeExQu5R)wb?XlmEV`XESM$?_Srv#<)a9m;=Ri8u1`l!G0g&z+6&kNhdJdjmM!{< zmaibRI>j@VsmA;4i?M%Sir}eIAmX!m{9r&A?qCzyqmurfr2DX^;K;cpHM*%&S7%x&SdZgJw)jE`eB9sYRY+U2b#$P$^#wqJg zTTV51W1N9gk8{o4IL+J%#p&X1ULEI!yKzX|0pvKi+q;Orhwvc+S3h@i#~_Y6veE7s zc+=S->{_=I*&*)6G&e8v)8&z#h*%%0W>?qD0M}iWa3w*9iEdcM8X@2;hlEommNJ1Bykp1+J$~TV zS644oV=V@=0XMe~#m)*2Q82JBiG%4fGal$b9#03%gE=5U6vEcLc;IC6D|R{}(Dleb z`~F~IJR209wLmX7D>)ZI&k9ni<7&8vJHN+)oH^KzCQ zaPsm_2-sT8jHXJQq3FqeC5#V)_b>bp3p&Nox*H+NDK5 zV~XhIX8Dm8y{(o0sl}k(bmoBeQ)nhTmAX8fW%(c|%|doGBT(4*eDwY*=UKd}E zb8l8@Fjat29^u?&3NV&$sO3Fg%U?;6^I;K*FpLjI0*w_Pt!@W^=l?gU{Y&u zAVM|tsHI@tU@o>Ajnt&DH3=jfh8Qde|!dmUVkHK+ zS>am#f~y3U3OGhzMn*{?X`WWF)EfR(DcD1j+Jd!}{o|6f4u-p@&W{Je#Teq{m}2a^ zH!$xGnqa{)cUHtP4P(xB3w*3yVcy%*zOLT(f!P)fI#m0*vi2oRjX1wp5$Bx3gt#)m zj`cLVFj#6FxXs3un*S>X*MnYHo4XK{tP5vVS1m5<2d2~i7=G8UU~olEg_QA|^0?v& zd_zWAKV#u+G*G!=|E;vH2lcBVcVnL(n()<7lzt7VeXqm1#ficHKPh8VRI!Hp^Kc}w zhoOcg?=WY2Q+d@~5{r6>VhxYyX<(K8XLw;7mMj4E>;DRJ*wk(Uvf6){CidhBr+|go zWsCiHaKw(szEn4{-a`~C+_K)${14`ht*V+ZVxr-=Z9yIVAI%>7-^&17HF4~ilZTUC z8^1o34Y)<$e9Hv80KblB;;1#NHeO%7bS}A?Vrk>`EL?mEn{g$F9-f91 zF1>uk_C#D(>q^AnbG&KSM{$5+LUFVr?|9LU_uGl{6&EY=i5TiHR=h!xFGW$mN%4Ng z#}%Jbp7SDKv8!S~#Sw~pY>jr+ic1tP zQT&zz*7VP}9I&PzHernhC7P-$N?9+^<_zFWf<}7w#Y+ z-(;Zu@6=wngP<2KSm^(v`oAgCmI2QnOMl?GVnM#R!2T&w>_)_u=bnoFi3q|e1Uun^ z1@g59>L(K+3%3xEZ!j?bEXDam1mPA!x^N2tSF8RiBIN57Zz5vs_!m=@%&SMF-aBTE%rl zd@F(&CBiOW<@SmtMC9wP>4Q{%qT(rvqZKD9PE$OK2){Kd&r@7Ngx_-&S1Den>1!2l zQQV|>kK*?gw-VuJI}zplLiKMbzNh%1;vU6)ik}maFNhOc`iT-DcOs%+j#TWfSgP2E z2)n^54^bRVgrD)6K2!BIisz`lQRODZi-^c~g{FT;^&1rLRQ#Ue{X~@ih{{hWzDUHr z{<`7^ivG4nU!Yj7SgVNBVkw_Dq@^De(LEv;D$1>E)U&I~-4x3d`I~|H$0$}P^4SII z&s3bLSfhB2;`NH_6mL4=Dan@kfeJE54xklHyLqUn+i}xJ&U1#RG~y{yso` zgNoUT@~sHy`Dh%|2PmGTI82exE-}4A@pMJ9nNUAlu~u=h;u6L46faP`M)7*Z4T`rZ z@_`QeeN^$siq9zW9apCBQT$ACzv4d>9sFjbU4~+oV!mQ~#V(3RDfUwAqc~V`h@yPs z0)9uUJV9}aVwK`7#U{m-iWezfrpQMJSWiB4LFBu+#1|ERsrW0!-HLxybUCg6sPwg%t}FJ1TZjB=r^TdMcJF4pAJg$QRvdC%>nGBr>49Sg}cQrQ$`3 zmnpX9vR<$HTNO7e-mS=&=;{9@#a9(ySA0kDw~8Mrexmp%#V-{9u1J1Q`i&^Y6#0Ta z^}Q62QzXYA^+J^ZOsG6oalGO*#Y)9ligOfOb6L0Ms=ih2Zdbfp@qWeDT-DoDFW;a+ zy?(0l&lTTPd|UAY#a)Ud8eqGkin)pfik%g^C?2cWOR>M=AjOjvM<|}AI6?7r#j_M= zE7mHKXno?<7( zBNdNP?4j723tPUe1Akx@6u%XUlN4KXVb4?jLd9i@=PF*Pc&Va%vj_ffQu$Uzxqbuv zJt}`+@nOZs6`xjoR`Df8mm~X^D!Uxn@2UKuVgRrDN`EQlDCQ}4QanV-?3Mo}qZQBIzqw{#A+_6y;k((BGxetza+wr#2NIL ztti)-Aj@?oAUQIaK2TAvCqX_<<<{4cNQOcCCPngLP`*Y{t`|YRLuI*61o<(QNq#~5 zR}|k-{H-F{E|~6eR+I38a;Bnt9jJ@SWs3b26N;l0#}m;Hq`IJ=*@|SfpuAjBuJ=He z>pehnTQL1jMKW7ZenRmj#a9%`VZrnd6y>P`*Y{uG661>s7v0QLfuSPfiQkKc-0b3d*l2{*nm0w^V*t z@pr2KOy&KGWU^rXm?Ft6D7)8bj-?ELy;a{=@p#pf>Vo#CDdMz6>>-LCAc)glK^)Em zG0g>AUk8Y*zC^LNVqe7pih~tLDvnXCP@JSVU2(Qzt>S#eCdHMCs}(O+T%&lSV(aS& zn^eD9af{-^ijOO9RotfdoZ=3}*A(AWd|UB7#SaxfQv5`5zv7pQh5Gw5k22%q4U1edL-&po^FIjF~fW|K6L5hqArm4BX_OgD>5B@*k|3&j;Yu zBS`73(pifZEa0;fo?JEcGZw(;VW<24H$4|y*gyQI7f!g^IAxOot@hQeTiTUk%qLQkA_H)8VedaJv+KITE;E%)M6 zuwG(4VYw`i?I50q;O0Tp+INg)#Tn7fOu)74?y*?yG_Sv_;ja#f^cO{N>vsp@ZXQIf_T6#)6KkEjxoNjS;q~|BG}Au%!!DNc_W0i?H=EixqIyH`Fre) zNeDT6><$wUx;9_+WOei1S5`OQ(Y?C)zB7(*4y`z<*%{Q-{Jj-5&BcT2n>UX-s@XrP zU-Knr9M#-?UZ3XBpoZq}4LYj%N~GVjqHlA_sQ%4?c{R;fjH+qAeBN=*&WbM0R>rdC zJ6FtXj%PGBUp%Tyv)y57^QH5;G#`0JPM_OG^hOzV@V^*&`!yeRMgVQ}qm35Y=tCQ? z-Wl95b@-IwuYtWj!}4$Z^@E>&V$XZ*6MNL>pV((?MSSlkHfnG&O1ulTx)i0~InO@+ zxMu%~WzBc3Xl%Yz{C=?0w=ulOzhd<8BNFz;k$dn!{qZCB_(p~I*k{;l!yKs{*2WG^ zNAC&=hrKU11P=RLaJ{D5uy2u4_rRYKS z)>~kw4_l)WQy%P-_#sL}-^@F@`6!gXtogDPf8L2&_5K+8_eX?wUlh83XJlh#XKUkk z!?)IU-htWWL+?9fi3$62qQej-?2iJYz%Vcj^aK4-dmzhlVEYG@7c2|0I0Xk3ZUbU3kODM5kTh4FeJn?BbqS&fg2N zOZx5WumD8)@j8;Ax86W#pMfOjF|0biV+#i(-DihShb2htM?mSEiR`|C?fI&*&ll>% z3upeoB&Ntk&T;Lz;DH`rF1>~W^RQ%rxV}4bDRDj0hQq|^gA}JQm&>;kXa17BQH=9m zkJCGEHUPY+QKl5)pTA4{m!Jyxci?}JACa~lUOo);$ijn*mU9Oa>m`o2D_{bidLEj> z{=j$fst49j-UJBT9c_j(vJf5v_vBJo)- zy~6xrQ0zXKgvxRmM;UFZ&apz}TB1Mp3aS|@&omVX$7YI{XT)f13i5=?I~q}V>O*}p z|00g^&{4eUlyL$6@fA#I8xACYfQypQapBvbi>+YU10!zxcvc%4q@q9e7RBRL497mD z@n99BF^6?ILB*Wd25XrVISBds*)p5xMV!4+9iXoY|S3r9Aa?oN+cXGiV6`Kko4dh@Wu`EprRP@Nm}UoQAsAh8_uLB4?YbIxF;OTg^b8 z`p{$UOdwBv=y8?8u`^h&CnCcDKJe5($)cWA(eTuVe$+-jyb7NB@igA5c?)Adp!lrx zlCQWZb}7Z@JIPlfi{mje4ToOr^h?y%S6mWnX02a}{Z+(cV#l+fpGNX=n&m6*(WYw2 zOe^$?7G!wpLqFFB7@qpj4lQ?Z3@^%ApmLtPDz zy~k?2rFqB1R-&6izs`7F+FKE;W$L?a_oFjlS>1&Ettg4 z08jlj(jtGs2Bw3j-pJvC&sZ>c>Wv&N;0J(1;HfwHa|$j-p&{_pzkoA4UvZxB(ucrP zZ_;}g{1tTwfu~+Rz+T+9U?|H2PrXSWP_T_McIQ^1)Nj&hZsbDtLzJ;Hj63%Ei+P zxL<|9Q_o$=DgKGCAfFDwQ_p?GDSp{kz(@!@^}!4(-VPMJL6_jEABiq=ir)(qoJAkt zsc$P5V1Ewyxht4K`Z+q#Ge{z`axmhA2>7?aAkTgu8ctA;DOK)x{#uNfkJC17g#2XC zlGUHHPop`paNZAZs^x>M3wW#E=>SPdy7G zPkm2z2zcssMxaDCJm9DM!b14X3W2BoRl4FGtk4j^Z;UVzUua&A!D|nBi44!(k!_^jG6s-_= z>Wy4i(3SS!sW);{!Rss!JoWuiS+3{>184xA`h+Mhw+r}1gb;Y@Sp%ndlR1!wz*A2b zPVr{DAjmp`r`{;;w+kL*CBRc}6c5`4_t648^+vJPF8Dbuz*BD&&)Efkr3HBEO(`$i zR>l&zXRV}9!BbC}l@b{|^_2N30FlX49|BMP1yB^UK}rZb^%U6WU$W1@Q!h7Wikqwq zuIdydD|qTTINXs`?yxrmp86M{=*U$k1fF^hZbyFfIRu`1mTJm>-OU7^`VU|Vo_eZ^ zY%T*byD`DuM?B!?j$VWly7ayfMLgjDD^fE!2fIL&3V=_ZJoF*()N|#t?M_QrFnH>F zi|F(FKS2d>KDHV~c76fMfZYw6FnH=$z{?Rgz3QEb z5^vM)c9?QU;}>WmN49CVQRJ`{>Vq0ay0i)Kqo>()*u`Fqy!HYg9|-~j5-W<$?u9es z;)#~M(ASMo9y_KZl<+Iw_99_mzE0t&jc;nAE zjd&2L{6H_1&WKTLPvV~uD7tct4-$Tpm?0h+l{h4E%_jI5klAR8s!mGUJJ!)1kB05LHw4NnHULxMLCjgslO*h>|xB*`US5@OYL^%5ty;$;?^VbvY&wZo+0hP?nw-@(+w zygUeo;pgyP7w)lPpN6nsBDF?%&SGRf0!fL9T&TnfIS$&2paFRrL7qrMkwoSLKi%c4 zTnDU+XTyvBnBype$Y8d40C4LOOtgZ)%hW=|%E;pgD3FgI&g70`jVGAs1VRmh@SZYq zDFXPocovw4D#4l+s*`9%J%FEa^AL8yIb_=h{ziV^!&J@iDM}KrcEX%6Q=*jwR>rZK z>XMA8(C8JKyuwNm_oO(PT`NOnf1iE#bqRgCZ58KA(%#zuWE(TN1pms1Hv2jiLzl>BGA)I7nrV*k^Hh3k1haV1g zv~Zh2hhxf2L}`J^cQ;=F)D84Hh`CKGMcmA14DI-+kO zVB!LPfDBU3Mxp(lWQ3+9BTYtFnPlXA1k51< z>y8|CNk;hGFb3A;gOfdvEy|JVPG}2gXQFJ&4-up=MxHc6Q<9PGMp&6-GpW|8hed6=CmllNqoLG8+u~!#X0HiFl*iT<}3pVry?S z`jtes5;pVQaq{6iK^&%!MZavN+b$pGwA(EB8R@nP@l)9-HURNato{2EuM=!G@s+5W zyK&yQ0Xi8q(Lir)Lm+`De2pfW_B2R)1{?htqG?-$w5`(U#}e5-pViPrG;LcmoNaqu z^lQcvP21`{ZENtft)Y=^drIoPW-O8IqfbveN4ukhev#2K?W|9=6UE487?j~4wSNSy z+qn43zB0tr>NMhX6HgGe=BE*hOifO6_ZT-nM@D;n9Ffxmy*AF>S6n-(2L9oU6dPBQ z6A?fNOW>@+TqNki;$_>HVM3B+&&EHqs7xT#Q)f*iG$LRMuSzn~Wc1Tfm0ARt5auJm z#7-?9ex%USMM$!kD4NNEOzU98y*OmyBLJjoWq)vI%&@Lsw@MjbDZj~_)C$xqeGHo_z?nf666XftC?OPr*NI@E6e71LVpBs;;u?E!o?HET*4TH z0J;K{v5ZcTlu3k12tq*1$QedY;L6V&;O=FV2LW>T5>32!>UfZ90Q*cfaAUa}S}WU3 z{Qpdve*M*}82J(bIj>$7EGtS<;JXTFDS_)2jv-gCVkFP#37l%8XQT@P9Bf$?M5`$D zM*xQ_frsx@8Yi4NP{X5E2f$T{n>&ce%HiYAh$!JH1n?UBlZ>!P=v`-sN^blEleU8* zu%%s9rd?Ii)pl{U(w}6+xT;LMs+8RLhjmiUe7vqsPrIt1s~5yoonOd*jVn3+u!**X zo4sa3ow$ipvuq7OM$p-MmflA1(mRn$(mG?alE`vlFH0|bz=wHBG|SV{)KY?zHEt-0 zrENnnCDnOKs`HjKfhFA{9_v;TO-Xf95}g$wtleK(ia9i`8RhAzG3==|ro^#CEpe2m z#8HPUu}E8Fe)mYxvRIqg!Ey~&ddK<=OS2DT#pD1BE6DcOa98~^ESoJDL0w+W|J|IQ zruSTa)I$)1^eH#wp9k@KVnU|*Juyp_-xIMEzbE1;eoxFXm){d=<@dyzPiirhcr;J5 zeeNR}9oaeC1UgL!8xl)_L&c|Pp5!_fu7Ks4xd96Y%6Hs>ec&;vi-rd2g$pA3XR_lV`y z4xZSOve9nM^J%QGs{8GDpe;!}Gl~Lj%gN_SLceA4UUa*x27IIWx!@WVg2~+c{JcP> zO%~9_cF&$LZc}<2xDm^sA!BD*US3{4C`9dEy?O;Q%HTIrdf2E_A!*TLk+BytIbgz! zI`ySrD}rhhl|qjEfM$+L>Ea}2_ey&)`jmYhlKz#_GM$qL!@1Bw!j%@<63fsjPl0N) zw6qlLt$hZ|=;V%)ZUgbA_LDY%{d6olDAQS73eVBFG`^)rw4K)%r$<#`N*&IA)H<^y;p^{*NcHgy@t z8GMi&c+TgqP-F(3O4hW5y~AEO9n7Xdr!&||gH9}-W?+?~(C?Xa7Ih-7J;-tcj-lZU z#7MZAMDIkMcfnDK?!*4%+#(E|pFok1=TBnY0+D0TePFnCf?ZQAoM*_cECiXozAnmA zn!vHiCBTU`IvLX89-2)SO$JRb&8Djh1X}ZM+QAMW*mOQSZ&V=CiLvW2%9%&|aPDp| zT(V%&jJk$2Ut-guy6S~i)uM$})lG97t7g>CLE^Gmjf)n{#QHa*vHG8-tE{fCU%1Gs zS}@b(KA2mvPdVAhX3VBd{ru{MZZTL(7cFVDs%q*MHIR9-W+7@aYtf=}=AsTm=gt9h zp5eM%CUk_#FS!KjKIOtx*|?ypcF~f07YvwPS;jvgS7pyQE z$^RV$lK%$UNbD#J7A-V9iP-06&c_ZmX56sRRg*04PKL%+cpok7kwbavGjZ+;7-2cU zBB3mT+#g#~MS{r?dlG0mv5U=~(MamgWwUB$T2*uAFPb@Hev93Xq?OC7XK-(=nGOE; z1yysat5F0Bn=!v}?t<#7nM>eo$-*TK)mSR3Sg`@z%@}R-H6VpuEN4-4I5NBxuLqgp>p1$g)H8xb9GHe*SeKvcbK{{m4{3Ylmx6hWs7w8I^Y7+3qLgS)ys^-sN{TIyS zj^pk((zD20vrra!4pa5)xT)@8*&)B?=f@$abLEWsTT;odB9-I~RWGMxC1iKwHNC@d zN)8WHv;Dq4BU`23z zR>@G@=lxIQpe%G7Ea>RpL=6r+dg%M?#iOel_4x#nZf_w$M z$OJq}v7h2_#fgeD6&EY6R=iFzsrY@xt%@%zzODE-#Z1gsmfJzGo8kb)If{*n7b)`j z73SNa_#4H)De?(#rgu~nZW71?RUWB$vEo`q;R1o(HkE&__^#p}MdAK{U4QIWEN6t` zWW{R5C5o3Q-lTY!;vj4B*lS%gI;ls@P9)gyLjHUJj%EGR4akg#!cn z!PxzoeyZYBMd6NMK9z4&yhHJairW?UDE>_`7B+r6DfU!6L2<02a5A8r1uCDXc#Yz1 zia$`?rnpn_eMR9~fFD1e_>ulmoT0c_@qWc86yH!R&M^7P6^AK~QXHo^Q?XWYp<<)r zxr$dRZd2T$_@3fEMR|uG^^W1#!gp`mDCQGk(@n9bqP)uw`x8~>F^P7k5TT!_@>E4W zutYr{UZUN6#l@;WPvr{~FID{wDt|{&-t~u{@2PyB;#S3Niu~Xe%Xv-lLq)#JNd11r zFBNU9$*f~5G zaw7=0f;`G{zVO&jl*{D6t}1s^#Gz5r`zy+E4tB#-9<4Y|u~u=uq8#U7zf5J`;$nFh zDPFC(Mv+f5GF^^yz-Lr`Uh!o`zGp+bUn#z$_@UxQigFx;-JewctK#1kg`*kinLLgG z+bXtGUtsbeE%Tvg#`prz^S~Z3|RxRBTdoIod8!`D(>AiZ?56RNSn1 zx1!6@_K3V&sm#{_*siw}f2;UAMZVp`^iLJ}oHOMk6!}m#TKBXvJd{`zRi#c#`5U#nFo66sIblsW?lK53aKw zixe9a&sAKdc$wl=ifa{bR^;R8^z&oI|5E&!qP&WR^k1p$a=QIamqZCh5oUC}dA|I2d{R+hk6faS{T5*lydPSGhZL`WQ zr`r!yen^o|+|&PFMLB$tQ zimxlatN6YmUld_^@;eR~RXInoP_am{MDZBK-imz{2P+Oy9H}@)QGUmv9QhpwY*c-d z;%dc<6|YuYqqt7-7RAkqcPl=p_!C9>9fxw>RQWx{4;4RA+^e`>QGVYcpC3P1*gs)K zz8XVWzA*qCpz>fv`NjbBBUP?YoTON(I9*YG&%s{4H2~yWHuQgk;%$m|DBi31fa0Ty zPb#+NdV59nuPVy72H^i)m2nub_zfKQ_ZUPo9~7JQJUowbcKY|)zk|aG*F8N%O8+D2 zo8($Gx=60y0$Om`P{!%IY)9fh?Qq&ETVF*Nn8xjB1PsU5+Vy}<>vDO&z};{UyWUW?gWmOrDI{fjrmr-- z5A^Ql`r~~Ouib~J-@C36(6s}9Q~z>4xuo0I@i&$C>EFMv*nT~K)0Syc;6eONH*Hxz zbX_8_CUnELy?0*FdBaaT_;z39_}BW2eQWKq+jobZFgTrJYeO6HB-QSV{g3anoop~U zopRwjfAD|&&i?S0XA+zD`J1_;4n6PA3Pg8j`R_-qPfUDomw$tAW6sSEY@XQXWd9`LUpwT} z4Hv{V{Pfh@5BQvEVPE$)YleLK@&(5yZa?6Z9k~~8!|WdK3*2^UIDGvR9U|8U!8~PM zA6g&W2M+SxLmV(s`Lb>Z?7qmi(Q3PPn3cQMw=v^}Gc0HKFekXyztLH1?~6M2O_?`D z*V-H3*&p9B@ejT$qkXJ6E|{(Dkce*dCt`_UB0Dkh56*4i5qkN*4ut1`N9gL84n#)0 zav)>Q%LgJh_=N7CxZi)vD+i(@esUno{?R@=^S=&6=Q!{U`w_6Uefy%mw|8Ehh^)UT zvGc*Kb=C%__J-QuCZ2`AH}T(hh28Dh0~sTpO}w1Q*kP?7R{LMI&mOR^fNl=@PxRLM zXxX2#-_N$L_ub;GANKJn&d`rX_|8sbPT!lIF+MX9+>p6`$j4)>pH%#!5G~t~v2pFt zwL9Bv2(I_9v(bP4wSo0*H)eu4DtBY<@Ywn#qr!L7X3@BhGdtw;IVP3e`ud_YPFbH!f?PBP@9osF6G{?4%p%!QjnyE8DO zt?c|AQ}<_BZ(}B6erInxU>8SsyuIIV&8U5RpD&y9)xTp??c4jqIgG!WJ@n&YKHtWl z?ziGkz#XJ}PmV{8Ljw>mqC{bP3vy|s*u`}ocJp&y^> z^Os#a)Hi+l@Zax@ZS=1XY{*U)CVU&~hdT#wgSpq!JJ?T`CpIL$lbE-wOJdiqKoTSJ zdzSso&MmvV{h0?=v7$9ocTJWa4E{dK>-(|{`t9Xdbfdhmx{YTFtu`gJ0(F*LIa2W}t<+f#i7}iWxnp49yug3G^Qs89qH4~7+@BxTySQ& zh0kPNPEau?_5sBcRm_X=L1QFBQ;nx|~_Oc<15F z;`b%~?>MvAWN>EPiqg`YS<>HW&a7uyv#Oxm<|ON#=FDQnzKS!;l#t@gBFj;VGwV6_ z*Fl_FS`cU%IO}o-VhF#IGfVB2Gs{RR&a4yRf}C0ZU{Oy-jCeTCER(k|wwY~8b7q}O zG0mBE1&1chne}^)MVd3~QWo@2a%P!w2gi5~^BZ$!@gpVR%rbe$#CU(q!@XBPLX7Mxk9(4m(z ztCR{aXI3Gbrv=VLmI?gOL{WZ!ogMMhvEbfQGnZ=zM zoLQ8GGs~=)p$c}R%b8`vS(-CT))EhA)@=3=II~O-`U|Sq{=;!*Iq;k2%p#wTmow`% zX7zAp@rfLAW{qGai@}-22x*lvO|=ifnI#Dz9E#KRMQP3~-i-EgW*y)dcsR3?EE=3y zrWGR#b}&CUvo4XMD+-PUdO5S&(%!?F#SiRwIkP&^-ou&2n_OSbne`AYz?sDw2xry> zbm8U9;)7Z(IJ4g2&hc_){g!57|7sN3nYZf#HZNkNIJ5YK+N${b=wmC6VA*kb*1_tOjRX&8 z)*v(}lIs&TEaA)wJ%Evm6#8=SLoP3Y){*w{$Z9)w5c3tcj398cyNspUZ@1ya^$E}< z5V|~olJNpwTOPn4Lb!{{iL?wF%R+dGB6MN3?U1p&5{mg$UW#hjVY|)U@Hq+?SxQLx7-4O zkLZrVg(Th&E9Omc8;qMQ=J^P2)+3ZOELmXLd3H8wq~>L!QV7Mo-EZfcsy`exm!FI4 zjIuLZz6a;|yAX=cHOlT(^24e8sA|bP%Wh{fzY6gMs?MP*pH?ezu5%PZ@d37_on1)f z&v60gL4@M7*gx&;BdFYjD?yhc6!R{+U0^((hAW0+5K87QoMqXCcAK@ZTmZ!!1Q061 zvZHCuCMY&g$%iYT6b7>Qpm>|gSB^Qme=owy@72e@xvh$t#pv$K$eHKVG`~mJREF3L93beNxoP8kBi_OY$r1v4^0! zD)!P>DWz2jbYYYK)LhkZ2FRsRm)8o*8J58FN{9n6sfDD9k--Q|AaVgZEPE9_l0*T# zIs`taLvo~wBxAhNj|9TYaAFb|dkp~z1bR0Kbd}ly*zZzX7sNnp zI+3tKqSFYb0^{8xC1c8Ks|fZPIGaF-BY>h}^D0K@ofVuQO(JgwtO#Vq7Ar>FW=!Bh z(R%ZvjfdEHaT#P81U3s?R)iw1v)1VZTxFz|z*+>Y>xbiFmej*EeIj8t0(ya9+B<rPi%t2R5_rt!G$HaG1LP&J2c@EntQP&5gmtc-k^VAt(>Uum@@ON06I!w| zaCcI0C{Ze_}qkF$)s@{M5}_8su|SK)NTU(L!gsXN2+<@*daDSF88HplbJtB~S zA52F6BqRJ44I!LlWPlN(!hOW4M1D8Gl_vTf04E716hY34t+NSFA)u(nBqKYF(3E84 zZ6mBqGQu->RF3eu(bpvz`BLB-v$-an~d3ttwo}TTQr?;%) zJZ(b2HbnSo z#72eRHq#XvHytTDQBerCz6hMA7!v|#C!z#1NijU>Ns8g&Y+Z?fv5F?sE7K&dMx1}h z?3sp}S8amsO_^xm%wyy|Bh)7O7)KVThjsmsASNB-B`F!*g19a%n^&dh3n-b=^JS%X zzO0NU(=+4r^mtaL#}k>;(3rPI(E+!P4xWJY-o-E%aOoxbNWJ z-tgd%Q6*j63@f2zM;(-q?mgMB%BA^d6FAi!>-?2pGv`}ZfgQ+h$+8+-RL$)woLspx zyR`{BkO%bEF5QDX<{1z1Zyv&gy5EbwWk*rRL%~7qc8?FOd)6HX>^p80^MP}Mhl%vY z9cK+f(3-H;KXI*}ajxGP7GJe88|9xMxHeqH-xGQ2TK}}QelFrXvb*WrpTY>P%sqkY zu-7N$K^REa#$61(He40CE4Vg{m!K0|*Rqg zg=^vNAwfK{!yN9OffJnJ!Rto`i*TOJor3-6)p0@K$)=l+bMhx1nQ_j?5d6|jlENzp zs4;;Plr?rIs_Tanln>9l^<$iqGsG6qk2_Pnm2o@Q&4dl#qB4?-T8*2vpdarV(LyQsM&+u*=e2L>8En?u&=0Y z)n}|M)o$$|VngBBa5+XE(&5Q$1IDo(x|Ik>A{_iP5w@~PU+^#q zTRi%a*73?U+4w+hELvm1qpZ6~n^hr|msy!gy4h!h!DUG1%)G{Jj{~9k!a$*lU!PEM4%byD;d2X!M4sOaFNlJt5N+;2vN?cFS_;l zqFcu=tRyu%5O9W0cn`s`&b5=jM})^?9E(Q=`*f0Ha}+JXSqOoLX8Aqs9-~<;9;+FA zR_~;{I!S)iiz`zz0#<1PZ_40=!A`nofTo-dNgmdVWSFKAda%E_>oYRI2A$a70d`>1To`zK|7--6e1{{CZjw_ zV55m9-aE;8J{-ZeDhZtHS}S(}MH$yZ%YZV@OLE?G5rN*_oiTD4G}-i*1123tLW0p# zO8=fm)S6S z^z6%Q4;w>ux=~YEWzWX0Zne2TT5%%I3SN%Dy>~hGUdB0va2@hM80c!z)Z4fsu}iDkr9xGl33Hp0Gpxk zOwJ|Nm>LA_v8R+Oxna<0v<+`0nGqM;!8MW@$wB80Yt&%!4=#@9=aVIoofZi85%$Q; zGXl}hkh+l1GXjpnQm5ZwXY@3uUn#15{i^VVEWWIfOq(RFjFbd2$eme+c+^=As>dOL zXt$n*WfU}ws59vyLCHygLa0TZC8`gW2eKpqo&yIYgmgmpth61KFJrKQa%jnb~DXhZ*Hy zJXo9$ADPY#BrL^ba6YwOm)U`6WQ|V6{@5?F??(n_ektZ>%*ITl_sFtFxP-E^qBPzYiDhWtGW3`eyO47cZXzc!{S;7TO5zG>JTwCj(!kNLjV7zFH? z+(84ulQ7M*!IR1z=C8g|Ssf!rd18Cig=pb1-+w3bYRrc0TNt12vX^ibk9U zJI;N>@RrtbS;&*-%U+I(GTXpnO=tTKqk+Yl7${f-*aKKtFaQUyC**@ouP4|IZxp*f zo{zc?V-AcPx@*WZa=!+hE$4HJIls1V3&gSmok>WF^-DTBg83NCE2k{j8y5NG3=|Jg^kDVDlr%AwI-eV>ktC=FcEK zY8AAGbF>xN>HkY!(<(A3{`aw&)}6Yr%)&n~99AVx9Wx@$IS6{zxlLeQlY>y*kHJYo^^AtZNl@U>Gky?znyf2c8x0xnNe^k`r)d0j9~G3;IHCtX;BTCa?zjn!2TZ zdp6YdoL$zR8Zx`~oH29m37}k@4aJQ5S+ys?|I*{CdoDP(rY_!d&g^9~>T7zI$9s-_7MGa)CY?wWF_S}VF4FwM+A|L~uv0%Xr+1U`Yu=kzJy>I>^42JxZU2Y~O z45%u>OF4h8P+2aS&rX{>24?B0*sydim@${l0_SC#uDE9Ie3ttScv8t;S_V@L#oUJ3 zD28OkEk;ZTPEVHqL#?V>a(I&5Sav<3-E_xOYTk-VwdxyDsHWTe-^ZT%4LMVB8n1Kl zpJPrjt~vLn>gsc3pCYep)xrfc=3|$HZx&~P zHg-__7%s?@7A>0J5U*KOA3wQ%L43r5nbosrgZ32!v$Luj8WzW z7S(tASJrP{4sFS8%1hqv#vkg3*KasnXT&uW3A{SCp+@&qnJ^Y$a6PLC~VWWZwg1DKNpyNx&(JGZmW@dC8CI*D4BcDP&$~q+WPSfv>A9yrqx}c$o|+ zyrn?lEd>r&z3`ero~g3%mO@^wvhbEd7G5&o_f@}D@nyxg6@|AHcEVcYR`Nj_QlNGBKmndGMc$4B?ijOEhulP&F-zolCF@T9q z|H4}e?5eWxma=@6g|`&4@RkCXsa|+XAq#IQP~6DxRgdKvDRKV0Vqm!dnVic!z-7R4=@x zkcCeOD7>XW;VlK`<56>#FTABd;VlIUZz)iCOM${$3KU))U^&(h<`dph;3$=aw-oYB zm4&wy@V^Ll@iI;CuX^D>MLePU(W)2zQ^e0y{dCm}Zw}&hsu#W- z#Dy;hc%$ltCkOFcDWhKZsQ&wkPbqF!e31ydU#R?s;@hhKNM+&6L42R;|E7B3K}9?V z2Lkp>o+4f>68UIF;mtug!kYs-;mrY_%yj6-s@-_SDXO2Ta*g6L#d8%`6OsRFmDecV zr25-czDrSfbYL(1IVfNFbAT^ty71;e7M>j7`>H303ETI%Vi3nR${C6{e6--tftkoT ziacN7Jd~Rmz^*FGJ2Q~WRPLw9dp5L}2Qq+XsXRmR9K}V7OBGirUaWYz;&qB^6(3T3 zOz|nj?TSBD{JG-)Ved`gqpGsD-!oKIs*+Sv8KA-(C_so95(Y)3Az+B0sEA;rqRfIV zU<5=Q7*tfWQJGW-NKkQ}aA-uu2~iOdgW680jUx)SfN^68nk+ z#1lkw9!9^ME}6f-p?`D!1#gtROk5?d7Vi@u64#21qDnt6iJQfP=QA~rmteO;%Xf;q z#h=7_(c$?Q_8~DU{=4~26Iyi5B|E{=0{7l>}ek<0B`$hi5 zmgOU2Be98ihBHu@f>lAI9;46`tz9b*V!z8ow!6? zD&8uZ=^9{nzvMOI6XMh2Msbs9uHR7ZP01gKJH(yhZt*+uU*gZA4Iiv0f4)d&iToWL z1TahNzt94Af`D@Ajij(S}pd9FB5yg^(nt`Jv=_lOUOYsDwU=fxMr zEn+q0 zUlYyu4(Q*P?9XeuQ}S-{2eDTCRdo5i1m)AkEb%|he_AR#e;(9clKYASM1LOCQzf4+ zjuFR;mEtsUrs&UudadN^#TUg_#2V3`=k!a-UyFFd$+R;dHW6Eh=6e?U;c&@+68nh# z#ew2b@icLyI95DYJWsqryjtY1ZrShEqCb!6y^{TTOE*aN=P7+(^2g%mVx9Q2ctE@f ztfvUq;#^;`$X_~Bo-AH0&JwQ|O}q%$t(1J5_@MZRXudbWZiD2l;v3>8;uqp~;=jZY zzc-+Ky4YB3Dw;SESY9OgDAB};fc`|ugT=E%^Zf|Rr%0YI@<-iV-#YPm@kMcqSR=kG zejt7+el6}3e-X|19{5M3VzV9-2Lf_S$;Dz9v9DMm4i--pM~i2RQ^gC#S>om5wc_<+ zmAF#8SA0->N_v7d&OFDzlfJV%<_oHpTg7raIv>|jCh=QqIjx!x;R=q zTbv}GFJ2_h6z7Wb#0BCKak*G6-X-2AJ|eCa`MZ7A|84OT@eA>v;$HD*(Z+XYmJ5rS zVxAZmISBym=7@h4ZxC-1tHj&IyTk{@N5rSa=fzjV*Tlbz?}?v@Uy9#~-;2M94!)qX zp7~;d*h)-@ox~Ecr&uN)D;_Tn5r>H*#j)Z{#9HeE)`dccZ&~+kBaNX z=fqdU*TlEQ_r=e}uf#p#4`RLes~E-&fA(9Z7#Ev~ZN&CsXR)hzl-NrgAf6x&6;BgK ziQ~kHVx@SAI9t3*yjEN+-Yl*ZZxcB`1>5tcxLy2*_=UJj{9gP?{6%zfJwNGUme@#a zBDN9Ri^XCW@ksGcVn15YG=ZhDKGsP># zYedc^V){dTOk5{!6gP>SW`y>ii9d+7B4-@o@}^>uSS%hT_7aa1PZUoV&k{LX3H{9y zuN1El7l=#5PwFfsZ@?cb}}> zf7Z)BClzQrDaMqCU4BKmCz> z-;~>8T*PqQ<$wHT1f#D`!9wFeiY>WJb?8Yg5;M$*6N01&#x&8KYR8; zc3m-e#?qNSzTIfZsq5|87x!CWM^mnk?I15e^2;D=-Q3Z#3YpQzUv@s^RDUb*LmrN6 z`oq_oq`!H{`(==|9)~~L`5%ATTqsig-JjwQm+MJ?Rml5g=;LMhb6IhH{AD*mPW87Q z{%FSf;W9Ak?@r`drUZ$f&86^%?csm8jOk&~w|fo0f8=ut|Kr>783gnGr~i=++nPFm zygZ3~YW+5*v=^H?S-)42$5^fe%x50_rH*NTU8KJc&~QE13uR;EaX2^r*za7Yzi%LG z?LP{$y)vVZ?+=#(2iU!Z`fc}(K;I5?mG|gc*ziftRo&YIfq{#vWBSH+g{mYB7C zWzgEw>2j;hH&#wXc=wCJo)u*kHMQ2Nw`#35o9ka~T~ixCKCmWS67EL%?!Mn{>s9Xb zuB>=+XK0yI^;&KJ9ZtQK>mC|fRQBDYm&KMZ3+FAg_WW>JWyKZY_pLyeOtdRwv3<0& z`vo^^aTey04r5mFz``mkeNm{YX?bwb8GR#F_M+%w8*@o#F6cSoomvO8A9q@1C6-qd zR5Yn*fjQEfRs4;)moJs>tAlawf^N{mm71>MP zLVv%5K0rO5OIxwA{+0G=i^?mu*1s}jbNws!mikwY&aRq0;gPz`1!+~S_FYrAwf?>K z&<v(Vh*tkI9ta`(7S+M>xdxyvG$v$|l;NxK$i*n8ZFyKF@Byz>2Dy?h|EORa^QlMl*{T1WC&%liArsa3nS|!f%rR71)9`BSa?Ym}M zXj$5Fr^=~!^FoUw%VSlcl{qUu{K|RR-Q71hV%L)JMKxBNyow$b9V=d{*j8&T;D~*t zesf}5Z2%t*Z-I&(}Yf;C4L5Y)89impQ?`PVnsVXEcjA_SwG9QGtr|@^FQ_EP}bx@e)7w z>LwNE?Xg{FacGfS5&I%*1xC^WjHu@@nkqS(wzTJ1+Je#YO8pj$mMur`l+|N(n0I_d zt9|o-;s~eJ%dpy7|Bn4i{X0j$^+jJq1n5w)uA*vZtja1HP!n4gsS2(5u(o^$`eyn` zyZU50yZZ#KL%Y^IQimt)byjRny?x&^m?J(4jk5s9hdIuno9ZL?1#2EbPpz#D%z34L z-hC(SdcUM>*YSPq@3U>E%e{SD&*@pd9orz5vJJ+RM;7N`p7J?0p_P$a-0J2PODc}s z*`(sLoskt873;oWjn-~Ef2Y|}Xf16z?kvI<>Q}MzbL-i&n)=83fPFg-#F@Qu#nAs=x^a z=WTnRbK$Np(|q^$-x-#MT1rrjGn6pNfhz;aJRwbJf$S=8k; zYiSQP`v#_2fndM{9JRw;q0MIASM(mBkh<550(j+Ew^C*=t%XT-Ty zq>I)Vh|WVbBV97Q3WTG4Z7k9y-xD*V=fZKMOEXV2^PNY!W^{x%1$cI3ElbF3r!B(`eg_;lvk z>wD>WV1%NZm}5u3AiM!$^auQjOwVE7G=tT?&|eWean!}epso`le+wUtM&^vDv?6PBRUl`?6f5$$ zKN2|Kd1RfWaC8jo^+d$%xtQ;~GyC&NiQatYk*9KQGHZ@SPp9#El`V)qK=B3BOHQJB zbS}jgTbL)CiNYwKd`Di!59e6xw$U@$xtpU!M(hy1pKW?I($9#Ua`29}71^p4l|V!T zURMKpKtu~_wBDZ4X>|2wj(Jp>D2s9pk+*WrFs_ct!B3N{$UAaX9%Yz?$oncgFuH&v zb31;J$yyDH@+)`bqukR0Cov@YAjMBI7n-HRqL;8mpJj0mb`ry*rCibH8f={JoZFg3 z8<{^GEsd)Ahk9(6aafeiMUA&&lXVD0Mmk~kPJ9~uV!m_QVT;B$u`@8=`O~HefjEy? zkn=q`93R6Kk9S&na%P+_qeL*@xmP|GUy7ARFyHyVa7B(iHeNvcNxuJ*_#+%KnD3mE z6g!D-aR#N0V7_y&e2;kV0OTo7dP}psXZ(GxAM>4ihmx{*clyVC=bn9eJe}n+-?_KE ze|#V18BTs%Q+{B44!aTaoqP6!;t{SN^PRJE(9LlMM~z^<^KGWS!{XepBDXtv+?8BR zX&XO-4l&<3_YpU-#fkT&0`r~oah;p^AQ-=aE-~Nv3^dhE>-q%=s9Yp_g zSMWB{udq(pNJeDkV01s~6b$TuK|baW#seofOfjX(-=2&+<@w{VZ7@Rl5-7~kpQF(1 z%s6~-zdYBMaZqQ>=?LaK=jJY$fi-4E5_b4;Sj5e-1oNF!;E34H9>RR*UJnN1SF-(> z?_47SYh=TN0lF_Z41TjBz3ngq*v0!m6)CfGDbQ7b9fSGKJvkJg$ezP|=fhAtGv7Hg zxiD6>o76<+IB9%-8)t(fmpcVKo6*(HEQ7Fq#=yi8%y-VUdg~8iPcels-}zvy1@oO# z)!gP`z>IDTuw3MW2;4*Exw< zu(Iv6AF<5M@@6;Bege8Q#!hxI1N!4wf@ld4F!}lG5P|_N4+dVs-`4gdbfBH7$QTa35onzZQO8GyCsH>C6OOmA zTTyox2>+xxY5)SDZ%R%C|kaO?eQ}dd?=N;)l(Kx*%Pjz7f9a3?X7Wehvh&hDv;XEfp9I--MF!vSWjPf+Kp*38%r-jYF|ZPQd;f4!{FGD z^lsArFHQmN?}hE%NqZ@+LwF4lz*g{lPxfq|h27IhTPdwW*1)zTX?wnB`xflpNZLwi z9kL0w!;`ktJln5ew=-!grPYovtrjBjp}bd*dp-MKV7nhFVcIBVUIDILk*s!iqva1G zZA_Ni=9TM;#idAI-$-e-dlKu|i1b6!zR)#&*&ntQNqZ@+4nJUDAC47yAG_L)_QE*q z*aF{$N5J|Fq>eEN*CBH?1sB44WY!`TvDBev@;9p!J*|W6n7`|hvv07Yv*7J8dNW>j zqR{6^#>;+W_91x=I`OFU5=)uC>|1-GefVRnOGV zspx*c4P`LuMPs(%bYzB6U>nXuW)hOO_744!?SL^Av>YL{AK#mDYq01+q@o^vxmO{*f~0y6GUfPp2$KD+9ea#r z*;_kc^%0V(_daB5DX`wzNKqv98hf3kUGsMs{d{M~_WOR?!mLo)qYZTkT|| z6h9+T+Oha|EdA8mv2q+OOnoN6@@ypI=W=A`P@tcik#0mv@x#)t@iBpZez9ZoeLwfZ z@?Iq4=Ott|QlOvhNbe!Z4>vbUyXLPsN7zo*2KwP>*aORNkj!XEZ-#G(NZx3mE#@G` z-)UTXz=`pJyJSR6RmwFRM+x$|ykonS-;z*cFTk{v+t8uDzVj&!~P1}Ek(a%Vx&Q0)JlQ@#8b1^cV zkW$*t(yqn7^XVtwiSZ%2@pB9;`>-h6ekL+!P+;4qAXACt`7uY9^(gIFgU~2@kP}<# z`?wlbSF#v=+=@&!1^QTv%wtGJEaN%yj!_#-jV933$xiGO-_vWbeU*jjX(uwDQ=q5) z$m~NZVi|cd$0+`6!?pN#E0R6fiSYrvXGMBbIiJk2mP& z6eq@zA;!;8Sf0Y7tkrqQOrk(PbCJ0mNqsaG+iV9)V}C-j$2hU|^sx%+Ww5%L#TG+& z6q$!9Tm@khGA|(&vCN@wL!*)ZnW+)~e#sh*bz%XWolT8Cg#C6pV2yr4=0^&wQD#eA zN+PLctkEu(Hh;fiZk!VvNI$GqYgo2IGPODynIkE%R)df^5y`7iC;DM&*Zk!f+dkWg zE%E(~gXI_&W$R`mGm`@SEJ0=wlKgN~pN;dGWBxKWft~I~--4fpv&ua%zl-JBo@bC* z&+_K9WX>vHL<9bv#`2kN<8)l0nB&Nsu-t}ZjwAm>W;c>$O3~IaC8m3&4lnadIjvxX zWJ)zhrYRL>bkWwa`1fM3RCFFo@t9r;qs~ZX8yt_!01B-0NMz1J(x_mYZ$fE|4J5mX z8-2s~aUraxvKY7H9mrHuppUnZ*@{%eGM*!^M!ZStn)%dY$l>u_tSK%xOpShp{m*nj zZ%qnuOh7W;ijnDrq+Vo=SlTsz8`Dp3CpOym(+`%%uqgeEK;}#etkpDRrXZ#GDPU4r0C-$B1=QUWq%A)kM z6PeE`(9eEk_91zG%rUA9O5?*3dZ-iYi3<`_mz>r(79bfPhcd%NA7#k&LMmbz&ym;D zhr^R=rljx58g+7FbA4|^VSfse@pc|ElPJ*JTx2dsQp>pC^kQlAw=Z*tIk7GDV~z^2 zyqQJ0-#m)U!xYR>0hyPOy#1y#{jjua{#MXWu@f^sK7`eF7Nd`!kol1UePp)5u>eU2 zm69JEIH+=)+x(v4_J&2N36;9s&7{y}`lyMPdy5<4Vtl9M_p*|!xYDcrGOUJIW}chD zkWG^&MV8eff*mZ&=G6xX^L)psyV((7McuN-TL1|grZm6 zlksCkC1XAP(U?%}GB5&iZMtcnS~` zvCIFL!Lcw5Q6BRN6FiY)KH>X$bz!l%7x{|0Pmo|mmqsxSG!2 zH_itWyO7Y-C9|3FYkp94EZ+P6&F34lrc(&I#I)c88T5*ICd|N0@Q18u5#cps5HT1I z{Q}HCiG%{g`zec<=S&?~M6d(=Qp~fqSafjBxLQn$ZE8Ui=KYWDWdfqFHt)ZsZ2uFn zz-)hJI=~pyArmLUwb64O2lN~#ATdkW9R7+HB?vygGkU)*M(|q$qlT@DfyB-0wQ87O zHJnD#0vtw>QZ_Ct09Q+9Gm{*M{^&DHd=DajDvlez=3_isDVz1c{@|X(lMZ{1#8)A- zXE33jSv7kpgs+W$II-Vk2NUclRAANY0M^KPnz36DEs?^QD1YGshCZQGgoHQ=kV`Qq zP@8JXLz23#Eve%#(3c3AoTL3o@%wObqbI8xz zF!nzqk*P#7Aw4jCH}i8+Wad-lD#&Y)QYRi?4|xlc?}Pa_Qe<}8ok*!=D60zDKhh^vcCyZ*TL;D3n^7c`EI0;b^77}W-<5s zKh?(X@Kha|Y(5y_>T7OpCfkh3fe=#dDGxz1?ZX`H%uh>^ndhwoe>w9Tk-`iTv^ang zlsKb9$ikHEkUvBI2O}ex3}lWye)aJ^FwYBpUuK@Y;>&6P-Umvy06G7|{p$DHz#DfV z3p2)JhIi(9yU3TB=j{q#X8ucGMx}Ql&o9_!Ib`N}pz!V40)A!lWqtu`#wxnFlT*&?jqzuY2YO>Ml%?3tgJA~U}=MP~k+6q)%fQ+uyGYtJuvA5wM}3(I`l*I6%vw*lxSE*_o^WYOjJ+wdOpHA~1jmV! z_}Vj?QOyh=Nn&-xFGfGrsb(eI6GGKnk@3!_$$)x@SHinN zCN*@Q3CYHTKx&r;OsJJk&|*_@#Cj**p(!Wc`^|}$M|yM*!Gzv*s+n2j34v;6R(V3G znr|MiM?#5Bz-E&@h2R;&j2Hh@0h5oQ<5|M!F{aE1Q@MMY07d~knZFIY1D2Y-#BuOa zBbWKsUZIBFfpQ5FcLiKg5WHYRmY9I#TGJg9BWQ*vAo?6Kb37qby%d={kx+u*DO~|! z)|u=OViOXcA_S_L@pg|P?;^`x1O*B0981j3F$h&g*cDj5jf?|zkPh1B-$0dRO=Wz%w9>X-v{mZZNr+T8FjRJY z+vffPDz_kEpC!19;b@8D1Trc68uypql%hSprENH>xg=+ z19-Bqt<(K;28x7|rBCC*&0Ftjz9R;oHPHq+c98tt5Cys4Eivx?%-zrPd>XL>iJ{}t zfBm&-H3glX5LGjCiDR@4YaPzDGNC1Y1=4VGHD-P_-~%5R=?^pf@NPgCB%D!ZS2I(A zgyST^;}^a!4dhXY<2Qs5ZL<)|iFuxaBOJ?6;Ojj_j%1ux2Zk07GV%BPjgYG2Fy;4O z-<3bAQe1I7eSw5Z5MLv)5{CHN?w3RzQa&A!FG4~g;%!s~h5DOAhxc8-zi(}NA^@-W z?|)eQ-}Zv%YapBV5)#G%;q9mhfaW)omE^YfcE}+Fn?m(LP14`+q@qR zFCV%BBs7cQ#_|`jiNC!W1OxLyBYCOkC4S+?2N!MlqjQ}%8hKiCLR@Gr3=b?tH4Aw0 z@4VqK7@8oynj-2Nvm4IxG&;jA>fnwd%@=m}ovDe4-tbC4KOi}dm()%^Cl5-Et$ zg-CPE-j9T%8o`sGmhiMT9|`*(v4HipE}mV@OqHi6co4u1p+Obo%Y$2pxokY7yRG9qfPK#>M9_DJY#-!fqKO%9?=>&H;X-amD0|5FJfX8Oy$X$IGs+9d}v zEzCm^T2m5GHCXW_Q@?|#v?vd}qu}7l(*aLl}Dw94M zUS#v{;rKpWo8>1Q=p$9x&=#9kl}HC~Ud#5s+@* zcU!Tc+WwN%RoV^8lxnj)FQ@S)S|DYUQ>Cly2Cr1i@oYmWwp1~t43CC4)DGS(wmlc7 z^Ne}J)qRSxp>D~y(|)^ISl+wxNcwQ?24%939BVx+c}w`9tNk6E4E zV_f4Q^#-k9z_sa{OH#a~Dw8#7cpvTH9&v4!=S|WBd^9MNJ9NXlXus_dmVe`59}P+# z0QK1ctIv=Q?hy;Gwt7oa>XE8UX$#ALX?z@f1KD4a;={EYl*xKDynS|Xf7tdec;-#w z6d$R|q>qL-&wkq~(Ds+4tkO=tQD(La?j8G;v28lJ7%9~}MVYK2OWX-NUW@u()*{b~ zPha-E!WsVEge6r-sJCAbS-%Xv9sfJ?vl`6LYA{cpwj16?J9w12Hox8T5evQ^``#Or z2km#XOMS4>P{3bufR_eka;!GIhxXfX#>XVh53Gr8Hzr`dR5s~G4BK`J+=`Ts~;o1$#l>X?2@_mhu10Sc@w!b9B zN2)UEqv4IS-}VPRS0JVMaP0VS{2V0z(*gT; z5mGTy36lRw)pbkJ`$u~ouQ#UXDf>Dea{Ui)`+R`31Br*PLvt=lT1QzZ3b(JE2>Ok^HgY>&eu9Iv#H|xfbsU{I}yBd*SQw z_n7mhjO#pL@|cMij2(ASoZm4=4WGsUQp3lO8FLsT_f0-;^0>psA?6-p_#F^7YWM+5 z{kX%!Cyg32;hf3i{%^-09zOM=ss9}(6VDmVIv-Rk6PeJj+keO1?=}uU5jZejTxs{> zF&O#Qm`PI+!3(P|p1?s)t4X7#O@M@B?TE4C&K`wmb|Xy8FzB$Az0i2mAYd0@WIZpJ zG=Ubu^H30ad>KSkyvZ__U;L&GKP|L^W`wy585Fs(9~7CvI77z-T?9l{T;!nZX8Tc* zM;9WfW=qC%Ep7Clq9PamS5c9hFe-9k&vOb3TewpgBh_tRr~t)`iHuOK#Q`VSD&#(! ziNMPFjT?0h;mr#M1zkH8QDPAWImC#df5>U!@yWCF4C=moH3Hy-F|oU5l?$YWwLQUGbun+V1$H zg>E#pZEpHy8M~f2(;KP%h?fAM4s|wvxo@b0K1!+Q`+szm%Twz4&L1tbGNqnB^B~et zPv*?lPTh3%rjNaL?fV1v`!USCkl%jeN|WQ|wLeI6&8lPy%2$qztF<@T9{n0Qw#oj@Pe<p$>6VtF1HbMyLcLRNt7v(Uj?aI<1hkLZIi2)I%`V?5|)S!bLY6#j@O5_>Y8I zo3>p0J1aK}t~p=<4junQsRA3v^U!gKB945Q!eDk5!#(Fye_W^$WX6X_lyS(#o>2nI z?4;5wnHK8Ys1f{hX5jI^&w|V2jw>!6#s~=vJ9pnVtDf6;NLp*LYbR$IX35T1Z#KO@-*Hi80Kj_C6+n* z7O~8)LU*IyFJ96!HIRExcUnpycaEb{?C9CpaPG&rKJoYUP|uLJXWyYc`_1HDb+_P``?6*4;ABz2zygWPqQ;I-`VUI!kqaNVh1Cy$#k?Q9Dk zN)KlV1}5&-!*`82*i0;I^9Lc0&lx`%frd>jMomRz^-1GKm{7U|IN2&to*_;6ENh?8$Golmi&Js!o2q0VfsS- zzbw{#a*y~QMV+raxwQKMf#w^wNNUXaK7)@{u=+{=t3uBw$B2n|f6=&6II@g5dn|6Q zOd4^{xN#UIxLGl3VshX1ZYiCDgUXn3oh#0nIBndNb0&|kxL~q3#5@0Hi{pL?qM=_f zbsWN+|Br*zPn!|Fn8D;&G%Xx7w~1NL8^`|V|BEr{z4z+8o7=w^liu80#qZC4 za|l7Ba7)zUjDOsY4sM9&h?qmd$W2K6>bD&UqfXLy6^|18h!rBAywD$C?I1^rlf|jx zW#U!h5^4o3i1{^Y41 z@mJBrCxu-L95ZO&NjzJ;K)h1CQM^Mm@kmkbMah2`KNo)#gBbAi-$-mHb{G4J{1rLv z#)%h*SBfUyCzjtOd7b!*XyRUC`9*lVKtETDH;Z?P8^t%oPsHy;6PF(455qo6KPE0c zc!FdTmmcyY$tEs6`XjG z$bBUrOQPHfqZM~Ic; zH1Q%5<8Y>U6^XQnguk1_<QcOr+O2Y0a$rV~|;xfYiBmw)B6Me1mu+iSo0gxHE24?R2>Xv@|B1MhguYI8zmjNA43i$RUio4Rv9(wv7K>d; zlskq*JqL&M7-PPB0$OFwC1hS;1$KNN}`#lu9-4a?;w&LZf? zS3HS&_&Y@$E4vBe`QioQEb(%2A&K&S9L435@7MA*;uGT2;>#q;y(VrGKhbg%UlH~E zR`cN>ckxKk#8-qL6JHVhv+U0h$BGlg3rYBy zNuqw&OTS1o@fG36#8(9Gmi~V6VG`y1IEyb+hQC+E4`jDP{7U?%_%Csv7{M1=miOZ; zV&*L)wD^j8*c3b9`p>4t13wh}vtokY%-&2oK6_&HWQUK~!s&q(ncagsP) zyjZ-3gr6J4#o}r$zgv7*{G0fUxIx@T!p}S6cJWIs|62S}tP>sFxMF=nVlIj6!ggYX zc$zp(lI;uqpS#l2#!xL;&!18%1lVq1|f z8&h8@n)_~$drLk>JWf1O{Iht5c!hYic)e)u&%xhH$+wC3h!2R5iTvR^>+`Jmg7~`l zrpT9=Y4?%1OXTk$sQ*!{6Z!fm^%0RTE>kWPJBa+bAN51TVd4mJj5txO6fYDn5$B5Y z#D(IG;!5#0@gDI3ajp2I$oLPe*UREo@eOgi_z&@4;y%&leM6MTdvAtWVy@UsY$b9k z7uugK@@F8Fr-&DcGsUaKYsH1)jUscah=Er8Z5U(tPyvJpNV_KAH)Ff>mnZ(890S<53#>E zP#h)>7bl2}s>E_L#7o6%#p}f?aiw^#_@Ky;b@cO$xLIT@AL?tx{bDBXCqvJ;&t!A4 zQ0yc!Koytw6wAbc;vjLjI8rqCyHT!E@}=S&alW`fTp_L!8D56#-7LN@ekAS^zY+I| zzliC)e~t24VpFlDSR@vUM~S_}J+CFRl~Ui<`tP;=AGp z;+NvrVy(DeWKIT^02={@`K_d;#1+ydMv{U-5s@lEl4@gvbZzd*UKB!4HG=NQocEZN3)6Sgxf zW{Qo(CZc(+0lT)64-?Jv4d~5t4X~H={lo#{VDVJZJl}x*7|9bw^SlH4gP(KE)$)1b z4dP;Pg}6$*OT15fL^RJo;Qv|4FNj;j8qqulf!&9aKNG(czZJh1_luZj%o{gihL|rF zh^@tTVzJmoJX-86_7?|=40gutW}b(DS4qBBTq&C8AXsjmdw@?#zd?LSd|iA~d|x!r zLs0H}$v=s|hz_3*V0mM)sn}UG&pojGD9H?XMf+pLZHqW`=j$ov1$XNobgo!C(<5gEve_D756 zxd&thlcRpPI7S>VP8O$#7l|{)x#B$WF7ZC`5pk{fwD`QZN!%j7Cw?e?D}FET6Mqqd zy#J5-M?~{n1G0Ip0Ujg$vEqs1VDWVEEb%YmWO1f=ndm>?xKZ*Q;yvQuMDu(D>)#}K zi}1Ddvj>A|viW4YvN@lNqxkzoW`Zj<^rY%Dev+lvfO#pR`<|NNqtJcCBCZvm7X9ZOTO`+r?}*#Q&%`gqZ^iG$UqnaG1=7VVv9Z`xY%dmx=J^Nu z#XSE2drDs>9xEO%4iSfmBg8S{U&P5G!(p=Dmy7;$kGmv4C_W-SDLx~Lm@e^^E_>K6ZSSQ+geh?JRa}%`BJU0Ogq;D=V zXerxYDl%Rvd{ulyd|PC2Q2O63?iVdSr+}UzA<0H!a}xJP7z~v9&SIHZE;8&Vm!Bmv@+W1+ zrXuHx^F&7Xq`q2Y98b!RiHzb&`E_xJ$kL=ua8h0_GR7w5H6p`oQr;{w(kA79hx+r*vXZjlixx!gi1Mv~Dd$wndrP*UzJG6p5(a*1zxX8GYl(&eC8A61CmfAr^~W#D3xcafCQVoF>i?uMw{kZx`B#AB#VU^&+Ds(tk|E zV+b>j@b%Q_0Yf}SGQ@3eL)_*v^zCq2Yve+)t=K{AB=!({ie+NCI7l2K4ikrq6U2#P zr8rHTBhD4)iSxy!;tFwK9ZvinZ zW{L%3b1~+4_W3N2dqoAlpW>+(O`0}pv{gKH+7yoy{M<^abNboHP0C^H9X(M~xmmW!!WtWhs6UnJSLLkEF+sgWrboztv3S z6j}0!idn^D&YLs|b3CP%I(y2fNiga&_=Mt7)22;1XY>Wr;PwxHaOz}tn%_#XP&fWb z`Jn5}r#1f44v&b<=U_W7jayF*Bih-<$nUo^ap+4RP}((Xk4fGAAean z6nH#im1#ljOk8K-`!>E3@i8uc>SO9P1oX=wYgOUcneJCMW!c#&dD^YUzTOJS|M)&e zLy@}P9@x3c;FIfRKltmt0C~R*vepZza3M4L_{+|Roa%4J4LHs~M}K&nlJqwZdA|&@ z)~E2t_fhJc*QA zze3c{??2p5O4jdH*R-YOwRkW5q5=8;;W_kJt5ai|6FIvFtR?w z!M6xH|Kt11fg;te1ohkQ8-c!E=Wg9gx)nBjO1t+sytKy=-H+^1SXg4z-rv%alEV)_ zys)rq_tMfXMn5urcE5oY45Q(H5J4^Jm%0g8nk7N6y&Z5oj9Z6&wdbT8*DUKBUXZcq zxjlzp-g4>Yrk59l7TIl_MRw^cO|utfEIYkrY>~a&Nk_x>Tzq-@-k|egZQ+^^YYP^< z_LX&8O~vpEyU=PK+v5fs)hw;EMlPvCSN*ARy^|A#Y(usS?ZYSsYnIeGWlQUv!hA@Z za}c!Gxu(`Cw5qJVcKU6*5#YD#lzt1#kEj{3t18RdGw5==Dr0XT5ZHZv=54#vgD35} zKFeyIUl-`qs4kG1U*}%hsLq|Z=#e>(^xc)#w`^CatWCX@lV9gxxr604mfOEs9_Y5Z zUvO_A`2My%n4`!xcpx5x_wZfdpf`nr>LWgg#Z-~8HZE20(F!sZpRxV|Z(|Z(eQxU0MA* z)Vq1HI;VLIEpCi8UGqqvU1@#V)Z0Tl)Z2ZzE^86jHegpK%GxMvcjB7!1O0b7#~xB| zm)gq%B}@B;_69;vZOg2-R*Zi%ZKb>PraG%+K^-QP?A#JHXY1(q-F zJNt*B52aUymgOyX(CX0Q+^X>Ml?B<$^ROk{#pl)JROK$i*xb=(j~j9JxZ#YdjPl4{ z{AO-(UJGY;Bt5cte#L9Gfi*U^%ufZSEv!Ti#uNH}U{0O89{oRj(IczT%Nc#kcLmGa z)CaoeU_7CBvE0UT`!~x2rBC#=_6Dr?w}o~`oOOGx?08M%x`*@lcgyd&ixWGBWwyrEUsqE*iFXZG4zk-c`Ls{F2Pjn+K<<(?a=S_Uf8%fl5J z%fbs=F3VVQZ9$WYllJ`D)ma=`GR)}fEqc>UUG&B}_)Du(QATJibL@XFjpHD9m}Pj9<@XG6ai zE@0pH-FZHaeuFCJe7*|T9NzgNVBd&CaOQpJfBrz17pbWqhi|>P9pl}hbnVcb5D|VI zmX6CMM--gIB~I{GN>18x7&xP-I-%ekA`oOK3FkwUa8GJ-sZpiPp%f1CjX*b?#urlq zfgmQefO%RuOq|#8Cy<}pk@*-G7v>$q{9Py*=#+=6Cd+w=HYNEyH@e}#`CQ9P{0X*c z@(EPIz?b+NdJY9_hd&7pb;@FeoSUhhV)ALLur%!~JI=2T;Xvq4m+!_#{)}pc?#4V- z$k)PS=$<_4t@NJw(+{}}+PhX}ICOht66EL?kVAK*;UsA}2`l;$x;Aug(EQ*%5wM&? z=;S_^MV%Ar{Gn!V!!#=p3|t2tIl3=UIoHYzA6~*lJAL`(KF#V+@+Z(#&Sl?u)>phKq&s;IVD^h%nz$jb4dA;Ugn{`+h*Z!beFAMA??`(GtVaHf%vpiJ8#} ztjnJy#-h2bX)lTS(Z^V}x5R>IHCI$7v3axy%l462Xysb5%>HR_0Y(&WGf!QH{efrdJgkk(Rwbs&|eWean!|zqOKFde+wtj$eaZ-A~X6kSM{XCteg>}&$hx(F=tyq# z_f>Xa^m24lczgOcroDrr-?5S(<@SY}n?343EL7QYrN4gbXnn->5R`SDL# z(Mi7ll6WQM$xh=RaCPq_y2by>^;P=Id&Hycg(*&Yh%dS&ddB%BC47OSLrGcu5c;3) z+n2|`;QBB0m-mlvqQ4nVex@luFkZoKyu`O36n~lWrB1~BFd#7`-iLCvllFwE&#*Z6 ztMKhk9(N@-vB`<|qr=rsF82{PvBimZqT+5RvnAHxCO!zpPhgWCaAJJ7)lKXO#&^=k zLrywhPIMDrBbHu(yMniocEUPkBN~J+K;^tV=&d#BLeLTL5 zJ=EUT2noc`Wcv@XHA2EzBO4wJ(0u{#6J>>a+hM+d8_&d_aG9NJ-o}NiH(0cfFNfkq zSaGwl_}u$Jw{xtDR2Q8h?Z0hl1gGPSg9K$Nmzy_uJz^0cnjM9)t6_)Pv!dNJFye7ejd@|J!o*96FbW&=GpNtX>q+* z12?hCj$cNL8$1_oVznJVoaS2)cmu+I-?pWWgV z++*Y!RyvRB6pX7DRysEhcO=P8_k?FT?nh8G<54Gkqm#jn+w4g8#7ZZFYxUOujbEt1 z3blZV9Sl&_+~#4xjBX6Deb590yryVwbLaE-g|^5C1G)H{&N0YWflUP*tHsak;$k<> zBcE-z;OsHs&TfnTMsx!K9(!>;#v@_Np7;~AdF>dv+zD}lkyg!NH@k2LT4@y`S$5%6 zbP4?OXB(00oW$9%vh6g!WuG2#a(SZ7z7@K(9mu6;IeGViY3IOAdY+T_ID}w;%Y%Uj z@wc^oJsQI~RN)ozGhxP$JpvcJZH~bzupss(42M8lfz;-HRK-rSb6A3Ne%PJ{9+q&82n-RXAhHTaBT)%^8QVlz8us?Hl~UuHnbAN)Ys@&&Z(MJS&~N?hbAi>Uk& z3ceNF_Ai!Q;1wQ=n{B5fwLO=rM#c&v=gLUzW?KsE0;9wg(K|?qMeLsfyA_o$;uh2c zNQwEZcoWa#m>fLPL~47^WP~4RYUgm1@;CdJA|)QB&lX;5_=Eh1s9fhM8?lM}HT*G1 ziKjhfGb-C*YxC#ji4C5zHI*+xv6jlcRJQbdUX<_spgK|ODdV)fp)uZCM?#fKExVPS z{V0@t{h%`vlwGLIr}DI>SQ%2=86}ooXlHRCp3oe>;Y4aX1BDCiTQSiB6Wy(uT9b;trN8lJSh(X(9x zy9blDQd;f!gSZ7q^ON>VJ^L47`$E!QO6!oj;d@=ucDZN!KJ4C2+DZxEt`}$g%cT7t z&;DE3@=2;!Zz-*I{3gV!zygj%(?4<7v@?La-+a>Q*-L4)I}5gBkp?C0FLzCUHi2y% z$?H!kOQ7h4WOd;2h2LecTjFCcv!k3|q$A()8v=vDNFDhC;5o>Qr@+|?ZbW7=QW47> zdLuN?L*nyQd3+0*hQe6=9%So#+uGfpz1L zGrhn3d8XaWiSf1DV%E=iIi?VU7Rh)ShRmr*rb?G0b1{Hz#9lhU+jf|~hh)6%LFOAIQ=?#OoMDi> zmc4}1*tzj{Gm?Fz6U)LeqM>EYVOfA={G5W!$wtXdIlJT((nb#@M#}~+a zhE&8d+GfVnE}Nc4($i=sw#)a#=eu=C#uFdzW+53*?T|?z6|qdJr+x4gux8NHWNdjH zE={}o!S)yy=Exk5%rFY9(_&;6A{DVrswaNCPP3k)r&pZpS@6`*(~qOT-+T|BBJ(jl z(AIQ!b^>QeB#orD@D#D$g=oL+Wb-9lQ>V7DXoF?i*H1<5|$jTXS%cv}ej8<32*JCRvUf!^LgrUuDW?H6SBBUzofuh2`xglV-WxKZOL zuPwfIBN;y(kZDhWeuf}37^!GaL#?cm`M7# z(@vn!z7U(qsY%PEfQIDQ?XvPR+^l9>+Zh?27aL}nnJd+4x@`~0qdudxH6V}EvSsES zV2>HR8ti-Ebd<#v;ySH8>~XUq&vvs?{pY|w>{puhxyB;cPy@^fatNxK-^e~B(_43= zpz+l>X^E<{PI0ZLR^ytWCZcy&UL_r)emq^?Q2 zw$QPM%-W@Emw^$GYqN6gQ;Xo~b%s4OM16-Ac4^*VdtKk)(9p1q(}I6CUDPpXmFCGw z5lu15yEUjfF^_{@vMkrqP`a3t`ZP>c@oYRS!1h{l(qfys)SVap>8#;G;a z5bI{XEja@VTx({n$y^G73rJq2n+0<4JHX+=LPS5}|6=b<;H#?6cE9)8XUa$*fgqE| zBtVz~35cLUrf@_=MnP0G1PBC#5R)(#62zfmwE{r}f*!0|$0}{9wOTFCBMR1`RcWcU zRm4{K92y&2@AItv>~jtX9q#wt-|zeGy&G2k>wVWe?6rrp_kMB8gxDMJZls6F{nn@U zq!@iy!XXxM4V;NZ&vv6fk6>AD0;EoC0jSM}QwU@+nTWs{OWDkNt;u3CvDtX15^lzm z5%IViPA-udA9(j_z3Zr2PcgM_F!@a(cw&rN?`ovStLl{4QJMP@^o@-Vk-%Ir!P**g z(D}B>-mUpmg0G;XafDm*NyPWyyae?B9S(UByjt^u=#Ri5i0F|NL_cerWH8yQA!`FW z)23F8Lch16vXGgK#L=Ih%7S$CF#pKGc>`Pu$2_>PESMLg$j=9$JT~j7USo^Qz=u&9 z>zrf=l7-RX0+WBSvCyPZVr@C+3@|Lj+`((7MTmA%WE2^*rsBXA}qJzp99WR7;K z>GP=s2i`xRHU*4A}643JJiX6jH>)eO?NSDG(1C zD5XMtP~mr82f1*RCNYk69x)5ffvMyeJvFZ2i_uf>3QlYnJamY*#t5&wLPLxm35`bh z0t#eI@NqMwSRI=MPYs-FL%yU-j6y;Iqw*A1z@ekIG}1$>#E!LWbu0(%%!A8-$$QwT zFDalI`n(ubXTr5PN{w}f%30qG@WrU)wdOG?95b&tJKWkK3krU8qHRql=&<;%jwK0e zj8Nc)G{oqU&}f7x6xip8DQ=|IF?wbg{S;!M(bw8BdiZOMW7Ya%^jzr*PK+L2W`?b0 z)=HdZ&lYX*OR?f?fbF$)f}6URe%+}T;PI+i4?F#@mr(C&s9JrWv?kdEe{sRZXV zBCU>fg6DKNOuaiAgP3|0_!S^2d@%}~wNg0A>)5Ww#5`J+Jdakn^N3T&fyLt(r;66N zU5$yMosk$?bV_1q(J6_cMW=iZ9jk?IS0g=iwlys=&P$WWd1>-EFLh$x(a-c=(#p51 zF|qQ^K%XZzjyyMy@E$X&91Wh>k!&4yf?YTwkHyOHkM|3<B3{s_77mvx`d(D?)Nzftu)MCd(9pQx95Vmh1Hnr%dOqAoO!;eQcsk@y3B_ zZ^F=zUWjjq`Hig*n!#{5XcO#W9LvXY59hgQ(5l08lU-u;&w|4+j}1bBosc3Mgp-f4 zK^%3c^X840%$o{H$v7hl;ZPvKS-}Fy5;!j<{cJ}F6=3G^MtKoXL9?M2cn;A$i$+Fe z?5nXzNWU9{ezV2fe@vs<3f6(FMkJi?5d1EbV>Q?@ulu2A1Kqj3aqKZIQK4hKLJ<=i zvW%az1~ED6(3v^Vb$~+`5WFn%f_NHx;>#7b6{)z>=tPGFK*A%8*tqO7gqv9uj*f4F zOjmG}C%^?T-3NAx(R-oEc^YvEoMU0Jngvfa92PNx=Q;svsa0HLPJ4JX@L9z%()ACB zakt!VqOGz@y2t4K5gbn-fnA9Zp2_g2fNK?=ubA@}F7rl4mFOP=2gBaPbU4Ra-Wa1t z3;n~5L7XE|NGJw&iFrG_m-7^i01p6O&h&Fv#{rArK8#~pV~if|rVtup^hj6})h;>!BgPO^n%+`4EIGsoIGiT9$Bap?p5Rd@^ExQu?#UyfzY4J>A2b^QAZcIAOn#se-zquQ+VJs<(nzJ$710x_?Lw%xE zoRnsBYw!N`bfkCjgfTATY~mHvbU5r_#4I@Eejd+Q`H?;o4dX>WpPfJ#5^N@pzMC7p zRSap$c=Wp;4p|Xyr8kzbqTK(XCbWu`k*qh=Ui}=i`*(pD;+PlUG~NpeBchGkxJ!W9 zmr#UzIaM60oP|s?1P#8}EH``+i#`frD!WlLJt}U*LlhW3sg;cY?D41Ae zV!3T`5A)p^i)yz;=XovSnu;~lYt>P$c?9+T!ZhJRVt~p2LSm4~|EOB5QZ1&KAh%F; zCWEME@i+-5YD_FQe3?5?j77Cu!T64Vhh|S$L7q;BO{P-`)(Q&}!IiWvjzH`tw=Uf- zQ!TizdO<3hK~%GNWZ>1pi?!UXAY-v|ZUy5v)*N$x4o_jDOSxPGU{Donl97GpFAoN< z!*#@^uRETpUw_@HevRuNQE*E9IvFtnelo&NXGTK_BU17A3L-VB3;(-su<-T-EjG8y$+Tj8`QMwy; z0D4aLKWU zG^wpiliJET^A%i2YiUv~mL|28p}Z_bjHFsDO=>G=1xKzUt}YWjT9Z@?L(?%Dh>=uE zO;RZg?dHZvDy1f=l*G85s1%Odc+=-6Dutml-54h*B{6O%Duv@#U`FLcr7+YTx0(}_ zf-W_i?e{y588wU-Z#rNZg2r*UTE@e8^5Mqfc+#cB_wxAVT8iZjas2ieVyU-{iUWyQ zp2{0ns8q}NjfIeQZ=>M;o)RBfv!nA66vB?hT`ER_`*;XP45Q%g%>hq|@5nKV+=r2m zSG>1NC&lvisRG_yfXZt>2cIq} zdv87@WzPvfmz2FXCz7)FCP7m6X2|geE4JSs;-eD5loVcR_^?q&Us5Oz6x5lRNh7cQ zDtY8R758R3jJ)=(U)`UBDf>3fu_L0P8vdQ?Bheokw5Wd z@M`2uhIq2XR8W1q^*lbyI1T793SI>%a-fsyOwm<&%eT2@p{d{%pEMP`4&f@nv+xkE z(9En(nj2nuNpr(fCCv>l^Q5`qsgmY~R~`n<-FPG2Tyok0Ue!GUhYJycee1K9ts&iu zxl6o@Ioq1aa|`#ZVM^izf;S+|X7eP0(+m@h*}e#eL0U;-aM+9+kUXg|8k*@u@e!Bca-a|%n^WN=@_LESrbkT(2e4go8>-Kwh*mLipjR}3Y~Z50yvLGE9spJmlP{x z+R8-@XU$$6LpD2rN}QD>opU6g*&HwKiO!9^xR%X4k0~t0C_Y0#QVmi}Oe#-&=H%s? z9M?M{^GwxSqj^^9#kK5PF_v6vllmZ`{N{;wA|VsG3FFt2LEBrjlX6Qak3LyXC)3f;09%Z(Yo!a_E7{24WCD)$XKoDXW{98r*bzLne`iDZfU z^|qHmQnQjCUQ1j|TlTvs<^WvM*d;6D)ehQ>^^u7gZ*{UVKKYWB@hSyP(l1Q%c&mdp z^K+F+$vx%KS1evn`)w|uy5x*2(SU?{GDGRme>$e1|8%aynU(0jL~h@_67n(+;hfVw zOrH1*{&;aubp7PTwQTS3n>0)*=6GCo^rDesVp4hHD+DjsiXC1vZqYjdwD=Z5KRr zd*NR9l=4$P4EI@*o{PsFaCgITJ@7W}DZB;sAsi>Ox6x0>n^Bzg-o}|r=hw9L^bL^L z!mWejk;vP4MA{5@6C95_-o|N47lA8)^EUeFM!=ON>Amsjgzn%FByY+6!cT)E8A|fm zt(h6-{0nhWW4oxRKmJc$vb1(iW&h}cMfH`n3##WwmsZcIU$CSaUxqQ^_&a(@ZDs$n ztLH3QI=9lAbNbBsB}*37&741HPCtB(reF1v>dJnV6|)!g8``gAK=IIimksK-xMJaw z+L=d%&csUq%wXo?iaAyMtjvEpqq>!K|4t^07R+XykEzwrqLQLwuWtWNcE@d;`poOA zV~v8JRy2n_KWA~>g1U0lrKpMnQ$DwHUd7Ty_2u;|YbxuY!+4d~)z8IS(-1JW_;Sys zt}h-1TEsv?=&={nR^p>PZj{9p^;PiUb_r@&E{PXp0ld3vCY*Dv&ki`b*@2X7yiDV) zgb*ytrpT>59PYqn*@0lt4%p5`kwDPtUK9ufi`%#F*glX7ZK!J?H9r!GAfajofJs1gQZ2tXyv>>N>8UY;R*b=tsGax z-u}QE$DX~csC|2O562-89B8U+`gxrlZfB}}dE*R@7{_ElzkaApe+cP8XN5hkvRfcz z`TQ8)HprR2_WY9*_Zcz!XkC&RF#cehzyL-m3Y_dBi*WGL05FKXMNiOqD6NQ3P$_>? zNPiQ;J~E{TotN-p6=Ecn;iY%(#ULgnM;cR3(0R2!!VYIT=Z9%UCd+SR{CaZ6Zhg^X zZmGqpVH-C`=B6s&@h?<)f4v<@ciZ9RcT5wG&b}y-{g!_r`-5)9-7!&zJD5M}a#ONX zUvz?^|6xs%8hZJ^P?NPwPdGN8ryeynrZzCT`0s1u69iUU(9!re;`V;5= z@zJ>>O{q!EjNKt)pSlyk%l{h_U=!m0<6-i~#X0be@-!W`A`eq^QDUaJ#eSe>C5mn1 zR`C`jarZIPd8YBD!GfGX24>%I?1y$`jI=mSfzJ~_*6ERiW#ETPUc>SI~V9Xi8V zfF$`!>E$rue=~+IDH6P0)@6ati`&x?q{f z%b~J}N=T;|X`GRA^8;j1#zukW~Z zi0hnxE0$;UVHyq>SjB@*n!7r;=O{W?aRklkoE>yNS&G$p09NOdu{vjIb-pguTb+^i z%cbt>>?Ur(avD$k)$tO4osyLJ>SZ>DVzybGQL(&IR@NO|9BYdD6r*;^5g^6AKg&waX89dzx+5yxj%=!u0Y0HFmug;3Wsr2 zD8DG_z@5(n_gVRD2jZYJLMPB5#sW7+fL-y;<2L%yc^n7ru=5OlDNpT#qIBHeg|0z= z+>Tk;*7@_QQgixHA8F6lq6Ky!HG&Bq!Ay6SpqO2jb}o}JJ6AB-ULYCF)zX~#*P zXLi?6Fy9?aOdA}{Q=EZ3Av((&(Flq52W>kXJrI; z%Wb>7eBNA~wk|GTv81N5+A3dCU0%6jL4A2e?fg2ceEFREC5va{OtGTA(kibVG{mZ_ zoil1YBi1dLUtO`NeD>0L*3xPUm2)Hf2oFB7F|TgHDny^RsDgRmo00VcOUe;aSzBAZ z#42Ar+sm)AVlKtnMU~ZF893!!vJ`RW)hwxFnt8ZND4(-r$)yXB`V70S;j@#;C$&hjm%;sYaf&WGN~)Z_$zpg)UxzMl4udv$VFdyawN$ zEU(7LFXvgvpm;D-;7gTr(Owmxg7Dp(MN6vZN6eq2n_W?dYnsKCrbEih>!N3mAA|mz zTW8grjrV}@rv$ZfwO*H_i3?Vs%jeCjt3-*Fiz{pAS60tiX`MA;T4Z$bX%Tbf5aAV1 z@qm(3BZc^mW@SZPWv|FZ_!MS;ULFkXHyah5Qx(CNI2Y96nkrIq8a|*m^x{ar#dB(w z4x6*279aKOw|Efb`l_XiXM^*gpI5VNP`|pGeshZlQ^RiQhwH0hRTZ^!p{S^xQ#B0v zFFUQW-{L;=Y9jsS&s|Tpp9eFIhgP&YMo<%PJNv#muQW6&G@53M{CuSz2F=aRx9Xh>H}Ml3t3% zvlFv%4!Xmw!eUbeO!IO!(o9;G<0ZoGft_Xm=R7W?%!FG$rwY|wGP};2P2E)N62%E` zNy3ZD&snsj4wWpgo4Wv)WDC$C=Gx3EpI@7)3$Vao#~rTI?jO=w-YTHiel^DzBU8u35Mi z<_B-f(G^v*(Zh?D%*Ha7yby3QuBi7Mpodzu4q-DQYlf%v86AN3A4CFq-RVwV6E2 zQG2ArUv~|iTeqaV3QH4uucnNn&1xYtRN$zkSW`E?FqY4+tVhEuIXu?r(`Qbr!^qBD zxTLzGx_&_M%=ruIXO2F1>e*AvPjxx7Z0e+$lWLbN#I9U7^Q_UMF(7l%+VVOUgKpzq z<;|`5EGe&Z1NepEC6|^jsxb3$cJi)bdJ$>oRhvVMjvT7))N{v=EaR%q4*gNuQS;Vb!WKmN&XTiJ$m2=%eti+5 zNo{0g?c&Io#j`7M3uSHuJvpbcu5L+fUF4WsSiSx;t303E!S@`n;rd{8CXC7Pp?h!R zO}bH;1y`nA6}~$3?cgsuZ7nQU*_>DPvbIccs6B-APgePzK@LsZr@-mN+vyPG59V53r zM$W;PWzF4A^Vn-U-c38sN>ot)4Xt_D(uYTnSR>jjXU=4M@gx#ASG$vl)LZ%?;&8D{ zI=uBu^AC z5v#>j;s$Y>_F@(agBJrc#HT0@iB3axL^E}_%|^FcZ^w1SFxWsOgvY- zSX?YNh&PBk#2E5)Va zRpO1}o#I2{bE2^wjB*Z2{;QaVFEFwEE@D4%rD$vhBm8N}`$S{I7y2`>)G_@y(b(99 zJX`X7ah14Myjr|YY!bgG?h>C6jZIwSd#p{|j~R|SeW7?48DZ;4nh{aVRaitDAnQSw&t9`OgFv3ZO9 zpO9>9-=h52B)=(sAR1e@h<}(e;u#yakh##aKX50}=-WzeFLsjN*tSJHW7`%Ss_Oq`wNvsg(b%?y-q^MUUsAe#;v3>2#W%KX5wAt^S7HDsxNNtvX$xjkMtx2a zyNX4MS0bJv4j0FY4WhAmi*$EVMn3nEkbkc5-Qo-4 z9`Q}_ZSl7x(tScApU))+aS6e8r;6EPt{4#u#9k!w8A>9b;gY8*`~q>dI8QV-Z;`HE zvaxxKa<8C_eAbf)-=^?e#k<7 iXU;$tMz?IDrRFU7aS4@s2svG}?8rRd9c!|_2W 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
  1. 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

    BEjg&S2~~47akN_hqng#~~}k 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 }X>$J-Wv#Ih}YrchCsW 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%0DH&*Tw9nEn+9*cGKQxvrW5c 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
    + * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |---------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP\\DSP_Lib_TestSuite | DSP_Lib test suite | + * |\b CMSIS\\DSP\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP\\Include | DSP_Lib include files | + * |\b CMSIS\\DSP\\Lib | DSP_Lib binaries | + * |\b CMSIS\\DSP\\Projects | Projects to rebuild DSP_Lib binaries | + * |\b CMSIS\\DSP\\Source | DSP_Lib source files | + * + *
    + * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
    + *     typedef struct
    + *     {
    + *       uint16_t numRows;     // number of rows of the matrix.
    + *       uint16_t numCols;     // number of columns of the matrix.
    + *       float32_t *pData;     // points to the data of the matrix.
    + *     } arm_matrix_instance_f32;
    + * 
    + * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
    + *     pData[i*numCols + j]
    + * 
    + * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to \ref arm_mat_init_f32(), \ref arm_mat_init_q31() and \ref arm_mat_init_q15() + * for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
    + * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
    + * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
    + * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
    + * 
    + * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
    + *     ARM_MATH_SIZE_MISMATCH
    + * 
    + * Otherwise the functions return + *
    + *     ARM_MATH_SUCCESS
    + * 
    + * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
    + *     ARM_MATH_MATRIX_CHECK
    + * 
    + * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ + +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ + +/** + * @defgroup groupSVM SVM Functions + * This set of functions is implementing SVM classification on 2 classes. + * The training must be done from scikit-learn. The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/SVM.py + * + * If more than 2 classes are needed, the functions in this folder + * will have to be used, as building blocks, to do multi-class classification. + * + * No multi-class classification is provided in this SVM folder. + * + */ + + +/** + * @defgroup groupBayes Bayesian estimators + * + * Implement the naive gaussian Bayes estimator. + * The training must be done from scikit-learn. + * + * The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/Bayes.py + */ + +/** + * @defgroup groupDistance Distance functions + * + * Distance functions for use with clustering algorithms. + * There are distance functions for float vectors and boolean vectors. + * + */ + + +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" + #pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + + +/* Included for instrinsics definitions */ +#if defined (_MSC_VER ) +#include +#define __STATIC_FORCEINLINE static __forceinline +#define __STATIC_INLINE static __inline +#define __ALIGNED(x) __declspec(align(x)) + +#elif defined (__GNUC_PYTHON__) +#include +#define __ALIGNED(x) __attribute__((aligned(x))) +#define __STATIC_FORCEINLINE static __attribute__((inline)) +#define __STATIC_INLINE static __attribute__((inline)) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wattributes" + +#else +#include "cmsis_compiler.h" +#endif + + + +#include +#include +#include +#include + + +#define F64_MAX ((float64_t)DBL_MAX) +#define F32_MAX ((float32_t)FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_MAX ((float16_t)FLT_MAX) +#endif + +#define F64_MIN (-DBL_MAX) +#define F32_MIN (-FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_MIN (-(float16_t)FLT_MAX) +#endif + +#define F64_ABSMAX ((float64_t)DBL_MAX) +#define F32_ABSMAX ((float32_t)FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_ABSMAX ((float16_t)FLT_MAX) +#endif + +#define F64_ABSMIN ((float64_t)0.0) +#define F32_ABSMIN ((float32_t)0.0) + +#if defined(ARM_MATH_FLOAT16) +#define F16_ABSMIN ((float16_t)0.0) +#endif + +#define Q31_MAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_MAX ((q15_t)(0x7FFF)) +#define Q7_MAX ((q7_t)(0x7F)) +#define Q31_MIN ((q31_t)(0x80000000L)) +#define Q15_MIN ((q15_t)(0x8000)) +#define Q7_MIN ((q7_t)(0x80)) + +#define Q31_ABSMAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_ABSMAX ((q15_t)(0x7FFF)) +#define Q7_ABSMAX ((q7_t)(0x7F)) +#define Q31_ABSMIN ((q31_t)0) +#define Q15_ABSMIN ((q15_t)0) +#define Q7_ABSMIN ((q7_t)0) + +/* evaluate ARM DSP feature */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + #define ARM_MATH_DSP 1 +#endif + +#if defined(ARM_MATH_NEON) +#include +#endif + +#if defined (ARM_MATH_HELIUM) + #define ARM_MATH_MVEF + #define ARM_MATH_FLOAT16 +#endif + +#if defined (ARM_MATH_MVEF) + #define ARM_MATH_MVEI + #define ARM_MATH_FLOAT16 +#endif + +#if defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) +#include +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 ((q31_t)(0x100)) +#define DELTA_Q15 ((q15_t)0x5) +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macros for complex numbers + */ + + /* Dimension C vector space */ + #define CMPLX_DIM 2 + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief vector types + */ +#if defined(ARM_MATH_NEON) || defined (ARM_MATH_MVEI) + /** + * @brief 64-bit fractional 128-bit vector data type in 1.63 format + */ + typedef int64x2_t q63x2_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 1.31 format. + */ + typedef int32x4_t q31x4_t; + + /** + * @brief 16-bit fractional 128-bit vector data type with 16-bit alignement in 1.15 format. + */ + typedef __ALIGNED(2) int16x8_t q15x8_t; + + /** + * @brief 8-bit fractional 128-bit vector data type with 8-bit alignement in 1.7 format. + */ + typedef __ALIGNED(1) int8x16_t q7x16_t; + + /** + * @brief 32-bit fractional 128-bit vector pair data type in 1.31 format. + */ + typedef int32x4x2_t q31x4x2_t; + + /** + * @brief 32-bit fractional 128-bit vector quadruplet data type in 1.31 format. + */ + typedef int32x4x4_t q31x4x4_t; + + /** + * @brief 16-bit fractional 128-bit vector pair data type in 1.15 format. + */ + typedef int16x8x2_t q15x8x2_t; + + /** + * @brief 16-bit fractional 128-bit vector quadruplet data type in 1.15 format. + */ + typedef int16x8x4_t q15x8x4_t; + + /** + * @brief 8-bit fractional 128-bit vector pair data type in 1.7 format. + */ + typedef int8x16x2_t q7x16x2_t; + + /** + * @brief 8-bit fractional 128-bit vector quadruplet data type in 1.7 format. + */ + typedef int8x16x4_t q7x16x4_t; + + /** + * @brief 32-bit fractional data type in 9.23 format. + */ + typedef int32_t q23_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 9.23 format. + */ + typedef int32x4_t q23x4_t; + + /** + * @brief 64-bit status 128-bit vector data type. + */ + typedef int64x2_t status64x2_t; + + /** + * @brief 32-bit status 128-bit vector data type. + */ + typedef int32x4_t status32x4_t; + + /** + * @brief 16-bit status 128-bit vector data type. + */ + typedef int16x8_t status16x8_t; + + /** + * @brief 8-bit status 128-bit vector data type. + */ + typedef int8x16_t status8x16_t; + + +#endif + +#if defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF) /* floating point vector*/ + /** + * @brief 32-bit floating-point 128-bit vector type + */ + typedef float32x4_t f32x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector data type + */ + typedef __ALIGNED(2) float16x8_t f16x8_t; +#endif + + /** + * @brief 32-bit floating-point 128-bit vector pair data type + */ + typedef float32x4x2_t f32x4x2_t; + + /** + * @brief 32-bit floating-point 128-bit vector quadruplet data type + */ + typedef float32x4x4_t f32x4x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector pair data type + */ + typedef float16x8x2_t f16x8x2_t; + + /** + * @brief 16-bit floating-point 128-bit vector quadruplet data type + */ + typedef float16x8x4_t f16x8x4_t; +#endif + + /** + * @brief 32-bit ubiquitous 128-bit vector data type + */ + typedef union _any32x4_t + { + float32x4_t f; + int32x4_t i; + } any32x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit ubiquitous 128-bit vector data type + */ + typedef union _any16x8_t + { + float16x8_t f; + int16x8_t i; + } any16x8_t; +#endif + +#endif + +#if defined(ARM_MATH_NEON) + /** + * @brief 32-bit fractional 64-bit vector data type in 1.31 format. + */ + typedef int32x2_t q31x2_t; + + /** + * @brief 16-bit fractional 64-bit vector data type in 1.15 format. + */ + typedef __ALIGNED(2) int16x4_t q15x4_t; + + /** + * @brief 8-bit fractional 64-bit vector data type in 1.7 format. + */ + typedef __ALIGNED(1) int8x8_t q7x8_t; + + /** + * @brief 32-bit float 64-bit vector data type. + */ + typedef float32x2_t f32x2_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit float 64-bit vector data type. + */ + typedef __ALIGNED(2) float16x4_t f16x4_t; +#endif + + /** + * @brief 32-bit floating-point 128-bit vector triplet data type + */ + typedef float32x4x3_t f32x4x3_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector triplet data type + */ + typedef float16x8x3_t f16x8x3_t; +#endif + + /** + * @brief 32-bit fractional 128-bit vector triplet data type in 1.31 format + */ + typedef int32x4x3_t q31x4x3_t; + + /** + * @brief 16-bit fractional 128-bit vector triplet data type in 1.15 format + */ + typedef int16x8x3_t q15x8x3_t; + + /** + * @brief 8-bit fractional 128-bit vector triplet data type in 1.7 format + */ + typedef int8x16x3_t q7x16x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector pair data type + */ + typedef float32x2x2_t f32x2x2_t; + + /** + * @brief 32-bit floating-point 64-bit vector triplet data type + */ + typedef float32x2x3_t f32x2x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector quadruplet data type + */ + typedef float32x2x4_t f32x2x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 64-bit vector pair data type + */ + typedef float16x4x2_t f16x4x2_t; + + /** + * @brief 16-bit floating-point 64-bit vector triplet data type + */ + typedef float16x4x3_t f16x4x3_t; + + /** + * @brief 16-bit floating-point 64-bit vector quadruplet data type + */ + typedef float16x4x4_t f16x4x4_t; +#endif + + /** + * @brief 32-bit fractional 64-bit vector pair data type in 1.31 format + */ + typedef int32x2x2_t q31x2x2_t; + + /** + * @brief 32-bit fractional 64-bit vector triplet data type in 1.31 format + */ + typedef int32x2x3_t q31x2x3_t; + + /** + * @brief 32-bit fractional 64-bit vector quadruplet data type in 1.31 format + */ + typedef int32x4x3_t q31x2x4_t; + + /** + * @brief 16-bit fractional 64-bit vector pair data type in 1.15 format + */ + typedef int16x4x2_t q15x4x2_t; + + /** + * @brief 16-bit fractional 64-bit vector triplet data type in 1.15 format + */ + typedef int16x4x2_t q15x4x3_t; + + /** + * @brief 16-bit fractional 64-bit vector quadruplet data type in 1.15 format + */ + typedef int16x4x3_t q15x4x4_t; + + /** + * @brief 8-bit fractional 64-bit vector pair data type in 1.7 format + */ + typedef int8x8x2_t q7x8x2_t; + + /** + * @brief 8-bit fractional 64-bit vector triplet data type in 1.7 format + */ + typedef int8x8x3_t q7x8x3_t; + + /** + * @brief 8-bit fractional 64-bit vector quadruplet data type in 1.7 format + */ + typedef int8x8x4_t q7x8x4_t; + + /** + * @brief 32-bit ubiquitous 64-bit vector data type + */ + typedef union _any32x2_t + { + float32x2_t f; + int32x2_t i; + } any32x2_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit ubiquitous 64-bit vector data type + */ + typedef union _any16x4_t + { + float16x4_t f; + int16x4_t i; + } any16x4_t; +#endif + + /** + * @brief 32-bit status 64-bit vector data type. + */ + typedef int32x4_t status32x2_t; + + /** + * @brief 16-bit status 64-bit vector data type. + */ + typedef int16x8_t status16x4_t; + + /** + * @brief 8-bit status 64-bit vector data type. + */ + typedef int8x16_t status8x8_t; + +#endif + + + +/** + @brief definition to read/write two 16 bit values. + @deprecated + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __un(aligned) int32_t +#elif defined(_MSC_VER ) + #define __SIMD32_TYPE int32_t +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr)) +#define __SIMD64(addr) (*( int64_t **) & (addr)) + +#define STEP(x) (x) <= 0 ? 0 : 1 +#define SQ(x) ((x) * (x)) + +/* SIMD replacement */ + + +/** + @brief Read 2 Q15 from Q15 pointer. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2 ( + q15_t * pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, pQ15, 4); +#else + val = (pQ15[1] << 16) | (pQ15[0] & 0x0FFFF) ; +#endif + + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_ia ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 += 2; + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_da ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 -= 2; + return (val); +} + +/** + @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2_ia ( + q15_t ** pQ15, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ15, &val, 4); +#else + (*pQ15)[0] = (val & 0x0FFFF); + (*pQ15)[1] = (val >> 16) & 0x0FFFF; +#endif + + *pQ15 += 2; +} + +/** + @brief Write 2 Q15 to Q15 pointer. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2 ( + q15_t * pQ15, + q31_t value) +{ + q31_t val = value; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (pQ15, &val, 4); +#else + pQ15[0] = val & 0x0FFFF; + pQ15[1] = val >> 16; +#endif +} + + +/** + @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_ia ( + q7_t ** pQ7) +{ + q31_t val; + + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val =(((*pQ7)[3] & 0x0FF) << 24) | (((*pQ7)[2] & 0x0FF) << 16) | (((*pQ7)[1] & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + + *pQ7 += 4; + + return (val); +} + +/** + @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_da ( + q7_t ** pQ7) +{ + q31_t val; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val = ((((*pQ7)[3]) & 0x0FF) << 24) | ((((*pQ7)[2]) & 0x0FF) << 16) | ((((*pQ7)[1]) & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + *pQ7 -= 4; + + return (val); +} + +/** + @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q7x4_ia ( + q7_t ** pQ7, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ7, &val, 4); +#else + (*pQ7)[0] = val & 0x0FF; + (*pQ7)[1] = (val >> 8) & 0x0FF; + (*pQ7)[2] = (val >> 16) & 0x0FF; + (*pQ7)[3] = (val >> 24) & 0x0FF; + +#endif + *pQ7 += 4; +} + +/* + +Normally those kind of definitions are in a compiler file +in Core or Core_A. + +But for MSVC compiler it is a bit special. The goal is very specific +to CMSIS-DSP and only to allow the use of this library from other +systems like Python or Matlab. + +MSVC is not going to be used to cross-compile to ARM. So, having a MSVC +compiler file in Core or Core_A would not make sense. + +*/ +#if defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#ifndef ARM_MATH_DSP + /** + * @brief definition to pack two 16 bit values. + */ + #define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) + #define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) +#endif + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_FORCEINLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_FORCEINLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + __STATIC_FORCEINLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y) ) ); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + const q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + const q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + +/** + * @brief Integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32_t arm_exponent_f32(float32_t x, int32_t nb) +{ + float32_t r = x; + nb --; + while(nb > 0) + { + r = r * x; + nb--; + } + return(r); +} + +/** + * @brief 64-bit to 32-bit unsigned normalization + * @param[in] in is input unsigned long long value + * @param[out] normalized is the 32-bit normalized value + * @param[out] norm is norm scale + */ +__STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm) +{ + int32_t n1; + int32_t hi = (int32_t) (in >> 32); + int32_t lo = (int32_t) ((in << 32) >> 32); + + n1 = __CLZ(hi) - 32; + if (!n1) + { + /* + * input fits in 32-bit + */ + n1 = __CLZ(lo); + if (!n1) + { + /* + * MSB set, need to scale down by 1 + */ + *norm = -1; + *normalized = (((uint32_t) lo) >> 1); + } else + { + if (n1 == 32) + { + /* + * input is zero + */ + *norm = 0; + *normalized = 0; + } else + { + /* + * 32-bit normalization + */ + *norm = n1 - 1; + *normalized = lo << *norm; + } + } + } else + { + /* + * input fits in 64-bit + */ + n1 = 1 - n1; + *norm = -n1; + /* + * 64 bit normalization + */ + *normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1)); + } +} + +__STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den) +{ + q31_t result; + uint64_t absNum; + int32_t normalized; + int32_t norm; + + /* + * if sum fits in 32bits + * avoid costly 64-bit division + */ + absNum = num > 0 ? num : -num; + arm_norm_64_to_32u(absNum, &normalized, &norm); + if (norm > 0) + /* + * 32-bit division + */ + result = (q31_t) num / den; + else + /* + * 64-bit division + */ + result = (q31_t) (num / den); + + return result; +} + + +/* + * @brief C custom defined intrinsic functions + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 + */ + __STATIC_FORCEINLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 + */ + __STATIC_FORCEINLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 + */ + __STATIC_FORCEINLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 + */ + __STATIC_FORCEINLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 + */ + __STATIC_FORCEINLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 + */ + __STATIC_FORCEINLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX + */ + __STATIC_FORCEINLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX + */ + __STATIC_FORCEINLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX + */ + __STATIC_FORCEINLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX + */ + __STATIC_FORCEINLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX + */ + __STATIC_FORCEINLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX + */ + __STATIC_FORCEINLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD + */ + __STATIC_FORCEINLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB + */ + __STATIC_FORCEINLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD + */ + __STATIC_FORCEINLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX + */ + __STATIC_FORCEINLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX + */ + __STATIC_FORCEINLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD + */ + __STATIC_FORCEINLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX + */ + __STATIC_FORCEINLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD + */ + __STATIC_FORCEINLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD + */ + __STATIC_FORCEINLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 + */ + __STATIC_FORCEINLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA + */ + __STATIC_FORCEINLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter (fast version). + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns either + * ARM_MATH_SUCCESS if initialization was successful or + * ARM_MATH_ARGUMENT_ERROR if numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter (fast version). + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + /** + * @brief Instance structure for the modified Biquad coefs required by vectorized code. + */ + typedef struct + { + float32_t coeffs[8][4]; /**< Points to the array of modified coefficients. The array is of length 32. There is one per stage */ + } arm_biquad_mod_coef_f32; +#endif + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + const q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pCoeffsMod points to the modified filter coefficients (only MVE version). + * @param[in] pState points to the state buffer. + */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + void arm_biquad_cascade_df1_mve_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + arm_biquad_mod_coef_f32 * pCoeffsMod, + float32_t * pState); +#endif + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u16( + const uint16_t * pSrc, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u32( + const uint32_t * pSrc, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u8( + const uint8_t * pSrc, + uint8_t * pDst, + uint32_t blockSize); + +/** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_BITONIC = 0, + /**< Bitonic sort */ + ARM_SORT_BUBBLE = 1, + /**< Bubble sort */ + ARM_SORT_HEAP = 2, + /**< Heap sort */ + ARM_SORT_INSERTION = 3, + /**< Insertion sort */ + ARM_SORT_QUICK = 4, + /**< Quick sort */ + ARM_SORT_SELECTION = 5 + /**< Selection sort */ + } arm_sort_alg; + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_DESCENDING = 0, + /**< Descending order (9 to 0) */ + ARM_SORT_ASCENDING = 1 + /**< Ascending order (0 to 9) */ + } arm_sort_dir; + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_alg alg; /**< Sorting algorithm selected */ + arm_sort_dir dir; /**< Sorting order (direction) */ + } arm_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_sort_f32( + const arm_sort_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] alg Selected algorithm. + * @param[in] dir Sorting order. + */ + void arm_sort_init_f32( + arm_sort_instance_f32 * S, + arm_sort_alg alg, + arm_sort_dir dir); + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_dir dir; /**< Sorting order (direction) */ + float32_t * buffer; /**< Working buffer */ + } arm_merge_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in,out] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_merge_sort_f32( + const arm_merge_sort_instance_f32 * S, + float32_t *pSrc, + float32_t *pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] dir Sorting order. + * @param[in] buffer Working buffer. + */ + void arm_merge_sort_init_f32( + arm_merge_sort_instance_f32 * S, + arm_sort_dir dir, + float32_t * buffer); + + /** + * @brief Struct for specifying cubic spline type + */ + typedef enum + { + ARM_SPLINE_NATURAL = 0, /**< Natural spline */ + ARM_SPLINE_PARABOLIC_RUNOUT = 1 /**< Parabolic runout spline */ + } arm_spline_type; + + /** + * @brief Instance structure for the floating-point cubic spline interpolation. + */ + typedef struct + { + arm_spline_type type; /**< Type (boundary conditions) */ + const float32_t * x; /**< x values */ + const float32_t * y; /**< y values */ + uint32_t n_x; /**< Number of known data points */ + float32_t * coeffs; /**< Coefficients buffer (b,c, and d) */ + } arm_spline_instance_f32; + + /** + * @brief Processing function for the floating-point cubic spline interpolation. + * @param[in] S points to an instance of the floating-point spline structure. + * @param[in] xq points to the x values ot the interpolated data points. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples of output data. + */ + void arm_spline_f32( + arm_spline_instance_f32 * S, + const float32_t * xq, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point cubic spline interpolation. + * @param[in,out] S points to an instance of the floating-point spline structure. + * @param[in] type type of cubic spline interpolation (boundary conditions) + * @param[in] x points to the x values of the known data points. + * @param[in] y points to the y values of the known data points. + * @param[in] n number of known data points. + * @param[in] coeffs coefficients array for b, c, and d + * @param[in] tempBuffer buffer array for internal computations + */ + void arm_spline_init_f32( + arm_spline_instance_f32 * S, + arm_spline_type type, + const float32_t * x, + const float32_t * y, + uint32_t n, + float32_t * coeffs, + float32_t * tempBuffer); + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q15_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q15_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q15_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q15; + +arm_status arm_cfft_init_q15( + arm_cfft_instance_q15 * S, + uint16_t fftLen); + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q31_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q31_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q31_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q31; + +arm_status arm_cfft_init_q31( + arm_cfft_instance_q31 * S, + uint16_t fftLen); + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const float32_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const float32_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const float32_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_f32; + + + arm_status arm_cfft_init_f32( + arm_cfft_instance_f32 * S, + uint16_t fftLen); + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + /** + * @brief Instance structure for the Double Precision Floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float64_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f64; + + void arm_cfft_f64( + const arm_cfft_instance_f64 * S, + float64_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q15 cfftInst; +#else + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q31 cfftInst; +#else + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the Double Precision Floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f64 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float64_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f64 ; + +arm_status arm_rfft_fast_init_f64 ( + arm_rfft_fast_instance_f64 * S, + uint16_t fftLen); + + +void arm_rfft_fast_f64( + arm_rfft_fast_instance_f64 * S, + float64_t * p, float64_t * pOut, + uint8_t ifftFlag); + + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + + + void arm_rfft_fast_f32( + const arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + const float32_t *pTwiddle; /**< points to the twiddle factor table. */ + const float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + const float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + const q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + const q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + +/** + @brief Instance structure for floating-point FIR decimator. + */ +typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + +/** + @brief Processing function for floating-point FIR decimator. + @param[in] S points to an instance of the floating-point FIR decimator structure + @param[in] pSrc points to the block of input data + @param[out] pDst points to the block of output data + @param[in] blockSize number of samples to process + */ +void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + @brief Initialization function for the floating-point FIR decimator. + @param[in,out] S points to an instance of the floating-point FIR decimator structure + @param[in] numTaps number of coefficients in the filter + @param[in] M decimation factor + @param[in] pCoeffs points to the filter coefficients + @param[in] pState points to the state buffer + @param[in] blockSize number of input samples to process per call + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + */ +arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + const float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + +#if defined(ARM_MATH_NEON) +void arm_biquad_cascade_df2T_compute_coefs_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs); +#endif + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + const float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + @brief Correlation of Q15 sequences + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +*/ +void arm_correlate_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ +void arm_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence. + @param[in] srcALen length of the first input sequence. + @param[in] pSrcB points to the second input sequence. + @param[in] srcBLen length of the second input sequence. + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ +void arm_correlate_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + @brief Correlation of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void arm_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
    +   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
    +   *    A0 = Kp + Ki + Kd
    +   *    A1 = (-Kp ) - (2 * Kd )
    +   *    A2 = Kd
    +   * 
    + * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return processed output sample. + */ + __STATIC_FORCEINLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + +/** + @brief Process function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around rather than clip. + In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ +__STATIC_FORCEINLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + +/** + @brief Process function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ +__STATIC_FORCEINLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @return none + */ + __STATIC_FORCEINLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + +/** + @brief Clarke transform for Q31 version + @param[in] Ia input three-phase coordinate a + @param[in] Ib input three-phase coordinate b + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + +/** + @brief Inverse Clarke transform for Q31 version + @param[in] Ialpha input two-phase orthogonal vector axis alpha + @param[in] Ibeta input two-phase orthogonal vector axis beta + @param[out] pIa points to output three-phase coordinate a + @param[out] pIb points to output three-phase coordinate b + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + * + * The function implements the forward Park transform. + * + */ + __STATIC_FORCEINLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + +/** + @brief Park transform for Q31 version + @param[in] Ialpha input two-phase vector coordinate alpha + @param[in] Ibeta input two-phase vector coordinate beta + @param[out] pId points to output rotor reference frame d + @param[out] pIq points to output rotor reference frame q + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + +/** + @brief Inverse Park transform for Q31 version + @param[in] Id input coordinate of rotor reference frame d + @param[in] Iq input coordinate of rotor reference frame q + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
    +   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
    +   *       where x0, x1 are nearest values of input x
    +   *             y0, y1 are nearest values to output y
    +   * 
    + * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + __STATIC_FORCEINLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= (S->nValues - 1)) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + __STATIC_FORCEINLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + +/** + @brief Floating-point vector of log values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vlog_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + @brief Floating-point vector of exp values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vexp_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
    +   *      x1 = x0 - f(x0)/f'(x0)
    +   * 
    + * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
    +   *     x0 = in/2                         [initial guess]
    +   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
    +   * 
    + */ + + + /** + * @addtogroup SQRT + * @{ + */ + +/** + @brief Floating-point square root function. + @param[in] in input value + @param[out] pOut square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +__STATIC_FORCEINLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + *pOut = __sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); + #else + *pOut = sqrtf(in); + #endif + +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + +/** + @brief Q31 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + +/** + @brief Q15 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @brief Vector Floating-point square root function. + * @param[in] pIn input vector. + * @param[out] pOut vector of square roots of input elements. + * @param[in] len length of input vector. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + void arm_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len); + + void arm_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len); + + void arm_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset; + int32_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q15_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q7_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + @brief Maximum value of a floating-point vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult maximum value returned here + @return none + */ + void arm_max_no_idx_f32( + const float32_t *pSrc, + uint32_t blockSize, + float32_t *pResult); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Struct for specifying SVM Kernel + */ +typedef enum +{ + ARM_ML_KERNEL_LINEAR = 0, + /**< Linear kernel */ + ARM_ML_KERNEL_POLYNOMIAL = 1, + /**< Polynomial kernel */ + ARM_ML_KERNEL_RBF = 2, + /**< Radial Basis Function kernel */ + ARM_ML_KERNEL_SIGMOID = 3 + /**< Sigmoid kernel */ +} arm_ml_kernel_type; + + +/** + * @brief Instance structure for linear SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ +} arm_svm_linear_instance_f32; + + +/** + * @brief Instance structure for polynomial SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + int32_t degree; /**< Polynomial degree */ + float32_t coef0; /**< Polynomial constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_polynomial_instance_f32; + +/** + * @brief Instance structure for rbf SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_rbf_instance_f32; + +/** + * @brief Instance structure for sigmoid SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t coef0; /**< Independant constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_sigmoid_instance_f32; + +/** + * @brief SVM linear instance init function + * @param[in] S Parameters for SVM functions + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @return none. + * + */ + + +void arm_svm_linear_init_f32(arm_svm_linear_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes); + +/** + * @brief SVM linear prediction + * @param[in] S Pointer to an instance of the linear SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ + +void arm_svm_linear_predict_f32(const arm_svm_linear_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM polynomial instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] degree Polynomial degree + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + + +void arm_svm_polynomial_init_f32(arm_svm_polynomial_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + int32_t degree, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM polynomial prediction + * @param[in] S Pointer to an instance of the polynomial SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_polynomial_predict_f32(const arm_svm_polynomial_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM radial basis function instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_rbf_init_f32(arm_svm_rbf_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t gamma + ); + +/** + * @brief SVM rbf prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult decision value + * @return none. + * + */ +void arm_svm_rbf_predict_f32(const arm_svm_rbf_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + +/** + * @brief SVM sigmoid instance init function + * @param[in] S points to an instance of the rbf SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_sigmoid_init_f32(arm_svm_sigmoid_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM sigmoid prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_sigmoid_predict_f32(const arm_svm_sigmoid_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + + +/** + * @brief Instance structure for Naive Gaussian Bayesian estimator. + */ +typedef struct +{ + uint32_t vectorDimension; /**< Dimension of vector space */ + uint32_t numberOfClasses; /**< Number of different classes */ + const float32_t *theta; /**< Mean values for the Gaussians */ + const float32_t *sigma; /**< Variances for the Gaussians */ + const float32_t *classPriors; /**< Class prior probabilities */ + float32_t epsilon; /**< Additive value to variances */ +} arm_gaussian_naive_bayes_instance_f32; + +/** + * @brief Naive Gaussian Bayesian Estimator + * + * @param[in] S points to a naive bayes instance structure + * @param[in] in points to the elements of the input vector. + * @param[in] pBuffer points to a buffer of length numberOfClasses + * @return The predicted class + * + */ + + +uint32_t arm_gaussian_naive_bayes_predict_f32(const arm_gaussian_naive_bayes_instance_f32 *S, + const float32_t * in, + float32_t *pBuffer); + +/** + * @brief Computation of the LogSumExp + * + * In probabilistic computations, the dynamic of the probability values can be very + * wide because they come from gaussian functions. + * To avoid underflow and overflow issues, the values are represented by their log. + * In this representation, multiplying the original exp values is easy : their logs are added. + * But adding the original exp values is requiring some special handling and it is the + * goal of the LogSumExp function. + * + * If the values are x1...xn, the function is computing: + * + * ln(exp(x1) + ... + exp(xn)) and the computation is done in such a way that + * rounding issues are minimised. + * + * The max xm of the values is extracted and the function is computing: + * xm + ln(exp(x1 - xm) + ... + exp(xn - xm)) + * + * @param[in] *in Pointer to an array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return LogSumExp + * + */ + + +float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize); + +/** + * @brief Dot product with log arithmetic + * + * Vectors are containing the log of the samples + * + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[in] pTmpBuffer temporary buffer of length blockSize + * @return The log of the dot product . + * + */ + + +float32_t arm_logsumexp_dot_prod_f32(const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t *pTmpBuffer); + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize); + + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float32_t arm_kullback_leibler_f32(const float32_t * pSrcA + ,const float32_t * pSrcB + ,uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float64_t arm_kullback_leibler_f64(const float64_t * pSrcA, + const float64_t * pSrcB, + uint32_t blockSize); + + +/** + * @brief Weighted sum + * + * + * @param[in] *in Array of input values. + * @param[in] *weigths Weights + * @param[in] blockSize Number of samples in the input array. + * @return Weighted sum + * + */ +float32_t arm_weighted_sum_f32(const float32_t *in + , const float32_t *weigths + , uint32_t blockSize); + + +/** + * @brief Barycenter + * + * + * @param[in] in List of vectors + * @param[in] weights Weights of the vectors + * @param[out] out Barycenter + * @param[in] nbVectors Number of vectors + * @param[in] vecDim Dimension of space (vector dimension) + * @return None + * + */ +void arm_barycenter_f32(const float32_t *in + , const float32_t *weights + , float32_t *out + , uint32_t nbVectors + , uint32_t vecDim); + +/** + * @brief Euclidean distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Bray-Curtis distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Canberra distance between two vectors + * + * This function may divide by zero when samples pA[i] and pB[i] are both zero. + * The result of the computation will be correct. So the division per zero may be + * ignored. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Chebyshev distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Cityblock (Manhattan) distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Correlation distance between two vectors + * + * The input vectors are modified in place ! + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize); + +/** + * @brief Cosine distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Jensen-Shannon distance between two vectors + * + * This function is assuming that elements of second vector are > 0 + * and 0 only when the corresponding element of first vector is 0. + * Otherwise the result of the computation does not make sense + * and for speed reasons, the cases returning NaN or Infinity are not + * managed. + * + * When the function is computing x log (x / y) with x 0 and y 0, + * it will compute the right value (0) but a division per zero will occur + * and shoudl be ignored in client code. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize); + +/** + * @brief Minkowski distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] n Norm order (>= 2) + * @param[in] blockSize vector length + * @return distance + * + */ + + + +float32_t arm_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize); + +/** + * @brief Dice distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] order Distance order + * @param[in] blockSize Number of samples + * @return distance + * + */ + + +float32_t arm_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Hamming distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Jaccard distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Kulsinski distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Roger Stanimoto distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Russell-Rao distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Michener distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Sneath distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Yule distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
    +   *   typedef struct
    +   *   {
    +   *     uint16_t numRows;
    +   *     uint16_t numCols;
    +   *     float32_t *pData;
    +   * } arm_bilinear_interp_instance_f32;
    +   * 
    + * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
    +   *     XF = floor(x)
    +   *     YF = floor(y)
    +   * 
    + * \par + * The interpolated output point is computed as: + *
    +   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
    +   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
    +   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
    +   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
    +   * 
    + * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numCols - 2) || yIndex < 0 || yIndex > (S->numRows - 2)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex ) + (yIndex ) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex ) + (yIndex+1) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0x0FFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0x0FFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0x0FFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0x0FFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT +#endif + + + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_mve_tables.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_mve_tables.h new file mode 100644 index 0000000..4d2c135 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_mve_tables.h @@ -0,0 +1,235 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mve_tables.h + * Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc + * used for MVE implementation only + * + * $Date: 08. January 2020 + * $Revision: V1.7.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 _ARM_MVE_TABLES_H + #define _ARM_MVE_TABLES_H + + #include "arm_math.h" + + + + + + +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_f32[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_f32[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_f32[2]; +extern float32_t rearranged_twiddle_stride1_16_f32[8]; +extern float32_t rearranged_twiddle_stride2_16_f32[8]; +extern float32_t rearranged_twiddle_stride3_16_f32[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_f32[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_f32[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_f32[3]; +extern float32_t rearranged_twiddle_stride1_64_f32[40]; +extern float32_t rearranged_twiddle_stride2_64_f32[40]; +extern float32_t rearranged_twiddle_stride3_64_f32[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_f32[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_f32[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_f32[4]; +extern float32_t rearranged_twiddle_stride1_256_f32[168]; +extern float32_t rearranged_twiddle_stride2_256_f32[168]; +extern float32_t rearranged_twiddle_stride3_256_f32[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_f32[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_f32[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_f32[5]; +extern float32_t rearranged_twiddle_stride1_1024_f32[680]; +extern float32_t rearranged_twiddle_stride2_1024_f32[680]; +extern float32_t rearranged_twiddle_stride3_1024_f32[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) || defined(ARM_TABLE_TWIDDLECOEF_F32_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_f32[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_f32[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_f32[6]; +extern float32_t rearranged_twiddle_stride1_4096_f32[2728]; +extern float32_t rearranged_twiddle_stride2_4096_f32[2728]; +extern float32_t rearranged_twiddle_stride3_4096_f32[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q31[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q31[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q31[2]; +extern q31_t rearranged_twiddle_stride1_16_q31[8]; +extern q31_t rearranged_twiddle_stride2_16_q31[8]; +extern q31_t rearranged_twiddle_stride3_16_q31[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q31[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q31[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q31[3]; +extern q31_t rearranged_twiddle_stride1_64_q31[40]; +extern q31_t rearranged_twiddle_stride2_64_q31[40]; +extern q31_t rearranged_twiddle_stride3_64_q31[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q31[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q31[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q31[4]; +extern q31_t rearranged_twiddle_stride1_256_q31[168]; +extern q31_t rearranged_twiddle_stride2_256_q31[168]; +extern q31_t rearranged_twiddle_stride3_256_q31[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q31[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q31[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q31[5]; +extern q31_t rearranged_twiddle_stride1_1024_q31[680]; +extern q31_t rearranged_twiddle_stride2_1024_q31[680]; +extern q31_t rearranged_twiddle_stride3_1024_q31[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q31_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q31[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q31[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q31[6]; +extern q31_t rearranged_twiddle_stride1_4096_q31[2728]; +extern q31_t rearranged_twiddle_stride2_4096_q31[2728]; +extern q31_t rearranged_twiddle_stride3_4096_q31[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q15[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q15[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q15[2]; +extern q15_t rearranged_twiddle_stride1_16_q15[8]; +extern q15_t rearranged_twiddle_stride2_16_q15[8]; +extern q15_t rearranged_twiddle_stride3_16_q15[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q15[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q15[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q15[3]; +extern q15_t rearranged_twiddle_stride1_64_q15[40]; +extern q15_t rearranged_twiddle_stride2_64_q15[40]; +extern q15_t rearranged_twiddle_stride3_64_q15[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q15[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q15[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q15[4]; +extern q15_t rearranged_twiddle_stride1_256_q15[168]; +extern q15_t rearranged_twiddle_stride2_256_q15[168]; +extern q15_t rearranged_twiddle_stride3_256_q15[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q15[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q15[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q15[5]; +extern q15_t rearranged_twiddle_stride1_1024_q15[680]; +extern q15_t rearranged_twiddle_stride2_1024_q15[680]; +extern q15_t rearranged_twiddle_stride3_1024_q15[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q15_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q15[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q15[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q15[6]; +extern q15_t rearranged_twiddle_stride1_4096_q15[2728]; +extern q15_t rearranged_twiddle_stride2_4096_q15[2728]; +extern q15_t rearranged_twiddle_stride3_4096_q15[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#endif /*_ARM_MVE_TABLES_H*/ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_vec_math.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_vec_math.h new file mode 100644 index 0000000..0ce9464 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_vec_math.h @@ -0,0 +1,372 @@ +/****************************************************************************** + * @file arm_vec_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.7.0 + * @date 15. October 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 _ARM_VEC_MATH_H +#define _ARM_VEC_MATH_H + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_helium_utils.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) + +#define INV_NEWTON_INIT_F32 0x7EF127EA + +static const float32_t __logf_rng_f32=0.693147180f; + + +/* fast inverse approximation (3x newton) */ +__STATIC_INLINE f32x4_t vrecip_medprec_f32( + f32x4_t x) +{ + q31x4_t m; + f32x4_t b; + any32x4_t xinv; + f32x4_t ax = vabsq(x); + + xinv.f = ax; + m = 0x3F800000 - (xinv.i & 0x7F800000); + xinv.i = xinv.i + m; + xinv.f = 1.41176471f - 0.47058824f * xinv.f; + xinv.i = xinv.i + m; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f)); + /* + * restore sign + */ + xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f)); + + return xinv.f; +} + +/* fast inverse approximation (4x newton) */ +__STATIC_INLINE f32x4_t vrecip_hiprec_f32( + f32x4_t x) +{ + q31x4_t m; + f32x4_t b; + any32x4_t xinv; + f32x4_t ax = vabsq(x); + + xinv.f = ax; + + m = 0x3F800000 - (xinv.i & 0x7F800000); + xinv.i = xinv.i + m; + xinv.f = 1.41176471f - 0.47058824f * xinv.f; + xinv.i = xinv.i + m; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f)); + /* + * restore sign + */ + xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f)); + + return xinv.f; +} + +__STATIC_INLINE f32x4_t vdiv_f32( + f32x4_t num, f32x4_t den) +{ + return vmulq(num, vrecip_hiprec_f32(den)); +} + +/** + @brief Single-precision taylor dev. + @param[in] x f32 quad vector input + @param[in] coeffs f32 quad vector coeffs + @return destination f32 quad vector + */ + +__STATIC_INLINE f32x4_t vtaylor_polyq_f32( + f32x4_t x, + const float32_t * coeffs) +{ + f32x4_t A = vfmasq(vdupq_n_f32(coeffs[4]), x, coeffs[0]); + f32x4_t B = vfmasq(vdupq_n_f32(coeffs[6]), x, coeffs[2]); + f32x4_t C = vfmasq(vdupq_n_f32(coeffs[5]), x, coeffs[1]); + f32x4_t D = vfmasq(vdupq_n_f32(coeffs[7]), x, coeffs[3]); + f32x4_t x2 = vmulq(x, x); + f32x4_t x4 = vmulq(x2, x2); + f32x4_t res = vfmaq(vfmaq_f32(A, B, x2), vfmaq_f32(C, D, x2), x4); + + return res; +} + +__STATIC_INLINE f32x4_t vmant_exp_f32( + f32x4_t x, + int32x4_t * e) +{ + any32x4_t r; + int32x4_t n; + + r.f = x; + n = r.i >> 23; + n = n - 127; + r.i = r.i - (n << 23); + + *e = n; + return r.f; +} + + +__STATIC_INLINE f32x4_t vlogq_f32(f32x4_t vecIn) +{ + q31x4_t vecExpUnBiased; + f32x4_t vecTmpFlt0, vecTmpFlt1; + f32x4_t vecAcc0, vecAcc1, vecAcc2, vecAcc3; + f32x4_t vecExpUnBiasedFlt; + + /* + * extract exponent + */ + vecTmpFlt1 = vmant_exp_f32(vecIn, &vecExpUnBiased); + + vecTmpFlt0 = vecTmpFlt1 * vecTmpFlt1; + /* + * a = (__logf_lut_f32[4] * r.f) + (__logf_lut_f32[0]); + */ + vecAcc0 = vdupq_n_f32(__logf_lut_f32[0]); + vecAcc0 = vfmaq(vecAcc0, vecTmpFlt1, __logf_lut_f32[4]); + /* + * b = (__logf_lut_f32[6] * r.f) + (__logf_lut_f32[2]); + */ + vecAcc1 = vdupq_n_f32(__logf_lut_f32[2]); + vecAcc1 = vfmaq(vecAcc1, vecTmpFlt1, __logf_lut_f32[6]); + /* + * c = (__logf_lut_f32[5] * r.f) + (__logf_lut_f32[1]); + */ + vecAcc2 = vdupq_n_f32(__logf_lut_f32[1]); + vecAcc2 = vfmaq(vecAcc2, vecTmpFlt1, __logf_lut_f32[5]); + /* + * d = (__logf_lut_f32[7] * r.f) + (__logf_lut_f32[3]); + */ + vecAcc3 = vdupq_n_f32(__logf_lut_f32[3]); + vecAcc3 = vfmaq(vecAcc3, vecTmpFlt1, __logf_lut_f32[7]); + /* + * a = a + b * xx; + */ + vecAcc0 = vfmaq(vecAcc0, vecAcc1, vecTmpFlt0); + /* + * c = c + d * xx; + */ + vecAcc2 = vfmaq(vecAcc2, vecAcc3, vecTmpFlt0); + /* + * xx = xx * xx; + */ + vecTmpFlt0 = vecTmpFlt0 * vecTmpFlt0; + vecExpUnBiasedFlt = vcvtq_f32_s32(vecExpUnBiased); + /* + * r.f = a + c * xx; + */ + vecAcc0 = vfmaq(vecAcc0, vecAcc2, vecTmpFlt0); + /* + * add exponent + * r.f = r.f + ((float32_t) m) * __logf_rng_f32; + */ + vecAcc0 = vfmaq(vecAcc0, vecExpUnBiasedFlt, __logf_rng_f32); + // set log0 down to -inf + vecAcc0 = vdupq_m(vecAcc0, -INFINITY, vcmpeqq(vecIn, 0.0f)); + return vecAcc0; +} + +__STATIC_INLINE f32x4_t vexpq_f32( + f32x4_t x) +{ + // Perform range reduction [-log(2),log(2)] + int32x4_t m = vcvtq_s32_f32(vmulq_n_f32(x, 1.4426950408f)); + f32x4_t val = vfmsq_f32(x, vcvtq_f32_s32(m), vdupq_n_f32(0.6931471805f)); + + // Polynomial Approximation + f32x4_t poly = vtaylor_polyq_f32(val, exp_tab); + + // Reconstruct + poly = (f32x4_t) (vqaddq_s32((q31x4_t) (poly), vqshlq_n_s32(m, 23))); + + poly = vdupq_m(poly, 0.0f, vcmpltq_n_s32(m, -126)); + return poly; +} + +__STATIC_INLINE f32x4_t arm_vec_exponent_f32(f32x4_t x, int32_t nb) +{ + f32x4_t r = x; + nb--; + while (nb > 0) { + r = vmulq(r, x); + nb--; + } + return (r); +} + +__STATIC_INLINE f32x4_t vrecip_f32(f32x4_t vecIn) +{ + f32x4_t vecSx, vecW, vecTmp; + any32x4_t v; + + vecSx = vabsq(vecIn); + + v.f = vecIn; + v.i = vsubq(vdupq_n_s32(INV_NEWTON_INIT_F32), v.i); + + vecW = vmulq(vecSx, v.f); + + // v.f = v.f * (8 + w * (-28 + w * (56 + w * (-70 + w *(56 + w * (-28 + w * (8 - w))))))); + vecTmp = vsubq(vdupq_n_f32(8.0f), vecW); + vecTmp = vfmasq(vecW, vecTmp, -28.0f); + vecTmp = vfmasq(vecW, vecTmp, 56.0f); + vecTmp = vfmasq(vecW, vecTmp, -70.0f); + vecTmp = vfmasq(vecW, vecTmp, 56.0f); + vecTmp = vfmasq(vecW, vecTmp, -28.0f); + vecTmp = vfmasq(vecW, vecTmp, 8.0f); + v.f = vmulq(v.f, vecTmp); + + v.f = vdupq_m(v.f, INFINITY, vcmpeqq(vecIn, 0.0f)); + /* + * restore sign + */ + v.f = vnegq_m(v.f, v.f, vcmpltq(vecIn, 0.0f)); + return v.f; +} + +__STATIC_INLINE f32x4_t vtanhq_f32( + f32x4_t val) +{ + f32x4_t x = + vminnmq_f32(vmaxnmq_f32(val, vdupq_n_f32(-10.f)), vdupq_n_f32(10.0f)); + f32x4_t exp2x = vexpq_f32(vmulq_n_f32(x, 2.f)); + f32x4_t num = vsubq_n_f32(exp2x, 1.f); + f32x4_t den = vaddq_n_f32(exp2x, 1.f); + f32x4_t tanh = vmulq_f32(num, vrecip_f32(den)); + return tanh; +} + +__STATIC_INLINE f32x4_t vpowq_f32( + f32x4_t val, + f32x4_t n) +{ + return vexpq_f32(vmulq_f32(n, vlogq_f32(val))); +} + +#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)*/ + +#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) +#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */ + +#if (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) + +#include "NEMath.h" +/** + * @brief Vectorized integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32x4_t arm_vec_exponent_f32(float32x4_t x, int32_t nb) +{ + float32x4_t r = x; + nb --; + while(nb > 0) + { + r = vmulq_f32(r , x); + nb--; + } + return(r); +} + + +__STATIC_INLINE float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x) +{ + float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN)); + float32x4_t e = vrsqrteq_f32(x1); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + return vmulq_f32(x, e); +} + +__STATIC_INLINE int16x8_t __arm_vec_sqrt_q15_neon(int16x8_t vec) +{ + float32x4_t tempF; + int32x4_t tempHI,tempLO; + + tempLO = vmovl_s16(vget_low_s16(vec)); + tempF = vcvtq_n_f32_s32(tempLO,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempLO = vcvtq_n_s32_f32(tempF,15); + + tempHI = vmovl_s16(vget_high_s16(vec)); + tempF = vcvtq_n_f32_s32(tempHI,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempHI = vcvtq_n_s32_f32(tempF,15); + + return(vcombine_s16(vqmovn_s32(tempLO),vqmovn_s32(tempHI))); +} + +__STATIC_INLINE int32x4_t __arm_vec_sqrt_q31_neon(int32x4_t vec) +{ + float32x4_t temp; + + temp = vcvtq_n_f32_s32(vec,31); + temp = __arm_vec_sqrt_f32_neon(temp); + return(vcvtq_n_s32_f32(temp,31)); +} + +#endif /* (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_VEC_MATH_H */ + +/** + * + * End of file. + */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/BUILD.gn new file mode 100644 index 0000000..f9419fa --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_alarm") { + sources = [ "app_alarm.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.c new file mode 100644 index 0000000..4cb5788 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.c @@ -0,0 +1,726 @@ +/** + **************************************************************************************** + * @file app_alarm.c + * @author BLE Driver Team + * @brief APP Alarm Library. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "grx_hal.h" +#include "app_alarm.h" + +#ifdef HAL_CALENDAR_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + +#define _LOCAL_APP_ALARM_LOCK() \ + uint32_t __l_irq_rest = __get_BASEPRI(); \ + __set_BASEPRI(NVIC_GetPriority(BLE_IRQn) + \ + (1 << (NVIC_GetPriorityGrouping() + 1))); + +#define _LOCAL_APP_ALARM_UNLOCK() \ + __set_BASEPRI(__l_irq_rest); + +#define APP_ALARM_BASE_ALARM_MARK 0x9f00 +#define APP_ALARM_FIRST_YEAR (2000UL) +#define APP_ALARM_SECONDS_PER_HOUR (3600UL) +#define APP_ALARM_SECONDS_PER_DAY (24UL * APP_ALARM_SECONDS_PER_HOUR) +#define APP_ALARM_SECONDS_PER_YEAR (365UL * APP_ALARM_SECONDS_PER_DAY) +#define APP_ALARM_DAYS_PER_MONTH {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +#define IS_APP_ALARM_LEAP_YEAR(__YEAR__) ((((__YEAR__) % 4) == 0 && ((__YEAR__) % 100) != 0) || \ + ((__YEAR__) % 400) == 0) + +#define APP_ALARM_LOCK() _LOCAL_APP_ALARM_LOCK() +#define APP_ALARM_UNLOCK() _LOCAL_APP_ALARM_UNLOCK() + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +typedef struct +{ + app_alarm_id_t alarm_id; + uint32_t delay; + app_alarm_t alarm; +} app_alarm_node_t; + +typedef struct +{ + app_alarm_node_t alarm_list[MAX_ALARM_SUPPORT]; + app_alarm_node_t alarm0; + calendar_handle_t handle; + bool initialized; + uint8_t alarm_available; + NvdsTag_t alarm_data_tag; + app_alarm_fun_t callback; +} app_alarm_info_t; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static uint32_t time2seconds(const app_time_t *time); +static void update_alarm_delay(const app_time_t *cur_time, const uint32_t cur_seconds, app_alarm_node_t *alarm_node); +static void calendar_alarm_cb(calendar_handle_t *hcalendar); +static void sort_alarm_list(void); +static uint8_t check_alarm_existed_alarm_id(app_alarm_id_t alarm_id); +static uint8_t check_alarm_existed_alarm(const app_alarm_t *alarm); +static uint16_t save_alarm_list(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static app_alarm_info_t s_app_alarm_info = {0}; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_alarm_init(NvdsTag_t tag, app_alarm_fun_t callback) +{ + hal_status_t hal_err_code; + uint8_t error_code; + uint16_t len; + app_alarm_node_t alarm_buf[MAX_ALARM_SUPPORT]; + + if (0xFFFF == tag || 0x0000 == tag || NULL == callback) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + /* Clear rtc_alarm globle info */ + memset(&s_app_alarm_info, 0, sizeof(app_alarm_info_t)); + + /* Initialize calendar */ + hal_err_code = hal_calendar_init(&s_app_alarm_info.handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + /* Copy alarm setting from NVDS to buffer */ + s_app_alarm_info.alarm_data_tag = tag; + s_app_alarm_info.callback = callback; + len = sizeof(alarm_buf); + error_code = nvds_get(s_app_alarm_info.alarm_data_tag, &len, (uint8_t *)alarm_buf); + if (NVDS_SUCCESS != error_code) + { + if (NVDS_TAG_NOT_EXISTED == error_code) + { + memset(alarm_buf, 0, sizeof(alarm_buf)); + error_code = nvds_put(s_app_alarm_info.alarm_data_tag, sizeof(alarm_buf), (const uint8_t *)alarm_buf); + if (NVDS_SUCCESS != error_code) + { + return HAL_ERROR; + } + } + else + { + return HAL_ERROR; + } + } + + /* Base alarm, generate an alarm clock at 0 o'clock every day */ + s_app_alarm_info.alarm0.alarm.hour = 0; + s_app_alarm_info.alarm0.alarm.min = 0; + s_app_alarm_info.alarm0.alarm.alarm_date_week_mask = 0x7F; + s_app_alarm_info.alarm0.alarm.alarm_sel = CALENDAR_ALARM_SEL_WEEKDAY; + s_app_alarm_info.alarm0.alarm_id = APP_ALARM_BASE_ALARM_MARK; + + /* Check the number of alarm */ + for (uint8_t i = 0; i < MAX_ALARM_SUPPORT; i++) + { + if (alarm_buf[i].alarm.alarm_date_week_mask) + { + memcpy(&s_app_alarm_info.alarm_list[i], &alarm_buf[i], sizeof(app_alarm_node_t)); + s_app_alarm_info.alarm_available++; + } + } + + s_app_alarm_info.initialized = true; + + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_deinit(void) +{ + hal_status_t hal_err_code; + uint8_t error_code; + + if (!s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL); + HAL_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_calendar_deinit(&s_app_alarm_info.handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + error_code = nvds_del(s_app_alarm_info.alarm_data_tag); + if (NVDS_SUCCESS != error_code) + { + return APP_DRV_ERR_HAL; + } + + /* Clear rtc_alarm globle info */ + memset(&s_app_alarm_info, 0, sizeof(app_alarm_info_t)); + + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_add(const app_alarm_t *alarm, app_alarm_id_t p_alarm_id) +{ + hal_status_t hal_err_code; + app_drv_err_t app_err_code; + + if (NULL == alarm || + MAX_ALARM_SUPPORT <= s_app_alarm_info.alarm_available || + !s_app_alarm_info.initialized || + APP_ALARM_BASE > p_alarm_id) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + APP_ALARM_LOCK(); + /* Check the alarm is existed, avoid to load the same alarm */ + if (check_alarm_existed_alarm(alarm) == s_app_alarm_info.alarm_available) + { + /* Insert to end */ + memcpy(&s_app_alarm_info.alarm_list[s_app_alarm_info.alarm_available].alarm, alarm, sizeof(app_alarm_t)); + s_app_alarm_info.alarm_list[s_app_alarm_info.alarm_available].alarm_id = p_alarm_id ; + s_app_alarm_info.alarm_available++; + + /* Sort alarm then set the lastest */ + sort_alarm_list(); + if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay) + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm); + } + else + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm); + } + + if (HAL_OK != hal_err_code) + { + APP_ALARM_UNLOCK(); + return hal_err_code; + } + + app_err_code = save_alarm_list(); + if (APP_DRV_SUCCESS != app_err_code) + { + APP_ALARM_UNLOCK(); + return app_err_code; + } + } + APP_ALARM_UNLOCK(); + + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_del(app_alarm_id_t alarm_id) +{ + hal_status_t hal_err_code; + app_drv_err_t app_err_code; + + if (0 == s_app_alarm_info.alarm_available || + !s_app_alarm_info.initialized || + APP_ALARM_BASE > alarm_id) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + APP_ALARM_LOCK(); + uint8_t indx = check_alarm_existed_alarm_id(alarm_id); + if (indx < s_app_alarm_info.alarm_available) + { + /* Delete the indx */ + for (uint8_t i = indx; i < s_app_alarm_info.alarm_available - 1; i++) + { + memcpy(&s_app_alarm_info.alarm_list[i], &s_app_alarm_info.alarm_list[i + 1], sizeof(app_alarm_node_t)); + } + s_app_alarm_info.alarm_available--; + /* Check alarm available, if there is not any alarm then disable alarm */ + if (s_app_alarm_info.alarm_available > 0) + { + if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay) + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm); + } + else + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm); + } + if (HAL_OK != hal_err_code) + { + APP_ALARM_UNLOCK(); + return hal_err_code; + } + } + else + { + hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL); + if (HAL_OK != hal_err_code) + { + APP_ALARM_UNLOCK(); + return hal_err_code; + } + } + + app_err_code = save_alarm_list(); + if (APP_DRV_SUCCESS != app_err_code) + { + APP_ALARM_UNLOCK(); + return app_err_code; + } + } + else + { + APP_ALARM_UNLOCK(); + return APP_DRV_ERR_INVALID_PARAM; + } + + APP_ALARM_UNLOCK(); + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_del_all(void) +{ + hal_status_t hal_err_code; + app_drv_err_t app_err_code; + + if (0 == s_app_alarm_info.alarm_available || + !s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + APP_ALARM_LOCK(); + for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++) + { + memset(&s_app_alarm_info.alarm_list[i], 0, sizeof(app_alarm_node_t)); + } + s_app_alarm_info.alarm_available = 0; + hal_err_code = hal_calendar_disable_event(&s_app_alarm_info.handle, CALENDAR_ALARM_DISABLE_ALL); + if (HAL_OK != hal_err_code) + { + APP_ALARM_UNLOCK(); + return hal_err_code; + } + + app_err_code = save_alarm_list(); + if (APP_DRV_SUCCESS != app_err_code) + { + APP_ALARM_UNLOCK(); + return app_err_code; + } + + APP_ALARM_UNLOCK(); + + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_get_time(app_time_t *p_time) +{ + hal_status_t hal_err_code; + + if (p_time == NULL || !s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_err_code = hal_calendar_get_time(&s_app_alarm_info.handle, p_time); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_alarm_set_time(app_time_t *p_time) +{ + hal_status_t hal_err_code; + + if (p_time == NULL || !s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_err_code = hal_calendar_init_time(&s_app_alarm_info.handle, p_time); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} + +/* If you reset system time, you should call this function again */ +uint16_t app_alarm_reload(void) +{ + hal_status_t hal_err_code; + + if (!s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (0 < s_app_alarm_info.alarm_available) + { + /* Sort alarm then set the lastest */ + sort_alarm_list(); + sys_delay_ms(100); + if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay) + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm); + } + else + { + hal_err_code = hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm); + } + HAL_ERR_CODE_CHECK(hal_err_code); + } + + return APP_DRV_SUCCESS; +} + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/* Caculate seconds from 01.01.2000 00:00 to the input time */ +static uint32_t time2seconds(const app_time_t *time) +{ + uint32_t seconds = 0; + uint32_t mon_days[12] = APP_ALARM_DAYS_PER_MONTH; + + seconds = time->year * APP_ALARM_SECONDS_PER_YEAR + ((time->year + 3) / 4) * APP_ALARM_SECONDS_PER_DAY; + + mon_days[1] = IS_APP_ALARM_LEAP_YEAR((uint32_t)time->year + APP_ALARM_FIRST_YEAR) ? 29 : 28; + for (uint32_t i = 0; i < time->mon - 1; i++) + { + seconds += mon_days[i] * APP_ALARM_SECONDS_PER_DAY; + } + + seconds += (uint32_t)(time->date - 1) * APP_ALARM_SECONDS_PER_DAY; + + seconds += (uint32_t)time->hour * APP_ALARM_SECONDS_PER_HOUR; + + seconds += (uint32_t)time->min * 60 + (uint32_t)time->sec; + + return seconds; +} + +/* To caculate how long it will take to get to the alarm time from now */ +static void update_alarm_delay(const app_time_t *cur_time, const uint32_t cur_seconds, app_alarm_node_t *alarm_node) +{ + uint32_t alarm_sec = 0; + uint32_t mon_days[12] = APP_ALARM_DAYS_PER_MONTH; + app_time_t time; + + mon_days[1] = IS_APP_ALARM_LEAP_YEAR((uint32_t)cur_time->year + APP_ALARM_FIRST_YEAR) ? 29 : 28; + + memcpy(&time, cur_time, sizeof(app_time_t)); + /* Set current hour, min and sec to alarm time */ + time.sec = 0; + time.min = alarm_node->alarm.min; + time.hour = alarm_node->alarm.hour; + if (CALENDAR_ALARM_SEL_DATE == alarm_node->alarm.alarm_sel) + { + /* Type of alarm is date every month */ + time.date = alarm_node->alarm.alarm_date_week_mask; + alarm_sec = time2seconds(&time); + /* Calculate the latest alarm time in the future */ + if (alarm_sec <= cur_seconds) + { + if (++time.mon > 12) + { + time.mon = 1; + time.year++; + } + else + { + if (time.date > mon_days[time.mon - 1]) + { + time.mon++; + } + } + alarm_sec = time2seconds(&time); + } + } + else + { + /* Type of alarm is day every week */ + /* Get the latest date */ + uint8_t mask = 1 << time.week; + do { + /* Check if the alarm time is over current time */ + if (mask & alarm_node->alarm.alarm_date_week_mask) + { + alarm_sec = time2seconds(&time); + if (alarm_sec > cur_seconds) + { + break; + } + } + + /* Get the next latest alarm time */ + for (uint8_t day = 1; day < 8; day++) + { + mask <<= 1; + if (0x80 == mask) + { + mask = CALENDAR_ALARM_WEEKDAY_SUN; + } + + if (mask & alarm_node->alarm.alarm_date_week_mask) + { + time.date += day; + break; + } + } + if (time.date > mon_days[time.mon - 1]) + { + time.date -= mon_days[time.mon - 1]; + if (++time.mon > 12) + { + time.mon = 1; + time.year++; + } + } + alarm_sec = time2seconds(&time); + } while(0); + } + + alarm_node->delay = alarm_sec - cur_seconds; +} + +static void calendar_alarm_notify(app_alarm_node_t *alarm_node) +{ + app_time_t time; + + app_alarm_get_time(&time); + + if (time.hour == alarm_node->alarm.hour && time.min == alarm_node->alarm.min) + { + if (0 == alarm_node->alarm.hour && 0 == alarm_node->alarm.min) + { + if (CALENDAR_ALARM_SEL_WEEKDAY == alarm_node->alarm.alarm_sel) + { + if (alarm_node->alarm.alarm_date_week_mask & (1UL << time.week)) + { + s_app_alarm_info.callback(alarm_node->alarm_id); + } + } + else + { + if (alarm_node->alarm.alarm_date_week_mask == time.date) + { + s_app_alarm_info.callback(alarm_node->alarm_id); + } + } + } + else + { + s_app_alarm_info.callback(alarm_node->alarm_id); + } + } +} + +static void calendar_alarm_cb(calendar_handle_t *hcalendar) +{ + app_alarm_node_t alarm_node; + + /* Check alarm available */ + if (0 < s_app_alarm_info.alarm_available) + { + /* Save the current alarm */ + memcpy(&alarm_node, &s_app_alarm_info.alarm_list[0], sizeof(app_alarm_node_t)); + /* Sort for setting next */ + sort_alarm_list(); + + if (s_app_alarm_info.alarm0.delay <= s_app_alarm_info.alarm_list[0].delay) + { + hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm0.alarm); + } + else + { + hal_calendar_set_alarm(&s_app_alarm_info.handle, &s_app_alarm_info.alarm_list[0].alarm); + } + + /* User callback */ + calendar_alarm_notify(&alarm_node); + } +} + +static int32_t partition(app_alarm_node_t *alarm_list, int32_t begin, int32_t end) +{ + uint32_t x = alarm_list[end].delay; + int32_t i = begin - 1; + int32_t j; + app_alarm_node_t tmp; + + for (j = begin; j < end; j++) + { + if (alarm_list[j].delay <= x) + { + i++; + if (j != i) + { + memcpy(&tmp, &alarm_list[i], sizeof(app_alarm_node_t)); + memcpy(&alarm_list[i], &alarm_list[j], sizeof(app_alarm_node_t)); + memcpy(&alarm_list[j], &tmp, sizeof(app_alarm_node_t)); + } + } + } + + if (++i != end) + { + memcpy(&tmp, &alarm_list[i], sizeof(app_alarm_node_t)); + memcpy(&alarm_list[i], &alarm_list[end], sizeof(app_alarm_node_t)); + memcpy(&alarm_list[end], &tmp, sizeof(app_alarm_node_t)); + } + + return i; +} + +static void quick_sort(app_alarm_node_t *alarm_list, int32_t begin, int32_t end) +{ + int32_t m = 0; + + if ((NULL == alarm_list) || (begin >= end)) + { + return; + } + + m = partition(alarm_list, begin, end); + quick_sort(alarm_list, begin, m - 1); + quick_sort(alarm_list, m + 1, end); +} + +static void sort_alarm_list(void) +{ + app_time_t cur_time; + uint32_t cur_sec; + + if (0 < s_app_alarm_info.alarm_available) + { + hal_calendar_get_time(&s_app_alarm_info.handle, &cur_time); + cur_sec = time2seconds(&cur_time); + + /* Update alarm seconds */ + for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++) + { + update_alarm_delay(&cur_time, cur_sec, &s_app_alarm_info.alarm_list[i]); + } + + /* sort the seconds */ + quick_sort(s_app_alarm_info.alarm_list, 0, s_app_alarm_info.alarm_available - 1); + + /* update the alarm0 seconds */ + update_alarm_delay(&cur_time, cur_sec, &s_app_alarm_info.alarm0); + } +} + +static uint8_t check_alarm_existed_alarm_id(app_alarm_id_t alarm_id) +{ + uint8_t indx = 0; + + for (; indx < s_app_alarm_info.alarm_available; indx++) + { + if (s_app_alarm_info.alarm_list[indx].alarm_id == alarm_id) + { + break; + } + } + + return indx; +} + +static uint8_t check_alarm_existed_alarm(const app_alarm_t *alarm) +{ + uint8_t indx = 0; + + for (; indx < s_app_alarm_info.alarm_available; indx++) + { + if (!memcmp(&s_app_alarm_info.alarm_list[indx].alarm, alarm, sizeof(app_alarm_t))) + { + break; + } + } + + return indx; +} + +static uint16_t save_alarm_list(void) +{ + uint8_t error_code; + app_alarm_node_t alarm_buf[MAX_ALARM_SUPPORT]; + + if (!s_app_alarm_info.initialized) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + memset(alarm_buf, 0, sizeof(alarm_buf)); + for (uint8_t i = 0; i < s_app_alarm_info.alarm_available; i++) + { + memcpy(&alarm_buf[i], &s_app_alarm_info.alarm_list[i], sizeof(app_alarm_node_t)); + } + + error_code = nvds_put(s_app_alarm_info.alarm_data_tag, sizeof(alarm_buf), (const uint8_t *)alarm_buf); + if (NVDS_SUCCESS != error_code) + { + return error_code; + } + + return APP_DRV_SUCCESS; +} + +/* Calendar HAL driver alarm callback */ +void hal_calendar_alarm_callback(calendar_handle_t *hcalendar) +{ + calendar_alarm_cb(hcalendar); +} + +/* Calendar HAL driver overflow callback */ +void hal_calendar_overflow_callback(calendar_handle_t *hcalendar) +{ + calendar_alarm_cb(hcalendar); +} + +void CALENDAR_IRQHandler(void) +{ + hal_calendar_irq_handler(&s_app_alarm_info.handle); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.h new file mode 100644 index 0000000..e40b540 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_alarm/app_alarm.h @@ -0,0 +1,206 @@ +/** + **************************************************************************************** + * + * @file app_alarm.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of APP Alarm APIs library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +#ifndef __APP_ALARM__ +#define __APP_ALARM__ + +#include "grx_sys.h" +#include "app_drv_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_CALENDAR_MODULE_ENABLED + +/** @addtogroup APP_ALARM_DEFINES Macro definition + * @{ + */ + +/**@brief APP ALARM tag mask for user application. + */ +#define APP_ALARM_BASE 0x8000 + +/**@brief Get App Alarm tag for user application. + */ +#define APP_ALARM_ID(idx) (APP_ALARM_BASE | ((idx) & 0x7FFF)) + +/**@brief The maximum number of alarms. + */ +#define MAX_ALARM_SUPPORT 8 + +/**@brief App Alarm base year. + */ +#define APP_ALARM_BASE_YEAR (2000) + +/** @} */ + +/** @defgroup APP_ALARM Time + * @{ + */ + +/** + * @brief App time structure definition + */ +typedef calendar_time_t app_time_t; + +/** + * @brief App alarm structure definition + */ +typedef calendar_alarm_t app_alarm_t; + +/** + * @brief App alarm id definition + */ +typedef uint16_t app_alarm_id_t; + +/** @} */ + +/** @addtogroup APP_ALARM_STRUCTURES Event definition + * @{ + */ + +/** + *@brief The alarm node trigger function. + */ +typedef void (*app_alarm_fun_t)(app_alarm_id_t app_alarm_id); + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_ALARM_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP ALARM according to the specified parameters in the + * NvdsTag_t where the alram data is stored. + * + * @param[in] tag: Location where the alram data is stored. + * @param[in] callback: Pointer to alarm expire callback function + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_alarm_init(NvdsTag_t tag, app_alarm_fun_t callback); + +/** + **************************************************************************************** + * @brief De-initialize the app alarm. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_alarm_deinit(void); + +/** + **************************************************************************************** + * @brief Set a App alarm. + * + * @note if your call the app_alarm_set_time function, + * you should call this function after 1s. + * + * @param[in] alarm: After seconds will generate an alarm interrupt. + * @param[in] alarm_id: the id of alarm node. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_add(const calendar_alarm_t *alarm, app_alarm_id_t alarm_id); + +/** + **************************************************************************************** + * @brief Delete a App alarm from list. + * + * @param[in] alarm_id: the id of alarm node. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_del(app_alarm_id_t alarm_id); + +/** + **************************************************************************************** + * @brief Get current App time. + * + * @param[in] p_time: Pointer to a app time struction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_get_time(calendar_time_t *p_time); + +/** + **************************************************************************************** + * @brief Initialize the app time. + * + * @param[in] p_time: Pointer to a app time struction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_set_time(calendar_time_t *p_time); + +/** + **************************************************************************************** + * @brief Time synchronization function. + * + * @note If you reset system time, you should call this function again after 1s + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_reload(void); + +/** + **************************************************************************************** + * @brief Delete all App alarm from list. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_alarm_del_all(void); + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __APP_ALARM__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/BUILD.gn new file mode 100644 index 0000000..1ddc3ee --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_assert") { + sources = [ "app_assert.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.c old mode 100755 new mode 100644 index f0631d7..908f20e --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.c @@ -41,12 +41,13 @@ * INCLUDE FILES ***************************************************************************************** */ +#include "app_assert.h" +#include "app_log.h" #include #include #include #include -#include "app_log.h" -#include "app_assert.h" + /* * DEFINITIONS @@ -76,7 +77,8 @@ ***************************************************************************************** */ /**@brief Assert information save. */ -struct app_asser_info_t { +struct app_asser_info_t +{ char file_name[APP_ASSERT_FILE_NAME_LEN]; int magic1; int file_line; @@ -94,8 +96,9 @@ struct app_asser_info_t { */ static struct app_asser_info_t s_assert_info; -static sys_assert_cb_t s_assert_cbs = { - .assert_err_cb = app_assert_err_cb, +static sys_assert_cb_t s_assert_cbs = +{ + .assert_err_cb = app_assert_err_cb , .assert_param_cb = app_assert_param_cb, .assert_warn_cb = app_assert_warn_cb, }; @@ -114,28 +117,21 @@ static sys_assert_cb_t s_assert_cbs = { static void app_assert_info_output(uint8_t assert_type) { char assert_info[1024] = {0}; - uint32_t ret; s_assert_info.file_name[APP_ASSERT_FILE_NAME_LEN - 1] = ' '; s_assert_info.expr[APP_ASSERT_FILE_NAME_LEN - 1] = ' '; - if (assert_type == APP_ASSERT_ERROR) { - ret = sprintf_s(assert_info, sizeof(assert_info), "[ERROR] %s", s_assert_info.expr); - if (ret < 0) { - return; - } - } else if (assert_type == APP_ASSERT_WARNING) { - ret = sprintf_s(assert_info, sizeof(assert_info), "[WARNING] Param0:%d,Param1:%d", s_assert_info.param0, - s_assert_info.param1); - if (ret < 0) { - return; - } - } else if (assert_type == APP_ASSERT_PARAM) { - ret = sprintf_s(assert_info, sizeof(assert_info), "[PARAM] Param0:%d,Param1:%d", \ - s_assert_info.param0, s_assert_info.param1); - if (ret < 0) { - return; - } + if (APP_ASSERT_ERROR == assert_type) + { + sprintf(assert_info,"[ERROR] %s", s_assert_info.expr); + } + else if (APP_ASSERT_WARNING == assert_type) + { + sprintf(assert_info,"[WARNING] Param0:%d,Param1:%d", s_assert_info.param0, s_assert_info.param1); + } + else if (APP_ASSERT_PARAM == assert_type) + { + sprintf(assert_info,"[PARAM] Param0:%d,Param1:%d", s_assert_info.param0, s_assert_info.param1); } app_log_output(APP_LOG_LVL_ERROR, @@ -160,8 +156,8 @@ __WEAK void app_assert_warn_cb(int param0, int param1, const char *file, int lin file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file); - memset_s(&s_assert_info, sizeof(s_assert_info), 0, sizeof(s_assert_info)); - memcpy_s(s_assert_info.file_name, sizeof (s_assert_info.file_name), file, file_name_len); + memset(&s_assert_info, 0, sizeof(s_assert_info)); + memcpy(s_assert_info.file_name, file, file_name_len); s_assert_info.magic1 = APP_ASSERT_WARN_MAGIC_1; s_assert_info.file_line = line; @@ -177,14 +173,14 @@ __WEAK void app_assert_warn_cb(int param0, int param1, const char *file, int lin __WEAK void app_assert_param_cb(int param0, int param1, const char *file, int line) { - __disable_irq(); + __disable_irq(); uint32_t file_name_len; file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file); - memset_s(&s_assert_info, sizeof (s_assert_info), 0, sizeof(s_assert_info)); - memcpy_s(s_assert_info.file_name, sizeof (s_assert_info.file_name), file, file_name_len); + memset(&s_assert_info, 0, sizeof(s_assert_info)); + memcpy(s_assert_info.file_name, file, file_name_len); s_assert_info.magic1 = (int)APP_ASSERT_PARAM_MAGIC_1; s_assert_info.file_line = line; @@ -196,13 +192,13 @@ __WEAK void app_assert_param_cb(int param0, int param1, const char *file, int li // Also can store assert info to flash app_assert_info_output(APP_ASSERT_PARAM); - while (1) { - }; + + while(1); } __WEAK void app_assert_err_cb(const char *expr, const char *file, int line) { - __disable_irq(); + __disable_irq(); uint32_t file_name_len; uint32_t expre_len; @@ -210,9 +206,10 @@ __WEAK void app_assert_err_cb(const char *expr, const char *file, int line) file_name_len = (APP_ASSERT_FILE_NAME_LEN < strlen(file)) ? APP_ASSERT_FILE_NAME_LEN : strlen(file); expre_len = (APP_ASSERT_EXPR_NAME_LEN < strlen(expr)) ? APP_ASSERT_EXPR_NAME_LEN : strlen(expr); - memset_s(&s_assert_info, sizeof(s_assert_info), 0, sizeof(s_assert_info)); - memcpy_s(s_assert_info.file_name, sizeof(s_assert_info.file_name), file, file_name_len); - memcpy_s(s_assert_info.expr, sizeof(s_assert_info.expr), expr, expre_len); + memset(&s_assert_info, 0, sizeof(s_assert_info)); + memcpy(s_assert_info.file_name, file, file_name_len); + memcpy(s_assert_info.expr, expr, expre_len); + s_assert_info.magic1 = (int)APP_ASSERT_ERR_MAGIC_1; s_assert_info.file_line = line; s_assert_info.magic2 = (int)APP_ASSERT_ERR_MAGIC_2; @@ -221,8 +218,7 @@ __WEAK void app_assert_err_cb(const char *expr, const char *file, int line) // Also can store assert info to flash app_assert_info_output(APP_ASSERT_ERROR); - while (1) { - }; + while(1); } void app_assert_init(void) @@ -232,7 +228,10 @@ void app_assert_init(void) void app_assert_handler(const char *expr, const char *file, int line) { - if (s_assert_cbs.assert_err_cb) { + if (s_assert_cbs.assert_err_cb) + { s_assert_cbs.assert_err_cb(expr, file, line); } } + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.h old mode 100755 new mode 100644 index c648f83..45bb084 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_assert/app_assert.h @@ -38,8 +38,8 @@ #ifndef __APP_ASSERT_H__ #define __APP_ASSERT_H__ +#include "grx_sys.h" #include -#include "gr55xx_sys.h" /** * @defgroup APP_ASSERT_MAROC Defines @@ -53,7 +53,7 @@ { \ app_assert_handler(#EXPR, __FILE__, __LINE__); \ } \ - } while (0) + } while(0) /** @} */ /** @@ -112,6 +112,11 @@ void app_assert_param_cb(int param0, int param1, const char *file, int line); ***************************************************************************************** */ void app_assert_err_cb(const char *expr, const char *file, int line); + + /** @} */ -#endif \ No newline at end of file +#endif + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/BUILD.gn new file mode 100644 index 0000000..3aa079a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_error") { + sources = [ + "app_error.c", + "cortex_backtrace.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.c old mode 100755 new mode 100644 index 107975c..639f5cf --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.c @@ -41,26 +41,27 @@ * INCLUDE FILES ***************************************************************************************** */ +#include "app_error.h" +#include "app_error_cfg.h" +#include "app_log.h" #include #include #include -#include "app_error_cfg.h" -#include "app_log.h" -#include "app_error.h" /* * DEFINITIONS ***************************************************************************************** */ #define APP_ERROR_INFO_LEN 512 -#define APP_ERROR_CODE_NB 43 +#define APP_ERROR_CODE_NB 46 /* * STRUCTURES ***************************************************************************************** */ /**@brief SDK error code information. */ -typedef struct { +typedef struct +{ sdk_err_t error_code; char *error_info; } error_code_info_t; @@ -69,8 +70,10 @@ typedef struct { * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -#ifndef GR5515_E -static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] = { +static char s_error_print_info[APP_ERROR_INFO_LEN] = { 0 }; + +static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] = +{ {SDK_SUCCESS, "Successful."}, {SDK_ERR_INVALID_PARAM, "Invalid parameter supplied."}, {SDK_ERR_POINTER_NULL, "Invalid pointer supplied."}, @@ -114,10 +117,11 @@ static error_code_info_t s_error_code_info[APP_ERROR_CODE_NB] = { {SDK_ERR_INVALID_CID, "Invalid CID supplied."}, {SDK_ERR_INVALID_CHL_NUM, "Invalid channel number supplied."}, {SDK_ERR_NOT_ENOUGH_CREDITS, "Not enough credits."}, + {SDK_ERR_REPEAT_CID, "Invalid repeat CID."}, + {SDK_ERR_CACHE_NOT_ENABLE, "Cache feature is not enabled."}, + {SDK_ERR_CACHE_INVALID, "Cache data is invalid."}, }; -#else -static error_code_info_t s_error_code_info[]; -#endif + /* * GLOBAL FUNCTION DEFINITIONS @@ -126,36 +130,34 @@ static error_code_info_t s_error_code_info[]; __WEAK void app_error_fault_handler(app_error_info_t *p_error_info) { #if APP_ERROR_INFO_PRINT_ENABLE - uint32_t ret; - char s_error_print_info[APP_ERROR_INFO_LEN]; - ret = memset_s(s_error_print_info, sizeof(s_error_print_info), 0, APP_ERROR_INFO_LEN); - if (ret < 0) { - return; - } + memset(s_error_print_info, 0, APP_ERROR_INFO_LEN); - if (APP_ERROR_API_RET == p_error_info->error_type) { - for (uint8_t i = 0; ; i++) { - if (p_error_info->value.error_code == s_error_code_info[i].error_code) { - ret = sprintf_s(s_error_print_info, sizeof (s_error_print_info), - "Error code 0x%04X: %s", - p_error_info->value.error_code, - s_error_code_info[i].error_info); + if (APP_ERROR_API_RET == p_error_info->error_type) + { + for (uint8_t i = 0; ; i++) + { + if (p_error_info->value.error_code == s_error_code_info[i].error_code) + { + sprintf(s_error_print_info, + "Error code 0x%04X: %s", + p_error_info->value.error_code, + s_error_code_info[i].error_info); break; - } else if (i == APP_ERROR_CODE_NB) { - ret = sprintf_s(s_error_print_info, sizeof(s_error_print_info), \ - "Error code 0x%04X: No found information.", p_error_info->value.error_code); + } + else if (APP_ERROR_CODE_NB == i) + { + sprintf(s_error_print_info, "Error code 0x%04X: No found information.", p_error_info->value.error_code); break; } } - } else if (APP_ERROR_BOOL_COMPARE == p_error_info->error_type) { - ret = sprintf_s(s_error_print_info, sizeof(s_error_print_info), - "(%s) is not established.", - p_error_info->value.expr); + } + else if (APP_ERROR_BOOL_COMPARE == p_error_info->error_type) + { + sprintf(s_error_print_info, + "(%s) is not established.", + p_error_info->value.expr); } - if (ret < 0) { - return; - } app_log_output(APP_LOG_LVL_ERROR, APP_LOG_TAG, p_error_info->file, diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.h old mode 100755 new mode 100644 index c50b987..8764158 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error.h @@ -38,8 +38,8 @@ #ifndef __APP_ERROR_H__ #define __APP_ERROR_H__ -#include #include "ble_error.h" +#include /** * @defgroup APP_ERROR_MAROC Defines @@ -48,32 +48,39 @@ /**@brief Macro for calling error handler function if supplied error code isn`t GR_SUCCESS. */ #define APP_ERROR_CHECK(ERROR_CODE) \ - do { \ - if ((ERROR_CODE) != SDK_SUCCESS) { \ - app_error_info_t error_info = { \ + do \ + { \ + if (ERROR_CODE != SDK_SUCCESS) \ + { \ + app_error_info_t error_info = \ + { \ .error_type = APP_ERROR_API_RET, \ - .value.error_code = (ERROR_CODE), \ + .value.error_code = ERROR_CODE, \ .file = __FILE__, \ .func = __FUNCTION__, \ .line = __LINE__, \ }; \ app_error_fault_handler(&error_info); \ } \ - } while (0) + } while(0) /**@brief Macro for calling error handler function if supplied boolean value is false. */ #define APP_BOOL_CHECK(BOOL_VAL) \ - do { \ - if (!(BOOL_VAL)) { \ - app_error_info_t error_info = { \ + do \ + { \ + if (!BOOL_VAL) \ + { \ + app_error_info_t error_info = \ + { \ .error_type = APP_ERROR_BOOL_COMPARE, \ .value.expr = #BOOL_VAL, \ - .file = __FILE__, \ - .func = __FUNCTION__, .line = __LINE__, \ + .file = __FILE__, \ + .func = __FUNCTION__, \ + .line = __LINE__, \ }; \ app_error_fault_handler(&error_info); \ } \ - } while (0) + } while(0) /** @} */ /** @@ -81,7 +88,8 @@ * @{ */ /**@brief App error check type.*/ -typedef enum { +typedef enum +{ APP_ERROR_API_RET, /**< API return error code check failed. */ APP_ERROR_BOOL_COMPARE, /**< Bool value check failed. */ } app_error_type_t; @@ -92,9 +100,11 @@ typedef enum { * @{ */ /**@brief App error info.*/ -typedef struct { +typedef struct +{ app_error_type_t error_type; /**< Error occurred type. */ - union { + union + { sdk_err_t error_code; /**< Error code. */ char const *expr; /**< Error expression. */ } value; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error_cfg.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error_cfg.h old mode 100755 new mode 100644 index 91a5a63..00658df --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error_cfg.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/app_error_cfg.h @@ -38,10 +38,10 @@ #ifndef __APP_ERROR_CFG_H__ #define __APP_ERROR_CFG_H__ +#include "grx_sys.h" #include #include #include -#include "gr55xx.h" /** * @defgroup APP_ERROR_CFG_MAROC Defines @@ -49,22 +49,20 @@ */ #define APP_IS_USING_FREEROTS false /**< Is using FREEROTS or not. */ #define APP_ERROR_DUMP_STACK_INFO_ENABLE 1 /**< Enable dump stack information. */ -/**< Enable error information prinf. */ -#define APP_ERROR_INFO_PRINT_ENABLE 1 -/**< Supported function call stack max depth, default is 16. */ -#define APP_ERROR_CALL_STACK_DEPTH_MAX 16 +#define APP_ERROR_INFO_PRINT_ENABLE 1 /**< Enable error information prinf. */ +#define APP_ERROR_CALL_STACK_DEPTH_MAX 16 /**< Supported function call stack max depth, default is 16. */ #if APP_ERROR_INFO_PRINT_ENABLE -#define APP_ERROR_INFO_PRINT(...) printf(__VA_ARGS__);printf("\r\n") /**< Print line. */ + #define APP_ERROR_INFO_PRINT(...) printf(__VA_ARGS__);printf("\r\n");/**< Print line. */ #else -#define APP_ERROR_INFO_PRINT(...) + #define APP_ERROR_INFO_PRINT(...) #endif #if APP_IS_USING_FREEROTS -#include "FreeRTOS.h" -extern uint32_t *vTaskStackAddr(void); -extern uint32_t vTaskStackSize(void); -extern char *vTaskName(void); + #include "FreeRTOS.h" + extern uint32_t *vTaskStackAddr(void); + extern uint32_t vTaskStackSize(void); + extern char *vTaskName(void); #endif /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.c old mode 100755 new mode 100644 index 9d66f4d..5a2c958 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.c @@ -39,17 +39,19 @@ * INCLUDE FILES ***************************************************************************************** */ +#include "cortex_backtrace.h" +#include "app_error.h" +#include "fault_trace.h" #include "app_assert.h" #include "app_log.h" +#include +#include + #if ENABLE_BACKTRACE_FEA -#define CALL_STACK_INFO_CNT 11 -#define BIT_8 8 -#define BIT_9 9 -#define BIT_10 10 #if __STDC_VERSION__ < 199901L -#error "must be C99 or higher. try to add '-std=c99' to compile parameters" + #error "must be C99 or higher. try to add '-std=c99' to compile parameters" #endif /* @@ -64,81 +66,106 @@ #endif #ifdef ENV_USE_FREERTOS -#include "FreeRTOS.h" -#include "task.h" -#define APP_IS_USING_FREEROTS 1 + #include "FreeRTOS.h" + #include "task.h" + #define APP_IS_USING_FREEROTS 1 #endif #ifndef SYS_FAULT_TRACE_MODE -#define SYS_FAULT_TRACE_MODE 1 + #define SYS_FAULT_TRACE_MODE 3 #endif +//----------------------------------------------------------------------------------------------- #define NVDS_FAULT_INFO_LEN_MAX (1024) static char s_fault_info_nvds[NVDS_FAULT_INFO_LEN_MAX] = {0}; static uint32_t s_fault_info_nvds_len = 0; -void fault_trace_nvds_save_prepare(void) +void __fault_trace_nvds_save_prepare(void) { - memset_s(s_fault_info_nvds, NVDS_FAULT_INFO_LEN_MAX, 0, NVDS_FAULT_INFO_LEN_MAX); + memset(s_fault_info_nvds, 0, NVDS_FAULT_INFO_LEN_MAX); s_fault_info_nvds_len = 0; } -void fault_trace_nvds_add(const char *format, ...) +void __fault_trace_nvds_add(const char *format, ...) { - int ret; - int INFO_OFFSET = 100; - - if (s_fault_info_nvds_len + INFO_OFFSET >= NVDS_FAULT_INFO_LEN_MAX) + if (s_fault_info_nvds_len + 100 >= NVDS_FAULT_INFO_LEN_MAX) return; va_list argx; - va_start(argx, format); - ret = vsprintf_s(s_fault_info_nvds+s_fault_info_nvds_len, NVDS_FAULT_INFO_LEN_MAX, format, argx); - if (ret < 0) { - return; - } + va_start(argx,format); + vsprintf(s_fault_info_nvds+s_fault_info_nvds_len,format,argx); va_end(argx); s_fault_info_nvds_len = strlen(s_fault_info_nvds); } -void fault_trace_nvds_save_flush(void) +void __fault_trace_nvds_save_flush(void) { fault_db_record_add((uint8_t *)s_fault_info_nvds, s_fault_info_nvds_len); } - -#if SYS_FAULT_TRACE_MODE == 1 // only UART Print -#define FAULT_TRACE_OUTPUT_PREPARE() -#define FAULT_TRACE_OUTPUT(format, ...) APP_ERROR_INFO_PRINT(format, ##__VA_ARGS__) -#define FAULT_TRACE_OUTPUT_FLUSH() app_log_flush() -#elif SYS_FAULT_TRACE_MODE == 2 // only Save to NVDS -#define FAULT_TRACE_OUTPUT_PREPARE() fault_trace_db_init();fault_trace_nvds_save_prepare() -#define FAULT_TRACE_OUTPUT(format, ...) do { - fault_trace_nvds_add(format, ##__VA_ARGS__); \ - fault_trace_nvds_add("\r\n")ï¼› - } while (0) -#define FAULT_TRACE_OUTPUT_FLUSH() fault_trace_nvds_save_flush() +//-------------------------------------------------------------------------------------- +#if SYS_FAULT_TRACE_MODE == 1 //only UART Print + #define __FAULT_TRACE_OUTPUT_PREPARE() + #define __FAULT_TRACE_OUTPUT(format, ...) APP_ERROR_INFO_PRINT(format,##__VA_ARGS__) + #define __FAULT_TRACE_OUTPUT_FLUSH() app_log_flush() +#elif SYS_FAULT_TRACE_MODE == 2 //only Save to NVDS + #define __FAULT_TRACE_OUTPUT_PREPARE() fault_trace_db_init();__fault_trace_nvds_save_prepare() + #define __FAULT_TRACE_OUTPUT(format, ...) __fault_trace_nvds_add(format,##__VA_ARGS__);__fault_trace_nvds_add("\r\n") + #define __FAULT_TRACE_OUTPUT_FLUSH() __fault_trace_nvds_save_flush() #elif SYS_FAULT_TRACE_MODE == 3 // UART Print and Save to NVDS -#define FAULT_TRACE_OUTPUT_PREPARE() fault_trace_db_init();fault_trace_nvds_save_prepare() -#define FAULT_TRACE_OUTPUT(format, ...) do { - APP_ERROR_INFO_PRINT(format, ##__VA_ARGS__); \ - fault_trace_nvds_add(format, ##__VA_ARGS__); \ - fault_trace_nvds_add("\r\n"); \ - } while (0) -#define FAULT_TRACE_OUTPUT_FLUSH() do { - app_log_flush(); \ - fault_trace_nvds_save_flush(); \ - } while (0) + #define __FAULT_TRACE_OUTPUT_PREPARE() fault_trace_db_init();__fault_trace_nvds_save_prepare() + #define __FAULT_TRACE_OUTPUT(format, ...) APP_ERROR_INFO_PRINT(format,##__VA_ARGS__); \ + __fault_trace_nvds_add(format,##__VA_ARGS__);__fault_trace_nvds_add("\r\n") + #define __FAULT_TRACE_OUTPUT_FLUSH() app_log_flush(); \ + __fault_trace_nvds_save_flush() #else -#define FAULT_TRACE_OUTPUT_PREPARE() -#define FAULT_TRACE_OUTPUT(...) -#define FAULT_TRACE_OUTPUT_FLUSH() + #define __FAULT_TRACE_OUTPUT_PREPARE() + #define __FAULT_TRACE_OUTPUT(...) + #define __FAULT_TRACE_OUTPUT_FLUSH() +#endif + +#if defined(__CC_ARM) + #define CSTACK_BLOCK_NAME ARM_LIB_STACK /**< C stack block name: ARM_LIB_STACKHEAP. */ + #define CODE_SECTION_NAME FLASH_CODE /**< Code section name: ER_FLASH. */ + + #define SECTION_START(_name_) _name_##$$Base + #define SECTION_END(_name_) _name_##$$Limit + #define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base + #define IMAGE_SECTION_END(_name_) Image$$##_name_##$$ZI$$Limit + #define CSTACK_BLOCK_START(_name_) IMAGE_SECTION_START(_name_) + #define CSTACK_BLOCK_END(_name_) IMAGE_SECTION_END(_name_) + #define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_) + #define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_) + + extern const int CSTACK_BLOCK_START(CSTACK_BLOCK_NAME); + extern const int CSTACK_BLOCK_END(CSTACK_BLOCK_NAME); + extern const int CODE_SECTION_START(CODE_SECTION_NAME); + extern const int CODE_SECTION_END(CODE_SECTION_NAME); +#elif defined(__ICCARM__) + #define CSTACK_BLOCK_NAME "CSTACK" /**< C stack block name, default is 'CSTACK'. */ + #define CODE_SECTION_NAME ".text" /**< Code section name, default is '.text'. */ + + #pragma section = CMB_CSTACK_BLOCK_NAME + #pragma section = CMB_CODE_SECTION_NAME +#elif defined(__GNUC__) + #define CSTACK_BLOCK_START __sstack /**< C stack block start address, defined on linker script file, default is _sstack. */ + #define CSTACK_BLOCK_END __estack /**< C stack block end address, defined on linker script file, default is _estack. */ + #define CODE_SECTION_START __stext /**< code section start address, defined on linker script file, default is _stext. */ + #define CODE_SECTION_END __etext /**< code section end address, defined on linker script file, default is _etext. */ + + extern const int CSTACK_BLOCK_START; + extern const int CSTACK_BLOCK_END; + extern const int CODE_SECTION_START; + extern const int CODE_SECTION_END; +#else + #error "not supported compiler" #endif /* * STRUCTURE ***************************************************************************************** */ -typedef struct { +typedef struct +{ uint32_t code_start_addr; uint32_t code_end_addr; } code_section_info_t; @@ -147,7 +174,8 @@ typedef struct { * ENUMERATION ***************************************************************************************** */ -enum { +enum +{ CB_PRINT_ASSERT_ON_THREAD, CB_PRINT_ASSERT_ON_HANDLER, CB_PRINT_THREAD_STACK_INFO, @@ -190,58 +218,59 @@ enum { * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static const char * const s_print_info[] = { - [CB_PRINT_ASSERT_ON_THREAD] = "Assert on thread %s", - [CB_PRINT_ASSERT_ON_HANDLER] = "Assert on interrupt or bare metal(no OS) environment", - [CB_PRINT_THREAD_STACK_INFO] = "=== Thread stack information ===", - [CB_PRINT_MAIN_STACK_INFO] = "==== Main stack information ====", - [CB_PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow", - [CB_PRINT_MAIN_STACK_OVERFLOW] = "Error: Main stack(%08x) was overflow", - [CB_PRINT_CALL_STACK_INFO] = "Call stack info : %.*s", - [CB_PRINT_CALL_STACK_ERR] = "Dump call stack has an error", - [CB_PRINT_FAULT_ON_THREAD] = "Fault on thread %s", - [CB_PRINT_FAULT_ON_HANDLER] = "Fault on interrupt or bare metal(no OS) environment", - [CB_PRINT_REGS_TITLE] = "==== Registers information =====", - [CB_PRINT_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch", - [CB_PRINT_MFSR_IACCVIOL] = "Memory management: instruction access violation", - [CB_PRINT_MFSR_DACCVIOL] = "Memory management: data access violation", - [CB_PRINT_MFSR_MUNSTKERR] = "Memory management: unstacking error", - [CB_PRINT_MFSR_MSTKERR] = "Memory management: stacking error", - [CB_PRINT_MFSR_MLSPERR] = "Memory management: floating-point lazy state preservation", - [CB_PRINT_BFSR_IBUSERR] = "Bus fault: instruction access violation", - [CB_PRINT_BFSR_PRECISERR] = "Bus fault: precise data access violation", - [CB_PRINT_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation", - [CB_PRINT_BFSR_UNSTKERR] = "Bus fault: unstacking error", - [CB_PRINT_BFSR_STKERR] = "Bus fault: stacking error", - [CB_PRINT_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation", - [CB_PRINT_UFSR_UNDEFINSTR] = "Usage fault: attempts to execute an undefined instruction", - [CB_PRINT_UFSR_INVSTATE] = "Usage fault: attempts to switch to an invalid state (e.g., ARM)", - [CB_PRINT_UFSR_INVPC] = "Usage fault: \ - attempts to do an exception with a bad value in the EXC_RETURN number", - [CB_PRINT_UFSR_NOCP] = "Usage fault: attempts to execute a coprocessor instruction", - [CB_PRINT_UFSR_UNALIGNED] = "Usage fault: indicates that an unaligned access fault has taken place", - [CB_PRINT_UFSR_DIVBYZERO0] = "Usage fault: Indicates a divide by zero has taken place \ - (can be set only if DIV_0_TRP is set)", - [CB_PRINT_DFSR_HALTED] = "Debug fault: halt requested in NVIC", - [CB_PRINT_DFSR_BKPT] = "Debug fault: BKPT instruction executed", - [CB_PRINT_DFSR_DWTTRAP] = "Debug fault: DWT match occurred", - [CB_PRINT_DFSR_VCATCH] = "Debug fault: Vector fetch occurred", - [CB_PRINT_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted", - [CB_PRINT_MMAR] = "The memory management fault occurred address is %08x", - [CB_PRINT_BFAR] = "The bus fault occurred address is %08x", +static const char * const s_print_info[] = +{ + [CB_PRINT_ASSERT_ON_THREAD] = "Assert on thread %s", + [CB_PRINT_ASSERT_ON_HANDLER] = "Assert on interrupt or bare metal(no OS) environment", + [CB_PRINT_THREAD_STACK_INFO] = "=== Thread stack information ===", + [CB_PRINT_MAIN_STACK_INFO] = "==== Main stack information ====", + [CB_PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow", + [CB_PRINT_MAIN_STACK_OVERFLOW] = "Error: Main stack(%08x) was overflow", + [CB_PRINT_CALL_STACK_INFO] = "Call stack info : %.*s", + [CB_PRINT_CALL_STACK_ERR] = "Dump call stack has an error", + [CB_PRINT_FAULT_ON_THREAD] = "Fault on thread %s", + [CB_PRINT_FAULT_ON_HANDLER] = "Fault on interrupt or bare metal(no OS) environment", + [CB_PRINT_REGS_TITLE] = "==== Registers information =====", + [CB_PRINT_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch", + [CB_PRINT_MFSR_IACCVIOL] = "Memory management: instruction access violation", + [CB_PRINT_MFSR_DACCVIOL] = "Memory management: data access violation", + [CB_PRINT_MFSR_MUNSTKERR] = "Memory management: unstacking error", + [CB_PRINT_MFSR_MSTKERR] = "Memory management: stacking error", + [CB_PRINT_MFSR_MLSPERR] = "Memory management: floating-point lazy state preservation", + [CB_PRINT_BFSR_IBUSERR] = "Bus fault: instruction access violation", + [CB_PRINT_BFSR_PRECISERR] = "Bus fault: precise data access violation", + [CB_PRINT_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation", + [CB_PRINT_BFSR_UNSTKERR] = "Bus fault: unstacking error", + [CB_PRINT_BFSR_STKERR] = "Bus fault: stacking error", + [CB_PRINT_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation", + [CB_PRINT_UFSR_UNDEFINSTR] = "Usage fault: attempts to execute an undefined instruction", + [CB_PRINT_UFSR_INVSTATE] = "Usage fault: attempts to switch to an invalid state (e.g., ARM)", + [CB_PRINT_UFSR_INVPC] = "Usage fault: attempts to do an exception with a bad value in the EXC_RETURN number", + [CB_PRINT_UFSR_NOCP] = "Usage fault: attempts to execute a coprocessor instruction", + [CB_PRINT_UFSR_UNALIGNED] = "Usage fault: indicates that an unaligned access fault has taken place", + [CB_PRINT_UFSR_DIVBYZERO0] = "Usage fault: Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)", + [CB_PRINT_DFSR_HALTED] = "Debug fault: halt requested in NVIC", + [CB_PRINT_DFSR_BKPT] = "Debug fault: BKPT instruction executed", + [CB_PRINT_DFSR_DWTTRAP] = "Debug fault: DWT match occurred", + [CB_PRINT_DFSR_VCATCH] = "Debug fault: Vector fetch occurred", + [CB_PRINT_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted", + [CB_PRINT_MMAR] = "The memory management fault occurred address is %08x", + [CB_PRINT_BFAR] = "The bus fault occurred address is %08x", }; -static uint32_t s_main_stack_start_addr = ZERO; -static uint32_t s_main_stack_size = ZERO; +static uint32_t s_main_stack_start_addr = 0; +static uint32_t s_main_stack_size = 0; +//static uint32_t s_code_start_addr = 0; +//static uint32_t s_code_size = 0; static bool s_is_stack_overflow = false; static bool s_is_on_thread_before_fault = false; static bool s_is_on_fault = false; -static char s_call_stack_info[APP_ERROR_CALL_STACK_DEPTH_MAX * CALLBACK_CNT] = { ZERO }; +static char s_call_stack_info[APP_ERROR_CALL_STACK_DEPTH_MAX * (8 + 1)] = { 0 }; static cb_hard_fault_regs_t s_regs; -static uint32_t s_code_section_count = ZERO; +static uint32_t s_code_section_count = 0; static code_section_info_t s_code_section_infos[FAULT_CODE_SECTON_CNT_MAX]; /* @@ -251,45 +280,45 @@ static code_section_info_t s_code_section_infos[FAULT_CODE_SECTON_CNT_MAX]; /**@brief Include or export for supported cb_psp_get and cb_sp_get function */ #if APP_IS_USING_FREEROTS #if defined(__CC_ARM) -static __inline __asm uint32_t cb_psp_get(void) -{ - mrs r0, psp - bx lr -} -static __inline __asm uint32_t cb_sp_get(void) -{ - mov r0, sp - bx lr -} + static __inline __asm uint32_t cb_psp_get(void) + { + mrs r0, psp + bx lr + } + static __inline __asm uint32_t cb_sp_get(void) + { + mov r0, sp + bx lr + } #elif defined(__ICCARM__) // IAR iccarm specific functions Close Raw Asm Code Warning. #pragma diag_suppress=Pe940 -static uint32_t cb_psp_get(void) -{ - __asm("mrs r0, psp"); - __asm("bx lr"); -} -static uint32_t cb_sp_get(void) -{ - __asm("mov r0, sp"); - __asm("bx lr"); -} + static uint32_t cb_psp_get(void) + { + __asm("mrs r0, psp"); + __asm("bx lr"); + } + static uint32_t cb_sp_get(void) + { + __asm("mov r0, sp"); + __asm("bx lr"); + } #pragma diag_default=Pe940 #elif defined(__GNUC__) -__attribute__ ((always_inline)) static inline uint32_t cb_psp_get(void) -{ - register uint32_t result; - __asm volatile ("MRS %0, psp\n" : "=r" (result)); - return(result); -} -__attribute__ ((always_inline)) static inline uint32_t cb_sp_get(void) -{ - register uint32_t result; - __asm volatile ("MOV %0, sp\n" : "=r" (result)); - return(result); -} + __attribute__( ( always_inline ) ) static inline uint32_t cb_psp_get(void) + { + register uint32_t result; + __asm volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); + } + __attribute__( ( always_inline ) ) static inline uint32_t cb_sp_get(void) + { + register uint32_t result; + __asm volatile ("MOV %0, sp\n" : "=r" (result) ); + return(result); + } #else -#error "not supported compiler" + #error "not supported compiler" #endif #endif @@ -305,8 +334,11 @@ __attribute__ ((always_inline)) static inline uint32_t cb_sp_get(void) */ static void cb_cur_thread_stack_info_get(uint32_t sp, uint32_t *p_start_addr, uint32_t *p_stack_size) { +// APP_ASSERT_CHECK(p_start_addr); +// APP_ASSERT_CHECK(p_stack_size); + *p_start_addr = (uint32_t)vTaskStackAddr(); - *p_stack_size = vTaskStackSize() * sizeof(StackType_t); + *p_stack_size = vTaskStackSize() * sizeof( StackType_t ); } /** @@ -332,449 +364,523 @@ static const char *cb_cur_thread_name_get(void) */ static void cb_stack_info_dump(uint32_t stack_start_addr, uint32_t stack_size, uint32_t *p_stack) { - if (s_is_stack_overflow) { - if (s_is_on_thread_before_fault) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_THREAD_STACK_OVERFLOW], p_stack); - } else { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MAIN_STACK_OVERFLOW], p_stack); + if (s_is_stack_overflow) + { + if (s_is_on_thread_before_fault) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_THREAD_STACK_OVERFLOW], p_stack); + } + else + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MAIN_STACK_OVERFLOW], p_stack); } - if ((uint32_t)p_stack < stack_start_addr) { + if ((uint32_t)p_stack < stack_start_addr) + { p_stack = (uint32_t *)stack_start_addr; - } else if ((uint32_t) p_stack > stack_start_addr + stack_size) { + } + else if ((uint32_t) p_stack > stack_start_addr + stack_size) + { p_stack = (uint32_t *)(stack_start_addr + stack_size); } - } else { - if (s_is_on_thread_before_fault) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_THREAD_STACK_INFO]); - } else { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MAIN_STACK_INFO]); + } + else + { + if (s_is_on_thread_before_fault) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_THREAD_STACK_INFO]); + } + else + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MAIN_STACK_INFO]); } } - for (; (uint32_t)p_stack < stack_start_addr + stack_size; p_stack++) { - FAULT_TRACE_OUTPUT(" addr: %08x data: %08x", p_stack, *p_stack); + for (; (uint32_t)p_stack < stack_start_addr + stack_size; p_stack++) + { + __FAULT_TRACE_OUTPUT(" addr: %08x data: %08x", p_stack, *p_stack); app_log_flush(); } - FAULT_TRACE_OUTPUT("========="); + __FAULT_TRACE_OUTPUT("========="); } #endif #if (__CORTEX_M != CB_CPU_ARM_CORTEX_M0) - -void deal_mvalue(void) -{ - // Memory Management Fault. - if (s_regs.mfsr.bits.IACCVIOL) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_IACCVIOL]); - } - - if (s_regs.mfsr.bits.DACCVIOL) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_DACCVIOL]); - } - - if (s_regs.mfsr.bits.MUNSTKERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MUNSTKERR]); - } - - if (s_regs.mfsr.bits.MSTKERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MSTKERR]); - } - -#if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) - if (s_regs.mfsr.bits.MLSPERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MLSPERR]); - } -#endif - if (s_regs.mfsr.bits.MMARVALID) { - if ((s_regs.mfsr.bits.IACCVIOL) || (s_regs.mfsr.bits.DACCVIOL)) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MMAR], s_regs.mmar); - } - } -} - -void deal_bvalue(void) -{ - if (s_regs.bfsr.bits.IBUSERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_IBUSERR]); - } - - if (s_regs.bfsr.bits.PRECISERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_PRECISERR]); - } - - if (s_regs.bfsr.bits.IMPREISERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_IMPREISERR]); - } - - if (s_regs.bfsr.bits.UNSTKERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_UNSTKERR]); - } - - if (s_regs.bfsr.bits.STKERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_STKERR]); - } - -#if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) - if (s_regs.bfsr.bits.LSPERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_LSPERR]); - } -#endif - - if (s_regs.bfsr.bits.BFARVALID) { - if (s_regs.bfsr.bits.PRECISERR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFAR], s_regs.bfar); - } - } -} - -void deal_uvalue(void) -{ - if (s_regs.ufsr.bits.UNDEFINSTR) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_UNDEFINSTR]); - } - - if (s_regs.ufsr.bits.INVSTATE) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_INVSTATE]); - } - - if (s_regs.ufsr.bits.INVPC) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_INVPC]); - } - - if (s_regs.ufsr.bits.NOCP) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_NOCP]); - } - - if (s_regs.ufsr.bits.UNALIGNED) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_UNALIGNED]); - } - - if (s_regs.ufsr.bits.DIVBYZERO0) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_DIVBYZERO0]); - } -} - -void deal_dvalue(void) -{ - if (s_regs.dfsr.bits.HALTED) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_HALTED]); - } - - if (s_regs.dfsr.bits.BKPT) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_BKPT]); - } - - if (s_regs.dfsr.bits.DWTTRAP) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_DWTTRAP]); - } - - if (s_regs.dfsr.bits.VCATCH) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_VCATCH]); - } - - if (s_regs.dfsr.bits.EXTERNAL) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_EXTERNAL]); - } -} - /** ***************************************************************************************** - * Fault diagnosis then print cause of fault - ***************************************************************************************** - */ + * Fault diagnosis then print cause of fault + ***************************************************************************************** + */ static void cb_fault_diagnosis(void) { - FAULT_TRACE_OUTPUT("Fault reason:"); + __FAULT_TRACE_OUTPUT("Fault reason:"); - if (s_regs.hfsr.bits.VECTBL) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_HFSR_VECTBL]); + if (s_regs.hfsr.bits.VECTBL) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_HFSR_VECTBL]); } - if (s_regs.hfsr.bits.FORCED) { + if (s_regs.hfsr.bits.FORCED) + { // Memory Management Fault. - if (s_regs.mfsr.value) { - deal_mvalue(); - } - // Bus Fault - if (s_regs.bfsr.value) { - deal_bvalue(); - } - // Usage Fault - if (s_regs.ufsr.value) { - deal_uvalue(); - } - } + if (s_regs.mfsr.value) + { + if (s_regs.mfsr.bits.IACCVIOL) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_IACCVIOL]); + } - // Debug Fault - if (s_regs.hfsr.bits.DEBUGEVT) { - if (s_regs.dfsr.value) { - deal_dvalue(); - } - } -} -#endif + if (s_regs.mfsr.bits.DACCVIOL) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_DACCVIOL]); + } + + if (s_regs.mfsr.bits.MUNSTKERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MUNSTKERR]); + } + + if (s_regs.mfsr.bits.MSTKERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MSTKERR]); + } #if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) -#define FPSCR_OFFSET 18 - static uint32_t cb_statck_fpu_reg_del(uint32_t fault_handler_lr, uint32_t sp) - { - bool statck_has_fpu_regs = (fault_handler_lr & (1UL << 4)) == 0 ? true : false; - - // The stack has S0~S15 and FPSCR registers when statck_has_fpu_regs is true, double word align. - return statck_has_fpu_regs == true ? sp + sizeof(size_t) * FPSCR_OFFSET : sp; - } + if (s_regs.mfsr.bits.MLSPERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MFSR_MLSPERR]); + } #endif - static uint32_t cb_backtrace_call_stack_depth(uint32_t *p_buffer, uint32_t size, uint32_t sp) - { - uint32_t stack_start_addr = s_main_stack_start_addr; - uint32_t depth = 0; - uint32_t stack_size = s_main_stack_size; - uint32_t pc; - uint32_t i; - - if (s_is_stack_overflow) { - if (sp < stack_start_addr) { - sp = stack_start_addr; - } else if (sp > stack_start_addr + stack_size) { - sp = stack_start_addr + stack_size; - } - } - // Copy called function address. - for (; sp < stack_start_addr + stack_size; sp += sizeof(uint32_t)) { - // The *sp value may be LR, so need decrease a word to PC. - pc = *((uint32_t *)sp) - sizeof(uint32_t); - - // The Cortex-M using thumb instruction, so the pc must be an odd number. - if (pc % TWO == 0) { - continue; - } - - for (i = 0; i < s_code_section_count; i++) { - if ((pc >= (s_code_section_infos[i].code_start_addr)) && \ - (pc <= (s_code_section_infos[i].code_end_addr)) && \ - (depth < APP_ERROR_CALL_STACK_DEPTH_MAX) && \ - (depth < size) && \ - ((depth != TWO) || (!is_regs_saved_lr_valid) || (pc != p_buffer[1]))) { - // The second depth function may be already saved, so need ignore repeat. - p_buffer[depth++] = pc; - } else if ((depth == TWO) && is_regs_saved_lr_valid && (pc == p_buffer[1])) { - continue; + if (s_regs.mfsr.bits.MMARVALID) + { + if (s_regs.mfsr.bits.IACCVIOL || s_regs.mfsr.bits.DACCVIOL) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_MMAR], s_regs.mmar); } } } - return depth; - } + //Bus Fault + if (s_regs.bfsr.value) + { + if (s_regs.bfsr.bits.IBUSERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_IBUSERR]); + } - /** - ***************************************************************************************** - * Backtrace function call stack - * - * @param[in] p_buffer: Pointer to call stack buffer. - * @param[in] size: Size of call stack buffer. - * @param[in] sp: Stack pointer - * - * @return Depth - ***************************************************************************************** - */ - static uint32_t cb_backtrace_call_stack(uint32_t *p_buffer, uint32_t size, uint32_t sp) - { - uint32_t stack_start_addr = s_main_stack_start_addr; - uint32_t depth = 0; - uint32_t stack_size = s_main_stack_size; - uint32_t pc; - uint32_t i; + if (s_regs.bfsr.bits.PRECISERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_PRECISERR]); + } - bool is_regs_saved_lr_valid = false; - if (!s_is_on_fault) { -#if APP_IS_USING_FREEROTS - // OS environment. - if (cb_sp_get() == cb_psp_get()) { - cb_cur_thread_stack_info_get(sp, &stack_start_addr, &stack_size); + if (s_regs.bfsr.bits.IMPREISERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_IMPREISERR]); + } + + if (s_regs.bfsr.bits.UNSTKERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_UNSTKERR]); + } + + if (s_regs.bfsr.bits.STKERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_STKERR]); + } + +#if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) + if (s_regs.bfsr.bits.LSPERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFSR_LSPERR]); } #endif - depth = cb_backtrace_call_stack_depth(p_buffer, size, sp); - return depth; + if (s_regs.bfsr.bits.BFARVALID) + { + if (s_regs.bfsr.bits.PRECISERR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_BFAR], s_regs.bfar); + } + } } - if (!s_is_stack_overflow) { + // Usage Fault + if (s_regs.ufsr.value) + { + if (s_regs.ufsr.bits.UNDEFINSTR) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_UNDEFINSTR]); + } + + if (s_regs.ufsr.bits.INVSTATE) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_INVSTATE]); + } + + if (s_regs.ufsr.bits.INVPC) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_INVPC]); + } + + if (s_regs.ufsr.bits.NOCP) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_NOCP]); + } + + if (s_regs.ufsr.bits.UNALIGNED) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_UNALIGNED]); + } + + if (s_regs.ufsr.bits.DIVBYZERO0) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_UFSR_DIVBYZERO0]); + } + } + } + + // Debug Fault + if (s_regs.hfsr.bits.DEBUGEVT) + { + if (s_regs.dfsr.value) + { + if (s_regs.dfsr.bits.HALTED) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_HALTED]); + } + + if (s_regs.dfsr.bits.BKPT) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_BKPT]); + } + + if (s_regs.dfsr.bits.DWTTRAP) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_DWTTRAP]); + } + + if (s_regs.dfsr.bits.VCATCH) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_VCATCH]); + } + + if (s_regs.dfsr.bits.EXTERNAL) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_DFSR_EXTERNAL]); + } + } + } +} +#endif + +#if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) +static uint32_t cb_statck_fpu_reg_del(uint32_t fault_handler_lr, uint32_t sp) +{ + bool statck_has_fpu_regs = (fault_handler_lr & (1UL << 4)) == 0 ? true : false; + + // The stack has S0~S15 and FPSCR registers when statck_has_fpu_regs is true, double word align. + return statck_has_fpu_regs == true ? sp + sizeof(size_t) * 18 : sp; +} +#endif + +/** + ***************************************************************************************** + * Backtrace function call stack + * + * @param[in] p_buffer: Pointer to call stack buffer. + * @param[in] size: Size of call stack buffer. + * @param[in] sp: Stack pointer + * + * @return Depth + ***************************************************************************************** + */ +static uint32_t cb_backtrace_call_stack(uint32_t *p_buffer, uint32_t size, uint32_t sp) +{ + uint32_t stack_start_addr = s_main_stack_start_addr; + uint32_t depth = 0; + uint32_t stack_size = s_main_stack_size; + uint32_t pc; + uint32_t i; + + bool is_regs_saved_lr_valid = false; + + if (s_is_on_fault) + { + if (!s_is_stack_overflow) + { // First depth is PC p_buffer[depth++] = s_regs.saved.pc; // Second depth is from LR, so need decrease a word to PC pc = s_regs.saved.lr - sizeof(uint32_t); - for (i = 0; i < s_code_section_count; i++) { - if ((pc >= s_code_section_infos[i].code_start_addr) && - (pc <= s_code_section_infos[i].code_end_addr) && - (depth < APP_ERROR_CALL_STACK_DEPTH_MAX) && - (depth < size)) { + + for (i = 0; i < s_code_section_count; i++) + { + if ((pc >= s_code_section_infos[i].code_start_addr) && \ + (pc <= s_code_section_infos[i].code_end_addr) && \ + (depth < APP_ERROR_CALL_STACK_DEPTH_MAX) && \ + (depth < size)) + { p_buffer[depth++] = pc; is_regs_saved_lr_valid = true; } } } + #if APP_IS_USING_FREEROTS // Program is running on thread before fault. - if (s_is_on_thread_before_fault) { + if (s_is_on_thread_before_fault) + { + cb_cur_thread_stack_info_get(sp, &stack_start_addr, &stack_size); + } + } + else + { + // OS environment. + if (cb_sp_get() == cb_psp_get()) + { cb_cur_thread_stack_info_get(sp, &stack_start_addr, &stack_size); } #endif - depth = cb_backtrace_call_stack_depth(p_buffer, size, sp); - return depth; } - /** - ***************************************************************************************** - * Dump function call stack - * - * @param[in] sp:Pointer to stack. - ***************************************************************************************** - */ - static void cb_call_stack_print(uint32_t sp) + if (s_is_stack_overflow) { - int ret; - uint32_t i; - uint32_t cur_depth = 0; - uint32_t call_stack_buf[APP_ERROR_CALL_STACK_DEPTH_MAX] = {0}; + if (sp < stack_start_addr) + { + sp = stack_start_addr; + } + else if (sp > stack_start_addr + stack_size) + { + sp = stack_start_addr + stack_size; + } + } - cur_depth = cb_backtrace_call_stack(call_stack_buf, APP_ERROR_CALL_STACK_DEPTH_MAX, sp); + // Copy called function address. + for (; sp < stack_start_addr + stack_size; sp += sizeof(uint32_t)) + { + // The *sp value may be LR, so need decrease a word to PC. + pc = *((uint32_t *)sp) - sizeof(uint32_t); - for (i = 0; i < cur_depth; i++) { - ret = sprintf_s(s_call_stack_info + i * CALL_STACK_INFO_CNT, - NVDS_FAULT_INFO_LEN_MAX, "%08lx", call_stack_buf[i]); - if (ret < 0) { - return; + // The Cortex-M using thumb instruction, so the pc must be an odd number. + if (pc % 2 == 0) + { + continue; + } + + for (i = 0; i < s_code_section_count; i++) + { + if ((pc >= s_code_section_infos[i].code_start_addr) && \ + (pc <= s_code_section_infos[i].code_end_addr) && \ + (depth < APP_ERROR_CALL_STACK_DEPTH_MAX) && \ + (depth < size)) + { + // The second depth function may be already saved, so need ignore repeat. + if ((depth == 2) && is_regs_saved_lr_valid && (pc == p_buffer[1])) + { + continue; + } + p_buffer[depth++] = pc; } - s_call_stack_info[i * CALL_STACK_INFO_CNT + BIT_8] = '<'; - s_call_stack_info[i * CALL_STACK_INFO_CNT + BIT_9] = '-'; - s_call_stack_info[i * CALL_STACK_INFO_CNT + BIT_10] = '-'; - } - - if (cur_depth) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_CALL_STACK_INFO], \ - cur_depth * CALL_STACK_INFO_CNT, s_call_stack_info); - } else { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_CALL_STACK_ERR]); } } - /* - * GLOBAL FUNCTION DEFINITIONS - ***************************************************************************************** - */ + return depth; +} - /** - ***************************************************************************************** - * @brief Add Code sections for stack analysis. - ***************************************************************************************** - */ - bool cortex_backtrace_code_section_add(uint32_t code_start_addr, uint32_t code_end_addr) +/** + ***************************************************************************************** + * Dump function call stack + * + * @param[in] sp:Pointer to stack. + ***************************************************************************************** + */ +static void cb_call_stack_print(uint32_t sp) +{ + uint32_t i; + uint32_t cur_depth = 0; + uint32_t call_stack_buf[APP_ERROR_CALL_STACK_DEPTH_MAX] = {0}; + + cur_depth = cb_backtrace_call_stack(call_stack_buf, APP_ERROR_CALL_STACK_DEPTH_MAX, sp); + + for (i = 0; i < cur_depth; i++) { - if (s_code_section_count < FAULT_CODE_SECTON_CNT_MAX) { - return false; - } - - s_code_section_infos[s_code_section_count].code_start_addr = code_start_addr; - s_code_section_infos[s_code_section_count].code_end_addr = code_end_addr - TWO; - ++s_code_section_count; - - return true; +// sprintf(s_call_stack_info + i * (8 + 1), "%08lx", call_stack_buf[i]); +// s_call_stack_info[i * (8 + 1) + 8] = ' '; + sprintf(s_call_stack_info + i * (8 + 3), "%08lx", call_stack_buf[i]); + s_call_stack_info[i * (8 + 3) + 8] = '<'; + s_call_stack_info[i * (8 + 3) + 9] = '-'; + s_call_stack_info[i * (8 + 3) + 10] = '-'; } - void stack_cfg(uint32_t fault_handler_sp) + if (cur_depth) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_CALL_STACK_INFO], cur_depth * (8 + 3), s_call_stack_info); + } + else + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_CALL_STACK_ERR]); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ + +/** + ***************************************************************************************** + * @brief Add Code sections for stack analysis. + ***************************************************************************************** + */ +bool cortex_backtrace_code_section_add(uint32_t code_start_addr, uint32_t code_end_addr) +{ + if (FAULT_CODE_SECTON_CNT_MAX > s_code_section_count) + { + return false; + } + + s_code_section_infos[s_code_section_count].code_start_addr = code_start_addr; + s_code_section_infos[s_code_section_count].code_end_addr = code_end_addr - 2; + ++s_code_section_count; + + return true; +} + +/** + ***************************************************************************************** + * @brief Initialize Cortex backtrace. + ***************************************************************************************** + */ +void cortex_backtrace_fault_handler(uint32_t fault_handler_lr, uint32_t fault_handler_sp) +{ + __FAULT_TRACE_OUTPUT_PREPARE(); + + //BL 0 ER_IROM_BOOT + s_code_section_infos[s_code_section_count ].code_start_addr = 0x00000000; + s_code_section_infos[s_code_section_count ].code_end_addr = 0x000036FE; + //BL 1 ER_IROM_BOOT + s_code_section_infos[s_code_section_count + 1].code_start_addr = 0x00003C00; + s_code_section_infos[s_code_section_count + 1].code_end_addr = 0x00003D3A; + //BL 1 ER_IROM_BLE_STACK + s_code_section_infos[s_code_section_count + 2].code_start_addr = 0x00003D6C; + s_code_section_infos[s_code_section_count + 2].code_end_addr = 0x0005CE3A; + //SDK ER_SDK + s_code_section_infos[s_code_section_count + 3].code_start_addr = 0x00062C00; + s_code_section_infos[s_code_section_count + 3].code_end_addr = 0x0007D0E4; + s_code_section_count += 4; + +// #if SYS_FAULT_TRACE_MODE +// hardfault_trace_handler(fault_handler_lr, fault_handler_sp); +// #endif +#if defined(__CC_ARM) + s_main_stack_start_addr = (uint32_t)&CSTACK_BLOCK_START(CSTACK_BLOCK_NAME); + s_main_stack_size = (uint32_t)&CSTACK_BLOCK_END(CSTACK_BLOCK_NAME) - s_main_stack_start_addr; +// s_code_start_addr = (uint32_t)&CODE_SECTION_START(CODE_SECTION_NAME); +// s_code_size = (uint32_t)&CODE_SECTION_END(CODE_SECTION_NAME) - s_code_start_addr; + uint32_t i_code_start_addr = 0; + uint32_t i_code_size = 0; + i_code_start_addr = (uint32_t)&CODE_SECTION_START(CODE_SECTION_NAME); + i_code_size = (uint32_t)&CODE_SECTION_END(CODE_SECTION_NAME) - i_code_start_addr; +// printf("\r\ni_code_start_addr=0X%x,i_code_size=%d\r\n",i_code_start_addr,i_code_size); + s_code_section_infos[s_code_section_count ].code_start_addr = (uint32_t)&CODE_SECTION_START(CODE_SECTION_NAME); + s_code_section_infos[s_code_section_count ].code_end_addr = (uint32_t)&CODE_SECTION_END(CODE_SECTION_NAME); + s_code_section_count +=1; + +#elif defined(__ICCARM__) + uint32_t s_main_stack_start_addr = (uint32_t)__section_begin(CSTACK_BLOCK_NAME); + uint32_t s_main_stack_size = (uint32_t)__section_end(CSTACK_BLOCK_NAME) - s_main_stack_start_addr; +// uint32_t s_code_start_addr = (uint32_t)__section_begin(CODE_SECTION_NAME); +// uint32_t s_code_size = (uint32_t)__section_end(CODE_SECTION_NAME) - s_code_start_addr; +#elif defined(__GNUC__) + s_main_stack_start_addr = (uint32_t)(&CSTACK_BLOCK_START); + s_main_stack_size = (uint32_t)(&CSTACK_BLOCK_END) - s_main_stack_start_addr; +// uint32_t s_code_start_addr = (uint32_t)(&CODE_SECTION_START); +// uint32_t s_code_size = (uint32_t)(&CODE_SECTION_END) - s_code_start_addr; + s_code_section_infos[s_code_section_count ].code_start_addr = (uint32_t)(&CODE_SECTION_START); + s_code_section_infos[s_code_section_count ].code_end_addr = (uint32_t)(&CODE_SECTION_END); + s_code_section_count +=1; +#else + #error "not supported compiler" +#endif + uint32_t stack_pointer = fault_handler_sp; uint32_t saved_regs_addr = stack_pointer; const char *regs_name[] = { "R0 ", "R1 ", "R2 ", "R3 ", "R12", "LR ", "PC ", "PSR" }; + #if APP_ERROR_DUMP_STACK_INFO_ENABLE uint32_t stack_start_addr = s_main_stack_start_addr; uint32_t stack_size = s_main_stack_size; #endif // Only call once +// APP_ASSERT_CHECK(!s_is_on_fault); + s_is_on_fault = true; + #if APP_IS_USING_FREEROTS - s_is_on_thread_before_fault = fault_handler_lr & (1UL << LEFT_MOV_2BIT); + s_is_on_thread_before_fault = fault_handler_lr & (1UL << 2); // Check which stack was used before (MSP or PSP). - if (s_is_on_thread_before_fault) { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_THREAD], - cb_cur_thread_name_get() ? cb_cur_thread_name_get() : "NO_NAME"); + if (s_is_on_thread_before_fault) + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_THREAD], + cb_cur_thread_name_get() ? cb_cur_thread_name_get() : "NO_NAME"); + stack_pointer = cb_psp_get(); saved_regs_addr = stack_pointer; + #if APP_ERROR_DUMP_STACK_INFO_ENABLE cb_cur_thread_stack_info_get(stack_pointer, &stack_start_addr, &stack_size); #endif - } else { - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_HANDLER]); + } + else + { + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_HANDLER]); } #else - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_HANDLER]); + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_FAULT_ON_HANDLER]); #endif + // Delete saved R0~R3, R12, LR, PC, xPSR registers space - stack_pointer += sizeof(uint32_t) * REGISTER_CNT; + stack_pointer += sizeof(uint32_t) * 8; + #if (__CORTEX_M == CB_CPU_ARM_CORTEX_M4) || (__CORTEX_M == CB_CPU_ARM_CORTEX_M7) stack_pointer = cb_statck_fpu_reg_del(fault_handler_lr, stack_pointer); #endif + #if APP_ERROR_DUMP_STACK_INFO_ENABLE // Check stack overflow. - if (stack_pointer < stack_start_addr || stack_pointer > stack_start_addr + stack_size) { + if (stack_pointer < stack_start_addr || stack_pointer > stack_start_addr + stack_size) + { s_is_stack_overflow = true; } + // Dump stack information. +// cb_stack_info_dump(stack_start_addr, stack_size, (uint32_t *)stack_pointer); #endif -} -void platform_cfg(void) -{ -#if defined(__CC_ARM) - s_main_stack_start_addr = (uint32_t)&CSTACK_BLOCK_START(CSTACK_BLOCK_NAME); - s_main_stack_size = (uint32_t)&(CSTACK_BLOCK_END(CSTACK_BLOCK_NAME) - s_main_stack_start_addr); - uint32_t i_code_start_addr = 0; - uint32_t i_code_size = 0; - i_code_start_addr = (uint32_t)&CODE_SECTION_START(CODE_SECTION_NAME); - i_code_size = (uint32_t)&(CODE_SECTION_END(CODE_SECTION_NAME) - i_code_start_addr); - s_code_section_infos[s_code_section_count ].code_start_addr = (uint32_t)&CODE_SECTION_START(CODE_SECTION_NAME); - s_code_section_infos[s_code_section_count ].code_end_addr = (uint32_t)&CODE_SECTION_END(CODE_SECTION_NAME); - s_code_section_count +=1; -#elif defined(__ICCARM__) - uint32_t s_main_stack_start_addr = (uint32_t)__section_begin(CSTACK_BLOCK_NAME); - uint32_t s_main_stack_size = (uint32_t)__section_end(CSTACK_BLOCK_NAME) - s_main_stack_start_addr; -#elif defined(__GNUC__) - uint32_t s_main_stack_start_addr = (uint32_t)(&CSTACK_BLOCK_START); - uint32_t s_main_stack_size = (uint32_t)(&CSTACK_BLOCK_END) - s_main_stack_start_addr; -#else -#error "not supported compiler" -#endif -} - -void reg_cfg(void) -{ - if (!s_is_stack_overflow) { + if (!s_is_stack_overflow) + { // Dump register. - FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_REGS_TITLE]); + __FAULT_TRACE_OUTPUT(s_print_info[CB_PRINT_REGS_TITLE]); - s_regs.saved.r0 = ((uint32_t *)saved_regs_addr)[DRG_R0]; // Register R0 - s_regs.saved.r1 = ((uint32_t *)saved_regs_addr)[DRG_R1]; // Register R1 - s_regs.saved.r2 = ((uint32_t *)saved_regs_addr)[DRG_R2]; // Register R2 - s_regs.saved.r3 = ((uint32_t *)saved_regs_addr)[DRG_R3]; // Register R3 - s_regs.saved.r12 = ((uint32_t *)saved_regs_addr)[DRG_R4]; // Register R12 - s_regs.saved.lr = ((uint32_t *)saved_regs_addr)[DRG_R5]; // Link register LR - s_regs.saved.pc = ((uint32_t *)saved_regs_addr)[DRG_R6]; // Program Counter PC - s_regs.saved.psr.value = ((uint32_t *)saved_regs_addr)[DRG_R7]; // Program status word PSR + s_regs.saved.r0 = ((uint32_t *)saved_regs_addr)[0]; // Register R0 + s_regs.saved.r1 = ((uint32_t *)saved_regs_addr)[1]; // Register R1 + s_regs.saved.r2 = ((uint32_t *)saved_regs_addr)[2]; // Register R2 + s_regs.saved.r3 = ((uint32_t *)saved_regs_addr)[3]; // Register R3 + s_regs.saved.r12 = ((uint32_t *)saved_regs_addr)[4]; // Register R12 + s_regs.saved.lr = ((uint32_t *)saved_regs_addr)[5]; // Link register LR + s_regs.saved.pc = ((uint32_t *)saved_regs_addr)[6]; // Program Counter PC + s_regs.saved.psr.value = ((uint32_t *)saved_regs_addr)[7]; // Program status word PSR - FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[0], s_regs.saved.r0, \ - regs_name[1], s_regs.saved.r1); - FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[2], s_regs.saved.r2, \ - regs_name[3], s_regs.saved.r3); - FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[4], s_regs.saved.r12, \ - regs_name[5], s_regs.saved.lr); - FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[6], s_regs.saved.pc, \ - regs_name[7], s_regs.saved.psr.value); - FAULT_TRACE_OUTPUT("========="); + __FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[0], s_regs.saved.r0, regs_name[1], s_regs.saved.r1); + __FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[2], s_regs.saved.r2, regs_name[3], s_regs.saved.r3); + __FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[4], s_regs.saved.r12, regs_name[5], s_regs.saved.lr); + __FAULT_TRACE_OUTPUT(" %s: %08x %s: %08x", regs_name[6], s_regs.saved.pc, regs_name[7], s_regs.saved.psr.value); + __FAULT_TRACE_OUTPUT("========="); } // The Cortex-M0 is not support fault diagnosis. @@ -791,53 +897,9 @@ void reg_cfg(void) cb_fault_diagnosis(); #endif -} -void GR5515_D_cfg(void) -{ -#if defined(GR5515_D) -#define CODE_INDEX1 1 -#define CODE_INDEX2 2 -#define CODE_INDEX3 3 - // BL 0 ER_IROM_BOOT - s_code_section_infos[s_code_section_count ].code_start_addr = 0x00000000; - s_code_section_infos[s_code_section_count ].code_end_addr = 0x000036FE; - // BL 1 ER_IROM_BOOT - s_code_section_infos[s_code_section_count + CODE_INDEX1].code_start_addr = 0x00003C00; - s_code_section_infos[s_code_section_count + CODE_INDEX1].code_end_addr = 0x00003D3A; - // BL 1 ER_IROM_BLE_STACK - s_code_section_infos[s_code_section_count + CODE_INDEX2].code_start_addr = 0x00003D6C; - s_code_section_infos[s_code_section_count + CODE_INDEX2].code_end_addr = 0x0005CE3A; - // SDK ER_SDK - s_code_section_infos[s_code_section_count + CODE_INDEX3].code_start_addr = 0x00062C00; - s_code_section_infos[s_code_section_count + CODE_INDEX3].code_end_addr = 0x0007D0E4; - s_code_section_count += FOUR; -#else - // ER_IROM_BOOT - s_code_section_infos[s_code_section_count ].code_start_addr = 0x00004000; - s_code_section_infos[s_code_section_count ].code_end_addr = 0x0000413A; - // ER_IROM_BLE_STACK - s_code_section_infos[s_code_section_count + 1].code_start_addr = 0x0000416C; - s_code_section_infos[s_code_section_count + 1].code_end_addr = 0x0004c25A; - s_code_section_count += TWO; -#endif -} - -/** - ***************************************************************************************** - * @brief Initialize Cortex backtrace. - ***************************************************************************************** - */ -void cortex_backtrace_fault_handler(uint32_t fault_handler_lr, uint32_t fault_handler_sp) -{ - FAULT_TRACE_OUTPUT_PREPARE(); - - GR5515_D_cfg(); - platform_cfg(); - stack_cfg(fault_handler_sp); - reg_cfg(); cb_call_stack_print(stack_pointer); - FAULT_TRACE_OUTPUT_FLUSH(); + __FAULT_TRACE_OUTPUT_FLUSH(); } #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.h old mode 100755 new mode 100644 index 2bc5fa1..8af0d2b --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/cortex_backtrace.h @@ -38,71 +38,8 @@ #ifndef __CORTEX_BACKTRACE_H__ #define __CORTEX_BACKTRACE_H__ -#include #include "app_error_cfg.h" - -#if ENABLE_BACKTRACE_FEASS -#define TWO 2 -#define FOUR 4 -#define LEFT_MOV_2BIT 2 -#define REGISTER_CNT 8 -#define DRG_R0 0 -#define DRG_R1 1 -#define DRG_R2 2 -#define DRG_R3 3 -#define DRG_R4 4 -#define DRG_R5 5 -#define DRG_R6 6 -#define DRG_R7 7 - -#if defined(__CC_ARM) -#define CSTACK_BLOCK_NAME ARM_LIB_STACKHEAP /**< C stack block name: ARM_LIB_STACKHEAP. */ -#define CODE_SECTION_NAME FLASH_CODE /**< Code section name: ER_FLASH. */ - -#define SECTION_START(_name_) _name_##$$Base -#define SECTION_END(_name_) _name_##$$Limit -#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base -#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$ZI$$Limit -#define CSTACK_BLOCK_START(_name_) IMAGE_SECTION_START(_name_) -#define CSTACK_BLOCK_END(_name_) IMAGE_SECTION_END(_name_) -#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_) -#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_) - -extern const int CSTACK_BLOCK_START(CSTACK_BLOCK_NAME); -extern const int CSTACK_BLOCK_END(CSTACK_BLOCK_NAME); -extern const int CODE_SECTION_START(CODE_SECTION_NAME); -extern const int CODE_SECTION_END(CODE_SECTION_NAME); -#elif defined(__ICCARM__) -#define CSTACK_BLOCK_NAME "CSTACK" /**< C stack block name, default is 'CSTACK'. */ -#define CODE_SECTION_NAME ".text" /**< Code section name, default is '.text'. */ - -#pragma section = CMB_CSTACK_BLOCK_NAME -#pragma section = CMB_CODE_SECTION_NAME -#elif defined(__GNUC__) - -/**< C stack block start address, defined on linker script file, default is _sstack. */ -#define CSTACK_BLOCK_START _sstack -/**< C stack block end address, defined on linker script file, default is _estack. */ -#define CSTACK_BLOCK_END _estack -/**< code section start address, defined on linker script file, default is _stext. */ -#define CODE_SECTION_START _stext -/**< code section end address, defined on linker script file, default is _etext. */ -#define CODE_SECTION_END _etext -#define CALLBACK_CNT 9 -#define ZERO 0 - -extern const int CSTACK_BLOCK_START; -extern const int CSTACK_BLOCK_END; -extern const int CODE_SECTION_START; -extern const int CODE_SECTION_END; -#else -#error "not supported compiler" -#endif -#endif - -void fault_trace_nvds_save_prepare(void); -void fault_trace_nvds_add(const char *format, ...); -void fault_trace_nvds_save_flush(void); +#include /** * @defgroup CORTEX_BACKTRACE_MAROC Defines @@ -113,34 +50,25 @@ void fault_trace_nvds_save_flush(void); #define CB_CPU_ARM_CORTEX_M4 (0x04U) /**< Cortex-M4 Core */ #define CB_CPU_ARM_CORTEX_M7 (0x07U) /**< Cortex-M7 Core */ -/**< System Handler Control and State Register.*/ -#define CB_SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) -/**< Memory management fault State register. */ -#define CB_NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) -/**< Bus fault State register. */ -#define CB_NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) -/**< Usage fault State register. */ -#define CB_NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) -/**< Hard fault State register. */ -#define CB_NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) -/**< Debug fault State register. */ -#define CB_NVIC_DFSR (*(volatile unsigned short*)(0xE000ED30u)) -/**< Memory management fault address register. */ -#define CB_NVIC_MMAR (*(volatile unsigned int*) (0xE000ED34u)) -/**< Bus fault manage address register. */ -#define CB_NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) -/**< Auxiliary fault State register. */ -#define CB_NVIC_AFSR (*(volatile unsigned short*)(0xE000ED3Cu)) +#define CB_SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) /**< System Handler Control and State Register. */ +#define CB_NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) /**< Memory management fault State register. */ +#define CB_NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) /**< Bus fault State register. */ +#define CB_NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) /**< Usage fault State register. */ +#define CB_NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) /**< Hard fault State register. */ +#define CB_NVIC_DFSR (*(volatile unsigned short*)(0xE000ED30u)) /**< Debug fault State register. */ +#define CB_NVIC_MMAR (*(volatile unsigned int*) (0xE000ED34u)) /**< Memory management fault address register. */ +#define CB_NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) /**< Bus fault manage address register. */ +#define CB_NVIC_AFSR (*(volatile unsigned short*)(0xE000ED3Cu)) /**< Auxiliary fault State register. */ /**@brief ELF(Executable and Linking Format) file extension name for each compiler. */ #if defined(__CC_ARM) -#define CB_ELF_FILE_EXTENSION_NAME ".axf" + #define CB_ELF_FILE_EXTENSION_NAME ".axf" #elif defined(__ICCARM__) -#define CB_ELF_FILE_EXTENSION_NAME ".out" + #define CB_ELF_FILE_EXTENSION_NAME ".out" #elif defined(__GNUC__) -#define CB_ELF_FILE_EXTENSION_NAME ".elf" + #define CB_ELF_FILE_EXTENSION_NAME ".elf" #else -#error "not supported compiler" + #error "not supported compiler" #endif /** @} */ @@ -149,123 +77,130 @@ void fault_trace_nvds_save_flush(void); * @{ */ /**@brief Cortex-M fault registers. */ -typedef struct { - struct { - unsigned int r0; /**< Register R0. */ - unsigned int r1; /**< Register R1. */ - unsigned int r2; /**< Register R2. */ - unsigned int r3; /**< Register R3. */ - unsigned int r12; /**< Register R12. */ - unsigned int lr; /**< Link register. */ - unsigned int pc; /**< Program counter. */ - union { - unsigned int value; - struct { - unsigned int IPSR : 8; /**< Interrupt Program Status register (IPSR). */ - unsigned int EPSR : 19; /**< Execution Program Status register (EPSR). */ - unsigned int APSR : 5; /**< Application Program Status register (APSR). */ - } bits; - } psr; /**< Program status register. */ - } saved; +typedef struct +{ + struct + { + unsigned int r0; /**< Register R0. */ + unsigned int r1; /**< Register R1. */ + unsigned int r2; /**< Register R2. */ + unsigned int r3; /**< Register R3. */ + unsigned int r12; /**< Register R12. */ + unsigned int lr; /**< Link register. */ + unsigned int pc; /**< Program counter. */ + union + { + unsigned int value; + struct + { + unsigned int IPSR : 8; /**< Interrupt Program Status register (IPSR). */ + unsigned int EPSR : 19; /**< Execution Program Status register (EPSR). */ + unsigned int APSR : 5; /**< Application Program Status register (APSR). */ + } bits; + } psr; /**< Program status register. */ + } saved; - union { - unsigned int value; - struct { - unsigned int MEMFAULTACT : 1; /**< Read as 1 if memory management fault is active. */ - unsigned int BUSFAULTACT : 1; /**< Read as 1 if bus fault exception is active. */ - unsigned int UnusedBits1 : 1; /**< Unused Bits 1. */ - unsigned int USGFAULTACT : 1; /**< Read as 1 if usage fault exception is active. */ - unsigned int UnusedBits2 : 3; /**< Unused Bits 2. */ - unsigned int SVCALLACT : 1; /**< Read as 1 if SVC exception is active. */ - unsigned int MONITORACT : 1; /**< Read as 1 if debug monitor exception is active. */ - unsigned int UnusedBits3 : 1; /**< Unused Bits 3. */ - unsigned int PENDSVACT : 1; /**< Read as 1 if PendSV exception is active. */ - unsigned int SYSTICKACT : 1; /**< Read as 1 if SYSTICK exception is active. */ -/**< Usage fault pended; usage fault started but was replaced by a higher-priority exception. */ - unsigned int USGFAULTPENDED : 1; -/**< Memory management fault pended; memory management fault started but was replaced - * by a higher-priority exception. */ - unsigned int MEMFAULTPENDED : 1; -/**< Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception. */ - unsigned int BUSFAULTPENDED : 1; -/**< SVC pended; SVC was started but was replaced by a higher-priority exception. */ - unsigned int SVCALLPENDED : 1; - unsigned int MEMFAULTENA : 1; /**< Memory management fault handler enable. */ - unsigned int BUSFAULTENA : 1; /**< Bus fault handler enable. */ - unsigned int USGFAULTENA : 1; /**< Usage fault handler enable. */ - } bits; - } syshndctrl; /**< System Handler Control and State Register (0xE000ED24). */ + union + { + unsigned int value; + struct + { + unsigned int MEMFAULTACT : 1; /**< Read as 1 if memory management fault is active. */ + unsigned int BUSFAULTACT : 1; /**< Read as 1 if bus fault exception is active. */ + unsigned int UnusedBits1 : 1; /**< Unused Bits 1. */ + unsigned int USGFAULTACT : 1; /**< Read as 1 if usage fault exception is active. */ + unsigned int UnusedBits2 : 3; /**< Unused Bits 2. */ + unsigned int SVCALLACT : 1; /**< Read as 1 if SVC exception is active. */ + unsigned int MONITORACT : 1; /**< Read as 1 if debug monitor exception is active. */ + unsigned int UnusedBits3 : 1; /**< Unused Bits 3. */ + unsigned int PENDSVACT : 1; /**< Read as 1 if PendSV exception is active. */ + unsigned int SYSTICKACT : 1; /**< Read as 1 if SYSTICK exception is active. */ + unsigned int USGFAULTPENDED : 1; /**< Usage fault pended; usage fault started but was replaced by a higher-priority exception. */ + unsigned int MEMFAULTPENDED : 1; /**< Memory management fault pended; memory management fault started but was replaced by a higher-priority exception. */ + unsigned int BUSFAULTPENDED : 1; /**< Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception. */ + unsigned int SVCALLPENDED : 1; /**< SVC pended; SVC was started but was replaced by a higher-priority exception. */ + unsigned int MEMFAULTENA : 1; /**< Memory management fault handler enable. */ + unsigned int BUSFAULTENA : 1; /**< Bus fault handler enable. */ + unsigned int USGFAULTENA : 1; /**< Usage fault handler enable. */ + } bits; + } syshndctrl; /**< System Handler Control and State Register (0xE000ED24). */ - union { - unsigned char value; - struct { - unsigned char IACCVIOL : 1; /**< Instruction access violation. */ - unsigned char DACCVIOL : 1; /**< Data access violation. */ - unsigned char UnusedBits : 1; /**< Unused Bits 1. */ - unsigned char MUNSTKERR : 1; /**< Unstacking error. */ - unsigned char MSTKERR : 1; /**< Stacking error. */ - unsigned char MLSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */ - unsigned char UnusedBits2 : 1; /**< Unused Bits 2. */ - unsigned char MMARVALID : 1; /**< Indicates the MMAR is valid. */ - } bits; - } mfsr; /**< Memory Management Fault Status Register (0xE000ED28). */ - unsigned int mmar; /**< Memory Management Fault Address Register (0xE000ED34). */ + union + { + unsigned char value; + struct + { + unsigned char IACCVIOL : 1; /**< Instruction access violation. */ + unsigned char DACCVIOL : 1; /**< Data access violation. */ + unsigned char UnusedBits : 1; /**< Unused Bits 1. */ + unsigned char MUNSTKERR : 1; /**< Unstacking error. */ + unsigned char MSTKERR : 1; /**< Stacking error. */ + unsigned char MLSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */ + unsigned char UnusedBits2 : 1; /**< Unused Bits 2. */ + unsigned char MMARVALID : 1; /**< Indicates the MMAR is valid. */ + } bits; + } mfsr; /**< Memory Management Fault Status Register (0xE000ED28). */ + unsigned int mmar; /**< Memory Management Fault Address Register (0xE000ED34). */ - union { - unsigned char value; - struct { - unsigned char IBUSERR : 1; /**< Instruction access violation. */ - unsigned char PRECISERR : 1; /**< Precise data access violation. */ - unsigned char IMPREISERR : 1; /**< Imprecise data access violation. */ - unsigned char UNSTKERR : 1; /**< Unstacking error. */ - unsigned char STKERR : 1; /**< Stacking error. */ - unsigned char LSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */ - unsigned char UnusedBits : 1; /**< Unused Bits 1. */ - unsigned char BFARVALID : 1; /**< Indicates BFAR is valid. */ - } bits; - } bfsr; /**< Bus Fault Status Register (0xE000ED29). */ - unsigned int bfar; /**< Bus Fault Manage Address Register (0xE000ED38). */ + union + { + unsigned char value; + struct + { + unsigned char IBUSERR : 1; /**< Instruction access violation. */ + unsigned char PRECISERR : 1; /**< Precise data access violation. */ + unsigned char IMPREISERR : 1; /**< Imprecise data access violation. */ + unsigned char UNSTKERR : 1; /**< Unstacking error. */ + unsigned char STKERR : 1; /**< Stacking error. */ + unsigned char LSPERR : 1; /**< Floating-point lazy state preservation (M4/M7). */ + unsigned char UnusedBits : 1; /**< Unused Bits 1. */ + unsigned char BFARVALID : 1; /**< Indicates BFAR is valid. */ + } bits; + } bfsr; /**< Bus Fault Status Register (0xE000ED29). */ + unsigned int bfar; /**< Bus Fault Manage Address Register (0xE000ED38). */ - union { - unsigned short value; - struct { - unsigned short UNDEFINSTR : 1; /**< Attempts to execute an undefined instruction. */ - unsigned short INVSTATE : 1; /**< Attempts to switch to an invalid state (e.g., ARM). */ - /**< Attempts to do an exception with a bad value in the EXC_RETURN number. */ - unsigned short INVPC : 1; - unsigned short NOCP : 1; /**< Attempts to execute a coprocessor instruction. */ - unsigned short UnusedBits : 4; /**< Unused Bits 1. */ - unsigned short UNALIGNED : 1; /**< Indicates that an unaligned access fault has taken place. */ -unsigned short DIVBYZERO0 : - 1; /**< Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set). */ - } bits; - } ufsr; /**< Usage Fault Status Register (0xE000ED2A). */ + union + { + unsigned short value; + struct + { + unsigned short UNDEFINSTR : 1; /**< Attempts to execute an undefined instruction. */ + unsigned short INVSTATE : 1; /**< Attempts to switch to an invalid state (e.g., ARM). */ + unsigned short INVPC : 1; /**< Attempts to do an exception with a bad value in the EXC_RETURN number. */ + unsigned short NOCP : 1; /**< Attempts to execute a coprocessor instruction. */ + unsigned short UnusedBits : 4; /**< Unused Bits 1. */ + unsigned short UNALIGNED : 1; /**< Indicates that an unaligned access fault has taken place. */ + unsigned short DIVBYZERO0 : 1; /**< Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set). */ + } bits; + } ufsr; /**< Usage Fault Status Register (0xE000ED2A). */ - union { - unsigned int value; - struct { - unsigned int UnusedBits : 1; - unsigned int VECTBL : 1; /**< Indicates hard fault is caused by failed vector fetch. */ - unsigned int UnusedBits2 : 28; /**< Unused Bits 1. */ -unsigned int FORCED : - 1; /**< Indicates hard fault is taken because of bus fault/memory management fault/usage fault. */ - unsigned int DEBUGEVT : 1; /**< Indicates hard fault is triggered by debug event. */ - } bits; - } hfsr; /**< Hard Fault Status Register (0xE000ED2C). */ + union + { + unsigned int value; + struct + { + unsigned int UnusedBits : 1; + unsigned int VECTBL : 1; /**< Indicates hard fault is caused by failed vector fetch. */ + unsigned int UnusedBits2 : 28; /**< Unused Bits 1. */ + unsigned int FORCED : 1; /**< Indicates hard fault is taken because of bus fault/memory management fault/usage fault. */ + unsigned int DEBUGEVT : 1; /**< Indicates hard fault is triggered by debug event. */ + } bits; + } hfsr; /**< Hard Fault Status Register (0xE000ED2C). */ - union { - unsigned int value; - struct { - unsigned int HALTED : 1; /**< Halt requested in NVIC. */ - unsigned int BKPT : 1; /**< BKPT instruction executed. */ - unsigned int DWTTRAP : 1; /**< DWT match occurred. */ - unsigned int VCATCH : 1; /**< Vector fetch occurred. */ - unsigned int EXTERNAL : 1; /**< EDBGRQ signal asserted. */ - } bits; /**< Unused Bits 1. */ - } dfsr; /**< Debug Fault Status Register (0xE000ED30). */ + union + { + unsigned int value; + struct + { + unsigned int HALTED : 1; /**< Halt requested in NVIC. */ + unsigned int BKPT : 1; /**< BKPT instruction executed. */ + unsigned int DWTTRAP : 1; /**< DWT match occurred. */ + unsigned int VCATCH : 1; /**< Vector fetch occurred. */ + unsigned int EXTERNAL : 1; /**< EDBGRQ signal asserted. */ + } bits; /**< Unused Bits 1. */ + } dfsr; /**< Debug Fault Status Register (0xE000ED30). */ - unsigned int - afsr; /**< Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional). */ + unsigned int afsr; /**< Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional). */ } cb_hard_fault_regs_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_gcc.s b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_gcc.s new file mode 100644 index 0000000..a71160f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_gcc.s @@ -0,0 +1,28 @@ +;/** +; ***************************************************************************************** +; * +; * @file app_hardfault_kei.s +; * +; * @brief App HardFault Handler Function Implementation for GCC. +; * +; * Copyright(C) 2016-2018, Shenzhen Goodix Technology Co., Ltd +; * All Rights Reserved +; * +; ***************************************************************************************** +; */ + +.syntax unified +.thumb +.text + +/* NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file. */ + +.global HardFault_Handler +.type HardFault_Handler, %function +HardFault_Handler: + MOV r0, lr /* get lr */ + MOV r1, sp /* get stack pointer (current is MSP) */ + BL cortex_backtrace_fault_handler + +Fault_Loop: + BL Fault_Loop /* while(1) */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_iar.s b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_iar.s old mode 100755 new mode 100644 diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_keil.s b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_error/hardfault_handler/cortex_hardfault_keil.s old mode 100755 new mode 100644 diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/BUILD.gn new file mode 100644 index 0000000..fd34876 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_key") { + sources = [ + "app_key.c", + "app_key_core.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.c new file mode 100644 index 0000000..b8c4715 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.c @@ -0,0 +1,237 @@ +/** + ***************************************************************************************** + * + * @file app_key.c + * + * @brief App key Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_key.h" +#include "app_gpiote.h" + +#ifdef ENV_USE_FREERTOS +#include "FreeRTOS.h" +#include "timers.h" +#else +#include "app_timer.h" +#endif +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_KEY_TIMER_INTERVAL 10 /**< App key polling interval interval (in units of 1ms). */ +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint8_t s_app_key_info[APP_KEY_REG_COUNT_MAX]; +static app_gpiote_param_t s_app_io_cfg[APP_KEY_REG_COUNT_MAX]; +static app_key_evt_cb_t s_app_key_evt_cb; +static uint8_t s_app_key_reg_num; +#ifdef ENV_USE_FREERTOS +static TimerHandle_t app_key_timer_handle = NULL; +#else +static app_timer_id_t s_app_key_timer_id; +#endif +static bool s_is_timer_enabled; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + ***************************************************************************************** + * @brief Polling app key pressed state. + ***************************************************************************************** + */ +static void app_key_press_state_polling(void) +{ + app_io_pin_state_t pin_state; + bool is_pressed = false; + + for (uint8_t key_idx = 0; key_idx < s_app_key_reg_num; key_idx++) + { + is_pressed = false; + + pin_state = app_io_read_pin(s_app_io_cfg[key_idx].type, s_app_io_cfg[key_idx].pin); + + if (APP_IO_PIN_RESET == pin_state && s_app_io_cfg[key_idx].pull == APP_IO_PULLUP) + { + is_pressed = true; + } + else if (APP_IO_PIN_SET == pin_state && s_app_io_cfg[key_idx].pull == APP_IO_PULLDOWN) + { + is_pressed = true; + } + + app_key_core_key_pressed_record(key_idx, is_pressed); + } +} + +/** + ***************************************************************************************** + * @brief App key timing timeout handler. + ***************************************************************************************** + */ +static void app_key_timeout_handler(void *p_arg) +{ + app_key_press_state_polling(); + app_key_core_polling_10ms(); +} + +/** + ***************************************************************************************** + * @brief Start app key timer. + ***************************************************************************************** + */ +static void app_key_timer_start(void) +{ +#if defined(ENV_USE_FREERTOS) + xTimerStartFromISR(app_key_timer_handle, 0); +#else + app_timer_create(&s_app_key_timer_id, ATIMER_REPEAT, app_key_timeout_handler); + app_timer_start(s_app_key_timer_id, APP_KEY_TIMER_INTERVAL, NULL); +#endif + s_is_timer_enabled = true; +} + +/** + ***************************************************************************************** + * @brief Stop app key timer. + ***************************************************************************************** + */ +void app_key_timer_stop(void) +{ +#if defined(ENV_USE_FREERTOS) + xTimerStopFromISR(app_key_timer_handle,0); +#else + app_timer_delete(&s_app_key_timer_id); +#endif + s_is_timer_enabled = false; +} + +/** + ***************************************************************************************** + * @brief App key core event handler. + ***************************************************************************************** + */ +static void app_key_core_evt_handler(uint8_t key_idx, app_key_click_type_t key_click_type) +{ + if (app_key_core_is_all_release()) + { + app_key_timer_stop(); + } + + s_app_key_evt_cb(s_app_key_info[key_idx], key_click_type); +} + +static void app_gpiote_event_handler(app_io_evt_t *p_evt) +{ + if ( NULL == p_evt) + return; + + for (uint8_t key_idx = 0; key_idx < s_app_key_reg_num; key_idx++) + { + if ((s_app_io_cfg[key_idx].type == p_evt->type)&& + (p_evt->pin & s_app_io_cfg[key_idx].pin)) + { + if (!s_is_timer_enabled) + { + app_key_timer_start(); + } + app_key_core_key_wait_polling_record(key_idx); + return; + } + } +} + + + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +bool app_key_init(app_key_gpio_t key_inst[], uint8_t key_num, app_key_evt_cb_t key_evt_cb) +{ + if (APP_KEY_REG_COUNT_MAX < key_num || NULL == key_evt_cb) + { + return false; + } + + for (uint8_t key_idx = 0; key_idx < key_num; key_idx++) + { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (key_inst[key_idx].gpio_type != APP_IO_TYPE_NORMAL && + key_inst[key_idx].gpio_type != APP_IO_TYPE_AON) + { + continue; + } +#elif (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + if (key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOA && + key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOB && + key_inst[key_idx].gpio_type != APP_IO_TYPE_GPIOC && + key_inst[key_idx].gpio_type != APP_IO_TYPE_AON) + { + continue; + } +#endif + s_app_key_info[key_idx] = key_inst[key_idx].key_id; + s_app_io_cfg[key_idx].type = key_inst[key_idx].gpio_type; + s_app_io_cfg[key_idx].pin = key_inst[key_idx].gpio_pin; + s_app_io_cfg[key_idx].mode = key_inst[key_idx].trigger_mode; + s_app_io_cfg[key_idx].pull = key_inst[key_idx].pull; + s_app_io_cfg[key_idx].io_evt_cb = app_gpiote_event_handler; + } + + app_gpiote_init(s_app_io_cfg, key_num); + + s_app_key_reg_num = key_num; + s_app_key_evt_cb = key_evt_cb; + app_key_core_cb_register(app_key_core_evt_handler); + +/* If using FreeRTOS, xTimer need to be create and do not create in IRQ handler */ +#if defined(ENV_USE_FREERTOS) + #if defined(FREERTOS_V10_4_3_LTS) + app_key_timer_handle = + xTimerCreate(NULL, APP_KEY_TIMER_INTERVAL, pdTRUE, NULL, (TimerCallbackFunction_t)app_key_timeout_handler); + #else + app_key_timer_handle = xTimerCreate(NULL, APP_KEY_TIMER_INTERVAL, pdTRUE, NULL, app_key_timeout_handler); + #endif +#endif + return true; +} + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.h new file mode 100644 index 0000000..7ab301f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key.h @@ -0,0 +1,95 @@ +/** + **************************************************************************************** + * + * @file app_key.c + * + * @brief App Key API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_KEY_H__ +#define __APP_KEY_H__ + +#include "app_key_core.h" +#include "app_gpiote.h" +#include +#include + +/** + * @defgroup APP_KEY_STRUCT Structures + * @{ + */ +/**@brief App key gpio initialization variables. */ +typedef struct +{ + app_io_type_t gpio_type; /**< Key gpio type. */ + uint32_t gpio_pin; /**< Key gpio pin. */ + app_io_mode_t trigger_mode; /**< Specifies the operating mode for the selected pin. */ + app_io_pull_t pull; /**< Pull mode.*/ + uint8_t key_id; /**< Key register ID. */ +} app_key_gpio_t; +/** @} */ + +/** + * @defgroup APP_KEY_TYPEDEF Typedefs + * @{ + */ +/**@brief APP Key event callback.*/ +typedef void (*app_key_evt_cb_t)(uint8_t key_id, app_key_click_type_t key_click_type); +/** @} */ + +/** + * @defgroup APP_KEY_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief App key initialize. + * + * @param[in] key_inst: The array of key instance. + * @param[in] key_num: The number of key instance. + * @param[in] key_click_cb: App key click event callback. + * + * @return Result of app key inlitialization. + ***************************************************************************************** + */ +bool app_key_init(app_key_gpio_t key_inst[], uint8_t key_num, app_key_evt_cb_t key_click_cb); + +/** + ***************************************************************************************** + * @brief App key pressed down handler. + ***************************************************************************************** + */ +void app_key_pressed_handler(app_key_gpio_t *p_app_key_info); +/** @} */ + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.c new file mode 100644 index 0000000..15307a7 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.c @@ -0,0 +1,319 @@ +/** + ***************************************************************************************** + * + * @file app_key_core.c + * + * @brief App Key Core Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_key_core.h" +#include + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +/**@brief App key core variable. */ +struct app_key_core_t +{ + bool is_pressed; + bool is_in_polling; +}; +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static app_key_core_evt_cb_t s_key_core_evt_cb; +static struct app_key_core_t s_key_core_info[APP_KEY_REG_COUNT_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_key_core_key_polling_cplt(uint8_t key_idx) +{ + s_key_core_info[key_idx].is_pressed = false; + s_key_core_info[key_idx].is_in_polling = false; +} + +/** + ***************************************************************************************** + * @brief APP key click event handler. + * + * @param[in] key_idx: Index of key register. + * @param[in] key_state: Key state of read procedure. + ***************************************************************************************** + */ +static void app_key_core_click_event_handler(uint8_t key_idx, app_key_state_t key_state) +{ + app_key_click_type_t key_click_type = APP_KEY_NO_CLICK; + + switch (key_state) + { + case APP_KEY_STA_NO_CLICK: + key_click_type = APP_KEY_NO_CLICK; + app_key_core_key_polling_cplt(key_idx); + break; + + case APP_KEY_STA_SINGLE_CLICK: + key_click_type = APP_KEY_SINGLE_CLICK; + app_key_core_key_polling_cplt(key_idx); + break; + + case APP_KEY_STA_DOUBLE_CLICK: + key_click_type = APP_KEY_DOUBLE_CLICK; + app_key_core_key_polling_cplt(key_idx); + break; + + case APP_KEY_STA_LONG_CLICK: + key_click_type = APP_KEY_LONG_CLICK; + break; + + case APP_KEY_STA_CONTINUE_CLICK: + key_click_type = APP_KEY_CONTINUE_CLICK; + break; + + case APP_KEY_STA_RELEASE: + key_click_type = APP_KEY_CONTINUE_RELEASE; + break; + + default: + break; + } + + s_key_core_evt_cb(key_idx, key_click_type); +} + +/** + ***************************************************************************************** + * @brief App key state scan. + * + * @param[in] key_idx: Index of key. + * + * @return Result of scan. + ***************************************************************************************** + */ +static app_key_state_t app_key_core_state_scan(uint8_t key_idx) +{ + static app_key_state_t key_scan_state[APP_KEY_REG_COUNT_MAX] = {APP_KEY_STA_INIT}; + static uint8_t key_long_click_count[APP_KEY_REG_COUNT_MAX] = {0}; + + app_key_state_t key_state_return = APP_KEY_STA_INIT; + + switch (key_scan_state[key_idx]) + { + case APP_KEY_STA_INIT: + if (s_key_core_info[key_idx].is_pressed) + { + key_scan_state[key_idx] = APP_KEY_STA_DEBOUNCE; + } + break; + + case APP_KEY_STA_DEBOUNCE: + if (s_key_core_info[key_idx].is_pressed) + { + key_long_click_count[key_idx] = 0; + key_scan_state[key_idx] = APP_KEY_STA_PRESS; + } + else + { + key_scan_state[key_idx] = APP_KEY_STA_INIT; + key_state_return = APP_KEY_STA_NO_CLICK; + } + break; + + case APP_KEY_STA_PRESS: + if (!s_key_core_info[key_idx].is_pressed) + { + key_state_return = APP_KEY_STA_SINGLE_CLICK; + key_scan_state[key_idx] = APP_KEY_STA_INIT; + } + else + { + if ( APP_KEY_LONG_TIME_COUNT <= ++key_long_click_count[key_idx]) + { + key_state_return = APP_KEY_STA_LONG_CLICK; + key_scan_state[key_idx] = APP_KEY_STA_WAITE_RELEASE; + } + } + break; + + case APP_KEY_STA_WAITE_RELEASE: + if (!s_key_core_info[key_idx].is_pressed) + { + key_scan_state[key_idx] = APP_KEY_STA_INIT; + app_key_core_key_polling_cplt(key_idx); + key_state_return = APP_KEY_STA_RELEASE; + } + else + { + key_state_return = APP_KEY_STA_CONTINUE_CLICK; + } + break; + + default: + break; + } + + return key_state_return; +} + +/** + ***************************************************************************************** + * @brief App key click type read. + * + * @param[in] key_idx: Index of key register. + ***************************************************************************************** + */ +static void app_key_core_click_read(uint8_t key_idx) +{ + static app_key_state_t key_read_state[APP_KEY_REG_COUNT_MAX] = {APP_KEY_STA_INIT}; + static uint8_t key_double_click_count[APP_KEY_REG_COUNT_MAX] = {0}; + static uint8_t key_continue_click_count[APP_KEY_REG_COUNT_MAX] = {0}; + + app_key_state_t current_key_state; + + current_key_state = app_key_core_state_scan(key_idx); + + switch (key_read_state[key_idx]) + { + case APP_KEY_STA_INIT: + if (APP_KEY_STA_SINGLE_CLICK == current_key_state) + { + key_double_click_count[key_idx] = 0; + key_read_state[key_idx] = APP_KEY_STA_SINGLE_CLICK; + } + else if (APP_KEY_STA_NO_CLICK == current_key_state ||APP_KEY_STA_LONG_CLICK == current_key_state) + { + app_key_core_click_event_handler(key_idx, current_key_state); + } + else if (APP_KEY_STA_CONTINUE_CLICK == current_key_state) + { + if (APP_KEY_CONTINUE_TIME_COUNT <= ++key_continue_click_count[key_idx]) + { + key_continue_click_count[key_idx] = 0; + key_read_state[key_idx] = APP_KEY_STA_CONTINUE_CLICK; + app_key_core_click_event_handler(key_idx, APP_KEY_STA_CONTINUE_CLICK); + } + } + break; + + case APP_KEY_STA_SINGLE_CLICK: + if (APP_KEY_STA_SINGLE_CLICK == current_key_state) + { + key_read_state[key_idx] = APP_KEY_STA_INIT; + app_key_core_click_event_handler(key_idx, APP_KEY_STA_DOUBLE_CLICK); + } + else if (APP_KEY_DOUBLE_TIME_COUNT <= ++key_double_click_count[key_idx]) + { + key_read_state[key_idx] = APP_KEY_STA_INIT; + app_key_core_click_event_handler(key_idx, APP_KEY_STA_SINGLE_CLICK); + } + break; + + case APP_KEY_STA_CONTINUE_CLICK: + if (APP_KEY_STA_RELEASE == current_key_state) + { + key_read_state[key_idx] = APP_KEY_STA_INIT; + app_key_core_click_event_handler(key_idx, APP_KEY_STA_RELEASE); + } + else if (APP_KEY_STA_CONTINUE_CLICK == current_key_state) + { + if (APP_KEY_CONTINUE_TIME_COUNT <= ++key_continue_click_count[key_idx]) + { + key_continue_click_count[key_idx] = 0; + key_read_state[key_idx] = APP_KEY_STA_CONTINUE_CLICK; + app_key_core_click_event_handler(key_idx, APP_KEY_STA_CONTINUE_CLICK); + } + } + break; + + default: + break; + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +bool app_key_core_cb_register(app_key_core_evt_cb_t key_core_evt_cb) +{ + if (NULL == key_core_evt_cb) + { + return false; + } + + s_key_core_evt_cb = key_core_evt_cb; + + return true; +} + +void app_key_core_polling_10ms() +{ + for (uint8_t key_idx = 0; key_idx < APP_KEY_REG_COUNT_MAX; key_idx++) + { + if (s_key_core_info[key_idx].is_in_polling) + { + app_key_core_click_read(key_idx); + } + } +} + +void app_key_core_key_wait_polling_record(uint8_t key_idx) +{ + s_key_core_info[key_idx].is_in_polling = true; +} + +void app_key_core_key_pressed_record(uint8_t key_idx, bool is_pressed) +{ + s_key_core_info[key_idx].is_pressed = is_pressed; +} + +bool app_key_core_is_all_release(void) +{ + for (uint8_t key_idx = 0; key_idx < APP_KEY_REG_COUNT_MAX; key_idx++) + { + if (s_key_core_info[key_idx].is_pressed) + { + return false; + } + } + + return true; +} + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.h new file mode 100644 index 0000000..0b8bcd3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_key/app_key_core.h @@ -0,0 +1,146 @@ +/** + **************************************************************************************** + * + * @file App key core.h + * + * @brief App Key Core API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __APP_KEY_CORE_H__ +#define __APP_KEY_CORE_H__ + +#include +#include + +/** + * @defgroup APP_KEY_CORE_MAROC Defines + * @{ + */ +#define APP_KEY_REG_COUNT_MAX 10 /**< Maximum number of key instance can register, which can be configurable. */ +#define APP_KEY_DOUBLE_TIME_COUNT 50 /**< Double click time count(in unit of 10ms), which can be configurable. */ +#define APP_KEY_LONG_TIME_COUNT 100 /**< Long click time count(in uint of 10ms), which can be configurable. */ +#define APP_KEY_CONTINUE_TIME_COUNT 20 /**< Continue click time count(in uint of 10ms), which can be configurable. */ +/** @} */ + +/** + * @defgroup APP_KEY_CORE_ENUM Enumerations + * @{ + */ +/**@brief App key polling state. */ +typedef enum +{ + APP_KEY_STA_INIT, /**< Key initialization state for key scan procedure. */ + APP_KEY_STA_DEBOUNCE, /**< Key debounce state for key scan procedure. */ + APP_KEY_STA_PRESS, /**< Key press state for key scan procedure. */ + APP_KEY_STA_WAITE_RELEASE, /**< Waite key release state for key scan procedure. */ + APP_KEY_STA_NO_CLICK, /**< Key no click state for key read procedure. */ + APP_KEY_STA_SINGLE_CLICK, /**< Key single click state for key read procedure. */ + APP_KEY_STA_DOUBLE_CLICK, /**< Key double click state for key read procedure. */ + APP_KEY_STA_LONG_CLICK, /**< Key long click state for key read procedure. */ + APP_KEY_STA_CONTINUE_CLICK, /**< Key continue click state for key read procedure. */ + APP_KEY_STA_RELEASE, /**< key continue click release state. */ +} app_key_state_t; + +/**@brief App key click event type. */ +typedef enum +{ + APP_KEY_NO_CLICK, /**< Key no click event. */ + APP_KEY_SINGLE_CLICK, /**< Key single click event. */ + APP_KEY_DOUBLE_CLICK, /**< Key double click event. */ + APP_KEY_LONG_CLICK, /**< Key long click event. */ + APP_KEY_CONTINUE_CLICK, /**< Key continue click event. */ + APP_KEY_CONTINUE_RELEASE /**< Key continue click release. */ +} app_key_click_type_t; +/** @} */ + +/** + * @defgroup APP_KEY_CORE_TYPEDEF Typedefs + * @{ + */ +/**@brief APP Key core event callback.*/ +typedef void (*app_key_core_evt_cb_t)(uint8_t key_idx, app_key_click_type_t key_click_type); +/** @} */ + +/** + * @defgroup APP_KEY_CORE_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Register app key click event callback. + * + * @param[in] key_core_evt_cb: Key core event callback. + * + * @return Result of key core event callback is NULL or not. + ***************************************************************************************** + */ +bool app_key_core_cb_register(app_key_core_evt_cb_t key_core_evt_cb); + +/** + ***************************************************************************************** + * @brief Record app key is pressed down. + * + * @param[in] key_idx: Index of key register. + * @param[in] is_pressed: True or false + ***************************************************************************************** + */ +void app_key_core_key_pressed_record(uint8_t key_idx, bool is_pressed); + +/** + ***************************************************************************************** + * @brief Notificaiton which key is waiting for polling. + * + * @param[in] key_idx: Index of key register. + ***************************************************************************************** + */ +void app_key_core_key_wait_polling_record(uint8_t key_idx); + +/** + ***************************************************************************************** + * @brief Check all keys are released or not. + * + * @return Result of checking. + ***************************************************************************************** + */ +bool app_key_core_is_all_release(void); + +/** + ***************************************************************************************** + * @brief App key state polling. + ***************************************************************************************** + */ +void app_key_core_polling_10ms(void); +/** @} */ + +#endif +/** @} */ +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/BUILD.gn new file mode 100644 index 0000000..feff43b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_linked_list") { + sources = [ "app_linked_list.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.c new file mode 100644 index 0000000..721f6ea --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.c @@ -0,0 +1,254 @@ +/** + ***************************************************************************************** + * + * @file app_linked_list.c + * + * @brief App Linked List Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_linked_list.h" +#include + + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +sdk_err_t app_s_list_init(app_s_list_t *p_s_list) +{ + if (NULL == p_s_list) + { + return SDK_ERR_POINTER_NULL; + } + + p_s_list->p_head = NULL; + p_s_list->size = 0; + + return SDK_SUCCESS; +} + + +app_s_list_node_t *app_s_list_node_append(app_s_list_t *p_s_list) +{ + app_s_list_node_t *p_iterator_node; + app_s_list_node_t *p_s_insert_node; + + if (NULL == p_s_list) + { + return NULL; + } + + p_s_insert_node = app_malloc(sizeof(app_s_list_node_t)); + + if (NULL == p_s_insert_node) + { + return NULL; + } + + memset(p_s_insert_node, 0, sizeof(app_s_list_node_t)); + + if (NULL == p_s_list->p_head) + { + p_s_list->p_head = p_s_insert_node; + p_s_list->size = 1; + + return p_s_insert_node; + } + + p_iterator_node = p_s_list->p_head; + + while(p_iterator_node->p_next_node) + { + p_iterator_node = p_iterator_node->p_next_node; + } + + p_iterator_node->p_next_node = p_s_insert_node; + p_s_insert_node->p_next_node = NULL; + + p_s_list->size++; + + return p_s_insert_node; +} + +app_s_list_node_t *app_s_list_node_insert(app_s_list_t *p_s_list, app_s_list_node_t *p_dgt_node, bool is_ahead) +{ + app_s_list_node_t *p_previous_node; + app_s_list_node_t *p_iterator_node; + app_s_list_node_t *p_s_insert_node; + + if (NULL == p_s_list || NULL == p_dgt_node) + { + return NULL; + } + + p_s_insert_node = app_malloc(sizeof(app_s_list_node_t)); + + if (NULL == p_s_insert_node) + { + return NULL; + } + + + p_previous_node = p_s_list->p_head; + p_iterator_node = p_s_list->p_head; + + do + { + if (p_iterator_node == p_dgt_node) + { + break; + } + + p_previous_node = p_iterator_node; + p_iterator_node = p_iterator_node->p_next_node; + + } while (p_iterator_node); + + if (NULL == p_iterator_node) + { + return NULL; + } + + if (is_ahead) + { + if (p_iterator_node == p_s_list->p_head) + { + p_s_insert_node->p_next_node = p_iterator_node; + p_s_list->p_head = p_s_insert_node; + } + else + { + p_s_insert_node->p_next_node = p_iterator_node; + p_previous_node->p_next_node = p_s_insert_node; + } + } + else + { + p_s_insert_node->p_next_node = p_iterator_node->p_next_node; + p_iterator_node->p_next_node = p_s_insert_node; + } + + p_s_list->size++; + + return p_s_insert_node; +} + +sdk_err_t app_s_list_node_delete(app_s_list_t *p_s_list, app_s_list_node_t *p_s_list_node, bool free_data) +{ + app_s_list_node_t *p_previous_node; + app_s_list_node_t *p_iterator_node; + + if (NULL == p_s_list || NULL == p_s_list_node) + { + return SDK_ERR_POINTER_NULL; + } + + if (p_s_list_node == p_s_list->p_head) + { + p_s_list->p_head = p_s_list_node->p_next_node; + if (free_data) + { + app_free(p_s_list_node->p_data); + } + app_free(p_s_list_node); + + return SDK_SUCCESS; + } + + p_previous_node = p_s_list->p_head; + p_iterator_node = p_s_list->p_head; + + do + { + if (p_iterator_node == p_s_list_node) + { + break; + } + + p_previous_node = p_iterator_node; + p_iterator_node = p_iterator_node->p_next_node; + + } while (p_iterator_node); + + if (NULL == p_iterator_node) + { + return SDK_ERR_LIST_ITEM_NOT_FOUND; + } + + p_previous_node->p_next_node = p_iterator_node->p_next_node; + if (free_data) + { + app_free(p_s_list_node->p_data); + } + app_free(p_s_list_node); + + p_s_list->size--; + + return SDK_SUCCESS; +} + +sdk_err_t app_s_list_clear(app_s_list_t *p_s_list, bool free_data) +{ + app_s_list_node_t *p_iterator_node; + + if (NULL == p_s_list) + { + return SDK_ERR_POINTER_NULL; + } + + if (NULL == p_s_list->p_head) + { + return SDK_SUCCESS; + } + + p_iterator_node = p_s_list->p_head; + + while (p_iterator_node) + { + if (free_data) + { + app_free(p_iterator_node->p_data); + } + p_s_list->p_head = p_iterator_node->p_next_node; + app_free(p_iterator_node); + p_iterator_node = p_s_list->p_head; + }; + + p_s_list->size = 0; + + return SDK_SUCCESS; +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.h new file mode 100644 index 0000000..4672dbb --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_linked_list/app_linked_list.h @@ -0,0 +1,136 @@ +/** + **************************************************************************************** + * + * @file app_linked_list.h + * + * @brief App Linked List API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_LINKED_LIST_H__ +#define __APP_LINKED_LIST_H__ + +#include "grx_hal.h" +#include "grx_sys.h" +#include "app_memory.h" +#include +#include + +/** + * @defgroup APP_LINKED_LIST_STRUCT Structures + * @{ + */ +/**@brief App Singly Linked List Node */ +typedef struct singly_list_node +{ + void *p_data; /**< Pointer to data. */ + struct singly_list_node *p_next_node; /**< Pointer to next node. */ +} app_s_list_node_t; + +/**@brief App Singly Linked List */ +typedef struct +{ + app_s_list_node_t *p_head; /**< Pointer to head node. */ + uint32_t size; /**< Size of list. */ +} app_s_list_t; +/** @} */ + +/** + * @defgroup APP_LINKED_LIST_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize one singly linked list instance. + * + * @param[in] p_s_list: Pointer to a singly linked list instance. + * + * @return Result of initialization. + ***************************************************************************************** + */ +sdk_err_t app_s_list_init(app_s_list_t *p_s_list); + +/** + ***************************************************************************************** + * @brief Append one singly linked list node at tail. + * + * @param[in] p_s_list: Pointer to a singly linked list instance. + * + * @return Pointer to append node. + ***************************************************************************************** + */ +app_s_list_node_t *app_s_list_node_append(app_s_list_t *p_s_list); + +/** + ***************************************************************************************** + * @brief Insert one singly linked list node into designated location. + * + * @param[in] p_s_list: Pointer to a singly linked list instance. + * @param[in] p_dgt_node: Pointer to a designated singly linked list node. + * @param[in] is_ahead: True: insert in ahead of designated node, False: insert in behind of designated node. + * + * @return Pointer to insert node. + ***************************************************************************************** + */ +app_s_list_node_t *app_s_list_node_insert(app_s_list_t *p_s_list, app_s_list_node_t *p_dgt_node, bool is_ahead); + +/** + ***************************************************************************************** + * @brief Delete one designated singly linked list node. + * + * @param[in] p_s_list: Pointer to a singly linked list instance. + * @param[in] p_s_list_node: Pointer to a designated singly linked list node. + * @param[in] free_data: Free node data or not. + * + * @return Result of delete. + ***************************************************************************************** + */ +sdk_err_t app_s_list_node_delete(app_s_list_t *p_s_list, app_s_list_node_t *p_s_list_node, bool free_data); + +/** + ***************************************************************************************** + * @brief Clear one singly linked list instance. + * + * @param[in] p_s_list: Pointer to a singly linked list instance. + * @param[in] free_data: Free node data or not. + * + * @return Result of clear. + ***************************************************************************************** + */ +sdk_err_t app_s_list_clear(app_s_list_t *p_s_list, bool free_data); + + + +/** @} */ + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/BUILD.gn new file mode 100644 index 0000000..3731c62 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_log") { + sources = [ + "app_log.c", + "app_log_dump_port.c", + "app_log_store.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.c old mode 100755 new mode 100644 index 1cdf35c..bed1ec3 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.c @@ -39,18 +39,17 @@ * INCLUDE FILES ***************************************************************************************** */ +#include "app_log.h" #include #include #include -#include "app_log.h" /* * DEFINE ***************************************************************************************** */ #if APP_LOG_COLOR_ENABLE -/**@brief CSI(Control Sequence Introducer/Initiator) sign more information on - * https://en.wikipedia.org/wiki/ANSI_escape_code. */ +/**@brief CSI(Control Sequence Introducer/Initiator) sign more information on https://en.wikipedia.org/wiki/ANSI_escape_code. */ #define CSI_START "\033[" #define CSI_END "\033[0m" @@ -100,18 +99,18 @@ #endif -#define BIT_8 8 - /* * STRUCTURES ***************************************************************************************** */ /**@brief App log environment variable. */ -struct app_log_env_t { +struct app_log_env_t +{ app_log_init_t app_log_init; /**< App log initialization variables. */ bool is_filter_set; /**< App log filter is set or not. */ app_log_trans_func_t trans_func; /**< App log transmit function. */ app_log_flush_func_t flush_func; /**< App log flush function. */ + }; /* @@ -120,7 +119,8 @@ struct app_log_env_t { */ static uint8_t s_log_encode_buf[APP_LOG_LINE_BUF_SIZE]; /**< App log data encode buffer. */ -static const char *s_log_svt_lvl_output_info[] = { /**< App log severity level outpout information. */ +static const char *s_log_svt_lvl_output_info[] = /**< App log severity level outpout information. */ +{ [APP_LOG_LVL_ERROR] = "APP_E: ", [APP_LOG_LVL_WARNING] = "APP_W: ", [APP_LOG_LVL_INFO] = "APP_I: ", @@ -128,7 +128,8 @@ static const char *s_log_svt_lvl_output_info[] = { /**< App log severi }; #if APP_LOG_COLOR_ENABLE -static const char *s_log_color_output_info[] = { /**< App log level outpout color information. */ +static const char *s_log_color_output_info[] = /**< App log level outpout color information. */ +{ [APP_LOG_LVL_ERROR] = APP_LOG_COLOR_ERROR, [APP_LOG_LVL_WARNING] = APP_LOG_COLOR_WARNING, [APP_LOG_LVL_INFO] = APP_LOG_COLOR_INFO, @@ -157,17 +158,21 @@ static struct app_log_env_t s_app_log_env; /**< App log enviro static uint16_t app_log_strcpy(uint16_t wr_idx, uint8_t *p_log_buff, const char *p_log_data) { uint16_t cpy_length = 0; - char *temp_p_log_data = p_log_data; - if (!p_log_buff || !temp_p_log_data) { + if (!p_log_buff || !p_log_data) + { return cpy_length; } - while (*temp_p_log_data != 0) { - if ((wr_idx + cpy_length) < APP_LOG_LINE_BUF_SIZE) { - p_log_buff[wr_idx + cpy_length] = *temp_p_log_data++; + while (*p_log_data != 0) + { + if ((wr_idx + cpy_length) < APP_LOG_LINE_BUF_SIZE) + { + p_log_buff[wr_idx + cpy_length] = *p_log_data++; cpy_length++; - } else { + } + else + { break; } } @@ -187,11 +192,15 @@ static uint16_t app_log_strcpy(uint16_t wr_idx, uint8_t *p_log_buff, const char */ static bool app_log_is_fmt_set(uint8_t level, uint8_t fmt) { - if (s_app_log_env.app_log_init.fmt_set[level] & fmt) { + if (s_app_log_env.app_log_init.fmt_set[level] & fmt) + { return true; - } else { + } + else + { return false; } + } /** @@ -206,11 +215,13 @@ static bool app_log_is_fmt_set(uint8_t level, uint8_t fmt) */ static void app_log_data_trans(uint8_t *p_data, uint16_t length) { - if (p_data == NULL || length == 0) { + if (NULL == p_data || 0 == length) + { return; } - if (s_app_log_env.trans_func) { + if (s_app_log_env.trans_func) + { s_app_log_env.trans_func(p_data, length); } @@ -225,13 +236,18 @@ static void app_log_data_trans(uint8_t *p_data, uint16_t length) */ sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_func, app_log_flush_func_t flush_func) { - if (NULL == p_log_init) { + if (NULL == p_log_init) + { s_app_log_env.is_filter_set = false; - memset_s(&s_app_log_env.app_log_init, sizeof (s_app_log_env.app_log_init), 0, sizeof(app_log_init_t)); - } else if (p_log_init->filter.level <= APP_LOG_LVL_DEBUG) { + memset(&s_app_log_env.app_log_init, 0, sizeof(app_log_init_t)); + } + else if ( p_log_init->filter.level <= APP_LOG_LVL_DEBUG) + { s_app_log_env.is_filter_set = true; - memset_s(&s_app_log_env.app_log_init, sizeof (s_app_log_env.app_log_init), p_log_init, sizeof(app_log_init_t)); - } else { + memcpy(&s_app_log_env.app_log_init, p_log_init, sizeof(app_log_init_t)); + } + else + { return SDK_ERR_INVALID_PARAM; } @@ -241,92 +257,28 @@ sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_fu return SDK_SUCCESS; } -uint16_t encode_name(uint8_t level, const char *file, const char *func, const long line) -{ - uint16_t log_length = 0; - char line_num[APP_LOG_LINE_NB_LEN_MAX + 1] = { 0 }; - - // Encode file directory name , function name and lune number info. - if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR | APP_LOG_FMT_FUNC | APP_LOG_FMT_LINE)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, "("); - - if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, file); - - if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, " "); - } else if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, ":"); - } - } - - if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, func); - - if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) { - log_length += app_log_strcpy(log_length, s_log_encode_buf, " Line:"); - } - } - - if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) { - snprintf_s(line_num, sizeof (line_num), APP_LOG_LINE_NB_LEN_MAX, "%ld", line); - log_length += app_log_strcpy(log_length, s_log_encode_buf, line_num); - } - - log_length += app_log_strcpy(log_length, s_log_encode_buf, ") "); - } - return log_length; -} - -uint16_t calculate_log_length(uint16_t log_length, int fmt_result) -{ - uint8_t newline_length = strlen(APP_LOG_NEWLINE_SIGN); - uint16_t log_len = log_length; - // Calculate log length - if ((fmt_result > -1) && (log_len + fmt_result) <= APP_LOG_LINE_BUF_SIZE) { - log_len += fmt_result; - } else { - log_len = APP_LOG_LINE_BUF_SIZE; - } - -#if APP_LOG_COLOR_ENABLE - if (log_len + (sizeof(CSI_END) - 1) + newline_length > APP_LOG_LINE_BUF_SIZE) { - log_len = APP_LOG_LINE_BUF_SIZE; - // Reserve some space for CSI end sign. - log_len -= sizeof(CSI_END) - 1; -#else - if (log_len + newline_length > APP_LOG_LINE_BUF_SIZE) { - log_len = APP_LOG_LINE_BUF_SIZE; -#endif - log_len -= newline_length; - } - -#if APP_LOG_COLOR_ENABLE - // Encode CSI end sign. - log_len += app_log_strcpy(log_len, s_log_encode_buf, CSI_END); -#endif - - // Encode newline sign. - log_len += app_log_strcpy(log_len, s_log_encode_buf, APP_LOG_NEWLINE_SIGN); - return log_len; -} - -void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, - const char *format, ...) +void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, const char *format, ...) { uint16_t log_length = 0; + uint8_t newline_length = strlen(APP_LOG_NEWLINE_SIGN); int fmt_result = 0; + char line_num[APP_LOG_LINE_NB_LEN_MAX + 1] = { 0 }; va_list ap; - if (level > s_app_log_env.app_log_init.filter.level && s_app_log_env.is_filter_set) { + if (level > s_app_log_env.app_log_init.filter.level && s_app_log_env.is_filter_set) + { return; } + #if APP_LOG_TAG_ENABLE - if (!strstr(tag, s_app_log_env.app_log_init.filter.tag)) { + if (!strstr(tag, s_app_log_env.app_log_init.filter.tag)) + { return; } #endif + va_start(ap, format); + APP_LOG_LOCK(); #if APP_LOG_COLOR_ENABLE @@ -336,25 +288,98 @@ void app_log_output(uint8_t level, const char *tag, const char *file, const char #endif // Encode level info. - if (app_log_is_fmt_set(level, APP_LOG_FMT_LVL)) { + if (app_log_is_fmt_set(level, APP_LOG_FMT_LVL)) + { log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[level]); } #if APP_LOG_TAG_ENABLE // Encode tag info. - if (app_log_is_fmt_set(level, APP_LOG_FMT_TAG)) { + if (app_log_is_fmt_set(level, APP_LOG_FMT_TAG)) + { log_length += app_log_strcpy(log_length, s_log_encode_buf, tag); log_length += app_log_strcpy(log_length, s_log_encode_buf, " "); } #endif - log_length = encode_name(level, file, func, line); + + // Encode file directory name , function name and lune number info. + if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR | APP_LOG_FMT_FUNC | APP_LOG_FMT_LINE)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, "("); + + if (app_log_is_fmt_set(level, APP_LOG_FMT_DIR)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, file); + + if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, " "); + } + else if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, ":"); + } + } + + if (app_log_is_fmt_set(level, APP_LOG_FMT_FUNC)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, func); + + if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, " Line:"); + } + } + + if (app_log_is_fmt_set(level, APP_LOG_FMT_LINE)) + { + snprintf(line_num, APP_LOG_LINE_NB_LEN_MAX, "%ld", line); + log_length += app_log_strcpy(log_length, s_log_encode_buf, line_num); + } + + log_length += app_log_strcpy(log_length, s_log_encode_buf, ") "); + } + // Encode other log data to buffer. '\0' must be added in the end by vsnprintf. */ - fmt_result = vsnprintf_s((char *)s_log_encode_buf + log_length, sizeof (s_log_encode_buf), - APP_LOG_LINE_BUF_SIZE - log_length, format, ap); + fmt_result = vsnprintf((char *)s_log_encode_buf + log_length, APP_LOG_LINE_BUF_SIZE - log_length, format, ap); va_end(ap); - log_length = calculate_log_length(log_length, fmt_result); + + // Calculate log length + if ((fmt_result > -1) && (log_length + fmt_result) <= APP_LOG_LINE_BUF_SIZE) + { + log_length += fmt_result; + } + else + { + log_length = APP_LOG_LINE_BUF_SIZE; + } + +#if APP_LOG_COLOR_ENABLE + if (log_length + (sizeof(CSI_END) - 1) + newline_length > APP_LOG_LINE_BUF_SIZE) + { + log_length = APP_LOG_LINE_BUF_SIZE; + // Reserve some space for CSI end sign. + log_length -= sizeof(CSI_END) - 1; +#else + if (log_length + newline_length > APP_LOG_LINE_BUF_SIZE) + { + log_length = APP_LOG_LINE_BUF_SIZE; +#endif + log_length -= newline_length; + } + +#if APP_LOG_COLOR_ENABLE + // Encode CSI end sign. + log_length += app_log_strcpy(log_length, s_log_encode_buf, CSI_END); +#endif + + // Encode newline sign. + log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN); + + app_log_data_trans(s_log_encode_buf, log_length); + APP_LOG_UNLOCK(); } @@ -368,10 +393,14 @@ void app_log_raw_info(const char *format, ...) APP_LOG_LOCK(); - fmt_result = vsnprintf_s((char *)s_log_encode_buf, sizeof(s_log_encode_buf), APP_LOG_LINE_BUF_SIZE, format, ap); - if ((fmt_result > -1) && (fmt_result) <= APP_LOG_LINE_BUF_SIZE) { + fmt_result = vsnprintf((char *)s_log_encode_buf, APP_LOG_LINE_BUF_SIZE, format, ap); + + if ((fmt_result > -1) && (fmt_result) <= APP_LOG_LINE_BUF_SIZE) + { log_length = fmt_result; - } else { + } + else + { log_length = APP_LOG_LINE_BUF_SIZE; } @@ -380,50 +409,132 @@ void app_log_raw_info(const char *format, ...) APP_LOG_UNLOCK(); } -void app_log_hex_dump(uint8_t *p_data, uint16_t length) +void app_log_hex_dump(void *p_data, uint16_t length) { uint16_t log_length = 0; uint16_t convert_idx = 0; + uint16_t line_num = 0; char dump_str[8] = {0}; APP_LOG_LOCK(); - for (convert_idx = 0; convert_idx < length; convert_idx++) { - if (log_length >= APP_LOG_LINE_BUF_SIZE) { - log_length = APP_LOG_LINE_BUF_SIZE; - break; + line_num = length / APP_LOG_PER_LINE_HEX_DUMP_SIZE; + + for (uint8_t i = 0; i < line_num; i ++) + { + if (app_log_is_fmt_set(APP_LOG_LVL_DEBUG, APP_LOG_FMT_LVL)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[APP_LOG_LVL_DEBUG]); } - if (p_data[convert_idx] < ' ') { - s_log_encode_buf[log_length] = '.'; - log_length++; - } else { - snprintf_s(dump_str, sizeof (dump_str), BIT_8, "%02X ", p_data[convert_idx]); + for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++) + { + snprintf(dump_str, 8, "%02X ", ((uint8_t *)p_data)[convert_idx++]); log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str); } + + if (convert_idx % APP_LOG_PER_LINE_HEX_DUMP_SIZE == 0) + { + snprintf(dump_str, 8, " | "); + log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str); + convert_idx -= APP_LOG_PER_LINE_HEX_DUMP_SIZE; + for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++) + { + if (((uint8_t *)p_data)[convert_idx] < ' ' || ((uint8_t *)p_data)[convert_idx] > 0x7f) + { + s_log_encode_buf[log_length] = '.'; + log_length++; + } + else + { + s_log_encode_buf[log_length] = ((uint8_t *)p_data)[convert_idx]; + log_length++; + } + convert_idx++; + } + } + log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN); + app_log_data_trans(s_log_encode_buf, log_length); + log_length = 0; } - app_log_data_trans(s_log_encode_buf, log_length); + if (length % APP_LOG_PER_LINE_HEX_DUMP_SIZE) + { + if (app_log_is_fmt_set(APP_LOG_LVL_DEBUG, APP_LOG_FMT_LVL)) + { + log_length += app_log_strcpy(log_length, s_log_encode_buf, s_log_svt_lvl_output_info[APP_LOG_LVL_DEBUG]); + } + + for (uint8_t j = 0; j < length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++) + { + snprintf(dump_str, 8, "%02X ", ((uint8_t *)p_data)[convert_idx++]); + log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str); + } + + for (uint8_t j = 0; j < APP_LOG_PER_LINE_HEX_DUMP_SIZE -length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++) + { + snprintf(dump_str, 8, " "); + log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str); + } + + snprintf(dump_str, 8, " | "); + log_length += app_log_strcpy(log_length, s_log_encode_buf, dump_str); + convert_idx -= length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; + for (uint8_t j = 0; j < length % APP_LOG_PER_LINE_HEX_DUMP_SIZE; j++) + { + if (((uint8_t *)p_data)[convert_idx] < ' ' || ((uint8_t *)p_data)[convert_idx] > 0x7f) + { + s_log_encode_buf[log_length] = '.'; + log_length++; + } + else + { + s_log_encode_buf[log_length] = ((uint8_t *)p_data)[convert_idx]; + log_length++; + } + convert_idx++; + } + + log_length += app_log_strcpy(log_length, s_log_encode_buf, APP_LOG_NEWLINE_SIGN); + app_log_data_trans(s_log_encode_buf, log_length); + } APP_LOG_UNLOCK(); } void app_log_flush(void) { - if (s_app_log_env.flush_func) { + if (s_app_log_env.flush_func) + { s_app_log_env.flush_func(); } } + #if IO_REDIRECT == 0 #if defined(__CC_ARM) -struct __FILE { +struct __FILE +{ int handle; }; -FILE s_stdout; -FILE s_stdin; +FILE __stdout; +FILE __stdin; + +#if !defined(__MICROLIB) +void _sys_exit(int x) { + x = x; +} + +void _ttywrch(int ch) { + ch = ch; +} + +void _sys_command_string(int y) { + y = y; +} +#endif int fputc(int ch, FILE *file) { @@ -437,11 +548,11 @@ int fputc(int ch, FILE *file) int _write(int file, const char *buf, int len) { int tx_len = 0; - char *temp_buf = buf; - while (tx_len < len) { + while (tx_len < len) + { app_log_data_trans((uint8_t *)buf, 1); - temp_buf++; + buf++; tx_len++; } return tx_len; @@ -449,14 +560,14 @@ int _write(int file, const char *buf, int len) #elif defined(__ICCARM__) -size_t s_write(int handle, const unsigned char *buf, size_t size) +size_t __write(int handle, const unsigned char *buf, size_t size) { size_t len = 0; - unsigned char* temp_buf = buf; - while (len < size) { + while (len < size) + { app_log_data_trans((uint8_t *)buf, 1); - temp_buf++; + buf++; len++; } return len; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.h old mode 100755 new mode 100644 index a26bc1d..4680bc3 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log.h @@ -39,8 +39,8 @@ #define __APP_LOG_H__ #include "custom_config.h" -#include "gr55xx_sys.h" -#include "gr55xx_hal.h" +#include "grx_sys.h" +#include "grx_hal.h" #if APP_LOG_STORE_ENABLE #include "app_log_store.h" #endif @@ -71,11 +71,12 @@ #define APP_LOG_UNLOCK() LOCAL_INT_RESTORE() /**< APP log unlock. */ #ifndef APP_LOG_TAG -#define APP_LOG_TAG "NO_TAG" /**< Default app log tag. */ + #define APP_LOG_TAG "NO_TAG" /**< Default app log tag. */ #endif #define APP_LOG_LINE_BUF_SIZE 256 /**< Buffer size for every line's log. */ -#define APP_LOG_SEVERITY_LEVEL APP_LOG_LVL_DEBUG /**< Default log severity level. */ +#define APP_LOG_PER_LINE_HEX_DUMP_SIZE 8 /**< Hex char dump size in per line. */ +#define APP_LOG_SEVERITY_LEVEL APP_LOG_LVL_DEBUG /**< Default log severity level. */ #define APP_LOG_TAG_LEN_MAX 20 /**< Maximum length of output filter's tag. */ #define APP_LOG_LINE_NB_LEN_MAX 5 /**< Maximum length of output line number. */ #define APP_LOG_NEWLINE_SIGN "\r\n" /**< Newline sign output. */ @@ -106,43 +107,39 @@ /** @} */ #if APP_LOG_PRINTF_ENABLE -#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_ERROR -#define APP_LOG_ERROR(...) app_log_output(APP_LOG_LVL_ERROR, APP_LOG_TAG, \ - __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) -#else -#define APP_LOG_ERROR(...) -#endif + #if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_ERROR + #define APP_LOG_ERROR(...) app_log_output(APP_LOG_LVL_ERROR, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + #else + #define APP_LOG_ERROR(...) + #endif -#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_WARNING -#define APP_LOG_WARNING(...) app_log_output(APP_LOG_LVL_WARNING, APP_LOG_TAG, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) -#else -#define APP_LOG_WARNING(...) -#endif + #if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_WARNING + #define APP_LOG_WARNING(...) app_log_output(APP_LOG_LVL_WARNING, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + #else + #define APP_LOG_WARNING(...) + #endif -#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_INFO -#define APP_LOG_INFO(...) app_log_output(APP_LOG_LVL_INFO, APP_LOG_TAG, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) -#else -#define APP_LOG_INFO(...) -#endif + #if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_INFO + #define APP_LOG_INFO(...) app_log_output(APP_LOG_LVL_INFO, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + #else + #define APP_LOG_INFO(...) + #endif -#if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_DEBUG -#define APP_LOG_DEBUG(...) app_log_output(APP_LOG_LVL_DEBUG, APP_LOG_TAG, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) -#else -#define APP_LOG_DEBUG(...) -#endif + #if APP_LOG_SEVERITY_LEVEL >= APP_LOG_LVL_DEBUG + #define APP_LOG_DEBUG(...) app_log_output(APP_LOG_LVL_DEBUG, APP_LOG_TAG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + #else + #define APP_LOG_DEBUG(...) + #endif -#define APP_LOG_RAW_INFO(...) app_log_raw_info(__VA_ARGS__) -#define APP_LOG_HEX_DUMP(p_data, length) app_log_hex_dump(p_data, length) + #define APP_LOG_RAW_INFO(...) app_log_raw_info( __VA_ARGS__) + #define APP_LOG_HEX_DUMP(p_data, length) app_log_hex_dump(p_data, length) #else -#define APP_LOG_ERROR(...) -#define APP_LOG_WARNING(...) -#define APP_LOG_INFO(...) -#define APP_LOG_DEBUG(...) -#define APP_LOG_RAW_INFO(...) -#define APP_LOG_HEX_DUMP(p_data, length) + #define APP_LOG_ERROR(...) + #define APP_LOG_WARNING(...) + #define APP_LOG_INFO(...) + #define APP_LOG_DEBUG(...) + #define APP_LOG_RAW_INFO(...) + #define APP_LOG_HEX_DUMP(p_data, length) #endif /** @} */ @@ -162,13 +159,15 @@ typedef void (*app_log_flush_func_t)(void); * @{ */ /**@brief App log filter. */ -typedef struct { +typedef struct +{ uint8_t level; /**< App log filter level. */ char tag[APP_LOG_TAG_LEN_MAX + 1]; /**< App log filter tag. */ } app_log_filter_t; /**@brief App log init stucture. */ -typedef struct { +typedef struct +{ app_log_filter_t filter; /**< App log filter. */ uint8_t fmt_set[APP_LOG_LVL_NB]; /**< Format of app log. See @ref APP_LOG_FMT.*/ } app_log_init_t; @@ -185,7 +184,6 @@ typedef struct { * @param[in] p_log_feat: Pointer to app log feature set. * @param[in] trans_func: App log transmit function. * @param[in] flush_func: App log flush function. - * * @return Result of initialization. ***************************************************************************************** @@ -205,8 +203,7 @@ sdk_err_t app_log_init(app_log_init_t *p_log_init, app_log_trans_func_t trans_fu * @param[in] ...: Arguments. ***************************************************************************************** */ -void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, - const char *format, ...); +void app_log_output(uint8_t level, const char *tag, const char *file, const char *func, const long line, const char *format, ...); /** ***************************************************************************************** @@ -226,7 +223,7 @@ void app_log_raw_info(const char *format, ...); * @param[in] length Length of data. ***************************************************************************************** */ -void app_log_hex_dump(uint8_t *p_data, uint16_t length); +void app_log_hex_dump(void *p_data, uint16_t length); /** ***************************************************************************************** @@ -237,3 +234,7 @@ void app_log_flush(void); /** @} */ #endif + + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.c new file mode 100644 index 0000000..5672e10 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.c @@ -0,0 +1,231 @@ +/** + ***************************************************************************************** + * + * @file app_log_store_dump_port.c + * + * @brief App Log store dump port Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "app_log_dump_port.h" +#include "app_log_store.h" +#include "lms.h" +#include "app_error.h" +#include "custom_config.h" + +#if APP_LOG_STORE_ENABLE +/* + * DEFINE + ***************************************************************************************** + */ + + +/* + * STRUCTURES + ***************************************************************************************** + */ + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static void lms_log_length_send(uint32_t log_len); +static void lms_data_send(uint8_t *p_data, uint16_t length); +static void lms_data_send_finish_cb(void); +static app_log_dump_cbs_t s_dump_cbs = +{ + .dump_start_cb = lms_log_length_send, + .dump_process_cb = lms_data_send, + .dump_finish_cb = lms_data_send_finish_cb +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint8_t *s_send_data_addr = NULL; +static uint16_t s_send_block_size = 0; +static uint32_t s_sended_len = 0; +static uint16_t s_once_size = 20; +static uint32_t s_checksum = 0; + +static void lms_log_length_send(uint32_t log_len) +{ + sdk_err_t error_code; + uint8_t arr[10] = {0}; + arr[0] = 0x81; + arr[1] = 0; + arr[2] = log_len; + arr[3] = log_len >> 8; + arr[4] = log_len >> 16; + arr[5] = log_len >> 24; + error_code = lms_notify_cmd(0, arr, 6); + APP_ERROR_CHECK(error_code); +} + +static void lms_data_send(uint8_t *p_data, uint16_t length) +{ + for(uint16_t i = 0; i < length; i++) + s_checksum += p_data[i]; + + sdk_err_t error_code; + s_send_block_size = length; + s_send_data_addr = p_data; + + if (s_send_block_size > s_once_size) + { + s_sended_len += s_once_size; + error_code = lms_notify_data(0, s_send_data_addr, s_once_size); + APP_ERROR_CHECK(error_code); + } + else + { + s_sended_len += s_send_block_size; + error_code = lms_notify_data(0, s_send_data_addr, s_send_block_size); + APP_ERROR_CHECK(error_code); + } +} +static void lms_data_continue_send(void) +{ + if (NULL == s_send_data_addr) + { + return; + } + sdk_err_t error_code; + uint16_t remain = s_send_block_size - s_sended_len; + uint16_t offset = 0; + + if (remain > s_once_size) + { + offset = s_sended_len; + s_sended_len += s_once_size; + + error_code = lms_notify_data(0, &s_send_data_addr[offset], s_once_size); + APP_ERROR_CHECK(error_code); + } + else if(remain > 0) + { + offset = s_sended_len; + s_sended_len += remain; + error_code = lms_notify_data(0, &s_send_data_addr[offset],remain); + APP_ERROR_CHECK(error_code); + } + else + { + //vPortFree(s_send_data_addr); + s_send_data_addr = NULL; + s_send_block_size = 0; + s_sended_len = 0; + app_log_dump_continue(); + } +} + +static void lms_data_send_finish_cb(void) +{ + uint8_t arr[5] = {0}; + arr[0] = 0xc1; + arr[1] = s_checksum; + arr[2] = s_checksum >> 8; + arr[3] = s_checksum >> 16; + arr[4] = s_checksum >> 24; + lms_notify_cmd(0, arr, 5); + s_checksum = 0; +} + +static void lms_service_process_event(lms_evt_t *p_evt) +{ + uint8_t arr[10] = {0}; + sdk_err_t error_code; + switch (p_evt->evt_type) + { + case LMS_EVT_CMD_RECEIVE_DATA: + if (1 == p_evt->p_data[0]) + { + error_code = app_log_store_dump(&s_dump_cbs); + if (error_code) + { + arr[0] = 0x81; + arr[1] = error_code; + error_code = lms_notify_cmd(0, arr, 6); + APP_ERROR_CHECK(error_code); + } + } + else if(2 == p_evt->p_data[0]) + { + error_code = app_log_store_clear(); + APP_ERROR_CHECK(error_code); + arr[0] = 0x82; + arr[1] = 0; + error_code = lms_notify_cmd(0, arr, 2); + APP_ERROR_CHECK(error_code); + } + break; + + case LMS_EVT_CMD_NOTIFY_COMPLETE: + break; + + case LMS_EVT_DATA_RECEIVE_DATA: + break; + + case LMS_EVT_DATA_NOTIFY_COMPLETE: + lms_data_continue_send(); + break; + + + default: + break; + } +} + +void lms_update_mtu_size(uint16_t new_mtu) +{ + s_once_size = new_mtu - 3; +} + +void app_log_dump_service_init(void) +{ + sdk_err_t error_code; + lms_init_t lms_init; + + lms_init.evt_handler = lms_service_process_event; + + error_code = lms_service_init(&lms_init); + APP_ERROR_CHECK(error_code); +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.h new file mode 100644 index 0000000..73cf46c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_dump_port.h @@ -0,0 +1,58 @@ +/** + **************************************************************************************** + * + * @file app_log_dump_port.h + * + * @brief App Log dump port API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_LOG_DUMP_PORTH__ +#define __APP_LOG_DUMP_PORTH__ + +#include + +/** + ***************************************************************************************** + * @brief Update the Length of log data packet. + ***************************************************************************************** + */ +void lms_update_mtu_size(uint16_t new_mtu); + +/** + ***************************************************************************************** + * @brief Init log dump service. + ***************************************************************************************** + */ +void app_log_dump_service_init(void); +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.c old mode 100755 new mode 100644 index 4226bf1..4d48cad --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.c @@ -40,6 +40,7 @@ * INCLUDE FILES ***************************************************************************************** */ +#include "app_log_store.h" #if APP_LOG_STORE_ENABLE #include "utility.h" @@ -52,21 +53,19 @@ #define APP_LOG_STORE_TIME_DEFAULT "[1970/01/01 00:00:00:000] " #define APP_LOG_STORE_CACHE_SIZE ((APP_LOG_STORE_LINE_SIZE) * (APP_LOG_STORE_CACHE_NUM)) #define APP_LOG_STORE_ONECE_OP_SIZE 1024 -#define APP_LOG_STORE_BUSY_BIT (0x01 << 0) +#define APP_LOG_STORE_CLEAR_BIT (0x01 << 0) #define APP_LOG_STORE_SAVE_BIT (0x01 << 1) #define APP_LOG_STORE_DUMP_BIT (0x01 << 2) - -#define OFFSET_0 0 -#define OFFSET_1 1 -#define OFFSET_2 2 - +#define APP_LOG_STORE_DUMP_READY_BIT (0x01 << 3) +#define APP_LOG_STORE_DUMP_START_BIT (0x01 << 4) /* * STRUCTURES ***************************************************************************************** */ /**@brief App log store head info. */ -typedef struct { +typedef struct +{ uint32_t magic; /**< Magic for app log store. */ uint32_t db_addr; /**< Start address of app log db flash. */ uint32_t db_size; /**< Size of app log db flash. */ @@ -76,7 +75,8 @@ typedef struct { } log_store_head_t; /**@brief App log store environment variable. */ -struct log_store_env_t { +struct log_store_env_t +{ bool initialized; uint8_t store_status; log_store_head_t store_head; @@ -90,10 +90,11 @@ struct log_store_env_t { */ static struct log_store_env_t s_log_store_env; static app_log_store_op_t s_log_store_ops; -static app_log_store_dump_cb_t s_log_store_dump_cb; +static app_log_dump_cbs_t *s_log_dump_cbs; static uint32_t s_log_store_dump_offset; -static ring_buffer_t s_log_store_rbuf; -static uint8_t s_log_store_cache[APP_LOG_STORE_CACHE_SIZE]; +static ring_buffer_t s_log_store_rbuf __attribute__((section("RAM_CODE"))) = {0}; +static uint8_t s_log_store_cache[APP_LOG_STORE_CACHE_SIZE] __attribute__((section("RAM_CODE"))) = {0}; +static uint8_t s_read_dump_buffer[APP_LOG_STORE_ONECE_OP_SIZE]; /* * LOCAL FUNCTION DEFINITIONS @@ -103,8 +104,10 @@ static uint32_t log_store_check_sum_calc(uint8_t *p_data, uint32_t len) { uint32_t check_sum = 0; - if (p_data && len) { - for (uint8_t i = 0; i < len; i++) { + if (p_data && len) + { + for (uint8_t i = 0; i < len; i++) + { check_sum += p_data[i]; } } @@ -118,13 +121,15 @@ static bool log_store_head_check(log_store_head_t *p_head, uint32_t db_addr, uin uint8_t *head_data = (uint8_t *)p_head; if (p_head->magic != APP_LOG_STORE_MAGIC || - p_head->db_addr != db_addr || - p_head->db_size != db_size || - p_head->offset > db_size) { + p_head->db_addr != db_addr || + p_head->db_size != db_size || + p_head->offset > db_size) + { return false; } - if (p_head->check_sum != log_store_check_sum_calc(head_data, head_len - OFFSET_2)) { + if (p_head->check_sum != log_store_check_sum_calc(head_data, head_len - 2)) + { return false; } @@ -136,9 +141,10 @@ static bool log_store_head_update(uint16_t nv_tag, log_store_head_t *p_head) uint16_t head_len = sizeof(log_store_head_t); uint8_t *head_data = (uint8_t *)p_head; - p_head->check_sum = log_store_check_sum_calc(head_data, head_len - OFFSET_2); + p_head->check_sum = log_store_check_sum_calc(head_data, head_len - 2); - if (nvds_put(nv_tag, head_len, (uint8_t *)p_head)) { + if (nvds_put(nv_tag, head_len, (uint8_t *)p_head)) + { return false; } @@ -147,7 +153,8 @@ static bool log_store_head_update(uint16_t nv_tag, log_store_head_t *p_head) static bool log_store_time_stamp_encode(uint8_t *p_buffer, uint8_t buffer_size) { - if (buffer_size != APP_LOG_STORE_TIME_SIZE) { + if (APP_LOG_STORE_TIME_SIZE != buffer_size) + { return false; } @@ -155,12 +162,12 @@ static bool log_store_time_stamp_encode(uint8_t *p_buffer, uint8_t buffer_size) s_log_store_ops.time_get(&rtc_time); - if (APP_LOG_STORE_TIME_SIZE == snprintf_s((char *)p_buffer, APP_LOG_STORE_TIME_SIZE, \ - APP_LOG_STORE_TIME_SIZE, \ - "[%04d/%02d/%02d %02d:%02d:%02d:%03d] ", \ - rtc_time.year, rtc_time.month, rtc_time.day, \ - rtc_time.hour, rtc_time.min, \ - rtc_time.sec, rtc_time.msec)) { + if (APP_LOG_STORE_TIME_SIZE == snprintf((char *)p_buffer, + APP_LOG_STORE_TIME_SIZE, + "[%04d/%02d/%02d %02d:%02d:%02d:%03d] ", + rtc_time.year, rtc_time.month, rtc_time.day, + rtc_time.hour, rtc_time.min, rtc_time.sec, rtc_time.msec)) + { return true; } @@ -171,97 +178,141 @@ static void log_store_data_flash_write(void) { uint32_t align_num = 0; uint32_t read_len; - uint8_t read_buff[APP_LOG_STORE_ONECE_OP_SIZE]; + uint8_t *read_buff = s_read_dump_buffer; - if ((s_log_store_env.store_head.offset % s_log_store_env.blk_size) == 0) { - if (s_log_store_ops.flash_erase) { + if (0 == (s_log_store_env.store_head.offset % s_log_store_env.blk_size)) + { + if (s_log_store_ops.flash_erase) + { s_log_store_ops.flash_erase(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset, s_log_store_env.blk_size); } } align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, s_log_store_env.store_head.offset); - if (align_num != s_log_store_env.store_head.offset) { + + if (align_num != s_log_store_env.store_head.offset) + { read_len = ring_buffer_read(&s_log_store_rbuf, read_buff, align_num - s_log_store_env.store_head.offset); - } else { + } + else + { read_len = ring_buffer_read(&s_log_store_rbuf, read_buff, APP_LOG_STORE_ONECE_OP_SIZE); } - if (s_log_store_ops.flash_write && read_len) { - s_log_store_ops.flash_write(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset, read_buff, - read_len); + if (s_log_store_ops.flash_write && read_len) + { + s_log_store_ops.flash_write(s_log_store_env.store_head.db_addr + s_log_store_env.store_head.offset, read_buff, read_len); s_log_store_env.store_head.offset += read_len; } - if (s_log_store_env.store_head.offset >= s_log_store_env.store_head.db_size) { + if (s_log_store_env.store_head.offset >= s_log_store_env.store_head.db_size) + { s_log_store_env.store_head.offset = 0; s_log_store_env.store_head.flip_over = 1; } log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head); + } static void log_store_to_flash(void) { -#if (APP_LOG_STORE_RUN_ON_OS == 0) - if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) { - return; - } - - s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT; -#endif - log_store_data_flash_write(); s_log_store_env.store_status &= ~APP_LOG_STORE_SAVE_BIT; -#if (APP_LOG_STORE_RUN_ON_OS == 0) - s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT; -#endif } static void log_dump_from_flash(void) { - uint8_t dump_buffer[APP_LOG_STORE_ONECE_OP_SIZE]; + uint8_t *dump_buffer = s_read_dump_buffer; uint16_t dump_len; + uint32_t need_dump_size = s_log_store_env.store_head.flip_over ? + s_log_store_env.store_head.db_size : s_log_store_env.store_head.offset; - if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) { - return; - } - s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT; + if (s_log_store_ops.flash_read && need_dump_size) + { + uint32_t align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, need_dump_size); - if (s_log_store_ops.flash_read) { - uint32_t align_num = ALIGN_NUM(APP_LOG_STORE_ONECE_OP_SIZE, s_log_store_env.store_head.offset); - if (align_num != s_log_store_env.store_head.offset && - (s_log_store_dump_offset + APP_LOG_STORE_ONECE_OP_SIZE) == align_num) { - dump_len = (s_log_store_env.store_head.offset + APP_LOG_STORE_ONECE_OP_SIZE - align_num); - } else { + if (align_num != need_dump_size && + (s_log_store_dump_offset + APP_LOG_STORE_ONECE_OP_SIZE) == align_num) + { + dump_len = (need_dump_size + APP_LOG_STORE_ONECE_OP_SIZE - align_num); + } + else + { dump_len = APP_LOG_STORE_ONECE_OP_SIZE; } s_log_store_ops.flash_read(s_log_store_dump_offset + s_log_store_env.store_head.db_addr, dump_buffer, dump_len); - if (s_log_store_dump_cb) { - s_log_store_dump_cb(dump_buffer, dump_len); + s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_READY_BIT; + + s_log_store_dump_offset += dump_len; + if (need_dump_size == s_log_store_dump_offset) + { + s_log_store_dump_offset = 0; + s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT; + } + + if (s_log_dump_cbs->dump_process_cb) + { + s_log_dump_cbs->dump_process_cb(dump_buffer, dump_len); } - s_log_store_dump_offset += dump_len; - } else { + } + else + { s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT; + s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT; } - - if (s_log_store_env.store_head.db_size == s_log_store_dump_offset) { - s_log_store_dump_offset = 0; - } - - if (s_log_store_env.store_head.offset == s_log_store_dump_offset) { - s_log_store_dump_offset = 0; - s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_BIT; - } - - s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT; } +static void log_store_flush(void) +{ + uint32_t items_count = 0; + + if (!s_log_store_env.initialized) + { + return; + } + do + { + items_count = ring_buffer_items_count_get(&s_log_store_rbuf); + + if (items_count) + { + log_store_data_flash_write(); + } + } while (items_count >= APP_LOG_STORE_ONECE_OP_SIZE); +} + +static void log_dump_ready(void) +{ + uint32_t log_length; + log_store_flush(); + + // get length and send + if (s_log_dump_cbs->dump_start_cb) + { + log_length = s_log_store_env.store_head.flip_over ? + s_log_store_env.store_head.db_size : s_log_store_env.store_head.offset; + s_log_dump_cbs->dump_start_cb(log_length); + } +} + +static void log_store_clear(void) +{ + s_log_store_env.store_head.offset = 0; + s_log_store_env.store_head.flip_over = 0; + ring_buffer_clean(&s_log_store_rbuf); + + log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head); + + s_log_store_dump_offset = 0; + s_log_store_env.store_status = APP_LOG_STORE_DUMP_READY_BIT; +} /* * GLOBAL FUNCTION DEFINITIONS @@ -271,46 +322,61 @@ uint16_t app_log_store_init(app_log_store_info_t *p_info, app_log_store_op_t *p_ { uint16_t head_len = sizeof(log_store_head_t); - if (s_log_store_env.initialized) { + if (s_log_store_env.initialized) + { return SDK_ERR_DISALLOWED; } - if (p_info == NULL || - p_op_func == NULL || - p_op_func->flash_init == NULL || - p_op_func->flash_read == NULL || - p_op_func->flash_write == NULL || - p_op_func->flash_erase == NULL || - p_info->db_size == 0 || - p_info->blk_size == 0 || - (p_info->db_addr % p_info->blk_size) != 0) { + if (NULL == p_info + || NULL == p_op_func + || NULL == p_op_func->flash_init + || NULL == p_op_func->flash_read + || NULL == p_op_func->flash_write + || NULL == p_op_func->flash_erase + || 0 == p_info->db_size + || 0 == p_info->blk_size + || 0 != (p_info->db_addr % p_info->blk_size)) + { return SDK_ERR_INVALID_PARAM; } nvds_get(p_info->nv_tag, &head_len, (uint8_t *)&s_log_store_env.store_head); - if (!log_store_head_check(&s_log_store_env.store_head, p_info->db_addr, p_info->db_size)) { + if (!log_store_head_check(&s_log_store_env.store_head, p_info->db_addr, p_info->db_size)) + { s_log_store_env.store_head.magic = APP_LOG_STORE_MAGIC; s_log_store_env.store_head.db_addr = p_info->db_addr; s_log_store_env.store_head.db_size = p_info->db_size; s_log_store_env.store_head.offset = 0; s_log_store_env.store_head.flip_over = 0; - if (!log_store_head_update(p_info->nv_tag, &s_log_store_env.store_head)) { + if (!log_store_head_update(p_info->nv_tag, &s_log_store_env.store_head)) + { return SDK_ERR_SDK_INTERNAL; } } - ring_buffer_init(&s_log_store_rbuf, s_log_store_cache, APP_LOG_STORE_CACHE_SIZE); - - memcpy_s(&s_log_store_ops, sizeof (s_log_store_ops), p_op_func, sizeof(s_log_store_ops)); + memcpy(&s_log_store_ops, p_op_func, sizeof(s_log_store_ops)); s_log_store_env.head_nv_tag = p_info->nv_tag; s_log_store_env.blk_size = p_info->blk_size; s_log_store_env.initialized = true; + s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT; p_op_func->flash_init(); + if (APP_LOG_STORE_CACHE_SIZE != s_log_store_rbuf.buffer_size) + { + ring_buffer_init(&s_log_store_rbuf, s_log_store_cache, APP_LOG_STORE_CACHE_SIZE); + } + else + { + if (s_log_store_ops.sem_give) + { + s_log_store_ops.sem_give(); + } + } + return SDK_SUCCESS; } @@ -319,17 +385,13 @@ uint16_t app_log_store_save(const uint8_t *p_data, const uint16_t length) { uint8_t time_encode[APP_LOG_STORE_TIME_SIZE] = APP_LOG_STORE_TIME_DEFAULT; - if (!s_log_store_env.initialized) { + if (!s_log_store_env.initialized) + { return SDK_ERR_DISALLOWED; } - if (s_log_store_env.store_status & APP_LOG_STORE_BUSY_BIT) { - return SDK_ERR_BUSY; - } - - s_log_store_env.store_status |= APP_LOG_STORE_BUSY_BIT; - - if (s_log_store_ops.time_get) { + if (s_log_store_ops.time_get) + { log_store_time_stamp_encode(time_encode, APP_LOG_STORE_TIME_SIZE); time_encode[APP_LOG_STORE_TIME_SIZE - 1] = ' '; } @@ -337,78 +399,60 @@ uint16_t app_log_store_save(const uint8_t *p_data, const uint16_t length) ring_buffer_write(&s_log_store_rbuf, time_encode, APP_LOG_STORE_TIME_SIZE); ring_buffer_write(&s_log_store_rbuf, p_data, length); - if (ring_buffer_items_count_get(&s_log_store_rbuf >= APP_LOG_STORE_ONECE_OP_SIZE)) { + if ((APP_LOG_STORE_ONECE_OP_SIZE <= ring_buffer_items_count_get(&s_log_store_rbuf)) && + !(s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT)) + { s_log_store_env.store_status |= APP_LOG_STORE_SAVE_BIT; -#if APP_LOG_STORE_RUN_ON_OS - log_store_to_flash(); -#endif + if (s_log_store_ops.sem_give) + { + s_log_store_ops.sem_give(); + } } - s_log_store_env.store_status &= ~APP_LOG_STORE_BUSY_BIT; - return SDK_SUCCESS; } - -void app_log_store_flush(void) +uint16_t app_log_store_dump(app_log_dump_cbs_t * p_dump_cbs) { - uint32_t items_count = 0; - - if (!s_log_store_env.initialized) { - return; - } - - do { - items_count = ring_buffer_items_count_get(&s_log_store_rbuf); - if (items_count) { - log_store_data_flash_write(); - } - } while (items_count >= APP_LOG_STORE_ONECE_OP_SIZE); -} - -uint16_t app_log_store_dump(app_log_store_dump_cb_t dump_cb) -{ - if (!s_log_store_env.initialized) { + if (!s_log_store_env.initialized) + { return SDK_ERR_DISALLOWED; } - if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) { + if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) + { return SDK_ERR_BUSY; } - - if (dump_cb == NULL) { - return SDK_ERR_POINTER_NULL; - } - - s_log_store_dump_cb = dump_cb; - - app_log_store_flush(); - - if (s_log_store_env.store_head.flip_over == 0 && s_log_store_env.store_head.offset == 0) { - return SDK_SUCCESS; - } - - if (s_log_store_env.store_head.flip_over) { - uint32_t align_num; - - align_num = ALIGN_NUM(s_log_store_env.blk_size, s_log_store_env.store_head.offset); - - s_log_store_dump_offset = align_num >= s_log_store_env.store_head.db_size ? 0 : align_num; - } else { - s_log_store_dump_offset = 0; - } - + s_log_dump_cbs = p_dump_cbs; + s_log_store_env.store_status |= APP_LOG_STORE_DUMP_START_BIT; s_log_store_env.store_status |= APP_LOG_STORE_DUMP_BIT; + if (s_log_store_ops.sem_give) + { + s_log_store_ops.sem_give(); + } return SDK_SUCCESS; } -void app_log_store_clear(void) +uint16_t app_log_store_clear(void) { - s_log_store_env.store_head.offset = 0; - s_log_store_env.store_head.flip_over = 0; + if (!s_log_store_env.initialized) + { + return SDK_ERR_DISALLOWED; + } + s_log_store_env.store_status |= APP_LOG_STORE_CLEAR_BIT; + if (s_log_store_ops.sem_give) + { + s_log_store_ops.sem_give(); + } + + return SDK_SUCCESS; +} - log_store_head_update(s_log_store_env.head_nv_tag, &s_log_store_env.store_head); +void app_log_status_reset(void) +{ + s_log_store_dump_offset = 0; + s_log_store_env.store_status = APP_LOG_STORE_DUMP_READY_BIT; } bool app_log_store_dump_ongoing(void) @@ -416,17 +460,52 @@ bool app_log_store_dump_ongoing(void) return (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) ? true : false; } +void app_log_dump_continue(void) +{ + s_log_store_env.store_status |= APP_LOG_STORE_DUMP_READY_BIT; + + if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) + { + if (s_log_store_ops.sem_give) + { + s_log_store_ops.sem_give(); + } + } + else + { + if (s_log_dump_cbs->dump_finish_cb) + s_log_dump_cbs->dump_finish_cb(); + } +} + void app_log_store_schedule(void) { -#if APP_LOG_STORE_RUN_ON_OS == 0 - if (s_log_store_env.store_status & APP_LOG_STORE_SAVE_BIT) { + if (s_log_store_ops.sem_take) + { + s_log_store_ops.sem_take(); + } + + if (s_log_store_env.store_status & APP_LOG_STORE_CLEAR_BIT) + { + log_store_clear(); + } + + if (s_log_store_env.store_status & APP_LOG_STORE_SAVE_BIT) + { log_store_to_flash(); } -#endif - if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) { + if ((s_log_store_env.store_status & APP_LOG_STORE_DUMP_BIT) && (s_log_store_env.store_status & APP_LOG_STORE_DUMP_READY_BIT)) + { + if (s_log_store_env.store_status & APP_LOG_STORE_DUMP_START_BIT) + { + log_dump_ready(); + s_log_store_env.store_status &= ~APP_LOG_STORE_DUMP_START_BIT; + } + log_dump_from_flash(); } } + #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.h old mode 100755 new mode 100644 index 41dee56..04c7f26 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_log/app_log_store.h @@ -40,7 +40,7 @@ #include "custom_config.h" #if APP_LOG_STORE_ENABLE -#include "gr55xx_sys.h" +#include "grx_sys.h" #include "ring_buffer.h" #include #include @@ -61,16 +61,20 @@ * @{ */ /**@brief APP LOG Store flash data dump callback type. */ -typedef void (*app_log_store_dump_cb_t)(uint8_t *p_data, uint16_t len); +typedef void (*app_log_store_dump_process_cb_t)(uint8_t *p_data, uint16_t len); +typedef void (*app_log_store_dump_start_cb_t)(uint32_t len); +typedef void (*app_log_store_dump_finish_cb_t)(void); +typedef void (*app_log_sem_process)(void); /** @} */ /** * @defgroup APP_LOG_STORE_STRUCT Structures * @{ */ -/**@brief The date and time structure. The packed size is 7 bytes. */ -typedef struct { - uint16_t year; /**< Year time element. */ + /**@brief The date and time structure. The packed size is 7 bytes. */ +typedef struct +{ + uint8_t year; /**< Year time element. */ uint8_t month; /**< Month time element. */ uint8_t day; /**< Day time element. */ uint8_t hour; /**< Hour time element. */ @@ -80,16 +84,20 @@ typedef struct { } app_log_store_time_t; /**@brief App log store operation functions. */ -typedef struct { +typedef struct +{ bool (*flash_init)(void); /**< Flash init. */ bool (*flash_erase)(const uint32_t addr, const uint32_t size); /**< Flash erase. */ uint32_t (*flash_read)(const uint32_t addr, uint8_t *buf, const uint32_t size); /**< Flash read. */ uint32_t (*flash_write)(const uint32_t addr, const uint8_t *buf, const uint32_t size); /**< Flash write. */ void (*time_get)(app_log_store_time_t *p_time); /**< Get real time. */ + app_log_sem_process sem_give; + app_log_sem_process sem_take; } app_log_store_op_t; /**@brief App log store init stucture. */ -typedef struct { +typedef struct +{ uint16_t nv_tag; /**< NVDS Tag for app log store env. */ uint32_t db_addr; /**< Start address of app log db flash. */ uint32_t db_size; /**< Size of app log db flash. */ @@ -97,6 +105,15 @@ typedef struct { } app_log_store_info_t; /** @} */ +/**@brief App log store dump stucture. */ +typedef struct +{ + app_log_store_dump_process_cb_t dump_process_cb; /**< App log store dump callback. */ + app_log_store_dump_start_cb_t dump_start_cb; /**< App log store dump start callback. */ + app_log_store_dump_finish_cb_t dump_finish_cb; /**< App log store dump finish callback. */ +} app_log_dump_cbs_t; +/** @} */ + /** * @defgroup APP_LOG_STORE_FUNCTION Functions * @{ @@ -134,21 +151,15 @@ uint16_t app_log_store_save(const uint8_t *p_data, uint16_t length); * @return Result of dump. ***************************************************************************************** */ -uint16_t app_log_store_dump(app_log_store_dump_cb_t dump_cb); +uint16_t app_log_store_dump(app_log_dump_cbs_t *p_dump_cbs); -/** - ***************************************************************************************** - * @brief Flush app log store cache to flash. - ***************************************************************************************** - */ -void app_log_store_flush(void); /** ***************************************************************************************** * @brief App log store clear. ***************************************************************************************** */ -void app_log_store_clear(void); +uint16_t app_log_store_clear(void); /** ***************************************************************************************** @@ -157,12 +168,21 @@ void app_log_store_clear(void); */ bool app_log_store_dump_ongoing(void); +/** + ***************************************************************************************** + * @brief Continue log dump. + ***************************************************************************************** + */ +void app_log_dump_continue(void); /** ***************************************************************************************** * @brief App log store schedule for save and dump. ***************************************************************************************** */ void app_log_store_schedule(void); + /** @} */ #endif #endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/BUILD.gn new file mode 100644 index 0000000..d44487d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_memory") { + sources = [ "app_memory.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.c new file mode 100644 index 0000000..e1f49c8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.c @@ -0,0 +1,267 @@ +/** + ***************************************************************************************** + * + * @file app_memory.c + * + * @brief App Memory Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_memory.h" +#include "utility.h" +#include + +/* + * DEFINE + ***************************************************************************************** + */ +#define MEM_BLOCK_SIZE ALIGN_NUM(APP_MEM_ALIGN_NUM, sizeof(app_mem_block_t)) +#define BLOCK_ALLOCATED_BIT ((size_t)1 << (sizeof(size_t) * 8 - 1)) +#define BLOCK_ALLOC_SIZE_MIN (MEM_BLOCK_SIZE + APP_MEM_ALIGN_NUM) + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static __attribute__ ((aligned (APP_MEM_ALIGN_NUM))) uint8_t s_mem_heap[APP_MEM_HEAP_SIZE]; + +static app_mem_block_t s_start_list_node; +static app_mem_block_t s_end_list_node; +static size_t s_curr_free_bytes; +static size_t s_ever_free_bytes_min; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_mem_init(void) +{ + app_mem_block_t *p_fir_free_block; + + s_start_list_node.p_next_free_block = (void *)s_mem_heap; + s_start_list_node.block_size = 0; + + + s_end_list_node.p_next_free_block = NULL; + s_end_list_node.block_size = 0; + + p_fir_free_block = (void *)s_mem_heap; + + p_fir_free_block->p_next_free_block = &s_end_list_node; + p_fir_free_block->block_size = APP_MEM_HEAP_SIZE; + + s_curr_free_bytes = p_fir_free_block->block_size; + s_ever_free_bytes_min = p_fir_free_block->block_size; +} + + +static void free_block_node_insert(app_mem_block_t *p_insert_node) +{ + app_mem_block_t *p_iterator_node = &s_start_list_node; + + while (p_iterator_node->p_next_free_block < p_insert_node && + NULL != p_iterator_node->p_next_free_block->p_next_free_block) + { + p_iterator_node = p_iterator_node->p_next_free_block; + } + + + if (((uint8_t *)p_iterator_node + p_iterator_node->block_size) == (uint8_t *)p_insert_node) + { + p_iterator_node->block_size += p_insert_node->block_size; + p_insert_node = p_iterator_node; + } + + if (((uint8_t *)p_insert_node + p_insert_node->block_size) == (uint8_t *)p_iterator_node->p_next_free_block) + { + if (p_iterator_node->p_next_free_block != &s_end_list_node) + { + p_insert_node->block_size += p_iterator_node->p_next_free_block->block_size; + p_insert_node->p_next_free_block = p_iterator_node->p_next_free_block->p_next_free_block; + } + else + { + p_insert_node->p_next_free_block = &s_end_list_node; + } + } + else + { + p_insert_node->p_next_free_block = p_iterator_node->p_next_free_block; + } + + if (p_iterator_node != p_insert_node) + { + p_iterator_node->p_next_free_block = p_insert_node; + } +} + + + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void *app_malloc(size_t size) +{ + app_mem_block_t *p_block; + app_mem_block_t *p_pre_block; + app_mem_block_t *p_new_block; + void *return_ptr = NULL; + + APP_MEM_LOCK(); + + if (NULL == s_start_list_node.p_next_free_block) + { + app_mem_init(); + } + + if (0 == (size & BLOCK_ALLOCATED_BIT) && 0 != size) + { + size += MEM_BLOCK_SIZE; + size = ALIGN_NUM(APP_MEM_ALIGN_NUM, size); + } + else + { + return return_ptr; + } + + if (size > 0 && size < s_curr_free_bytes) + { + p_pre_block = &s_start_list_node; + p_block = s_start_list_node.p_next_free_block; + + while ((p_block->block_size < size) && (NULL != p_block->p_next_free_block)) + { + p_pre_block = p_block; + p_block = p_block->p_next_free_block; + } + + if (p_block != &s_end_list_node) + { + return_ptr = (void *)((uint8_t *)p_pre_block->p_next_free_block + MEM_BLOCK_SIZE); + p_pre_block->p_next_free_block = p_block->p_next_free_block; + + if ((p_block->block_size - size) > BLOCK_ALLOC_SIZE_MIN) + { + p_new_block = (void *)((uint8_t *)p_block + size); + p_new_block->block_size = p_block->block_size - size; + p_block->block_size = size; + + free_block_node_insert(p_new_block); + } + + s_curr_free_bytes -= p_block->block_size; + + if (s_curr_free_bytes < s_ever_free_bytes_min) + { + s_ever_free_bytes_min = s_curr_free_bytes; + } + + p_block->block_size |= BLOCK_ALLOCATED_BIT; + p_block->p_next_free_block = NULL; + } + } + + APP_MEM_UNLOCK(); + + return return_ptr; +} + + +void app_free(void *ptr) +{ + app_mem_block_t *p_block; + + if (NULL == ptr) + { + return; + } + + APP_MEM_LOCK(); + + p_block = (app_mem_block_t *)((uint8_t *)ptr - MEM_BLOCK_SIZE); + + + if (p_block->block_size & BLOCK_ALLOCATED_BIT) + { + if (NULL == p_block->p_next_free_block) + { + p_block->block_size &= ~BLOCK_ALLOCATED_BIT; + + s_curr_free_bytes += p_block->block_size; + + free_block_node_insert(p_block); + } + } + + APP_MEM_UNLOCK(); +} + +void *app_realloc(void *ptr, size_t size) +{ + app_mem_block_t *p_block; + void *p_realloc_ptr; + size_t block_size; + size_t copy_size; + + p_realloc_ptr = app_malloc(size); + if (p_realloc_ptr) + { + APP_MEM_LOCK(); + p_block = (app_mem_block_t *)((uint8_t *)ptr - MEM_BLOCK_SIZE); + block_size = (p_block->block_size & ~BLOCK_ALLOCATED_BIT); + copy_size = (block_size - MEM_BLOCK_SIZE) > size ? size : (block_size - MEM_BLOCK_SIZE); + memcpy(p_realloc_ptr, (uint8_t *)ptr, copy_size); + APP_MEM_UNLOCK(); + app_free(ptr); + return p_realloc_ptr; + } + + return NULL; +} + +size_t app_mem_curr_free_size_get(void) +{ + return s_curr_free_bytes; +} + + +size_t app_mem_ever_free_min_size_get(void) +{ + return s_ever_free_bytes_min; +} + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.h new file mode 100644 index 0000000..e7c7e24 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_memory/app_memory.h @@ -0,0 +1,128 @@ +/** + **************************************************************************************** + * + * @file app_memory.h + * + * @brief App Memory API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_MEMORY_H__ +#define __APP_MEMORY_H__ + +#include "grx_hal.h" +#include +#include + +/** + * @defgroup APP_MEMORY_MAROC Defines + * @{ + */ +#ifndef APP_MEM_ALIGN_NUM +#define APP_MEM_ALIGN_NUM 4 /**< ALIGN number: 4 byte. */ +#endif + +#ifndef APP_MEM_HEAP_SIZE +#define APP_MEM_HEAP_SIZE (4 * 1024) /**< Total app memory heap size. */ +#endif + +#define APP_MEM_LOCK() GLOBAL_EXCEPTION_DISABLE() /**< App memory lock. */ +#define APP_MEM_UNLOCK() GLOBAL_EXCEPTION_ENABLE() /**< App memory unlock. */ +/** @} */ + + +/** + * @defgroup APP_MEMORY_STRUCT Structures + * @{ + */ +/**@brief App Memory Block Information */ +typedef struct mem_block_info +{ + struct mem_block_info *p_next_free_block; /**< Pointer to next free block. */ + size_t block_size; /**< Size of block. */ +} app_mem_block_t; + +/** @} */ + +/** + * @defgroup APP_MEMORY_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Malloc a block memory. + * + * @param[in] size: Size of memory needed to be alloced. + * + * @return Pointer to alloced memory. + ***************************************************************************************** + */ +void *app_malloc(size_t size); + +/** + ***************************************************************************************** + * @brief Realloc a block memory. + * + * @param[in] ptr: Pointer to memory had been alloced. + * @param[in] size: Size of memory needed to be realloced. + * + * @return Pointer to realloced memory. + ***************************************************************************************** + */ +void *app_realloc(void *ptr, size_t size); + +/** + ***************************************************************************************** + * @brief Free a block memory. + * + * @param[in] ptr: Pointer to memory needed to be free. + ***************************************************************************************** + */ +void app_free(void *ptr); + +/** + ***************************************************************************************** + * @brief Get current free size of app memory. + ***************************************************************************************** + */ +size_t app_mem_curr_free_size_get(void); + +/** + ***************************************************************************************** + * @brief Get ever min free size of app memory. + ***************************************************************************************** + */ +size_t app_mem_ever_free_min_size_get(void); +/** @} */ + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/BUILD.gn new file mode 100644 index 0000000..c3c71d5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_queue") { + sources = [ "app_queue.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.c new file mode 100644 index 0000000..6f68c4c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.c @@ -0,0 +1,277 @@ +/** + ***************************************************************************************** + * + * @file app_queue.c + * + * @brief APP Queue function Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_queue.h" +#include "grx_hal.h" +#include +#include + +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_QUEUE_LOCK() LOCAL_INT_DISABLE(BLE_IRQn) +#define APP_QUEUE_UNLOCK() LOCAL_INT_RESTORE() + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +sdk_err_t app_queue_init(app_queue_t *p_queue, void *p_buffer, uint16_t queue_size, uint16_t element_size) +{ + if (NULL == p_queue || NULL == p_buffer) + { + return SDK_ERR_POINTER_NULL; + } + + p_queue->element_size = element_size; + p_queue->queue_size = queue_size; + p_queue->p_buffer = p_buffer; + p_queue->start_idx = 0; + p_queue->end_idx = 0; + + return SDK_SUCCESS; +} + +sdk_err_t app_queue_push(app_queue_t *p_queue, void const *p_elemment) +{ + bool is_full; + uint16_t wr_idx; + void *p_wr_pos; + sdk_err_t error_code = SDK_SUCCESS; + + if (NULL == p_queue || NULL == p_elemment) + { + return SDK_ERR_POINTER_NULL; + } + + APP_QUEUE_LOCK(); + + is_full = app_queue_is_full(p_queue); + + if (is_full) + { + error_code = SDK_ERR_NO_RESOURCES; + } + else + { + wr_idx = p_queue->end_idx; + p_wr_pos = (void *)((size_t)p_queue->p_buffer + wr_idx * p_queue->element_size); + p_queue->end_idx = app_queue_next_idx_get(p_queue->end_idx, p_queue->queue_size); + + memcpy(p_wr_pos, p_elemment, p_queue->element_size); + } + + APP_QUEUE_UNLOCK(); + + return error_code; +} + +uint16_t app_queue_multi_push(app_queue_t *p_queue, void const *p_elemment, uint16_t amount) +{ + uint16_t stored_num = 0; + uint16_t surplus_space = 0; + uint16_t over_flow = 0; + uint16_t wr_idx; + void *p_wr_pos; + void *p_head_pos; + + if (NULL == p_elemment || 0 == amount) + { + stored_num = 0; + } + + APP_QUEUE_LOCK(); + + surplus_space = app_queue_surplus_space_get(p_queue); + wr_idx = p_queue->end_idx; + p_wr_pos = (void *)((size_t)p_queue->p_buffer + wr_idx * p_queue->element_size); + p_head_pos = (void *)((size_t)p_queue->p_buffer); + + stored_num = amount > surplus_space ? surplus_space : amount; + + if (p_queue->start_idx <= p_queue->end_idx) + { + if (p_queue->end_idx + amount >= p_queue->queue_size) + { + over_flow = p_queue->end_idx + amount - p_queue->queue_size; + } + } + + memcpy(p_wr_pos, p_elemment, p_queue->element_size * (stored_num - over_flow)); + memcpy(p_head_pos, + (void const *)((size_t)p_elemment + p_queue->element_size * (stored_num - over_flow)), + p_queue->element_size * over_flow); + + wr_idx += stored_num; + + if (wr_idx >= p_queue->queue_size) + { + wr_idx -= p_queue->queue_size; + } + + p_queue->end_idx = wr_idx; + + APP_QUEUE_UNLOCK(); + + return stored_num; +} + +sdk_err_t app_queue_peek(app_queue_t *p_queue, void *p_elemment) +{ + uint16_t peek_idx = 0; + void *p_peek_pos = NULL; + sdk_err_t error_code = SDK_SUCCESS; + + if (NULL == p_queue || NULL == p_elemment) + { + return SDK_ERR_POINTER_NULL; + } + + APP_QUEUE_LOCK(); + + if (app_queue_is_empty(p_queue)) + { + error_code = SDK_ERR_LIST_ITEM_NOT_FOUND; + } + + peek_idx = p_queue->start_idx; + p_peek_pos = (void *)((size_t)p_queue->p_buffer + peek_idx * p_queue->element_size); + + memcpy(p_elemment, p_peek_pos, p_queue->element_size); + + APP_QUEUE_UNLOCK(); + + return error_code; +} + +sdk_err_t app_queue_pop(app_queue_t *p_queue, void *p_elemment) +{ + uint16_t peek_idx = 0; + void *p_peek_pos = NULL; + sdk_err_t error_code = SDK_SUCCESS; + + if (NULL == p_queue || NULL == p_elemment) + { + return SDK_ERR_POINTER_NULL; + } + + APP_QUEUE_LOCK(); + + if (app_queue_is_empty(p_queue)) + { + error_code = SDK_ERR_LIST_ITEM_NOT_FOUND; + } + else + { + peek_idx = p_queue->start_idx; + p_peek_pos = (void *)((size_t)p_queue->p_buffer + peek_idx * p_queue->element_size); + p_queue->start_idx = app_queue_next_idx_get(p_queue->start_idx, p_queue->queue_size); + + memcpy(p_elemment, p_peek_pos, p_queue->element_size); + } + + APP_QUEUE_UNLOCK(); + + return error_code; +} + +uint16_t app_queue_surplus_space_get(app_queue_t *p_queue) +{ + uint16_t start_idx = p_queue->start_idx; + uint16_t end_idx = p_queue->end_idx; + uint16_t queue_size = p_queue->queue_size; + uint16_t surplus_space = 0; + + APP_QUEUE_LOCK(); + + if (start_idx <= end_idx) + { + surplus_space = queue_size - end_idx + start_idx; + } + else + { + surplus_space = start_idx - end_idx - 1; + } + + APP_QUEUE_UNLOCK(); + + return surplus_space; +} + +uint16_t app_queue_items_count_get(app_queue_t *p_queue) +{ + uint16_t start_idx = p_queue->start_idx; + uint16_t end_idx = p_queue->end_idx; + uint16_t queue_size = p_queue->queue_size; + uint16_t items_count = 0; + + if (NULL == p_queue) + { + return 0; + } + + APP_QUEUE_LOCK(); + + if (start_idx <= end_idx) + { + items_count = end_idx - start_idx; + } + else + { + items_count = queue_size - start_idx + end_idx; + } + + APP_QUEUE_UNLOCK(); + + return items_count; +} + +void app_queue_clean(app_queue_t *p_queue) +{ + APP_QUEUE_LOCK(); + + p_queue->start_idx = 0; + p_queue->end_idx = 0; + + APP_QUEUE_UNLOCK(); +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.h new file mode 100644 index 0000000..56680b9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_queue/app_queue.h @@ -0,0 +1,208 @@ + /** + ***************************************************************************************** + * + * @file app_queue.h + * + * @brief Header file - APP QUEUE APIs + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_QUEUE_H__ +#define __APP_QUEUE_H__ + +#include "grx_sys.h" +#include +#include + +/** + * @defgroup APP_QUEUE_STRUCT Structures + * @{ + */ +/**@brief App queue instance information. */ +typedef struct +{ + uint16_t element_size; /**< Size of app queue element. */ + uint16_t queue_size; /**< Size of app queue buffer. */ + void *p_buffer; /**< Pointer to app queue buffer. */ + uint16_t start_idx; /**< Start index of app queue. */ + uint16_t end_idx; /**< End index of app queue. */ +} app_queue_t; +/** @} */ + +/** + * @defgroup APP_QUEUE_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize one app queue instance. + * + * @param[in] p_queue: Pointer to app queue instance. + * @param[in] p_buffer: Pointer to queue buffer. + * @param[in] queue_size: Size of queue buffer(The actual queue allocation size is one more than available). + * @param[in] element_size: Size of queue element + * + * @return Result of initializing app queue. + ***************************************************************************************** + */ +sdk_err_t app_queue_init(app_queue_t *p_queue, void *p_buffer, uint16_t queue_size, uint16_t element_size); + +/** + ***************************************************************************************** + * @brief Push one element to tail of app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + * @param[in] p_elemment: Pointer to the element that will be stored in the queue. + * + * @return Result of element push. + ***************************************************************************************** + */ +sdk_err_t app_queue_push(app_queue_t *p_queue, void const *p_elemment); + +/** + ***************************************************************************************** + * @brief Push some elements to tail of app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + * @param[in] p_elemment: Pointer to the elements that will be stored in the queue. + * @param[in] amount: Amount of the elements that wants be stored in the queue. + * + * @return Amount of writen elements. + ***************************************************************************************** + */ +uint16_t app_queue_multi_push(app_queue_t *p_queue, void const *p_elemment, uint16_t amount); + +/** + ***************************************************************************************** + * @brief Peek one element from tail of app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + * @param[out] p_elemment: Pointer to where the element will be copied. + * + * @return Result of element peek. + ***************************************************************************************** + */ +sdk_err_t app_queue_peek(app_queue_t *p_queue, void *p_elemment); + +/** + ***************************************************************************************** + * @brief Pop one element from tail of app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + * @param[out] p_elemment: Pointer to where the element will be copied. + * + * @return Result of element pop. + ***************************************************************************************** + */ +sdk_err_t app_queue_pop(app_queue_t *p_queue, void *p_elemment); + +/** + ***************************************************************************************** + * @brief Get next index. + * + * @param[in] curr_idx: Current index. + * @param[in] size: Size of current app queue. + * + * @retval Next index. + ***************************************************************************************** + */ +__STATIC_FORCEINLINE uint16_t app_queue_next_idx_get(uint16_t curr_idx, uint16_t size) +{ + return (curr_idx < size) ? (curr_idx + 1) : 0; +} + +/** + ***************************************************************************************** + * @brief Check app queue is full or not. + * + * @param[in] p_queue: Pointer to app queue instance. + * + * @return Result of check. + ***************************************************************************************** + */ +__STATIC_FORCEINLINE bool app_queue_is_full(app_queue_t *p_queue) +{ + uint16_t next_idx; + + next_idx = app_queue_next_idx_get( p_queue->end_idx, p_queue->queue_size); + + return next_idx == p_queue->start_idx; +} + +/** + ***************************************************************************************** + * @brief Check app queue is empty or not. + * + * @param[in] p_queue: Pointer to app queue instance. + * + * @return Result of check. + ***************************************************************************************** + */ +__STATIC_FORCEINLINE bool app_queue_is_empty(app_queue_t *p_queue) +{ + return (p_queue->start_idx == p_queue->end_idx); +} + +/** + ***************************************************************************************** + * @brief Get surplus space of one app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + * + * @retval Size of surplus space. + ***************************************************************************************** + */ +uint16_t app_queue_surplus_space_get(app_queue_t *p_queue); + +/** + ***************************************************************************************** + * @brief Get availdble data from one ring buffer. + * + * @param[in] p_queue: Pointer to app queue instance. + * + * @retval Count of availdble items. + ***************************************************************************************** + */ +uint16_t app_queue_items_count_get(app_queue_t *p_queue); + +/** + ***************************************************************************************** + * @brief Clean one app queue. + * + * @param[in] p_queue: Pointer to app queue instance. + ***************************************************************************************** + */ +void app_queue_clean(app_queue_t *p_queue); + +/** @} */ + + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/BUILD.gn new file mode 100644 index 0000000..69d0b77 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_scheduler") { + sources = [ "app_scheduler.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.c new file mode 100644 index 0000000..97055be --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.c @@ -0,0 +1,178 @@ +/** + ***************************************************************************************** + * + * @file app_scheduler.c + * + * @brief App Scheduler Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_scheduler.h" +#include "grx_hal.h" +#include "app_memory.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_SCHEDULER_LOCK() LOCAL_INT_DISABLE(BLE_IRQn) +#define APP_SCHEDULER_UNLOCK() LOCAL_INT_RESTORE() + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief App scheduler environment variable. */ +struct app_scheduler_env_t +{ + app_scheduler_evt_info_t *p_evt_info_buffer; + uint16_t evt_queue_size; + volatile uint8_t queue_start_index; + volatile uint8_t queue_end_index; +}; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static struct app_scheduler_env_t s_app_scheduler_env; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static __INLINE uint8_t next_index_get(uint8_t index) +{ + return (index < s_app_scheduler_env.evt_queue_size) ? (index + 1) : 0; +} + +static __INLINE bool is_evt_queue_full() +{ + return next_index_get(s_app_scheduler_env.queue_end_index) == s_app_scheduler_env.queue_start_index; +} + +static __INLINE bool is_evt_queue_empty() +{ + return s_app_scheduler_env.queue_end_index == s_app_scheduler_env.queue_start_index; +} + + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +sdk_err_t app_scheduler_init(uint16_t queue_size) +{ + if (!queue_size) + { + return SDK_ERR_INVALID_PARAM; + } + + s_app_scheduler_env.p_evt_info_buffer = app_malloc((queue_size + 1) * sizeof(app_scheduler_evt_info_t)); + + if (NULL == s_app_scheduler_env.p_evt_info_buffer) + { + return SDK_ERR_NO_RESOURCES; + } + + memset(s_app_scheduler_env.p_evt_info_buffer, 0, (queue_size + 1) * sizeof(app_scheduler_evt_info_t)); + + s_app_scheduler_env.evt_queue_size = queue_size; + s_app_scheduler_env.queue_start_index = 0; + s_app_scheduler_env.queue_end_index = 0; + + return SDK_SUCCESS; +} + +sdk_err_t app_scheduler_evt_put(void const *p_evt_data, uint16_t evt_data_size, app_scheduler_evt_handler_t evt_handler) +{ + sdk_err_t error_code; + void *evt_data_ptr; + + APP_SCHEDULER_LOCK(); + + if (!is_evt_queue_full()) + { + s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].evt_handler = evt_handler; + s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].evt_data_size = evt_data_size; + if (p_evt_data && evt_data_size) + { + evt_data_ptr = app_malloc(evt_data_size); + if (NULL == evt_data_ptr) + { + return SDK_ERR_NO_RESOURCES; + } + + memcpy(evt_data_ptr, p_evt_data, evt_data_size); + s_app_scheduler_env.p_evt_info_buffer[s_app_scheduler_env.queue_end_index].p_evt_data = evt_data_ptr; + } + s_app_scheduler_env.queue_end_index = next_index_get(s_app_scheduler_env.queue_end_index); + error_code = SDK_SUCCESS; + } + else + { + error_code = SDK_ERR_NO_RESOURCES; + } + + APP_SCHEDULER_UNLOCK(); + + return error_code; +} + +void app_scheduler_execute(void) +{ + while(!is_evt_queue_empty()) + { + void *p_evt_data; + uint16_t evt_data_size; + app_scheduler_evt_handler_t evt_handler; + uint8_t evt_index; + + evt_index = s_app_scheduler_env.queue_start_index; + + p_evt_data = s_app_scheduler_env.p_evt_info_buffer[evt_index].p_evt_data; + evt_data_size = s_app_scheduler_env.p_evt_info_buffer[evt_index].evt_data_size; + evt_handler = s_app_scheduler_env.p_evt_info_buffer[evt_index].evt_handler; + + if (evt_handler) + { + evt_handler(p_evt_data, evt_data_size); + } + + app_free(p_evt_data); + + s_app_scheduler_env.queue_start_index = next_index_get(s_app_scheduler_env.queue_start_index); + } +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.h new file mode 100644 index 0000000..555679c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_scheduler/app_scheduler.h @@ -0,0 +1,104 @@ +/** + **************************************************************************************** + * + * @file app_scheduler.h + * + * @brief App Scheduler API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __APP_SCHEDULER_H__ +#define __APP_SCHEDULER_H__ + +#include "grx_sys.h" +#include +#include + +/** + * @defgroup APP_SCHEDULER_TYPEDEF Typedefs + * @{ + */ +/**@brief APP Scheduler event handler type. */ +typedef void (*app_scheduler_evt_handler_t)(void *p_evt_data, uint16_t evt_data_size); +/** @} */ + +/** + * @defgroup APP_SCHEDULER_STRUCT Structures + * @{ + */ +/**@brief App scheduler event information. */ +typedef struct +{ + app_scheduler_evt_handler_t evt_handler; /**< Event handler. */ + void *p_evt_data; /**< Pointer to event data. */ + uint16_t evt_data_size; /**< Size of event data. */ +} app_scheduler_evt_info_t; +/** @} */ + +/** + * @defgroup APP_SCHEDULER_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize app scheduler module. + * + * @param[in] queue_size: Event queue size. + * + * @return Result of initialization. + ***************************************************************************************** + */ +sdk_err_t app_scheduler_init(uint16_t queue_size); + +/** + ***************************************************************************************** + * @brief Put an event into event queue. + * + * @param[in] p_evt_data: Pointer to event data. + * @param[in] evt_data_size: Size of event data. + * @param[in] evt_handler: Event handler. + * + * @return Result of put. + ***************************************************************************************** + */ +sdk_err_t app_scheduler_evt_put(void const *p_evt_data, uint16_t evt_data_size, app_scheduler_evt_handler_t evt_handler); + +/** + ***************************************************************************************** + * @brief Executing all events. + ***************************************************************************************** + */ +void app_scheduler_execute(void); +/** @} */ + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/BUILD.gn new file mode 100644 index 0000000..aae4e14 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("app_timer") { + sources = [ "app_timer.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.c old mode 100755 new mode 100644 index 875c65d..1eb0610 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.c @@ -39,16 +39,21 @@ * INCLUDE FILES ***************************************************************************************** */ -#include -#include "custom_config.h" -#include "gr55xx_hal.h" -#include "gr55xx_pwr.h" #include "app_timer.h" - -#if APP_TIMER_USE_SCHEDULER -#include "app_scheduler.h" +#include "grx_hal.h" +#include "gr_soc.h" +#if APP_TIMER_ASSERT_ENABLE +#include "app_assert.h" +#else +#define APP_ASSERT_CHECK(x) #endif + +/* + * GLOBAL VERIABLE DECLARATION + ***************************************************************************************** + */ + /* * DEFINES ***************************************************************************************** @@ -64,453 +69,604 @@ not disable SVC_IRQ, BLE_IRQ, BLE_SLEEP_IRQ to ensure the highest priority of Bluetooth services */ -#define LOCAL_APP_TIMER_LOCK() \ - uint32_t __l_irq_rest = __get_BASEPRI(); \ - __set_BASEPRI(NVIC_GetPriority(BLE_IRQn) + \ - (1 << (NVIC_GetPriorityGrouping() + 1))) +#define _LOCAL_APP_TIMER_LOCK() \ + uint32_t __l_irq_rest = __get_BASEPRI(); \ + __set_BASEPRI(NVIC_GetPriority(BLE_IRQn) + \ + (1 << (NVIC_GetPriorityGrouping() + 1))); -#define LOCAL_APP_TIMER_UNLOCK() \ - __set_BASEPRI(__l_irq_rest) +#define _LOCAL_APP_TIMER_UNLOCK() \ + __set_BASEPRI(__l_irq_rest); -/**@brief The length of timer node list. */ -#define TIMER_NODE_CNT 20 -#define TIMER_INVALID_DELAY_VALUE 0 -#define TIMER_INVALID_NODE_NUMBER 0xFF -#define APP_TIMER_STOP_VALUE 0x1 -#define APP_TIMER_INVALID_ID NULL -#define APP_TIMER_SUC 0x0 -#define APP_TIMER_FAIL (-1) -#define APP_TIMER_LOCK() LOCAL_APP_TIMER_LOCK() -#define APP_TIMER_UNLOCK() LOCAL_APP_TIMER_UNLOCK() +#define APP_TIMER_LOCK() _LOCAL_APP_TIMER_LOCK() +#define APP_TIMER_UNLOCK() _LOCAL_APP_TIMER_UNLOCK() -static inline uint32_t APP_TIMER_MS_TO_US(uint32_t x) +/** @brief app timer clock and some time conversion formula definitions */ +#define APP_TIMER_CLK_FREQ_HZ (hal_sleep_timer_get_clock_freq()) +#define APP_TIMER_MS_TO_US(x) ((x) * 1000UL) +//#define APP_TIMER_US_TO_TICKS(x) ((((uint64_t)(x) * APP_TIMER_CLK_FREQ_HZ) + (999999)) / 1000000) +#define APP_TIMER_US_TO_TICKS(x) (((double)(x) * APP_TIMER_CLK_FREQ_HZ / 1000000.0) + 0.5) +#define APP_TIMER_TICKS_TO_US(x) ((uint64_t)(x) * 1000000.0f / APP_TIMER_CLK_FREQ_HZ) + +/** @brief app timer status return definitions */ +#define APP_TIMER_RET_SUC (1) +#define APP_TIMER_RET_FAIL (0) + +/** @brief app timer work parameter definitions */ +#define APP_TIMER_INTERNAL_TIMEOUT (1000) +#define APP_TIMER_DELAY_MS_MIN (1) +#define APP_TIMER_DELAY_MS_MAX (36 * 3600 * 1000) +#define APP_TIMER_DELAY_US_MAX ((uint64_t)APP_TIMER_DELAY_MS_MAX * 1000) +#define APP_TIMER_TRIGGER_WINDOW_US (0) + +#define FALL_WITHIN_TRIGGER_WINDOW(x) (((x) - s_app_timer_info.apptimer_total_us) <= s_app_timer_info.apptimer_trigger_window_us) +#define WITHIN_TRIGGER_WINDOW_MARK(x) (x->timer_mark = true) +#define WITHIN_TRIGGER_WINDOW_CLEAR(x) (x->timer_mark = false) +#define IS_TRIGGER_WINDOW_MARKED(x) (x->timer_mark == true) + +/** @brief App timer global state variable. */ +typedef struct app_timer_struct { - return x * 1000UL; -} + uint32_t cnt_node; + app_timer_t *p_curr_timer_node; + app_timer_t *p_within_window_one_shot_node_hd; + uint64_t apptimer_total_us; + uint64_t apptimer_trigger_window_us; + app_timer_t hd_node; +}app_timer_info_t; -static inline float APP_TIMER_TICKS_TO_US(uint32_t x) +/** @brief App timer node state variable. */ +typedef enum { - float ret = ((x) * 1000000.0f / sys_lpclk_get()); - return ret; -} + NOT_INIT = 0xFF, + STOP = 0x00, + RUN = 0x01, +}app_timer_node_statu_t; -static inline void APP_TIMER_GET_CURRENT_TICKS(uint32_t x) +/** @brief App timer global list, all newly added timer nodes will be added to the queue. */ +static app_timer_info_t s_app_timer_info = { - hal_pwr_get_timer_current_value(PWR_TIMER_TYPE_SLP_TIMER, x); -} - -/**@brief App timer global state variable. */ -typedef struct app_timer_struct { - uint8_t apptimer_start; - uint8_t apptimer_in_int; - app_timer_t *p_curr_timer_node; - int apptimer_runout_time; - uint32_t apptimer_total_ticks; - uint32_t apptimer_total_ticks_us; -} app_timer_info_t; - - -/**@brief App timer state types. */ -enum { - APP_TIMER_STOP = 0, - APP_TIMER_START, + .cnt_node = 0, + .p_curr_timer_node = NULL, + .p_within_window_one_shot_node_hd = NULL, + .apptimer_total_us = 0, + .apptimer_trigger_window_us = APP_TIMER_TRIGGER_WINDOW_US, }; -/**@brief App timer state types. */ -enum { - TIMER_NODE_FREE = 0, - TIMER_NODE_USED, -}; - -/**@brief App timer state types. */ -enum { - APP_TIMER_NODE_START = 0xaa, - APP_TIMER_NODE_STOP, -}; - -/**@brief Aon-timer global list, all newly added timer nodes will be added to the queue. */ -static app_timer_t s_timer_node[TIMER_NODE_CNT]; -static app_timer_info_t s_app_timer_info; - /* - * LOCAL VARIABLE DEFINITIONS + * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -app_timer_t* get_next_timer(void) +static void sleep_timer_handler_register(void); +static void low_level_timer_startup(uint64_t value); +static void low_level_timer_stop(void); +static uint64_t low_level_timer_rest_get(void); +static uint8_t app_timer_running_queue_insert(app_timer_id_t *p_timer_id); +static app_timer_id_t* app_timer_running_queue_remove(app_timer_id_t *p_timer_id); +static uint8_t app_timer_running_queue_trigger_window_mark(void); +static uint8_t app_timer_running_queue_trigger_window_execute(void); +static void app_timer_node_init(app_timer_id_t *p_timer_id, uint64_t delay, void *p_ctx, uint64_t insert_time); +static uint8_t is_need_insert_front(uint64_t delay_value, uint64_t rest_time); +static uint8_t is_timer_node_created(app_timer_id_t *p_timer_id); + + +/** + **************************************************************************************** + * @brief sleep timer Interrupt Handler + * @retval none + **************************************************************************************** + */ +void SLPTIMER_IRQHandler(void) { - int min_handle = TIMER_INVALID_NODE_NUMBER; - uint32_t min_value = (uint32_t)0xFFFFFFFF; - - for (int idx = 0; idx < TIMER_NODE_CNT; idx++) { - if (s_timer_node[idx].original_delay && (s_timer_node[idx].timer_node_status == APP_TIMER_NODE_START)) { - if ((s_timer_node[idx].next_trigger_time - s_app_timer_info.apptimer_total_ticks) < min_value) { - min_value = s_timer_node[idx].next_trigger_time - s_app_timer_info.apptimer_total_ticks; - min_handle = idx; - } else if (s_timer_node[idx].next_trigger_time < s_app_timer_info.apptimer_total_ticks) { - s_timer_node[idx].next_trigger_time = s_app_timer_info.apptimer_total_ticks; - min_value = 0; - min_handle = idx; - } - - if (min_value == 0) { - return &s_timer_node[min_handle]; - } - } - } - - if (min_handle == TIMER_INVALID_NODE_NUMBER) { - return NULL; - } - - return &s_timer_node[min_handle]; -} - -void clear_total_ticks(void) -{ - if (s_app_timer_info.apptimer_total_ticks >= 0xF0000000) { - for (int idx = 0; idx < TIMER_NODE_CNT; idx++) { - if (s_timer_node[idx].original_delay) { - s_timer_node[idx].next_trigger_time -= s_app_timer_info.apptimer_total_ticks; - } - } - s_app_timer_info.apptimer_total_ticks = 0x0; - } -} - -__STATIC_INLINE void app_timer_drv_stop(void) -{ - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_DISABLE, APP_TIMER_STOP_VALUE); -} - -uint8_t app_timer_get_valid_node(void) -{ - uint8_t idx = 0; - for (idx=0; idxtimeout_handler(p_timer_evt->p_ctx); -} -#endif - -TINY_RAM_SECTION void hal_pwr_sleep_timer_elapsed_callback(void) -{ - APP_TIMER_LOCK(); - - app_timer_t *p_timer_node = s_app_timer_info.p_curr_timer_node; - app_timer_t *p_exe_node = p_timer_node; - s_app_timer_info.apptimer_total_ticks += s_app_timer_info.apptimer_runout_time; - - if (p_timer_node->next_trigger_mode == ATIMER_ONE_SHOT) { - p_timer_node->original_delay = 0x0; - } else if (p_timer_node->next_trigger_mode == ATIMER_REPEAT) { - p_timer_node->next_trigger_time = p_timer_node->original_delay + s_app_timer_info.apptimer_total_ticks; - } - - clear_total_ticks(); - s_app_timer_info.p_curr_timer_node = get_next_timer(); - p_timer_node = s_app_timer_info.p_curr_timer_node; - - if (s_app_timer_info.p_curr_timer_node != NULL) { - s_app_timer_info.apptimer_runout_time = p_timer_node->next_trigger_time-s_app_timer_info.apptimer_total_ticks; - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_SINGLE, - sys_us_2_lpcycles(s_app_timer_info.apptimer_runout_time)); - } else { - s_app_timer_info.apptimer_start = APP_TIMER_STOP; - pwr_mgmt_notify_timer_event(EVENT_APP_TIMER_STOP); - } - - APP_TIMER_UNLOCK(); - if (p_exe_node && (p_exe_node->timer_node_status == APP_TIMER_NODE_START)) { - if (p_exe_node->next_trigger_mode == ATIMER_ONE_SHOT) { - p_exe_node->timer_node_status = APP_TIMER_NODE_STOP; - } -#if APP_TIMER_USE_SCHEDULER - app_timer_evt_t evt; - - evt.timeout_handler = p_exe_node->next_trigger_callback; - evt.p_ctx = p_exe_node->next_trigger_callback_var; - - app_scheduler_evt_put(&evt, sizeof(evt), timeout_handler_scheduled_exec); -#else - p_exe_node->next_trigger_callback(p_exe_node->next_trigger_callback_var); -#endif - } + hal_pwr_sleep_timer_irq_handler(); } /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ -uint8_t app_timer_get_status(void) +void hal_pwr_sleep_timer_elapsed_callback(void) { - return (s_app_timer_info.apptimer_start == APP_TIMER_STOP)?0:1; -} + app_timer_t *p_curr_node = app_timer_running_queue_remove(NULL); -TINY_RAM_SECTION uint32_t app_timer_stop_and_ret(app_timer_id_t p_timer_id) -{ - uint32_t ret = 0; - uint32_t atimer_curr_ticks = 0, atimer_curr_us = 0; - app_timer_t *p_timer_node = p_timer_id; + APP_ASSERT_CHECK(p_curr_node); - if (p_timer_node == NULL) { - return 0; + s_app_timer_info.apptimer_total_us = p_curr_node->next_shot_time; + if (s_app_timer_info.apptimer_total_us >= APP_TIMER_DELAY_US_MAX) + { + app_timer_t *tmp = (app_timer_id_t *)&s_app_timer_info.hd_node; + while (tmp->p_next) + { + if (tmp->p_next->next_shot_time >= s_app_timer_info.apptimer_total_us) + { + tmp->p_next->next_shot_time -= s_app_timer_info.apptimer_total_us; + } + else + { + /* should never come here */ + APP_ASSERT_CHECK(false); + } + tmp = tmp->p_next; + } + + s_app_timer_info.apptimer_total_us = 0; } - hal_pwr_get_timer_current_value(PWR_TIMER_TYPE_SLP_TIMER, &atimer_curr_ticks); + if (p_curr_node->timer_node_mode == ATIMER_REPEAT) + { + p_curr_node->next_shot_time = s_app_timer_info.apptimer_total_us + p_curr_node->original_delay; + app_timer_running_queue_insert(p_curr_node); + } - app_timer_drv_stop(); + app_timer_running_queue_trigger_window_mark(); - atimer_curr_us = (uint32_t)(APP_TIMER_TICKS_TO_US(atimer_curr_ticks)); + if (s_app_timer_info.p_curr_timer_node) + { + APP_ASSERT_CHECK(s_app_timer_info.p_curr_timer_node->next_shot_time >= s_app_timer_info.apptimer_total_us); + low_level_timer_startup(s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us); + } - uint32_t already_ran_time = s_app_timer_info.apptimer_runout_time - atimer_curr_us; + if (p_curr_node->timer_node_cb) + p_curr_node->timer_node_cb(p_curr_node->arg); + else + APP_ASSERT_CHECK(false); - s_app_timer_info.apptimer_total_ticks += already_ran_time; + app_timer_running_queue_trigger_window_execute(); +} - ret = s_app_timer_info.apptimer_runout_time - atimer_curr_us; +sdk_err_t app_timer_start_api(app_timer_id_t *p_timer_id, uint32_t delay, void *p_ctx) +{ + uint8_t trigger_flag = false; + uint64_t insert_time = 0; + uint64_t last_rest_time; - p_timer_node->original_delay = 0x0; - p_timer_node->timer_node_status = APP_TIMER_NODE_STOP; + if ((NULL == p_timer_id) || + (delay > APP_TIMER_DELAY_MS_MAX) || + (delay < APP_TIMER_DELAY_MS_MIN)) + return SDK_ERR_INVALID_PARAM; - s_app_timer_info.apptimer_start = APP_TIMER_STOP; - pwr_mgmt_notify_timer_event(EVENT_APP_TIMER_STOP); - return ret; + APP_TIMER_LOCK(); + + if ((!is_timer_node_created(p_timer_id)) || + (p_timer_id->timer_node_status != STOP)) + { + APP_TIMER_UNLOCK(); + return SDK_ERR_DISALLOWED; + } + + last_rest_time = low_level_timer_rest_get(); + + if (is_need_insert_front(APP_TIMER_MS_TO_US(delay), last_rest_time)) + { + if (s_app_timer_info.p_curr_timer_node) + { + APP_ASSERT_CHECK(last_rest_time <= (s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us)); + s_app_timer_info.apptimer_total_us = s_app_timer_info.p_curr_timer_node->next_shot_time - last_rest_time; + low_level_timer_stop(); + } + else + { + // the node that will be started is the first timer node + s_app_timer_info.apptimer_total_us = 0; + last_rest_time = 0; + } + trigger_flag = true; + insert_time = s_app_timer_info.apptimer_total_us; + } + else + { + APP_ASSERT_CHECK(last_rest_time <= (s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us)); + insert_time = s_app_timer_info.p_curr_timer_node->next_shot_time - last_rest_time; + } + + app_timer_node_init(p_timer_id, delay, p_ctx, insert_time); + app_timer_running_queue_insert(p_timer_id); + + sleep_timer_handler_register(); + if (!NVIC_GetEnableIRQ(SLPTIMER_IRQn)) + { + NVIC_ClearPendingIRQ(SLPTIMER_IRQn); + NVIC_EnableIRQ(SLPTIMER_IRQn); + } + + if (trigger_flag) + { + APP_ASSERT_CHECK(s_app_timer_info.p_curr_timer_node->next_shot_time > s_app_timer_info.apptimer_total_us); + low_level_timer_startup(s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us); + } + + APP_TIMER_UNLOCK(); + + return SDK_SUCCESS; +} + +void app_timer_stop_api(app_timer_id_t *p_timer_id) +{ + uint8_t timer_has_stop = false; + uint64_t last_rest_time = 0; + + if (NULL == p_timer_id) + return; + + APP_TIMER_LOCK(); + if (p_timer_id->timer_node_status == RUN) + { + if (s_app_timer_info.p_curr_timer_node == p_timer_id) + { + last_rest_time = low_level_timer_rest_get(); + APP_ASSERT_CHECK(last_rest_time <= (s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us)); + s_app_timer_info.apptimer_total_us = (p_timer_id->next_shot_time - last_rest_time); + + low_level_timer_stop(); + timer_has_stop = true; + } + + app_timer_running_queue_remove(p_timer_id); + + if (timer_has_stop && s_app_timer_info.p_curr_timer_node) + { + APP_ASSERT_CHECK(s_app_timer_info.p_curr_timer_node->next_shot_time > s_app_timer_info.apptimer_total_us); + low_level_timer_startup(s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us); + } + else if ((!timer_has_stop) && (NULL == s_app_timer_info.p_curr_timer_node)) + { + low_level_timer_stop(); + APP_ASSERT_CHECK(false); + } + } + + APP_TIMER_UNLOCK(); } sdk_err_t app_timer_delete(app_timer_id_t *p_timer_id) { - app_timer_t *p_timer_node = *p_timer_id; - - if (p_timer_node == APP_TIMER_INVALID_ID) { + if (NULL == p_timer_id) return SDK_ERR_INVALID_PARAM; - } - APP_TIMER_LOCK(); + app_timer_stop_api(p_timer_id); + p_timer_id->timer_node_status = NOT_INIT; + p_timer_id->original_delay = 0; + p_timer_id->next_shot_time = 0; + p_timer_id->timer_node_cb = NULL; - p_timer_node->original_delay = 0x0; - p_timer_node->timer_node_status = APP_TIMER_NODE_STOP; - p_timer_node->timer_node_used = TIMER_NODE_FREE; - *p_timer_id = APP_TIMER_INVALID_ID; - - if (s_app_timer_info.p_curr_timer_node == p_timer_node) { - app_timer_drv_stop(); - p_timer_node = get_next_timer(); - if (p_timer_node != NULL) { - s_app_timer_info.apptimer_runout_time = p_timer_node->next_trigger_time- - s_app_timer_info.apptimer_total_ticks; - s_app_timer_info.p_curr_timer_node = p_timer_node; - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_SINGLE, - sys_us_2_lpcycles(s_app_timer_info.apptimer_runout_time)); - } else { - s_app_timer_info.apptimer_start = APP_TIMER_STOP; - s_app_timer_info.p_curr_timer_node = NULL; - pwr_mgmt_notify_timer_event(EVENT_APP_TIMER_STOP); - } - } - APP_TIMER_UNLOCK(); return SDK_SUCCESS; } -void app_timer_stop(app_timer_id_t p_timer_id) +uint8_t app_timer_get_status(void) { + uint8_t status = (uint8_t)STOP; + APP_TIMER_LOCK(); - app_timer_t *p_timer_node = p_timer_id; - uint32_t atimer_curr_ticks = 0, atimer_curr_us = 0; + if (s_app_timer_info.p_curr_timer_node) + status = (uint8_t)RUN; - if (p_timer_node == NULL) { - APP_TIMER_UNLOCK(); - return ; - } - - if (p_timer_node->timer_node_status != APP_TIMER_NODE_START) { - APP_TIMER_UNLOCK(); - return; - } - - p_timer_node->timer_node_status = APP_TIMER_NODE_STOP; - p_timer_node->original_delay = 0x0; - - if (s_app_timer_info.p_curr_timer_node == p_timer_node) { - app_timer_drv_stop(); - APP_TIMER_GET_CURRENT_TICKS(&atimer_curr_ticks); - - atimer_curr_us = (uint32_t)(APP_TIMER_TICKS_TO_US(atimer_curr_ticks)); - - if (atimer_curr_ticks == 0xFFFFFFFF) { - ll_pwr_clear_wakeup_event(LL_PWR_WKUP_EVENT_TIMER); - NVIC_ClearPendingIRQ(SLPTIMER_IRQn); - atimer_curr_ticks = 0; - } - - uint32_t already_ran_time = s_app_timer_info.apptimer_runout_time - atimer_curr_us; - s_app_timer_info.apptimer_total_ticks += already_ran_time; - - p_timer_node = get_next_timer(); - if (p_timer_node != NULL) { - s_app_timer_info.apptimer_runout_time = p_timer_node->next_trigger_time- - s_app_timer_info.apptimer_total_ticks; - s_app_timer_info.p_curr_timer_node = p_timer_node; - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_SINGLE, - sys_us_2_lpcycles(s_app_timer_info.apptimer_runout_time)); - } else { - s_app_timer_info.apptimer_start = APP_TIMER_STOP; - pwr_mgmt_notify_timer_event(EVENT_APP_TIMER_STOP); - } - } APP_TIMER_UNLOCK(); - return ; + + return status; } -TINY_RAM_SECTION sdk_err_t app_timer_start(app_timer_id_t p_timer_id, uint32_t delay, uint8_t *p_ctx) +void app_timer_trigger_window_set(uint64_t window_us) { - app_timer_t *p_timer_node = p_timer_id; - uint32_t delay_time = APP_TIMER_MS_TO_US(delay); - uint32_t atimer_curr_ticks = 0, atimer_curr_us = 0; - bool is_pending_trigger = false; + APP_TIMER_LOCK(); + s_app_timer_info.apptimer_trigger_window_us = window_us; + APP_TIMER_UNLOCK(); +} - if (p_timer_node == NULL) - return SDK_ERR_INVALID_PARAM; - - /* DO NOT SUPPORT NULL TIMER */ - if (delay = TIMER_INVALID_DELAY_VALUE) { - return SDK_ERR_INVALID_PARAM; - } +uint64_t app_timer_trigger_window_get(void) +{ + uint64_t window_us = APP_TIMER_TRIGGER_WINDOW_US; APP_TIMER_LOCK(); - - app_timer_t *p_cur_node = p_timer_node; - - if (p_cur_node->timer_node_status == APP_TIMER_NODE_START) { - APP_TIMER_UNLOCK(); - return SDK_ERR_BUSY; - } - - p_cur_node->next_trigger_callback_var = p_ctx; - p_cur_node->timer_node_status = APP_TIMER_NODE_START; - /*******ther first time to start timer********/ - if (APP_TIMER_STOP == s_app_timer_info.apptimer_start) { - NVIC_ClearPendingIRQ(SLPTIMER_IRQn); - - s_app_timer_info.p_curr_timer_node = p_cur_node; - s_app_timer_info.apptimer_runout_time = delay_time; - s_app_timer_info.apptimer_total_ticks = 0x0; - s_app_timer_info.apptimer_start = APP_TIMER_START; - - p_cur_node->original_delay = delay_time; - p_cur_node->next_trigger_time = delay_time + s_app_timer_info.apptimer_total_ticks; - - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_SINGLE, - sys_us_2_lpcycles(s_app_timer_info.apptimer_runout_time)); - /* - * < NVIC_EnableIRQ(SLPTIMER_IRQn) > - * This function must be placed after initializing the parameters of timer, - * otherwise an unprepared timer interrupt may be triggered ahead of time, leading to hardfault. - */ - NVIC_EnableIRQ(SLPTIMER_IRQn); - } else { - /* - To stop sleep timer counter. if time expired at this time, - the counter of sleep timer will filled with 0xFFFFFFFF. - */ - if (s_app_timer_info.p_curr_timer_node->original_delay >= delay_time) { - app_timer_drv_stop(); - } - - /* To get current counter in sleep timer. */ - APP_TIMER_GET_CURRENT_TICKS(&atimer_curr_ticks); - - /* Current counter transform to u-second. */ - atimer_curr_us = (uint32_t)(APP_TIMER_TICKS_TO_US(atimer_curr_ticks)); - - /* - Because when the sleep timer counts to zero, - the counter value will automatically be 0xFFFFFFFF. - so we need to manually change to 0 and set is_pending_trigger to true. - */ - if (atimer_curr_ticks == 0xFFFFFFFF) { - atimer_curr_us = 0x0; - is_pending_trigger = true; - } - - /* To get the rest of ran time of the current timer node. */ - uint32_t already_ran_time = s_app_timer_info.apptimer_runout_time - atimer_curr_us; - - if (atimer_curr_us > delay_time) { - s_app_timer_info.p_curr_timer_node = p_cur_node; - s_app_timer_info.apptimer_runout_time = delay_time; - } - - p_cur_node->original_delay = delay_time; - - if (s_app_timer_info.p_curr_timer_node->original_delay >= delay_time) { - if (is_pending_trigger == false) { - s_app_timer_info.apptimer_total_ticks += already_ran_time; - p_cur_node->next_trigger_time = delay_time + s_app_timer_info.apptimer_total_ticks; - s_app_timer_info.apptimer_runout_time = s_app_timer_info.p_curr_timer_node->next_trigger_time - - s_app_timer_info.apptimer_total_ticks; - } else { - p_cur_node->next_trigger_time = delay_time + s_app_timer_info.apptimer_total_ticks + already_ran_time; - } - - if ((is_pending_trigger == false)&&(s_app_timer_info.apptimer_runout_time < 0)) { - s_app_timer_info.apptimer_runout_time = 0; - } - if (is_pending_trigger == false) { - hal_pwr_config_timer_wakeup(PWR_SLP_TIMER_MODE_SINGLE, - sys_us_2_lpcycles(s_app_timer_info.apptimer_runout_time)); - } - } else { - p_cur_node->next_trigger_time = delay_time + s_app_timer_info.apptimer_total_ticks + already_ran_time; - } - } - - pwr_mgmt_notify_timer_event(EVENT_APP_TIMER_START); - + window_us = s_app_timer_info.apptimer_trigger_window_us; APP_TIMER_UNLOCK(); - return SDK_SUCCESS; + + return window_us; } sdk_err_t app_timer_create(app_timer_id_t *p_timer_id, app_timer_type_t mode, app_timer_fun_t callback) { - uint8_t handle = TIMER_INVALID_NODE_NUMBER; - - if (callback == NULL) + if (!IS_APP_TIMER_MODE(mode)) return SDK_ERR_INVALID_PARAM; - /* p_timer_id is already in use */ - if (*p_timer_id != NULL) - return SDK_ERR_DISALLOWED; + if ((NULL == p_timer_id) || (NULL == callback)) + { + return SDK_ERR_INVALID_PARAM; + } APP_TIMER_LOCK(); - /* pick up one null item for new timer node */ - handle = app_timer_get_valid_node(); - if (handle == TIMER_INVALID_NODE_NUMBER) { - *p_timer_id = NULL; - APP_TIMER_UNLOCK(); - return SDK_ERR_LIST_FULL; - } - app_timer_set_var(handle, mode, callback); + p_timer_id->timer_node_status = STOP; + p_timer_id->timer_node_mode = mode; + p_timer_id->timer_node_cb = callback; - *p_timer_id = &s_timer_node[handle]; APP_TIMER_UNLOCK(); + return SDK_SUCCESS; } + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +static void sleep_timer_handler_register(void) +{ + static uint8_t handler_registered = false; + + if (!handler_registered) + { + soc_register_nvic(SLPTIMER_IRQn, (uint32_t)SLPTIMER_IRQHandler); + handler_registered = true; + } +} +static void low_level_timer_startup(uint64_t value) +{ + uint32_t timeout = 0; + uint32_t lpcycles = APP_TIMER_US_TO_TICKS(value); + + APP_ASSERT_CHECK(value <= APP_TIMER_DELAY_US_MAX); + + hal_sleep_timer_config_and_start(PWR_SLP_TIMER_MODE_SINGLE, lpcycles); + while (!hal_sleep_timer_status_get()) + { + delay_us(1); + if (timeout++ >= APP_TIMER_INTERNAL_TIMEOUT) + { + APP_ASSERT_CHECK(false); + return; + } + } +} + +static void low_level_timer_stop(void) +{ + uint32_t timeout = 0; + + hal_sleep_timer_stop(); + while (hal_sleep_timer_status_get()) + { + delay_us(1); + if (timeout++ >= APP_TIMER_INTERNAL_TIMEOUT) + { + APP_ASSERT_CHECK(false); + return; + } + } +} + +static uint64_t low_level_timer_rest_get(void) +{ + uint32_t atimer_curr_ticks = hal_sleep_timer_get_current_value(); + uint64_t curr_rest_us = 0; + + if (atimer_curr_ticks == 0xFFFFFFFF) + { + return 0; + } + + curr_rest_us = APP_TIMER_TICKS_TO_US(atimer_curr_ticks); + if (s_app_timer_info.p_curr_timer_node) + { + if (curr_rest_us > (s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us)) + curr_rest_us = s_app_timer_info.p_curr_timer_node->next_shot_time - s_app_timer_info.apptimer_total_us; + } + else + { + curr_rest_us = 0; + } + + return curr_rest_us; +} + +static uint8_t app_timer_running_queue_insert(app_timer_t *p_timer_id) +{ + if (p_timer_id == NULL) + { + return false; + } + + APP_TIMER_LOCK(); + + app_timer_t *tmp = (app_timer_id_t *)&s_app_timer_info.hd_node; + p_timer_id->p_next = NULL; + + while (tmp->p_next) + { + app_timer_t *curr_node = tmp->p_next; + if (curr_node->next_shot_time > p_timer_id->next_shot_time) + { + p_timer_id->p_next = tmp->p_next; + break; + } + tmp = tmp->p_next; + } + + tmp->p_next = p_timer_id; + p_timer_id->timer_node_status = RUN; + + s_app_timer_info.cnt_node++; + s_app_timer_info.p_curr_timer_node = s_app_timer_info.hd_node.p_next; + + APP_TIMER_UNLOCK(); + return true; +} + +static uint8_t app_timer_running_queue_trigger_window_mark(void) +{ + // todo: + // 1, pick timer nodes that fall within the trigger window; + // 2, mark these timers; + // 1), for repeat node, need mark and adjust next_shot_timer; + // 2), for one-shot node, chain up these timers in specify list + + APP_TIMER_LOCK(); + + app_timer_t *p_triggered_node = NULL; + app_timer_t *tmp = &s_app_timer_info.hd_node; + + while (tmp->p_next) + { + if (FALL_WITHIN_TRIGGER_WINDOW(tmp->p_next->next_shot_time)) + { + p_triggered_node = tmp->p_next; + WITHIN_TRIGGER_WINDOW_MARK(p_triggered_node); + + app_timer_running_queue_remove(p_triggered_node); + if (p_triggered_node->timer_node_mode == ATIMER_REPEAT) + { + p_triggered_node->next_shot_time = s_app_timer_info.apptimer_total_us + p_triggered_node->original_delay; + app_timer_running_queue_insert(p_triggered_node); + } + else + { + app_timer_t **pp_trigger_window_one_shot_node_tail = &s_app_timer_info.p_within_window_one_shot_node_hd; + while (*pp_trigger_window_one_shot_node_tail) + { + pp_trigger_window_one_shot_node_tail = &(*pp_trigger_window_one_shot_node_tail)->p_next; + } + p_triggered_node->p_next = NULL; + (*pp_trigger_window_one_shot_node_tail)->p_next = p_triggered_node; + } + } + else + { + break; + } + } + + APP_TIMER_UNLOCK(); + return true; +} + +static uint8_t app_timer_running_queue_trigger_window_execute(void) +{ + // todo: + // 1, check timer node that marked in the app_timer_running_queue_trigger_window_mark(); + // 2, execute the callback; + // 3, clear mark; + + APP_TIMER_LOCK(); + + app_timer_t *p_triggered_node = NULL; + app_timer_t *tmp = &s_app_timer_info.hd_node; + + while (tmp->p_next) + { + if (IS_TRIGGER_WINDOW_MARKED(tmp->p_next)) + { + p_triggered_node = tmp->p_next; + + if (p_triggered_node->timer_node_cb) + p_triggered_node->timer_node_cb(p_triggered_node->arg); + else + APP_ASSERT_CHECK(false); + + WITHIN_TRIGGER_WINDOW_CLEAR(p_triggered_node); + } + + tmp = tmp->p_next; + } + + while (s_app_timer_info.p_within_window_one_shot_node_hd) + { + p_triggered_node = s_app_timer_info.p_within_window_one_shot_node_hd; + if (p_triggered_node->timer_node_cb) + p_triggered_node->timer_node_cb(p_triggered_node->arg); + else + APP_ASSERT_CHECK(false); + + WITHIN_TRIGGER_WINDOW_CLEAR(p_triggered_node); + + s_app_timer_info.p_within_window_one_shot_node_hd = p_triggered_node->p_next; + p_triggered_node->p_next = NULL; + } + + APP_TIMER_UNLOCK(); + return true; +} + +static app_timer_t *app_timer_running_queue_remove(app_timer_id_t *p_timer_id) +{ + app_timer_t *remove_node = NULL; + + APP_TIMER_LOCK(); + + if (NULL != s_app_timer_info.hd_node.p_next) + { + if (NULL == p_timer_id) + { + // the node that will be removed is the first node + remove_node = s_app_timer_info.hd_node.p_next; + + s_app_timer_info.hd_node.p_next = remove_node->p_next; + s_app_timer_info.cnt_node--; + } + else + { + // remove specified node + app_timer_t *tmp = (app_timer_id_t *)&s_app_timer_info.hd_node; + while (tmp->p_next) + { + if (tmp->p_next == p_timer_id) + { + s_app_timer_info.cnt_node--; + tmp->p_next = p_timer_id->p_next; + + remove_node = p_timer_id; + break; + } + tmp = tmp->p_next; + } + } + + if (remove_node) + { + remove_node->p_next = NULL; + remove_node->timer_node_status = STOP; + s_app_timer_info.p_curr_timer_node = s_app_timer_info.hd_node.p_next; + } + } + + APP_TIMER_UNLOCK(); + return remove_node; +} + +static void app_timer_node_init(app_timer_id_t *p_timer_id, uint64_t delay, void *p_ctx, uint64_t insert_time) +{ + p_timer_id->arg = p_ctx; + p_timer_id->original_delay = APP_TIMER_MS_TO_US(delay); + p_timer_id->next_shot_time = insert_time + p_timer_id->original_delay; + p_timer_id->p_next = NULL; +} + +static uint8_t is_need_insert_front(uint64_t delay_value, uint64_t rest_time) +{ + APP_TIMER_LOCK(); + if (s_app_timer_info.p_curr_timer_node == NULL) + { + APP_TIMER_UNLOCK(); + return APP_TIMER_RET_SUC; + } + + APP_ASSERT_CHECK(rest_time <= s_app_timer_info.p_curr_timer_node->original_delay); + { + if (delay_value < rest_time) + { + APP_TIMER_UNLOCK(); + return APP_TIMER_RET_SUC; + } + } + APP_TIMER_UNLOCK(); + return APP_TIMER_RET_FAIL; +} + +static uint8_t is_timer_node_created(app_timer_id_t *p_timer_id) +{ + if (p_timer_id) + { + if ((p_timer_id->timer_node_cb) && + (IS_APP_TIMER_MODE(p_timer_id->timer_node_mode))) + return true; + } + + return false; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.h old mode 100755 new mode 100644 index 99eb6bd..421c8a9 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/app_timer/app_timer.h @@ -38,27 +38,34 @@ #ifndef __APP_TIMER_H__ #define __APP_TIMER_H__ +#include "grx_sys.h" #include #include -#include "gr55xx_sys.h" /** * @defgroup APP_TIMER_MAROC Defines * @{ */ -#ifndef APP_TIMER_USE_SCHEDULER -#define APP_TIMER_USE_SCHEDULER 0 /**< Enable scheduling app_timer events to app_scheduler. */ -#endif +/** @brief For compatibility with previous version. */ +#define app_timer_start(a, b, c) app_timer_start_api(&a, b, c) +#define app_timer_stop(a) app_timer_stop_api(&a) + +/** @brief App timer version difine. */ +#define APP_TIMER_VERSION 0x0200 + +/** @brief App timer assert enable define. */ +#define APP_TIMER_ASSERT_ENABLE 0 /** @} */ /** * @defgroup APP_TIMER_ENUM Enumerations * @{ */ -/**@brief App timer trigger types. */ -typedef enum { - ATIMER_ONE_SHOT = 0x0, /**< The timer will expire only once. */ - ATIMER_REPEAT /**< The timer will restart each time it expires. */ +/** @brief App timer trigger types. */ +typedef enum +{ + ATIMER_ONE_SHOT = 0x0, /**< The timer will expire only once. */ + ATIMER_REPEAT /**< The timer will restart each time it expires. */ } app_timer_type_t; /** @} */ @@ -66,40 +73,36 @@ typedef enum { * @defgroup APP_TIMER_TYPEDEF Typedefs * @{ */ -/**@brief The timer node trigger function. */ -typedef void (*app_timer_fun_t)(uint8_t* p_ctx); +/** @brief The timer node trigger function. */ +typedef void (*app_timer_fun_t)(void* p_ctx); /** @} */ /** * @defgroup APP_TIMER_STRUCT Structures * @{ */ -/**@brief App timer global variable. */ -typedef struct { - uint8_t timer_node_used; /**< Timer node is used or not. */ - uint8_t timer_node_status; /**< Timer node status. */ - uint8_t next_trigger_mode; /**< Next trigger mode. */ - uint32_t original_delay; /**< Original delay (us). */ - uint32_t next_trigger_time; /**< Next trigger time. */ - uint8_t* next_trigger_callback_var; /**< Timer trigger callback argument. */ - app_timer_fun_t next_trigger_callback; /**< Timer trigger callback . */ +/** @brief App timer global variable. */ +typedef struct app_timer_s +{ + uint8_t timer_mark; + uint8_t timer_node_status; /**< Timer node status. */ + uint8_t timer_node_mode; /**< Next trigger mode. */ + uint64_t original_delay; /**< Original delay (us). */ + uint64_t next_shot_time; + void* arg; /**< Timer trigger callback argument. */ + app_timer_fun_t timer_node_cb; /**< Timer trigger callback . */ + struct app_timer_s *p_next; } app_timer_t; -#if APP_TIMER_USE_SCHEDULER -/**@brief Structure passed to app_scheduler. */ -typedef struct { - app_timer_fun_t timeout_handler; /**< Timer timeout handler. */ - void *p_ctx; /**< Pointer to callback argument. */ -} app_timer_evt_t; -#endif /** @} */ /** * @defgroup APP_TIMER_TYPEDEF Typedefs * @{ */ -/**@brief The timer node id. */ -typedef app_timer_t* app_timer_id_t; +/** @brief The timer node id. */ +typedef app_timer_t app_timer_id_t; +typedef app_timer_t* p_app_timer_id_t; /** @} */ /** @@ -131,21 +134,13 @@ typedef app_timer_t* app_timer_id_t; */ sdk_err_t app_timer_create(app_timer_id_t *p_timer_id, app_timer_type_t mode, app_timer_fun_t callback); -/** - ***************************************************************************************** - * @brief Gets the current app timer's switching status - * @return state 0 means stop 1 means open - ***************************************************************************************** - */ -uint8_t app_timer_get_status(void); - /** ***************************************************************************************** * @brief To stop a existed timer in node list * @param[in] p_timer_id: the id of timer node ***************************************************************************************** */ -void app_timer_stop(app_timer_id_t p_timer_id); +void app_timer_stop_api(app_timer_id_t *p_timer_id); /** ***************************************************************************************** @@ -156,7 +151,7 @@ void app_timer_stop(app_timer_id_t p_timer_id); * @param[in] p_ctx : the pointer of context ***************************************************************************************** */ -sdk_err_t app_timer_start(app_timer_id_t p_timer_id, uint32_t delay, uint8_t *p_ctx); +sdk_err_t app_timer_start_api(app_timer_id_t *p_timer_id, uint32_t delay, void *p_ctx); /** ***************************************************************************************** @@ -169,14 +164,52 @@ sdk_err_t app_timer_delete(app_timer_id_t *p_timer_id); /** ***************************************************************************************** - * @brief Stop the currently running timer and return the running time - * - * @param[in] p_timer_handle: Pointer to the timer handle - * - * @return The time that the current timer has run + * @brief Gets the current app timer's switching status + * @return state 0 means stop, 1 means run ***************************************************************************************** */ -uint32_t app_timer_stop_and_ret(app_timer_id_t p_timer_id); +uint8_t app_timer_get_status(void); + +/** + ***************************************************************************************** + * @brief Set the app timer's trigger window, all timer nodes that fall within the window + * will be triggered at the same time. + * @param[in] window_us: new trigger window size, in us + ***************************************************************************************** + */ +void app_timer_trigger_window_set(uint64_t window_us); + +/** + ***************************************************************************************** + * @brief Get the app timer's trigger window, all timer nodes that fall within the window + * will be triggered at the same time. + * @return current trigger window size, in us + ***************************************************************************************** + */ +uint64_t app_timer_trigger_window_get(void); + +#define IS_APP_TIMER_MODE(MODE) \ + (((MODE) == ATIMER_ONE_SHOT) || ((MODE) == ATIMER_REPEAT)) + +#define APP_TIMER_DEFINE(name, func, mode) \ + app_timer_t name = \ + { \ + .timer_node_status = 0x0, \ + .timer_node_mode = mode, \ + .timer_node_cb = func, \ + } + +#define APP_TIMER_QUICK_START(name, func, peido) \ + { \ + app_timer_create(&name, ATIMER_REPEAT, func); \ + app_timer_start_api(&name, peido, &name); \ + } + +#define APP_TIMER_QUICK_STOP(name) \ + { \ + app_timer_stop_api(&name); \ + } + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/BUILD.gn new file mode 100644 index 0000000..b9a83dd --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("at_cmd") { + sources = [ + "at_cmd.c", + "at_cmd_utils.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.c new file mode 100644 index 0000000..60f4ad6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.c @@ -0,0 +1,366 @@ +/** + **************************************************************************************** + * + * @file AT_CMD.c + * + * @brief AT Command implementation. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "at_cmd.h" +#include "at_cmd_utils.h" +#include "cmsis_compiler.h" +#include + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief AT Command environment variable. */ +struct at_cmd_env_t +{ + uint8_t cmd_num; + at_cmd_src_t cmd_src; + at_cmd_attr_t *p_cmd_attr; + at_cmd_time_callback_t cmd_time_cb; + at_cmd_cplt_callback_t cmd_cplt_cb; + at_cmd_state_t cmd_state; +}; + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +static struct at_cmd_env_t s_at_cmd_env; +static at_cmd_parse_t s_parse_rlt; + +static uint8_t at_cmd_inp_buff[AT_CMD_BUFFER_SIZE_MAX]; +static uint8_t at_cmd_rsp_buff[AT_CMD_BUFFER_SIZE_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + ***************************************************************************************** + * @brief Check AT CMD input integrity. + * + * @param[in] p_data: Pointer to input data. + * @param[in] length: Length of input data. + * @param[out] p_parse_rlt: Pointer to parse result. + * + * @return Result of check. + ***************************************************************************************** + */ +static bool at_cmd_integrity_check(const uint8_t *p_data, uint16_t length, at_cmd_parse_t *p_parse_rlt) +{ + if (0 != memcmp(p_data, "AT:", 3)) + { + return false; + } + for (uint8_t i = 1; i < length; i++) + { + if (0x0a == p_data[i] && 0x0d == p_data[i - 1]) + { + p_parse_rlt->buff_length = i + 1; + memcpy(p_parse_rlt->p_buff, p_data, p_parse_rlt->buff_length); + return true; + } + } + + return false; +} + +/** + ***************************************************************************************** + * @brief Get args of AT CMD. + * + * @param[out] p_parse_rlt: Pointer to parse result. + ***************************************************************************************** + */ +static void at_cmd_args_get(at_cmd_parse_t *p_parse_rlt) +{ + p_parse_rlt->arg_count = 0; + + uint16_t first_arg_idx = 0; + + p_parse_rlt->cmd_tag_idx = 3; + + for (uint16_t i = p_parse_rlt->cmd_tag_idx; i <= (p_parse_rlt->buff_length - 2); i++) + { + if (i == (p_parse_rlt->buff_length - 2)) + { + p_parse_rlt->cmd_tag_length = i - p_parse_rlt->cmd_tag_idx; + p_parse_rlt->arg_count = 0; + return; + } + + if ('=' == p_parse_rlt->p_buff[i]) + { + p_parse_rlt->cmd_tag_length = i - p_parse_rlt->cmd_tag_idx + 1; + first_arg_idx = i + 1; + break; + } + } + + p_parse_rlt->arg_idx[0] = first_arg_idx; + + for (uint16_t i = first_arg_idx; i <= (p_parse_rlt->buff_length - 2); i++) + { + if ((':' == p_parse_rlt->p_buff[i]) || (',' == p_parse_rlt->p_buff[i])) + { + p_parse_rlt->arg_length[p_parse_rlt->arg_count] = i - p_parse_rlt->arg_idx[p_parse_rlt->arg_count]; + p_parse_rlt->arg_count++; + p_parse_rlt->arg_idx[p_parse_rlt->arg_count] = i + 1; + } + else if (i == (p_parse_rlt->buff_length - 2)) + { + p_parse_rlt->arg_length[p_parse_rlt->arg_count] = i - p_parse_rlt->arg_idx[p_parse_rlt->arg_count]; + p_parse_rlt->arg_count++; + } + } +} + +/** + ***************************************************************************************** + * @brief Get ID of AT CMD. + * + * @param[out] p_parse_rlt: Pointer to parse result. + ***************************************************************************************** + */ +static void at_cmd_id_get(at_cmd_parse_t *p_parse_rlt) +{ + p_parse_rlt->cmd_id = AT_CMD_INVALID; + + for (uint8_t i = 0; i < s_at_cmd_env.cmd_num; i++) + { + if (p_parse_rlt->cmd_tag_length == s_at_cmd_env.p_cmd_attr[i].cmd_tag_length) + { + if (0 == memcmp(&p_parse_rlt->p_buff[p_parse_rlt->cmd_tag_idx], + s_at_cmd_env.p_cmd_attr[i].cmd_tag_str, + p_parse_rlt->cmd_tag_length)) + { + p_parse_rlt->cmd_id = s_at_cmd_env.p_cmd_attr[i].cmd_id; + p_parse_rlt->cmd_idx = i; + break; + } + } + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void at_cmd_init(at_cmd_init_t *p_cmd_init) +{ + memset(&s_at_cmd_env, 0, sizeof(s_at_cmd_env)); + memset(&s_parse_rlt, 0, sizeof(at_cmd_parse_t)); + + s_at_cmd_env.cmd_num = p_cmd_init->cmd_num; + s_at_cmd_env.p_cmd_attr = p_cmd_init->p_cmd_attr; + s_at_cmd_env.cmd_time_cb = p_cmd_init->cmd_time_cb; + s_at_cmd_env.cmd_cplt_cb = p_cmd_init->cmd_cplt_cb; + s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE; + s_at_cmd_env.cmd_src = AT_CMD_SRC_UART; + + s_parse_rlt.p_buff = at_cmd_inp_buff; + s_parse_rlt.buff_length = 0; +} + +void at_cmd_parse(at_cmd_src_t cmd_src, const uint8_t *p_data, uint16_t length) +{ + AT_CMD_RSP_DEF(cmd_rsp); + bool reset = false; + static at_cmd_parse_t pre_parse_rlt; + + s_at_cmd_env.cmd_src = cmd_src; + if (pre_parse_rlt.cmd_id == AT_CMD_CONN_INIT) + { + s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE; + reset = true; + } + + // Check parse cmd is allowed or not + if (AT_CMD_IN_READY_PARSE != s_at_cmd_env.cmd_state) + { + cmd_rsp.error_code = AT_CMD_ERR_PARSE_NOT_ALLOWED; + at_cmd_execute_cplt(&cmd_rsp); + return; + } + else + { + s_at_cmd_env.cmd_state = AT_CMD_IN_PARSING; + } + + // Check cmd input is integrity or not + if (!at_cmd_integrity_check(p_data, length, &s_parse_rlt)) + { + cmd_rsp.error_code = AT_CMD_ERR_INVALID_INPUT; + at_cmd_execute_cplt(&cmd_rsp); + return; + } + + // Get cmd parameters + at_cmd_args_get(&s_parse_rlt); + + // Get cmd Id + at_cmd_id_get(&s_parse_rlt); + + if (reset && s_parse_rlt.cmd_id == AT_CMD_CONN_CANCEL) + { + cmd_rsp.error_code = AT_CMD_ERR_NO_ERROR; + cmd_rsp.length = at_cmd_printf_bush(cmd_rsp.data, "start cancel connect..."); + at_cmd_execute_cplt(&cmd_rsp); + } + + // Check cmd id is valid or not + if (AT_CMD_INVALID == s_parse_rlt.cmd_id) + { + cmd_rsp.error_code = AT_CMD_ERR_UNSUPPORTED_CMD; + at_cmd_execute_cplt(&cmd_rsp); + return; + } + + s_at_cmd_env.cmd_state = AT_CMD_IN_WAITE_EXECUTE; + pre_parse_rlt = s_parse_rlt; +} + +void at_cmd_execute_timing_process(void) +{ + AT_CMD_RSP_DEF(cmd_rsp); + + if (AT_CMD_IN_READY_PARSE != s_at_cmd_env.cmd_state) + { + s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE; + + cmd_rsp.error_code = AT_CMD_ERR_TIMEOUT; + at_cmd_execute_cplt(&cmd_rsp); + } +} + +void at_cmd_execute_cplt(at_cmd_rsp_t *p_cmd_rsp) +{ + uint8_t length = 0; + + if (AT_CMD_ERR_NO_ERROR != p_cmd_rsp->error_code) + { + switch(p_cmd_rsp->error_code) + { + case AT_CMD_ERR_INVALID_INPUT: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Invalid input."); + break; + case AT_CMD_ERR_UNSUPPORTED_CMD: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Unsupported AT CMD."); + break; + case AT_CMD_ERR_PARSE_NOT_ALLOWED: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: No allowed parse state."); + break; + case AT_CMD_ERR_CMD_REQ_ALLOWED: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Command request is not allowed."); + break; + case AT_CMD_ERR_NO_CMD_HANDLER: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: No AT CMD handler."); + break; + case AT_CMD_ERR_INVALID_PARAM: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Invalid parameters."); + break; + case AT_CMD_ERR_HAL_ERROR: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Hal error."); + break; + case AT_CMD_ERR_TIMEOUT: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: AT CMD execute timeout."); + break; + case AT_CMD_ERR_OTHER_ERROR: + length = at_cmd_printf_bush(at_cmd_rsp_buff, "ERR: Other error code."); + break; + default: + break; + } + } + else + { + memcpy(at_cmd_rsp_buff, p_cmd_rsp->data, p_cmd_rsp->length); + length = p_cmd_rsp->length; + } + + at_cmd_rsp_buff[length] = 0x0d; + at_cmd_rsp_buff[length + 1] = 0x0a; + + if (s_at_cmd_env.cmd_cplt_cb) + { + if (AT_CMD_SRC_UART == s_at_cmd_env.cmd_src) + { + s_at_cmd_env.cmd_cplt_cb(AT_CMD_RSP_DEST_UART, at_cmd_rsp_buff, length + 2); + } + else if (AT_CMD_SRC_BLE == s_at_cmd_env.cmd_src) + { + s_at_cmd_env.cmd_cplt_cb(AT_CMD_RSP_DEST_BLE, at_cmd_rsp_buff, length + 2); + } + } + + s_at_cmd_env.cmd_state = AT_CMD_IN_READY_PARSE; + if (AT_CMD_ERR_TIMEOUT == p_cmd_rsp->error_code && + s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_timeout_str) + { + char *cmd_timeout_str = s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_timeout_str; + uint16_t length = strlen(cmd_timeout_str); + at_cmd_parse(s_at_cmd_env.cmd_src, (const uint8_t *)cmd_timeout_str, length); + } +} + +void at_cmd_schedule(void) +{ + if (AT_CMD_IN_WAITE_EXECUTE == s_at_cmd_env.cmd_state) + { + s_at_cmd_env.cmd_state = AT_CMD_IN_EXECUTING; + + if (s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_handler) + { + if (s_at_cmd_env.cmd_time_cb) + { + s_at_cmd_env.cmd_time_cb(); + } + + s_at_cmd_env.p_cmd_attr[s_parse_rlt.cmd_idx].cmd_handler(&s_parse_rlt); + } + else + { + AT_CMD_RSP_DEF(cmd_rsp); + cmd_rsp.error_code = AT_CMD_ERR_NO_CMD_HANDLER; + at_cmd_execute_cplt(&cmd_rsp); + } + } +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.h new file mode 100644 index 0000000..9afb7ea --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd.h @@ -0,0 +1,247 @@ +/** + ***************************************************************************************** + * + * @file AT_CMD.h + * + * @brief AT Command API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __AT_CMD_H_ +#define __AT_CMD_H_ + +#include +#include + + +/** + * @defgroup AT_CMD_MACRO Defines + * @{ + */ +#define AT_CMD_BUFFER_SIZE_MAX 256 /**< Maximum size of AT CMD buffer. */ +#define AT_CMD_ARG_COUNT_MAX 28 /**< Maximum number of arguments input. */ +/** @} */ + +/** + * @defgroup AT_CMD_ENUM Enumerations + * @{ + */ +/**@brief AT CMD state. */ +typedef enum +{ + AT_CMD_IN_READY_PARSE = 0x01, /**< Ready for AT CMD parse state. */ + AT_CMD_IN_PARSING, /**< In parsing AT CMD state. */ + AT_CMD_IN_WAITE_EXECUTE, /**< Waite for executing state. */ + AT_CMD_IN_EXECUTING, /**< In executing state. */ +} at_cmd_state_t; + +/**@brief AT CMD source type. */ +typedef enum +{ + AT_CMD_SRC_INVALID, /**< Invalid AT CMD source. */ + AT_CMD_SRC_UART, /**< AT CMD source: Uart. */ + AT_CMD_SRC_BLE, /**< AT CMD source: BLE. */ +} at_cmd_src_t; + +/**@brief AT CMD response destination type. */ +typedef enum +{ + AT_CMD_RSP_DEST_INVALID, /**< Invalid AT CMD response destination. */ + AT_CMD_RSP_DEST_UART, /**< AT CMD response destination: Uart. */ + AT_CMD_RSP_DEST_BLE, /**< AT CMD response destination: BLE.*/ +} at_cmd_rsp_dest_t; + +/**@brief AT CMD ID type. */ +typedef enum +{ + AT_CMD_INVALID, /**< Invalid AT CMD type. */ + AT_CMD_TEST, /**< Test module AT CMD. */ + AT_CMD_VERSION_GET, /**< Module version get AT CMD. */ + AT_CMD_RESET, /**< System reset. */ + AT_CMD_BAUD_SET, /**< Uart baud rate set AT CMD. */ + AT_CMD_ADDR_GET, /**< Board address get AT CMD. */ + AT_CMD_GAP_ROLE_GET, /**< GAP role get AT CMD. */ + AT_CMD_GAP_ROLE_SET, /**< GAP role set AT CMD. */ + AT_CMD_GAP_NAME_GET, /**< GAP name get AT CMD. */ + AT_CMD_GAP_NAME_SET, /**< GAP name set AT CMD. */ + AT_CMD_ADV_PARAM_SET, /**< Advertising parameters set AT CMD. */ + AT_CMD_ADV_DATA_SET, /**< Advertising data set AT CMD. */ + AT_CMD_RSP_DATA_SET, /**< Scan response data set AT CMD. */ + AT_CMD_ADV_START, /**< Start advertising AT CMD. */ + AT_CMD_ADV_STOP, /**< Stop advertising AT CMD. */ + AT_CMD_SCAN_PARAM_SET, /**< Scan parameters set AT CMD. */ + AT_CMD_SCAN_START, /**< Start scan AT CMD. */ + AT_CMD_SCAN_STOP, /**< Stop scan AT CMD. */ + AT_CMD_CONN_PARAM_SET, /**< Connect parameters set AT CMD. */ + AT_CMD_CONN_INIT, /**< Initiate connection AT CMD. */ + AT_CMD_CONN_CANCEL, /**< Cancel connection AT CMD. */ + AT_CMD_DISCONN, /**< Disconnect AT CMD. */ + AT_CMD_MTU_EXCHANGE, /**< Exchange MTU AT CMD. */ + AT_CMD_SRVC_DISC, /**< Discovery service AT CMD. */ + AT_CMD_CONN_PARAM_UPDATE, /**< Connect parameters update AT CMD. */ + AT_CMD_ATTR_READ, /**< Read attr AT CMD. */ + AT_CMD_ATTR_WRITE, /**< Write attr AT CMD. */ + AT_CMD_NB /**< Number of supported AT CMD. */ +} at_cmd_id_t; + +/**@brief AT CMD error code. */ +typedef enum +{ + AT_CMD_ERR_NO_ERROR, /**< No error. */ + AT_CMD_ERR_INVALID_INPUT, /**< Invalid input. */ + AT_CMD_ERR_UNSUPPORTED_CMD, /**< Unsupported AT CMD. */ + AT_CMD_ERR_PARSE_NOT_ALLOWED, /**< No allowed parse state. */ + AT_CMD_ERR_CMD_REQ_ALLOWED, /**< Command request is not allowed. */ + AT_CMD_ERR_NO_CMD_HANDLER, /**< No AT CMD handler. */ + AT_CMD_ERR_INVALID_PARAM, /**< Invalid parameters. */ + AT_CMD_ERR_HAL_ERROR, /**< Hal error. */ + AT_CMD_ERR_TIMEOUT, /**< AT CMD execute timeout. */ + + AT_CMD_ERR_OTHER_ERROR, /**< Other error code. */ +} at_cmd_error_t; +/** @} */ + +/** + * @defgroup AT_CMD_STRUCT Structures + * @{ + */ +/**@brief AT CMD parse result. */ +typedef struct +{ + at_cmd_id_t cmd_id; /**< AT CMD ID type. */ + uint8_t cmd_idx; /**< AT CMD index in its table. */ + uint8_t cmd_tag_idx; /**< AT CMD tag index. */ + uint8_t cmd_tag_length; /**< Length of AT CMD tag. */ + uint8_t arg_count; /**< Count of arguments. */ + uint8_t arg_idx[AT_CMD_ARG_COUNT_MAX]; /**< Index of arguments. */ + uint8_t arg_length[AT_CMD_ARG_COUNT_MAX]; /**< Length of arguments. */ + uint8_t *p_buff; /**< Pointer to AT CMD buffer. */ + uint16_t buff_length; /**< BUffer valid length. */ +} at_cmd_parse_t; + +/**@brief AT CMD response variables. */ +typedef struct +{ + at_cmd_error_t error_code; /**< Error code. */ + uint8_t data[AT_CMD_BUFFER_SIZE_MAX]; /**< Response data. */ + uint16_t length; /**< Length of response data. */ +} at_cmd_rsp_t; +/** @} */ + +/** + * @defgroup AT_CMD_TYPEDEF Typedefs + * @{ + */ +/**@brief AT CMD handler type. */ +typedef void (*at_cmd_handler_t)(at_cmd_parse_t *p_cmd_parse); + +/**@brief AT CMD execute timing callback type. */ +typedef void (*at_cmd_time_callback_t)(void); + +/**@brief AT CMD execute complete callback type. */ +typedef void (*at_cmd_cplt_callback_t)(at_cmd_rsp_dest_t rsp_dest, const uint8_t *p_data, uint8_t length); +/** @} */ + +/** + * @defgroup AT_CMD_STRUCT Structures + * @{ + */ +/**@brief AT CMD attribute. */ +typedef struct +{ + at_cmd_id_t cmd_id; /**< AT CMD ID type. */ + char *cmd_tag_str; /**< String of AT CMD tag. */ + uint8_t cmd_tag_length; /**< Length of AT CMD tag. */ + at_cmd_handler_t cmd_handler; /**< AT CMD handler. */ + char *cmd_timeout_str; /**< String of timeout AT CMD. */ +} at_cmd_attr_t; + +/**@brief AT CMD initialization variables. */ +typedef struct +{ + at_cmd_attr_t *p_cmd_attr; /**< Pointer to AT CMD attribute table. */ + uint8_t cmd_num; /**< Number of AT CMD register. */ + at_cmd_time_callback_t cmd_time_cb; /**< AT CMD timing callback. */ + at_cmd_cplt_callback_t cmd_cplt_cb; /**< AT CMD execute complete callback. */ +} at_cmd_init_t; +/** @} */ + +/** + * @defgroup AT_CMD_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize AT CMD module. + * + * @param[in] p_cmd_init: Pointer to p_cmd_init. + ***************************************************************************************** + */ +void at_cmd_init(at_cmd_init_t *p_cmd_init); + +/** + ***************************************************************************************** + * @brief Parse user input data. + * + * @param[in] cmd_src: Source of input. + * @param[in] p_data: Pointer to input data. + * @param[in] length: Length of input data. + ***************************************************************************************** + */ +void at_cmd_parse(at_cmd_src_t cmd_src, const uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Process AT CMD execute timing check. + ***************************************************************************************** + */ +void at_cmd_execute_timing_process(void); + +/** + ***************************************************************************************** + * @brief AT CMD execute complete. + * + * @param[in] p_cmd_rsp: Pointer to cmd response. + ***************************************************************************************** + */ +void at_cmd_execute_cplt(at_cmd_rsp_t *p_cmd_rsp); + +/** + ***************************************************************************************** + * @brief AT CMD schedule, called in main(). + ***************************************************************************************** + */ +void at_cmd_schedule(void); +/** @} */ + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.c new file mode 100644 index 0000000..319abcf --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.c @@ -0,0 +1,157 @@ +/** + **************************************************************************************** + * + * @file at_cmd_utils.c + * + * @brief AT Command Utilities implementation. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "at_cmd_utils.h" +#include +#include +#include + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +uint8_t at_cmd_printf_bush(uint8_t *p_buff, const char *format, ...) +{ + char str_temp[AT_CMD_BUFFER_SIZE_MAX]; + va_list ap; + + va_start(ap, format); + vsprintf(str_temp, format, ap); + va_end(ap); + + memcpy(p_buff, (uint8_t *)str_temp, strlen(str_temp)); + + return (strlen(str_temp)); +} + +bool at_cmd_decimal_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num) +{ + if (0 == length) + { + return false; + } + + *p_num = 0; + + for (uint8_t i = 0; i < length; i++) + { + if ('0' > p_data[i] || '9' < p_data[i]) + { + return false; + } + else + { + *p_num = (*p_num * 10) + (p_data[i] - '0'); + } + } + + return true; +} + +bool at_cmd_hex_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num) +{ + if (2 >= length) + { + return false; + } + + *p_num = 0; + if ('0' != p_data[0]||('X' != p_data[1]&&'x' != p_data[1])) + { + return false; + } + for (uint8_t i = 2; i < length; i++) + { + if ('0' <= p_data[i] && '9' >= p_data[i]) + { + *p_num = (*p_num * 16) + (p_data[i] - '0'); + } + else if ('a' <= p_data[i] && 'f' >= p_data[i]) + { + *p_num = (*p_num * 16) + (p_data[i] - 'a' + 10); + } + else if ('A' <= p_data[i] && 'F' >= p_data[i]) + { + *p_num = (*p_num * 16) + (p_data[i] - 'A' + 10); + } + else + { + return false; + } + } + + return true; +} + +at_cmd_error_t at_cmd_hal_err_convert(hal_status_t error_code) +{ + switch (error_code) + { + case HAL_OK: + return AT_CMD_ERR_NO_ERROR; + + case HAL_ERROR: + case HAL_BUSY: + case HAL_TIMEOUT: + return AT_CMD_ERR_HAL_ERROR; + + default: + break; + } + + return AT_CMD_ERR_NO_ERROR; +} + +at_cmd_error_t at_cmd_ble_err_convert(sdk_err_t error_code) +{ + switch (error_code) + { + case BLE_SUCCESS: + return AT_CMD_ERR_NO_ERROR; + + case SDK_ERR_INVALID_PARAM: + case BLE_GAP_ERR_INVALID_PARAM: + return AT_CMD_ERR_INVALID_PARAM; + + default: + return AT_CMD_ERR_OTHER_ERROR; + } +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.h new file mode 100644 index 0000000..d2b2e7b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/at_cmd/at_cmd_utils.h @@ -0,0 +1,128 @@ +/** + ***************************************************************************************** + * + * @file AT_CMD_UTILS.h + * + * @brief AT Command Utilities API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __AT_CMD_UTILS_H__ +#define __AT_CMD_UTILS_H__ + +#include "at_cmd.h" +#include "grx_hal.h" +#include "grx_sys.h" + +/** + * @defgroup AT_CMD_UTILS_MACRO Defines + * @{ + */ +#define ERROR_CHECK(error_code) do \ + { \ + if (0 != error_code) \ + { \ + return error_code; \ + } \ + } while(0) /**< Error check. */ + +#define AT_CMD_RSP_DEF(at_cmd_rsp) at_cmd_rsp_t at_cmd_rsp = \ + { \ + .error_code = AT_CMD_ERR_NO_ERROR, \ + .data = {0}, \ + .length = 0, \ + } /**< Define AT CMD response variable. */ +/** @} */ + +/** + * @defgroup CTS_C_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Prinf string and push to buffer. + * + * @param[in] p_buff: Pointer to buffer. + * + * @result Length of data push to buffer. + ***************************************************************************************** + */ +uint8_t at_cmd_printf_bush(uint8_t *p_buff, const char *format, ...); + +/** + ***************************************************************************************** + * @brief Check decimal number is valid and calculate. + * + * @param[in] p_data: Pointer to data. + * @param[in] length: Length of dta. + * @param[out] p_num: Result of calculate. + + * @result Result of check. + ***************************************************************************************** + */ +bool at_cmd_decimal_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num); + +/** + ***************************************************************************************** + * @brief Check hexadecimal number is valid and calculate. + * + * @param[in] p_data: Pointer to data. + * @param[in] length: Length of dta. + * @param[out] p_num: Result of calculate. + * + * @result Result of check. + ***************************************************************************************** + */ +bool at_cmd_hex_num_check(uint8_t *p_data, uint16_t length, uint32_t *p_num); + +/** + ***************************************************************************************** + * @brief Convert hal error code to AT CMD error code. + * + * @param[in] error_code: HAL error code. + * + * @result Result of convert. + ***************************************************************************************** + */ +at_cmd_error_t at_cmd_hal_err_convert(hal_status_t error_code); + +/** + ***************************************************************************************** + * @brief Convert ble error code to AT CMD error code. + * + * @param[in] error_code: BLE error code. + * + * @result Result of convert. + ***************************************************************************************** + */ +at_cmd_error_t at_cmd_ble_err_convert(sdk_err_t error_code); +/** @} */ +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/BUILD.gn new file mode 100644 index 0000000..9a80612 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ble_advertising") { + sources = [ "ble_advertising.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.c new file mode 100644 index 0000000..88804bd --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.c @@ -0,0 +1,512 @@ +/** + **************************************************************************************** + * + * @file ble_advertising.c + * + * @brief BLE Advertising Module API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "ble_module_config.h" +#if BLE_ADVERTISING_ENABLE +#include "ble_advertising.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define BLE_ADV_HIGH_DUTY_DIR_DURATION 128 +#define BLE_ADV_INTERVAL_MIN 32 +#define BLE_ADV_DURATION_MAX 18000 + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief BLE Advertising Module environment variable. */ +struct ble_adv_env_t +{ + bool initialized; + bool adv_act_exist; + ble_adv_mode_t cur_adv_mode; + ble_adv_mode_cfg_t adv_mode_cfg; + ble_adv_evt_handler_t evt_handler; + ble_adv_err_handler_t err_handler; + ble_gap_ext_adv_param_t adv_param; + ble_gap_adv_time_param_t adv_time_param; + bool peer_addr_exist; +}; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static struct ble_adv_env_t adv_env; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode) +{ + return (ble_adv_mode_t)((adv_mode + 1) % (BLE_ADV_MODE_SLOW + 2)); +} + +static ble_adv_mode_t adv_mode_next_avail_get(ble_adv_mode_cfg_t *p_adv_mode_cfg, ble_adv_mode_t adv_mode) +{ + switch (adv_mode) + { + case BLE_ADV_MODE_DIRECTED_HIGH_DUTY: + if ((p_adv_mode_cfg->adv_directed_high_duty_enabled) && (!p_adv_mode_cfg->adv_extended_enabled) && + adv_env.peer_addr_exist) + { + return BLE_ADV_MODE_DIRECTED_HIGH_DUTY; + } + + case BLE_ADV_MODE_DIRECTED_LOW_DUTY: + if ((p_adv_mode_cfg->adv_directed_low_duty_enabled && adv_env.peer_addr_exist)) + { + return BLE_ADV_MODE_DIRECTED_LOW_DUTY; + } + + case BLE_ADV_MODE_FAST: + if (p_adv_mode_cfg->adv_fast_enabled) + { + return BLE_ADV_MODE_FAST; + } + + case BLE_ADV_MODE_SLOW: + if (p_adv_mode_cfg->adv_slow_enabled) + { + return BLE_ADV_MODE_SLOW; + } + + default: + return BLE_ADV_MODE_IDLE; + } +} + +static sdk_err_t directed_high_duty_adv_param_set(struct ble_adv_env_t *p_adv_env) +{ + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT | + BLE_GAP_ADV_PROP_DIRECTED_BIT | + BLE_GAP_ADV_PROP_HDC_BIT; + p_adv_env->adv_param.disc_mode = BLE_GAP_DISC_MODE_NON_DISCOVERABLE; + + p_adv_env->adv_time_param.max_adv_evt = 0; + + p_adv_env->adv_time_param.duration = BLE_ADV_HIGH_DUTY_DIR_DURATION; + + return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_GEN_RSLV, &p_adv_env->adv_param); +} + +static sdk_err_t directed_low_duty_adv_param_set(struct ble_adv_env_t *p_adv_env) +{ + if (p_adv_env->adv_mode_cfg.adv_extended_enabled) + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_DIRECTED_BIT | + BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + else + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_DIRECTED_BIT | + BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_directed_low_duty_interval; + p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_directed_low_duty_interval; + p_adv_env->adv_param.disc_mode = BLE_GAP_DISC_MODE_NON_DISCOVERABLE; + + p_adv_env->adv_time_param.max_adv_evt = 0; + p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_directed_low_duty_timeout; + return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_GEN_RSLV, &p_adv_env->adv_param); +} + +static sdk_err_t fast_adv_param_set(struct ble_adv_env_t *p_adv_env) +{ + if (p_adv_env->adv_mode_cfg.adv_extended_enabled) + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + else + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_SCANNABLE_BIT | + BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_fast_interval; + p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_fast_interval; + p_adv_env->adv_param.disc_mode = (p_adv_env->adv_param.filter_pol == BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY)? + BLE_GAP_DISC_MODE_GEN_DISCOVERABLE : BLE_GAP_DISC_MODE_NON_DISCOVERABLE; + + p_adv_env->adv_time_param.max_adv_evt = 0; + p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_fast_timeout; + + return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &p_adv_env->adv_param); +} + +static sdk_err_t slow_adv_param_set(struct ble_adv_env_t *p_adv_env) +{ + if (p_adv_env->adv_mode_cfg.adv_extended_enabled) + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_EXTENDED; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + else + { + p_adv_env->adv_param.type = BLE_GAP_ADV_TYPE_LEGACY; + p_adv_env->adv_param.prop = BLE_GAP_ADV_PROP_SCANNABLE_BIT | + BLE_GAP_ADV_PROP_CONNECTABLE_BIT; + } + p_adv_env->adv_param.prim_cfg.adv_intv_min = p_adv_env->adv_mode_cfg.adv_slow_interval; + p_adv_env->adv_param.prim_cfg.adv_intv_max = p_adv_env->adv_mode_cfg.adv_slow_interval; + p_adv_env->adv_param.disc_mode = (p_adv_env->adv_param.filter_pol == BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY)? + BLE_GAP_DISC_MODE_GEN_DISCOVERABLE : BLE_GAP_DISC_MODE_NON_DISCOVERABLE; + + p_adv_env->adv_time_param.max_adv_evt = 0; + p_adv_env->adv_time_param.duration = p_adv_env->adv_mode_cfg.adv_slow_timeout; + + return ble_gap_ext_adv_param_set(0, BLE_GAP_OWN_ADDR_STATIC, &p_adv_env->adv_param); +} + +static void ble_adv_started(void) +{ + ble_adv_evt_type_t evt = BLE_ADV_EVT_INVALID; + + switch(adv_env.cur_adv_mode) + { + case BLE_ADV_MODE_DIRECTED_HIGH_DUTY: + evt = BLE_ADV_EVT_DIRECTED_HIGH_DUTY; + break; + + case BLE_ADV_MODE_DIRECTED_LOW_DUTY: + evt = BLE_ADV_EVT_DIRECTED_LOW_DUTY; + break; + + case BLE_ADV_MODE_FAST: + evt = BLE_ADV_EVT_FAST; + break; + + case BLE_ADV_MODE_SLOW: + evt = BLE_ADV_EVT_SLOW; + break; + + default: + break; + } + + adv_env.adv_act_exist = true; + + if (adv_env.evt_handler && evt) + { + adv_env.evt_handler(evt); + } +} + +static void ble_advertising_err_on_ble_capture(uint8_t err_code) +{ + if (adv_env.err_handler && err_code) + { + adv_env.err_handler(err_code); + } +} + +static void ble_adv_stopped(uint8_t stop_reason) +{ + sdk_err_t err_code; + + adv_env.adv_act_exist = false; + + if (BLE_GAP_STOPPED_REASON_TIMEOUT == stop_reason) + { + err_code = ble_advertising_start(adv_mode_next_get(adv_env.cur_adv_mode)); + ble_advertising_err_on_ble_capture(err_code); + } + else if (BLE_GAP_STOPPED_REASON_CONN_EST == stop_reason) + { + if (adv_env.adv_mode_cfg.multi_link_enabled && !adv_env.adv_act_exist) + { + ble_advertising_start(BLE_ADV_MODE_DIRECTED_HIGH_DUTY); + } + } +} + +static void ble_adv_disconnected(void) +{ + if (adv_env.adv_mode_cfg.adv_on_disconnect_enabled && !adv_env.adv_act_exist) + { + ble_advertising_start(BLE_ADV_MODE_DIRECTED_HIGH_DUTY); + } +} + +static sdk_err_t adv_init_param_check(ble_adv_init_t *p_adv_init) +{ + if (NULL == p_adv_init) + { + return SDK_ERR_POINTER_NULL; + } + + ble_adv_mode_cfg_t *p_cfg = &p_adv_init->adv_mode_cfg; + + if (p_cfg->adv_directed_low_duty_enabled && + (p_cfg->adv_directed_low_duty_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_directed_low_duty_timeout > BLE_ADV_DURATION_MAX)) + { + return SDK_ERR_INVALID_PARAM; + } + + if (p_cfg->adv_fast_enabled && + (p_cfg->adv_fast_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_fast_interval > BLE_ADV_DURATION_MAX)) + { + return SDK_ERR_INVALID_PARAM; + } + if (p_cfg->adv_slow_enabled && + (p_cfg->adv_slow_interval < BLE_ADV_INTERVAL_MIN || p_cfg->adv_slow_interval > BLE_ADV_DURATION_MAX)) + { + return SDK_ERR_INVALID_PARAM; + } + + return SDK_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +sdk_err_t ble_advertising_init(ble_adv_init_t *p_adv_init) +{ + sdk_err_t error_code; + + if (adv_env.initialized) + { + return SDK_ERR_DISALLOWED; + } + + error_code = adv_init_param_check(p_adv_init); + RET_VERIFY_SUCCESS(error_code); + + adv_env.cur_adv_mode = BLE_ADV_MODE_IDLE; + adv_env.evt_handler = p_adv_init->evt_handler; + adv_env.err_handler = p_adv_init->err_handler; + + memcpy(&adv_env.adv_mode_cfg, &p_adv_init->adv_mode_cfg, sizeof(ble_adv_mode_cfg_t)); + + error_code = ble_gap_adv_data_set(0, + BLE_GAP_ADV_DATA_TYPE_DATA, + p_adv_init->adv_data.p_data, + p_adv_init->adv_data.length); + + if (p_adv_init->srp_data.p_data && p_adv_init->srp_data.length && !p_adv_init->adv_mode_cfg.adv_extended_enabled) + { + error_code = ble_gap_adv_data_set(0, + BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, + p_adv_init->srp_data.p_data, + p_adv_init->srp_data.length); + RET_VERIFY_SUCCESS(error_code); + } + + RET_VERIFY_SUCCESS(error_code); + + adv_env.initialized = true; + + return error_code; +} + +sdk_err_t ble_advertising_start(ble_adv_mode_t adv_mode) +{ + sdk_err_t error_code; + + if (!adv_env.initialized) + { + return SDK_ERR_DISALLOWED; + } + + adv_env.cur_adv_mode = adv_mode; + + //Set general parameters + adv_env.adv_param.disc_mode = BLE_GAP_DISC_MODE_GEN_DISCOVERABLE; + adv_env.adv_param.max_tx_pwr = 0; + adv_env.adv_param.prim_cfg.chnl_map = BLE_GAP_ADV_CHANNEL_37_38_39; + adv_env.adv_param.filter_pol = BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; +// adv_env.adv_param.filter_pol = (adv_env.adv_mode_cfg.ble_adv_whitelist_enabled)? +// BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_WLST : BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; + adv_env.adv_param.prim_cfg.phy = BLE_GAP_PHY_1MBPS_VALUE; + + if (adv_env.adv_mode_cfg.adv_extended_enabled) + { + if (adv_env.adv_mode_cfg.adv_primary_phy) + { + adv_env.adv_param.prim_cfg.phy = adv_env.adv_mode_cfg.adv_primary_phy; + } + + if (adv_env.adv_mode_cfg.adv_secondary_phy) + { + adv_env.adv_param.second_cfg.phy = adv_env.adv_mode_cfg.adv_secondary_phy; + } + else + { + adv_env.adv_param.second_cfg.phy = (ble_gap_le_phy_value_t)BLE_GAP_PHY_LE_1MBPS; + } + } + + if (((adv_env.adv_mode_cfg.adv_directed_high_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_HIGH_DUTY)) || \ + ((adv_env.adv_mode_cfg.adv_directed_low_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_HIGH_DUTY)) || \ + ((adv_env.adv_mode_cfg.adv_directed_low_duty_enabled) && (adv_env.cur_adv_mode == BLE_ADV_MODE_DIRECTED_LOW_DUTY))) + { + if (adv_env.evt_handler) + { + adv_env.evt_handler(BLE_ADV_EVT_DIR_ADDR_REQUEST); + } + } + else + { + memset(&adv_env.adv_param.peer_addr, 0, sizeof(ble_gap_bdaddr_t)); + } + + adv_env.cur_adv_mode = adv_mode_next_avail_get(&adv_env.adv_mode_cfg, adv_mode); + + if (adv_env.adv_mode_cfg.adv_extended_enabled) + { + if (adv_env.adv_mode_cfg.adv_primary_phy) + { + adv_env.adv_param.prim_cfg.phy = adv_env.adv_mode_cfg.adv_primary_phy; + } + + if (adv_env.adv_mode_cfg.adv_secondary_phy) + { + adv_env.adv_param.second_cfg.phy = adv_env.adv_mode_cfg.adv_secondary_phy; + } + } + + switch (adv_env.cur_adv_mode) + { + case BLE_ADV_MODE_DIRECTED_HIGH_DUTY: + error_code = directed_high_duty_adv_param_set(&adv_env); + RET_VERIFY_SUCCESS(error_code); + break; + + case BLE_ADV_MODE_DIRECTED_LOW_DUTY: + error_code = directed_low_duty_adv_param_set(&adv_env); + RET_VERIFY_SUCCESS(error_code); + break; + + case BLE_ADV_MODE_FAST: + error_code = fast_adv_param_set(&adv_env); + RET_VERIFY_SUCCESS(error_code); + break; + + case BLE_ADV_MODE_SLOW: + error_code = slow_adv_param_set(&adv_env); + RET_VERIFY_SUCCESS(error_code); + break; + + default: + break; + } + + return ble_gap_adv_start(0, &adv_env.adv_time_param); +} + +sdk_err_t ble_advertising_adv_data_update(const uint8_t *p_adv_data, uint16_t adv_data_len, const uint8_t *p_srsp_data, uint16_t srsp_data_len) +{ + sdk_err_t error_code; + + if ((p_adv_data == NULL) && (p_srsp_data == NULL) && (adv_data_len <= 0) && (srsp_data_len <= 0)) + { + return SDK_ERR_POINTER_NULL; + } + + if (adv_env.initialized == false) + { + return SDK_ERR_DISALLOWED; + } + else + { + if (p_adv_data && adv_data_len) + { + error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_DATA, p_adv_data, adv_data_len); + RET_VERIFY_SUCCESS(error_code); + } + + if (p_srsp_data && srsp_data_len) + { + error_code = ble_gap_adv_data_set(0, BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, p_srsp_data, srsp_data_len); + RET_VERIFY_SUCCESS(error_code); + } + } + return error_code; +} + +sdk_err_t ble_advertising_dir_addr_fill(ble_gap_bdaddr_t *p_peer_addr) +{ + for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++) + { + if (p_peer_addr->gap_addr.addr[i] != 0) + { + break; + } + return SDK_ERR_INVALID_PARAM; + } + + memcpy(&adv_env.adv_param.peer_addr, p_peer_addr, sizeof(ble_gap_bdaddr_t)); + adv_env.peer_addr_exist = true; + + return SDK_SUCCESS; +} + +void ble_advertising_evt_on_ble_capture(const ble_evt_t *p_evt) +{ + switch (p_evt->evt_id) + { + case BLE_GAPM_EVT_ADV_START: + ble_adv_started(); + break; + + case BLE_GAPM_EVT_ADV_STOP: + ble_adv_stopped(p_evt->evt.gapm_evt.params.adv_stop.reason); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + ble_adv_disconnected(); + break; + + default: + break; + } +} +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.h new file mode 100644 index 0000000..7d10ec3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_advertising/ble_advertising.h @@ -0,0 +1,192 @@ +/** + **************************************************************************************** + * + * @file ble_advertising.h + * + * @brief BLE Advertising Module Header + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __BLE_ADVERTISING_H__ +#define __BLE_ADVERTISING_H__ + +#include "gr_includes.h" + +/** + * @defgroup BLE_ADVERTISING_MAROC Defines + * @{ + */ +#define RET_VERIFY_SUCCESS(RET_CODE) \ +do \ +{ \ + if (RET_CODE != SDK_SUCCESS) \ + { \ + return RET_CODE; \ + } \ +} while(0) +/** @} */ + +/** + * @defgroup BLE_ADVERTISING_ENUM Enumerations + * @{ + */ +/**@brief Advertising mode type. */ +typedef enum +{ + BLE_ADV_MODE_IDLE, /**< No advertising activity. */ + BLE_ADV_MODE_DIRECTED_HIGH_DUTY, /**< High duty directed advertising. */ + BLE_ADV_MODE_DIRECTED_LOW_DUTY, /**< Low duty directed advertising. */ + BLE_ADV_MODE_FAST, /**< Fast advertising mode. */ + BLE_ADV_MODE_SLOW, /**< Slow advertising mode. */ +} ble_adv_mode_t; + +/**@brief Advertising events type. */ +typedef enum +{ + BLE_ADV_EVT_INVALID, /**< Invalid advertising event. */ + BLE_ADV_EVT_DIRECTED_HIGH_DUTY, /**< High duty directed advertising started. */ + BLE_ADV_EVT_DIRECTED_LOW_DUTY, /**< Low duty directed advertising started. */ + BLE_ADV_EVT_FAST, /**< Fast advertising started. */ + BLE_ADV_EVT_SLOW, /**< Slow advertising started. */ + BLE_ADV_EVT_DIR_ADDR_REQUEST, /**< Request peer address for directed advertising. */ +} ble_adv_evt_type_t; +/** @} */ + +/** + * @defgroup BLE_ADVERTISING_TYPEDEF Typedefs + * @{ + */ +/**@brief BLE advertising event handler type. */ +typedef void (*ble_adv_evt_handler_t)(ble_adv_evt_type_t evt); + +/**@brief BLE advertising error handler type. */ +typedef void (*ble_adv_err_handler_t)(uint8_t err_code); +/** @} */ + + +/** + * @defgroup BLE_ADVERTISING_STRUCT Structures + * @{ + */ +/**@brief Data structure. */ +typedef struct +{ + const uint8_t *p_data; /**< Pointer to the data. */ + uint16_t length; /**< Length of the data. */ +} ble_data_t; + +/**@brief Options for the different advertisement modes.*/ +typedef struct +{ + bool multi_link_enabled; /**< Enable or disable multi link. */ + bool adv_on_disconnect_enabled; /**< Enable or disable auto advertising after disconnecting. */ + bool adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. */ + bool adv_directed_low_duty_enabled; /**< Enable or disable low duty direct advertising mode. */ + bool adv_fast_enabled; /**< Enable or disable fast advertising mode. */ + bool adv_slow_enabled; /**< Enable or disable slow advertising mode. */ + bool adv_extended_enabled; /**< Enable or disable extended advertising. */ + uint16_t adv_directed_low_duty_interval; /**< Advertising interval for directed advertising. */ + uint16_t adv_directed_low_duty_timeout; /**< Time-out (number of tries) for direct advertising. */ + uint16_t adv_fast_interval; /**< Advertising interval for fast advertising. */ + uint16_t adv_fast_timeout; /**< Time-out (in units of 10ms) for fast advertising. */ + uint16_t adv_slow_interval; /**< Advertising interval for slow advertising. */ + uint16_t adv_slow_timeout; /**< Time-out (in units of 10ms) for slow advertising. */ + ble_gap_le_phy_value_t adv_secondary_phy; /**< PHY for the secondary (extended) advertising. */ + ble_gap_le_phy_value_t adv_primary_phy; /**< PHY for the primary advertising. */ +} ble_adv_mode_cfg_t; + +/**@brief Avertising initialization. */ +typedef struct +{ + ble_data_t adv_data; /**< Advertising data. */ + ble_data_t srp_data; /**< Scan response data. */ + ble_adv_mode_cfg_t adv_mode_cfg; /**< Advertising mode config. */ + ble_adv_evt_handler_t evt_handler; /**< Advertising event handler. */ + ble_adv_err_handler_t err_handler; /**< Advertising error handler. */ +} ble_adv_init_t; +/** @} */ + +/** + * @defgroup BLE_ADVERTISING_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize BLE advertising module. + * + * @param[in] p_adv_init: Pointer to advertising init params. + * + * @return Result of ble advertising initialization. + ***************************************************************************************** + */ +sdk_err_t ble_advertising_init(ble_adv_init_t *p_adv_init); + +/** + ***************************************************************************************** + * @brief Start advertising. + * + * @param[in] adv_mode: Advertising mode. + * + * @return Result of ble advertising start. + ***************************************************************************************** + */ +sdk_err_t ble_advertising_start(ble_adv_mode_t adv_mode); + +/** + ***************************************************************************************** + * @brief Update the advertising data. + * + * @param[in] p_adv_data: Pointer to the new advertising data, or null if advertising data dosen't need to be updated. + * @param[in] adv_data_len: Length of the new advertising data. + * @param[in] p_srsp_data: Pointer to the new scan response data, or null if advertising data dosen't need to be updated. + * @param[in] srsp_data_len: Length of the new scan response data. + * + * @return Result of adv data update. + ***************************************************************************************** + */ +sdk_err_t ble_advertising_adv_data_update(const uint8_t *p_adv_data, uint16_t adv_data_len, const uint8_t *p_srsp_data, uint16_t srsp_data_len); + +/** + ***************************************************************************************** + * @brief Fill direct advertising peer address. + * + * @param[in] p_peer_addr: Pointer to peer address. + * + * @return Result of address check. + ***************************************************************************************** + */ +sdk_err_t ble_advertising_dir_addr_fill(ble_gap_bdaddr_t *p_peer_addr); + +void ble_advertising_evt_on_ble_capture(const ble_evt_t *p_evt); + +/** @} */ + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/BUILD.gn new file mode 100644 index 0000000..98f8083 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ble_connect") { + sources = [ "ble_connect.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.c new file mode 100644 index 0000000..f37718c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.c @@ -0,0 +1,610 @@ +/** + **************************************************************************************** + * + * @file ble_connect.c + * + * @brief BLE Connect Module API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "ble_module_config.h" +#if BLE_CONNECT_ENABLE +#include "ble_connect.h" +#include "app_timer.h" +#include "utility.h" + +/* + * DEFINES + ***************************************************************************************** + */ +/**@brief Gapm config data. */ +#define BLE_CONN_INTERVAL_MIN 0x0006 /**< Minimum value for the connection interval(7.5 ms). */ +#define BLE_CONN_INTERVAL_MAX 0x0C80 /**< Maximum value for the connection interval(4 s). */ +#define BLE_CONN_LATENCY_MAX 0x01F3 /**< Maximum value for the slave latency(499). */ +#define BLE_CONN_TIMEOUT_MIN 0x000A /**< Minimum value for the supervision timeout(100ms s). */ +#define BLE_CONN_TIMEOUT_MAX 0x0C80 /**< Maximum value for the supervision timeout(32 s). */ +#define BLE_TIMER_TIMEOUT_MAX 4000000 /**< Maximum value for the app_timer timeout(4000 s). */ + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief BLE Connect Module environment variable. */ +typedef struct +{ + uint8_t act_conn_idx; + bool conn_param_manage_enable; + ble_conn_link_info_t link_info[BLE_CONN_LINK_CNT_MAX]; + uint32_t first_conn_param_update_delay; + uint32_t next_conn_param_update_delay; + uint8_t max_conn_param_update_count; + bool disconnect_on_fail; + ble_conn_evt_handler_t evt_handler; + ble_conn_err_handler_t err_handler; +} ble_conn_env_t; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static ble_conn_env_t s_conn_env; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool is_conn_param_ok(ble_gap_conn_param_t const * p_preferred_conn_param, + ble_gap_evt_conn_param_updated_t const * p_actual_conn_param, + uint16_t max_slave_latency_err, + uint16_t max_sup_timeout_err) +{ + uint32_t max_allowed_sl = p_preferred_conn_param->slave_latency + max_slave_latency_err; + uint32_t min_allowed_sl = p_preferred_conn_param->slave_latency + - MIN(max_slave_latency_err, p_preferred_conn_param->slave_latency); + uint32_t max_allowed_to = p_preferred_conn_param->sup_timeout + max_sup_timeout_err; + uint32_t min_allowed_to = p_preferred_conn_param->sup_timeout + - MIN(max_sup_timeout_err, p_preferred_conn_param->sup_timeout); + + // Check if interval is within the acceptable range. + // NOTE: Using max_conn_interval in the received event data because this contains + // the client's connection interval. + if ((p_actual_conn_param->conn_interval < p_preferred_conn_param->interval_min) || + (p_actual_conn_param->conn_interval > p_preferred_conn_param->interval_max)) + { + return false; + } + + // Check if slave latency is within the acceptable deviation. + if ((p_actual_conn_param->slave_latency < min_allowed_sl) + || (p_actual_conn_param->slave_latency > max_allowed_sl)) + { + return false; + } + + // Check if supervision timeout is within the acceptable deviation. + if ((p_actual_conn_param->sup_timeout < min_allowed_to) || (p_actual_conn_param->sup_timeout > max_allowed_to)) + { + return false; + } + + return true; +} + +void ble_connect_err_on_ble_capture(uint8_t err_code) +{ + if (s_conn_env.err_handler && err_code) + { + s_conn_env.err_handler(err_code); + } +} + +static bool send_update_request(uint8_t conn_idx, ble_gap_conn_param_t * p_new_conn_param) +{ + sdk_err_t error_code; + + ble_gap_conn_update_param_t conn_update_param; + memcpy(&conn_update_param, p_new_conn_param, sizeof(ble_gap_conn_param_t)); + conn_update_param.ce_len = 0; + + error_code = ble_gap_conn_param_update(conn_idx, &conn_update_param); + if ((error_code != SDK_SUCCESS) && (error_code != SDK_ERR_BUSY)) // SDK_ERR_BUSY means another conn_param_update request is pending. + { + ble_connect_err_on_ble_capture(error_code); + } + + return (error_code == SDK_SUCCESS); +} + +static void update_timeout_handler(void *p_context) +{ + uint32_t conn_idx = (uint32_t)p_context; + + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state) + { + if (s_conn_env.link_info[conn_idx].param_ok) + { + return; + } + // Check if we have reached the maximum number of attempts + if (s_conn_env.link_info[conn_idx].update_count < s_conn_env.max_conn_param_update_count) + { + bool update_sent = send_update_request(conn_idx, &s_conn_env.link_info[conn_idx].pref_conn_param); + if (update_sent) + { + s_conn_env.link_info[conn_idx].update_count++; + } + } + else + { + s_conn_env.link_info[conn_idx].update_count = 0; + + // Negotiation failed, disconnect automatically if this has been configured + if (s_conn_env.disconnect_on_fail) + { + sdk_err_t error_code; + + error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE); + + ble_connect_err_on_ble_capture(error_code); + } + + // Notify the application that the procedure has failed + if (s_conn_env.evt_handler) + { + ble_conn_evt_t conn_evt; + + conn_evt.evt_type = BLE_CONN_EVT_PARAM_NEGO_FAILED; + conn_evt.conn_idx = conn_idx; + + s_conn_env.evt_handler(&conn_evt); + } + } + } +} + +static void conn_param_negotiation(uint8_t conn_idx) +{ + // Start negotiation if the received connection parameters are not acceptable + if (!s_conn_env.link_info[conn_idx].param_ok) + { + sdk_err_t error_code; + uint32_t timeout_ticks; + + if (0 == s_conn_env.link_info[conn_idx].update_count) + { + // First connection parameter update + timeout_ticks = s_conn_env.first_conn_param_update_delay; + } + else + { + timeout_ticks = s_conn_env.next_conn_param_update_delay; + } + + app_timer_stop(s_conn_env.link_info[conn_idx].timer_id); + error_code = app_timer_start(s_conn_env.link_info[conn_idx].timer_id, timeout_ticks, (void *)(uint32_t)conn_idx); + ble_connect_err_on_ble_capture(error_code); + } + else + { + s_conn_env.link_info[conn_idx].update_count = 0; + + // Notify the application that the procedure has succeeded + if (s_conn_env.evt_handler != NULL) + { + ble_conn_evt_t evt; + + evt.evt_type = BLE_CONN_EVT_PARAM_NEGO_SUCCEEDED; + evt.conn_idx = conn_idx; + s_conn_env.evt_handler(&evt); + } + } +} + +static void ble_conn_established(uint8_t conn_idx, const ble_gap_evt_connected_t *p_conn_param) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return; + } + + s_conn_env.link_info[conn_idx].conn_state = BLE_CONN_STATE_CONNECTED; + s_conn_env.link_info[conn_idx].local_role = p_conn_param->ll_role; + s_conn_env.link_info[conn_idx].conn_param.conn_interval = p_conn_param->conn_interval; + s_conn_env.link_info[conn_idx].conn_param.slave_latency = p_conn_param->slave_latency; + s_conn_env.link_info[conn_idx].conn_param.sup_timeout = p_conn_param->sup_timeout; + s_conn_env.link_info[conn_idx].peer_addr.addr_type = p_conn_param->peer_addr_type; + memcpy(&s_conn_env.link_info[conn_idx].peer_addr.gap_addr, &p_conn_param->peer_addr, sizeof(ble_gap_addr_t)); + + + if (BLE_GAP_LL_ROLE_SLAVE == s_conn_env.link_info[conn_idx].local_role) + { + ble_gap_evt_conn_param_updated_t conn_updated_param; + memcpy(&conn_updated_param, &p_conn_param->conn_interval, sizeof(conn_updated_param)); + + s_conn_env.link_info[conn_idx].param_ok = is_conn_param_ok(&s_conn_env.link_info[conn_idx].pref_conn_param, + &conn_updated_param, + BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION, + BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION); + + if (s_conn_env.conn_param_manage_enable) + { + conn_param_negotiation(conn_idx); + } + else if (!s_conn_env.link_info[conn_idx].param_ok && s_conn_env.disconnect_on_fail) + { + sdk_err_t error_code; + + error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE); + ble_connect_err_on_ble_capture(error_code); + } + } + if (s_conn_env.evt_handler) + { + ble_conn_evt_t conn_evt; + + conn_evt.evt_type = BLE_CONN_EVT_CONNECTED; + conn_evt.conn_idx = conn_idx; + conn_evt.param.p_link_info = &s_conn_env.link_info[conn_idx]; + + s_conn_env.evt_handler(&conn_evt); + } +} + +static void ble_conn_terminated(uint8_t conn_idx, uint8_t reason) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return; + } + + app_timer_id_t timer_id_temp = s_conn_env.link_info[conn_idx].timer_id; + ble_gap_conn_param_t pref_conn_param_temp = s_conn_env.link_info[conn_idx].pref_conn_param; + + memset(&s_conn_env.link_info[conn_idx], 0, sizeof(ble_conn_link_info_t)); + s_conn_env.link_info[conn_idx].timer_id = timer_id_temp; + s_conn_env.link_info[conn_idx].conn_state = BLE_CONN_STATE_DISCONNECTED; + memcpy(&s_conn_env.link_info[conn_idx].pref_conn_param, &pref_conn_param_temp, sizeof(ble_gap_conn_param_t)); + + app_timer_stop(s_conn_env.link_info[conn_idx].timer_id); + + if (conn_idx == s_conn_env.act_conn_idx) + { + s_conn_env.act_conn_idx = BLE_GAP_INVALID_CONN_INDEX; + } + + if (s_conn_env.evt_handler) + { + ble_conn_evt_t conn_evt; + + conn_evt.evt_type = BLE_CONN_EVT_DISCONNECTED; + conn_evt.conn_idx = conn_idx; + conn_evt.param.disconn_reason = reason; + + s_conn_env.evt_handler(&conn_evt); + } +} + +static void ble_conn_param_updated(uint8_t conn_idx, const ble_gap_evt_conn_param_updated_t *p_conn_param_updated_info) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return; + } + + memcpy(&s_conn_env.link_info[conn_idx].conn_param, p_conn_param_updated_info, sizeof(ble_conn_param_t)); + + if (BLE_GAP_LL_ROLE_SLAVE == s_conn_env.link_info[conn_idx].local_role) + { + s_conn_env.link_info[conn_idx].param_ok = is_conn_param_ok(&s_conn_env.link_info[conn_idx].pref_conn_param, + p_conn_param_updated_info, + BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION, + BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION); + if (s_conn_env.conn_param_manage_enable) + { + conn_param_negotiation(conn_idx); + } + else if (!s_conn_env.link_info[conn_idx].param_ok && s_conn_env.disconnect_on_fail) + { + sdk_err_t error_code; + + error_code = ble_gap_disconnect_with_reason(conn_idx, BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE); + ble_connect_err_on_ble_capture(error_code); + } + } + + // Interval = 0x4000 means thats connect param update request is rejected by master. + if (s_conn_env.evt_handler && p_conn_param_updated_info->conn_interval != 0x4000) + { + ble_conn_evt_t conn_evt; + + conn_evt.evt_type = BLE_CONN_EVT_PATAM_UPDATED; + conn_evt.conn_idx = conn_idx; + conn_evt.param.p_update_param = (ble_conn_param_t *)p_conn_param_updated_info; + + s_conn_env.evt_handler(&conn_evt); + } +} + +static void ble_conn_link_encrypted(uint8_t conn_idx, uint8_t enc_ind) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return; + } + + s_conn_env.link_info[conn_idx].is_encrypt = true; +} + +static sdk_err_t conn_init_param_check(ble_conn_init_t *p_conn_init) +{ + if (NULL == p_conn_init) + { + return SDK_ERR_POINTER_NULL; + } + if (NULL != p_conn_init->p_conn_param) + { + ble_gap_conn_param_t *p_conn_param = p_conn_init->p_conn_param; + if (p_conn_param->interval_max > BLE_CONN_INTERVAL_MAX || p_conn_param->interval_min < BLE_CONN_INTERVAL_MIN || + p_conn_param->interval_max < p_conn_param->interval_min || p_conn_param->slave_latency > BLE_CONN_LATENCY_MAX || + p_conn_param->sup_timeout > BLE_CONN_TIMEOUT_MAX || p_conn_param->sup_timeout < BLE_CONN_TIMEOUT_MIN) + { + return SDK_ERR_INVALID_PARAM; + } + } + if (p_conn_init->first_conn_param_update_delay > BLE_TIMER_TIMEOUT_MAX || + p_conn_init->next_conn_param_update_delay > BLE_TIMER_TIMEOUT_MAX) + { + return SDK_ERR_INVALID_PARAM; + } + return SDK_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +sdk_err_t ble_connect_init(ble_conn_init_t *p_conn_init) +{ + sdk_err_t error_code; + + error_code = conn_init_param_check(p_conn_init); + RET_VERIFY_SUCCESS(error_code); + + memset(&s_conn_env, 0, sizeof(s_conn_env)); + + s_conn_env.act_conn_idx = BLE_GAP_INVALID_CONN_INDEX; + s_conn_env.conn_param_manage_enable = p_conn_init->conn_param_manage_enable; + if (s_conn_env.conn_param_manage_enable) + { + if (p_conn_init->p_conn_param != NULL) + { + // Set the connection param in stack. + error_code = ble_gap_ppcp_set(p_conn_init->p_conn_param); + RET_VERIFY_SUCCESS(error_code); + } + else + { + // Get the (default) connection param from stack. + error_code = ble_gap_ppcp_get(p_conn_init->p_conn_param); + RET_VERIFY_SUCCESS(error_code); + } + s_conn_env.first_conn_param_update_delay = p_conn_init->first_conn_param_update_delay; + s_conn_env.next_conn_param_update_delay = p_conn_init->next_conn_param_update_delay; + s_conn_env.max_conn_param_update_count = p_conn_init->max_conn_param_update_count; + + for (uint32_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++) + { + memcpy(&s_conn_env.link_info[i].pref_conn_param, p_conn_init->p_conn_param, sizeof(ble_gap_conn_param_t)); + + error_code = app_timer_create(&s_conn_env.link_info[i].timer_id, ATIMER_ONE_SHOT, + update_timeout_handler); + RET_VERIFY_SUCCESS(error_code); + } + } + + s_conn_env.disconnect_on_fail = p_conn_init->disconnect_on_fail; + s_conn_env.evt_handler = p_conn_init->evt_handler; + s_conn_env.err_handler = p_conn_init->err_handler; + + return SDK_SUCCESS; +} + +uint8_t ble_connect_established_cnt_get(void) +{ + uint8_t count = 0; + + for (uint8_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++) + { + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state) + { + count++; + } + } + + return count; +} + +bool ble_connect_is_connected(uint8_t conn_idx) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return false; + } + + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state) + { + return true; + } + + return false; +} + +sdk_err_t ble_connect_link_info_get(uint8_t conn_idx, ble_conn_link_info_t *p_link_info) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX || NULL == p_link_info) + { + return SDK_ERR_INVALID_PARAM; + } + + memcpy(p_link_info, &s_conn_env.link_info[conn_idx], sizeof(ble_conn_link_info_t)); + + return SDK_SUCCESS; +} + +sdk_err_t ble_connect_active_link_set(uint8_t conn_idx) +{ + if (conn_idx >= BLE_CONN_LINK_CNT_MAX || BLE_CONN_STATE_DISCONNECTED == s_conn_env.link_info[conn_idx].conn_state) + { + return SDK_ERR_INVALID_CONN_IDX; + } + + s_conn_env.act_conn_idx = conn_idx; + + return SDK_SUCCESS; +} + +uint8_t ble_connect_active_link_get(void) +{ + return s_conn_env.act_conn_idx; +} + +sdk_err_t ble_connect_all_to_do(ble_conn_all_link_exec_handler_t exec_handler) +{ + if (NULL == exec_handler) + { + return SDK_ERR_POINTER_NULL; + } + + for (uint8_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++) + { + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state) + { + exec_handler(i); + } + } + + return SDK_SUCCESS; +} + +sdk_err_t ble_connect_next_link_idx_get(uint8_t cur_conn_idx, uint8_t *next_conn_idx) +{ + if (cur_conn_idx >= BLE_CONN_LINK_CNT_MAX || NULL == next_conn_idx || + BLE_CONN_STATE_DISCONNECTED == s_conn_env.link_info[cur_conn_idx].conn_state) + { + *next_conn_idx = BLE_GAP_INVALID_CONN_INDEX; + return SDK_ERR_INVALID_CONN_IDX; + } + + for (uint8_t i = cur_conn_idx + 1; ; i++) + { + if (i == BLE_CONN_LINK_CNT_MAX) + { + i = 0; + } + + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[i].conn_state) + { + *next_conn_idx = i; + return SDK_SUCCESS; + } + } +} + +sdk_err_t ble_connect_param_update_stop(void) +{ + for (uint32_t i = 0; i < BLE_CONN_LINK_CNT_MAX; i++) + { + app_timer_stop(s_conn_env.link_info[i].timer_id); + } + return SDK_SUCCESS; +} + +sdk_err_t ble_connect_param_change(uint8_t conn_idx, ble_gap_conn_param_t *p_new_conn_param) +{ + sdk_err_t error_code = SDK_ERR_INVALID_CONN_IDX; + + if (conn_idx >= BLE_CONN_LINK_CNT_MAX) + { + return SDK_ERR_INVALID_CONN_IDX; + } + + if (p_new_conn_param == NULL) + { + p_new_conn_param = &s_conn_env.link_info[conn_idx].pref_conn_param; + } + + if (BLE_CONN_STATE_CONNECTED == s_conn_env.link_info[conn_idx].conn_state) + { + ble_gap_conn_update_param_t conn_update_param; + memcpy(&conn_update_param, p_new_conn_param, sizeof(ble_gap_conn_param_t)); + conn_update_param.ce_len = 0; + // Send request to master. + error_code = ble_gap_conn_param_update(conn_idx, &conn_update_param); + if (error_code == SDK_SUCCESS) + { + s_conn_env.link_info[conn_idx].param_ok = false; + s_conn_env.link_info[conn_idx].update_count = 1; + s_conn_env.link_info[conn_idx].pref_conn_param = *p_new_conn_param; + } + } + + return error_code; +} + +void ble_connect_evt_on_ble_capture(const ble_evt_t *p_evt) +{ + switch (p_evt->evt_id) + { + case BLE_GAPC_EVT_CONNECTED: + ble_conn_established(p_evt->evt.gapc_evt.index, &(p_evt->evt.gapc_evt.params.connected)); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + ble_conn_terminated(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; + + case BLE_GAPC_EVT_CONN_PARAM_UPDATED: + ble_conn_param_updated(p_evt->evt.gapc_evt.index, &(p_evt->evt.gapc_evt.params.conn_param_updated)); + break; + + case BLE_SEC_EVT_LINK_ENCRYPTED: + ble_conn_link_encrypted(p_evt->evt.gapc_evt.index, p_evt->evt_status); + break; + } +} + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.h new file mode 100644 index 0000000..472bace --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_connect/ble_connect.h @@ -0,0 +1,289 @@ +/** + **************************************************************************************** + * + * @file ble_connect.h + * + * @brief BLE Connect Module Header + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __BLE_CONNECT_H__ +#define __BLE_CONNECT_H__ + +#include "gr_includes.h" +#include "app_timer.h" + + +/** + * @defgroup BLE_CONNECT_MAROC Defines + * @{ + */ +#define RET_VERIFY_SUCCESS(RET_CODE) \ +do \ +{ \ + if (RET_CODE != SDK_SUCCESS) \ + { \ + return RET_CODE; \ + } \ +} while(0) + +#define BLE_CONN_PARAM_MAX_SLAVE_LATENCY_DEVIATION 10 /**< The largest acceptable deviation in slave latency. */ +#define BLE_CONN_PARAM_MAX_SUPERVISION_TIMEOUT_DEVIATION 100 /**< The largest acceptable deviation (in 10 ms units) in supervision timeout. */ + + +#ifdef CFG_MAX_CONNECTIONS + #define BLE_CONN_LINK_CNT_MAX CFG_MAX_CONNECTIONS +#else + #define BLE_CONN_LINK_CNT_MAX 10 +#endif + +/** @} */ + +/** + * @defgroup BLE_CONNECT_ENUM Enumerations + * @{ + */ +/**@brief BLE connect state. */ +typedef enum +{ + BLE_CONN_STATE_DISCONNECTED, /**< BLE link disconnected state. */ + BLE_CONN_STATE_CONNECTED, /**< BLE link connected state. */ +} ble_conn_state_t; + +/**@brief BLE connect events type. */ +typedef enum +{ + BLE_CONN_EVT_INVALID, /**< Invalid connect event. */ + BLE_CONN_EVT_CONNECTED, /**< Connected event. */ + BLE_CONN_EVT_DISCONNECTED, /**< Disconnected event. */ + BLE_CONN_EVT_PATAM_UPDATED, /**< Connect param updated event. */ + BLE_CONN_EVT_PPCP_GET_FAIL, /**< PPCP get fail. */ + BLE_CONN_EVT_PARAM_NEGO_FAILED, /**< Negotiation procedure failed. */ + BLE_CONN_EVT_PARAM_NEGO_SUCCEEDED /**< Negotiation procedure succeeded. */ +} ble_conn_evt_type_t; +/** @} */ + +/** + * @defgroup BLE_CONNECT_TYPEDEF Typedefs + * @{ + */ +/**@brief BLE connect role of LL layer. */ +typedef ble_gap_ll_role_type_t ble_conn_role_t; + +/**@brief BLE connect parameter. */ +typedef ble_gap_evt_conn_param_updated_t ble_conn_param_t; + +/**@brief All connected link need to execute handler type. */ +typedef void (*ble_conn_all_link_exec_handler_t)(uint8_t conn_idx); + +/**@brief BLE connect error handler type. */ +typedef void (*ble_conn_err_handler_t)(uint8_t err_code); +/** @} */ + +/** + * @defgroup BLE_CONNECT_STRUCT Structures + * @{ + */ +/**@brief BLE connect link information. */ +typedef struct +{ + bool is_encrypt; /**< Is encrypt or not. */ + ble_conn_state_t conn_state; /**< BLE connect state. */ + ble_conn_role_t local_role; /**< Local BLE LL role. */ + ble_gap_bdaddr_t peer_addr; /**< Peer address. */ + ble_conn_param_t conn_param; /**< BLE connect parameters. */ + ble_gap_conn_param_t pref_conn_param; /**< BLE prefer connect parameters. */ + uint8_t param_ok; /**< Whether the current connection parameters on this link are acceptable. */ + uint8_t update_count; /**< The number of times the connection parameters have been attempted + negotiated on this link. */ + app_timer_id_t timer_id; /**< Timer id of connect parameter update. */ +} ble_conn_link_info_t; + +/**@brief BLE connect event information. */ +typedef struct +{ + ble_conn_evt_type_t evt_type; + uint8_t conn_idx; + union + { + ble_conn_link_info_t *p_link_info; + uint8_t disconn_reason; + ble_conn_param_t *p_update_param; + } param; +}ble_conn_evt_t; +/** @} */ + +/** + * @defgroup BLE_CONNECT_TYPEDEF Typedefs + * @{ + */ +/**@brief BLE connect event handler type. */ +typedef void (*ble_conn_evt_handler_t)(ble_conn_evt_t *p_evt); +/** @} */ + +/** + * @defgroup BLE_CONNECT_STRUCT Structures + * @{ + */ +/**@brief BLE connect initialization. */ +typedef struct +{ + bool conn_param_manage_enable; /**< Enable or disable connect param auto update. */ + ble_gap_conn_param_t *p_conn_param; /**< Pointer to the connection parameters desired by the application.It will be fetched from host if set to NULL. */ + uint32_t first_conn_param_update_delay; /**< Time from connect to first time ble_gap_conn_param_update is called (in 1 ms). */ + uint32_t next_conn_param_update_delay; /**< Time between each call to ble_gap_conn_param_update after the first (in 1 ms). */ + uint8_t max_conn_param_update_count; /**< Number of attempts before giving up the negotiation. */ + bool disconnect_on_fail; /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection. */ + ble_conn_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Connection. */ + ble_conn_err_handler_t err_handler; /**< Function to be called in case of an error. */ +} ble_conn_init_t; +/** @} */ + + +/** + * @defgroup BLE_CONNECT_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize BLE connect module. + * + * @param[in] p_conn_init: Pointer to initialization params. + * + * @return Result of ble connect initialization. + ***************************************************************************************** + */ +sdk_err_t ble_connect_init(ble_conn_init_t *p_conn_init); + +/** + ***************************************************************************************** + * @brief Get count of established BLE connect link. + * + * @return Count of established ble connect link. + ***************************************************************************************** + */ +uint8_t ble_connect_established_cnt_get(void); + +/** + ***************************************************************************************** + * @brief Check BLE connect link is connected or not. + * + * @param[in] conn_idx: Index of connection. + * + * @return Result of check. + ***************************************************************************************** + */ +bool ble_connect_is_connected(uint8_t conn_idx); + +/** + ***************************************************************************************** + * @brief Get connect link information. + * + * @param[in] conn_idx: Index of connection. + * @param[in\out] p_link_info: Buffer for save information get. + * + * @return Result of get. + ***************************************************************************************** + */ +sdk_err_t ble_connect_link_info_get(uint8_t conn_idx, ble_conn_link_info_t *p_link_info); + +/** + ***************************************************************************************** + * @brief Set active connect link. + * + * @param[in] conn_idx: Index of connection. + * + * @return Result of set. + ***************************************************************************************** + */ +sdk_err_t ble_connect_active_link_set(uint8_t conn_idx); + +/** + ***************************************************************************************** + * @brief Set active connect link. + * + * @param[in] conn_idx: Index of connection. + * + * @return Result of get. + ***************************************************************************************** + */ +uint8_t ble_connect_active_link_get(void); + +/** + ***************************************************************************************** + * @brief All connected link need to execute handler. + * + * @param[in] exec_handler: Execute handler. + * + * @return Result of check. + ***************************************************************************************** + */ +sdk_err_t ble_connect_all_to_do(ble_conn_all_link_exec_handler_t exec_handler); + +/** + ***************************************************************************************** + * @brief Get next connected link index. + * + * @param[in] cur_conn_idx: Index of cur_connection. + * @param[in] next_conn_idx: Pointer to next connected link index. + * + * @return Result of get.. + ***************************************************************************************** + */ +sdk_err_t ble_connect_next_link_idx_get(uint8_t cur_conn_idx, uint8_t *next_conn_idx); + + /** + ***************************************************************************************** + * @brief Function for stopping the Connection Parameters manage module. + + * @return Result of stopping the Connection Parameters module. + ***************************************************************************************** + */ +sdk_err_t ble_connect_param_update_stop(void); + +/** + ***************************************************************************************** + * @brief Initialize parameter update request. + * + * @param[in] conn_idx: Index of connection. + * + * @param[in] p_new_param: Pointer to the new connect parameter. + * + * @return Result of ble advertising initialization. + ***************************************************************************************** + */ +sdk_err_t ble_connect_param_change(uint8_t conn_idx, ble_gap_conn_param_t *p_new_param); + +void ble_connect_evt_on_ble_capture(const ble_evt_t *p_evt); + +/** @} */ + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/BUILD.gn new file mode 100644 index 0000000..fd290d5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ble_gatt_service") { + sources = [ "ble_gatt_service.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.c new file mode 100644 index 0000000..83d92f6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.c @@ -0,0 +1,675 @@ +/** + **************************************************************************************** + * + * @file ble_gatt_service.c + * + * @brief BLE GATT Service Module API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "ble_gatt_service.h" +#include "ble_prf_types.h" +#include "custom_config.h" + + +/* + * DEFINES + ***************************************************************************************** + */ +#define BLE_GATTS_ATT_ELEMENT_SIZE sizeof(attm_desc_128_t) +#define BLE_GATTS_HADNLE_PTR_SIZE sizeof(uint16_t *) +#define BLE_GATTS_INVALID_SERV_IDX 0xff + +#define BLE_GATT_REALLOC_VERIFY(ptr, offset, size) \ +do \ +{ \ + if (NULL == ptr) \ + { \ + return SDK_ERR_NO_RESOURCES; \ + } \ + memset(&ptr[offset], 0, size); \ +} while(0); + +#define BLE_GATT_MALLOC_VERIFY(ptr, size) \ +do \ +{ \ + if (NULL == ptr) \ + { \ + return SDK_ERR_NO_RESOURCES; \ + } \ + memset(ptr, 0, size); \ +} while(0); + +/* + * STRUCTURES + ***************************************************************************************** + */ +typedef struct +{ + uint16_t start_hdl; /**< Start handle. */ + uint16_t end_hdl; /**< End handle. */ + ble_gatts_handler_t handlers; /**< Att handlers. */ +} ble_gatts_serv_info_t; + +typedef struct +{ + + uint8_t inc_serv_num; /**< Number of include services. */ + uint16_t **p_inc_hdl_tab; /**< Pointer to include service handle pointer table. */ + uint16_t **p_att_hdl_tab; /**< Pointer to attributehandle pointer table. */ + attm_desc_128_t *p_db_tab; /**< Pointer to db table. */ + ble_att_uuid_t uuid; /**< Service UUID. */ + uint8_t att_num; /**< Number of attributes. */ +} ble_gatts_db_info_t; + +typedef struct +{ + uint8_t serv_num; + uint16_t start_hdl; + ble_gatts_serv_info_t *p_serv_info; +} ble_gatts_serv_env_t; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static ble_err_t ble_gatts_serv_load(void); +static void ble_gatts_read_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_read_req); +static void ble_gatts_write_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_write_req); +static void ble_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_write_req); +static void ble_gatts_ntf_ind_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); +static void ble_gatts_cccd_recovery_cb(uint8_t conidx, uint16_t handle, uint16_t cccd_val); +static void ble_gatts_on_connect_cb(uint8_t conn_idx); +static void ble_gatts_on_disconnect_cb(uint8_t conn_idx, uint8_t reason); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static ble_prf_manager_cbs_t s_mgr_cbs = +{ + ble_gatts_serv_load, + ble_gatts_on_connect_cb, + ble_gatts_on_disconnect_cb +}; + +static gatts_prf_cbs_t s_gatts_cbs = +{ + ble_gatts_read_cb, + ble_gatts_write_cb, + ble_gatts_prep_write_cb, + ble_gatts_ntf_ind_cplt_cb, + ble_gatts_cccd_recovery_cb +}; + +static const prf_server_info_t s_prf_info = +{ + .max_connection_nb = CFG_MAX_CONNECTIONS, + .manager_cbs = &s_mgr_cbs, + .gatts_prf_cbs = &s_gatts_cbs +}; + +static uint8_t s_create_serv_idx; +static uint8_t s_load_serv_idx; +static ble_gatts_db_info_t *s_p_db_info_tab; +static ble_gatts_serv_env_t s_gatts_serv_env; + + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint8_t ble_gatts_serv_indx_find(uint16_t handle) +{ + for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++) + { + if (handle >= s_gatts_serv_env.p_serv_info[i].start_hdl && + handle <= s_gatts_serv_env.p_serv_info[i].end_hdl) + { + return i; + } + } + + return BLE_GATTS_INVALID_SERV_IDX; +} + +extern uint8_t fpb_save_state(void); +extern void fpb_load_state(uint8_t state); + +static ble_err_t ble_gatts_serv_load(void) +{ + fpb_load_state(0); + sdk_err_t error_code; + gatts_create_db_t gatts_db; + uint8_t uuid[] = BLE_ATT_16_TO_128_ARRAY(s_p_db_info_tab[s_load_serv_idx].uuid.uuid.uuid16); + + + memset(&gatts_db, 0, sizeof(gatts_create_db_t)); + + s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl = PRF_INVALID_HANDLE; + + if (s_p_db_info_tab[s_load_serv_idx].uuid.type == BLE_ATT_UUID_128) + { + gatts_db.uuid = s_p_db_info_tab[s_load_serv_idx].uuid.uuid.uuid128; + gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); + } + else + { + gatts_db.uuid = uuid; + gatts_db.srvc_perm = 0; + } + + gatts_db.shdl = &s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl; + gatts_db.attr_tab_cfg = NULL; + gatts_db.max_nb_attr = s_p_db_info_tab[s_load_serv_idx].att_num; + gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; + gatts_db.attr_tab.attr_tab_128 = s_p_db_info_tab[s_load_serv_idx].p_db_tab; + gatts_db.inc_srvc_num = s_p_db_info_tab[s_load_serv_idx].inc_serv_num; + + for (uint8_t i = 0; i < gatts_db.inc_srvc_num; i++) + { + gatts_db.inc_srvc_handle[i] = s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab[i]; + } + + error_code = ble_gatts_srvc_db_create(&gatts_db); + + if (SDK_SUCCESS == error_code) + { + s_gatts_serv_env.p_serv_info[s_load_serv_idx].end_hdl = s_gatts_serv_env.p_serv_info[s_load_serv_idx].start_hdl + \ + s_p_db_info_tab[s_load_serv_idx].att_num - 1; + } + + for (uint8_t i = 0; i < gatts_db.max_nb_attr; i++) + { + *(s_p_db_info_tab[s_load_serv_idx].p_att_hdl_tab[i]) = *(gatts_db.shdl) + i; + } + + if (s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab) + { + BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_inc_hdl_tab); + } + + + BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_att_hdl_tab); + BLE_GATT_SERV_FREE(s_p_db_info_tab[s_load_serv_idx].p_db_tab); + + + s_load_serv_idx++; + + if (s_load_serv_idx == s_gatts_serv_env.serv_num) + { + BLE_GATT_SERV_FREE(s_p_db_info_tab); + } + + fpb_save_state(); + return error_code; +} + +static void ble_gatts_read_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_read_req) +{ + uint8_t sevr_idx = ble_gatts_serv_indx_find(p_read_req->handle); + + if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX && + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.read_req_handler) + { + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.read_req_handler(conn_idx, p_read_req->handle); + } +} + +static void ble_gatts_write_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_write_req) +{ + uint8_t sevr_idx = ble_gatts_serv_indx_find(p_write_req->handle); + + gatts_write_cfm_t cfm; + + cfm.handle = p_write_req->handle; + cfm.status = sevr_idx == BLE_GATTS_INVALID_SERV_IDX ? BLE_ATT_ERR_INVALID_HANDLE : BLE_SUCCESS; + + ble_gatts_write_cfm(conn_idx, &cfm); + + if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX && + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.write_req_handler) + { + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.write_req_handler(conn_idx, + p_write_req->handle, + p_write_req->offset, + p_write_req->value, + p_write_req->length); + } +} + +static void ble_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_write_req) +{ + uint8_t sevr_idx = ble_gatts_serv_indx_find(p_prep_write_req->handle); + + gatts_prep_write_cfm_t cfm; + + cfm.handle = p_prep_write_req->handle; + cfm.status = sevr_idx == BLE_GATTS_INVALID_SERV_IDX ? BLE_ATT_ERR_INVALID_HANDLE : BLE_SUCCESS; + + ble_gatts_prepare_write_cfm(conn_idx, &cfm); +} + +static void ble_gatts_ntf_ind_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +{ + uint8_t sevr_idx = ble_gatts_serv_indx_find(p_ntf_ind->handle); + uint16_t h_offset = p_ntf_ind->handle - s_gatts_serv_env.start_hdl; + + if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX && + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.ntf_ind_handler) + { + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.ntf_ind_handler(conn_idx, status, p_ntf_ind->type, h_offset); + } +} + +static void ble_gatts_cccd_recovery_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val) +{ + uint8_t sevr_idx = ble_gatts_serv_indx_find(handle); + + if (sevr_idx != BLE_GATTS_INVALID_SERV_IDX && + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.cccd_recovery_handler) + { + s_gatts_serv_env.p_serv_info[sevr_idx].handlers.cccd_recovery_handler(conn_idx, handle, cccd_val); + } +} + +static void ble_gatts_on_connect_cb(uint8_t conn_idx) +{ + fpb_load_state(0); + + for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++) + { + if (s_gatts_serv_env.p_serv_info[i].handlers.on_conn_handler) + { + s_gatts_serv_env.p_serv_info[i].handlers.on_conn_handler(conn_idx); + } + } + fpb_save_state(); +} + +static void ble_gatts_on_disconnect_cb(uint8_t conn_idx, uint8_t reason) +{ + for (uint8_t i = 0; i < s_gatts_serv_env.serv_num; i++) + { + if (s_gatts_serv_env.p_serv_info[i].handlers.on_disconn_handler) + { + s_gatts_serv_env.p_serv_info[i].handlers.on_disconn_handler(conn_idx, reason); + } + } +} + +static void ble_gatts_att_perm_set(uint16_t *p_att_perm, uint16_t prop, ble_att_perm_t perm) +{ + if (NULL == p_att_perm || 0 == prop) + { + return; + } + + *p_att_perm = 0; + + if (prop & BLE_ATT_PROP_BROADCAST) + { + *p_att_perm |= (BROADCAST << 8); + } + + if (prop & BLE_ATT_PROP_READ) + { + *p_att_perm |= (READ << 8 | (((perm) & SEC_LEVEL_MASK) << READ_POS)); + } + + if (prop & BLE_ATT_PROP_WRITE_NO_RESP) + { + *p_att_perm |= (WRITE_CMD << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS)); + } + + if (prop & BLE_ATT_PROP_WRITE) + { + *p_att_perm |= (WRITE_REQ << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS)); + } + + if (prop & BLE_ATT_PROP_NOTIFY) + { + *p_att_perm |= (NOTIFY << 8 | (((perm) & SEC_LEVEL_MASK) << NOTIFY_POS)); + } + + if (prop & BLE_ATT_PROP_INDICATE) + { + *p_att_perm |= (INDICATE << 8 | (((perm) & SEC_LEVEL_MASK) << INDICATE_POS)); + } + + if (prop & BLE_ATT_PROP_WRITE_SIGNED) + { + *p_att_perm |= (WRITE_SIGNED << 8 | (((perm) & SEC_LEVEL_MASK) << WRITE_POS)); + } + + if (prop & BLE_ATT_PROP_EXTENDED) + { + *p_att_perm |= (EXT_PROP << 8); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +sdk_err_t ble_gatts_serv_add(bool is_primary, const ble_att_uuid_t *p_uuid, uint16_t *p_handle) +{ + size_t re_size; + void *mal_ptr; + uint8_t att_idx; + + if (NULL == p_uuid) + { + return SDK_ERR_POINTER_NULL; + } + + // re-malloc s_p_db_info_tab + mal_ptr = s_p_db_info_tab; + re_size = sizeof(ble_gatts_db_info_t) * (s_create_serv_idx + 1); + + s_p_db_info_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab, s_create_serv_idx, sizeof(ble_gatts_db_info_t)); + + // re-malloc s_gatts_serv_env.p_serv_info + mal_ptr = s_gatts_serv_env.p_serv_info; + re_size = sizeof(ble_gatts_serv_info_t) * (s_gatts_serv_env.serv_num + 1); + + s_gatts_serv_env.p_serv_info = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_gatts_serv_env.p_serv_info, s_gatts_serv_env.serv_num, sizeof(ble_gatts_serv_info_t)); + + // malloc att handle ptr table + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_MALLOC(BLE_GATTS_HADNLE_PTR_SIZE); + BLE_GATT_MALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, BLE_GATTS_HADNLE_PTR_SIZE); + + att_idx = s_p_db_info_tab[s_create_serv_idx].att_num; + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_handle; + + // re-malloc att table + s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_MALLOC(BLE_GATTS_ATT_ELEMENT_SIZE); + BLE_GATT_MALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, BLE_GATTS_ATT_ELEMENT_SIZE); + + // record service uuid + memcpy(&s_p_db_info_tab[s_create_serv_idx].uuid, p_uuid, sizeof(ble_att_uuid_t)); + + // ->uuid + if (is_primary) + { + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + } + else + { + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_SECONDARY_SERVICE); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + } + // ->perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC; + // ->ext_perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0; + // ->max_size + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0; + + s_gatts_serv_env.serv_num++; + s_p_db_info_tab[s_create_serv_idx].att_num++; + + return SDK_SUCCESS; +} + +sdk_err_t ble_gatts_inc_serv_add(uint16_t *p_handle) +{ + size_t re_size; + void *mal_ptr; + uint8_t inc_serv_idx; + uint8_t att_idx; + + if (NULL == p_handle) + { + return SDK_ERR_POINTER_NULL; + } + + att_idx = s_p_db_info_tab[s_create_serv_idx].att_num; + + // re-malloc att handle ptr table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab; + re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 1); + + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE); + + // re-malloc att table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab; + re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 1); + + s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE); + + // ->uuid + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_INCLUDE); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + // ->perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC; + // ->ext_perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0; + // ->max_size + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0; + + inc_serv_idx = s_p_db_info_tab[s_create_serv_idx].inc_serv_num; + + // re-malloc p_inc_hdl_table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab; + re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].inc_serv_num + 1); + s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab, inc_serv_idx, BLE_GATTS_HADNLE_PTR_SIZE); + + s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab = mal_ptr; + s_p_db_info_tab[s_create_serv_idx].p_inc_hdl_tab[inc_serv_idx] = p_handle; + s_p_db_info_tab[s_create_serv_idx].inc_serv_num++; + + s_p_db_info_tab[s_create_serv_idx].att_num++; + + return SDK_SUCCESS; +} + +sdk_err_t ble_gatts_characteristic_add(ble_gatts_att_t *p_att, uint16_t *p_val_handle) +{ + size_t re_size; + void *mal_ptr; + uint8_t att_idx; + + if (NULL == p_att) + { + return SDK_ERR_POINTER_NULL; + } + + att_idx = s_p_db_info_tab[s_create_serv_idx].att_num; + + // re-malloc att handle ptr table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab; + re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 2); + + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE * 2); + + // re-malloc att table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab; + re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 2); + + s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE * 2); + + // Character dec + // ->uuid + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_CHARACTERISTIC); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + // ->perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm = READ_PERM_UNSEC; + // ->ext_perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = 0; + // ->max_size + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = 0; + + s_p_db_info_tab[s_create_serv_idx].att_num++; + att_idx++; + + // Character val + // ->uuid + if (p_att->att_uuid.type == BLE_ATT_UUID_128) + { + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, p_att->att_uuid.uuid.uuid128, 16); + } + else + { + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(p_att->att_uuid.uuid.uuid16); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + } + // ->perm + ble_gatts_att_perm_set(&s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm, p_att->att_prop, p_att->att_perm); + // ->ext_perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = ATT_VAL_LOC_USER; + if (p_att->att_uuid.type == BLE_ATT_UUID_128) + { + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm |= SERVICE_TABLE_TYPE_128; + } + // ->max_size + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = p_att->max_len; + + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_val_handle; + + s_p_db_info_tab[s_create_serv_idx].att_num++; + + return SDK_SUCCESS; +} + +sdk_err_t ble_gatts_descriptor_add(ble_gatts_att_t *p_att, uint16_t *p_handle) +{ + size_t re_size; + void *mal_ptr; + uint8_t att_idx; + + if (NULL == p_att) + { + return SDK_ERR_POINTER_NULL; + } + + att_idx = s_p_db_info_tab[s_create_serv_idx].att_num; + + // re-malloc att handle ptr table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab; + re_size = BLE_GATTS_HADNLE_PTR_SIZE * (s_p_db_info_tab[s_create_serv_idx].att_num + 1); + + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab, att_idx, BLE_GATTS_HADNLE_PTR_SIZE); + + // re-malloc att table + mal_ptr = s_p_db_info_tab[s_create_serv_idx].p_db_tab; + re_size = BLE_GATTS_ATT_ELEMENT_SIZE * (att_idx + 1); + + s_p_db_info_tab[s_create_serv_idx].p_db_tab = BLE_GATT_SERV_REALLOC(mal_ptr, re_size); + BLE_GATT_REALLOC_VERIFY(s_p_db_info_tab[s_create_serv_idx].p_db_tab, att_idx, BLE_GATTS_ATT_ELEMENT_SIZE); + + // ->uuid + if (p_att->att_uuid.type == BLE_ATT_UUID_128) + { + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, p_att->att_uuid.uuid.uuid128, 16); + } + else + { + uint8_t uuid[16] = BLE_ATT_16_TO_128_ARRAY(p_att->att_uuid.uuid.uuid16); + memcpy(s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].uuid, uuid, 16); + } + + // ->perm + ble_gatts_att_perm_set(&s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].perm, p_att->att_prop, p_att->att_perm); + // ->ext_perm + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm = ATT_VAL_LOC_USER; + if (p_att->att_uuid.type == BLE_ATT_UUID_128) + { + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].ext_perm |= SERVICE_TABLE_TYPE_128; + } + // ->max_size + s_p_db_info_tab[s_create_serv_idx].p_db_tab[att_idx].max_size = p_att->max_len; + + s_p_db_info_tab[s_create_serv_idx].p_att_hdl_tab[att_idx] = p_handle; + + s_p_db_info_tab[s_create_serv_idx].att_num++; + + return SDK_SUCCESS; +} + +sdk_err_t ble_gatts_serv_enable(ble_gatts_handler_t *p_att_handler) +{ + if (NULL == p_att_handler) + { + return SDK_ERR_POINTER_NULL; + } + + memcpy(&s_gatts_serv_env.p_serv_info[s_create_serv_idx].handlers, p_att_handler, sizeof(ble_gatts_handler_t)); + + return ble_server_prf_add(&s_prf_info); +} + +sdk_err_t ble_gatts_att_req_reply(uint8_t conn_idx, ble_gatts_att_req_reply_t *p_att_reply) +{ + if (NULL == p_att_reply) + { + return SDK_ERR_POINTER_NULL; + } + + if (BLE_ATT_READ_REPLY == p_att_reply->type) + { + gatts_read_cfm_t cfm; + + cfm.handle = p_att_reply->param.rd.handle; + cfm.status = p_att_reply->param.rd.status; + cfm.value = p_att_reply->param.rd.p_value; + cfm.length = p_att_reply->param.rd.length; + + return ble_gatts_read_cfm(conn_idx, &cfm); + } + else if (BLE_ATT_WRITE_REPLY == p_att_reply->type) + { + gatts_write_cfm_t cfm; + + cfm.handle = p_att_reply->param.wr.handle; + cfm.status = p_att_reply->param.wr.status; + + return ble_gatts_write_cfm(conn_idx, &cfm); + } + else + { + return SDK_ERR_INVALID_PARAM; + } +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.h new file mode 100644 index 0000000..9fcc45f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_gatt_service/ble_gatt_service.h @@ -0,0 +1,252 @@ +/** + **************************************************************************************** + * + * @file ble_gatt_service.h + * + * @brief BLE GATT Service Module Header + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __BLE_GATT_SERVICE_H__ +#define __BLE_GATT_SERVICE_H__ + +#include "ble.h" +#include "app_memory.h" + +/** + * @defgroup BLE_GATT_SERVICE_MAROC Defines + * @{ + */ +#define BLE_GATT_SERV_MALLOC(size) app_malloc(size) /**< Malloc adaptor. */ +#define BLE_GATT_SERV_FREE(ptr) app_free(ptr) /**< Free adaptor. */ +#define BLE_GATT_SERV_REALLOC(ptr, size) app_realloc(ptr, size) /**< Realloc adaptor. */ +/** @} */ + +/** + * @defgroup BLE_GATT_SERVICE_ENUM Enumerations + * @{ + */ +/**@brief BLE ATT UUID types. */ +typedef enum +{ + BLE_ATT_UUID_16, /**< 16-bit UUID type. */ + BLE_ATT_UUID_128 /**< 128-bit UUID type. */ +} ble_att_uuid_type_t; + +/**@brief BLE ATT properties. */ +typedef enum +{ + BLE_ATT_PROP_BROADCAST = 0x01 << 0, /**< Broadcast. */ + BLE_ATT_PROP_READ = 0x01 << 1, /**< Read. */ + BLE_ATT_PROP_WRITE_NO_RESP = 0x01 << 2, /**< Write CMD. */ + BLE_ATT_PROP_WRITE = 0x01 << 3, /**< Write with response. */ + BLE_ATT_PROP_NOTIFY = 0x01 << 4, /**< Notify. */ + BLE_ATT_PROP_INDICATE = 0x01 << 5, /**< Indicate. */ + BLE_ATT_PROP_WRITE_SIGNED = 0x01 << 6, /**< Signed write. */ + BLE_ATT_PROP_EXTENDED = 0x01 << 7, /**< Extended. */ +} ble_att_prop_t; + +/**@brief BLE ATT permission. */ +typedef enum +{ + BLE_ATT_NOAUTH, /**< No need to be encrypted or authenticated. */ + BLE_ATT_UNAUTH, /**< Need to be encrypted, but not to be authenticated. */ + BLE_ATT_AUTH, /**< Need to be encrypted and authenticated (MITM). */ + BLE_ATT_SEC_CON, /**< Need to be encrypted and authenticated (secure connections). */ +} ble_att_perm_t; + +/**@brief BLE ATT request reply types. */ +typedef enum +{ + BLE_ATT_READ_REPLY, /**< GATTS read reply. */ + BLE_ATT_WRITE_REPLY /**< GATTS write reply. */ +} ble_att_req_reply_type_t; +/** @} */ + +/** + * @defgroup BLE_GATT_SERVICE_TYPEDEF Typedefs + * @{ + */ +/**@brief Read attribute value request handler. */ +typedef void (*ble_gatts_read_req_handler_t)(uint8_t conn_idx, uint16_t handle); + +/**@brief Write attribute value request handler. */ +typedef void (*ble_gatts_write_req_handler_t)(uint8_t conn_idx, uint16_t handle, uint16_t offset, const uint8_t *p_value, uint16_t length); + +/**@brief Notification or indication handler. */ +typedef void (*ble_gatts_ntf_ind_handler_t)(uint8_t conn_idx, uint8_t status, gatt_evt_type_t type, uint16_t h_offset); + +/**@brief CCCD value recovery handler. */ +typedef void (*ble_gatts_cccd_recovery_handler_t)(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val); + +/**@brief Connect handler. */ +typedef void (*ble_gatts_on_connect_handler_t)(uint8_t conn_idx); + +/**@brief Disconnect handler. */ +typedef void (*ble_gatts_on_disconnect_handler_t)(uint8_t conn_idx, uint8_t reason); + +/** @} */ + +/** + * @defgroup BLE_GATT_SERVICE_STRUCT Structures + * @{ + */ +/**@brief BLE ATT UUID. */ +typedef struct +{ + ble_att_uuid_type_t type; /**< UUID type. */ + union + { + uint16_t uuid16; /**< 16-bit UUID. */ + uint8_t uuid128[16]; /**< 128-bit UUID. */ + }uuid; /**< UUID. */ +} ble_att_uuid_t; + +/**@brief GATT Attribute. */ +typedef struct +{ + ble_att_uuid_t att_uuid; /**< Pointer to the attribute UUID. */ + uint16_t att_prop; /**< ATT propertie bit map. */ + ble_att_perm_t att_perm; /**< ATT permission. */ + uint16_t max_len; /**< Maximum attribute value length. */ +} ble_gatts_att_t; + +/**@brief GATT Attribute read/write request reply. */ +typedef struct +{ + ble_att_req_reply_type_t type; /**< Reply type. */ + union + { + struct + { + uint16_t handle; /**< Value handle. */ + uint8_t status; /**< Reply status. */ + }wr; /**< Write reply. */ + struct + { + uint16_t handle; /**< Value handle. */ + uint8_t status; /**< Reply status. */ + uint8_t *p_value; /**< Pointer to read value. */ + uint16_t length; /**< Length of read value. */ + }rd; /**< Read reply. */ + }param; /**< Parameter of reply. */ +} ble_gatts_att_req_reply_t; + +/**@brief BLE GATTs callbacks. */ +typedef struct +{ + ble_gatts_read_req_handler_t read_req_handler; /**< Read attribute value request handler. */ + ble_gatts_write_req_handler_t write_req_handler; /**< Write attribute value request handler. */ + ble_gatts_ntf_ind_handler_t ntf_ind_handler; /**< Notification or indication handler. */ + ble_gatts_cccd_recovery_handler_t cccd_recovery_handler; /**< CCCD value recovery handler. */ + ble_gatts_on_connect_handler_t on_conn_handler; + ble_gatts_on_disconnect_handler_t on_disconn_handler; +} ble_gatts_handler_t; +/** @} */ + +/** + * @defgroup BLE_GATT_SERVICE_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Add primary/secondary service. + * + * @param[in] is_primary: Is primary service or not. + * @param[in] p_uuid: Pointer to service UUID. + * @param[out] p_handle: Pointer to service handle(will be allocated async after advertising start). + * + * @return Result of gatt service add. + ***************************************************************************************** + */ +sdk_err_t ble_gatts_serv_add(bool is_primary, const ble_att_uuid_t *p_uuid, uint16_t *p_handle); + +/** + ***************************************************************************************** + * @brief Add included service to GATT service. + * + * @param[in] p_offset: Pointer to the include service handle. + * + * @return Result of include service add. + ***************************************************************************************** + */ +sdk_err_t ble_gatts_inc_serv_add(uint16_t *p_handle); + +/** + ***************************************************************************************** + * @brief Add characteristic to GATT service. + * + * @param[in] p_att: Pointer to att info. + * @param[out] p_handle: Pointer to value handle(will be allocated async after advertising start). + * + * @return Result of gatt characteristic add. + ***************************************************************************************** + */ +sdk_err_t ble_gatts_characteristic_add(ble_gatts_att_t *p_att, uint16_t *p_val_handle); + +/** + ***************************************************************************************** + * @brief Add descriptor to GATT service. + * + * @param[in] p_att: Pointer to att info. + * @param[out] p_handle: Pointer to descriptor handle(will be allocated async after advertising start). + * + * @return Result of gatt descriptor add. + ***************************************************************************************** + */ +sdk_err_t ble_gatts_descriptor_add(ble_gatts_att_t *p_att, uint16_t *p_handle); + +/** + ***************************************************************************************** + * @brief Enable service to local DB. + * + * @param[in] p_att_handler: Pointer to attribute request handler. + * + * @return Result of publish. + ***************************************************************************************** + */ +sdk_err_t ble_gatts_serv_enable(ble_gatts_handler_t *p_att_handler); + +/** + **************************************************************************************** + * @brief Reply to an attribute read/write request. + * + * @param[in] conn_idx: Connection index. + * @param[in] p_att_reply: Pointer to att reply. + * + * @return Result of reply. + **************************************************************************************** + */ +sdk_err_t ble_gatts_att_req_reply(uint8_t conn_idx, ble_gatts_att_req_reply_t *p_att_reply); + +/** @} */ + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/BUILD.gn new file mode 100644 index 0000000..e0b70b4 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ble_scanner") { + sources = [ "ble_scanner.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.c new file mode 100644 index 0000000..c05e3d7 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.c @@ -0,0 +1,518 @@ +/** + ***************************************************************************************** + * + * @file ble_scanner.c + * + * @brief BLE Scanner Module implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* +* INCLUDE FILES +****************************************************************************************** +*/ +#include "ble_scanner.h" + +#if BLE_SCANNER_ENABLE + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief BLE Scanner Module environment variable. */ +struct ble_scanner_env_t +{ + bool connect_auto; + bool is_matched; + ble_gap_scan_param_t scan_param; + ble_gap_init_param_t conn_param; + ble_scanner_evt_handler_t evt_handler; + ble_scanner_err_handler_t err_handler; + bool filter_enable; + uint8_t filter_type; + ble_scanner_filter_mode_t filter_mode; + ble_scanner_filter_data_t target_data; +}; + +/* + * LOCAL VARIABLE DECLARATION + ***************************************************************************************** + */ +static struct ble_scanner_env_t s_scanner_env; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +//static void on_scanner_stoped(void *arg) +static void on_scanner_stoped(const ble_gap_stopped_reason_t reason) +{ + ble_scanner_evt_t event; + uint8_t error_code; + + event.evt_type = BLE_SCANNER_EVT_INVALID; + + if (BLE_GAP_STOPPED_REASON_TIMEOUT == reason) + { + event.evt_type = s_scanner_env.filter_type ? BLE_SCANNER_EVT_FILTER_NO_MATCH : BLE_SCANNER_EVT_TIMEOUT; + } + + if (BLE_GAP_STOPPED_REASON_ON_USER == reason && s_scanner_env.is_matched) + { + s_scanner_env.is_matched = false; + error_code = ble_gap_connect(BLE_GAP_OWN_ADDR_STATIC, &s_scanner_env.conn_param); + if (error_code) + { + ble_scanner_err_on_ble_capture(error_code); + } + } + + if (event.evt_type && s_scanner_env.evt_handler) + { + s_scanner_env.evt_handler(&event); + } +} + +static void on_scanner_connected(uint8_t conn_idx) +{ + ble_scanner_evt_t event; + + event.evt_type = BLE_SCANNER_EVT_CONNECTED; + event.param.conn_idx = conn_idx; + + if (s_scanner_env.evt_handler) + { + s_scanner_env.evt_handler(&event); + } +} + +static void ble_scanner_uuid_encode(const uint8_t *p_uuid_data, uint16_t length, uint8_t uuid_type, ble_scanner_uuid_t *p_uuid_buff) +{ + if (NULL == p_uuid_data || NULL == p_uuid_buff) + { + return; + } + + uint8_t current_offset = 0; + + while (current_offset < length) + { + switch (uuid_type) + { + case UUID_16_BIT_BYTES: + if (p_uuid_buff->uuid_16_bit_count < UUID_16_BIT_NUM_MAX) + { + memcpy(&p_uuid_buff->uuid_16_bit[p_uuid_buff->uuid_16_bit_count++], &p_uuid_data[current_offset], UUID_16_BIT_BYTES); + current_offset += UUID_16_BIT_BYTES; + } + break; + + case UUID_32_BIT_BYTES: + if (p_uuid_buff->uuid_32_bit_count < UUID_32_BIT_NUM_MAX) + { + memcpy(&p_uuid_buff->uuid_16_bit[p_uuid_buff->uuid_32_bit_count++], &p_uuid_data[current_offset], UUID_32_BIT_BYTES); + current_offset += UUID_32_BIT_BYTES; + } + break; + + case UUID_128_BIT_BYTES: + if (p_uuid_buff->uuid_128_bit_count < UUID_128_BIT_NUM_MAX) + { + memcpy(&p_uuid_buff->uuid_128_bit[p_uuid_buff->uuid_128_bit_count++][0], &p_uuid_data[current_offset], UUID_128_BIT_BYTES); + current_offset += UUID_128_BIT_BYTES; + } + break; + + default: + return; + } + } +} + +static void ble_scanner_parse_record(uint8_t ad_type, const uint8_t *p_data, uint16_t length, ble_scanner_parse_rec_t *p_parse_rec) +{ + uint8_t rec_idx = p_parse_rec->type_count; + + p_parse_rec->single_rec[rec_idx].ad_type = ad_type; + p_parse_rec->single_rec[rec_idx].type_data.p_data = p_data; + p_parse_rec->single_rec[rec_idx].type_data.length = length; + p_parse_rec->type_count++; +} + +static void ble_scanner_data_parse(const ble_gap_evt_adv_report_t *p_adv_report, ble_scanner_parse_report_t *p_parse_report) +{ + if (NULL == p_adv_report || NULL == p_parse_report) + { + return; + } + + memset(p_parse_report, 0, sizeof(ble_scanner_parse_report_t)); + + p_parse_report->adv_report_type = (ble_gap_adv_report_type_t)p_adv_report->adv_type; + p_parse_report->rssi = p_adv_report->rssi; + memcpy(&p_parse_report->peer_addr, &p_adv_report->broadcaster_addr, sizeof(ble_gap_bdaddr_t)); + memcpy(&s_scanner_env.conn_param.peer_addr, &p_adv_report->broadcaster_addr, sizeof(ble_gap_bdaddr_t)); + + uint8_t parse_offset = 0; + uint8_t *adv_data = p_adv_report->data; + uint8_t adv_data_len = p_adv_report->length; + uint8_t fragment_ad_type = 0; + uint8_t fragment_length = 0; + uint8_t data_length = 0; + + while (parse_offset < adv_data_len) + { + fragment_length = adv_data[parse_offset++]; + + if (0 == fragment_length) + { + break; + } + + data_length = fragment_length - 1; + fragment_ad_type = adv_data[parse_offset++]; + + switch (fragment_ad_type) + { + case BLE_GAP_AD_TYPE_FLAGS: + p_parse_report->flag = adv_data[parse_offset]; + p_parse_report->adv_type_parsed.flag = true; + break; + + case BLE_GAP_AD_TYPE_APPEARANCE: + p_parse_report->appearance = adv_data[parse_offset] | adv_data[parse_offset + 1] << 8; + p_parse_report->adv_type_parsed.appearance = true; + break; + + case BLE_GAP_AD_TYPE_SHORTENED_NAME: + case BLE_GAP_AD_TYPE_COMPLETE_NAME: + p_parse_report->local_name.p_data = &adv_data[parse_offset]; + p_parse_report->local_name.length = data_length; + p_parse_report->adv_type_parsed.local_name = true; + break; + + case BLE_GAP_AD_TYPE_MANU_SPECIFIC_DATA: + p_parse_report->manufacture_data.p_data = &adv_data[parse_offset]; + p_parse_report->manufacture_data.length = data_length; + p_parse_report->adv_type_parsed.manufacture_data = true; + break; + + case BLE_GAP_AD_TYPE_MORE_16_BIT_UUID: + case BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID: + ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_16_BIT_BYTES, &p_parse_report->uuid_list); + p_parse_report->adv_type_parsed.uuid = true; + break; + + case BLE_GAP_AD_TYPE_MORE_32_BIT_UUID: + case BLE_GAP_AD_TYPE_COMPLETE_LIST_32_BIT_UUID: + ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_32_BIT_BYTES, &p_parse_report->uuid_list); + p_parse_report->adv_type_parsed.uuid = true; + break; + + case BLE_GAP_AD_TYPE_MORE_128_BIT_UUID: + case BLE_GAP_AD_TYPE_COMPLETE_LIST_128_BIT_UUID: + ble_scanner_uuid_encode(&adv_data[parse_offset], data_length, UUID_128_BIT_BYTES, &p_parse_report->uuid_list); + p_parse_report->adv_type_parsed.uuid = true; + break; + + default: + ble_scanner_parse_record(fragment_ad_type, &adv_data[parse_offset], data_length, &p_parse_report->other_parse_rec); + break; + } + + parse_offset += data_length; + } +} + +static bool ble_scanner_filter_uuid_macth(ble_data_t *p_uuid, ble_scanner_uuid_t *p_uuid_list) +{ + if (p_uuid->length == UUID_16_BIT_BYTES) + { + for (uint8_t i = 0; i < p_uuid_list->uuid_16_bit_count; i++) + { + if (0 == memcmp(p_uuid->p_data, (uint8_t *)&p_uuid_list->uuid_16_bit[i], UUID_16_BIT_BYTES)) + { + return true; + } + } + } + + if (p_uuid->length == UUID_32_BIT_BYTES) + { + for (uint8_t i = 0; i < p_uuid_list->uuid_32_bit_count; i++) + { + if (0 == memcmp(p_uuid->p_data, (uint8_t *)&p_uuid_list->uuid_32_bit[i], UUID_32_BIT_BYTES)) + { + return true; + } + } + } + + if (p_uuid->length == UUID_128_BIT_BYTES) + { + for (uint8_t i = 0; i < p_uuid_list->uuid_128_bit_count; i++) + { + if (0 == memcmp(p_uuid->p_data, p_uuid_list->uuid_128_bit[i], UUID_128_BIT_BYTES)) + { + return true; + } + } + } + + return false; +} + +static bool ble_scanner_filter_match_check(ble_scanner_parse_report_t *p_parse_report, ble_scanner_filter_match_t *p_match_result) +{ + memset(p_match_result, 0, sizeof(ble_scanner_filter_match_t)); + + if (s_scanner_env.filter_type & BLE_SCANNER_NAME_FILTER) + { + if (p_parse_report->local_name.length == s_scanner_env.target_data.dev_name.length && + 0 == memcmp(p_parse_report->local_name.p_data, + s_scanner_env.target_data.dev_name.p_data, + s_scanner_env.target_data.dev_name.length)) + { + p_match_result->dev_name_match = true; + } + } + + if (s_scanner_env.filter_type & BLE_SCANNER_APPEARANCE_FILTER) + { + if (p_parse_report->appearance == s_scanner_env.target_data.appearance) + { + p_match_result->appearance_match = true; + } + } + + if (s_scanner_env.filter_type & BLE_SCANNER_UUID_FILTER) + { + if (ble_scanner_filter_uuid_macth(&s_scanner_env.target_data.svr_uuid, &p_parse_report->uuid_list)) + { + p_match_result->uuid_match = true; + } + } + + if (s_scanner_env.filter_type & BLE_SCANNER_ADDR_FILTER) + { + if (0 == memcmp(&s_scanner_env.target_data.target_addr, &p_parse_report->peer_addr, sizeof(ble_gap_bdaddr_t))) + { + p_match_result->addr_match = true; + } + } + + if (BLE_SCANNER_FILTER_ANYONE_MATCH == s_scanner_env.filter_mode) + { + if (p_match_result->dev_name_match || + p_match_result->appearance_match || + p_match_result->uuid_match || + p_match_result->addr_match) + { + return true; + } + + return false; + } + else + { + if (s_scanner_env.filter_type & BLE_SCANNER_NAME_FILTER && !p_match_result->dev_name_match) + { + return false; + } + + if (s_scanner_env.filter_type & BLE_SCANNER_APPEARANCE_FILTER && !p_match_result->appearance_match) + { + return false; + } + + if (s_scanner_env.filter_type & BLE_SCANNER_UUID_FILTER && !p_match_result->uuid_match) + { + return false; + } + + if (s_scanner_env.filter_type & BLE_SCANNER_ADDR_FILTER && !p_match_result->addr_match) + { + return false; + } + } + + return true; +} + +static void on_scanner_adv_report(const ble_gap_evt_adv_report_t *p_adv_report) +{ + ble_scanner_parse_report_t parse_report; + ble_scanner_evt_t event; + ble_scanner_filter_match_t match_result; + + memset(&event, 0, sizeof(event)); + memset(&parse_report, 0, sizeof(parse_report)); + memset(&match_result, 0, sizeof(match_result)); + + if(!s_scanner_env.is_matched) + { + ble_scanner_data_parse(p_adv_report, &parse_report); + } + + event.evt_type = BLE_SCANNER_EVT_ADV_REPORT_PARSE; + memcpy(&event.param.parse_record, &parse_report, sizeof(ble_scanner_parse_report_t)); + + if (s_scanner_env.evt_handler) + { + s_scanner_env.evt_handler(&event); + } + + if (s_scanner_env.filter_enable) + { + if (ble_scanner_filter_match_check(&parse_report, &match_result)) + { + event.evt_type = BLE_SCANNER_EVT_FILTER_MATCH; + memcpy(&event.param.match_result, &match_result, sizeof(ble_scanner_filter_match_t)); + + if (s_scanner_env.evt_handler) + { + s_scanner_env.evt_handler(&event); + } + + if (s_scanner_env.connect_auto) + { + s_scanner_env.is_matched = true; + ble_scanner_stop(); + } + } + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +sdk_err_t ble_scanner_init(ble_scanner_init_t *p_scan_init) +{ + if (NULL == p_scan_init) + { + return SDK_ERR_INVALID_PARAM; + } + + memcpy(&s_scanner_env, p_scan_init, sizeof(ble_scanner_init_t)); + + return ble_gap_scan_param_set(BLE_GAP_OWN_ADDR_STATIC, &s_scanner_env.scan_param); +} + +sdk_err_t ble_scanner_filter_set(uint8_t filter_type, ble_scanner_filter_data_t *p_filter_data) +{ + sdk_err_t error_code = SDK_SUCCESS; + + if (NULL == p_filter_data) + { + return SDK_ERR_INVALID_PARAM; + } + + s_scanner_env.filter_type = filter_type; + memcpy(&s_scanner_env.target_data, p_filter_data, sizeof(ble_scanner_filter_data_t)); + + return error_code; +} + +void ble_scanner_filter_disable(void) +{ + s_scanner_env.filter_enable = false; +} + +void ble_scanner_filter_enable(ble_scanner_filter_mode_t filter_mode) +{ + s_scanner_env.filter_mode = filter_mode; + + s_scanner_env.filter_enable = true; +} + +sdk_err_t ble_scanner_start(void) +{ + ble_scanner_evt_t event; + + if (s_scanner_env.scan_param.use_whitelist) + { + event.evt_type = BLE_SCANNER_EVT_WHITELIST_REQUEST; + + if (s_scanner_env.evt_handler) + { + s_scanner_env.evt_handler(&event); + } + } + + return ble_gap_scan_start(); +} + +sdk_err_t ble_scanner_stop(void) +{ + return ble_gap_scan_stop(); +} + + +void ble_scanner_err_on_ble_capture(uint8_t err_code) +{ + if (s_scanner_env.err_handler && err_code) + { + s_scanner_env.err_handler(err_code); + } +} + +void ble_scanner_evt_on_ble_capture(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GAPM_EVT_SCAN_START: + break; + + case BLE_GAPM_EVT_SCAN_STOP: + on_scanner_stoped(p_evt->evt.gapm_evt.params.scan_stop.reason); + break; + + case BLE_GAPM_EVT_ADV_REPORT: + on_scanner_adv_report(&p_evt->evt.gapm_evt.params.adv_report); + break; + + case BLE_GAPC_EVT_CONNECTED: + on_scanner_connected(p_evt->evt.gapc_evt.index); + break; + + default: + break; + } +} +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.h new file mode 100644 index 0000000..636432d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_scanner/ble_scanner.h @@ -0,0 +1,331 @@ +/** + ***************************************************************************************** + * + * @file ble_scanner.h + * + * @brief BLE Scanner Module API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +#ifndef __BLE_SCANNER__ +#define __BLE_SCANNER__ + +#include "ble_module_config.h" +#include "ble_event.h" +#include "ble_gapm.h" + +/** + * @defgroup BLE_SCANNER_MAROC Defines + * @{ + */ +/**@brief Capture scanner event. */ +#define BLE_SCANNER_EVT_CAPTURE(err, evt_id, arg) \ +do \ +{ \ + if (err != BLE_SUCCESS) \ + { \ + ble_scanner_err_on_ble_capture(err); \ + } \ + else \ + { \ + ble_scanner_evt_on_ble_capture(evt_id, arg); \ + } \ +} while(0) +/** @} */ + +#define AD_TYPE_NUM_MAX 10 /**< Maximum number of ad type can be parsed in one advertising report packet. */ +#define UUID_16_BIT_NUM_MAX 14 /**< Maximum number of 16 bit uuid service can be parsed in one advertising report packet. */ +#define UUID_32_BIT_NUM_MAX 7 /**< Maximum number of 32 bit uuid service can be parsed in one advertising report packet. */ +#define UUID_128_BIT_NUM_MAX 1 /**< Maximum number of 128 bit uuid service can be parsed in one advertising report packet. */ + +#define UUID_16_BIT_BYTES 2 /**< Length of bytes for 16 bit UUID. */ +#define UUID_32_BIT_BYTES 4 /**< Length of bytes for 32 bit UUID. */ +#define UUID_128_BIT_BYTES 16 /**< Length of bytes for 128 bit UUID. */ +/** @} */ + +/** + * @defgroup BLE_SCANNER_ENUM Enumerations + * @{ + */ +/**@brief BLE GAP event ids. */ +enum +{ + BLE_GAP_EVT_ID_ADV_START = BLE_COMMON_EVT_BASE, + BLE_GAP_EVT_ID_ADV_STOP, + BLE_GAP_EVT_ID_ADV_REPORT, + BLE_GAP_EVT_ID_CONNECTED, + BLE_GAP_EVT_ID_DISCONNECTED, + BLE_GAP_EVT_ID_CONNECTED_CANCLE, + BLE_GAP_EVT_ID_CONN_PARAM_UPDATED, + BLE_GAP_EVT_ID_PHY_UPDATED, + BLE_GAP_EVT_ID_DEV_INFO_GOT, + BLE_GAP_EVT_ID_SCAN_START, + BLE_GAP_EVT_ID_SCAN_STOP, + BLE_GAP_EVT_ID_SCAN_REQUEST, + BLE_GAP_EVT_ID_SYNC_ESTABLISH, + BLE_GAP_EVT_ID_PEER_NAME_GOT, + BLE_GAP_EVT_ID_CONN_PARAM_UPDATE_REQUEST, + BLE_GAP_EVT_ID_CONN_INFO_GOT, + BLE_GAP_EVT_ID_PEER_DEV_INFO_GOT, + BLE_GAP_EVT_ID_DATA_LENGTH_UPDATED, + BLE_GAP_EVT_ID_READ_RSLV_ADDR +}; + +/**@brief BLE Scanner filter match mode. */ +typedef enum +{ + BLE_SCANNER_FILTER_ALL_MATCH, /**< Only when all type match. */ + BLE_SCANNER_FILTER_ANYONE_MATCH, /**< Just match any type . */ +} ble_scanner_filter_mode_t; + +/**@brief BLE Scanner filter types. */ +typedef enum +{ + BLE_SCANNER_NAME_FILTER = (0x01 << 0), /**< Filter device base on target device name. */ + BLE_SCANNER_APPEARANCE_FILTER = (0x01 << 1), /**< Filter device base on target appearance. */ + BLE_SCANNER_UUID_FILTER = (0x01 << 2), /**< Filter device base on tagert service UUID. */ + BLE_SCANNER_ADDR_FILTER = (0x01 << 3), /**< Filter device base on target address. */ +} ble_scanner_filter_type_t; + +/**@brief BLE Scanner event type. */ +typedef enum +{ + BLE_SCANNER_EVT_INVALID, /**< Invalid event. */ + BLE_SCANNER_EVT_WHITELIST_REQUEST, /**< Request user to add whitelist. */ + BLE_SCANNER_EVT_TIMEOUT, /**< Scan tiemout. */ + BLE_SCANNER_EVT_ADV_REPORT_PARSE, /**< Advertising report parsed. */ + BLE_SCANNER_EVT_FILTER_MATCH, /**< Filter match from adv report. */ + BLE_SCANNER_EVT_FILTER_NO_MATCH, /**< Filter no match from adv report. */ + BLE_SCANNER_EVT_CONNECTED, /**< Connected. */ +} ble_scanner_evt_type_t; +/** @} */ + +/** + * @defgroup BLE_SCANNER_STRUCT Structures + * @{ + */ +/**@brief Data structure. */ +typedef struct +{ + const uint8_t *p_data; /**< Pointer to the data. */ + uint16_t length; /**< Length of the data. */ +} ble_data_t; + +/**@brief Target data provided to filter. */ +typedef struct +{ + ble_data_t dev_name; /**< Target device name. */ + uint16_t appearance; /**< Target appearance. */ + ble_data_t svr_uuid; /**< Target service UUID. */ + ble_gap_bdaddr_t target_addr; /**< Target device address. */ +} ble_scanner_filter_data_t; + +/**@brief UUID data parsed from advertising report. */ +typedef struct +{ + uint8_t uuid_16_bit_count; /**< Count of 16 bit uuid parsed. */ + uint8_t uuid_32_bit_count; /**< Count of 32 bit uuid parsed. */ + uint8_t uuid_128_bit_count; /**< Count of 128 bit uuid parsed. */ + uint16_t uuid_16_bit[UUID_16_BIT_NUM_MAX]; /**< All 16 bit uuid data parsed. */ + uint32_t uuid_32_bit[UUID_32_BIT_NUM_MAX]; /**< All 32 bit uuid data parsed. */ + uint8_t uuid_128_bit[UUID_128_BIT_NUM_MAX][UUID_128_BIT_BYTES]; /**< All 128 bit uuid data parsed. */ +} ble_scanner_uuid_t; + +/**@brief Parsed adv types */ +typedef struct +{ + bool flag; /**< True if flag existed, false or not. */ + bool appearance; /**< True if appearance existed, false or not. */ + bool local_name; /**< True if service UUID existed, false or not. */ + bool manufacture_data; /**< True if manufacture data existed, false or not. */ + bool uuid; /**< True if UUID existed, false or not. */ +} ble_scanner_adv_type_t; + +/**@brief Single advertising type parsed from advertising report. */ +typedef struct +{ + uint8_t ad_type; /**< GAP advertising data type. */ + ble_data_t type_data; /**< Adv type raw data. */ +} ble_scanner_single_rec_t; + +/**@brief All GAP advertising type parsed from advertising report. */ +typedef struct +{ + uint8_t type_count; /**< Count of advertising type parsed. */ + ble_scanner_single_rec_t single_rec[AD_TYPE_NUM_MAX]; /**< Information of parsed. */ +} ble_scanner_parse_rec_t; + +/**@brief All parsed result from advertising report. */ +typedef struct +{ + ble_gap_adv_report_type_t adv_report_type; /**< Advertising report type. */ + ble_scanner_adv_type_t adv_type_parsed; /**< Parsed adv types. */ + ble_gap_bdaddr_t peer_addr; /**< Address of device from which advertising. */ + int8_t rssi; /**< RSSI (between -127 and +20 dBm). */ + uint8_t flag; /**< Flag, shall not appear more than once in a block. */ + uint16_t appearance; /**< Appearance, shall not appear more than once in a block. */ + ble_data_t local_name; /**< Local name, shall not appear more than once in a block. */ + ble_data_t manufacture_data; /**< Manufacturer specific data. */ + ble_scanner_uuid_t uuid_list; /**< Service uuid list. */ + ble_scanner_parse_rec_t other_parse_rec; /**< Other data parse record. */ +} ble_scanner_parse_report_t; + +/**@brief Matched with which target data. */ +typedef struct +{ + bool dev_name_match; /**< True if device name matched, false or not. */ + bool appearance_match; /**< True if appearance matched, false or not. */ + bool uuid_match; /**< True if service UUID matched, false or not. */ + bool addr_match; /**< True if address matched, false or not. */ +} ble_scanner_filter_match_t; + +/**@brief BLE Scanner Module event. */ +typedef struct +{ + ble_scanner_evt_type_t evt_type; /**< BLE Scanner event type. */ + union + { + ble_scanner_filter_match_t match_result; /**< Filter match result. */ + ble_scanner_parse_report_t parse_record; /**< Advertising report parse result record. */ + uint8_t conn_idx; /**< Connect index. */ + } param; +} ble_scanner_evt_t; +/** @} */ + +/** + * @defgroup BLE_SCANNER_TYPEDEF Typedefs + * @{ + */ +/**@brief BLE scanner event handler type. */ +typedef void (*ble_scanner_evt_handler_t)(ble_scanner_evt_t *p_evt); + +/**@brief BLE scanner error handler type. */ +typedef void (*ble_scanner_err_handler_t)(uint8_t err_code); +/** @} */ + +/** + * @defgroup BLE_SCANNER_STRUCT Structures + * @{ + */ +typedef struct +{ + bool connect_auto; /**< Ture: Connect to target device when found, False: Notify to application when device when found. */ + ble_gap_scan_param_t scan_param; /**< Scan parameters. */ + ble_gap_init_param_t conn_param; /**< Connect parameters which must be initialized when @see connect_auto to be set Ture. */ + ble_scanner_evt_handler_t evt_handler; /**< Handler to handle scan events for application. */ + ble_scanner_err_handler_t err_handler; /**< Handler to handle scan errors for application. */ +} ble_scanner_init_t; +/** @} */ + +/** + * @defgroup BLE_SCANNER_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief BLE Scanner Module initialization. + * + * @param[in] p_scanner_init: Pointer to BLE Scanner Module initialization parameters + * + * @return Result of init operation. + ***************************************************************************************** + */ +sdk_err_t ble_scanner_init(ble_scanner_init_t *p_scanner_init); + +/** + ***************************************************************************************** + * @brief BLE Scanner Module filter set(can override set). + * + * @param[in] filter_type: Filter type. + * @param[in] p_filter_data: Pointer to data for filtering. + * + * @return Result of set operation. + ***************************************************************************************** + */ +sdk_err_t ble_scanner_filter_set(uint8_t filter_type, ble_scanner_filter_data_t *p_filter_data); + +/** + ***************************************************************************************** + * @brief BLE Scanner Module filter diasble. + ***************************************************************************************** + */ +void ble_scanner_filter_disable(void); + +/** + ***************************************************************************************** + * @brief BLE Scan Module filter enable. + * + * @param[in] filter_mode: Filter mode. + ***************************************************************************************** + */ +void ble_scanner_filter_enable(ble_scanner_filter_mode_t filter_mode); + +/** + ***************************************************************************************** + * @brief BLE Scanner Module starts scanning device. + * + * @return Result of start scanning. + ***************************************************************************************** + */ +sdk_err_t ble_scanner_start(void); + +/** + ***************************************************************************************** + * @brief BLE Scanner Module stop scanning device. + * + * @return Result of stop scanning. + ***************************************************************************************** + */ +sdk_err_t ble_scanner_stop(void); + +/** + ***************************************************************************************** + * @brief Capture scanner events on BLE. + * + * @param[in] evt_id: Event ID on BLE. + * @param[in] arg: Arguments. + ***************************************************************************************** + */ +void ble_scanner_evt_on_ble_capture(const ble_evt_t *p_evt); + +/** + ***************************************************************************************** + * @brief Capture scanner error. + * + * @param[in] err_code: Error code. + ***************************************************************************************** + */ +void ble_scanner_err_on_ble_capture(uint8_t err_code); +/** @} */ +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/BUILD.gn new file mode 100644 index 0000000..01b78e2 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ble_time") { + sources = [ "ble_time.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.c new file mode 100644 index 0000000..0d5ddca --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.c @@ -0,0 +1,68 @@ +/** + ***************************************************************************************** + * + * @file ble_time.c + * + * @brief Provide method to get and calculate ble time. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "grx_hal.h" +#include "grx_sys.h" +#include "ble_time.h" + +/** + **************************************************************************************** + * @brief This function get the ble time. + * + * @note This function is supported only when ble core is powered on + * + **************************************************************************************** + */ +ble_time_t rwip_time_get(void); + +/** + **************************************************************************************** + * @brief This function gets the ble time. + * + * @note This function is supported only when ble stack is initiated + * + **************************************************************************************** + */ +SECTION_RAM_CODE ble_time_t ble_time_get(void) +{ + pwr_mgmt_ble_wakeup(); + return rwip_time_get(); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.h new file mode 100644 index 0000000..02b8572 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ble/ble_time/ble_time.h @@ -0,0 +1,35 @@ +#ifndef __APP_BLE_TIME_H__ +#define __APP_BLE_TIME_H__ +#include "grx_hal.h" + +/* + * MACRO DEFINITIONS + ***************************************************************************************** + */ +#define TICK_MS_IN_HUS (2000) +#define HALF_SLOT_SIZE (625) +#define RWIP_MAX_CLOCK_TIME (0xFFFFFFF) +#define SECOND_IN_HUS (2000000) +#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME)) + +/* + * STRUCTURE DEFINITIONS + ***************************************************************************************** + */ +typedef struct +{ + uint32_t hs; + uint16_t hus; +} ble_time_t; + +/** + **************************************************************************************** + * @brief This function get the ble time. + * + * @note This function is supported only when ble stack is initiated + * + **************************************************************************************** + */ +ble_time_t ble_time_get(void); + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/BUILD.gn new file mode 100644 index 0000000..fe5dc56 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "inc" ] +} + +kernel_module("crypto_lib") { + sources = [ + "src/crypto_aes.c", + "src/crypto_ecc.c", + "src/crypto_ecc_port.c", + "src/crypto_gcm.c", + "src/crypto_pkc.c", + "src/crypto_pkc_port.c", + "src/crypto_rsa.c", + "src/crypto_rsa_port.c", + "src/crypto_sha256.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_aes.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_aes.h new file mode 100644 index 0000000..c2f1a35 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_aes.h @@ -0,0 +1,360 @@ +/** + **************************************************************************************** + * + * @file crypto_aes.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto AES library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER + * @{ + */ + +/** @defgroup CRYPTO_AES AES + * @brief AES CRYPTO driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRYPTO_AES_H__ +#define __CRYPTO_AES_H__ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRYPTO_AES_MACRO Defines + * @{ + */ + +#define AES_BLOCK_SIZE 16 /**< AES BLOCK SIZE. */ +#define AES_ENCRYPT 1 /**< AES ENCRYPT MODE. */ +#define AES_DECRYPT 0 /**< AES DECRYPT MODE. */ +#define AES_MAX_KEY_SIZE 32 /**< AES MAX KEY SIZE. */ +/** @} */ + +/** @addtogroup CRYPTO_AES_ENUM Enumerations + * @{ + */ + +/** + * @brief This defines the process state of aes padding type value. + */ +typedef enum { + PADDING_NONE = 0, /**< AES padding type none. */ + PADDING_ZEROS, /**< AES padding type zeros. */ + PADDING_PKCS7, /**< AES padding type pkcs7. */ +} crypto_aes_padding_t; +/** @} */ + +/** @addtogroup CRYPTO_AES_CONTEXT_STRUCTURES Structures + * @{ + */ + +/** @defgroup AES Context Structurs Definition + * @{ + */ + +/** + * @brief This defines the structure of aes context. + */ +typedef struct +{ + uint8_t key[AES_MAX_KEY_SIZE]; /**< the key. */ + uint16_t keybits; /**< the keybits. */ + crypto_aes_padding_t padding_mode; /**< padding mode. */ + void *instance; /**< the aes instance. */ +} crypto_aes_context; +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRYPTO_AES_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief crypto aes init. + * + * @param[in] ctx: aes context. + * + **************************************************************************************** + */ +void crypto_aes_init(crypto_aes_context *ctx); + +/** + **************************************************************************************** + * @brief crypto aes free. + * + * @param[in] ctx: aes context. + * + **************************************************************************************** + */ +void crypto_aes_free(crypto_aes_context *ctx); + +/** + **************************************************************************************** + * @brief crypto aes set the padding type. + * + * @param[in] ctx: aes context. + * @param[in] padding_type: PADDING_NONE/PADDING_ZEROS/PADDING_PKCS7. + * + * @retval ::-1: The aes set paddings type error. + * @retval ::0: The aes set paddings type successfully. + **************************************************************************************** + */ +int crypto_aes_set_paddings(crypto_aes_context *ctx, crypto_aes_padding_t padding_type); + +/** + * **************************************************************************************** + * @brief AES key schedule (encryption) + * + * @param[in] ctx: AES context to be initialized + * @param[in] key: encryption key + * @param[in] keybits: must be 128, 192 or 256 + * + * @retval ::-1: The aes set key enc error. + * @retval ::0: The aes set key enc successfully. + * **************************************************************************************** + */ +int crypto_aes_setkey_enc(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits); + +/** + * **************************************************************************************** + * @brief AES key schedule (decryption) + * + * @param[in] ctx: AES context to be initialized + * @param[in] key: encryption key + * @param[in] keybits: must be 128, 192 or 256 + * + * @retval ::-1: The aes set key enc error. + * @retval ::0: The aes set key enc successfully. + * **************************************************************************************** + */ +int crypto_aes_setkey_dec(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits); + +/** + * **************************************************************************************** + * @brief pkcs7 padding algorithm + * + * @param[in] input: input block + * @param[in] length: input length + * @param[out] output: output block + * + * @retval ::-1: The aes pkcs7 padding error. + * @retval ::others: The aes pkcs7 padding output length. + * ***************************************************************************************** + */ +int crypto_aes_pkcs7_padding(uint8_t *input, uint32_t length, uint8_t *output); + +/** + * **************************************************************************************** + * @brief zero padding algorithm + * + * @param[in] input: input block + * @param[in] length: input length + * @param[out] output: output block + * + * @retval ::-1: The aes zero padding error. + * @retval ::others: The aes zero padding output length. + * ***************************************************************************************** + */ +int crypto_aes_zero_padding(uint8_t *input, uint32_t length, uint8_t *output); + +/** + * **************************************************************************************** + * @brief get output length + * + * @param[in] length: input length + * @param[in] padding_type: padding type + * + * @retval ::len: The output len. + * ***************************************************************************************** + */ +uint32_t crypto_aes_get_output_length(uint32_t length, crypto_aes_padding_t padding_type); + +/** + * **************************************************************************************** + * @brief AES-ECB block encryption/decryption + * + * @param[in] ctx: AES context + * @param[in] mode: AES_ENCRYPT or AES_DECRYPT + * @param[in] input: input block + * @param[in] length: input length + * @param[out] output: output block + * + * @retval ::-1: The aes ecb crypt error. + * @retval ::0: The aes ecb crypt successfully. + * ***************************************************************************************** + */ +int crypto_aes_crypt_ecb(crypto_aes_context *ctx, uint8_t mode, uint8_t *input, uint32_t length, uint8_t *output); + +/** + * ***************************************************************************************** + * @brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * @note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * @param[in] ctx: AES context + * @param[in] mode: AES_ENCRYPT or AES_DECRYPT + * @param[in] iv: initialization vector (updated after use) + * @param[in] input: buffer holding the input data + * @param[in] length: buffer holding the input data length + * @param[out] output: buffer holding the output data + * + * @retval ::-1: The aes cbc crypt error. + * @retval ::0: The aes cbc crypt successfully. + * ***************************************************************************************** + */ +int crypto_aes_crypt_cbc(crypto_aes_context *ctx, uint8_t mode, uint8_t iv[16], uint8_t *input, uint32_t length, uint8_t *output); + +/** + * ***************************************************************************************** + * @brief AES-CTR buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * @note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * @param[in] ctx: AES context + * @param[in] length: buffer holding the input data length + * @param[in] nc_off: The offset in the current stream_block, for resuming within the current cipher stream. + * The offset pointer should be 0 at the start of a stream. + * @param[in] nonce_counter: The 128-bit nonce and counter. + * It must be a readable-writeable buffer of 16 Bytes. + * @param[in] stream_block: The saved stream block for resuming. + * This is overwritten by the function. + * It must be a readable-writeable buffer of 16 Bytes. + * @param[in] input: buffer holding the input data + * @param[out] output: buffer holding the output data + * + * @retval ::-1: The aes ctr crypt error. + * @retval ::0: The aes ctr crypt successfully. + * ***************************************************************************************** + */ +int crypto_aes_crypt_ctr(crypto_aes_context *ctx, uint32_t length, uint32_t *nc_off, + uint8_t nonce_counter[16], uint8_t stream_block[16], const uint8_t *input, uint8_t *output); + +/** + * ***************************************************************************************** + * @brief AES-CFB128 buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * @note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * @param[in] ctx: AES context + * @param[in] mode: AES operation + * @param[in] length: buffer holding the input data length + * @param[in] iv_off: The offset in IV (updated after use) + * @param[in] iv: The initialization vector (updated after use) + * @param[in] input: buffer holding the input data + * @param[out] output: buffer holding the output data + * + * @retval ::-1: The aes ctr crypt error. + * @retval ::0: The aes ctr crypt successfully. + * ***************************************************************************************** + */ +int crypto_aes_crypt_cfb128(crypto_aes_context *ctx, uint8_t mode, uint32_t length, uint32_t *iv_off, + uint8_t iv[16], const uint8_t *input, uint8_t *output); + +/** + * ***************************************************************************************** + * @brief AES-OFB buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * @note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * @param[in] ctx: AES context + * @param[in] length: buffer holding the input data length + * @param[in] iv_off: The offset in IV (updated after use) + * @param[in] iv: The initialization vector (updated after use) + * @param[in] input: buffer holding the input data + * @param[out] output: buffer holding the output data + * + * @retval ::-1: The aes ctr crypt error. + * @retval ::0: The aes ctr crypt successfully. + * ***************************************************************************************** + */ +int crypto_aes_crypt_ofb(crypto_aes_context *ctx, uint32_t length, uint32_t *iv_off, + uint8_t iv[16], const uint8_t *input, uint8_t *output); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_AES_H__ */ + +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_ecc.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_ecc.h new file mode 100644 index 0000000..4fc4308 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_ecc.h @@ -0,0 +1,411 @@ +/** + **************************************************************************************** + * + * @file crypto_ecc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto ECC library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER + * @{ + */ + +/** @defgroup CRYPTO_ECC ECC + * @brief ECC CRYPTO driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRYPTO_ECC_H__ +#define __CRYPTO_ECC_H__ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRYPTO_ECC_MACRO Defines + * @{ + */ + +#define ECC_U32_LENGTH (8) /**< ECC supported 256-bit. */ +#define ECC_HASH_SHA_256 (1) /**< ECC use hash sha256. */ +#define ECC_HASH_NONE (0) /**< ECC without hash. */ +/** @} */ + +/** @addtogroup CRYPTO_ECC_ENUM Enumerations + * @{ + */ + +/** + * @brief ECC Return code. + */ +typedef enum _algo_ecc_ret { + + ECC_OK = 0, /**< ECC Return OK. */ + ECC_ERROR_PARAMETER = 10000, /**< ECC Return Parameter Error. */ + ECC_ERROR_SIGN, /**< ECC Return Sign Error. */ + ECC_ERROR_VERIFY, /**< ECC Return Verify Error. */ + ECC_ERROR_POINT_NOT_ON_CURVE, /**< ECC Return Point is not on curve Error. */ + ECC_ERROR_INTERFACE_EMPTY, /**< ECC Return interface not found. */ +} algo_ecc_ret_e; + +/** + * @brief ECC Curve type. + */ +typedef enum _algo_ecc_curve_type { + + ECC_CURVE_SECP256R1, /**< NIST SECP256R1 Curve. */ + ECC_CURVE_SECP256K1, /**< NIST SECP256K1 Curve. */ +} algo_ecc_curve_type_e; +/** @} */ + +/** @addtogroup CRYPTO_ECC_CONTEXT_STRUCTURES Structures + * @{ + */ + +/** @defgroup ECC Point Structurs Definition + * @{ + */ + +/** + * @brief Defines a data structure of a point, include x-axis and y-axis. And (0,0) is defined as the point of infinite. + */ +typedef struct _algo_ecc_point { + + uint32_t x[ECC_U32_LENGTH]; /**< point' x-axis, interger format (ANSI X9.62 - 2005 (Page 27))*/ + uint32_t y[ECC_U32_LENGTH]; /**< point' y-axis, interger format (ANSI X9.62 - 2005 (Page 27))*/ + +} algo_ecc_point_t; +/** @} */ + +/** @defgroup ECC Curve Structurs Definition + * @{ + */ + +/** + * @brief User defined elliptic curve description. + */ +typedef struct _algo_ecc_curve_parameter { + + /** + * parameter A in Montgomery Filed! a = a * R, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 a = {0xfffffffc,0xffffffff,0xffffffff,0x00000003,0x00000000,0x00000000,0x00000004,0xfffffffc}; + */ + uint32_t a[ECC_U32_LENGTH]; /**< parameter A in Montgomery Filed! */ + + /** + * parameter B in Montgomery Filed! b = b * R, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 b = {0x29c4bddf,0xd89cdf62,0x78843090,0xacf005cd,0xf7212ed6,0xe5a220ab,0x04874834,0xdc30061d}; + */ + uint32_t b[ECC_U32_LENGTH]; /**< parameter B in Montgomery Filed! */ + + /** + * parameter p, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 p = {0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff}; + */ + uint32_t p[ECC_U32_LENGTH]; /**< parameter P in curve */ + + /** + * parameter R ^ 2 mod p, where R = 2 ^ 256, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 R^2 mod p {0x00000004, 0xfffffffd, 0xffffffff, 0xfffffffe, 0xfffffffb, 0xffffffff, 0x00000000, 0x00000003} + */ + uint32_t p_r_square[ECC_U32_LENGTH]; /**< R^2 mod p */ + + /** + * Montgomery multiplication constant for prime p + */ + uint32_t constp; /**< Montgomery multiplication constant for prime p */ + + /** + * parameter p, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 n = {0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xbce6faad, 0xa7179e84, 0xf3b9cac2, 0xfc632551} + */ + uint32_t n[ECC_U32_LENGTH]; /**< NIST P256 n */ + + /** + * parameter R ^ 2 mod n, where R = 2 ^ 256, denoted integer format as ANSI X9.62 - 2005 (Page 27). + * For example NIST P256 R^2 mod n {0x66e12d94, 0xf3d95620, 0x2845b239, 0x2b6bec59, 0x4699799c, 0x49bd6fa6, 0x83244c95, 0xbe79eea2} + */ + uint32_t n_r_square[ECC_U32_LENGTH]; /**< R^2 mod n */ + + /** + * Montgomery multiplication constant for prime n + */ + uint32_t constn; /**< Montgomery multiplication constant for prime n */ + + /** + * parameter h for ecc curve + */ + uint32_t h; /**< parameter h for ecc curve */ + + /** + * generation point for ecc curve + */ + algo_ecc_point_t G; /**< generation point for ecc curve */ + +} algo_ecc_curve_parameter_t; +/** @} */ + +/** @defgroup ECC Config Structurs Definition + * @{ + */ + +/** + * @brief ECC Computation config + * \note It is recommended to set config via API ecc_init_config + */ +typedef struct _algo_ecc_config { + + /* Followings parameters are for Both ECC/RSA */ + /** + * This member MUST BE specified. The default p256 params can be get from ROM + */ + algo_ecc_curve_parameter_t *curve; /**< ecc curve */ + +} algo_ecc_config_t; +/** @} */ + +/** @defgroup ECDSA Config Structurs Definition + * @{ + */ + +/** + * @brief The ECDSA context structure + */ +typedef struct _algo_ecc_ecdsa_config { + + /** + * ECDSA compute options, include curve type. + */ + algo_ecc_config_t calc_options; /**< ecc config options */ + + /** + * ECDSA our secret value, (a random number < n) + */ + uint32_t our_secret_value[ECC_U32_LENGTH]; /** +#include +#include +#include +#include +#include "crypto_ecc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t hw_ecc_rng32(void); +void hw_ecc_point_mul(algo_ecc_config_t *ecc_calc_options, + uint32_t k[ECC_U32_LENGTH], + algo_ecc_point_t *Q, + algo_ecc_point_t *result); +void hw_ecc_sha(const uint8_t *message, uint32_t message_byte_length, uint8_t output[32]); +void hw_ecc_modular_compare(algo_ecc_config_t *ecc_calc_options, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t result[]); +void ecc_modular_inverse(algo_ecc_config_t *ecc_config, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t out_a_inverse[]); +void hw_ecc_montgomery_inverse( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_prime[], uint32_t constp, uint32_t out_x[]); +void hw_ecc_modular_sub( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]); +void hw_ecc_montgomery_mul(algo_ecc_config_t *ecc_calc_options, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t constp, + uint32_t result[]); +void hw_ecc_modular_add( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]); +void ecc_modular_multiply(algo_ecc_config_t *ecc_config, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t out_result[]); +uint32_t ecc_is_infinite_point(algo_ecc_point_t *point); + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_ECC_PORT_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_gcm.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_gcm.h new file mode 100644 index 0000000..9e75515 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_gcm.h @@ -0,0 +1,238 @@ +/** + **************************************************************************************** + * + * @file crypto_gcm.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto GCM library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER + * @{ + */ + +/** @defgroup CRYPTO_GCM GCM + * @brief GCM CRYPTO driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRYPTO_GCM_H__ +#define __CRYPTO_GCM_H__ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "crypto_aes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup CRYPTO_GCM_CONTEXT_STRUCTURES Structures + * @{ + */ + +/** @defgroup GCM Context Structurs Definition + * @{ + */ + +/** + * @brief This defines the structure of gcm context. + */ +typedef struct crypto_gcm_context +{ + crypto_aes_context cipher_ctx; /**< The cipher context used. */ + uint64_t HL[16]; /**< Precalculated HTable low. */ + uint64_t HH[16]; /**< Precalculated HTable high. */ + uint64_t len; /**< The total length of the encrypted data. */ + uint64_t add_len; /**< The total length of the additional data. */ + unsigned char base_ectr[16]; /**< The first ECTR for tag. */ + unsigned char y[16]; /**< The Y working value. */ + unsigned char buf[16]; /**< The buf working value. */ + int mode; /**< The operation to perform: + #AES_ENCRYPT or + #AES_DECRYPT. */ +}crypto_gcm_context; +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRYPTO_GCM_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief crypto gcm init. + * + * @param[in] ctx: gcm context. + * + **************************************************************************************** + */ +void crypto_gcm_init( crypto_gcm_context *ctx ); + +/** + **************************************************************************************** + * @brief crypto gcm set key. + * + * @param[in] ctx: gcm context. + * @param[in] key: encryption/decryption key. + * @param[in] keybits: must be 128, 192 or 256. + * + * @retval ::-1: The gcm set key error. + * @retval ::0: The gcm set key successfully. + **************************************************************************************** + */ +int crypto_gcm_setkey( crypto_gcm_context *ctx, const uint8_t *key, uint32_t keybits ); + +/** + **************************************************************************************** + * @brief start GCM encryption or decryption. + * + * @param[in] ctx: gcm context. + * @param[in] mode: AES_ENCRYPT or AES_DECRYPT. + * @param[in] iv: The initialization vector. + * @param[in] iv_len: The length of the IV. + * @param[in] add: The buffer holding the additional data, or NULL if add_len is 0. + * @param[in] add_len: The length of the additional data. + * + * @retval ::-1: The gcm start error. + * @retval ::0: The gcm start successfully. + **************************************************************************************** + */ +int crypto_gcm_starts( crypto_gcm_context *ctx, int mode, const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len ); + +/** + **************************************************************************************** + * @brief update GCM encryption or decryption buffer. + * + * @param[in] ctx: gcm context. + * @param[in] length: The length of the input data. This must be a multiple of + * 16 except in the last call before crypto_gcm_finish(). + * @param[in] input: The buffer holding the input data. + * @param[out] output: The buffer for holding the output data. + * + * @retval ::-1: The gcm update error. + * @retval ::0: The gcm update successfully. + **************************************************************************************** + */ +int crypto_gcm_update( crypto_gcm_context *ctx, uint32_t length, const uint8_t *input, uint8_t *output ); + +/** + **************************************************************************************** + * @brief GCM generates the authentication tag. + * + * @param[in] ctx: gcm context. + * @param[out] tag: The buffer for holding the tag. + * @param[in] tag_len: The length of the tag to generate. + * + * @retval ::-1: The gcm generates tag error. + * @retval ::0: The gcm generates tag successfully. + **************************************************************************************** + */ +int crypto_gcm_finish( crypto_gcm_context *ctx, uint8_t *tag, uint32_t tag_len ); + +/** + **************************************************************************************** + * @brief crypto gcm free. + * + * @param[in] ctx: gcm context. + * + **************************************************************************************** + */ +void crypto_gcm_free( crypto_gcm_context *ctx ); + +/** + **************************************************************************************** + * @brief GCM encryption or decryption. + * + * @param[in] ctx: gcm context. + * @param[in] mode: AES_ENCRYPT or AES_DECRYPT. + * @param[in] length: The length of the input data. + * @param[in] iv: The initialization vector. + * @param[in] iv_len: The length of the IV. + * @param[in] add: The buffer holding the additional data, or NULL if add_len is 0. + * @param[in] add_len: The length of the additional data. + * @param[in] input: The buffer holding the input data. + * @param[out] output: The buffer for holding the output data. + * @param[out] tag: The buffer for holding the tag. + * @param[in] tag_len: The length of the tag to generate. + * + * @retval ::-1: The gcm encryption or decryption error. + * @retval ::0: The gcm encryption or decryption successfully. + **************************************************************************************** + */ +int crypto_gcm_crypt_and_tag( crypto_gcm_context *ctx, int mode, uint32_t length, + const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len, + const uint8_t *input, uint8_t *output, uint32_t tag_len, uint8_t *tag ); + +/** + **************************************************************************************** + * @brief GCM authenticated decryption. + * + * @param[in] ctx: gcm context. + * @param[in] length: The length of the input data. + * @param[in] iv: The initialization vector. + * @param[in] iv_len: The length of the IV. + * @param[in] add: The buffer holding the additional data, or NULL if add_len is 0. + * @param[in] add_len: The length of the additional data. + * @param[in] tag: The buffer for holding the tag. + * @param[in] tag_len: The length of the tag to generate. + * @param[in] input: The buffer holding the input data. + * @param[out] output: The buffer for holding the output data. + * + * @retval ::-1: The gcm authenticated decryption error. + * @retval ::0: The gcm authenticated decryption successfully. + **************************************************************************************** + */ +int crypto_gcm_auth_decrypt( crypto_gcm_context *ctx, uint32_t length, + const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len, + const uint8_t *tag, uint32_t tag_len, const uint8_t *input, uint8_t *output ); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_GCM_H__ */ + +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc.h new file mode 100644 index 0000000..b8343c3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc.h @@ -0,0 +1,237 @@ +/** + **************************************************************************************** + * + * @file crypto_pkc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto PKC library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +#ifndef __CRYPTO_PKC_H__ +#define __CRYPTO_PKC_H__ + +#include +#include +#include +#include +#include +#include "grx_hal.h" +#include "crypto_ecc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief modular shift operation: result(bits_len bit) = (2 ^ shift_bits) * in_a (bits_len bit) mod in_prime (bits_len bit) + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[in] shift_bits number of shift bits. + * + * \param[out] result bits_len bit output. + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_modular_left_shift_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_prime[], + uint32_t shift_bits, uint32_t result[]); + +/** + * \brief modular compare operation: result(bits_len bit) = in_a(bits_len bit) mod in_prime(bits_len bit) + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[out] result bits_len bit output. + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_modular_compare_handle(uint32_t bits_len, uint32_t in_a[],uint32_t in_prime[], + uint32_t result[]); + +/** + * \brief Montgomery inverse operation: (out_x,outk) = in_a ^(-1) * 2 ^ (out_k) mod in_prime, where bits_len <= out_k <= 2*bits_len + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[out] out_x bits_len bit output. + * + * \param[out] out_k output k (13 bits, denoted by a uint32_t variable). + * + * \return + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_montgomery_inverse(uint32_t bits_len, uint32_t in_a[], uint32_t in_prime[], uint32_t constp, uint32_t out_x[]); + +/** + * \brief compute modular exponent for RSA: result = in_a ^(in_b) mod in_prime + * + * \param[in] bits_len RSA number bit width, hardware supports up to 2048 bits + * + * \param[in] in_a the base number of bits_len bits + * + * \param[in] in_b the exponet number of bits_len bits + * + * \param[in] in_prime the modular number + * + * \param[in] r_square R^2 mod in_prime, where R = 2 ^ bits_len. If this field is NULL, the program will interanly + * compute R^2 mod p and constq, at a cost of performance degradation. + * + * \param[in] constq Montgomery multiplication constant of in_prime + * + * \param[out] result in_a ^(in_b) mod in_prime + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_rsa_modular_exponent_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], + uint32_t in_prime[], uint32_t r_square[], uint32_t constq,uint32_t result[]); + +/** + * \brief Montgomery multiply operation: result = in_a * in_b *R^(-1) mod in_prime, where R = 2^bits_len + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_b second input operand (bits_lenbit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[in] constq Montgomery multiplication constant for in_prime, where constq = (-in_prime[0]) ^(-1) mod 2^32 + * + * \param[out] result bits_len bit output. + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_montgomery_mul(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], + uint32_t constq, uint32_t result[]); + +/** + * \brief set ECC Curve type + * + * \param[in] ECC Curve type. + * + */ +ecc_curve_init_t *pkc_set_curve_p256_params(algo_ecc_curve_type_e curve); + +/** + * \brief Set user defined curve + * + * \param[in] curve ECC curve parameters, for NIST-P256 curve, invokers may fill this parameter with NULL + * Note that hal_pkc_init inits NIST-P256 curve, invokers may ignore this API if only use + * NIST-P256 curve. + * For other curves, invokers must fill the curve parameters \ref ecc_curve_parameter_t + * + */ +void hal_set_curve(ecc_curve_init_t * curve); + +/** + * \brief ECC point multiplication operation based on NIST P256 (also known as SECP256R1) curve. + * If secure mode is set(by hal_pkc_init), anti-DPA security measures will be employed, + * at a cost of performance loss (about 25%-35%) + * + * \param[in] k input 256 bit number. + * + * \param[in] Q input ecc point (x:256 bit, y:256 bit). If #Q is null, then Q point is equal G point + * + * \param[out] result output ecc point (x:256 bit, y:256 bit) -- result = k * point + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_ecc_point_mul_handle(uint32_t k[ECC_U32_LENGTH], ecc_point_t *Q, ecc_point_t *result); + +/** + * \brief modular sub operation: result(256 bit) = in_a(256 bit) - in_b(256 bit) mod in_prime(256 bit) + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_b second input operand (bits_len bit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[out] result bits_len bit output. + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_modular_sub_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], + uint32_t result[]); + +/** + * \brief modular add operation: result(256 bit) = in_a(256 bit) + in_b(256 bit) mod in_prime(256 bit) + * + * \param[in] bits_len number bit-length, support 256, 288, 320, ... up to 2048 bits.(32 bits per step) + * + * \param[in] in_a first input operand (bits_len bit). + * + * \param[in] in_b second input operand (bits_len bit). + * + * \param[in] in_prime input prime (bits_len bit). + * + * \param[out] result bits_len bit output. + * + * \return operation status + * \li \ref HAL_ERROR + * \li \ref HAL_OK + */ +hal_status_t hal_pkc_modular_add_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], + uint32_t result[]); + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_PKC_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc_port.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc_port.h new file mode 100644 index 0000000..f6dd0dd --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_pkc_port.h @@ -0,0 +1,64 @@ +/** + **************************************************************************************** + * + * @file crypto_pkc_port.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto PKC library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +#ifndef __CRYPTO_PKC_PORT_H__ +#define __CRYPTO_PKC_PORT_H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t (*pkc_rng_func_ptr)(void); + +void pkc_setbit(uint32_t q[], uint32_t in_prime[], uint32_t k, uint32_t bits_len); +void pkc_zeroize(void *start_address, uint32_t u32_len); +int32_t pkc_number_compare_to_const(uint32_t a[], uint32_t b, uint32_t bits_len); +uint8_t pkc_safe_compare(pkc_rng_func_ptr rng32, uint32_t *src, uint32_t *dest, uint32_t u32_len); +int32_t pkc_number_compare(uint32_t a[], uint32_t b[], uint32_t bits_len); +void pkc_read_oct_string(uint32_t *big_number, uint8_t* buffer, uint32_t byte_size); + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_PKC_PORT_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_rsa.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_rsa.h new file mode 100644 index 0000000..45fd85e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_rsa.h @@ -0,0 +1,203 @@ +/** + **************************************************************************************** + * + * @file crypto_rsa.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto RSA library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER + * @{ + */ + +/** @defgroup CRYPTO_RSA RSA + * @brief RSA CRYPTO driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRYPTO_RSA_H__ +#define __CRYPTO_RSA_H__ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRYPTO_RSA_MACRO Defines + * @{ + */ + +//#define RSA_OPENSSL_SEQ /**< Open with Openssl sequence.*/ +#define RSA_PKCS1_V21 (1) /**< PKCS1_PSS sign, as defined in PKCS#1_2.1/2.2: same message and private key will produce different result, since random salt is different each time.*/ +#define RSA_PKCS1_V15 (0) /**< PKCS1_V15 sign, same message and private key will produce same result.*/ +#define RSA_U32_LENGTH (64) /** +#include +#include +#include +#include +#include "crypto_rsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t hw_rsa_rng32(void); +void hw_rsa_sha(const uint8_t *message, uint32_t message_byte_length, uint8_t output[32]); +void hw_rsa_modular_left_shift(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t shift_bits, + uint32_t result[]); +void hw_rsa_modular_compare(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t result[]); +void rsa_modular_inverse(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t out_a_inverse[]); +void hw_rsa_montgomery_inverse(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t constp, + uint32_t out_x[]); +void hw_rsa_modular_exponent(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t result[]); +void hw_rsa_montgomery_mul(algo_rsa_config_t *rsa_calc_options, + uint32_t bis_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t constp, + uint32_t result[]); +int rsa_safer_memcmp( const void *a, const void *b, size_t n ); + +/** + * \brief compute modular exponent for RSA: out_result = (in_a ^in_b) mod in_prime + * + * \param[in] rsa_config rsa_config \ref algo_rsa_config_t + * + * \param[in] bits_len bit width of modular number of in_prime, supports up to 2048 bits + * + * \param[in] in_a the base number of bits_len bits + * + * \param[in] in_b the exponent number of bits_len bits; + * + * \param[in] in_prime the modular number + * + * \param[in] r_square R^2 mod in_prime, where R = 2 ^ bits_len + * + * \param[in] constp montgomery multiplication constant of in_prime + * + * \param[out] out_result in_a ^(in_b) mod in_prime + * + * \return + * \li \ref RSA_ERROR_PARAMETER : NULL input pointer + * \li \ref RSA_OK + */ +void rsa_modular_exponent(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + uint32_t out_result[]); + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_RSA_PORT_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_sha256.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_sha256.h new file mode 100644 index 0000000..553cc7d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/inc/crypto_sha256.h @@ -0,0 +1,297 @@ +/** + **************************************************************************************** + * + * @file crypto_sha256.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of crypto SHA256 library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2022 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup CRYPTO_DRIVER CRYPTO DRIVER + * @{ + */ + +/** @defgroup CRYPTO_SHA SHA + * @brief SHA CRYPTO driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRYPTO_SHA256_H__ +#define __CRYPTO_SHA256_H__ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRYPTO_SHA_MACRO Defines + * @{ + */ + +/** + * @brief SHA256 SIZE + */ +#define SHA256_SIZE 32 +/** + * @brief SHA256 MAX SIZE + */ +#define SHA256_MAX_SIZE 32 +/** + * @brief SHA256 BLOCK SIZE + */ +#define SHA256_BLOCK_SIZE 64 +/** + * @brief HMAC-SHA256 KEY SIZE + */ +#define HMAC_SHA256_KEY_SIZE 32 +/** @} */ + +/** @addtogroup CRYPTO_SHA_CONTEXT_STRUCTURES Structures + * @{ + */ + +/** @defgroup SHA Context Structurs Definition + * @{ + */ + +/** + * @brief This defines the structure of sha256 context. + */ +typedef struct crypto_sha256_context +{ + uint32_t total; /**< The number of Bytes processed. */ + uint32_t block_size; /**< block size. */ + uint8_t *input; /**< input data. */ + void *instance; /**< The sha256 instance. */ +} crypto_sha256_context; +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRYPTO_SHA_FUNCTIONS Functions + * @{ + */ + +/** + ******************************************************************************************* + * @brief This function initializes a SHA-256 context. + * + * @param[in] ctx: The SHA-256 context to initialize. This must not be NULL. + * + ******************************************************************************************* + */ +void crypto_sha256_init(crypto_sha256_context *ctx); + +/** + ******************************************************************************************* + * @brief This function clears a SHA-256 context. + * + * @param[in] ctx: The SHA-256 context to clear. This may be NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must point to an initialized + * SHA-256 context. + ******************************************************************************************* + */ +void crypto_sha256_free(crypto_sha256_context *ctx); + +/** + ******************************************************************************************* + * @brief This function clones the state of a SHA-256 context. + * + * @param[out] dst: The destination context. This must be initialized. + * @param[in] src: The context to clone. This must be initialized. + ******************************************************************************************* + */ +void crypto_sha256_clone(crypto_sha256_context *dst, const crypto_sha256_context *src); + +/** + ******************************************************************************************* + * @brief This function starts a SHA-256 calculation. + * + * @param[in] ctx: The SHA-256 context to use. This must be initialized. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_sha256_starts(crypto_sha256_context *ctx); + +/** + ******************************************************************************************* + * @brief This function feeds an input buffer into an ongoing + * SHA-256 calculation. + * + * @param[in] ctx: The SHA-256 context. This must be initialized + * and have a hash operation started. + * @param[in] input: The buffer holding the input data. This must + * be a readable buffer of length \p ilen Bytes. + * @param[in] ilen: The length of the input data in Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_sha256_update(crypto_sha256_context *ctx, const uint8_t *input, size_t ilen); + +/** + ******************************************************************************************* + * @brief This function finishes the SHA-256 operation, and writes + * the result to the output buffer. This function is for + * internal use only. + * + * @param[in] ctx: The SHA-256 context. This must be initialized + * and have a hash operation started. + * @param[out] output: SHA-256 result. + * This must be a writable buffer of length \c 32 Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_sha256_finish(crypto_sha256_context *ctx, uint8_t output[32]); + +/** + ******************************************************************************************* + * @brief This function calculates the SHA-256 into a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The SHA-256 result is calculated as + * output = SHA-256(input buffer). + * + * @param[in] input: The buffer holding the input data. This must be + * a readable buffer of length \p ilen Bytes. + * @param[in] ilen: The length of the input data in Bytes. + * @param[out] output: SHA-256 result. + * This must be a writable buffer of length \c 32 Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_sha256(const uint8_t *input, size_t ilen, uint8_t output[32]); + +/** + ******************************************************************************************* + * @brief This function starts a HMAC-SHA-256 calculation. + * + * @param[in] ctx: The HMAC-SHA-256 context to use. This must be initialized. + * @param[in] key: The HMAC secret key. + * @param[in] keylen: The length of the HMAC key in Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_hmac_sha256_starts(crypto_sha256_context *ctx, const uint8_t *key, size_t keylen); + +/** + ******************************************************************************************* + * @brief This function feeds an input buffer into an ongoing + * HMAC-SHA-256 calculation. + * + * @param[in] ctx: The HMAC-SHA-256 context. This must be initialized + * and have a hash operation started. + * @param[in] input: The buffer holding the input data. This must + * be a readable buffer of length \p ilen Bytes. + * @param[in] ilen: The length of the input data in Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_hmac_sha256_update(crypto_sha256_context *ctx, const uint8_t *input, size_t ilen); + +/** + ******************************************************************************************* + * @brief This function finishes the HMAC-SHA-256 operation, and + * writes the result to the output buffer. This function is for + * is forinternal use only. + * + * @param[in] ctx: The HMAC-SHA-256 context. This must be initialized + * and have a hash operation started. + * @param[out] output: HMAC-SHA-256 checksum result. + * This must be a writable buffer of length \c 32 Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_hmac_sha256_finish(crypto_sha256_context *ctx, uint8_t output[32]); + +/** + ******************************************************************************************* + * @brief This function calculates the HMAC-SHA-256 into a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The HMAC-SHA-256 result is calculated as + * output = HMAC-SHA-256(input buffer). + * + * @param[in] key: The HMAC secret key. + * @param[in] keylen: The length of the HMAC key in Bytes. + * @param[in] input: The buffer holding the input data. This must be + * a readable buffer of length \p ilen Bytes. + * @param[in] ilen: The length of the input data in Bytes. + * @param[out] output: HMAC-SHA-256 result. + * This must be a writable buffer of length \c 32 Bytes. + * + * @retval::-1:NULL input pointer. + * @retval::0: execute successfully. + ******************************************************************************************* + */ +int crypto_hmac_sha256(const uint8_t *key, size_t keylen, const uint8_t *input, size_t ilen, uint8_t output[32]); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRYPTO_SHA256_H__ */ + +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_aes.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_aes.c new file mode 100644 index 0000000..41621a6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_aes.c @@ -0,0 +1,615 @@ +#include "crypto_aes.h" +#include "grx_hal.h" + +#define crypto_malloc malloc +#define crypto_free free + +typedef struct +{ + uint8_t seed[AES_BLOCK_SIZE]; + aes_handle_t aes_handle; +} aes_instance_t; + +/* + * AES context init + */ +void crypto_aes_init(crypto_aes_context *ctx) +{ + if (ctx == NULL) + { + return; + } + + memset(ctx, 0x0, sizeof(crypto_aes_context)); + + ctx->instance = crypto_malloc(sizeof(aes_instance_t)); + + if (NULL == ctx->instance) + { + return; + } + + memset(ctx->instance, 0, sizeof(aes_instance_t)); +} + +/* + * AES context free + */ +void crypto_aes_free(crypto_aes_context *ctx) +{ + if (ctx == NULL) + { + return; + } + + if (ctx->instance) + { + crypto_free(ctx->instance); + } +} + +/* + * AES set paddings mode + */ +int crypto_aes_set_paddings(crypto_aes_context *ctx, crypto_aes_padding_t padding_type) +{ + if (ctx == NULL) + { + return -1; + } + ctx->padding_mode = padding_type; + return 0; +} + +static void aes_hardware_reset(void) +{ + CLEAR_BITS(MCU_SUB->SECURITY_RESET, MCU_SUB_SECURITY_RESET_AES); + SET_BITS(MCU_SUB->SECURITY_RESET, MCU_SUB_SECURITY_RESET_AES); +} + +static int crypto_set_aes_key(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits) +{ + int8_t ret = 0; + if (ctx == NULL || key == NULL || ctx->instance == NULL) + { + return -1; + } + + memset(ctx->key, 0, AES_MAX_KEY_SIZE); + memcpy(ctx->key, key, keybits >> 3); + ctx->keybits = keybits; + + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + switch (ctx->keybits) + { + case 128: + p_aes_handle->init.key_size = AES_KEYSIZE_128BITS; + break; + case 192: + p_aes_handle->init.key_size = AES_KEYSIZE_192BITS; + break; + case 256: + p_aes_handle->init.key_size = AES_KEYSIZE_256BITS; + break; + default: + ret = -1; + break; + } + + p_aes_handle->init.p_key = (uint32_t *)ctx->key; + + return ret; +} + +/* + * AES key schedule (encryption) + */ +int crypto_aes_setkey_enc(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits) +{ + return crypto_set_aes_key(ctx, key, keybits); +} + +/* + * AES key schedule (decryption) + */ +int crypto_aes_setkey_dec(crypto_aes_context *ctx, uint8_t *key, uint16_t keybits) +{ + return crypto_set_aes_key(ctx, key, keybits); +} + +/* + * pkcs7 padding + */ +int crypto_aes_pkcs7_padding(uint8_t *input, uint32_t length, uint8_t *output) +{ + if (input == NULL || output == NULL) + { + return -1; + } + + uint32_t out_len = ((length >> 4) + 1) * AES_BLOCK_SIZE; + int padding_value = AES_BLOCK_SIZE - (length & 0xF); + + if (input != output) + { + for (uint32_t i = 0; i < length; i++) + { + output[i] = input[i]; + } + } + + for (uint32_t i = length; i < out_len; i++) + { + output[i] = padding_value; + } + + return out_len; +} + +/* + * zero padding + */ +int crypto_aes_zero_padding(uint8_t *input, uint32_t length, uint8_t *output) +{ + if (input == NULL || output == NULL) + { + return -1; + } + + uint32_t out_len = ((length >> 4) + 1) * AES_BLOCK_SIZE; + + if (input != output) + { + for (uint32_t i = 0; i < length; i++) + { + output[i] = input[i]; + } + } + + for (uint32_t i = length; i < out_len; i++) + { + output[i] = 0; + } + + return out_len; +} + +/* + * get output length + */ +uint32_t crypto_aes_get_output_length(uint32_t length, crypto_aes_padding_t padding_type) +{ + if (PADDING_NONE == padding_type) + { + return length; + } + + return ((length >> 4) + 1) * AES_BLOCK_SIZE; +} + +/* + * AES-ECB buffer encryption/decryption + */ +static int crypto_internal_aes_ecb_crypt(crypto_aes_context *ctx, + uint8_t mode, + uint8_t *input, + uint32_t length, + uint8_t *output) +{ + int ret = 0; + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_ECB; + p_aes_handle->init.p_init_vector = NULL; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + if (mode == AES_ENCRYPT) + { + if (HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)input, length, (uint32_t *)output, 5000)) + { + ret = -1; + goto exit; + } + } + else + { + if (HAL_OK != hal_aes_ecb_decrypt(p_aes_handle, (uint32_t *)input, length, (uint32_t *)output, 5000)) + { + ret = -1; + goto exit; + } + } + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return ret; +} + +/* + * AES-ECB block encryption/decryption + */ +int crypto_aes_crypt_ecb(crypto_aes_context *ctx, uint8_t mode, uint8_t *input, uint32_t length, uint8_t *output) +{ + int ret = 0; + + uint32_t compute_len = 0; + uint8_t padding_len = 0; + + uint8_t padding_temp[AES_BLOCK_SIZE] = {0}; + + uint8_t *p_input = input; + uint8_t *p_output = output; + + if (ctx == NULL || input == NULL || output == NULL || mode > 1 || length == 0) + { + return -1; + } + + compute_len = length & (~0xF); + padding_len = length & 0xF; + + if ((ctx->padding_mode == PADDING_NONE) && padding_len) + { + return -1; + } + + if (0 != crypto_internal_aes_ecb_crypt(ctx, mode, p_input, compute_len, p_output)) + { + return -1; + } + + if (PADDING_NONE == ctx->padding_mode) + { + return 0; + } + + p_input += compute_len; + p_output += compute_len; + + if (PADDING_ZEROS == ctx->padding_mode) + { + crypto_aes_zero_padding(p_input, padding_len, padding_temp); + } + else if (PADDING_PKCS7 == ctx->padding_mode) + { + crypto_aes_pkcs7_padding(p_input, padding_len, padding_temp); + } + else + { + ret = -1; + } + + if (0 != ret) + { + return ret; + } + + if (0 != crypto_internal_aes_ecb_crypt(ctx, mode, padding_temp, AES_BLOCK_SIZE, p_output)) + { + return -1; + } + + return ret; +} + +/* + * AES-CBC buffer encryption/decryption + */ +static int crypto_internal_aes_cbc_crypt(crypto_aes_context *ctx, + uint8_t mode, + uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *input, + uint32_t length, + uint8_t *output) +{ + int ret = 0; + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_CBC; + p_aes_handle->init.p_init_vector = (uint32_t *)iv; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + if (mode == AES_ENCRYPT) + { + if (HAL_OK != hal_aes_cbc_encrypt(p_aes_handle, (uint32_t *)input, length, (uint32_t *)output, 5000)) + { + ret = -1; + goto exit; + } + } + else + { + if (HAL_OK != hal_aes_cbc_decrypt(p_aes_handle, (uint32_t *)input, length, (uint32_t *)output, 5000)) + { + ret = -1; + goto exit; + } + } + + if (mode == AES_ENCRYPT) + { + memcpy(iv, output + length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + else + { + memcpy(iv, input + length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return ret; +} + +/* + * AES-CBC buffer encryption/decryption + */ +int crypto_aes_crypt_cbc(crypto_aes_context *ctx, uint8_t mode, uint8_t iv[16], uint8_t *input, uint32_t length, uint8_t *output) +{ + int ret = 0; + + uint32_t compute_len = 0; + uint8_t padding_len = 0; + + uint8_t padding_temp[AES_BLOCK_SIZE] = {0}; + + uint8_t *p_input = input; + uint8_t *p_output = output; + + if (ctx == NULL || input == NULL || output == NULL || mode > 1 || length == 0) + { + return -1; + } + + compute_len = length & (~0xF); + padding_len = length & 0xF; + + if ((ctx->padding_mode == PADDING_NONE) && padding_len) + { + return -1; + } + + if (0 != crypto_internal_aes_cbc_crypt(ctx, mode, iv, p_input, compute_len, p_output)) + { + return -1; + } + + if (PADDING_NONE == ctx->padding_mode) + { + return 0; + } + + p_input += compute_len; + p_output += compute_len; + + if (PADDING_ZEROS == ctx->padding_mode) + { + crypto_aes_zero_padding(p_input, padding_len, padding_temp); + } + else if (PADDING_PKCS7 == ctx->padding_mode) + { + crypto_aes_pkcs7_padding(p_input, padding_len, padding_temp); + } + else + { + ret = -1; + } + + if (0 != ret) + { + return ret; + } + + if (0 != crypto_internal_aes_cbc_crypt(ctx, mode, iv, padding_temp, AES_BLOCK_SIZE, p_output)) + { + return -1; + } + + return ret; +} + +/* + * AES-CTR buffer encryption/decryption + */ +int crypto_aes_crypt_ctr(crypto_aes_context *ctx, uint32_t length, uint32_t *nc_off, + uint8_t nonce_counter[16], uint8_t stream_block[16], const uint8_t *input, uint8_t *output) +{ + int c, i; + size_t n; + + if (ctx == NULL || nc_off == NULL || nonce_counter == NULL || stream_block == NULL || input == NULL || output == NULL) + { + return ( -1 ); + } + + int ret = 0; + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_ECB; + p_aes_handle->init.p_init_vector = NULL; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + n = *nc_off; + + if ( n > 0x0F ) + return ( -1 ); + + while( length-- ) + { + if( n == 0 ) { + if ( HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)nonce_counter, 16, (uint32_t *)stream_block, 5000) ) + { + ret = -1; + goto exit; + } + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return( ret ); +} + +/* + * AES-CFB128 buffer encryption/decryption + */ +int crypto_aes_crypt_cfb128(crypto_aes_context *ctx, uint8_t mode, uint32_t length, uint32_t *iv_off, + uint8_t iv[16], const uint8_t *input, uint8_t *output) +{ + int c; + size_t n; + + if (ctx == NULL || mode > 1 || iv_off == NULL || iv == NULL || input == NULL || output == NULL) + { + return ( -1 ); + } + + int ret = 0; + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_ECB; + p_aes_handle->init.p_init_vector = NULL; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + n = *iv_off; + + if( n > 15 ) + return ( -1 ); + + if( mode == AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + { + if ( HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)iv, 16, (uint32_t *)iv, 5000) ) + { + ret = -1; + goto exit; + } + } + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + { + if ( HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)iv, 16, (uint32_t *)iv, 5000) ) + { + ret = -1; + goto exit; + } + } + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return( ret ); +} + +/* + * AES-OFB (Output Feedback Mode) buffer encryption/decryption + */ +int crypto_aes_crypt_ofb(crypto_aes_context *ctx, uint32_t length, uint32_t *iv_off, + uint8_t iv[16], const uint8_t *input, uint8_t *output) +{ + int ret = 0; + size_t n; + + if (ctx == NULL || iv_off == NULL || iv == NULL || input == NULL || output == NULL) + { + return ( -1 ); + } + + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_ECB; + p_aes_handle->init.p_init_vector = NULL; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + n = *iv_off; + + if( n > 15 ) + return ( -1 ); + + while( length-- ) + { + if( n == 0 ) + { + if ( HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)iv, 16, (uint32_t *)iv, 5000) ) + { + ret = -1; + goto exit; + } + } + *output++ = *input++ ^ iv[n]; + + n = ( n + 1 ) & 0x0F; + } + + *iv_off = n; + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return( ret ); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc.c new file mode 100644 index 0000000..e177f27 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc.c @@ -0,0 +1,651 @@ +#include "crypto_ecc.h" +#include "crypto_pkc.h" +#include "crypto_pkc_port.h" +#include "crypto_ecc_port.h" + +static bool ecc_is_zero_value(uint32_t *value, uint32_t len) +{ + for (int i = 0; i < len; i++) + { + if (value[i]) + { + return false; + } + } + + return true; +} + +static void ecc_init_config(algo_ecc_config_t *ecc_config, algo_ecc_curve_type_e curve) +{ + if (NULL == ecc_config) + { + return; + } + + ecc_config->curve = (algo_ecc_curve_parameter_t *)pkc_set_curve_p256_params(curve); +} + +void crypto_ecc_ecdsa_init(algo_ecc_ecdsa_config_t *ecdsa_data, algo_ecc_curve_type_e curve) +{ + if (NULL == ecdsa_data) + { + return; + } + + pkc_zeroize((void *)(&ecdsa_data->our_public_point), sizeof(algo_ecc_point_t) / 4); + pkc_zeroize((void *)(&ecdsa_data->our_secret_value), ECC_U32_LENGTH); + pkc_zeroize((void *)(&ecdsa_data->k), ECC_U32_LENGTH); + + ecc_init_config(&ecdsa_data->calc_options, curve); +} + +static void ecc_gen_rng(algo_ecc_config_t *ecc_config, uint32_t out[]) +{ + if (NULL == ecc_config) + { + return; + } + + uint32_t i = 0; + uint32_t *n = (uint32_t *)(ecc_config->curve->n); + + for (i = 0; i < ECC_U32_LENGTH; i++) + { + out[i] = hw_ecc_rng32(); + } + +#if 0 + if (out[ECC_U32_LENGTH - 1] >= n[ECC_U32_LENGTH - 1]) + { + out[ECC_U32_LENGTH - 1] = n[ECC_U32_LENGTH - 1] - 1; + } + + out[0] |= 2; +#else + // since the n defined as big endian + if (out[0] >= n[0]) + { + out[0] = n[0] - 1; + } + + out[ECC_U32_LENGTH - 1] |= 2; +#endif +} + +algo_ecc_ret_e crypto_ecc_ecdsa_gen_secret_and_public(algo_ecc_ecdsa_config_t *ecdsa_data) +{ + + uint32_t i = 0; + uint8_t ret = 0; + + if (NULL == ecdsa_data || NULL == ecdsa_data->calc_options.curve) + { + return ECC_ERROR_PARAMETER; + } + + for (i = 0; i < ECC_U32_LENGTH; i++) + { + if (ecdsa_data->our_secret_value[i] == 0) + { + ecdsa_data->our_secret_value[i] = hw_ecc_rng32(); + ret = 1; + } + } + + // make sure 1 < our_secret_value < n + if (ret == 1) + { + ecc_gen_rng(&ecdsa_data->calc_options, ecdsa_data->our_secret_value); + } + + hw_ecc_point_mul(&ecdsa_data->calc_options, ecdsa_data->our_secret_value, NULL, &ecdsa_data->our_public_point); + return ECC_OK; +} + +// s = (e + r1*d1 + r2 * d2)* ke_inverse + (r1 * d2 + r2 * d1) * ke_inverse +static void secure_calc_signature_s(algo_ecc_config_t *ecc_config, + uint32_t random_r1[ECC_U32_LENGTH], + uint32_t random_d1[ECC_U32_LENGTH], + uint32_t ke[ECC_U32_LENGTH], + uint32_t private_key[ECC_U32_LENGTH], + uint32_t e[ECC_U32_LENGTH], + uint32_t r[ECC_U32_LENGTH], + algo_ecc_curve_parameter_t *ecc_curve, + uint32_t out_sig_s[ECC_U32_LENGTH]) +{ + if (NULL == ecc_config || NULL == random_r1 || NULL == random_d1 || NULL == ke || NULL == private_key || NULL == e || NULL == r || NULL == out_sig_s || NULL == ecc_curve) + { + return; + } + + uint32_t ke_inverse[ECC_U32_LENGTH] = { 0 }; + uint32_t r2[ECC_U32_LENGTH] = { 0 }; + uint32_t d2[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp1[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp2[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp_rd1[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp_rd2[ECC_U32_LENGTH] = { 0 }; + + ecc_modular_inverse(ecc_config, ke, ecc_curve->n, ecc_curve->n_r_square, ecc_curve->constn, ke_inverse); + + // calc d2 = d - d1 + hw_ecc_modular_sub(ecc_config, private_key, random_d1, ecc_curve->n, d2); + + // calc r2 = r - r1 + hw_ecc_modular_sub(ecc_config, r, random_r1, ecc_curve->n, r2); + + // calc tmp_rd1 = r1 * d1 + hw_ecc_montgomery_mul(ecc_config, random_r1, random_d1, ecc_curve->n, ecc_curve->constn, tmp_rd1); + hw_ecc_montgomery_mul(ecc_config, tmp_rd1, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp_rd1); + + // calc tmp_rd2 = r2 * d2 + hw_ecc_montgomery_mul(ecc_config, r2, d2, ecc_curve->n, ecc_curve->constn, tmp_rd2); + hw_ecc_montgomery_mul(ecc_config, tmp_rd2, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp_rd2); + + // calc tmp1 = e + r1d1 + r2d2 + hw_ecc_modular_add(ecc_config, e, tmp_rd1, ecc_curve->n, tmp1); + hw_ecc_modular_add(ecc_config, tmp1, tmp_rd2, ecc_curve->n, tmp1); + + // calc tmp1 = (e + r1d1 + r2d2) * ke_inverse + hw_ecc_montgomery_mul(ecc_config, tmp1, ke_inverse, ecc_curve->n, ecc_curve->constn, tmp1); + hw_ecc_montgomery_mul(ecc_config, tmp1, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp1); + + ////Next Step. + // calc tmp_rd1 = r1 * d2 + hw_ecc_montgomery_mul(ecc_config, random_r1, d2, ecc_curve->n, ecc_curve->constn, tmp_rd1); + hw_ecc_montgomery_mul(ecc_config, tmp_rd1, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp_rd1); + + // calc tmp_rd2 = r2 * d1 + hw_ecc_montgomery_mul(ecc_config, r2, random_d1, ecc_curve->n, ecc_curve->constn, tmp_rd2); + hw_ecc_montgomery_mul(ecc_config, tmp_rd2, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp_rd2); + + // calc tmp2 = r1d1 + r2d2 + hw_ecc_modular_add(ecc_config, tmp_rd1, tmp_rd2, ecc_curve->n, tmp2); + + // calc tmp2 = (r1d2 + r2d1) * ke_inverse + hw_ecc_montgomery_mul(ecc_config, tmp2, ke_inverse, ecc_curve->n, ecc_curve->constn, tmp2); + hw_ecc_montgomery_mul(ecc_config, tmp2, ecc_curve->n_r_square, ecc_curve->n, ecc_curve->constn, tmp2); + + ////Final Step. + // calc s = tmp1 + tmp2 + hw_ecc_modular_add(ecc_config, tmp1, tmp2, ecc_curve->n, out_sig_s); +} + +static algo_ecc_ret_e ecc_ecdsa_sign_with_hash(algo_ecc_ecdsa_config_t *ecdsa_calc_options, + uint8_t *message_hash, + uint32_t out_signiture_r[ECC_U32_LENGTH], + uint32_t out_signiture_s[ECC_U32_LENGTH]) +{ + algo_ecc_ret_e err = ECC_OK; + uint32_t ke[ECC_U32_LENGTH] = { 0 }; + algo_ecc_point_t R = { { 0 }, { 0 } }; + uint32_t message_hash_bignumber[ECC_U32_LENGTH] = { 0 }; + uint32_t s1[ECC_U32_LENGTH] = { 0 }; + uint32_t s2[ECC_U32_LENGTH] = { 0 }; + uint32_t ke_backup[ECC_U32_LENGTH] = { 0 }; + algo_ecc_curve_parameter_t *ecc_curve = NULL; + uint32_t temp = 0; + + if (NULL == ecdsa_calc_options) + { + return ECC_ERROR_PARAMETER; + } + + ecc_curve = (ecdsa_calc_options->calc_options.curve); + + if (NULL == ecc_curve || NULL == message_hash || NULL == out_signiture_r || NULL == out_signiture_s) + { + return ECC_ERROR_PARAMETER; + } + + pkc_read_oct_string((uint32_t *)message_hash_bignumber, message_hash, ECC_U32_LENGTH * 4); + + for (int i = 0; i < (ECC_U32_LENGTH/2); i++) + { + temp = message_hash_bignumber[i]; + message_hash_bignumber[i] = message_hash_bignumber[ECC_U32_LENGTH - 1 - i]; + message_hash_bignumber[ECC_U32_LENGTH - 1 - i] = temp; + } + + do + { + uint32_t random_r1[ECC_U32_LENGTH] = { 0 }; + uint32_t random_d1[ECC_U32_LENGTH] = { 0 }; + uint32_t random_r2[ECC_U32_LENGTH] = { 0 }; + uint32_t random_d2[ECC_U32_LENGTH] = { 0 }; + + if (ecc_is_zero_value(ecdsa_calc_options->k, ECC_U32_LENGTH)) + { + // not indicate a k value, we random generate + ecc_gen_rng(&ecdsa_calc_options->calc_options, ecdsa_calc_options->k); + memcpy(ke, ecdsa_calc_options->k, ECC_U32_LENGTH * 4); + } + + memcpy(ke_backup, ke, ECC_U32_LENGTH * 4); + + // Step 1 Gen ke = SHA(message_hash || private_key || "ECDSA_SIGN_KEY"); + + ecc_gen_rng(&ecdsa_calc_options->calc_options, random_r1); + ecc_gen_rng(&ecdsa_calc_options->calc_options, random_d1); + ecc_gen_rng(&ecdsa_calc_options->calc_options, random_r2); + ecc_gen_rng(&ecdsa_calc_options->calc_options, random_d2); + + // step 2. calc R = ke * G + hw_ecc_point_mul(&ecdsa_calc_options->calc_options, ke, NULL, &R); + + hw_ecc_modular_compare(&ecdsa_calc_options->calc_options, R.x, ecc_curve->n, out_signiture_r); // print_ecc_data("R.x",R.x); + + hw_ecc_modular_compare( + &ecdsa_calc_options->calc_options, message_hash_bignumber, ecc_curve->n, message_hash_bignumber); + + secure_calc_signature_s( + &ecdsa_calc_options->calc_options, random_r1, random_d1, ke, ecdsa_calc_options->our_secret_value, message_hash_bignumber, out_signiture_r, ecc_curve, s1); + + memcpy(ke, ke_backup, ECC_U32_LENGTH * 4); + secure_calc_signature_s( + &ecdsa_calc_options->calc_options, random_r2, random_d2, ke, ecdsa_calc_options->our_secret_value, message_hash_bignumber, out_signiture_r, ecc_curve, s2); + + if (pkc_safe_compare(hw_ecc_rng32, s1, s2, ECC_U32_LENGTH) == 0) + { + err = ECC_OK; + } + else + { + err = ECC_ERROR_SIGN; + break; + } + // compare s, 0; + if (pkc_number_compare_to_const(s1, 0, 256) == 0) + { + err = ECC_ERROR_SIGN; + break; + } + + memcpy(out_signiture_s, s1, ECC_U32_LENGTH * 4); + + } while (0); + + if (ECC_OK != err) + { + pkc_zeroize((void *)out_signiture_s, ECC_U32_LENGTH); + pkc_zeroize((void *)out_signiture_r, ECC_U32_LENGTH); + pkc_zeroize((void *)ke, ECC_U32_LENGTH); + pkc_zeroize((void *)ke_backup, ECC_U32_LENGTH); + } + + pkc_zeroize((void *)s1, ECC_U32_LENGTH); + pkc_zeroize((void *)s2, ECC_U32_LENGTH); + + return err; +} + +algo_ecc_ret_e crypto_ecc_ecdsa_sign(algo_ecc_ecdsa_config_t *ecdsa_calc_options, + uint8_t hash_func, + uint8_t *message, + uint32_t message_byte_length, + uint32_t out_signiture_r[ECC_U32_LENGTH], + uint32_t out_signiture_s[ECC_U32_LENGTH]) +{ + + uint8_t hash[ECC_U32_LENGTH * 4] = { 0 }; + + if (NULL == ecdsa_calc_options || NULL == message) + { + return ECC_ERROR_PARAMETER; + } + + switch (hash_func) + { + case ECC_HASH_NONE: + memcpy(hash, message, message_byte_length); + break; + case ECC_HASH_SHA_256: + hw_ecc_sha(message, message_byte_length, (uint8_t *)hash); + break; + default: + return ECC_ERROR_PARAMETER; + } + + return ecc_ecdsa_sign_with_hash(ecdsa_calc_options, hash, out_signiture_r, out_signiture_s); +} + +static algo_ecc_ret_e ecc_is_point_on_curve(algo_ecc_config_t *ecc_calc_options, algo_ecc_point_t *Q) +{ + + uint32_t xr[ECC_U32_LENGTH] = { 0 }; + uint32_t yr[ECC_U32_LENGTH] = { 0 }; + uint32_t x3[ECC_U32_LENGTH] = { 0 }; + uint32_t ax[ECC_U32_LENGTH] = { 0 }; + uint32_t x3_ax_b[ECC_U32_LENGTH] = { 0 }; + uint32_t y2[ECC_U32_LENGTH] = { 0 }; + algo_ecc_curve_parameter_t *ecc_curve = NULL; + + if (NULL == ecc_calc_options && NULL == ecc_calc_options->curve && NULL == Q) + { + return ECC_ERROR_PARAMETER; + } + ecc_curve = ecc_calc_options->curve; + + // To montgomery field + hw_ecc_montgomery_mul(ecc_calc_options, Q->x, ecc_curve->p_r_square, ecc_curve->p, ecc_curve->constp, xr); + hw_ecc_montgomery_mul(ecc_calc_options, Q->y, ecc_curve->p_r_square, ecc_curve->p, ecc_curve->constp, yr); + + // calc x^3 + ax + b + hw_ecc_montgomery_mul(ecc_calc_options, xr, xr, ecc_curve->p, ecc_curve->constp, x3); + hw_ecc_montgomery_mul(ecc_calc_options, x3, xr, ecc_curve->p, ecc_curve->constp, x3); + hw_ecc_montgomery_mul(ecc_calc_options, xr, ecc_curve->a, ecc_curve->p, ecc_curve->constp, ax); + hw_ecc_modular_add(ecc_calc_options, x3, ax, ecc_curve->p, x3_ax_b); + hw_ecc_modular_add(ecc_calc_options, x3_ax_b, ecc_curve->b, ecc_curve->p, x3_ax_b); + + // calc y^2 + hw_ecc_montgomery_mul(ecc_calc_options, yr, yr, ecc_curve->p, ecc_curve->constp, y2); + + if (pkc_number_compare(x3_ax_b, y2, 256) == 0) + { + return ECC_OK; + } + + return ECC_ERROR_POINT_NOT_ON_CURVE; +} + +static void ecc_point_addition(algo_ecc_config_t *ecc_config, + algo_ecc_point_t *pointA, + algo_ecc_point_t *pointB, + algo_ecc_point_t *out_result) +{ + + uint32_t s[ECC_U32_LENGTH] = { 0 }; + uint32_t temp[ECC_U32_LENGTH] = { 0 }; + uint32_t temp2[ECC_U32_LENGTH] = { 0 }; + uint32_t temp3[ECC_U32_LENGTH] = { 0 }; + + if (NULL == ecc_config) + { + return; + } + + algo_ecc_curve_parameter_t *ecc_curve = (algo_ecc_curve_parameter_t *)(ecc_config->curve); + + // check input parameters + if (NULL == pointA || NULL == pointB || NULL == out_result || NULL == ecc_curve) + { + return; + } + + if (ecc_is_infinite_point(pointA)) + { + memcpy(out_result, pointB, sizeof(algo_ecc_point_t)); + return; + } + + if (ecc_is_infinite_point(pointB)) + { + memcpy(out_result, pointA, sizeof(algo_ecc_point_t)); + return; + } + + if (memcmp(pointA, pointB, sizeof(algo_ecc_point_t)) == 0) + { + if (pkc_number_compare_to_const(pointA->y, 0, 256) == 0) + { + // point of infinite + memset(out_result, 0, sizeof(algo_ecc_point_t)); + return; + } + else + { + // s = (3*(x1^2) + a)/(2*y1) mod p + uint32_t tmp[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp_backup[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp2[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp3[ECC_U32_LENGTH] = { 0 }; + uint32_t number2[ECC_U32_LENGTH] = { 2, 0, 0, 0, 0, 0, 0, 0 }; + uint32_t number3[ECC_U32_LENGTH] = { 3, 0, 0, 0, 0, 0, 0, 0 }; + + // calc tmp = x1 ^ 2 + ecc_modular_multiply( + ecc_config, pointA->x, pointA->x, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, tmp); + + // calc tmp2 = 3 * tmp = 3*(x1^2) + ecc_modular_multiply( + ecc_config, number3, tmp, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, tmp2); + + // calc tmp3 = tmp2 + a = tmp2 - 3 = 3*(x1^2) - 3; + hw_ecc_modular_sub(ecc_config, tmp2, number3, ecc_curve->p, tmp3); + + // calc tmp = 2* y1; + ecc_modular_multiply( + ecc_config, number2, pointA->y, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, tmp); + + // calc tmp2 = tmp ^(-1) = (2y1)^(-1); + memcpy(tmp_backup, tmp, 32); + ecc_modular_inverse(ecc_config, tmp, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, tmp2); + memcpy(tmp, tmp_backup, 32); + + // calc s = tmp3 * tmp2; + ecc_modular_multiply(ecc_config, tmp3, tmp2, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, s); + } + } + else + { + // point addition: s = (y2-y1)/(x2-x1) + if (memcmp(pointA->x, pointB->x, sizeof(algo_ecc_point_t)) == 0) + { + // return point of infinite + memset(out_result, 0, sizeof(algo_ecc_point_t)); + return; + } + else + { + // s = (y2-y1)/(x2-x1) mod p + uint32_t tmp[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp2[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp3[ECC_U32_LENGTH] = { 0 }; + + // tmp = y2-y1; + hw_ecc_modular_sub(ecc_config, pointB->y, pointA->y, ecc_curve->p, tmp); + + // tmp2 = x2-x1; + hw_ecc_modular_sub(ecc_config, pointB->x, pointA->x, ecc_curve->p, tmp2); + + // tmp3 = tmp2 ^(-1) = (x2-x1)^(-1); + ecc_modular_inverse(ecc_config, tmp2, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, tmp3); + + // s = tmp * tmp3 = (y2-y1)*((x2-x1)^(-1)) + ecc_modular_multiply(ecc_config, tmp, tmp3, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, s); + } + } + + // calc (x3,y3) + // x3 = s^2 - x1 - x2; + // y3 = s(x1-x3) - y1 + // temp = s^2 + ecc_modular_multiply(ecc_config, s, s, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, temp); + + // temp2 = temp - x1; + hw_ecc_modular_sub(ecc_config, temp, pointA->x, ecc_curve->p, temp2); + + // x3 = temp2 - x2; + hw_ecc_modular_sub(ecc_config, temp2, pointB->x, ecc_curve->p, out_result->x); + + // temp3 = x1 - x3; + hw_ecc_modular_sub(ecc_config, pointA->x, out_result->x, ecc_curve->p, temp3); + + // temp2 = s * temp3 = s(x1-x3); + ecc_modular_multiply(ecc_config, s, temp3, ecc_curve->p, ecc_curve->p_r_square, ecc_curve->constp, temp2); + + // y3 = temp2 - y1 = s(x1-x3) - y1; + hw_ecc_modular_sub(ecc_config, temp2, pointA->y, ecc_curve->p, out_result->y); +} + +static algo_ecc_ret_e ecc_ecdsa_verify_with_hash(algo_ecc_ecdsa_config_t *ecdsa_calc_options, + uint8_t *message_hash, + uint32_t in_signiture_r[ECC_U32_LENGTH], + uint32_t in_signiture_s[ECC_U32_LENGTH]) +{ + algo_ecc_ret_e err = ECC_OK; + uint32_t t2[ECC_U32_LENGTH] = { 0 }; + uint32_t tmp_rd1[ECC_U32_LENGTH] = { 0 }; + uint32_t u1[ECC_U32_LENGTH] = { 0 }; + uint32_t u2[ECC_U32_LENGTH] = { 0 }; + uint32_t r[ECC_U32_LENGTH] = { 0 }; + uint32_t s[ECC_U32_LENGTH] = { 0 }; + uint32_t x[ECC_U32_LENGTH] = { 0 }; + uint32_t message_hash_bignumber[ECC_U32_LENGTH] = { 0 }; + algo_ecc_point_t A = { { 0 }, { 0 } }; + algo_ecc_point_t u1G = { { 0 }, { 0 } }; + algo_ecc_point_t u2Q = { { 0 }, { 0 } }; + uint32_t temp = 0; + + if (NULL == ecdsa_calc_options) + { + return ECC_ERROR_PARAMETER; + } + algo_ecc_curve_parameter_t *ecc_curve = ecdsa_calc_options->calc_options.curve; + + if (NULL == ecc_curve || NULL == in_signiture_r || NULL == in_signiture_s) + { + return ECC_ERROR_PARAMETER; + } + pkc_read_oct_string((uint32_t *)message_hash_bignumber, (uint8_t *)message_hash, ECC_U32_LENGTH * 4); + for (int i = 0; i < (ECC_U32_LENGTH/2); i++) + { + temp = message_hash_bignumber[i]; + message_hash_bignumber[i] = message_hash_bignumber[ECC_U32_LENGTH - 1 - i]; + message_hash_bignumber[ECC_U32_LENGTH - 1 - i] = temp; + } + + do + { + hw_ecc_modular_compare(&ecdsa_calc_options->calc_options, in_signiture_r, ecc_curve->n, r); + hw_ecc_modular_compare(&ecdsa_calc_options->calc_options, in_signiture_s, ecc_curve->n, s); + + if (pkc_number_compare_to_const(in_signiture_r, 0, 256) == 0) + { + err = ECC_ERROR_VERIFY; + break; + } + + hw_ecc_modular_compare( + &ecdsa_calc_options->calc_options, message_hash_bignumber, ecc_curve->n, tmp_rd1); + + ecc_modular_inverse(&ecdsa_calc_options->calc_options, s, ecc_curve->n, ecc_curve->n_r_square, ecc_curve->constn, t2); + + ecc_modular_multiply( + &ecdsa_calc_options->calc_options, tmp_rd1, t2, ecc_curve->n, ecc_curve->n_r_square, ecc_curve->constn, u1); + + ecc_modular_multiply(&ecdsa_calc_options->calc_options, r, t2, ecc_curve->n, ecc_curve->n_r_square, ecc_curve->constn, u2); + + hw_ecc_point_mul(&ecdsa_calc_options->calc_options, u1, NULL, &u1G); + + if (ecc_is_point_on_curve(&ecdsa_calc_options->calc_options, &u1G) != ECC_OK) + { + + return ECC_ERROR_POINT_NOT_ON_CURVE; + } + + hw_ecc_point_mul(&ecdsa_calc_options->calc_options, u2, &ecdsa_calc_options->our_public_point, &u2Q); + + if (ecc_is_point_on_curve(&ecdsa_calc_options->calc_options, &u2Q) != ECC_OK) + { + return ECC_ERROR_POINT_NOT_ON_CURVE; + } + + ecc_point_addition(&ecdsa_calc_options->calc_options, &u1G, &u2Q, &A); + + hw_ecc_modular_compare(&ecdsa_calc_options->calc_options, A.x, ecc_curve->n, x); + + if (ecc_is_point_on_curve(&ecdsa_calc_options->calc_options, &A) != ECC_OK) + { + return ECC_ERROR_POINT_NOT_ON_CURVE; + } + + if (pkc_number_compare(x, r, 256) != 0) + { + return ECC_ERROR_VERIFY; + } + } while (0); + + return err; +} + +algo_ecc_ret_e crypto_ecc_ecdsa_verify(algo_ecc_ecdsa_config_t *ecdsa_calc_options, + uint8_t hash_func, + uint8_t *message, + uint32_t message_byte_length, + uint32_t in_signiture_r[ECC_U32_LENGTH], + uint32_t in_signiture_s[ECC_U32_LENGTH]) +{ + + uint8_t e[ECC_U32_LENGTH * 4] = { 0 }; + if (NULL == ecdsa_calc_options || NULL == message) + { + return ECC_ERROR_PARAMETER; + } + + switch (hash_func) + { + case ECC_HASH_NONE: + memcpy(e, message, message_byte_length); + break; + case ECC_HASH_SHA_256: + hw_ecc_sha(message, message_byte_length, (uint8_t *)e); + break; + default: + return ECC_ERROR_PARAMETER; + } + + return ecc_ecdsa_verify_with_hash(ecdsa_calc_options, e, in_signiture_r, in_signiture_s); +} + +void crypto_ecc_ecdh_init(algo_ecc_ecdh_config_t *ecdh_data, algo_ecc_curve_type_e curve) +{ + if (NULL == ecdh_data) + { + return; + } + + pkc_zeroize((void *)(&ecdh_data->our_public_point), sizeof(algo_ecc_point_t) / 4); + pkc_zeroize((void *)(&ecdh_data->peer_public_point), sizeof(algo_ecc_point_t) / 4); + pkc_zeroize((void *)(&ecdh_data->shared_point), sizeof(algo_ecc_point_t) / 4); + pkc_zeroize((void *)(&ecdh_data->our_secret_value), ECC_U32_LENGTH); + + ecc_init_config(&ecdh_data->calc_options, curve); +} + +algo_ecc_ret_e crypto_ecc_ecdh_gen_secret_and_public(algo_ecc_ecdh_config_t *ecdh_data) +{ + if (NULL == ecdh_data || NULL == ecdh_data->calc_options.curve) + { + return ECC_ERROR_PARAMETER; + } + + // make sure 1 < our_secret_value < n + ecc_gen_rng(&ecdh_data->calc_options, ecdh_data->our_secret_value); + + hw_ecc_point_mul( + &ecdh_data->calc_options, ecdh_data->our_secret_value, NULL, &ecdh_data->our_public_point); + + return ECC_OK; +} + +algo_ecc_ret_e crypto_ecc_ecdh_compute_shared(algo_ecc_ecdh_config_t *ecdh_data, algo_ecc_point_t *qb) +{ + + if (NULL == ecdh_data || NULL == ecdh_data->calc_options.curve || NULL == qb) + { + return ECC_ERROR_PARAMETER; + } + + if (ecc_is_point_on_curve(&ecdh_data->calc_options, qb) != ECC_OK) + { + return ECC_ERROR_POINT_NOT_ON_CURVE; + } + + memcpy(&ecdh_data->peer_public_point, qb, sizeof(algo_ecc_point_t)); + + hw_ecc_point_mul( + &ecdh_data->calc_options, ecdh_data->our_secret_value, &ecdh_data->peer_public_point, &ecdh_data->shared_point); + return ECC_OK; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc_port.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc_port.c new file mode 100644 index 0000000..1a4f265 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_ecc_port.c @@ -0,0 +1,192 @@ +#include "crypto_ecc_port.h" +#include "crypto_pkc.h" +#include "crypto_pkc_port.h" +#include "crypto_sha256.h" +#include "grx_hal.h" + +uint32_t hw_ecc_rng32(void) +{ + uint32_t rng32; + rng_handle_t g_rng_handle; + + g_rng_handle.p_instance = RNG; + g_rng_handle.init.seed_mode = RNG_SEED_FR0_S0; + g_rng_handle.init.lfsr_mode = RNG_LFSR_MODE_59BIT; + g_rng_handle.init.out_mode = RNG_OUTPUT_FR0_S0; + g_rng_handle.init.post_mode = RNG_POST_PRO_NOT; + + hal_rng_deinit(&g_rng_handle); + hal_rng_init(&g_rng_handle); + hal_rng_generate_random_number(&g_rng_handle, NULL, &rng32); + hal_rng_deinit(&g_rng_handle); + return rng32; +} + +void hw_ecc_point_mul(algo_ecc_config_t *ecc_calc_options, + uint32_t k[ECC_U32_LENGTH], + algo_ecc_point_t *Q, + algo_ecc_point_t *result) +{ + + hal_status_t err = HAL_OK; + ecc_curve_init_t *ecc_curve = (ecc_curve_init_t *)ecc_calc_options->curve; + + hal_set_curve(ecc_curve); + + err = hal_pkc_ecc_point_mul_handle(k, (ecc_point_t *)Q, (ecc_point_t *)result); + + if (HAL_OK != err) + { +// printf("hw_ecc_point_mul error %d\n", __LINE__); + } +} + +void hw_ecc_sha(const uint8_t *message, uint32_t message_byte_length, uint8_t output[32]) +{ + crypto_sha256_context config = { 0 }; + crypto_sha256_init(&config); + crypto_sha256_starts(&config); + crypto_sha256_update(&config, (uint8_t *)message, message_byte_length); + crypto_sha256_finish(&config, output); + crypto_sha256_free(&config); +} + +void hw_ecc_modular_compare(algo_ecc_config_t *ecc_calc_options, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t result[]) +{ + + hal_status_t err = HAL_OK; + + err = hal_pkc_modular_compare_handle(256, in_a, in_prime, result); + + if (HAL_OK != err) + { +// printf("hw_ecc_modular_compare error %d\n", __LINE__); + } +} + +// modular inverse +// output is a^(-1) +void ecc_modular_inverse( + algo_ecc_config_t *ecc_config, uint32_t in_a[], uint32_t in_prime[], uint32_t r_square[], uint32_t constq, uint32_t out_a_inverse[]) +{ + // check if input a = 0 + if (pkc_number_compare_to_const(in_a, 0, 256) == 0) + { + return; + } + + if ((in_prime[0] & 1) == 0) + { + return; + } + + hw_ecc_montgomery_inverse(ecc_config, in_a, in_prime, constq, out_a_inverse); +} + +void hw_ecc_montgomery_inverse( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_prime[], uint32_t constp, uint32_t out_x[]) +{ + + hal_status_t err = HAL_OK; + + err = hal_pkc_montgomery_inverse(256, in_a, in_prime, constp, out_x); + + if (HAL_OK != err) + { +// printf("hw_ecc_montgomery_inverse error %d\n", __LINE__); + } +} + +void hw_ecc_modular_sub( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]) +{ + hal_status_t err = HAL_OK; + + err = hal_pkc_modular_sub_handle(256, in_a, in_b, in_prime, result); + + if (HAL_OK != err) + { +// printf("hw_ecc_modular_sub error %d\n", __LINE__); + } +} + +void hw_ecc_montgomery_mul(algo_ecc_config_t *ecc_calc_options, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t constp, + uint32_t result[]) +{ + hal_status_t err = HAL_OK; + + err = hal_pkc_montgomery_mul(256, in_a, in_b, in_prime, constp, result); + + if (HAL_OK != err) + { +// printf("hw_eccmontgomery_mul error %d\n", __LINE__); + } +} + +void hw_ecc_modular_add( + algo_ecc_config_t *ecc_calc_options, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]) +{ + hal_status_t err = HAL_OK; + + err = hal_pkc_modular_add_handle(256, in_a, in_b, in_prime, result); + + if (HAL_OK != err) + { +// printf("hw_ecc_modular_add error %d\n", __LINE__); + } +} + +// c = a * b mod prime +void ecc_modular_multiply(algo_ecc_config_t *ecc_config, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t out_result[]) +{ + //algo_ecc_ret_e err = ECC_OK; + uint32_t tmp[64] = { 0 }; + + hw_ecc_montgomery_mul(ecc_config, in_a, in_b, in_prime, constq, tmp); + + hw_ecc_montgomery_mul(ecc_config, tmp, r_square, in_prime, constq, out_result); +} + +/** + * \brief check if point is an infinite point + * + * \param[in] point input point. + * + * \return + * \li 0 Not inifinte point + * \li 1 is infinite point + */ +uint32_t ecc_is_infinite_point(algo_ecc_point_t *point) +{ + + uint32_t i = 0; + + if (NULL == point) + { + return (uint32_t)ECC_ERROR_PARAMETER; + } + + for (i = 0; i < ECC_U32_LENGTH; i++) + { + + if (point->x[i] != 0 || point->y[i] != 0) + { + return 0; + } + } + + return 1; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_gcm.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_gcm.c new file mode 100644 index 0000000..23f42db --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_gcm.c @@ -0,0 +1,444 @@ +#include "crypto_gcm.h" +#include "grx_hal.h" + +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (uint8_t ) ( (n) >> 24 ); \ + (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \ + (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \ + (b)[(i) + 3] = (uint8_t) ( (n) ); \ +} + +typedef struct +{ + uint8_t seed[AES_BLOCK_SIZE]; + aes_handle_t aes_handle; +} aes_instance_t; + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint64_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +static void aes_hardware_reset(void) +{ + CLEAR_BITS(MCU_SUB->SECURITY_RESET, MCU_SUB_SECURITY_RESET_AES); + SET_BITS(MCU_SUB->SECURITY_RESET, MCU_SUB_SECURITY_RESET_AES); +} + +void crypto_gcm_init( crypto_gcm_context *ctx ) +{ + if (ctx == NULL) + { + return; + } + + memset( ctx, 0, sizeof( crypto_gcm_context ) ); + crypto_aes_init( &ctx->cipher_ctx ); +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ +static int gcm_gen_table( crypto_gcm_context *ctx ) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + + memset( h, 0, 16 ); + if( ( ret = crypto_aes_crypt_ecb(&ctx->cipher_ctx, AES_ENCRYPT, h, 16, h) ) != 0 ) + return( ret ); + + /* pack h as two 64-bits ints, big-endian */ + GET_UINT32_BE( hi, h, 0 ); + GET_UINT32_BE( lo, h, 4 ); + vh = (uint64_t) hi << 32 | lo; + + GET_UINT32_BE( hi, h, 8 ); + GET_UINT32_BE( lo, h, 12 ); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for( i = 4; i > 0; i >>= 1 ) + { + uint32_t T = ( vl & 1 ) * 0xe1000000U; + vl = ( vh << 63 ) | ( vl >> 1 ); + vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for( i = 2; i <= 8; i *= 2 ) + { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for( j = 1; j < i; j++ ) + { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return( 0 ); +} + +int crypto_gcm_setkey( crypto_gcm_context *ctx, const uint8_t *key, uint32_t keybits ) +{ + int ret = 0; + + if (ctx == NULL || key == NULL || ctx->cipher_ctx.instance == NULL) + { + return( -1 ); + } + + if( ( ret = crypto_aes_setkey_enc(&ctx->cipher_ctx, (uint8_t *)key, keybits) ) != 0 ) + { + return( ret ); + } + + if( ( ret = gcm_gen_table( ctx ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult( crypto_gcm_context *ctx, const uint8_t x[16], uint8_t output[16] ) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + + lo = x[15] & 0xf; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for( i = 15; i >= 0; i-- ) + { + lo = x[i] & 0xf; + hi = ( x[i] >> 4 ) & 0xf; + + if( i != 15 ) + { + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + PUT_UINT32_BE( zh >> 32, output, 0 ); + PUT_UINT32_BE( zh, output, 4 ); + PUT_UINT32_BE( zl >> 32, output, 8 ); + PUT_UINT32_BE( zl, output, 12 ); +} + +int crypto_gcm_starts( crypto_gcm_context *ctx, int mode, const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len ) +{ + int ret = 0; + uint8_t work_buf[16]; + uint32_t i; + const uint8_t *p; + uint32_t use_len = 0; + + if (ctx == NULL || iv == NULL || (add == NULL && add_len != 0)) + { + return( -1 ); + } + + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + /* IV is not allowed to be zero length */ + if( iv_len == 0 || + ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( -1 ); + } + + memset( ctx->y, 0x00, sizeof(ctx->y) ); + memset( ctx->buf, 0x00, sizeof(ctx->buf) ); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if( iv_len == 12 ) + { + memcpy( ctx->y, iv, iv_len ); + ctx->y[15] = 1; + } + else + { + memset( work_buf, 0x00, 16 ); + PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + + p = iv; + while( iv_len > 0 ) + { + use_len = ( iv_len < 16 ) ? iv_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->y[i] ^= p[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + + iv_len -= use_len; + p += use_len; + } + + for( i = 0; i < 16; i++ ) + ctx->y[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + } + + if( ( ret = crypto_aes_crypt_ecb(&ctx->cipher_ctx, AES_ENCRYPT, ctx->y, 16, ctx->base_ectr) ) != 0 ) + { + return( ret ); + } + + ctx->add_len = add_len; + p = add; + while( add_len > 0 ) + { + use_len = ( add_len < 16 ) ? add_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->buf[i] ^= p[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + add_len -= use_len; + p += use_len; + } + + return( 0 ); +} + +int crypto_gcm_update( crypto_gcm_context *ctx, uint32_t length, const uint8_t *input, uint8_t *output ) +{ + int ret = 0; + uint8_t ectr[16]; + uint32_t i; + const uint8_t *p; + uint8_t *out_p = output; + uint32_t use_len = 0; + + if (ctx == NULL || input == NULL || output == NULL) + { + return( -1 ); + } + + if( output > input && (size_t) ( output - input ) < length ) + return( -1 ); + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) + { + return( -1 ); + } + + aes_handle_t *p_aes_handle = &((aes_instance_t *)ctx->cipher_ctx.instance)->aes_handle; + + p_aes_handle->p_instance = AES; + p_aes_handle->init.chaining_mode = AES_CHAININGMODE_ECB; + p_aes_handle->init.p_init_vector = NULL; + p_aes_handle->init.p_seed = (uint32_t *)(((aes_instance_t *)ctx->cipher_ctx.instance)->seed); + p_aes_handle->init.dpa_mode = DISABLE; + + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + hal_aes_init(p_aes_handle); + + ctx->len += length; + + p = input; + while( length > 0 ) + { + use_len = ( length < 16 ) ? length : 16; + + for( i = 16; i > 12; i-- ) + if( ++ctx->y[i - 1] != 0 ) + break; + + if ( HAL_OK != hal_aes_ecb_encrypt(p_aes_handle, (uint32_t *)ctx->y, 16, (uint32_t *)ectr, 5000) ) + { + ret = -1; + goto exit; + } + + for( i = 0; i < use_len; i++ ) + { + if( ctx->mode == AES_DECRYPT ) + ctx->buf[i] ^= p[i]; + out_p[i] = ectr[i] ^ p[i]; + if( ctx->mode == AES_ENCRYPT ) + ctx->buf[i] ^= out_p[i]; + } + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + length -= use_len; + p += use_len; + out_p += use_len; + } + +exit: + hal_aes_deinit(p_aes_handle); + aes_hardware_reset(); + return( ret ); +} + +int crypto_gcm_finish( crypto_gcm_context *ctx, uint8_t *tag, uint32_t tag_len ) +{ + uint8_t work_buf[16]; + uint32_t i; + uint64_t orig_len; + uint64_t orig_add_len; + + if (ctx == NULL || tag == NULL) + { + return( -1 ); + } + + orig_len = ctx->len * 8; + orig_add_len = ctx->add_len * 8; + + if( tag_len > 16 || tag_len < 4 ) + return( -1 ); + + memcpy( tag, ctx->base_ectr, tag_len ); + + if( orig_len || orig_add_len ) + { + memset( work_buf, 0x00, 16 ); + + PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + + for( i = 0; i < 16; i++ ) + ctx->buf[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + for( i = 0; i < tag_len; i++ ) + tag[i] ^= ctx->buf[i]; + } + + return( 0 ); +} + +void crypto_gcm_free( crypto_gcm_context *ctx ) +{ + if( ctx == NULL ) + return; + crypto_aes_free( &ctx->cipher_ctx ); + memset( ctx, 0, sizeof( crypto_gcm_context ) ); +} + +int crypto_gcm_crypt_and_tag( crypto_gcm_context *ctx, int mode, uint32_t length, + const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len, + const uint8_t *input, uint8_t *output, uint32_t tag_len, uint8_t *tag ) +{ + int ret = 0; + + if (ctx == NULL || iv == NULL || input == NULL || output == NULL || tag == NULL || (add == NULL && add_len != 0)) + { + return( -1 ); + } + + if( ( ret = crypto_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) + return( ret ); + + if( ( ret = crypto_gcm_update( ctx, length, input, output ) ) != 0 ) + return( ret ); + + if( ( ret = crypto_gcm_finish( ctx, tag, tag_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int crypto_gcm_auth_decrypt( crypto_gcm_context *ctx, uint32_t length, + const uint8_t *iv, uint32_t iv_len, const uint8_t *add, uint32_t add_len, + const uint8_t *tag, uint32_t tag_len, const uint8_t *input, uint8_t *output ) +{ + int ret = 0; + uint8_t check_tag[16]; + uint32_t i; + int diff; + + if (ctx == NULL || iv == NULL || input == NULL || output == NULL || tag == NULL || (add == NULL && add_len != 0)) + { + return( -1 ); + } + + if( ( ret = crypto_gcm_crypt_and_tag( ctx, AES_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + memset( output, 0, length ); + return( -1 ); + } + + return( 0 ); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc.c new file mode 100644 index 0000000..2a48f9b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc.c @@ -0,0 +1,280 @@ +#include "crypto_pkc.h" + +static pkc_handle_t pkc_handle = { 0 }; +static ecc_curve_init_t ECC_CurveInitStruct = LL_ECC_CURVE_DEFAULT_CONFIG; + +static void pkc_set_curve_secp256r1(void) +{ + uint32_t A[ECC_U32_LENGTH] = {0xFFFFFFFC, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC}; + uint32_t B[ECC_U32_LENGTH] = {0xDC30061D, 0x04874834, 0xE5A220AB, 0xF7212ED6, 0xACF005CD, 0x78843090, 0xD89CDF62, 0x29C4BDDF}; + uint32_t P[ECC_U32_LENGTH] = {0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + uint32_t PRSquare[ECC_U32_LENGTH] = {0x00000004, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFB, 0xFFFFFFFF, 0x00000000, 0x00000003}; + uint32_t ConstP = 1; + uint32_t N[ECC_U32_LENGTH] = {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xBCE6FAAD, 0xA7179E84, 0xF3B9CAC2, 0xFC632551}; + uint32_t NRSquare[ECC_U32_LENGTH] = {0x66E12D94, 0xF3D95620, 0x2845B239, 0x2B6BEC59, 0x4699799C, 0x49BD6FA6, 0x83244C95, 0xBE79EEA2}; + uint32_t ConstN = 0xEE00BC4F; + uint32_t H = 1; + uint32_t GX[ECC_U32_LENGTH] = {0x6B17D1F2, 0xE12C4247, 0xF8BCE6E5, 0x63A440F2, 0x77037D81, 0x2DEB33A0, 0xF4A13945, 0xD898C296}; + uint32_t GY[ECC_U32_LENGTH] = {0x4FE342E2, 0xFE1A7F9B, 0x8EE7EB4A, 0x7C0F9E16, 0x2BCE3357, 0x6B315ECE, 0xCBB64068, 0x37BF51F5}; + + memcpy(ECC_CurveInitStruct.A, A, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.B, B, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.P, P, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.PRSquare, PRSquare, sizeof(uint32_t) * ECC_U32_LENGTH); + ECC_CurveInitStruct.ConstP = ConstP; + memcpy(ECC_CurveInitStruct.N, N, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.NRSquare, NRSquare, sizeof(uint32_t) * ECC_U32_LENGTH); + ECC_CurveInitStruct.ConstN = ConstN; + ECC_CurveInitStruct.H = H; + memcpy(ECC_CurveInitStruct.G.X, GX, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.G.Y, GY, sizeof(uint32_t) * ECC_U32_LENGTH); +} + +static void pkc_set_curve_secp256k1(void) +{ + uint32_t A[ECC_U32_LENGTH] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + uint32_t B[ECC_U32_LENGTH] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00001AB7}; + uint32_t P[ECC_U32_LENGTH] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFC2F}; + uint32_t PRSquare[ECC_U32_LENGTH] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x000007A2, 0x000E90A1}; + uint32_t ConstP = 0xD2253531; + uint32_t N[ECC_U32_LENGTH] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xBAAEDCE6, 0xAF48A03B, 0xBFD25E8C, 0xD0364141}; + uint32_t NRSquare[ECC_U32_LENGTH] = {0x9D671CD5, 0x81C69BC5, 0xE697F5E4, 0x5BCD07C6, 0x741496C2, 0x0E7CF878, 0x896CF214, 0x67D7D140}; + uint32_t ConstN = 0x5588B13F; + uint32_t H = 1; + uint32_t GX[ECC_U32_LENGTH] = {0x79BE667E, 0xF9DCBBAC, 0x55A06295, 0xCE870B07, 0x029BFCDB, 0x2DCE28D9, 0x59F2815B, 0x16F81798}; + uint32_t GY[ECC_U32_LENGTH] = {0x483ADA77, 0x26A3C465, 0x5DA4FBFC, 0x0E1108A8, 0xFD17B448, 0xA6855419, 0x9C47D08F, 0xFB10D4B8}; + + memcpy(ECC_CurveInitStruct.A, A, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.B, B, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.P, P, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.PRSquare, PRSquare, sizeof(uint32_t) * ECC_U32_LENGTH); + ECC_CurveInitStruct.ConstP = ConstP; + memcpy(ECC_CurveInitStruct.N, N, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.NRSquare, NRSquare, sizeof(uint32_t) * ECC_U32_LENGTH); + ECC_CurveInitStruct.ConstN = ConstN; + ECC_CurveInitStruct.H = H; + memcpy(ECC_CurveInitStruct.G.X, GX, sizeof(uint32_t) * ECC_U32_LENGTH); + memcpy(ECC_CurveInitStruct.G.Y, GY, sizeof(uint32_t) * ECC_U32_LENGTH); +} + +hal_status_t hal_pkc_modular_left_shift_handle( + uint32_t bits_len, uint32_t in_a[], uint32_t in_prime[], uint32_t shift_bits, uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + pkc_modular_shift_t pkc_left = { + .p_A = in_a, + .shift_bits = shift_bits, + .p_P = in_prime, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_modular_left_shift(&(pkc_handle), &pkc_left, 1000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_modular_compare_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_prime[], uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + + pkc_modular_compare_t pkc_comp = { + .p_A = in_a, + .p_P = in_prime, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_modular_compare(&(pkc_handle), &pkc_comp, 1000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_montgomery_inverse(uint32_t bits_len, uint32_t in_a[], uint32_t in_prime[], uint32_t constp, uint32_t out_x[]) +{ + hal_status_t ret = HAL_OK; + + pkc_montgomery_inversion_t pkc_inverse = { + .p_A = in_a, + .p_P = in_prime, + .ConstP = constp, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = out_x; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_montgomery_inversion(&pkc_handle, &pkc_inverse, 5000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_rsa_modular_exponent_handle(uint32_t bits_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t in_constp, + uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + pkc_rsa_modular_exponent_t pkc_rsa = { + .p_A = in_a, + .p_B = in_b, + .p_P = in_prime, + .p_P_R2 = r_square, + .ConstP = in_constp + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_rsa_modular_exponent(&(pkc_handle), &pkc_rsa, 1000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_montgomery_mul( + uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t constq, uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + pkc_montgomery_multi_t pkc_mul = { + .p_A = in_a, + .p_B = in_b, + .p_P = in_prime, + .ConstP = constq, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_montgomery_multi(&(pkc_handle), &pkc_mul, 5000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +ecc_curve_init_t *pkc_set_curve_p256_params(algo_ecc_curve_type_e curve) +{ + switch (curve) + { + case ECC_CURVE_SECP256R1: + pkc_set_curve_secp256r1(); + break; + case ECC_CURVE_SECP256K1: + pkc_set_curve_secp256k1(); + break; + default: + break; + } + return &ECC_CurveInitStruct; +} + +void hal_set_curve(ecc_curve_init_t *curve) +{ + if (NULL == curve) + { + pkc_handle.init.p_ecc_curve = (ecc_curve_init_t *)pkc_set_curve_p256_params(ECC_CURVE_SECP256R1); + } + else + { + pkc_handle.init.p_ecc_curve = curve; + } +} + +hal_status_t hal_pkc_ecc_point_mul_handle(uint32_t k[ECC_U32_LENGTH], ecc_point_t *Q, ecc_point_t *result) +{ + hal_status_t ret = HAL_OK; + pkc_ecc_point_multi_t pkc_point_mul; + + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + + if (NULL == pkc_handle.init.p_ecc_curve) + { + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + } + + pkc_handle.init.data_bits = 256; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = (uint32_t(*)(void))rand; + + hal_pkc_init(&pkc_handle); + + pkc_point_mul.p_K = k; + pkc_point_mul.p_ecc_point = Q; + + ret = hal_pkc_ecc_point_multi(&pkc_handle, &pkc_point_mul, 5000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_modular_sub_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + pkc_modular_sub_t pkc_sub = { + .p_A = in_a, + .p_B = in_b, + .p_P = in_prime, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_modular_sub(&(pkc_handle), &pkc_sub, 1000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} + +hal_status_t hal_pkc_modular_add_handle(uint32_t bits_len, uint32_t in_a[], uint32_t in_b[], uint32_t in_prime[], uint32_t result[]) +{ + hal_status_t ret = HAL_OK; + pkc_modular_add_t pkc_add = { + .p_A = in_a, + .p_B = in_b, + .p_P = in_prime, + }; + pkc_handle.p_instance = PKC; + pkc_handle.p_result = result; + pkc_handle.init.p_ecc_curve = &ECC_CurveInitStruct; + pkc_handle.init.data_bits = bits_len; + pkc_handle.init.secure_mode = PKC_SECURE_MODE_DISABLE; + pkc_handle.init.random_func = NULL; + + hal_pkc_init(&pkc_handle); + ret = hal_pkc_modular_add(&(pkc_handle), &pkc_add, 1000); + hal_pkc_deinit(&pkc_handle); + + return ret; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc_port.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc_port.c new file mode 100644 index 0000000..4da943f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_pkc_port.c @@ -0,0 +1,141 @@ +#include "crypto_pkc_port.h" + +static void pkc_random_delay(pkc_rng_func_ptr rng32_func) +{ + volatile uint32_t random = rng32_func(); + random &= 0x1F; + + while (random > 0) + { + random--; + } +} + +void pkc_setbit(uint32_t q[], uint32_t in_prime[], uint32_t k, uint32_t bits_len) +{ + uint32_t i = 0; + uint32_t n_u32 = 0; // the n-th u32 + uint32_t m_bit = 0; // the m-th bit + uint32_t prime_u32_length = bits_len >> 5; //(bits_len >> 5); + + if (k > bits_len) + { + return; + } + if (bits_len == k) + { + for (i = 0; i < prime_u32_length; i++) + { + q[i] = 0xFFFFFFFF ^ in_prime[i]; + } + q[prime_u32_length - 1]++; + return; + } + else + { + // 0 <= k < 2 ^ bits_len + for (i = 0; i < prime_u32_length; i++) + { + q[i] = 0; + } + + n_u32 = k >> 5; // k / 32; + m_bit = k & 0x1F; // k % 32 + q[n_u32] = 1 << m_bit; + } + + return; +} + +void pkc_zeroize(void *v, uint32_t u32_len) +{ + volatile uint32_t *p = (uint32_t *)v; + uint32_t i = 0; + for (i = 0; i < u32_len; i++) + { + p[i] = 0; + } + return; +} + +// ret: a > b ret 1; a == b ret 0; a < b ret -1; +int32_t pkc_number_compare_to_const(uint32_t a[], uint32_t b, uint32_t bits_len) +{ + uint32_t i = 0; + int32_t pkc_u32_len = bits_len >> 5; //(bits_len >> 5); + + if (a[0] > b) + { + return 1; + } + + for (i = pkc_u32_len - 1; i >= 1; i--) + { + if (a[i] > 0) + { + return 1; + } + } + + if (a[0] == b) + { + return 0; + } + + return -1; +} + +int32_t pkc_number_compare(uint32_t a[], uint32_t b[], uint32_t bits_len) +{ + int32_t i = 0; + uint32_t number_u32_len = bits_len >> 5; //(bits_len >> 5); + + for (i = number_u32_len - 1; i >= 0; i--) + { + if (a[i] > b[i]) + { + return 1; + } + else if (a[i] < b[i]) + { + return -1; + } + } + + return 0; +} + +uint8_t pkc_safe_compare(pkc_rng_func_ptr rng32, uint32_t *src, uint32_t *dest, uint32_t u32_len) +{ + uint8_t ret = 1; + + ret = pkc_number_compare(src, dest, u32_len * 32); + if (0 != ret) + { + return ret; + } + + pkc_random_delay(rng32); + + ret = pkc_number_compare(src, dest, u32_len * 32); + + if (0 != ret) + { + return ret; + } + + pkc_random_delay(rng32); + + return pkc_number_compare(src, dest, u32_len * 32); +} + +void pkc_read_oct_string(uint32_t *number, uint8_t *buffer, uint32_t byte_size) +{ + uint32_t i = 0; + uint8_t *x = (uint8_t *)number; + + for (i = 0; i < byte_size; i++) + { + x[i] = buffer[byte_size - 1 - i]; + } +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa.c new file mode 100644 index 0000000..41b0a7b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa.c @@ -0,0 +1,901 @@ +#include "crypto_rsa.h" +#include "crypto_rsa_port.h" +#include "crypto_pkc_port.h" + +#define ciL (sizeof(uint32_t)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ +#define SHA256_SIZE 32 +#define ZERO_PADDING_SIZE 8 + +typedef struct rsa_public_key +{ + uint32_t *n; + uint32_t e; + uint32_t *rr; + uint32_t c; +} rsa_public_key_t; + +typedef struct rsa_private_key +{ + uint32_t *d; +} rsa_private_key_t; + +typedef struct +{ + algo_rsa_config_t rsa_config; + uint32_t len; /*!< size(N) in chars */ + rsa_public_key_t pk; + rsa_private_key_t sk; +} rsa_context_t; + +static void swap_endian(uint32_t *in, uint32_t len, uint32_t *out) +{ + uint32_t i = 0; + + for (i = 0; i < len; i++) + { + out[i] = ((in[i] & 0xFF000000) >> 24) + ((in[i] & 0xFF0000) >> 8) + + ((in[i] & 0xFF00) << 8) + ((in[i] & 0xFF) << 24); + } +} + +static void swap_order(uint8_t *in, uint32_t len) +{ + int i; + uint8_t temp; + for(i = 0; i < len/2; i++) + { + temp = in[i]; + in[i] = in[len-i-1]; + in[len-i-1] = temp; + } +} + +/* + * Count leading zero bits in a given integer + */ +static uint32_t rsa_clz(const uint32_t x) +{ + uint32_t j = 0; + uint32_t mask = (uint32_t)1 << (biL - 1); + + for (j = 0; j < biL; j++) + { + if (x & mask) + break; + + mask >>= 1; + } + + return j; +} + +/* + * Return the number of bits + */ +static uint32_t bl_mpi_bitlen(int n, const uint32_t *p) +{ + uint32_t i, j; + + for (i = n - 1; i > 0; i--) + { + if (p[i] != 0) + { + break; + } + } + + j = biL - rsa_clz(p[i]); + + return ((i * biL) + j); +} + +static int mgf_mask(uint8_t *dst, uint32_t dlen, uint8_t *src, uint32_t slen) +{ + uint32_t i = 0; + uint32_t use_len = 0; + uint8_t counter[4] = { 0 }; + uint8_t *p = dst; + uint32_t hlen = SHA256_SIZE; + uint8_t mask[SHA256_SIZE]; + uint8_t mhash[SHA256_SIZE + 4]; + + memset(mask, 0, SHA256_SIZE); + memset(counter, 0, 4); + memcpy(mhash, src, SHA256_SIZE); + + /* Generate and apply dbMask */ + while (dlen > 0) + { + use_len = hlen; + if (dlen < hlen) + { + use_len = dlen; + } + memcpy((mhash + SHA256_SIZE), counter, 4); + hw_rsa_sha(mhash, SHA256_SIZE + 4, mask); + + for (i = 0; i < use_len; ++i) + { + *p++ ^= mask[i]; + } + + counter[3]++; + + dlen -= use_len; + } + + pkc_zeroize(mask, sizeof(mask) / 4); + + return 0; +} + +static algo_rsa_ret_e rsa_short_modular_exponent(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_a[], + algo_rsa_public_exponent_e e, + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + uint32_t out_result[]) +{ + algo_rsa_ret_e err = RSA_OK; + uint32_t b[RSA_U32_LENGTH] = { 0 }; + uint32_t array_len = bits_len >> 5; + + if (NULL == rsa_config) + { + return RSA_ERROR_PARAMETER; + } + + switch (e) + { + case RSA_E_65537: + b[array_len - 1] = 65537; + break; + + case RSA_E_17: + b[array_len - 1] = 17; + break; + + case RSA_E_3: + b[array_len - 1] = 3; + break; + + default: + return RSA_ERROR_PARAMETER; + } + + rsa_modular_exponent(rsa_config, bits_len, in_a, b, in_prime, r_square, constp, out_result); + + return err; +} + +static algo_rsa_ret_e rsa_private_key_modular_exponent(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_d[], + algo_rsa_public_exponent_e e, + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + uint32_t out_result[]) +{ + uint32_t r[RSA_U32_LENGTH] = { 0 }; + uint32_t cx[RSA_U32_LENGTH] = { 0 }; + uint32_t r1[RSA_U32_LENGTH] = { 0 }; + uint32_t tmp[RSA_U32_LENGTH] = { 0 }; + uint32_t temp_a[RSA_U32_LENGTH] = { 0 }; + algo_rsa_ret_e err = RSA_OK; + uint32_t i = 0; + uint32_t u32_len = bits_len >> 5; + + if (NULL == rsa_config) + { + return RSA_ERROR_PARAMETER; + } + + for (i = 0; i < u32_len; i++) + { + r[i] = hw_rsa_rng32(); + } + + // calc cx = in_a * (r ^(-1)) ^ e + memcpy(r1, r, sizeof(uint32_t) * RSA_U32_LENGTH); + rsa_modular_inverse(rsa_config, bits_len, r, in_prime, r_square, constp, cx); + memcpy(r, r1, sizeof(uint32_t) * RSA_U32_LENGTH); + + rsa_short_modular_exponent(rsa_config, bits_len, cx, e, in_prime, r_square, constp, cx); + + hw_rsa_montgomery_mul(rsa_config, bits_len, in_a, cx, in_prime, constp, cx); + hw_rsa_montgomery_mul(rsa_config, bits_len, r_square, cx, in_prime, constp, cx); + + // calc cx = cx ^ in_d = in_a ^ in_d * (r ^ (-1)); + rsa_modular_exponent(rsa_config, bits_len, cx, in_d, in_prime, r_square, constp, cx); + + // calc tmp = in_a ^ in_d = cx * r; + hw_rsa_montgomery_mul(rsa_config, bits_len, cx, r, in_prime, constp, cx); + hw_rsa_montgomery_mul(rsa_config, bits_len, cx, r_square, in_prime, constp, tmp); + + // cx = tmp ^ e + rsa_short_modular_exponent(rsa_config, bits_len, tmp, e, in_prime, r_square, constp, cx); + + hw_rsa_modular_compare(rsa_config, bits_len, in_a, in_prime, temp_a); + + if (pkc_safe_compare(hw_rsa_rng32, cx, temp_a, u32_len) != 0) + { + pkc_zeroize(tmp, u32_len); + return RSA_ERROR_SIGN_FUNCTION; + } + else + { + memcpy(out_result, tmp, u32_len * 4); + } + + return err; +} + +static algo_rsa_ret_e rsa_sign_encrypt_em(rsa_context_t *ctx, uint8_t *sig, uint32_t *output) +{ + algo_rsa_ret_e err = RSA_OK; + uint32_t tmp[RSA_U32_LENGTH] = { 0 }; + uint32_t tmp2[RSA_U32_LENGTH] = { 0 }; + uint32_t tmp1[RSA_U32_LENGTH] = { 0 }; + uint32_t word_bit_len = ctx->len * 8; + + memcpy(tmp, sig, ctx->len); + memcpy(tmp2, sig, ctx->len); + hw_rsa_modular_compare(&ctx->rsa_config, word_bit_len, tmp, (uint32_t *)(ctx->pk.n), tmp); + if (ctx->rsa_config.sign_pkcs_type == RSA_PKCS1_V21) + { + if (memcmp(tmp, tmp2, ctx->len) != 0) + { + return RSA_ERROR_RANDOM; + } + } + +#ifdef RSA_OPENSSL_SEQ + uint32_t i = 0; + uint32_t j = 0; + uint32_t n = ctx->len; + for (i = (ctx->len) - 1, j = 0; n > 0; i--, j++, n--) + { + sig[i] = (uint8_t)(tmp[j / ciL] >> ((j % ciL) << 3)); + } +#else + swap_endian((uint32_t *)sig, ctx->len/4, (uint32_t *)sig); +#endif + + if (ctx->rsa_config.sign_pkcs_type == RSA_PKCS1_V21) + { + memcpy(tmp1, sig, ctx->len); + memcpy(tmp2, sig, ctx->len); + hw_rsa_modular_compare(&ctx->rsa_config, word_bit_len, tmp1, (uint32_t *)(ctx->pk.n), tmp1); + if (memcmp(tmp1, tmp2, ctx->len) != 0) + { + return RSA_ERROR_RANDOM; + } + } + + if ((err = rsa_private_key_modular_exponent(&ctx->rsa_config, + word_bit_len, + (uint32_t *)sig, + ctx->sk.d, + (algo_rsa_public_exponent_e)ctx->pk.e, + (uint32_t *)(ctx->pk.n), + (uint32_t *)(ctx->pk.rr), + ctx->pk.c, + (uint32_t *)output)) + != RSA_OK) + { + return err; + } + + return RSA_OK; +} + +static algo_rsa_ret_e rsa_rsassa_pss_sign(rsa_context_t *ctx, const uint8_t *hash, uint8_t *sig) +{ + uint32_t i = 0; + algo_rsa_ret_e err = RSA_OK; + uint32_t salt[8] = { 0 }; + unsigned char *p = NULL; + uint32_t msb = 0, olen = 0, hlen = 32, slen = 32, offset = 0; + uint8_t zero_hash_p[ZERO_PADDING_SIZE + 2 * SHA256_SIZE]; + + do + { + err = RSA_OK; + p = sig; + msb = 0; + olen = 0; + hlen = 32; + slen = 32; + offset = 0; + olen = ctx->len; + if (olen < hlen + slen + 2) + { + err = RSA_ERROR_PARAMETER; + break; + } + + memset(sig, 0x0, olen); + memset(salt, 0x0, 8); + memset(zero_hash_p, 0, ZERO_PADDING_SIZE + 2 * SHA256_SIZE); + for (i = 0; i < 8; i++) + { + salt[i] = hw_rsa_rng32(); + } + + /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ +#ifdef RSA_OPENSSL_SEQ + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; +#else + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); +#endif + p += olen - hlen * 2 - 2; + *p++ = 0x01; + memcpy(p, salt, slen); + p += slen; + + memset(zero_hash_p, 0, ZERO_PADDING_SIZE); + memcpy(zero_hash_p + ZERO_PADDING_SIZE, hash, SHA256_SIZE); + memcpy(zero_hash_p + ZERO_PADDING_SIZE + SHA256_SIZE, (uint8_t *)salt, slen); + hw_rsa_sha(zero_hash_p, (ZERO_PADDING_SIZE + 2 * SHA256_SIZE), p); + + pkc_zeroize((uint32_t *)salt, slen / 4); + + /* Compensate for boundary condition when applying mask */ + if (msb % 8 == 0) + { + offset = 1; + } + + /* maskedDB: Apply dbMask to DB */ + if (olen != hlen) + { + if (mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen) < 0) + { + err = RSA_ERROR_PARAMETER; + break; + } + } + +#ifdef RSA_OPENSSL_SEQ + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; +#else + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); +#endif + sig[0] &= 0xFF >> (olen * 8 - msb); + + p += hlen; + *p++ = 0xBC; + + err = rsa_sign_encrypt_em(ctx, sig, (uint32_t *)sig); + + } while (err == RSA_ERROR_RANDOM); + + if (err != RSA_OK) + { + return err; + } + +#ifdef RSA_OPENSSL_SEQ + // convert signature(number format) to oct string format. + for (i = 0; i < (uint32_t)(ctx->len / 2); i++) + { + uint8_t temp = sig[i]; + sig[i] = sig[ctx->len - 1 - i]; + sig[ctx->len - 1 - i] = temp; + } +#else + swap_endian((uint32_t *)sig, ctx->len/4, (uint32_t *)sig); +#endif + + return RSA_OK; +} + +static void rsa_compute_montgomery_constant(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_prime[], + uint32_t r[], + uint32_t r_square[], + uint32_t *constp) +{ + uint32_t i = 0; + uint32_t m0 = 0; + uint32_t x = 0; + if (NULL == rsa_config || NULL == in_prime || NULL == constp) + { + return; + } + + // get R + pkc_setbit(r, in_prime, bits_len, bits_len); + + // get R^2 mod p + hw_rsa_modular_left_shift(rsa_config, bits_len, r, in_prime, bits_len, r_square); + + // get constp + m0 = in_prime[(bits_len >> 5) - 1]; + x = m0; + x += ((m0 + 2) & 4) << 1; + for (i = 32; i >= 8; i /= 2) + { + x *= 2 - m0 * x; + } + + *constp = (~x + 1); +} + +#ifdef RSA_OPENSSL_SEQ +static void rsa_pkcs15_padding(const uint8_t *hash, uint32_t len, uint8_t *em) +{ + uint8_t sha256_oid[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; + + if (len < 32 || len > 256) + { + return; + } + if (NULL == em) + { + return; + } + + memset(em, 0xff, len); + em[0] = 0x0; + em[1] = 0x01; + em[len - 32 - sizeof(sha256_oid) - 1] = 0x0; + + memcpy(&em[len - 32 - sizeof(sha256_oid)], sha256_oid, sizeof(sha256_oid)); + memcpy(&em[len - 32], hash, 32); +} +#else +static void rsa_pkcs15_padding(const uint8_t *hash, uint32_t len, uint8_t *em) +{ + size_t nb_pad = len; + uint8_t *p = em; + size_t hashlen = 32; + + if( nb_pad < hashlen ) + return; + + nb_pad -= hashlen; + + /* Need space for signature header and padding delimiter (3 bytes), + * and 8 bytes for the minimal padding */ + if( nb_pad < 3 + 8 ) + return; + nb_pad -= 3; + + /* Now nb_pad is the amount of memory to be filled + * with padding, and at least 8 bytes long. */ + + /* Write signature header and padding */ + *p++ = 0; + *p++ = 0x1; + memset( p, 0xFF, nb_pad ); + p += nb_pad; + *p++ = 0; + memcpy( p, hash, hashlen ); + + return; +} +#endif + +static algo_rsa_ret_e rsa_rsassa_pkcs1v15_sign(rsa_context_t *ctx, const uint8_t *hash, uint8_t *sig) +{ + algo_rsa_ret_e err = RSA_OK; + uint8_t *em = sig; + + rsa_pkcs15_padding(hash, ctx->len, em); + + if ((err = rsa_sign_encrypt_em(ctx, em, (uint32_t *)sig)) < 0) + { + return err; + } + +#ifdef RSA_OPENSSL_SEQ + uint32_t i = 0; + // convert signature(number format) to oct string format. + for (i = 0; i < ctx->len / 2; i++) + { + + uint8_t temp = sig[i]; + sig[i] = sig[ctx->len - 1 - i]; + sig[ctx->len - 1 - i] = temp; + } +#else + swap_endian((uint32_t *)sig, ctx->len/4, (uint32_t *)sig); +#endif + + return RSA_OK; +} + +algo_rsa_ret_e crypto_rsa_pkcs1_sign(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint8_t *message, + uint32_t message_len, + uint32_t private_key[], + algo_rsa_public_exponent_e e, + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + uint8_t sig[], + uint8_t is_hash) +{ + algo_rsa_ret_e ret = RSA_OK; + rsa_context_t ctx = { 0 }; + uint32_t rr[RSA_U32_LENGTH] = { 0 }; + uint8_t hash[32] = { 0 }; + if (is_hash == 1) + { + memcpy(hash, message, message_len); + } + else + { + hw_rsa_sha(message, message_len, hash); + } + + if (NULL == rsa_config || NULL == private_key || NULL == in_prime || bits_len < 1024 || bits_len > 2048) + { + return RSA_ERROR_PARAMETER; + } + + ctx.len = bits_len / 8; + ctx.sk.d = private_key; + ctx.pk.n = in_prime; + ctx.pk.rr = r_square; + ctx.pk.c = constp; + ctx.pk.e = e; + memcpy(&ctx.rsa_config, rsa_config, sizeof(algo_rsa_config_t)); + + // compute montgomery constants + if (NULL == r_square) + { + uint32_t r[RSA_U32_LENGTH] = { 0 }; + ctx.pk.rr = &rr[0]; + rsa_compute_montgomery_constant(&ctx.rsa_config, bits_len, in_prime, r, (uint32_t *)ctx.pk.rr, &ctx.pk.c); + } + + switch (e) + { + case RSA_E_65537: + case RSA_E_17: + case RSA_E_3: + ctx.pk.e = e; + break; + + default: + ret = RSA_ERROR_PARAMETER; + break; + } + + switch (rsa_config->sign_pkcs_type) + { + case RSA_PKCS1_V21: + ret = rsa_rsassa_pss_sign(&ctx, hash, sig); + rsa_config->sign_pkcs_type = RSA_PKCS1_V21; + break; + + case RSA_PKCS1_V15: + ret = rsa_rsassa_pkcs1v15_sign(&ctx, hash, sig); + rsa_config->sign_pkcs_type = RSA_PKCS1_V15; + break; + + default: + ret = RSA_ERROR_PARAMETER; + break; + } + + return ret; +} + +static algo_rsa_ret_e rsa_verify_decrypt_em(rsa_context_t *ctx, uint8_t *sig, uint8_t *output) +{ +#ifdef RSA_OPENSSL_SEQ + algo_rsa_ret_e ret; + int i, j; + int n = ctx->len; + uint32_t tmp[RSA_U32_LENGTH] = { 0 }; + uint32_t word_bit_len = ctx->len * 8; + + memcpy(tmp, sig, ctx->len); + + if ((ret = rsa_short_modular_exponent(&ctx->rsa_config, + word_bit_len, + (uint32_t *)sig, + (algo_rsa_public_exponent_e)ctx->pk.e, + (uint32_t *)(ctx->pk.n), + (uint32_t *)(ctx->pk.rr), + ctx->pk.c, + tmp)) + != RSA_OK) + { + + return ret; + } + + // convert to EM format(string data, big endian) + for (i = ctx->len - 1, j = 0; n > 0; i--, j++, n--) + { + output[i] = (uint8_t)(tmp[j / ciL] >> ((j % ciL) << 3)); + } +#else + algo_rsa_ret_e ret; + uint32_t word_bit_len = ctx->len * 8; + + if ((ret = rsa_short_modular_exponent(&ctx->rsa_config, + word_bit_len, + (uint32_t *)sig, + (algo_rsa_public_exponent_e)ctx->pk.e, + (uint32_t *)(ctx->pk.n), + (uint32_t *)(ctx->pk.rr), + ctx->pk.c, + (uint32_t *)output)) + != RSA_OK) + { + + return ret; + } + swap_endian((uint32_t *)output, ctx->len/4, (uint32_t *)output); +#endif + + return RSA_OK; +} + +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +static algo_rsa_ret_e rsa_rsassa_pss_verify(rsa_context_t *ctx, const uint8_t *hash, const uint8_t *sig) +{ + algo_rsa_ret_e ret = RSA_OK; + uint32_t siglen = 32; + uint8_t *p = NULL; + uint8_t result[SHA256_SIZE] = { 0 }; + uint8_t zeros[8] = { 0 }; + uint32_t hlen = 0; + uint32_t slen = 0, msb = 0; + uint8_t buf[RSA_U32_LENGTH * 4] = { 0 }; + uint32_t expected_salt_len = SHA256_SIZE; + uint32_t sig_number[RSA_U32_LENGTH] = { 0 }; + uint8_t zero_hash_p[ZERO_PADDING_SIZE + 2 * SHA256_SIZE] = { 0 }; + + siglen = ctx->len; + pkc_read_oct_string(sig_number, (uint8_t *)sig, siglen); + + if (siglen < 16 || siglen > sizeof(buf)) + { + return RSA_ERROR_PARAMETER; + } + + if ((ret = rsa_verify_decrypt_em(ctx, (uint8_t *)sig_number, buf)) < 0) + { + return ret; + } + + p = buf; + + if (buf[siglen - 1] != 0xBC) + return RSA_ERROR_VERIFY_FUNCTION; + + hlen = 32; + slen = siglen - hlen - 1; /* Currently length of salt + padding */ + memset(zeros, 0, 8); + + /* + * Note: EMSA-PSS verification is over the length of N - 1 bits + */ +#ifdef RSA_OPENSSL_SEQ + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; +#else + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); + msb = bl_mpi_bitlen(ctx->len >> 2, (const uint32_t *)ctx->pk.n) - 1; + swap_endian((uint32_t *)ctx->pk.n, ctx->len/4, (uint32_t *)ctx->pk.n); + swap_order((uint8_t *)ctx->pk.n, ctx->len); +#endif + + if (buf[0] >> (8 - siglen * 8 + msb)) + { + return RSA_ERROR_VERIFY_FUNCTION; + } + + /* Compensate for boundary condition when applying mask */ + if (msb % 8 == 0) + { + p++; + siglen -= 1; + } + + if (mgf_mask(p, siglen - hlen - 1, p + siglen - hlen - 1, hlen) < 0) + { + return RSA_ERROR_VERIFY_FUNCTION; + } + + buf[0] &= 0xFF >> (siglen * 8 - msb); + + while (p < buf + siglen) + { + if (*p != 0) + { + break; + } + p++; + } + + if ((p == buf + siglen) || (*p++ != 0x01)) + { + return RSA_ERROR_VERIFY_FUNCTION; + } + + /* Actual salt len */ + slen -= p - buf; + + if (slen != (uint32_t)expected_salt_len) + { + return RSA_ERROR_VERIFY_FUNCTION; + } + + /* + * Generate H = Hash( M' ) + */ + memset(zero_hash_p, 0, ZERO_PADDING_SIZE); + memcpy(zero_hash_p + ZERO_PADDING_SIZE, hash, SHA256_SIZE); + memcpy(zero_hash_p + ZERO_PADDING_SIZE + SHA256_SIZE, p, SHA256_SIZE); + hw_rsa_sha(zero_hash_p, (ZERO_PADDING_SIZE + 2 * SHA256_SIZE), result); + +#if 0 + if (memcmp(p + slen + 3, result, hlen - 4) == 0) +#else + if( memcmp( p + slen, result, hlen ) == 0 ) +#endif + { + return RSA_OK; + } + + return RSA_ERROR_VERIFY_FUNCTION; +} + +static algo_rsa_ret_e rsa_rsassa_pkcs1v15_verify(rsa_context_t *ctx, const uint8_t *hash, const uint8_t *sig) +{ + algo_rsa_ret_e err = RSA_OK; + uint8_t em_expect[RSA_U32_LENGTH * 4] = { 0 }; + uint8_t em_act[RSA_U32_LENGTH * 4] = { 0 }; + uint32_t sig_number[RSA_U32_LENGTH] = { 0 }; + + pkc_read_oct_string(sig_number, (uint8_t *)sig, ctx->len); + + rsa_pkcs15_padding(hash, ctx->len, em_expect); + +#ifdef RSA_OPENSSL_SEQ + uint32_t tmp[RSA_U32_LENGTH] = { 0 }; + uint32_t word_bit_len = ctx->len * 8; + uint32_t i = 0; + uint32_t j = 0; + uint32_t n = ctx->len; + uint32_t temp = 0; + + memcpy(tmp, em_expect, ctx->len); + hw_rsa_modular_compare(&ctx->rsa_config, word_bit_len, tmp, (uint32_t *)(ctx->pk.n), tmp); + + for (i = (ctx->len) - 1, j = 0; n > 0; i--, j++, n--) + { + em_expect[i] = (uint8_t)(tmp[j / ciL] >> ((j % ciL) << 3)); + } + memcpy(em_expect, tmp, ctx->len); + swap_endian((uint32_t *)em_expect, ctx->len/4, (uint32_t *)em_expect); + + hw_rsa_modular_compare(&ctx->rsa_config, word_bit_len, (uint32_t *)em_expect, + (uint32_t *)(ctx->pk.n), (uint32_t *)em_expect); + + for (i = 0; i < ctx->len / 2; i++) + { + temp = em_expect[i]; + em_expect[i] = em_expect[ctx->len - 1 - i]; + em_expect[ctx->len - 1 - i] = temp; + } +#endif + + if ((err = rsa_verify_decrypt_em(ctx, (uint8_t *)sig_number, em_act)) < 0) + { + return err; + } + +#ifdef RSA_OPENSSL_SEQ + if (memcmp(em_expect, em_act, ctx->len) != 0) + { + return RSA_ERROR_VERIFY_FUNCTION; + } +#else + if( ( err = (algo_rsa_ret_e)rsa_safer_memcmp( em_expect, em_act, ctx->len ) ) != 0 ) + { + return RSA_ERROR_VERIFY_FUNCTION; + } +#endif + + return err; +} + +algo_rsa_ret_e crypto_rsa_pkcs1_verify(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint8_t *message, + uint32_t message_len, + algo_rsa_public_exponent_e e, + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + const uint8_t sig[], + uint8_t is_hash) +{ + algo_rsa_ret_e ret = RSA_OK; + rsa_context_t ctx = { 0 }; + uint32_t rr[RSA_U32_LENGTH] = { 0 }; + uint8_t hash[32] = { 0 }; + if (is_hash == 1) + { + memcpy(hash, message, message_len); + } + else + { + hw_rsa_sha(message, message_len, hash); + } + + if (NULL == rsa_config || NULL == in_prime || bits_len < 1024 || bits_len > 2048) + { + return RSA_ERROR_PARAMETER; + } + + ctx.len = bits_len / 8; + ctx.pk.n = in_prime; + ctx.pk.rr = r_square; + ctx.pk.c = constp; + memcpy(&ctx.rsa_config, rsa_config, sizeof(algo_rsa_config_t)); + + // compute montgomery constants + if (NULL == r_square) + { + uint32_t r[RSA_U32_LENGTH] = { 0 }; + ctx.pk.rr = &rr[0]; + rsa_compute_montgomery_constant(rsa_config, bits_len, in_prime, r, (uint32_t *)ctx.pk.rr, &ctx.pk.c); + } + + switch (e) + { + case RSA_E_65537: + case RSA_E_17: + case RSA_E_3: + ctx.pk.e = e; + ret = RSA_OK; + break; + + default: + ret = RSA_ERROR_PARAMETER; + break; + } + + if (0 == ret) + { + + if (rsa_config->sign_pkcs_type == RSA_PKCS1_V21) + { + ret = rsa_rsassa_pss_verify(&ctx, (const uint8_t *)hash, (const uint8_t *)sig); + } + else if (rsa_config->sign_pkcs_type == RSA_PKCS1_V15) + { + ret = rsa_rsassa_pkcs1v15_verify(&ctx, (const uint8_t *)hash, (const uint8_t *)sig); + } + } + + return ret; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa_port.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa_port.c new file mode 100644 index 0000000..1632b83 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_rsa_port.c @@ -0,0 +1,146 @@ +#include "crypto_rsa_port.h" +#include "crypto_sha256.h" +#include "crypto_rsa.h" +#include "crypto_pkc.h" +#include "crypto_pkc_port.h" +#include "grx_hal.h" + +uint32_t hw_rsa_rng32(void) +{ + uint32_t rng32; + rng_handle_t g_rng_handle; + + g_rng_handle.p_instance = RNG; + g_rng_handle.init.seed_mode = RNG_SEED_FR0_S0; + g_rng_handle.init.lfsr_mode = RNG_LFSR_MODE_59BIT; + g_rng_handle.init.out_mode = RNG_OUTPUT_FR0_S0; + g_rng_handle.init.post_mode = RNG_POST_PRO_NOT; + + hal_rng_deinit(&g_rng_handle); + hal_rng_init(&g_rng_handle); + hal_rng_generate_random_number(&g_rng_handle, NULL, &rng32); + hal_rng_deinit(&g_rng_handle); + return rng32; +} + +void hw_rsa_sha(const uint8_t *message, uint32_t message_byte_length, uint8_t output[32]) +{ + crypto_sha256_context config = { 0 }; + crypto_sha256_init(&config); + crypto_sha256_starts(&config); + crypto_sha256_update(&config, (uint8_t *)message, message_byte_length); + crypto_sha256_finish(&config, output); + crypto_sha256_free(&config); +} + +void hw_rsa_modular_left_shift(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t shift_bits, + uint32_t result[]) +{ + hal_status_t err = HAL_ERROR; + + err = hal_pkc_modular_left_shift_handle(bits_len, in_a, in_prime, shift_bits, result); + + (void)err; +} + +void hw_rsa_modular_compare(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t result[]) +{ + hal_status_t err = HAL_ERROR; + + err = hal_pkc_modular_compare_handle(bits_len, in_a, in_prime, result); + (void)err; +} + +void hw_rsa_montgomery_inverse(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t constp, + uint32_t out_x[]) +{ + hal_status_t err = HAL_ERROR; + + err = hal_pkc_montgomery_inverse(bits_len, in_a, in_prime, constp, out_x); + (void)err; +} + +void rsa_modular_inverse(algo_rsa_config_t *ecc_config, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t out_a_inverse[]) +{ + // check if input a = 0 + if (pkc_number_compare_to_const(in_a, 0, bits_len) == 0) + { + return; + } + + hw_rsa_montgomery_inverse(ecc_config, bits_len, in_a, in_prime, constq, out_a_inverse); +} + +void hw_rsa_modular_exponent(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constq, + uint32_t result[]) +{ + hal_status_t err = HAL_ERROR; + + err = hal_pkc_rsa_modular_exponent_handle(bits_len, in_a, in_b, in_prime, r_square, constq, result); + + (void)err; +} + +//out_result in_a ^(in_b) mod in_prime +void rsa_modular_exponent(algo_rsa_config_t *rsa_config, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_d[], + uint32_t in_prime[], + uint32_t r_square[], + uint32_t constp, + uint32_t out_result[]) +{ + hw_rsa_modular_exponent(rsa_config, bits_len, in_a, in_d, in_prime, r_square, constp, out_result); +} + +void hw_rsa_montgomery_mul(algo_rsa_config_t *rsa_calc_options, + uint32_t bits_len, + uint32_t in_a[], + uint32_t in_b[], + uint32_t in_prime[], + uint32_t constp, + uint32_t result[]) +{ + hal_status_t err = HAL_ERROR; + + err = hal_pkc_montgomery_mul(bits_len, in_a, in_b, in_prime, constp, result); + (void)err; +} + +int rsa_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + const unsigned char *A = (const unsigned char *) a; + const unsigned char *B = (const unsigned char *) b; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= A[i] ^ B[i]; + + return( diff ); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_sha256.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_sha256.c new file mode 100644 index 0000000..7231d81 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/crypto_lib/src/crypto_sha256.c @@ -0,0 +1,301 @@ +#include "crypto_sha256.h" +#include "grx_hal.h" +//#include "mbedtls/sha256.h" + +#define crypto_malloc malloc +#define crypto_free free + +/** + * @brief This defines the structure of sha256 hmac context. + */ +typedef struct crypto_sha256_hmac_context +{ +// uint8_t pad[2 * SHA256_BLOCK_SIZE]; +// mbedtls_sha256_context m_ctx; + hmac_handle_t hmac_handle; +} crypto_sha256_hmac_context_t; + +/* + * SHA256 context init + */ +void crypto_sha256_init(crypto_sha256_context *ctx) +{ + if (ctx == NULL) + { + return; + } + memset(ctx, 0x0, sizeof(crypto_sha256_context)); + ctx->instance = (crypto_sha256_hmac_context_t *)crypto_malloc(sizeof(crypto_sha256_hmac_context_t)); + if (NULL == ctx->instance) + { + return; + } + memset(ctx->instance, 0x0, sizeof(crypto_sha256_hmac_context_t)); +} + +/* + * SHA256 context free + */ +void crypto_sha256_free(crypto_sha256_context *ctx) +{ +// crypto_sha256_hmac_context_t *hmac_ctx = NULL; + + if (ctx == NULL) + { + return; + } + if (ctx->input != NULL) + { + crypto_free(ctx->input); + ctx->input = NULL; + } +// hmac_ctx = (crypto_sha256_hmac_context_t *)ctx->hmac_ctx; +// if (NULL != hmac_ctx->hmac_handle.init.p_key) +// { +// crypto_free(hmac_ctx->hmac_handle.init.p_key); +// hmac_ctx->hmac_handle.init.p_key = NULL; +// } + if (NULL != ctx->instance) + { + crypto_free(ctx->instance); + ctx->instance = NULL; + } + memset(ctx, 0x0, sizeof(crypto_sha256_context)); +} + +/* + * SHA256 context clone + */ +void crypto_sha256_clone(crypto_sha256_context *dst, const crypto_sha256_context *src) +{ + if (dst == NULL || src == NULL) + { + return; + } + + *dst = *src; +} + +/* + * SHA256 context setup + */ +int crypto_sha256_starts(crypto_sha256_context *ctx) +{ + crypto_sha256_hmac_context_t *hmac_ctx = NULL; + + if (ctx == NULL) + { + return -1; + } + + if (ctx->input != NULL) + { + crypto_free(ctx->input); + ctx->input = NULL; + ctx->block_size = 0; + ctx->total = 0; + } + + hmac_ctx = (crypto_sha256_hmac_context_t *)ctx->instance; + hmac_ctx->hmac_handle.p_instance = HMAC; + hmac_ctx->hmac_handle.init.mode = HMAC_MODE_SHA; + hmac_ctx->hmac_handle.init.p_key = NULL; + hmac_ctx->hmac_handle.init.p_user_hash = NULL; + hmac_ctx->hmac_handle.init.dpa_mode = DISABLE; + + return 0; +} + +/* + * SHA256 update + */ +int crypto_sha256_update(crypto_sha256_context *ctx, const uint8_t *input, size_t ilen) +{ + int total_len = ilen + ctx->total; + int i = 0; + uint8_t *new_input = NULL; + + if (ctx == NULL || input == NULL) + { + return -1; + } + + if (ctx->input == NULL || total_len > ctx->block_size) + { + ctx->block_size = (total_len / SHA256_BLOCK_SIZE + 1) * SHA256_BLOCK_SIZE; + new_input = crypto_malloc(ctx->block_size); + if (new_input == NULL) + { + return -1; + } + memset(new_input, 0, ctx->block_size); + for (i = 0; i < ctx->total; i++) + { + new_input[i] = ctx->input[i]; + } + for (int j = 0; j < ilen; j++) + { + new_input[i] = input[j]; + i++; + } + if (ctx->input != NULL) + { + crypto_free(ctx->input); + } + ctx->input = new_input; + } + else + { + i = ctx->total; + for (int j = 0; j < ilen; j++) + { + ctx->input[i] = input[j]; + i++; + } + } + + ctx->total = total_len; + return 0; +} + +static int crypto_internal_sha256_finish(crypto_sha256_context *ctx, uint8_t *output) +{ + crypto_sha256_hmac_context_t *hmac_ctx = NULL; + int ret = 0; + uint8_t buf[SHA256_SIZE] = {0}; + + if (ctx == NULL || output == NULL) + { + return -1; + } + + hmac_ctx = (crypto_sha256_hmac_context_t *)ctx->instance; + hal_hmac_deinit(&hmac_ctx->hmac_handle); + hal_hmac_init(&hmac_ctx->hmac_handle); + + ret = hal_hmac_sha256_digest(&hmac_ctx->hmac_handle, (uint32_t *)ctx->input, ctx->total, (uint32_t *)buf, 5000); + if (0 != ret) + { + return -1; + } + + memcpy(output, buf, SHA256_SIZE); + hal_hmac_deinit(&hmac_ctx->hmac_handle); + + return ret; +} + +/* + * SHA256 finish + */ +int crypto_sha256_finish(crypto_sha256_context *ctx, uint8_t output[32]) +{ + if (ctx == NULL || output == NULL) + { + return -1; + } + + return crypto_internal_sha256_finish(ctx, output); +} + +/* + * SHA256 compute + */ +int crypto_sha256(const uint8_t *input, size_t ilen, uint8_t output[32]) +{ + int ret = 0; + crypto_sha256_context ctx = { 0 }; + + if (NULL == input) + { + return (-1); + } + + crypto_sha256_init(&ctx); + + if ((ret = crypto_sha256_starts(&ctx)) != 0) + goto exit; + + if ((ret = crypto_sha256_update(&ctx, input, ilen)) != 0) + goto exit; + + if ((ret = crypto_sha256_finish(&ctx, output)) != 0) + goto exit; + +exit: + crypto_sha256_free(&ctx); + + return (ret); +} + +/*********************************************************************/ + +int crypto_hmac_sha256_starts(crypto_sha256_context *ctx, const uint8_t *key, size_t keylen) +{ + crypto_sha256_hmac_context_t *hmac_ctx = NULL; + + if (ctx == NULL || key == NULL || keylen != HMAC_SHA256_KEY_SIZE) + { + return -1; + } + + if (ctx->input != NULL) + { + crypto_free(ctx->input); + ctx->input = NULL; + ctx->block_size = 0; + ctx->total = 0; + } + + hmac_ctx = (crypto_sha256_hmac_context_t *)ctx->instance; + hmac_ctx->hmac_handle.p_instance = HMAC; + hmac_ctx->hmac_handle.init.mode = HMAC_MODE_HMAC; + hmac_ctx->hmac_handle.init.key_fetch_type = HAL_HMAC_KEYTYPE_MCU; + hmac_ctx->hmac_handle.init.p_key = (uint32_t *)key; + hmac_ctx->hmac_handle.init.p_user_hash = NULL; + hmac_ctx->hmac_handle.init.dpa_mode = DISABLE; + + return 0; +} + +int crypto_hmac_sha256_update(crypto_sha256_context *ctx, const uint8_t *input, size_t ilen) +{ + return (crypto_sha256_update(ctx, input, ilen)); +} + +int crypto_hmac_sha256_finish(crypto_sha256_context *ctx, uint8_t output[32]) +{ + if (ctx == NULL || output == NULL) + { + return -1; + } + + return crypto_internal_sha256_finish(ctx, output); +} + +int crypto_hmac_sha256(const uint8_t *key, size_t keylen, const uint8_t *input, size_t ilen, uint8_t output[32]) +{ + int ret = 0; + crypto_sha256_context ctx = { 0 }; + + if (NULL == input) + { + return (-1); + } + + crypto_sha256_init(&ctx); + + if ((ret = crypto_hmac_sha256_starts(&ctx, key, keylen)) != 0) + goto exit; + + if ((ret = crypto_hmac_sha256_update(&ctx, input, ilen)) != 0) + goto exit; + + if ((ret = crypto_hmac_sha256_finish(&ctx, output)) != 0) + goto exit; + +exit: + crypto_sha256_free(&ctx); + + return (ret); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/BUILD.gn new file mode 100644 index 0000000..84c9538 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("dfu_master") { + sources = [ "dfu_master.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.c new file mode 100644 index 0000000..5e888f1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.c @@ -0,0 +1,828 @@ +/** + ***************************************************************************************** + * + * @file dfu_master.c + * + * @brief DFU master Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "dfu_master.h" +#include "flash_scatter_config.h" +#include +#include "app_log.h" +#include "hal_flash.h" + +/* + * DEFINES + **************************************************************************************** + */ +#define ONCE_SEND_LEN 1024 /**< DFU master once send length. */ +#define RECEIVE_MAX_LEN 2048 /**< DFU master receive max length. */ +#define CMD_FRAME_HEADER_L 0x44 /**< CMD header low byte. */ +#define CMD_FRAME_HEADER_H 0x47 /**< CMD header high byte. */ +#define GET_INFO 0x01 /**< Get info cmd. */ +#define PROGRAM_START 0x23 /**< Program start cmd. */ +#define PROGRAME_FLASH 0x24 /**< Program flash cmd. */ +#define PROGRAME_END 0x25 /**< Program end cmd. */ +#define SYSTEM_INFO 0x27 /**< System information cmd. */ +#define DFU_MODE_SET 0x41 /**< Dfu mode set cmd. */ +#define DFU_FW_INFO_GET 0x42 /**< Dfu fw info get cmd. */ +#define ACK_SUCCESS 0x01 /**< CMD ack success. */ +#define ACK_ERROR 0x02 /**< CMD ack error. */ + +#define DFU_ERASE_REGION_NOT_ALIGNED 0x00 /**< FW erase region not aligned. */ +#define DFU_ERASE_START_SUCCESS 0x01 /**< FW erase start sucess event. */ +#define DFU_ERASEING_SUCCESS 0x02 /**< FW erase flash sucess event. */ +#define DFU_ERASE_END_SUCCESS 0x03 /**< FW erase end sucess event. */ +#define DFU_ERASE_REGIONS_OVERLAP 0x04 /**< FW erase regions overlap. */ +#define DFU_ERASEING_FAIL 0x05 /**< FW erase flash fail event. */ +#define DFU_ERASE_REGIONS_NOT_EXIS 0x06 /**< FW erase regions not exist. */ +#define FAST_DFU_FLASH_SUCCESS 0xFF /**< FW write flash success. */ + +#define FLASH_OP_PAGE_SIZE 0x1000 /**< Flash page size. */ +#define PATTERN_VALUE (0x4744) /**< Pattern value. */ + +#define FW_SIGN_FLAG_OFFSET 72 /**< Firmware sign flag offset. */ +#define SIGN_FW_TYPE 0x10 /**< Sign Firmware Type. */ +#define NORMAL_FW_TYPE 0x00 /**< Normal Firmaware Type. */ + + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/**@brief DFU master submachine state. */ +typedef enum +{ + CHECK_FRAME_L_STATE = 0x00, + CHECK_FRAME_H_STATE, + RECEIVE_CMD_TYPE_L_STATE, + RECEIVE_CMD_TYPE_H_STATE, + RECEIVE_LEN_L_STATE, + RECEIVE_LEN_H_STATE, + RECEIVE_DATA_STATE, + RECEIVE_CHECK_SUM_L_STATE, + RECEIVE_CHECK_SUM_H_STATE, +} cmd_parse_state_t; + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief DFU master receive frame structure define. */ +typedef struct +{ + uint16_t cmd_type; + uint16_t data_len; + uint8_t data[RECEIVE_MAX_LEN]; + uint16_t check_sum; +} receive_frame_t; + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +static receive_frame_t s_receive_frame; +static bool s_cmd_receive_flag; +static uint16_t s_receive_data_count; +static uint32_t s_receive_check_sum; + +static dfu_img_info_t s_now_img_info; +static uint32_t s_page_start_addr; +static uint32_t s_all_check_sum; +static uint32_t s_file_size; +static bool s_run_fw_flag; +static dfu_m_func_cfg_t *s_p_func_cfg; + +static uint16_t s_sended_len; +static uint16_t s_all_send_len; +static uint16_t s_once_size = 350; +static uint8_t* s_send_data_buffer; + +static cmd_parse_state_t s_parse_state = CHECK_FRAME_L_STATE; + +static bool s_sec_flag = false; +static bool s_version_flag = false; + +static uint16_t s_erase_all_count = 0; + +uint8_t dfu_mode_set = 0; +uint32_t dfu_save_addr = 0; +uint8_t fast_dfu_mode = 0; +uint32_t s_program_size; +/** + ***************************************************************************************** + * @brief Function for getting updated firmware information. + * + * @param[in] img_info: Pointer of firmware information + ***************************************************************************************** + */ +static void dfu_m_get_img_info(dfu_img_info_t *img_info) +{ + if(s_p_func_cfg -> dfu_m_get_img_info != NULL) + { + s_p_func_cfg -> dfu_m_get_img_info(img_info); + } +} + +/** + ***************************************************************************************** + * @brief Function for get updated firmware data.. + * + * @param[in] addr: Get data address. + * @param[in] data: Pointer of get data. + * @param[in] len: Get data length + ***************************************************************************************** + */ +static void dfu_m_get_img_data(uint32_t addr, uint8_t *data, uint16_t len) +{ + if(s_p_func_cfg -> dfu_m_get_img_data != NULL) + { + s_p_func_cfg -> dfu_m_get_img_data(addr, data, len); + } +} + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +static void dfu_m_send_data(uint8_t *data, uint16_t len) +{ + if(s_p_func_cfg -> dfu_m_send_data != NULL) + { + s_p_func_cfg -> dfu_m_send_data(data, len); + } +} + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +static void dfu_m_event_handler(dfu_m_event_t event, uint8_t pre) +{ + if(s_p_func_cfg -> dfu_m_event_handler != NULL) + { + s_p_func_cfg -> dfu_m_event_handler(event, pre); + } +} + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +static void dfu_m_cmd_check(void) +{ + uint16_t i = 0; + for(i=0; i= s_once_size) + { + s_sended_len = s_once_size; + } + else + { + s_sended_len = len; + } + + dfu_m_send_data(s_send_data_buffer,s_sended_len); +} + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +static void dfu_m_send_frame(uint8_t *data,uint16_t len,uint16_t cmd_type) +{ + uint8_t send_data[RECEIVE_MAX_LEN + 8]; + uint16_t i = 0; + uint32_t check_sum = 0; + send_data[0] = CMD_FRAME_HEADER_L; + send_data[1] = CMD_FRAME_HEADER_H; + send_data[2] = cmd_type; + send_data[3] = cmd_type >> 8; + send_data[4] = len; + send_data[5] = len >> 8; + + for(i=2; i<6; i++) + { + check_sum += send_data[i]; + } + + for(i=0; i> 8; + dfu_m_send(send_data,len+8); +} + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +static void dfu_m_program_flash(uint16_t len) +{ + uint16_t i=0; + s_program_size += len; + + dfu_m_get_img_data(s_page_start_addr, &s_receive_frame.data[7], len); + for(i=0; i>8; + s_receive_frame.data[3] = dfu_save_addr>>16; + s_receive_frame.data[4] = dfu_save_addr>>24; + + s_receive_frame.data[5] = len; + s_receive_frame.data[6] = len>>8; + + dfu_m_send_frame(s_receive_frame.data, len+7, PROGRAME_FLASH); + dfu_save_addr += len; + s_page_start_addr += len; +} + +static void dfu_m_fast_program_flash(void) +{ + uint16_t remain; + extern uint8_t ble_send_cplt_flag; + uint16_t i = 0; + + while (s_program_size != s_file_size) + { + if (ble_send_cplt_flag || s_program_size == 0) + { + ble_send_cplt_flag = 0; + + dfu_m_get_img_data(s_page_start_addr, &s_receive_frame.data[0], s_once_size); + + if (s_program_size + s_once_size > s_file_size) + { + remain = s_file_size - s_program_size; + dfu_m_send(&s_receive_frame.data[0], remain); + for (i = 0; i < remain; i++) + { + s_all_check_sum += s_receive_frame.data[i]; + } + s_program_size += remain; + } + else + { + s_program_size += s_once_size; + dfu_m_send(&s_receive_frame.data[0], s_once_size); + for (i = 0; i < s_once_size; i++) + { + s_all_check_sum += s_receive_frame.data[i]; + } + } + + s_page_start_addr += s_once_size; + } + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void dfu_m_send_data_cmpl_process(void) +{ + int remain = s_all_send_len - s_sended_len; + + if(remain >= s_once_size) + { + dfu_m_send_data(&s_send_data_buffer[s_sended_len], s_once_size); + s_sended_len += s_once_size; + } + else if(remain > 0) + { + dfu_m_send_data(&s_send_data_buffer[s_sended_len], remain); + s_sended_len += remain; + } +} + + +void dfu_m_cmd_prase(uint8_t* data,uint16_t len) +{ + uint16_t i = 0; + + if(s_cmd_receive_flag == 0) + { + for(i=0; i= RECEIVE_MAX_LEN) + { + s_parse_state = CHECK_FRAME_L_STATE; + } + else + { + s_receive_data_count = 0; + s_parse_state = RECEIVE_DATA_STATE; + } + } + break; + + case RECEIVE_DATA_STATE: + { + s_receive_frame.data[s_receive_data_count] = data[i]; + if(++s_receive_data_count == s_receive_frame.data_len) + { + s_parse_state = RECEIVE_CHECK_SUM_L_STATE; + } + } + break; + + case RECEIVE_CHECK_SUM_L_STATE: + { + s_receive_frame.check_sum = data[i]; + s_parse_state = RECEIVE_CHECK_SUM_H_STATE; + } + break; + + case RECEIVE_CHECK_SUM_H_STATE: + { + s_receive_frame.check_sum |= (data[i] << 8); + s_parse_state = CHECK_FRAME_L_STATE; + dfu_m_cmd_check(); + } + break; + + default:{s_parse_state=CHECK_FRAME_L_STATE;}break; + } + } + } +} + +void dfu_m_init(dfu_m_func_cfg_t *dfu_m_func_cfg, uint16_t once_send_size) +{ + if(once_send_size != 0) + { + s_once_size = once_send_size; + } + + if(dfu_m_func_cfg != NULL) + { + s_p_func_cfg = dfu_m_func_cfg; + } +} + + +void dfu_m_program_start(bool security, bool run_fw) +{ + uint16_t img_len = sizeof(dfu_img_info_t); + uint32_t fw_sign_flag_addr = 0; + uint8_t fw_sign_flag[4] = {0}; + + s_run_fw_flag = run_fw; + s_page_start_addr = 0; + s_all_check_sum = 0; + s_file_size = 0; + s_program_size = 0; + s_receive_frame.data[0] = 0; + + dfu_m_get_img_info(&s_now_img_info); + + if((s_now_img_info.pattern != PATTERN_VALUE) || \ + (s_now_img_info.boot_info.load_addr % FLASH_OP_PAGE_SIZE != 0)) + { + dfu_m_event_handler(IMG_INFO_CHECK_FAIL, 0); + } + + s_page_start_addr = (s_now_img_info.boot_info.load_addr & 0xfffff000); + + s_now_img_info.boot_info.load_addr = dfu_save_addr; + + if(security)//security mode + { + s_file_size = (s_now_img_info.boot_info.bin_size + 48 + 856); + } + else + { + fw_sign_flag_addr = s_page_start_addr + s_now_img_info.boot_info.bin_size + 48 + FW_SIGN_FLAG_OFFSET; + hal_flash_read(fw_sign_flag_addr, fw_sign_flag, sizeof(fw_sign_flag)); + + if (fw_sign_flag[0] == 0x53 && fw_sign_flag[1] == 0x49 && fw_sign_flag[2] == 0x47 && fw_sign_flag[3] == 0x4E) + { + s_file_size = (s_now_img_info.boot_info.bin_size + 48 + 856); + s_receive_frame.data[0] |= SIGN_FW_TYPE; + } + else + { + s_file_size = (s_now_img_info.boot_info.bin_size + 48); + s_receive_frame.data[0] |= NORMAL_FW_TYPE; + } + } + + s_receive_frame.data[0] |= fast_dfu_mode; + + memcpy(&s_receive_frame.data[1], &s_now_img_info, img_len); + + dfu_m_send_frame(s_receive_frame.data, img_len+1, PROGRAM_START); +} + +void dfu_m_parse_state_reset(void) +{ + s_parse_state = CHECK_FRAME_L_STATE; + s_cmd_receive_flag = false; + s_receive_data_count = 0; + s_receive_check_sum = 0; +} + +void dfu_m_get_info(void) +{ + dfu_m_send_frame(s_receive_frame.data, 0, GET_INFO); +} + +void dfu_m_dfu_mode_set(uint8_t dfu_mode) +{ + s_receive_frame.data[0] = dfu_mode; + dfu_m_send_frame(s_receive_frame.data, 1, DFU_MODE_SET); +} + +void dfu_m_dfu_fw_info_get(void) +{ + dfu_m_send_frame(s_receive_frame.data, 0, DFU_FW_INFO_GET); +} + +void dfu_m_system_info_get(void) +{ + // read + uint32_t addr = FLASH_START_ADDR; + s_receive_frame.data[0] = 0x00; + // address + s_receive_frame.data[1] = addr; + s_receive_frame.data[2] = addr >> 8; + s_receive_frame.data[3] = addr >> 16; + s_receive_frame.data[4] = addr >> 24; + //length + s_receive_frame.data[5] = 0x07; + s_receive_frame.data[6] = 0; + + dfu_m_send_frame(s_receive_frame.data, 7, SYSTEM_INFO); +} + +bool dfu_m_get_sec_flag(void) +{ + return s_sec_flag; +} + +void dfu_m_schedule(dfu_m_rev_cmd_cb_t rev_cmd_cb) +{ + uint8_t pre = 0; + uint16_t erase_count = 0; + + if(s_cmd_receive_flag) + { + if (rev_cmd_cb) + { + rev_cmd_cb(); + } + + switch (s_receive_frame.cmd_type) + { + case PROGRAM_START: + if(s_receive_frame.data[0] == ACK_SUCCESS) + { + if (0x00 == fast_dfu_mode) + { + dfu_m_program_flash(ONCE_SEND_LEN); + dfu_m_event_handler(PRO_START_SUCCESS, 0); + } + else if (0x02 == fast_dfu_mode) + { + switch (s_receive_frame.data[1]) + { + case DFU_ERASE_START_SUCCESS: + s_erase_all_count = 0; + s_erase_all_count |= (s_receive_frame.data[2] & 0xff); + s_erase_all_count |= ((s_receive_frame.data[3] << 8) & 0xff00); + dfu_m_event_handler(ERASE_START_SUCCESS, 0); + break; + + case DFU_ERASEING_SUCCESS: + erase_count |= (s_receive_frame.data[2] & 0xff); + erase_count |= ((s_receive_frame.data[3] << 8) & 0xff00); + pre = (erase_count * 100) / s_erase_all_count; + dfu_m_event_handler(ERASEING_SUCCESS, pre); + break; + + case DFU_ERASE_END_SUCCESS: + dfu_m_event_handler(ERASE_END_SUCCESS, 0); + dfu_m_fast_program_flash(); + break; + + case DFU_ERASE_REGION_NOT_ALIGNED: + dfu_m_event_handler(ERASE_REGION_NOT_ALIGNED, 0); + break; + + case DFU_ERASE_REGIONS_OVERLAP: + dfu_m_event_handler(ERASE_REGION_OVERLAP, 0); + break; + + case DFU_ERASEING_FAIL: + dfu_m_event_handler(ERASE_FLASH_FAIL, 0); + break; + + case DFU_ERASE_REGIONS_NOT_EXIS: + dfu_m_event_handler(ERASE_REGION_NOT_EXIST, 0); + break; + + default: + break; + } + } + } + else + { + dfu_m_event_handler(PRO_START_ERROR, 0); + } + break; + + case PROGRAME_FLASH: + if(s_receive_frame.data[0] == ACK_SUCCESS) + { + pre = (s_program_size * 100) / s_file_size; + dfu_m_event_handler(PRO_FLASH_SUCCESS, pre); + //pro success, precent + if(s_program_size == s_file_size) + { + s_receive_frame.data[0] = s_run_fw_flag; + s_receive_frame.data[1] = s_all_check_sum; + s_receive_frame.data[2] = s_all_check_sum>>8; + s_receive_frame.data[3] = s_all_check_sum>>16; + s_receive_frame.data[4] = s_all_check_sum>>24; + dfu_m_send_frame(s_receive_frame.data, 5, PROGRAME_END);//progem end + } + else if(s_program_size + ONCE_SEND_LEN > s_file_size) + { + dfu_m_program_flash(s_file_size - s_program_size); + } + else + { + dfu_m_program_flash(ONCE_SEND_LEN); + } + } + else + { + dfu_m_event_handler(PRO_FLASH_FAIL, pre); + } + break; + + case PROGRAME_END: + if(s_receive_frame.data[0] == ACK_SUCCESS) + { + if (fast_dfu_mode == 0x02) + { + uint32_t check_sum = 0; + check_sum |= (s_receive_frame.data[1] & 0xff); + check_sum |= ((s_receive_frame.data[2] << 8) & 0xff00); + check_sum |= ((s_receive_frame.data[3] << 16) & 0xff0000); + check_sum |= ((s_receive_frame.data[4] << 24) & 0xff000000); + + if (check_sum == s_all_check_sum) + { + dfu_m_event_handler(PRO_END_SUCCESS, 0); + } + else + { + dfu_m_event_handler(PRO_END_FAIL, 0); + } + } + else if (fast_dfu_mode == 0x00) + { + dfu_m_event_handler(PRO_END_SUCCESS, 0); + } + } + else + { + dfu_m_event_handler(PRO_END_FAIL, 0); + } + break; + + case GET_INFO: + dfu_save_addr = 0; + if(s_receive_frame.data[0] == ACK_SUCCESS) + { + // dfu version + if (s_receive_frame.data[17] == DFU_VERSION) + { + s_version_flag = 1; // new version + } + else + { + s_version_flag = 0; // old version + } + dfu_m_system_info_get(); + } + else + { + dfu_m_event_handler(GET_INFO_FAIL, 0); + } + break; + + case DFU_FW_INFO_GET: + if (s_receive_frame.data[0] == ACK_SUCCESS) + { + dfu_save_addr = 0; + dfu_save_addr |= (s_receive_frame.data[1] & 0xff); + dfu_save_addr |= ((s_receive_frame.data[2] << 8) & 0xff00); + dfu_save_addr |= ((s_receive_frame.data[3] << 16) & 0xff0000); + dfu_save_addr |= ((s_receive_frame.data[4] << 24) & 0xff000000); + + dfu_m_dfu_mode_set(0x01); + } + else + { + // error + } + break; + + case SYSTEM_INFO: + if(s_receive_frame.data[0] == ACK_SUCCESS) + { + // security mode + if (s_receive_frame.data[1]) + { + s_sec_flag = true; + } + else + { + s_sec_flag = false; + } + + if (s_version_flag) + { + dfu_m_dfu_fw_info_get(); + } + } + break; + + case FAST_DFU_FLASH_SUCCESS: + if (s_receive_frame.data[0] == ACK_SUCCESS) + { + s_receive_frame.data[0] = s_run_fw_flag; + s_receive_frame.data[1] = s_all_check_sum; + s_receive_frame.data[2] = s_all_check_sum>>8; + s_receive_frame.data[3] = s_all_check_sum>>16; + s_receive_frame.data[4] = s_all_check_sum>>24; + dfu_m_send_frame(s_receive_frame.data, 5, PROGRAME_END);//progem end + } + else + { + dfu_m_event_handler(FAST_DFU_FLASH_FAIL, 0); + } + break; + + default: + break; + } + + s_cmd_receive_flag = 0; + } +} + + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.h new file mode 100644 index 0000000..39c731b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_master/dfu_master.h @@ -0,0 +1,203 @@ +/** + ***************************************************************************************** + * + * @file dfu_master.h + * + * @brief DFU master API. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __DFU_MASTER_H__ +#define __DFU_MASTER_H__ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include +#include "gr55xx_dfu.h" + + +#define DFU_VERSION 0x02 /**< The DFU Version. */ + +/** + * @defgroup DFU_MASTER_ENUM Enumerations + * @{ + */ +/**@brief DFU master event type definition. */ +typedef enum +{ + FRAM_CHECK_ERROR = 0, /**< Frame check error event. */ + IMG_INFO_CHECK_FAIL, /**< FW info check event. */ + GET_INFO_FAIL, /**< GET info error event. */ + PRO_START_ERROR, /**< FW program start error event. */ + PRO_START_SUCCESS, /**< FW program start success event. */ + PRO_FLASH_SUCCESS, /**< FW program success event. */ + PRO_FLASH_FAIL, /**< FW program fail event. */ + PRO_END_SUCCESS, /**< FW program end success event. */ + PRO_END_FAIL, /**< FW program end fail event. */ + ERASE_START_SUCCESS, /**< Erase Flash success. */ + ERASEING_SUCCESS, /**< Erasing Flash success. */ + ERASE_END_SUCCESS, /**< Erase end success. */ + ERASE_REGION_NOT_ALIGNED, /**< Erase regions not aligned. */ + ERASE_REGION_OVERLAP, /**< Erase regions overlap. */ + ERASE_FLASH_FAIL, /**< Erase flash fail. */ + ERASE_REGION_NOT_EXIST, /**< Erase region not exist. */ + FAST_DFU_FLASH_FAIL /**< FW write flash error. */ +}dfu_m_event_t; +/** @} */ + +/** + * @defgroup DFU_MASTER_STRUCT Structures + * @{ + */ +/**@brief IMG information definition. */ +typedef struct +{ + uint16_t pattern; /**< IMG info pattern. */ + uint16_t version; /**< IMG version. */ + dfu_boot_info_t boot_info; /**< IMG boot info. */ + uint8_t comments[12]; /**< IMG comments. */ +}dfu_img_info_t; + +/**@brief DFU master used function config definition. */ +typedef struct +{ + void(*dfu_m_get_img_info)(dfu_img_info_t *img_info); /**< This function is used to get updated firmware information. */ + void (*dfu_m_get_img_data)(uint32_t addr, uint8_t *data, uint16_t len); /**< This function is used to get updated firmware data. */ + void (*dfu_m_send_data)(uint8_t *data, uint16_t len); /**< This function is used to send data to peer device. */ + void (*dfu_m_event_handler)(dfu_m_event_t event, uint8_t pre); /**< This function is used to send event to app. */ +}dfu_m_func_cfg_t; +/** @} */ + +/** + * @defgroup DFU_MASTER_TYPEDEF Typedefs + * @{ + */ +/**@brief DFU Master Receive CMD Callback type. */ +typedef void (*dfu_m_rev_cmd_cb_t)(void); +/** @} */ + +/** + * @defgroup DFU_MASTER_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Function for reset the DFU cmd parse state. + ***************************************************************************************** + */ +void dfu_m_parse_state_reset(void); + +/** + ***************************************************************************************** + * @brief Function for checking DFU master cmd. + * + * @note This function should be called in loop. + ***************************************************************************************** + */ +void dfu_m_schedule(dfu_m_rev_cmd_cb_t rev_cmd_cb); + +/** + ***************************************************************************************** + * @brief Function for start update firmware. + * + * @param[in] security: Upgrade firmware is encrypted?. + * @param[in] run_fw: Whether to run the firmware immediately after the upgrade. + ***************************************************************************************** + */ +void dfu_m_program_start(bool security, bool run_fw); + +/** + ***************************************************************************************** + * @brief Function for get system information. + * + ***************************************************************************************** + */ +void dfu_m_system_info_get(void); + +/** + ***************************************************************************************** + * @brief Function for get information. + * + ***************************************************************************************** + */ +void dfu_m_get_info(void); + +/** + ***************************************************************************************** + * @brief Function for set dfu mode. + * + ***************************************************************************************** + */ +void dfu_m_dfu_mode_set(uint8_t dfu_mode); + +/** + ***************************************************************************************** + * @brief Function for get security mode. + * @return Result of security mode. + ***************************************************************************************** + */ +bool dfu_m_get_sec_flag(void); + +/** + ***************************************************************************************** + * @brief Function for initializing the DFU master. + * + * @note When APP wants to add DFU master feature,all functions in @ref dfu_m_func_cfg_t should be registered. + * + * @param[in] dfu_m_func_cfg: DFU master used functions. + * @param[in] once_send_size: DFU master once send size. + ***************************************************************************************** + */ +void dfu_m_init(dfu_m_func_cfg_t *dfu_m_func_cfg, uint16_t once_send_size); + +/** + ***************************************************************************************** + * @brief Function for prase received data. + * + * @param[in] data: Received data. + * @param[in] len: Data length. + ***************************************************************************************** + */ +void dfu_m_cmd_prase(uint8_t* data,uint16_t len); + +/** + ***************************************************************************************** + * @brief This function should be called when data sended completely. + * + * @retval void + ***************************************************************************************** + */ +void dfu_m_send_data_cmpl_process(void); + +/** @} */ +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/BUILD.gn new file mode 100644 index 0000000..ead8b87 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("dfu_port") { + sources = [ "dfu_port.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.c new file mode 100644 index 0000000..4fc29f1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.c @@ -0,0 +1,1179 @@ +/** + ***************************************************************************************** + * + * @file dfu_port.c + * + * @brief DFU port Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + /* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "dfu_port.h" +#include "hal_flash.h" +#include "grx_hal.h" +#include "otas.h" +#include "grx_sys.h" +#include "ring_buffer.h" +#include "flash_scatter_config.h" +#ifdef ENABLE_DFU_SPI_FLASH + #include "gr55xx_spi_flash.h" +#endif + + +#define FAST_DFU_INIT_STATE 0x00 +#define FAST_DFU_ERASE_FLASH_STATE 0x01 +#define FAST_DFU_PROGRAM_FLASH_STATE 0x02 + +#ifdef SOC_GR5332 +#define CATCH_BUFFER_SIZE (1024*4 + 32) +#define ENV_BUFFER_SIZE 400 +#define ENV_CHECK_SUM_OFFSET 0x28 +#endif + + +enum +{ + DFU_ACK_SUCCESS = 0x01, + DFU_ACK_ERROR, +}; + +enum +{ + DFU_FLASH_INNER, + DFU_FLASH_SPI = 0x01, + + FAST_DFU_INNER = 0x02, + FAST_DFU_SPI = 0X03, +}; + +enum +{ + NORMAL_FIRMWARE = 0x00, + SIGN_FIRMWARE = 0x01, + SECURITY_SIGN_FIRMWARE = 0x02, +}; + +enum +{ + DFU_ERASE_FLASH_ERROR = 0x00, + DFU_ERASE_FLASH_START, + DFU_ERASING_FLASH, + DFU_ERASE_FLASH_END, + DFU_ERASE_FLASH_OVERLAP, + DFU_ERASE_FLASH_OPER_FAILED, + DFU_ERASE_EXT_FLASH_NOT_EXIST, +}; + +#ifdef SOC_GR5332 +extern uint32_t dfu_env_all; +#else +extern uint32_t all_check_sum; +#endif + +extern uint8_t cmd_receive_flag; +extern uint32_t page_start_addr; + +extern void dfu_programing(uint16_t len); +extern void dfu_flash_type_set(uint8_t flash_type); +extern void dfu_program_start(uint32_t all_size); +extern uint32_t dfu_flash_write(const uint32_t addr,const uint8_t *buf, const uint32_t size); +extern uint32_t dfu_flash_read(const uint32_t addr,const uint8_t *buf, const uint32_t size); +extern bool dfu_flash_erase(const uint32_t addr, const uint32_t size); +extern void normal_dfu_schedule(void); + +#ifdef SOC_GR5526 +extern void send_frame_state(dfu_receive_frame_t *p_frame, uint8_t state); +extern uint32_t dfu_flash_cal_check_sum(uint32_t start_addr, uint16_t len); +extern uint32_t dfu_flash_programe(uint32_t address, uint8_t *p_write_buf, uint16_t write_len); +#endif + +#ifdef SOC_GR5332 +extern void dfu_programing_start(uint32_t all_size); +extern void dfu_programing_end(uint8_t status); +extern void dfu_frame_send(uint8_t *data,uint16_t len,uint16_t cmd_type); +#else +extern void dfu_program_start(uint32_t all_size); +extern void dfu_program_end(uint8_t status); +extern bool dfu_security_check_enable(void); +extern void dfu_send_frame(uint8_t *data,uint16_t len,uint16_t cmd_type); +#endif + +static void ble_send_data(uint8_t *p_data, uint16_t length); + +static dfu_info_t s_dfu_info; +static ring_buffer_t s_ble_rx_ring_buffer; +static uint8_t s_write_data[ONCE_WRITE_DATA_LEN]; +static bool s_ring_buffer_over_flag = false; +static uint8_t s_fast_dfu_state = FAST_DFU_INIT_STATE; +static bool s_program_end_flag = false; +static uint32_t s_program_address = 0x00; +static uint32_t s_file_size = 0x00; +static uint16_t s_erase_all_count = 0; +static uint32_t s_all_write_size = 0x00; +static uint16_t s_erase_count = 0; +static uint8_t s_fast_dfu_mode = 0x00; +static uint8_t s_data_buffer[DFU_BUFFER_SIZE]; +static dfu_image_info_t s_now_img_info; +static dfu_enter_callback s_dfu_enter_func = NULL; + +#ifdef SOC_GR5332 +static uint32_t all_check_sum; +static uint32_t *p_all_check_sum = NULL; +static uint8_t cache_data_buffer[CATCH_BUFFER_SIZE] = {0}; +static uint8_t env_data_buffer[ENV_BUFFER_SIZE] = {0}; + +static dfu_func_t s_dfu_func = +{ + .dfu_ble_send_data = ble_send_data, + .dfu_flash_read = hal_exflash_read, + .dfu_flash_write = hal_exflash_write, + .dfu_flash_erase = hal_exflash_erase, + .dfu_flash_get_info = hal_flash_get_info, + .dfu_flash_feat_enable = NULL, +}; + +static dfu_buf_table_t dfu_buffer = +{ + .frame_buf = s_data_buffer, + .frame_size = DFU_BUFFER_SIZE, + .jlink_buf = NULL, + .jlink_size = 0, + .cache_buf = cache_data_buffer, + .cache_size = CATCH_BUFFER_SIZE, + .env_buf = env_data_buffer, + .env_size = ENV_BUFFER_SIZE, +}; +#else +static bool s_flash_security_status = false; +static dfu_func_t s_dfu_func = +{ + .dfu_ble_send_data = ble_send_data, + .dfu_uart_send_data = NULL, + .dfu_flash_read = hal_flash_read, + .dfu_flash_write = hal_flash_write, + .dfu_flash_erase = hal_flash_erase, + .dfu_flash_erase_chip = hal_flash_erase_chip, + .dfu_flash_set_security = hal_flash_set_security, + .dfu_flash_get_security = hal_flash_get_security, + .dfu_flash_get_info = hal_flash_get_info, +}; +#endif + +#if defined(SOC_GR5526) || defined(SOC_GR5525) +static uint8_t s_flash_buffer[DFU_FLASH_SECTOR_SIZE]; + +static dfu_buffer_t dfu_buffer = +{ + .rec_data_buffer = s_data_buffer, + .rec_data_buffer_size = DFU_BUFFER_SIZE, + .flash_op_buffer = s_flash_buffer, + .flash_op_buffer_size = DFU_FLASH_SECTOR_SIZE +}; +#endif + + +#ifdef ENABLE_DFU_SPI_FLASH +static void dfu_spi_flash_init(uint8_t* p_data); /**< flash init. */ +static uint32_t dfu_spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes); /**< read flash data. */ +static uint32_t dfu_spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes); /**< write flash data. */ +static bool dfu_spi_flash_sector_erase(uint32_t address, uint32_t size); /**< erase flash sector. */ +static bool dfu_spi_flash_chip_erase(void); /**< erase flash chip. */ +static void dfu_spi_flash_device_info(uint32_t *id, uint32_t *size); /**< get flash device information. */ + +static dfu_spi_flash_func_t s_dfu_spi_flash_func= /**< SPI used functions config definition. */ +{ + .dfu_spi_flash_init = dfu_spi_flash_init, + .dfu_spi_flash_read = dfu_spi_flash_read, + .dfu_spi_flash_write = dfu_spi_flash_write, + .dfu_spi_flash_erase = dfu_spi_flash_sector_erase, + .dfu_spi_flash_erase_chip = dfu_spi_flash_chip_erase, + .dfu_spi_flash_get_info = dfu_spi_flash_device_info, +}; +#endif + + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +#ifdef SOC_GR5332 +static void dfu_program_start(uint32_t all_size) +{ + dfu_programing_start(all_size); +} + +static void dfu_program_end(uint8_t status) +{ + dfu_programing_end(status); +} + +static void dfu_send_frame(uint8_t *data,uint16_t len,uint16_t cmd_type) +{ + dfu_frame_send(data, len, cmd_type); +} +#endif + + +#ifdef ENABLE_DFU_SPI_FLASH + +static void dfu_spi_flash_init(uint8_t *p_data) +{ + flash_init_t flash_init; + flash_io_t *flash_io = (flash_io_t*)&flash_init.flash_io; + +#ifdef SOC_GR5515 + uint8_t flash_type = p_data[0]; + const app_io_type_t gpio_type[] = {APP_IO_TYPE_NORMAL,APP_IO_TYPE_AON,APP_IO_TYPE_MSIO}; + const uint32_t gpio_pin[] = {APP_IO_PIN_0,APP_IO_PIN_1,APP_IO_PIN_2,APP_IO_PIN_3,APP_IO_PIN_4,APP_IO_PIN_5,APP_IO_PIN_6,APP_IO_PIN_7,\ + APP_IO_PIN_8,APP_IO_PIN_9,APP_IO_PIN_10,APP_IO_PIN_11,APP_IO_PIN_12,APP_IO_PIN_13,APP_IO_PIN_14,APP_IO_PIN_15,\ + APP_IO_PIN_16,APP_IO_PIN_17,APP_IO_PIN_18,APP_IO_PIN_19,APP_IO_PIN_20,APP_IO_PIN_21,APP_IO_PIN_22,APP_IO_PIN_23,\ + APP_IO_PIN_24,APP_IO_PIN_25,APP_IO_PIN_26,APP_IO_PIN_27,APP_IO_PIN_28,APP_IO_PIN_29,APP_IO_PIN_30,APP_IO_PIN_31,}; + const app_io_mux_t gpio_pin_mux[] = {APP_IO_MUX_0,APP_IO_MUX_1,APP_IO_MUX_2,APP_IO_MUX_3,APP_IO_MUX_4,APP_IO_MUX_5,APP_IO_MUX_6,APP_IO_MUX_7,APP_IO_MUX_8}; + + if (flash_type == 0x01) + { + //SPI flash + flash_io->spi_cs.gpio = gpio_type[p_data[1]]; + flash_io->spi_cs.pin = gpio_pin[p_data[2]]; + flash_io->spi_cs.mux = gpio_pin_mux[p_data[3]]; + flash_io->spi_clk.gpio = gpio_type[p_data[4]]; + flash_io->spi_clk.pin = gpio_pin[p_data[5]]; + flash_io->spi_clk.mux = gpio_pin_mux[p_data[6]]; + flash_io->spi_io0.spim_mosi.gpio = gpio_type[p_data[7]]; + flash_io->spi_io0.spim_mosi.pin = gpio_pin[p_data[8]]; + flash_io->spi_io0.spim_mosi.mux = gpio_pin_mux[p_data[9]]; + flash_io->spi_io1.spim_miso.gpio = gpio_type[p_data[10]]; + flash_io->spi_io1.spim_miso.pin = gpio_pin[p_data[11]]; + flash_io->spi_io1.spim_miso.mux = gpio_pin_mux[p_data[12]]; + + flash_init.spi_type = FLASH_SPIM_ID; + flash_init.is_dual_line = false; + flash_init.is_high_freq = false; + + spi_flash_init(&flash_init); + } + else if (flash_type == 0x02)//QSPI flash + { + flash_io->spi_cs.gpio = gpio_type[p_data[1]]; + flash_io->spi_cs.pin = gpio_pin[p_data[2]]; + flash_io->spi_cs.mux = gpio_pin_mux[p_data[3]]; + flash_io->spi_clk.gpio = gpio_type[p_data[4]]; + flash_io->spi_clk.pin = gpio_pin[p_data[5]]; + flash_io->spi_clk.mux = gpio_pin_mux[p_data[6]]; + flash_io->spi_io0.qspi_io0.gpio = gpio_type[p_data[7]]; + flash_io->spi_io0.qspi_io0.pin = gpio_pin[p_data[8]]; + flash_io->spi_io0.qspi_io0.mux = gpio_pin_mux[p_data[9]]; + flash_io->spi_io1.qspi_io1.gpio = gpio_type[p_data[10]]; + flash_io->spi_io1.qspi_io1.pin = gpio_pin[p_data[11]]; + flash_io->spi_io1.qspi_io1.mux = gpio_pin_mux[p_data[12]]; + flash_io->qspi_io2.gpio = gpio_type[p_data[13]]; + flash_io->qspi_io2.pin = gpio_pin[p_data[14]]; + flash_io->qspi_io2.mux = gpio_pin_mux[p_data[15]]; + flash_io->qspi_io3.gpio = gpio_type[p_data[16]]; + flash_io->qspi_io3.pin = gpio_pin[p_data[17]]; + flash_io->qspi_io3.mux = gpio_pin_mux[p_data[18]]; + + flash_init.spi_type = p_data[19] ? FLASH_QSPI_ID1 : FLASH_QSPI_ID0; + flash_init.is_dual_line = false; + flash_init.is_high_freq = false; + + spi_flash_init(&flash_init); + } + else + { + //Unkown flash type + } +#endif + +#if defined(SOC_GR5525) || defined(SOC_GR5526) + uint8_t ssi_id; + + uint8_t flash_type = p_data[0]; + const app_io_type_t gpio_type[] = {APP_IO_TYPE_GPIOA, APP_IO_TYPE_GPIOB, APP_IO_TYPE_GPIOC, APP_IO_TYPE_AON, APP_IO_TYPE_MSIO, APP_IO_TYPE_NORMAL}; + const uint32_t gpio_pin[] = {APP_IO_PIN_0,APP_IO_PIN_1,APP_IO_PIN_2,APP_IO_PIN_3,APP_IO_PIN_4,APP_IO_PIN_5,APP_IO_PIN_6,APP_IO_PIN_7,\ + APP_IO_PIN_8,APP_IO_PIN_9,APP_IO_PIN_10,APP_IO_PIN_11,APP_IO_PIN_12,APP_IO_PIN_13,APP_IO_PIN_14,APP_IO_PIN_15}; + const app_io_mux_t gpio_pin_mux[] = {APP_IO_MUX_0,APP_IO_MUX_1,APP_IO_MUX_2,APP_IO_MUX_3,APP_IO_MUX_4,APP_IO_MUX_5,APP_IO_MUX_6,APP_IO_MUX_7,APP_IO_MUX_8}; + + if(flash_type == 0x01) + { + //SPI flash + flash_io->spi_cs.gpio = gpio_type[p_data[1]]; + flash_io->spi_cs.pin = gpio_pin[p_data[2]]; + flash_io->spi_cs.mux = gpio_pin_mux[p_data[3]]; + flash_io->spi_clk.gpio = gpio_type[p_data[4]]; + flash_io->spi_clk.pin = gpio_pin[p_data[5]]; + flash_io->spi_clk.mux = gpio_pin_mux[p_data[6]]; + flash_io->spi_io0.spim_mosi.gpio = gpio_type[p_data[7]]; + flash_io->spi_io0.spim_mosi.pin = gpio_pin[p_data[8]]; + flash_io->spi_io0.spim_mosi.mux = gpio_pin_mux[p_data[9]]; + flash_io->spi_io1.spim_miso.gpio = gpio_type[p_data[10]]; + flash_io->spi_io1.spim_miso.pin = gpio_pin[p_data[11]]; + flash_io->spi_io1.spim_miso.mux = gpio_pin_mux[p_data[12]]; + + flash_init.spi_type = FLASH_SPIM_ID; + flash_init.is_dual_line = false; + flash_init.is_high_freq = false; + + spi_flash_init(&flash_init); + } + else if(flash_type == 0x02) + { + //QSPI flash + flash_io->spi_cs.gpio = gpio_type[p_data[1]]; + flash_io->spi_cs.pin = gpio_pin[p_data[2]]; + flash_io->spi_cs.mux = gpio_pin_mux[p_data[3]]; + flash_io->spi_clk.gpio = gpio_type[p_data[4]]; + flash_io->spi_clk.pin = gpio_pin[p_data[5]]; + flash_io->spi_clk.mux = gpio_pin_mux[p_data[6]]; + flash_io->spi_io0.qspi_io0.gpio = gpio_type[p_data[7]]; + flash_io->spi_io0.qspi_io0.pin = gpio_pin[p_data[8]]; + flash_io->spi_io0.qspi_io0.mux = gpio_pin_mux[p_data[9]]; + flash_io->spi_io1.qspi_io1.gpio = gpio_type[p_data[10]]; + flash_io->spi_io1.qspi_io1.pin = gpio_pin[p_data[11]]; + flash_io->spi_io1.qspi_io1.mux = gpio_pin_mux[p_data[12]]; + flash_io->qspi_io2.gpio = gpio_type[p_data[13]]; + flash_io->qspi_io2.pin = gpio_pin[p_data[14]]; + flash_io->qspi_io2.mux = gpio_pin_mux[p_data[15]]; + flash_io->qspi_io3.gpio = gpio_type[p_data[16]]; + flash_io->qspi_io3.pin = gpio_pin[p_data[17]]; + flash_io->qspi_io3.mux = gpio_pin_mux[p_data[18]]; + + ssi_id = p_data[19] & 0x0F; + + flash_init.is_dual_line = false; + flash_init.is_high_freq = false; + flash_init.spi_type = (ssi_id == 0) ? FLASH_QSPI_ID0 : ((ssi_id == 1) ? FLASH_QSPI_ID1 : FLASH_QSPI_ID2); + + spi_flash_init(&flash_init); + } + else + { + //Unkown flash type + } +#endif +} + +static uint32_t dfu_spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + return spi_flash_read(address, buffer, nbytes); +} + +static uint32_t dfu_spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes) +{ + return spi_flash_write(address, buffer, nbytes); +} + +static bool dfu_spi_flash_sector_erase(uint32_t address, uint32_t size) +{ + return spi_flash_sector_erase(address, size); +} + +static bool dfu_spi_flash_chip_erase(void) +{ + return spi_flash_chip_erase(); +} + +static void dfu_spi_flash_device_info(uint32_t *id, uint32_t *size) +{ + spi_flash_device_info(id, size); +} +#endif + + +static void security_disable(void) +{ +#ifndef SOC_GR5332 + uint32_t sys_security = sys_security_enable_status_check(); + if(sys_security) + { + s_flash_security_status = hal_flash_get_security(); + hal_flash_set_security(false); + } +#endif +} + +static void security_state_recovery(void) +{ +#ifndef SOC_GR5332 + uint32_t sys_security = sys_security_enable_status_check(); + if(sys_security) + { + hal_flash_set_security(s_flash_security_status); + } +#endif +} + +static uint32_t hal_flash_read_judge_security(const uint32_t addr, uint8_t *buf, const uint32_t size) +{ + uint32_t read_bytes = 0; + + security_disable(); + read_bytes = hal_flash_read(addr, buf, size); + security_state_recovery(); + + return read_bytes; +} + +static void fast_dfu_write_data_to_buffer(uint8_t const *p_data, uint16_t length) +{ + ring_buffer_write(&s_ble_rx_ring_buffer, p_data, length); + + if(ring_buffer_surplus_space_get(&s_ble_rx_ring_buffer) < (ONCE_WRITE_DATA_LEN)) + { + if(!s_ring_buffer_over_flag) + { + extern uint8_t g_lld_con_heap_used_ratio_limit; + g_lld_con_heap_used_ratio_limit = 0; + s_ring_buffer_over_flag = true; + } + } +} + + +static void otas_evt_process(otas_evt_t *p_evt) +{ + switch (p_evt->evt_type) + { + case OTAS_EVT_TX_NOTIFICATION_ENABLED: + #ifndef SOC_GR5332 + dfu_cmd_parse_state_reset(); + #else + dfu_cmd_parse_reset(); + #endif + break; + + case OTAS_EVT_RX_RECEIVE_DATA: + if (!s_fast_dfu_mode || s_program_end_flag) + { + dfu_ble_receive_data_process(p_evt->p_data, p_evt->length); + } + else + { + s_fast_dfu_state = FAST_DFU_PROGRAM_FLASH_STATE; + fast_dfu_write_data_to_buffer(p_evt->p_data, p_evt->length); + } + break; + + case OTAS_EVT_NOTIFY_COMPLETE: + dfu_ble_send_data_cmpl_process(); + break; + + case OTAS_EVT_DFU_TASK_ENTER: + if(s_dfu_enter_func != NULL) + { + s_dfu_enter_func(); + } + break; + + default: + break; + } +} + + +static void ble_send_data(uint8_t *p_data, uint16_t length) +{ + otas_notify_tx_data(0, p_data, length); +} + +static bool check_system_info_address(uint32_t addr) +{ + return (addr >= FLASH_START_ADDR && addr < (FLASH_START_ADDR + 0x2000)); +} + +static void get_rom_version(uint8_t *p_read_buf) +{ + uint8_t i = 0; + uint32_t address = SYS_ROM_VERSION_ADDR; + while (i < 8) + { + *(p_read_buf + i) = *(__IO uint8_t*) address++; + i++; + } +} + +static void get_info_replace(dfu_receive_frame_t *p_frame) +{ + sdk_version_t sdk_version; + p_frame->data[0] = DFU_ACK_SUCCESS; + get_rom_version(&p_frame->data[1]); + + sys_sdk_verison_get(&sdk_version); + memcpy(&p_frame->data[9], &sdk_version, sizeof(sdk_version_t)); + + p_frame->data[17] = OTAS_VERSION; + + dfu_send_frame(p_frame->data, 20, p_frame->cmd_type); + cmd_receive_flag = 0; +} + +static void dfu_mode_set(dfu_receive_frame_t *p_frame) +{ + if (p_frame->data[0] == OTAS_DFU_MODE_COPY_UPGRADE) + { + s_dfu_info.dfu_mode_pattern = DFU_COPY_UPGRADE_MODE_PATTERN; + cmd_receive_flag = 0; + } + else + { + s_dfu_info.dfu_mode_pattern = DFU_NON_COPY_UPGRADE_MODE_PATTERN; + + security_disable(); + hal_flash_erase(DFU_INFO_START_ADDR, DFU_FLASH_SECTOR_SIZE); + hal_flash_write(DFU_INFO_START_ADDR, (uint8_t*)&s_dfu_info, sizeof(s_dfu_info)); + security_state_recovery(); + + hal_nvic_system_reset(); + } +} + +static void dfu_fw_info_get(dfu_receive_frame_t *p_frame) +{ + extern struct otas_env_t s_otas_env; + + p_frame->data[0] = DFU_ACK_SUCCESS; + p_frame->data[1] = s_dfu_info.dfu_fw_save_addr & 0xff; + p_frame->data[2] = (s_dfu_info.dfu_fw_save_addr >> 8) & 0xff; + p_frame->data[3] = (s_dfu_info.dfu_fw_save_addr >> 16) & 0xff; + p_frame->data[4] = (s_dfu_info.dfu_fw_save_addr >> 24) & 0xff; + +#ifdef BOOTLOADER_ENABLE + p_frame->data[5] = 0x00; // app bootloader +#else + p_frame->data[5] = 0x01; // app fw +#endif + + hal_flash_read_judge_security(APP_INFO_START_ADDR, (uint8_t *)&p_frame->data[6], sizeof(dfu_image_info_t)); + + dfu_send_frame(p_frame->data, 54, p_frame->cmd_type); + cmd_receive_flag = 0; +} + +static void fast_dfu_erase_flash(void) +{ + if (s_erase_count != s_erase_all_count) + { + uint32_t address = page_start_addr + (s_erase_count * DFU_FLASH_SECTOR_SIZE); +#ifdef SOC_GR5332 + if (!dfu_flash_erase(address, DFU_FLASH_SECTOR_SIZE)) +#else + if (dfu_flash_erase(address, DFU_FLASH_SECTOR_SIZE)) +#endif + { + s_erase_count++; + s_data_buffer[0] = DFU_ACK_SUCCESS; + s_data_buffer[1] = DFU_ERASING_FLASH; + s_data_buffer[2] = s_erase_count & 0xff; + s_data_buffer[3] = (s_erase_count >> 8) & 0xff; + } + else + { + s_data_buffer[0] = DFU_ACK_ERROR; + s_data_buffer[1] = DFU_ERASE_FLASH_OPER_FAILED; + } + } + else + { + s_fast_dfu_state = FAST_DFU_INIT_STATE; + s_data_buffer[0] = DFU_ACK_SUCCESS; + s_data_buffer[1] = DFU_ERASE_FLASH_END; + } + dfu_send_frame(s_data_buffer, 4, 0x23); +} + +static void fast_dfu_cal_check_sum(uint32_t address, uint16_t len) +{ + security_disable(); + dfu_flash_read(address, s_write_data, len); + security_state_recovery(); + + for(uint16_t i=0; idata[0] & 0x0F; + +#ifndef SOC_GR5332 + uint8_t firmware_type = (p_frame->data[0] & 0xF0) >> 4; +#else + p_all_check_sum = (uint32_t *)(dfu_env_all + ENV_CHECK_SUM_OFFSET); +#endif + + bool erase_state = false; + + s_fast_dfu_mode = 0x00; + + if (dfu_type == DFU_FLASH_INNER && p_frame->data_len == (sizeof(dfu_image_info_t) + 1)) // code in flash + { + memcpy(&s_now_img_info, &p_frame->data[1], sizeof(dfu_image_info_t)); + + if ((s_now_img_info.pattern != DFU_IMG_INFO_PATTERN) ||\ + (s_now_img_info.boot_info.load_addr % DFU_FLASH_SECTOR_SIZE != 0) ||\ + check_system_info_address(s_now_img_info.boot_info.load_addr)) + { + p_frame->data[0] = DFU_ACK_ERROR; + dfu_send_frame(p_frame->data, 1, p_frame->cmd_type); + return; + } + +#ifndef SOC_GR5332 + if (dfu_security_check_enable() == true)//security mode + { + s_file_size = s_now_img_info.boot_info.bin_size + 48 + 856; + } + else + { + s_file_size = s_now_img_info.boot_info.bin_size + 48; + } +#else + s_file_size = s_now_img_info.boot_info.bin_size + 48; +#endif + + page_start_addr = (s_now_img_info.boot_info.load_addr & 0xfffff000); + } + else if (dfu_type == FAST_DFU_INNER || dfu_type == FAST_DFU_SPI) + { + s_fast_dfu_mode = 0x01; + + if (p_frame->data_len == (sizeof(dfu_image_info_t) + 1)) // code in flash(fast) + { + memcpy(&s_now_img_info, &p_frame->data[1], sizeof(dfu_image_info_t)); + page_start_addr = (s_now_img_info.boot_info.load_addr & 0xfffff000); + +#ifndef SOC_GR5332 + if (dfu_security_check_enable() == true)//security mode + { + s_file_size = s_now_img_info.boot_info.bin_size + 48 + 856; + } + else + { + if (firmware_type == SIGN_FIRMWARE) + { + s_file_size = s_now_img_info.boot_info.bin_size + 48 + 856; + } + else if (firmware_type == SECURITY_SIGN_FIRMWARE) + { + s_file_size = s_now_img_info.boot_info.bin_size + 48 + 856; + } + else + { + s_file_size = s_now_img_info.boot_info.bin_size + 48; + } + } +#else + s_file_size = s_now_img_info.boot_info.bin_size + 48; +#endif + } + else // data or code in exflash or data in flash(fast) + { + page_start_addr = ((p_frame->data[4] << 24) | (p_frame->data[3] << 16) | (p_frame->data[2] << 8) | (p_frame->data[1])); + s_file_size = ((p_frame->data[8] << 24) | (p_frame->data[7] << 16) | (p_frame->data[6] << 8) | (p_frame->data[5])); + s_now_img_info.boot_info.load_addr = page_start_addr; + } + + if (s_file_size % DFU_FLASH_SECTOR_SIZE) + { + s_erase_all_count = (s_file_size / DFU_FLASH_SECTOR_SIZE) + 1; + } + else + { + s_erase_all_count = s_file_size / DFU_FLASH_SECTOR_SIZE; + } + + if (dfu_type == FAST_DFU_INNER) + { + dfu_flash_type_set(DFU_FLASH_INNER); + } + else + { + dfu_flash_type_set(DFU_FLASH_SPI); + } + + s_program_address = page_start_addr; + p_frame->data[0] = DFU_ACK_SUCCESS; + p_frame->data[1] = DFU_ERASE_FLASH_START; + p_frame->data[2] = s_erase_all_count & 0xff; + p_frame->data[3] = (s_erase_all_count >> 8) & 0xff; + dfu_send_frame(p_frame->data, 4, p_frame->cmd_type); + s_fast_dfu_state = FAST_DFU_ERASE_FLASH_STATE; + s_ring_buffer_over_flag = false; + s_all_write_size = 0; + s_erase_count = 0; + all_check_sum = 0; + s_program_end_flag = false; + ring_buffer_init(&s_ble_rx_ring_buffer, s_data_buffer, DFU_BUFFER_SIZE); + ring_buffer_clean(&s_ble_rx_ring_buffer); + dfu_program_start(s_file_size); + cmd_receive_flag = 0; + return ; + } + else// data in flash, data in exflash, code in exflash + { + page_start_addr = ((p_frame->data[4] << 24) | (p_frame->data[3] << 16) | (p_frame->data[2] << 8) | (p_frame->data[1])); + s_file_size = ((p_frame->data[8] << 24) | (p_frame->data[7] << 16) | (p_frame->data[6] << 8) | (p_frame->data[5])); + s_now_img_info.boot_info.load_addr = page_start_addr; + } + + if (dfu_type == DFU_FLASH_INNER) + { + dfu_flash_type_set(DFU_FLASH_INNER); + } + else + { + dfu_flash_type_set(DFU_FLASH_SPI); + } + + erase_state = dfu_flash_erase(page_start_addr, DFU_FLASH_SECTOR_SIZE); + + if (erase_state) + { + p_frame->data[0] = DFU_ACK_SUCCESS; + } + else + { + p_frame->data[0] = DFU_ACK_ERROR; + } + +#ifdef SOC_GR5332 + *p_all_check_sum = 0; +#else + all_check_sum = 0; +#endif + + dfu_send_frame(p_frame->data, 1, p_frame->cmd_type); + cmd_receive_flag = 0; + dfu_program_start(s_file_size); + dfu_flash_type_set(DFU_FLASH_INNER); +} + +#ifdef SOC_GR5526 +static void program_flash_replace(dfu_receive_frame_t *p_frame) +{ + bool flash_security_status = false; + uint8_t program_type = p_frame->data[0] & 0x0f; + uint8_t flash_type = (p_frame->data[0] & 0xf0)>>4; + uint32_t addr = ((p_frame->data[4] << 24) | (p_frame->data[3] << 16) | (p_frame->data[2] << 8) | (p_frame->data[1])); + uint16_t len = ((p_frame->data[6] << 8) | (p_frame->data[5])); + uint16_t program_state = 0; + uint32_t write_len = 0; + uint32_t write_addr = 0; + uint32_t write_offset = 0; + uint16_t temp_len = len; + + dfu_flash_type_set(flash_type); + if((flash_type == DFU_FLASH_INNER) && check_system_info_address(addr)) + { + send_frame_state(p_frame, DFU_ACK_ERROR); + return; + } + + if(dfu_security_check_enable() == true)//security mode + { + flash_security_status = hal_flash_get_security(); + hal_flash_set_security(false); //need Disable flash write Security auto + } + + if(program_type == 0x01)// 4k + { + write_addr = addr; + write_offset = 0; + + while(len) + { + write_len = len > DFU_FLASH_SECTOR_SIZE ? DFU_FLASH_SECTOR_SIZE : len; + + if((write_addr + write_len) >= (page_start_addr + DFU_FLASH_SECTOR_SIZE)) + { + dfu_flash_erase((page_start_addr + DFU_FLASH_SECTOR_SIZE),DFU_FLASH_SECTOR_SIZE); + page_start_addr += DFU_FLASH_SECTOR_SIZE; + } + program_state = dfu_flash_write(write_addr,&(p_frame->data[7+write_offset]),write_len); + if(program_state != 0) + { + all_check_sum += dfu_flash_cal_check_sum(write_addr, write_len); + } + else + { + break; + } + + write_addr += write_len; + write_offset += write_len; + len -= write_len; + } + } + else if(program_type == 0x00) + { + program_state = dfu_flash_programe(addr,&(p_frame->data[7]),len); + } + else if(program_type == 0x02) + { + program_state = dfu_flash_write(addr,&(p_frame->data[7]),len); + } + + if( program_state != 0) + { + p_frame->data[0] = DFU_ACK_SUCCESS; + if(program_type == 0x01) + { + dfu_programing(temp_len); + } + } + else + { + p_frame->data[0] = DFU_ACK_ERROR; + } + + dfu_send_frame(p_frame->data,1,p_frame->cmd_type); + cmd_receive_flag = 0; + + if(dfu_security_check_enable() == true)//security mode + { + hal_flash_set_security(flash_security_status); //recover + } + dfu_flash_type_set(DFU_FLASH_INNER); +} +#endif + +static void program_end_replace(dfu_receive_frame_t *p_frame) +{ + uint8_t check_result = false; + bool reset_device_flag = false; + uint32_t bin_check_sum = 0; + uint8_t end_flag = p_frame->data[0] & 0x0f; + + bin_check_sum = ((p_frame->data[4] << 24) | (p_frame->data[3] << 16) | (p_frame->data[2] << 8) | (p_frame->data[1])); + + if (bin_check_sum == all_check_sum) + { + check_result = true; + } + +#ifdef SOC_GR5332 + if (!s_fast_dfu_mode && bin_check_sum == (*p_all_check_sum)) + { + check_result = true; + } +#endif + + if (check_result) + { + p_frame->data[0] = 0x01; + } + else + { + p_frame->data[0] = 0x02; + } + + p_frame->data[1] = end_flag; + + if (s_fast_dfu_mode) + { + p_frame->data[1] = all_check_sum & 0xff; + p_frame->data[2] = (all_check_sum >> 8) & 0xff; + p_frame->data[3] = (all_check_sum >> 16) & 0xff; + p_frame->data[4] = (all_check_sum >> 24) & 0xff; + + dfu_send_frame(p_frame->data, 5, p_frame->cmd_type); + s_fast_dfu_mode = 0x00; + } + else + { + dfu_send_frame(p_frame->data,1,p_frame->cmd_type); + } + + if (check_result == 0x01) + { + if (end_flag == 0x01 || end_flag == 0x03) + { + ble_gatts_service_changed(); + dfu_program_end(check_result); + + security_disable(); + + s_dfu_info.dfu_fw_save_addr = s_now_img_info.boot_info.load_addr; + + uint32_t fw_img_info_addr = s_dfu_info.dfu_fw_save_addr + s_now_img_info.boot_info.bin_size; + hal_flash_read(fw_img_info_addr, (uint8_t *)&s_dfu_info.dfu_img_info, sizeof(dfu_image_info_t)); + + hal_flash_erase(DFU_INFO_START_ADDR, DFU_FLASH_SECTOR_SIZE); + +#ifdef BOOTLOADER_ENABLE + hal_flash_erase(APP_INFO_START_ADDR, DFU_FLASH_SECTOR_SIZE); + hal_flash_write(APP_INFO_START_ADDR, (uint8_t*)&s_dfu_info.dfu_img_info, sizeof(s_dfu_info.dfu_img_info)); +#else + hal_flash_write(DFU_INFO_START_ADDR, (uint8_t*)&s_dfu_info, sizeof(s_dfu_info)); +#endif + + security_state_recovery(); + if (end_flag == 0x01) + { + reset_device_flag = true; + delay_ms(200); + hal_nvic_system_reset(); + } + } + } + + if (reset_device_flag == false) + { + dfu_program_end(check_result); + } + dfu_flash_type_set(DFU_FLASH_INNER); + cmd_receive_flag = 0; +} + +uint16_t dfu_port_init(dfu_uart_send_data uart_send_data, uint32_t dfu_fw_save_addr, dfu_pro_callback_t *p_dfu_callback) +{ + memset(&s_dfu_info, 0, sizeof(s_dfu_info)); + + if (uart_send_data != NULL) + { + s_dfu_func.dfu_uart_send_data = uart_send_data; + } + +#ifdef SOC_GR5515 + dfu_init(&s_dfu_func, s_data_buffer, p_dfu_callback); + s_dfu_info.dfu_fw_save_addr = dfu_fw_save_addr; + + dfu_set_cmd_handler(0x00, 0x01, get_info_replace); + dfu_set_cmd_handler(0x06, 0X23, program_start_replace); + dfu_set_cmd_handler(0x08, 0x25, program_end_replace); + + dfu_set_cmd_handler(0x1C, 0X41, dfu_mode_set); + dfu_set_cmd_handler(0x1D, 0X42, dfu_fw_info_get); +#endif + +#ifdef SOC_GR5525 + dfu_init(&s_dfu_func, &dfu_buffer, p_dfu_callback); + s_dfu_info.dfu_fw_save_addr = dfu_fw_save_addr; + + dfu_set_cmd_handler(0x00, 0x01, get_info_replace); + dfu_set_cmd_handler(0x08, 0X23, program_start_replace); + dfu_set_cmd_handler(0x0A, 0x25, program_end_replace); + + dfu_set_cmd_handler(0x1C, 0X41, dfu_mode_set); + dfu_set_cmd_handler(0x1D, 0X42, dfu_fw_info_get); +#endif + +#ifdef SOC_GR5526 + dfu_init(&s_dfu_func, &dfu_buffer, p_dfu_callback); + s_dfu_info.dfu_fw_save_addr = dfu_fw_save_addr; + + dfu_set_cmd_handler(0x00, 0x01, get_info_replace); + dfu_set_cmd_handler(0x07, 0X23, program_start_replace); + dfu_set_cmd_handler(0x08, 0X24, program_flash_replace); + dfu_set_cmd_handler(0x09, 0x25, program_end_replace); + + dfu_set_cmd_handler(0x1C, 0X41, dfu_mode_set); + dfu_set_cmd_handler(0x1D, 0X42, dfu_fw_info_get); +#endif + +#ifdef SOC_GR5332 + if (SDK_SUCCESS != dfu_init(&s_dfu_func, &dfu_buffer, p_dfu_callback)) + { + return SDK_ERR_SDK_INTERNAL; + } + s_dfu_info.dfu_fw_save_addr = dfu_fw_save_addr; + + dfu_cmd_handler_set(0x00, 0x01, get_info_replace); + dfu_cmd_handler_set(0x08, 0X23, program_start_replace); + dfu_cmd_handler_set(0x0A, 0x25, program_end_replace); + + dfu_cmd_handler_set(0x1C, 0X41, dfu_mode_set); + dfu_cmd_handler_set(0x1D, 0X42, dfu_fw_info_get); +#endif + +#ifdef ENABLE_DFU_SPI_FLASH + dfu_spi_flash_func_config(&s_dfu_spi_flash_func); +#endif + + return SDK_SUCCESS; +} + +void dfu_service_init(dfu_enter_callback dfu_enter) +{ + otas_init_t otas_init; + + if (dfu_enter != NULL) + { + s_dfu_enter_func = dfu_enter; + } + + otas_init.evt_handler = otas_evt_process; + otas_service_init(&otas_init); +} + +#ifdef SOC_GR5332 +void dfu_ble_set_mtu_size(uint16_t mtu_size) +{ + +} +#endif + +static void fast_dfu_program_schedule(void) +{ + uint16_t read_len = 0; + uint16_t items_size = 0; + + items_size = ring_buffer_items_count_get(&s_ble_rx_ring_buffer); + if (items_size >= ONCE_WRITE_DATA_LEN) + { + read_len = ring_buffer_read(&s_ble_rx_ring_buffer, s_write_data, ONCE_WRITE_DATA_LEN); + + security_disable(); + dfu_flash_write(s_program_address, s_write_data, read_len); + security_state_recovery(); + + fast_dfu_cal_check_sum(s_program_address, read_len); + s_all_write_size += read_len; + s_program_address += read_len; + dfu_programing(read_len); + } + else + { + if (s_all_write_size + items_size == s_file_size) + { + read_len = ring_buffer_read(&s_ble_rx_ring_buffer, s_write_data, items_size); + if (read_len) + { + security_disable(); + dfu_flash_write(s_program_address, s_write_data, read_len); + security_state_recovery(); + + fast_dfu_cal_check_sum(s_program_address, read_len); + s_all_write_size += read_len; + } + dfu_programing(read_len); + + s_program_end_flag = true; + s_data_buffer[0] = DFU_ACK_SUCCESS; + dfu_send_frame(s_data_buffer, 1, 0xFF); // write over + s_fast_dfu_state = FAST_DFU_INIT_STATE; + } + } + + if (s_ring_buffer_over_flag && !s_program_end_flag) + { + if (ring_buffer_surplus_space_get(&s_ble_rx_ring_buffer) > ONCE_WRITE_DATA_LEN) + { + sys_lld_max_msg_usage_ratio_set(90); + s_ring_buffer_over_flag = false; + } + } +} + +void fast_dfu_schedule(void) +{ + switch (s_fast_dfu_state) + { + case FAST_DFU_ERASE_FLASH_STATE: + fast_dfu_erase_flash(); + break; + + case FAST_DFU_PROGRAM_FLASH_STATE: + fast_dfu_program_schedule(); + break; + + default: + break; + } +} + +void dfu_schedule(void) +{ + normal_dfu_schedule(); + fast_dfu_schedule(); +} + +uint16_t dfu_fw_image_info_get(uint32_t dfu_fw_save_addr, uint32_t fw_image_size, bool is_sign_fw, dfu_image_info_t *p_image_info) +{ + uint32_t fw_image_info_addr; + + if (!p_image_info) + { + return SDK_ERR_POINTER_NULL; + } + + if (is_sign_fw) + { + fw_image_info_addr = dfu_fw_save_addr + fw_image_size - 856; + if (sizeof(dfu_image_info_t) != hal_flash_read(fw_image_info_addr, (uint8_t *)&p_image_info, sizeof(dfu_image_info_t))) + { + return SDK_ERR_SDK_INTERNAL; + } + } + else + { + fw_image_info_addr = dfu_fw_save_addr + fw_image_size - 48; + if (sizeof(dfu_image_info_t) != hal_flash_read(fw_image_info_addr, (uint8_t *)&p_image_info, sizeof(dfu_image_info_t))) + { + return SDK_ERR_SDK_INTERNAL; + } + } + + return SDK_SUCCESS; +} + + +uint16_t dfu_info_update(uint32_t dfu_info_start_addr, dfu_image_info_t *p_image_info, uint32_t dfu_fw_save_addr, uint32_t dfu_mode_pattern) +{ + dfu_info_t dfu_info; + + if (!p_image_info) + { + return SDK_ERR_POINTER_NULL; + } + + dfu_info.dfu_fw_save_addr = dfu_fw_save_addr; + memcpy(&dfu_info.dfu_fw_save_addr, p_image_info, sizeof(dfu_image_info_t)); + dfu_info.dfu_mode_pattern = dfu_mode_pattern; + + if (!hal_flash_erase(dfu_info_start_addr, DFU_FLASH_SECTOR_SIZE)) + { + return SDK_ERR_SDK_INTERNAL; + } + + if (sizeof(dfu_image_info_t) != hal_flash_write(dfu_info_start_addr, (uint8_t *)&dfu_info, sizeof(dfu_info_t))) + { + return SDK_ERR_SDK_INTERNAL; + } + + return SDK_SUCCESS; +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.h new file mode 100644 index 0000000..bf86993 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/dfu_port/dfu_port.h @@ -0,0 +1,133 @@ +/** + ***************************************************************************************** + * + * @file dfu_port.h + * + * @brief DFU port API. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef _DFU_PORT_H__ +#define _DFU_PORT_H__ + +#include "gr_includes.h" +#include "otas.h" + +#define ONCE_WRITE_DATA_LEN 2048 /**< The data length of flash write-once. */ +#define DFU_BUFFER_SIZE 8192 /**< The dfu buffer size. */ + +#define DFU_COPY_UPGRADE_MODE_PATTERN 0x44425942 /**< Double Bank update mode. */ +#define DFU_NON_COPY_UPGRADE_MODE_PATTERN 0x53424e42 /**< Single Bank update mode. */ + +#define DFU_FLASH_SECTOR_SIZE 4096 /**< Flash sector size. */ +#define DFU_INFO_START_ADDR (FLASH_START_ADDR + 0x3000) /**< The start address of dfu info. */ +#define APP_INFO_START_ADDR (FLASH_START_ADDR + 0x2000) /**< The address of app info. */ +#define CHIP_REGS_BASE_ADDR_SEC (PERIPH_BASE + 0x10000) /**< The address of chip regs. */ + + +/**@brief DFU info. */ +typedef struct +{ + uint32_t dfu_fw_save_addr; /**< The save addr of dfu firmware. */ + dfu_image_info_t dfu_img_info; /**< The img_info of dfu firmware. */ + uint32_t dfu_mode_pattern; /**< The dfu mode pattern. */ +} dfu_info_t; + +/**@brief DFU uart send data function definition. */ +typedef void (*dfu_uart_send_data)(uint8_t *p_data, uint16_t length); + +/**@brief DFU enter callback definition. */ +typedef void (*dfu_enter_callback)(void); + +/** + ***************************************************************************************** + * @brief DFU BLE service init. + * + * @param[in] dfu_enter: DFU enter callback. + ***************************************************************************************** + */ +void dfu_service_init(dfu_enter_callback dfu_enter); + +/** + ***************************************************************************************** + * @brief DFU port init. + * @details If not using serial port update function, uart_send_data can be set NULL. + if the user doesn't care about the upgrade status,p_dfu_callback can set NULL. + * + * @param[in] uart_send_data : Function is used to send data to master by UART. + * @param[in] dfu_fw_save_addr: The start address of the upgraded firmware stored in flash + * @param[in] p_dfu_callback : DFU program state callback functions. + ***************************************************************************************** + */ +uint16_t dfu_port_init(dfu_uart_send_data uart_send_data, uint32_t dfu_fw_save_addr, dfu_pro_callback_t *p_dfu_callback); + +/** + ***************************************************************************************** + * @brief Function for checking DFU cmd. + * + * @note This function should be called in main loop. + ***************************************************************************************** + */ +void dfu_schedule(void); + +/** + **************************************************************************************** + * @brief get the dfu firmware image info. + * + * @param[in] dfu_fw_save_addr: The dfu firmware save address + * @param[in] fw_image_size : The size of firmware + * @param[in] is_sign_fw : Whether it is an sign firware + * @param[out] p_image_info : The temporary variables that save imag_info + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t dfu_fw_image_info_get(uint32_t dfu_fw_save_addr, uint32_t fw_image_size, bool is_sign_fw, dfu_image_info_t *p_image_info); + + +/** + **************************************************************************************** + * @brief Update the dfu info + * + * @param[in] dfu_info_start_addr : The start address of dfu info + * @param[in] p_image_info : The image info of update + * @param[in] dfu_fw_save_addr : The start address of dfu firmware + * @param[in] dfu_mode_pattern : The dfu mode pattern + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t dfu_info_update(uint32_t dfu_info_start_addr, dfu_image_info_t *p_image_info, uint32_t dfu_fw_save_addr, uint32_t dfu_mode_pattern); +/** @} */ + + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/BUILD.gn new file mode 100644 index 0000000..a3713d9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("fault_trace") { + sources = [ "fault_trace.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.c new file mode 100644 index 0000000..8fe5d6e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.c @@ -0,0 +1,480 @@ +/** + ***************************************************************************************** + * + * @file fault_trace.c + * + * @brief App Log Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "fault_trace.h" +#include "app_assert.h" +#include "grx_sys.h" +#include +#include +#include + +#if SYS_FAULT_TRACE_ENABLE + +/* + * DEFINES + ***************************************************************************************** + */ +#define FAULT_INFO_NVDS_TAG_BASE 0xA000 +#define FAULT_INFO_DB_ENV_TAG FAULT_INFO_NVDS_TAG_BASE + 0 +#define FAULT_INFO_DB_ENV_LEN sizeof(fault_info_db_env_t) +#define FAULT_INFO_LEN_MAX 1024 +#define ASSERT_FILE_NAME_LEN 64 +#define ASSERT_EXPR_NAME_LEN 64 + +#define ASSERT_ERROR 0x01 /**< Assert type: Error. */ +#define ASSERT_WARNING 0x02 /**< Assert type: Waring. */ +#define ASSERT_PARAM 0x03 /**< Assert type: Parameter check. */ + +/* + * STRUCTURES + ***************************************************************************************** + */ +/**@brief Assert information save. */ +typedef struct +{ + uint8_t assert_type; + char file_name[ASSERT_FILE_NAME_LEN]; + int file_line; + int param0; + int param1; + char expr[ASSERT_EXPR_NAME_LEN]; +} assert_info_t; + + + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +static fault_info_db_env_t s_fault_info_db_env; +static char s_fault_info[FAULT_INFO_LEN_MAX] = {0}; +static assert_info_t s_assert_info; + + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + ***************************************************************************************** + * @brief Assert info save. + * + * @param[in] p_assert_info: Pointer to assert info. + ***************************************************************************************** + */ +SECTION_RAM_CODE static void assert_info_save(assert_info_t *p_assert_info) +{ + memset(s_fault_info, 0, FAULT_INFO_LEN_MAX); + + p_assert_info->file_name[ASSERT_FILE_NAME_LEN - 1] = ' '; + p_assert_info->expr[ASSERT_EXPR_NAME_LEN - 1] = ' '; + + + if (ASSERT_ERROR == p_assert_info->assert_type) + { + sprintf(s_fault_info, + "(%s: %d) [ERROR] %s\r\n", + p_assert_info->file_name, + p_assert_info->file_line, + p_assert_info->expr); + } + else if (ASSERT_WARNING == p_assert_info->assert_type) + { + sprintf(s_fault_info, + "(%s: %d) [WARNING] Param0:%d,Param1:%d\r\n", + p_assert_info->file_name, + p_assert_info->file_line, + p_assert_info->param0, + p_assert_info->param1); + } + else if (ASSERT_PARAM == p_assert_info->assert_type) + { + sprintf(s_fault_info,"(%s: %d) [PARAM] Param0:%d,Param1:%d\r\n", + p_assert_info->file_name, + p_assert_info->file_line, + p_assert_info->param0, + p_assert_info->param1); + } + + fault_db_record_add((uint8_t *)s_fault_info, strlen(s_fault_info)); +} + +/** + ***************************************************************************************** + * @brief Assert warning callback. + * + * @param[in] param0: Parameter 0. + * @param[in] param1: Parameter 1. + * @param[in] file: File name. + * @param[in] line: Line number. + ***************************************************************************************** + */ +SECTION_RAM_CODE void app_assert_warn_cb(int param0, int param1, const char *file, int line) +{ + uint32_t file_name_len = 0; + + file_name_len = (ASSERT_FILE_NAME_LEN < strlen(file)) ? ASSERT_FILE_NAME_LEN : strlen(file); + + memset(&s_assert_info, 0, sizeof(assert_info_t)); + memcpy(s_assert_info.file_name, file, file_name_len); + + s_assert_info.assert_type = ASSERT_WARNING; + s_assert_info.file_line = line; + s_assert_info.param0 = param0; + s_assert_info.param1 = param1; + + assert_info_save(&s_assert_info); +} + +/** + ***************************************************************************************** + * @brief Assert param callback. + * + * @param[in] param0: Parameter 0. + * @param[in] param1: Parameter 1. + * @param[in] file: File name. + * @param[in] line: Line number. + ***************************************************************************************** + */ +SECTION_RAM_CODE void app_assert_param_cb(int param0, int param1, const char *file, int line) +{ + __disable_irq(); + + uint32_t file_name_len = 0; + + file_name_len = (ASSERT_FILE_NAME_LEN < strlen(file)) ? ASSERT_FILE_NAME_LEN : strlen(file); + + memset(&s_assert_info, 0, sizeof(assert_info_t)); + memcpy(s_assert_info.file_name, file, file_name_len); + + s_assert_info.assert_type = ASSERT_PARAM; + s_assert_info.file_line = line; + s_assert_info.param0 = param0; + s_assert_info.param1 = param1; + + assert_info_save(&s_assert_info); + + while(1); +} + +/** + ***************************************************************************************** + * @brief Assert error callback. + * + * @param[in] expr: Pxpression. + * @param[in] file: File name. + * @param[in] line: Line number. + ***************************************************************************************** + */ +SECTION_RAM_CODE void app_assert_err_cb(const char *expr, const char *file, int line) +{ + __disable_irq(); + + uint32_t expre_len = 0; + uint32_t file_name_len = 0; + + file_name_len = (ASSERT_FILE_NAME_LEN < strlen(file)) ? ASSERT_FILE_NAME_LEN : strlen(file); + expre_len = (ASSERT_EXPR_NAME_LEN < strlen(expr)) ? ASSERT_EXPR_NAME_LEN : strlen(expr); + + memset(&s_assert_info, 0, sizeof(assert_info_t)); + memcpy(s_assert_info.file_name, file, file_name_len); + memcpy(s_assert_info.expr, expr, expre_len); + + s_assert_info.assert_type = ASSERT_ERROR; + s_assert_info.file_line = line; + + assert_info_save(&s_assert_info); + while(1); +} + + +/** + ***************************************************************************************** + * @brief Update fault info record database environment variables. + ***************************************************************************************** + */ +static sdk_err_t fault_info_db_env_update(void) +{ + if (nvds_put(FAULT_INFO_DB_ENV_TAG, FAULT_INFO_DB_ENV_LEN, (uint8_t *)&s_fault_info_db_env)) + { + return SDK_ERR_SDK_INTERNAL; + } + else + { + return SDK_SUCCESS; + } +} + +/** + ***************************************************************************************** + * @brief Database is already exist or not. + * + * @return True or False. + ***************************************************************************************** + */ +static bool fault_info_db_is_available(void) +{ + fault_info_db_env_t db_env; + uint16_t length = FAULT_INFO_DB_ENV_LEN; + + return (NVDS_TAG_NOT_EXISTED == nvds_get(FAULT_INFO_DB_ENV_TAG, &length, (uint8_t *)&db_env)) ? false : true; +} + +/** + ***************************************************************************************** + * @brief Get fault info record database environment variables. + * + * @return Result of get. + ***************************************************************************************** + */ +static sdk_err_t fault_info_db_get(void) +{ + fault_info_db_env_t db_env; + uint16_t length = FAULT_INFO_DB_ENV_LEN; + + if (nvds_get(FAULT_INFO_DB_ENV_TAG, &length, (uint8_t *)&db_env)) + { + return SDK_ERR_SDK_INTERNAL; + } + else + { + memcpy(&s_fault_info_db_env, &db_env, FAULT_INFO_DB_ENV_LEN); + return SDK_SUCCESS; + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +sdk_err_t fault_trace_db_init(void) +{ + app_assert_init(); + + if (fault_info_db_is_available()) + { + return fault_info_db_get(); + } + else + { + for (uint8_t i = 0; i < FAULT_INFO_RECORDS_MAX; i++) + { + s_fault_info_db_env.rec_tag[i] = 0xFFFF; + } + + s_fault_info_db_env.rec_num = 0; + s_fault_info_db_env.usable_tag = FAULT_INFO_DB_ENV_TAG + 1; + + return fault_info_db_env_update(); + } +} + +sdk_err_t fault_db_record_add(const uint8_t *p_data, uint16_t length) +{ + sdk_err_t error_code; + + if (FAULT_INFO_RECORDS_MAX <= s_fault_info_db_env.rec_num) + { + s_fault_info_db_env.usable_tag = s_fault_info_db_env.rec_tag[0]; + s_fault_info_db_env.rec_tag[FAULT_INFO_RECORDS_MAX - 1] = 0xFFFF; + s_fault_info_db_env.rec_num--; + memcpy(&s_fault_info_db_env.rec_tag[0], + &s_fault_info_db_env.rec_tag[1], + (FAULT_INFO_RECORDS_MAX - 1) * sizeof(NvdsTag_t)); + } + + if (nvds_put(s_fault_info_db_env.usable_tag, length, p_data)) + { + return SDK_ERR_SDK_INTERNAL; + } + + if (FAULT_INFO_RECORDS_MAX <= s_fault_info_db_env.rec_num) + { + s_fault_info_db_env.rec_num++; + s_fault_info_db_env.rec_tag[FAULT_INFO_RECORDS_MAX - 1] = s_fault_info_db_env.usable_tag; + } + else + { + s_fault_info_db_env.rec_tag[s_fault_info_db_env.rec_num] = s_fault_info_db_env.usable_tag; + s_fault_info_db_env.rec_num++; + s_fault_info_db_env.usable_tag++; + } + + error_code = fault_info_db_env_update(); + + if (error_code) + { + s_fault_info_db_env.rec_num--; + s_fault_info_db_env.usable_tag--; + s_fault_info_db_env.rec_tag[s_fault_info_db_env.rec_num] = 0xffff; + } + + return error_code; +} + +uint8_t fault_db_records_num_get(void) +{ + return s_fault_info_db_env.rec_num; +} + +uint32_t fault_db_records_total_len_get(void) +{ + uint32_t total_len = 0; + + for (uint8_t i = 0; i <= s_fault_info_db_env.rec_num; i++) + { + total_len += nvds_tag_length(s_fault_info_db_env.rec_tag[i]); + } + + return total_len; +} + + +sdk_err_t fault_db_records_dump(uint8_t *p_buffer, uint32_t *p_length) +{ + uint16_t dump_len = 0; + uint16_t resi_len = 0; + uint32_t buff_len = *p_length; + + if (buff_len < fault_db_records_total_len_get()) + { + return SDK_ERR_INVALID_BUFF_LENGTH; + } + + for (uint8_t i = 0; i < s_fault_info_db_env.rec_num; i++) + { + resi_len = ((buff_len - dump_len) >= FAULT_INFO_LEN_MAX) ? FAULT_INFO_LEN_MAX : buff_len - dump_len; + + if (nvds_get(s_fault_info_db_env.rec_tag[i], &resi_len, &p_buffer[dump_len])) + { + *p_length = dump_len; + + return SDK_ERR_SDK_INTERNAL; + } + else + { + dump_len += resi_len; + } + } + + *p_length = dump_len; + + return SDK_SUCCESS; +} + +sdk_err_t fault_db_record_clear(void) +{ + for (uint8_t i = 0; i < s_fault_info_db_env.rec_num; i++) + { + nvds_del(s_fault_info_db_env.rec_tag[i]); + s_fault_info_db_env.rec_tag[i] = 0xFFFF; + } + + s_fault_info_db_env.rec_num = 0; + s_fault_info_db_env.usable_tag = FAULT_INFO_DB_ENV_TAG + 1; + + return fault_info_db_env_update(); +} + +#if defined ( __CC_ARM ) +void hardfault_trace_handler(unsigned int sp) +{ + unsigned int stacked_r0; + unsigned int stacked_r1; + unsigned int stacked_r2; + unsigned int stacked_r3; + unsigned int stacked_r12; + unsigned int stacked_lr; + unsigned int stacked_pc; + unsigned int stacked_psr; + + stacked_r0 = ((unsigned long *)sp)[0]; + stacked_r1 = ((unsigned long *)sp)[1]; + stacked_r2 = ((unsigned long *)sp)[2]; + stacked_r3 = ((unsigned long *)sp)[3]; + stacked_r12 = ((unsigned long *)sp)[4]; + stacked_lr = ((unsigned long *)sp)[5]; + stacked_pc = ((unsigned long *)sp)[6]; + stacked_psr = ((unsigned long *)sp)[7]; + + memset(s_fault_info, 0, FAULT_INFO_LEN_MAX); + + sprintf(s_fault_info, "HARDFAULT CALLSTACK INFO: R0-%08X R1-%08X R2-%08X R3-%08X R12-%08X LR-%08X PC-%08X XPSR-%08X\r\n", + stacked_r0, stacked_r1, stacked_r2, stacked_r3, stacked_r12, stacked_lr, stacked_pc, stacked_psr); + + fault_db_record_add((uint8_t *)s_fault_info, strlen(s_fault_info)); +} + +#elif defined ( __GNUC__ ) + +void hardfault_trace_handler(unsigned int *args) +{ + unsigned int stacked_r0; + unsigned int stacked_r1; + unsigned int stacked_r2; + unsigned int stacked_r3; + unsigned int stacked_r12; + unsigned int stacked_lr; + unsigned int stacked_pc; + unsigned int stacked_psr; + + stacked_r0 = ((unsigned long)args[0]); + stacked_r1 = ((unsigned long)args[1]); + stacked_r2 = ((unsigned long)args[2]); + stacked_r3 = ((unsigned long)args[3]); + + stacked_r12 = ((unsigned long)args[4]); + stacked_lr = ((unsigned long)args[5]); + stacked_pc = ((unsigned long)args[6]); + stacked_psr = ((unsigned long)args[7]); + + memset(s_fault_info, 0, FAULT_INFO_LEN_MAX); + + sprintf(s_fault_info, "HARDFAULT CALLSTACK INFO: R0-%08X R1-%08X R2-%08X R3-%08X R12-%08X LR-%08X PC-%08X XPSR-%08X\r\n", + stacked_r0, stacked_r1, stacked_r2, stacked_r3, stacked_r12, stacked_lr, stacked_pc, stacked_psr); + + fault_db_record_add((uint8_t *)s_fault_info, strlen(s_fault_info)); +} +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.h new file mode 100644 index 0000000..8387d6d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fault_trace/fault_trace.h @@ -0,0 +1,153 @@ +/** + **************************************************************************************** + * + * @file fault_trace.h + * + * @brief System Fault Trace API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __FAULT_TRACE_H__ +#define __FAULT_TRACE_H__ + +#include "custom_config.h" +#include "grx_sys.h" +#include +#include + +#if SYS_FAULT_TRACE_ENABLE + +/** + * @defgroup FAULT_TRACE_MAROC Defines + * @{ + */ +#define FAULT_INFO_RECORDS_MAX 0x10 /**< Maximum number of fault info records. */ +/** @} */ + +/** + * @defgroup FAULT_TRACE_STRUCT Structures + * @{ + */ +/**@brief System fault info database environment variable. */ +typedef struct +{ + NvdsTag_t rec_tag[FAULT_INFO_RECORDS_MAX]; /**< System fault info record tags. */ + uint16_t rec_num; /**< Number of all fault info records in database. */ + NvdsTag_t usable_tag; /**< Current usable NVDS tag. */ +} fault_info_db_env_t; +/** @} */ + +/** + * @defgroup FAULT_TRACE_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize system fault info record database. + * + * @return Result of initialize. + ***************************************************************************************** + */ +sdk_err_t fault_trace_db_init(void); + +/** + ***************************************************************************************** + * @brief Add a record at the end of the database. + * + * @param[in] p_data: Pointer to log data. + * @param[in] length: Length of data. + * + * @return Result of add. + ***************************************************************************************** + */ +sdk_err_t fault_db_record_add(const uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Get the number of records in the database. + * + * @return Number of records in the database. + ***************************************************************************************** + */ +uint8_t fault_db_records_num_get(void); + +/** + ***************************************************************************************** + * @brief Get the length of all records info in the database. + * + * @return Length of all records info in the database. + ***************************************************************************************** + */ +uint32_t fault_db_records_total_len_get(void); + +/** + ***************************************************************************************** + * @brief Dump records from the database. + * + * @param[in,out] p_buffer: Pointer to buffer. + * @param[in,out] p_length: Pointer to buffer length + ***************************************************************************************** + */ +sdk_err_t fault_db_records_dump(uint8_t *p_buffer, uint32_t *p_length); + +/** + ***************************************************************************************** + * @brief Clear database. + ***************************************************************************************** + */ +sdk_err_t fault_db_record_clear(void); + +#if defined ( __CC_ARM ) +/** + ***************************************************************************************** + * @brief Hardfault trace handler. + * + * @param[in] sp: Stack Pointer. + ***************************************************************************************** + */ +void hardfault_trace_handler(unsigned int sp); + +#elif defined ( __GNUC__ ) + +/** + ***************************************************************************************** + * @brief Hardfault trace handler. + * + * @param[in] args: Hardfault args. + ***************************************************************************************** + */ +void hardfault_trace_handler(unsigned int *args); +#endif +/** @} */ +#endif +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/BUILD.gn new file mode 100644 index 0000000..c95817a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("fcc") { + sources = [ "dtm_fcc_test.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.c new file mode 100644 index 0000000..a73a1e5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.c @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include "dtm_fcc_test_int.h" + +void fcc_test_init(void) +{ + bb_watch_timer_start = bb_watch_timer_start_fcc; + g_bb_watch_alarm.cb_alarm = bb_watch_timer_cbk_fcc; +} + +void dtm_test_init(void) +{ + bb_watch_timer_start = bb_watch_timer_start_dtm; + g_bb_watch_alarm.cb_alarm = bb_watch_timer_cbk_dtm; +} + +void em_ble_txrxcntl_txpwr_setf(int elt_idx, uint8_t txpwr) +{ + EM_BLE_WR(EM_BLE_TXRXCNTL_ADDR + elt_idx * REG_EM_BLE_CS_SIZE, \ + (EM_BLE_RD(EM_BLE_TXRXCNTL_ADDR + elt_idx * REG_EM_BLE_CS_SIZE) & ~((uint16_t)0x000000FF)) | ((uint16_t)txpwr << 0)); +} + +uint32_t ble_rwblecntl_get(void) +{ + return REG_BLE_RD(BLE_RWBLECNTL_ADDR); +} + +void ble_rwblecntl_set(uint32_t value) +{ + REG_BLE_WR(BLE_RWBLECNTL_ADDR, value); +} + +void bb_watch_timer_cbk_fcc(struct sch_alarm_tag* elt) +{ + if(lld_test_env != NULL) + { + // Point to parameters + struct lld_test_env_tag* test_par = lld_test_env; + if ((test_par->type == TEST_TX) && (test_par->data_len < 255)) + { + // Abort the event + ble_rwblecntl_set(ble_rwblecntl_get() | BLE_RFTEST_ABORT_BIT); + } + } +} + +uint16_t em_ble_rxccmpktcnt0_get(int elt_idx) +{ + return EM_BLE_RD(EM_BLE_RXCCMPKTCNT0_ADDR + elt_idx * REG_EM_BLE_CS_SIZE); +} + +void lld_test_frm_isr_fcc(uint32_t timestamp, bool abort) +{ + if(lld_test_env != NULL) + { + // Point to parameters + struct lld_test_env_tag* test_par = lld_test_env; + struct sch_arb_elt_tag* evt = &(lld_test_env->evt); + + // Remove event + sch_arb_remove(evt, true); + + // Check test mode end + if(test_par->state == TEST_EVT_END) + { + // Report test mode end to LLM + struct lld_test_end_ind* ind = KE_MSG_ALLOC(LLD_TEST_END_IND, TASK_LLM, TASK_NONE, lld_test_end_ind); + ind->status = CO_ERROR_NO_ERROR; + ind->nb_pkt_recv = (test_par->type == TEST_RX) ? em_ble_rxccmpktcnt0_get(EM_BLE_CS_ACT_ID_TO_INDEX(TEST_LINK_ID)) : 0; + ke_msg_send(ind); + + if (test_par->type == TEST_TX) + { + // Release TX buffer + ble_util_buf_acl_tx_free(test_par->em_buf); + } + + // Free event memory + lld_test_cleanup(); + } + else + { + // update event priority + evt->current_prio = abort + ? (evt->current_prio + rwip_priority[RWIP_PRIO_ADV_IDX].increment) + : rwip_priority[RWIP_PRIO_ADV_IDX].value; + + do + { + // Reschedule ASAP + SCH_ARB_ASAP_STG_SET(evt, SCH_ARB_FLAG_NO_ASAP, SCH_ARB_NO_PHASE, 0, 0); + evt->time.hs = CLK_ADD_2(rwip_time_get().hs, FCC_IFS_HALF_SLOT); + + // Try to reschedule + if (sch_arb_insert(evt) == 0) + { + test_par->state = TEST_EVT_WAIT; + break; + } + }while(1); + } + } +} + +void lld_test_frm_cbk_fcc(uint32_t timestamp, uint32_t dummy, uint8_t irq_type) +{ + FPB_PATCH_OFF(); + switch(irq_type) + { + case SCH_FRAME_IRQ_EOF: + { + lld_test_frm_isr_fcc(timestamp, false); + } break; + case SCH_FRAME_IRQ_EOF_ABORT: + { + lld_test_frm_isr_fcc(timestamp, true); + } break; + case SCH_FRAME_IRQ_RX: + { + lld_test_rx_isr_patch(timestamp); + } break; + } + FPB_PATCH_ON(); +} + +void bb_watch_timer_start_fcc(struct sch_prog_params* params) +{ + FPB_PATCH_OFF(); + g_bb_watch_alarm.timestamp = CLK_ADD_2(rwip_time_get().hs, 1); + sch_alarm_clear(&g_bb_watch_alarm); + sch_alarm_set(&g_bb_watch_alarm); + + /*In general, DTM project will be used with 0dbm at most of time, + so we want to reset the txpower to 0dbm by reset the register, + why the code place at here is that we don't want to import more patch*/ + if(TEST_LINK_ID == params->cs_idx) + { + uint8_t et_idx = sch_prog_env.et_idx_next_prog; + sch_prog_env.tab[et_idx].frm_cbk = lld_test_frm_cbk_fcc; + em_ble_txrxcntl_txpwr_setf(0, rwip_rf.txpwr_cs_get(TX_Power_dbm, 0)); + } + FPB_PATCH_ON(); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.h new file mode 100644 index 0000000..34d2a5e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test.h @@ -0,0 +1,27 @@ +#ifndef __DTM_FCC_TEST_H__ +#define __DTM_FCC_TEST_H__ + +#include +#include +#include +#include + +/** + ***************************************************************************************** + * @brief Initialize the FCC test environment. + * + * @note This function is used to prepare the FCC test environment. + ***************************************************************************************** + */ +void fcc_test_init(void); + +/** + ***************************************************************************************** + * @brief Save system context. + * + * @note This function is used to prepare the DTM test environment. + ***************************************************************************************** + */ +void dtm_test_init(void); + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test_int.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test_int.h new file mode 100644 index 0000000..24599e7 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/fcc/dtm_fcc_test_int.h @@ -0,0 +1,550 @@ +#ifndef __DTM_FCC_TEST_INT_H__ +#define __DTM_FCC_TEST_INT_H__ + +#include +#include +#include +#include + +/// FCC IFS +#define FCC_IFS_HALF_SLOT 4 + +/// Alias +#define bb_watch_timer_start_dtm bb_watch_timer_start_patch +#define bb_watch_timer_cbk_dtm bb_watch_timer_cbk_patch + +/// Clock +#define RWIP_MAX_CLOCK_TIME ((1L<<28) - 1) +#define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & RWIP_MAX_CLOCK_TIME)) + +/// Register Operations +#define REG_BLE_WR(addr, value) (*(volatile uint32_t *)(addr)) = (value) +#define REG_BLE_RD(addr) (*(volatile uint32_t *)(addr)) +#define EM_BLE_RD(addr) (*(volatile uint16_t *)(addr)) +#define EM_BLE_WR(addr, value) (*(volatile uint16_t *)(addr)) = (value) + +/// CS Index +#define TEST_LINK_ID (0) +#define EM_BLE_CS_ACT_ID_TO_INDEX(act_id) (act_id) + +/// Baseband Register Address +#define REG_EM_BLE_CS_SIZE (108) +#define CO_ALIGN2_HI(val) (((val)+1)&~1) +#define REG_CORE_BASE_ADDR (0xB0000000) +#define REG_EM_BASE_ADDR (0xB0008000) +#define BLE_RWBLECNTL_ADDR (REG_CORE_BASE_ADDR + 0x00000000) +#define EM_COMMON_OFFSET (0) + +/// Exchange table area definition +#define EM_EXCH_TABLE_LEN 16 +#define EM_ET_OFFSET (EM_COMMON_OFFSET) +#define EM_ET_END (EM_ET_OFFSET + EM_EXCH_TABLE_LEN * REG_EM_ET_SIZE) + +/// Frequency table area definition +#define EM_FT_OFFSET (EM_ET_END) +#define EM_RF_FREQ_TABLE_LEN 40 +#define EM_RF_VCO_TABLE_LEN 0 +#define EM_FT_END (EM_FT_OFFSET + (EM_RF_VCO_TABLE_LEN + EM_RF_FREQ_TABLE_LEN) * sizeof(uint8_t)) +#define EM_COMMON_END (EM_FT_END) + +/// Encryption area definition +#define EM_ENC_OFFSET CO_ALIGN2_HI(EM_COMMON_END) +#define EM_ENC_IN_OFFSET (EM_ENC_OFFSET) +#define EM_ENC_IN_SIZE (16) +#define EM_ENC_OUT_OFFSET (EM_ENC_IN_OFFSET + EM_ENC_IN_SIZE) +#define EM_ENC_OUT_SIZE (16) +#define EM_ENC_END (EM_ENC_OFFSET + EM_ENC_IN_SIZE + EM_ENC_OUT_SIZE) +#define EM_BLE_OFFSET (EM_ENC_END) +#define EM_BLE_CS_OFFSET (EM_BLE_OFFSET) +#define EM_BLE_RXCCMPKTCNT0_ADDR (REG_EM_BASE_ADDR + 0x00000056 + EM_BLE_CS_OFFSET) + +/// TXRXCNTL register definition +#define EM_BLE_TXRXCNTL_ADDR (REG_EM_BASE_ADDR + 0x00000020 + EM_BLE_CS_OFFSET) + +/// Baseband Register Bits +#define BLE_RFTEST_ABORT_BIT ((uint32_t)0x04000000) + +/// EM ET Size +#define REG_EM_ET_SIZE 16 + +/// Error Code +#define CO_ERROR_NO_ERROR 0x00 + +/// Convenient wrapper to ke_msg_alloc() +#define KE_MSG_ALLOC(id, dest, src, param_str) \ + (struct param_str*) ke_msg_alloc(id, dest, src, sizeof(struct param_str)) + +/// Build the first message ID of a task. (in fact a ke_msg_id_t) +#define TASK_FIRST_MSG(task) ((uint16_t)((task) << 8)) + +/// Tasks types definition, this value shall be in [0-254] range +#define TASK_ID_LLD (2) +#define TASK_NONE (0xFF) + +/// FPB Definitions +typedef enum +{ + FPB_PATCH_OFF=0, + FPB_PATCH_ON, +}fpb_t; + +void fpb_set_state(fpb_t state); + +fpb_t fpb_save_state(void); + +void fpb_load_state(fpb_t state); + +#define FPB_SAVE() fpb_t __fpb_state_local_var=fpb_save_state() +#define FPB_LOAD() fpb_load_state(__fpb_state_local_var) +#define FPB_PATCH_ON() fpb_save_state(); +#define FPB_PATCH_OFF() fpb_load_state(FPB_PATCH_OFF) + +/// Test mode event states +enum TEST_TYPE +{ + TEST_RX, + TEST_TX, +}; + +/// Message API of the LLM task +/*@TRACE*/ +enum lld_msg_id +{ + LLD_MSG_ID_FIRST = TASK_FIRST_MSG(TASK_ID_LLD), + + /* + * ************** Msg LD->LLM**************** + */ + LLD_ADV_REP_IND, + LLD_SCAN_REQ_IND, + LLD_SYNC_START_REQ, + LLD_PER_ADV_REP_IND, + LLD_PER_ADV_RX_END_IND, + LLD_SCAN_END_IND, + LLD_ADV_END_IND, + LLD_PER_ADV_END_IND, + LLD_INIT_END_IND, + LLD_TEST_END_IND, +}; + +enum KE_TASK_TYPE +{ + // Link Layer Tasks + TASK_LLM, +}; + +/// Frame type +enum SCH_FRAME_IRQ +{ + /// Normal End of Event + SCH_FRAME_IRQ_EOF = 0x00, + /// End of event due to an abort + SCH_FRAME_IRQ_EOF_ABORT = 0x01, + /// SKIP Event IRQ + SCH_FRAME_IRQ_SKIP = 0x04, + /// RX ACL IRQ + SCH_FRAME_IRQ_RX = 0x02, + /// TX ACL IRQ + SCH_FRAME_IRQ_TX = 0x03, +}; + +/// Priority index definition +enum rwip_prio_idx +{ + /// Default priority for scanning events + RWIP_PRIO_SCAN_IDX, + /// Default priority for auxillary scan/init (no_asap) rx events + RWIP_PRIO_AUX_RX_IDX, + /// Default priority for periodic adv rx events + RWIP_PRIO_PER_ADV_RX_DFT_IDX, + /// Default priority for initiating events + RWIP_PRIO_INIT_IDX, + /// LE connection events default priority + RWIP_PRIO_CONNECT_DFT_IDX, + /// LE connection events priority with activity + RWIP_PRIO_CONNECT_ACT_IDX, + /// Default priority for advertising events + RWIP_PRIO_ADV_IDX, + /// Default priority for advertising high duty cycle events + RWIP_PRIO_ADV_HDC_IDX, + /// Default priority for aux advertising events + RWIP_PRIO_ADV_AUX_IDX, + /// Default priority for periodic advertising events + RWIP_PRIO_PER_ADV_IDX, + /// Default priority for resolvable private addresses renewal event + RWIP_PRIO_RPA_RENEW_IDX, + + RWIP_PRIO_IDX_MAX +}; + +/// ASAP type definition +enum sch_arb_elt_asap_type +{ + /// 00: No ASAP + SCH_ARB_FLAG_NO_ASAP = 0, + /// 01: ASAP no limit + SCH_ARB_FLAG_ASAP_NO_LIMIT, + /// 10: ASAP with limit + SCH_ARB_FLAG_ASAP_LIMIT, + SCH_ARB_FLAG_MAX +}; + +/// ASAP slot parity definition +enum sch_arb_elt_asap_phase +{ + SCH_ARB_PHASE_0, + SCH_ARB_PHASE_1, + SCH_ARB_PHASE_2, + SCH_ARB_PHASE_3, + SCH_ARB_NO_PHASE, +}; + +/// Test mode event states +enum TEST_EVT_STATE +{ + TEST_EVT_WAIT, + TEST_EVT_ACTIVE, + TEST_EVT_END, +}; + +/// Set ASAP settings +#define SCH_ARB_ASAP_STG_SET(evt, type, phase, resched_att, prio_inc) \ +(evt->asap_settings = \ +( (((type) << 14) & 0xC000) | (((phase) << 11) & 0x3800) | \ + (((resched_att) << 4) & 0x03F0) | (((prio_inc) << 0) & 0x000F) )); + +/// List +struct co_list_hdr +{ + /// Pointer to next co_list_hdr + struct co_list_hdr *next; +}; + +/// simplify type name of list element header +typedef struct co_list_hdr co_list_hdr_t; + +/// Message Identifier. The number of messages is limited to 0xFFFF. +typedef uint16_t ke_msg_id_t; + +/// Task Identifier. Composed by the task type and the task index. +typedef uint16_t ke_task_id_t; + +/// Callback for interrupt related to the frame +typedef void (*frm_cbk_t)(uint32_t timestamp, uint32_t dummy, uint8_t irq_type); + +/// Alarm information +struct sch_alarm_tag +{ + /// List element for chaining in the Even Arbiter lists + struct co_list_hdr hdr; + + /// Timestamp of alarm expiry (in BT half-slots) + uint32_t timestamp; + + /// Call back function invoked upon alarm expiry + void (*cb_alarm)(struct sch_alarm_tag*); +}; + +/// Test mode end indication structure +struct lld_test_end_ind +{ + /// Status (BLE error code) + uint8_t status; + + /// Number of packets received + uint16_t nb_pkt_recv; +}; + +/// Time information +typedef struct +{ + /// Integer part of the time (in half-slot) + uint32_t hs; + /// Fractional part of the time (in half-us) (range: 0-624) + uint32_t hus; +} rwip_time_t; + +/// Additional parameters for BLE frame +struct sch_prog_params_ble +{ + /// Advertising channel type: 0x0: AE Start on Primary channel | 0x1: AE Start on Secondary channel + uint8_t ae_nps; + /// Reserved audio event (0: reTx, 1:primary) + uint8_t rsvd; + /// Isochronous event (0: normal event | 1: iso event) + uint8_t iso; + /// Start Instant Correction (SIC) bit value + uint8_t sic; +}; + +/// Parameters for a programmed frame +struct sch_prog_params +{ + /// Callback for handling interrupts related to the frame + frm_cbk_t frm_cbk; + /// Timestamp (in half-slots, based on local clock) and event offset (in half-us) of the programmed frame + rwip_time_t time; + /// Bandwidth duration of the event using priority 1 (in half us) + uint32_t bandwidth; + /// Dummy value reported when an event happen during the frame or the frame is completed + uint32_t dummy; + /// Priority during duration of bandwidth + uint8_t prio_1; + /// Priority after bandwidth elapsed + uint8_t prio_2; + /// Priority after trigger conditions + uint8_t prio_3; + /// Priority when specific action occurs during the event + uint8_t pti_prio; + /// Control structure index + uint8_t cs_idx; + /// Mode (0: BLE, 1:BT) + uint8_t mode; + + union + { + /// Additional parameters for BLE frame + struct sch_prog_params_ble ble; + } add; +}; + +/// Scheduling Arbiter Element +/*@TRACE*/ +struct sch_arb_elt_tag +{ + /// List element for chaining in the Even Arbiter lists + struct co_list_hdr hdr; + + /// Programming time expressed in half-slots and half-us + rwip_time_t time; + + /// Scheduling time limit in base time (half-slots) (only for ASAP LIMIT requests) + uint32_t asap_limit; + + /// Minimum duration of the event or frame (in half-us) + uint32_t duration_min; + + /** + * ASAP settings field + * bit |15 14|13 12 11| 10 | 9..4 | 3..0 | + * def | TYPE | Phase | To protect | Resched att | Prio inc | + * + * Type: + * - 00: No ASAP + * - 01: ASAP no limit + * - 10: ASAP with limit + * - 11: ASAP with limit, no parity check + * + * Phase: (only for ASAP requests) + * - 0: phase 0 + * - 1: phase 1 + * - 2: phase 2 + * - 3: phase 3 + * - 4: don't care + * + * Number of rescheduling attempts: + * - The remaining number of rescheduling attempts. + * - Rescheduling happens when the event is overlapped by a higher priority event + * - Only used for ASAP requests + * + * Priority increment: + * - The current priority value is incremented each time the event is overlapped by a new insertion and postponed + * - Only used for ASAP requests + */ + /*@trc_desc + *bit |15..14| 13..11 | 10 | 9..4 | 3..0 | + *def | Type | Phase | Rsvd | Resched_att | Prio_inc | + * + *Phase: only if Type = 01..11 + *Resched_att: only if Type = 01..11 + *Prio_inc: only if Type = 01..11 + * + *@trc_ref Type: + * - 00: No ASAP + * - 01: ASAP no limit + * - 10: ASAP with limit + * - 11: ASAP with limit and no parity check + * + *@trc_ref Phase: + * - 000: phase 0 + * - 001: phase 1 + * - 010: phase 2 + * - 011: phase 3 + * - 100: don-t care + */ + uint16_t asap_settings; + + /// Current priority + uint8_t current_prio; + /// Latency to notify to stop the activity before next activity is notified to start (in half-slots, 0 if no stop required) + uint8_t stop_latency; + // GDX Controller, Activity Role + uint8_t activity_role; + // GDX Controller, CS Index + uint8_t cs_idx; + + /************************************************************************************ + * ISR CALLBACKS + ************************************************************************************/ + + /// Start notification call back function + void (*cb_start)(struct sch_arb_elt_tag*); + /// Stop notification call back function + void (*cb_stop)(struct sch_arb_elt_tag*); + /// Cancel notification call back function + void (*cb_cancel)(struct sch_arb_elt_tag*); +}; + +/// LLD test mode environment structure +struct lld_test_env_tag +{ + /// Pointer to inquiry event + struct sch_arb_elt_tag evt; + + /// Buffer used for sending the test data + uint16_t em_buf; + + /// Type (0: RX | 1: TX) + uint8_t type; + + /// RF channel, N = (F - 2402) / 2 + uint8_t channel; + + /// Length of test data + uint8_t data_len; + + /** + * Packet payload + * 0x00 PRBS9 sequence "11111111100000111101" (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 + * 0x01 Repeated "11110000" (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 + * 0x02 Repeated "10101010" (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 + * 0x03 PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 + * 0x04 Repeated "11111111" (in transmission order) sequence + * 0x05 Repeated "00000000" (in transmission order) sequence + * 0x06 Repeated "00001111" (in transmission order) sequence + * 0x07 Repeated "01010101" (in transmission order) sequence + * 0x08-0xFF Reserved for future use + */ + uint8_t payload; + + /// current state of the test mode + uint8_t state; +}; + +/// Structure of a frame element +struct sch_prog_frm_elt +{ + /// Timestamp of the programmed frame (in BLE half slots, based on local clock) + uint32_t timestamp; + /// Callback for handling interrupts related to the frame + frm_cbk_t frm_cbk; + /// Dummy value (to be reported to the driver) + uint32_t dummy; + /// Indicate if the frame is valid (programmed and not skipped or finished) + bool valid; +}; + +/// SCH_PROG environment structure +struct sch_prog_env_tag +{ + /// Frame elements pool + struct sch_prog_frm_elt tab[REG_EM_ET_SIZE]; + + /// Exchange table index of the oldest entry currently used by the HW + uint8_t et_idx_current; + + /// Next exchange table index to program + uint8_t et_idx_next_prog; + + /// Number of programmed frames + uint8_t nb_prog; +}; + +/// API functions of the RF driver that are used by the BLE or BT software +struct rwip_rf_api +{ + /// Function called upon HCI reset command reception + void (*reset)(void); + /// Function called to enable/disable force AGC mechanism (true: en / false : dis) + void (*force_agc_enable)(bool); + /// Function called when TX power has to be decreased for a specific link id + bool (*txpwr_dec)(uint8_t); + /// Function called when TX power has to be increased for a specific link id + bool (*txpwr_inc)(uint8_t); + /// Function called when TX power has to be set to max for a specific link id + void (*txpwr_max_set)(uint8_t); + /// Function called to convert a TX power CS power field into the corresponding value in dBm + int8_t (*txpwr_dbm_get)(uint8_t, uint8_t); + /// Function called to convert a power in dBm into a control structure tx power field + uint8_t (*txpwr_cs_get)(int8_t, bool); + /// Function called to convert the RSSI read from the control structure into a real RSSI + int8_t (*rssi_convert)(uint8_t); + /// Function used to read a RF register + uint32_t (*reg_rd)(uint32_t); + /// Function used to write a RF register + void (*reg_wr)(uint32_t, uint32_t); + /// Function called to put the RF in deep sleep mode + void (*sleep)(void); + void (*default_tx_power_set)(int8_t); + int8_t (*default_tx_power_get)(); + /// Index of minimum TX power + uint8_t txpwr_min; + /// Index of maximum TX power + uint8_t txpwr_max; + /// RSSI high threshold ('real' signed value in dBm) + int8_t rssi_high_thr; + /// RSSI low threshold ('real' signed value in dBm) + int8_t rssi_low_thr; + /// interferer threshold ('real' signed value in dBm) + int8_t rssi_interf_thr; + /// RF wakeup delay (in slots) + uint8_t wakeup_delay; + /// GDX Controller : Index of default TX power + uint8_t txpwr_default; + /// Function called to change tx mode + uint8_t (*tx_mode_set)(uint8_t); + /// Function called to get tx mode + uint8_t (*tx_mode_get)(void); + /// Index of rf match circuit (ohm) + uint8_t mat_cir; + /// Function called to set rf match circuit (ohm) + void (*mat_cir_set)(uint8_t); + /// Function called to get rf match circuit (ohm) + uint8_t (*mat_cir_get)(void); +}; + +/// Internal API for priority +struct rwip_prio +{ + ///value + uint8_t value; + ///Increment + uint8_t increment; +}; + +/// External Objects +extern void (*bb_watch_timer_start)(struct sch_prog_params* params); +extern struct sch_alarm_tag g_bb_watch_alarm; +extern struct lld_test_env_tag* lld_test_env; +extern void bb_watch_timer_start_patch(struct sch_prog_params* params); +extern void bb_watch_timer_cbk_patch(struct sch_alarm_tag* elt); +extern void bb_watch_timer_start_fcc(struct sch_prog_params* params); +extern void bb_watch_timer_cbk_fcc(struct sch_alarm_tag* elt); +extern rwip_time_t rwip_time_get(void); +extern uint8_t sch_alarm_clear(struct sch_alarm_tag* elt); +extern void sch_alarm_set(struct sch_alarm_tag* elt); +extern int8_t TX_Power_dbm; +extern frm_cbk_t lld_test_frm_cbk; +extern struct sch_prog_env_tag sch_prog_env; +extern struct rwip_rf_api rwip_rf; +extern const struct rwip_prio rwip_priority[RWIP_PRIO_IDX_MAX]; +extern uint8_t sch_arb_remove(struct sch_arb_elt_tag *elt, bool not_waiting); +extern uint8_t (*sch_arb_insert)(struct sch_arb_elt_tag *); +extern void lld_test_cleanup(void); +extern void ble_util_buf_acl_tx_free(uint16_t buf); +extern void *ke_msg_alloc(ke_msg_id_t const id, ke_task_id_t const dest_id, + ke_task_id_t const src_id, uint16_t const param_len); +extern void ke_msg_send(void const *param_ptr); +extern void lld_test_rx_isr_patch(uint32_t timestamp); + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/font_gb2312.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/font_gb2312.c new file mode 100644 index 0000000..3d893ef --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/font_gb2312.c @@ -0,0 +1,24637 @@ +/**@brief gb2312 font define. */ +const uint8_t s_font_gb2312[]= +{ + /* 0xA1A1 [ ] [1]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A2 [?] [2]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x18,0x0C,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A3 [?] [3]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A4 [·] [4]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A5 [¯] [5]*/ + 0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A6 [?] [6]*/ + 0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A7 [¨] [7]*/ + 0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A8 [?] [8]*/ + 0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x09,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1A9 [?] [9]*/ + 0x00,0x00,0x04,0x04,0x04,0x0F,0x08,0x10,0x20,0x05,0x02,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0xF0,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1AA [—] [10]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1AB [~] [11]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x23,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x88,0x70,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1AC [?] [12]*/ + 0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00, + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + /* 0xA1AD […] [13]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1AE [‘] [14]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x08,0x10,0x20,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1AF [’] [15]*/ + 0x00,0x18,0x18,0x08,0x10,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, + /* 0xA1B0 [“] [16]*/ + 0x00,0x00,0x01,0x02,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x88,0x10,0x20,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1B1 [”] [17]*/ + 0x00,0x19,0x19,0x08,0x11,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1B2 [?] [18]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x00, + /* 0xA1B3 [?] [19]*/ + 0x00,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1B4 [<] [20]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + /* 0xA1B5 [>] [21]*/ + 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1B6 [«] [22]*/ + 0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x09,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00, + 0x10,0x24,0x48,0x90,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x90,0x48,0x24,0x10,0x00, + /* 0xA1B7 [»] [23]*/ + 0x08,0x24,0x12,0x09,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x09,0x12,0x24,0x08,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x90,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA1B8 [?] [24]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + /* 0xA1B9 [?] [25]*/ + 0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3C,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1BA [?] [26]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xFC,0x84,0xBC,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xE0,0x00,0x00,0x00,0x00, + /* 0xA1BB [?] [27]*/ + 0x00,0x00,0x00,0x00,0x07,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x3D,0x21,0x3F,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1BC [?] [28]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0xFC,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0xFC,0x00, + /* 0xA1BD [?] [29]*/ + 0x00,0x3F,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x3F,0x00, + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + /* 0xA1BE [?] [30]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0xFC,0xF8,0xF0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xE0,0xE0,0xF0,0xF8,0xFC,0x00, + /* 0xA1BF [?] [31]*/ + 0x00,0x3F,0x1F,0x0F,0x07,0x07,0x03,0x03,0x03,0x03,0x07,0x07,0x0F,0x1F,0x3F,0x00, + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + /* 0xA1C0 [±] [32]*/ + 0x00,0x00,0x01,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x01,0x00,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00, + /* 0xA1C1 [×] [33]*/ + 0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0x00, + /* 0xA1C2 [÷] [34]*/ + 0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x3F,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1C3 [:] [35]*/ + 0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1C4 [?] [36]*/ + 0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x00,0x00, + /* 0xA1C5 [?] [37]*/ + 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x00, + 0x00,0x00,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00, + /* 0xA1C6 [?] [38]*/ + 0x00,0x7F,0x30,0x18,0x0C,0x06,0x03,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x7F,0x00, + 0x00,0xFC,0x04,0x04,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x04,0x04,0xFC,0x00, + /* 0xA1C7 [?] [39]*/ + 0x00,0x7F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, + 0x00,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xF0,0x00, + /* 0xA1C8 [?] [40]*/ + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x07,0x00, + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0xC0,0x00, + /* 0xA1C9 [n] [41]*/ + 0x00,0x07,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + 0x00,0xC0,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00, + /* 0xA1CA [?] [42]*/ + 0x00,0x01,0x06,0x08,0x08,0x10,0x10,0x1F,0x10,0x10,0x10,0x08,0x08,0x06,0x01,0x00, + 0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00, + /* 0xA1CB [?] [43]*/ + 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, + /* 0xA1CC [v] [44]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0A,0x12,0x01,0x00,0x00, + 0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00, + /* 0xA1CD [?] [45]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, + /* 0xA1CE [?] [46]*/ + 0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x04,0x04,0x04,0x04,0x09,0x09,0x09,0x09,0x09, + 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA1CF [?] [47]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x7F,0x00,0x00, + 0x00,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00, + /* 0xA1D0 [?] [48]*/ + 0x00,0x00,0x07,0x18,0x20,0x20,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x60,0x10,0x10,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1D1 [?] [49]*/ + 0x00,0x00,0x07,0x18,0x20,0x20,0x40,0x43,0x43,0x40,0x20,0x20,0x18,0x07,0x00,0x00, + 0x00,0x00,0x80,0x60,0x10,0x10,0x08,0x08,0x08,0x08,0x10,0x10,0x60,0x80,0x00,0x00, + /* 0xA1D2 [?] [50]*/ + 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x09,0x06,0x00, + 0x00,0xC0,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1D3 [?] [51]*/ + 0x00,0x01,0x01,0x01,0x01,0x07,0x09,0x09,0x09,0x09,0x07,0x01,0x01,0x01,0x09,0x06, + 0xC0,0x20,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00,0x00, + /* 0xA1D4 [=] [52]*/ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1D5 [?] [53]*/ + 0x00,0x00,0x18,0x20,0x41,0x41,0x42,0x22,0x1C,0x00,0x7F,0x00,0x7F,0x00,0x00,0x00, + 0x00,0x00,0x70,0x88,0x04,0x04,0x04,0x08,0x30,0x00,0xFC,0x00,0xFC,0x00,0x00,0x00, + /* 0xA1D6 [˜] [54]*/ + 0x00,0x00,0x00,0x00,0x00,0x1C,0x23,0x40,0x1C,0x23,0x40,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x88,0x70,0x04,0x88,0x70,0x00,0x00,0x00,0x00,0x00, + /* 0xA1D7 [?] [55]*/ + 0x00,0x00,0x00,0x00,0x38,0x40,0x80,0x81,0x81,0x82,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x78,0x84,0x82,0x02,0x02,0x02,0x04,0x38,0x00,0x00,0x00,0x00, + /* 0xA1D8 [?] [56]*/ + 0x00,0x00,0x00,0x00,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7E,0x80,0x00,0x00,0x00,0x00,0x80,0x7E,0x00,0x00,0x00,0x00, + /* 0xA1D9 [?] [57]*/ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x01,0x01,0x02,0x7F,0x04,0x08,0x08,0x10,0x10,0x00, + 0x00,0x20,0x20,0x40,0x40,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1DA [?] [58]*/ + 0x00,0x01,0x01,0x01,0x03,0x0D,0x31,0xC1,0x31,0x0D,0x03,0x01,0x01,0x01,0x00,0x00, + 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00, + /* 0xA1DB [?] [59]*/ + 0x00,0x61,0x19,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x07,0x19,0x61,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x06,0x18,0x60,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA1DC [=] [60]*/ + 0x00,0x00,0x00,0x03,0x0C,0x30,0xC0,0x30,0xCC,0x33,0x0C,0x03,0x00,0x00,0x00,0x00, + 0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0xCC,0x30,0x0C,0x00, + /* 0xA1DD [=] [61]*/ + 0x60,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x19,0x66,0x18,0x60,0x00, + 0x00,0x00,0x00,0x80,0x60,0x18,0x06,0x18,0x66,0x98,0x60,0x80,0x00,0x00,0x00,0x00, + /* 0xA1DE [8] [62]*/ + 0x00,0x00,0x00,0x00,0x3C,0x42,0x81,0x81,0x81,0x42,0x3C,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x78,0x84,0x02,0x02,0x02,0x84,0x78,0x00,0x00,0x00,0x00,0x00, + /* 0xA1DF [?] [63]*/ + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1E0 [?] [64]*/ + 0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + /* 0xA1E1 [?] [65]*/ + 0x00,0x01,0x03,0x05,0x09,0x11,0x01,0x01,0x01,0x01,0x03,0x04,0x04,0x04,0x03,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x80,0x00, + /* 0xA1E2 [?] [66]*/ + 0x00,0x03,0x04,0x04,0x04,0x03,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x80,0x40,0x40,0x40,0x80,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1E3 [°] [67]*/ + 0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1E4 ['] [68]*/ + 0x00,0x08,0x08,0x10,0x10,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, + /* 0xA1E5 [?] [69]*/ + 0x00,0x12,0x12,0x24,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1E6 [?] [70]*/ + 0x60,0x91,0x96,0x6C,0x08,0x18,0x18,0x18,0x18,0x18,0x18,0x08,0x0C,0x06,0x01,0x00, + 0x00,0xF4,0x0C,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x08,0xF0,0x00, + /* 0xA1E7 [$] [71]*/ + 0x01,0x0F,0x11,0x31,0x31,0x31,0x19,0x0F,0x03,0x01,0x01,0x01,0x11,0x0D,0x07,0x01, + 0x00,0xE0,0x30,0x10,0x00,0x00,0x00,0x00,0xC0,0x70,0x18,0x18,0x18,0x30,0xE0,0x00, + /* 0xA1E8 [¤] [72]*/ + 0x00,0x40,0x20,0x17,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x17,0x20,0x40,0x00, + 0x00,0x02,0x04,0xE8,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0xE8,0x04,0x02,0x00, + /* 0xA1E9 [?] [73]*/ + 0x00,0x00,0x07,0x18,0x30,0x60,0x61,0x61,0x62,0x62,0x64,0x38,0x18,0x17,0x20,0x40, + 0x10,0x20,0xE8,0x58,0x48,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xE0,0x00,0x00, + /* 0xA1EA [?] [74]*/ + 0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x3F,0x04,0x04,0x08,0x08,0x08,0x10,0x7F,0x00, + 0xE0,0x10,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00, + /* 0xA1EB [‰] [75]*/ + 0x00,0x30,0x48,0x48,0x48,0x49,0x32,0x04,0x08,0x13,0x24,0x44,0x84,0x04,0x03,0x00, + 0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x0C,0x92,0x92,0x92,0x92,0x0C,0x00, + /* 0xA1EC [§] [76]*/ + 0x03,0x04,0x04,0x04,0x02,0x05,0x09,0x08,0x08,0x04,0x05,0x02,0x01,0x00,0x08,0x07, + 0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, + /* 0xA1ED [?] [77]*/ + 0x60,0x21,0x31,0x31,0x39,0x29,0x29,0x2D,0x2D,0x25,0x27,0x27,0x23,0x23,0xA1,0x41, + 0x80,0x40,0x00,0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x00,0x7E,0x00, + /* 0xA1EE [?] [78]*/ + 0x01,0x01,0x02,0x02,0x02,0x04,0xFC,0x40,0x30,0x08,0x08,0x11,0x16,0x18,0x20,0x00, + 0x00,0x00,0x80,0x80,0x80,0x40,0x7E,0x04,0x18,0x20,0x20,0x90,0x50,0x30,0x08,0x00, + /* 0xA1EF [?] [79]*/ + 0x01,0x01,0x03,0x03,0x03,0x07,0xFF,0x7F,0x3F,0x0F,0x0F,0x1F,0x1E,0x18,0x20,0x00, + 0x00,0x00,0x80,0x80,0x80,0xC0,0xFE,0xFC,0xF8,0xE0,0xE0,0xF0,0xF0,0x30,0x08,0x00, + /* 0xA1F0 [?] [80]*/ + 0x00,0x07,0x1C,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x1C,0x07,0x00,0x00, + 0x00,0xC0,0x70,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x70,0xC0,0x00,0x00, + /* 0xA1F1 [?] [81]*/ + 0x00,0x07,0x1F,0x3F,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x1F,0x07,0x00,0x00, + 0x00,0xC0,0xF0,0xF8,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xC0,0x00,0x00, + /* 0xA1F2 [?] [82]*/ + 0x00,0x07,0x18,0x23,0x24,0x48,0x50,0x50,0x50,0x48,0x24,0x23,0x18,0x07,0x00,0x00, + 0x00,0xC0,0x30,0x88,0x48,0x24,0x14,0x14,0x14,0x24,0x48,0x88,0x30,0xC0,0x00,0x00, + /* 0xA1F3 [?] [83]*/ + 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00, + 0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xA1F4 [?] [84]*/ + 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01,0x00, + 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00, + /* 0xA1F5 [?] [85]*/ + 0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00, + /* 0xA1F6 [¦] [86]*/ + 0x00,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x00,0x00, + 0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0x00,0x00, + /* 0xA1F7 [?] [87]*/ + 0x00,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x7F,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0xFC,0x00,0x00, + /* 0xA1F8 [?] [88]*/ + 0x00,0x01,0x01,0x03,0x03,0x07,0x07,0x0F,0x0F,0x1F,0x1F,0x3F,0x3F,0x7F,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xE0,0xE0,0xF0,0xF0,0xF8,0xF8,0xFC,0x00,0x00, + /* 0xA1F9 [?] [89]*/ + 0x00,0x43,0x23,0x10,0x08,0x04,0x02,0x61,0x62,0x04,0x08,0x10,0x23,0x43,0x80,0x00, + 0x00,0x04,0x08,0x10,0x20,0x40,0x80,0x0C,0x8C,0x40,0x20,0x10,0x08,0x04,0x02,0x00, + /* 0xA1FA [?] [90]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x60,0x38,0xFE,0x38,0x60,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA1FB [?] [91]*/ + 0x00,0x00,0x00,0x00,0x02,0x0C,0x38,0xFF,0x38,0x0C,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1FC [?] [92]*/ + 0x01,0x01,0x03,0x03,0x07,0x05,0x09,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x80,0x80,0xC0,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA1FD [?] [93]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x09,0x05,0x07,0x03,0x03,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0xC0,0x80,0x80,0x00,0x00, + /* 0xA1FE [?] [94]*/ + 0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFC,0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00, + /* 0xA2A1 [?] [95]*/ + 0x00,0x01,0x00,0x00,0x01,0x03,0x05,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + /* 0xA2A2 [?] [96]*/ + 0x00,0x08,0x00,0x00,0x08,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00, + 0x00,0x40,0x00,0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0xE0,0x00,0x00,0x00, + /* 0xA2A3 [?] [97]*/ + 0x00,0x11,0x00,0x00,0x11,0x33,0x11,0x11,0x11,0x11,0x11,0x11,0x3B,0x00,0x00,0x00, + 0x00,0x10,0x00,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0xB8,0x00,0x00,0x00, + /* 0xA2A4 [?] [98]*/ + 0x00,0x10,0x00,0x00,0x16,0x32,0x12,0x11,0x11,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x0C,0x08,0x08,0x10,0x10,0xA0,0xA0,0x40,0x40,0x00,0x00,0x00, + /* 0xA2A5 [?] [99]*/ + 0x00,0x00,0x00,0x00,0x18,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x30,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA2A6 [?] [100]*/ + 0x00,0x00,0x00,0x00,0xC1,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00, + 0x00,0x10,0x00,0x00,0x90,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + /* 0xA2A7 [?] [101]*/ + 0x00,0x00,0x00,0x00,0xC6,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + 0x00,0x44,0x00,0x00,0x44,0xCC,0x44,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00,0x00, + /* 0xA2A8 [?] [102]*/ + 0x00,0x01,0x00,0x00,0xC5,0x47,0x45,0x45,0x29,0x29,0x29,0x11,0x13,0x00,0x00,0x00, + 0x00,0x24,0x00,0x00,0x24,0x6C,0x24,0x24,0x24,0x24,0x24,0x24,0xAE,0x00,0x00,0x00, + /* 0xA2A9 [?] [103]*/ + 0x00,0x20,0x00,0x00,0x27,0x62,0x21,0x20,0x20,0x20,0x21,0x22,0x77,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1C,0x08,0x10,0xA0,0x40,0xA0,0x10,0x08,0x1C,0x00,0x00,0x00, + /* 0xA2AA [?] [104]*/ + 0x00,0x00,0x00,0x00,0x1C,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x1C,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x70,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x70,0x00,0x00,0x00, + /* 0xA2AB [?] [105]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2AC [?] [106]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2AD [?] [107]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2AE [?] [108]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2AF [?] [109]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2B0 [?] [110]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2B1 [?] [111]*/ + 0x01,0x03,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B2 [?] [112]*/ + 0x0F,0x10,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x18,0x98,0x00,0x00,0x00,0x00, + /* 0xA2B3 [?] [113]*/ + 0x1F,0x00,0x01,0x02,0x06,0x01,0x00,0x00,0x00,0x00,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x80,0x80,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B4 [?] [114]*/ + 0x02,0x02,0x04,0x04,0x09,0x09,0x11,0x11,0x1F,0x01,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B5 [?] [115]*/ + 0x1F,0x10,0x10,0x10,0x1E,0x01,0x00,0x00,0x00,0x00,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B6 [?] [116]*/ + 0x02,0x04,0x08,0x08,0x10,0x17,0x18,0x10,0x10,0x10,0x10,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x98,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B7 [?] [117]*/ + 0x1F,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00, + 0xC0,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B8 [?] [118]*/ + 0x0F,0x10,0x10,0x10,0x09,0x06,0x09,0x10,0x10,0x10,0x10,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x98,0x18,0x00,0x00,0x00,0x00, + /* 0xA2B9 [?] [119]*/ + 0x0F,0x10,0x10,0x10,0x10,0x11,0x0E,0x00,0x01,0x01,0x02,0x04,0x00,0x00,0x00,0x00, + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + /* 0xA2BA [?] [120]*/ + 0x23,0x64,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x23,0x00,0x00,0x00,0x00, + 0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2C,0xCC,0x00,0x00,0x00,0x00, + /* 0xA2BB [?] [121]*/ + 0x20,0x61,0xA2,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x8C,0x8C,0x00,0x00,0x00,0x00, + /* 0xA2BC [?] [122]*/ + 0x23,0x64,0xA0,0x20,0x20,0x20,0x20,0x21,0x22,0x24,0x24,0x27,0x00,0x00,0x00,0x00, + 0xC0,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x0C,0xEC,0x00,0x00,0x00,0x00, + /* 0xA2BD [?] [123]*/ + 0x27,0x60,0xA0,0x20,0x21,0x20,0x20,0x20,0x20,0x20,0x24,0x23,0x00,0x00,0x00,0x00, + 0xE0,0x20,0x40,0x80,0x80,0x40,0x20,0x20,0x20,0x20,0x4C,0x8C,0x00,0x00,0x00,0x00, + /* 0xA2BE [?] [124]*/ + 0x20,0x60,0xA1,0x21,0x22,0x22,0x24,0x24,0x27,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + 0x80,0x80,0x00,0x00,0x40,0x40,0x40,0x40,0xF0,0x40,0x4C,0x4C,0x00,0x00,0x00,0x00, + /* 0xA2BF [?] [125]*/ + 0x27,0x64,0xA4,0x24,0x27,0x20,0x20,0x20,0x20,0x20,0x24,0x23,0x00,0x00,0x00,0x00, + 0xE0,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x4C,0x8C,0x00,0x00,0x00,0x00, + /* 0xA2C0 [?] [126]*/ + 0x20,0x61,0xA2,0x22,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x23,0x00,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0x20,0x2C,0xCC,0x00,0x00,0x00,0x00, + /* 0xA2C1 [?] [127]*/ + 0x27,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + 0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x80,0x80,0x8C,0x8C,0x00,0x00,0x00,0x00, + /* 0xA2C2 [?] [128]*/ + 0x23,0x64,0xA4,0x24,0x22,0x21,0x22,0x24,0x24,0x24,0x24,0x23,0x00,0x00,0x00,0x00, + 0xC0,0x20,0x20,0x20,0x40,0x80,0x40,0x20,0x20,0x20,0x2C,0xCC,0x00,0x00,0x00,0x00, + /* 0xA2C3 [?] [129]*/ + 0x23,0x64,0xA4,0x24,0x24,0x24,0x23,0x20,0x20,0x20,0x20,0x21,0x00,0x00,0x00,0x00, + 0xC0,0x20,0x20,0x20,0x20,0x60,0xA0,0x20,0x40,0x40,0x8C,0x0C,0x00,0x00,0x00,0x00, + /* 0xA2C4 [?] [130]*/ + 0x38,0x45,0x05,0x05,0x05,0x09,0x11,0x21,0x21,0x41,0x41,0x7C,0x00,0x00,0x00,0x00, + 0xE0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x16,0xE6,0x00,0x00,0x00,0x00, + /* 0xA2C5 [?] [131]*/ + 0x10,0x20,0x41,0x43,0x85,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x41,0x41,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10, + /* 0xA2C6 [?] [132]*/ + 0x10,0x20,0x47,0x48,0x80,0x80,0x80,0x80,0x81,0x82,0x84,0x88,0x48,0x4F,0x20,0x10, + 0x10,0x08,0x84,0x44,0x42,0x42,0x42,0x82,0x02,0x02,0x02,0x02,0x04,0xC4,0x08,0x10, + /* 0xA2C7 [?] [133]*/ + 0x10,0x20,0x4F,0x40,0x80,0x81,0x83,0x80,0x80,0x80,0x80,0x80,0x48,0x47,0x20,0x10, + 0x10,0x08,0xC4,0x44,0x82,0x02,0x02,0x82,0x42,0x42,0x42,0x42,0x84,0x04,0x08,0x10, + /* 0xA2C8 [?] [134]*/ + 0x10,0x20,0x41,0x41,0x82,0x82,0x84,0x84,0x88,0x88,0x8F,0x80,0x40,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x82,0x82,0x82,0x82,0xE2,0x82,0x84,0x84,0x08,0x10, + /* 0xA2C9 [?] [135]*/ + 0x10,0x20,0x47,0x44,0x84,0x84,0x87,0x80,0x80,0x80,0x80,0x80,0x44,0x43,0x20,0x10, + 0x10,0x08,0xE4,0x04,0x02,0x02,0x82,0x42,0x22,0x22,0x22,0x22,0x44,0x84,0x08,0x10, + /* 0xA2CA [?] [136]*/ + 0x10,0x20,0x41,0x42,0x84,0x84,0x88,0x8B,0x8C,0x88,0x88,0x88,0x48,0x47,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x82,0x42,0x42,0x42,0x42,0x44,0x84,0x08,0x10, + /* 0xA2CB [?] [137]*/ + 0x10,0x20,0x4F,0x40,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x41,0x41,0x20,0x10, + 0x10,0x08,0xE4,0x24,0x42,0x42,0x82,0x82,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10, + /* 0xA2CC [?] [138]*/ + 0x10,0x20,0x47,0x48,0x88,0x88,0x84,0x83,0x84,0x88,0x88,0x88,0x48,0x47,0x20,0x10, + 0x10,0x08,0x84,0x44,0x42,0x42,0x82,0x02,0x82,0x42,0x42,0x42,0x44,0x84,0x08,0x10, + /* 0xA2CD [?] [139]*/ + 0x10,0x20,0x43,0x44,0x84,0x84,0x84,0x84,0x83,0x80,0x80,0x80,0x40,0x41,0x20,0x10, + 0x10,0x08,0xC4,0x24,0x22,0x22,0x22,0x62,0xA2,0x22,0x42,0x42,0x84,0x04,0x08,0x10, + /* 0xA2CE [?] [140]*/ + 0x10,0x20,0x48,0x59,0xA9,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x49,0x48,0x20,0x10, + 0x10,0x08,0xE4,0x14,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x14,0xE4,0x08,0x10, + /* 0xA2CF [?] [141]*/ + 0x10,0x20,0x48,0x58,0xA8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x48,0x48,0x20,0x10, + 0x10,0x08,0x24,0x64,0xA2,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x24,0x24,0x08,0x10, + /* 0xA2D0 [?] [142]*/ + 0x10,0x20,0x48,0x59,0xA8,0x88,0x88,0x88,0x88,0x88,0x88,0x89,0x49,0x49,0x20,0x10, + 0x10,0x08,0xE4,0x14,0x12,0x12,0x12,0x22,0x42,0x82,0x82,0x02,0x04,0xF4,0x08,0x10, + /* 0xA2D1 [?] [143]*/ + 0x10,0x20,0x4B,0x58,0xA8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x4A,0x49,0x20,0x10, + 0x10,0x08,0xF4,0x14,0x22,0x42,0xC2,0x22,0x12,0x12,0x12,0x12,0x24,0xC4,0x08,0x10, + /* 0xA2D2 [?] [144]*/ + 0x10,0x20,0x48,0x58,0xA8,0x88,0x89,0x89,0x8A,0x8A,0x8B,0x88,0x48,0x48,0x20,0x10, + 0x10,0x08,0x44,0x44,0x82,0x82,0x22,0x22,0x22,0x22,0xFA,0x22,0x24,0x24,0x08,0x10, + /* 0xA2D3 [?] [145]*/ + 0x10,0x20,0x4B,0x5A,0xAA,0x8A,0x8B,0x88,0x88,0x88,0x88,0x88,0x4A,0x49,0x20,0x10, + 0x10,0x08,0xF4,0x04,0x02,0x02,0xC2,0x22,0x12,0x12,0x12,0x12,0x24,0xC4,0x08,0x10, + /* 0xA2D4 [?] [146]*/ + 0x10,0x20,0x48,0x58,0xA9,0x89,0x8A,0x8A,0x8B,0x8A,0x8A,0x8A,0x4A,0x49,0x20,0x10, + 0x10,0x08,0x44,0x84,0x02,0x02,0x02,0xE2,0x12,0x12,0x12,0x12,0x14,0xE4,0x08,0x10, + /* 0xA2D5 [?] [147]*/ + 0x10,0x20,0x4B,0x58,0xA8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x48,0x48,0x20,0x10, + 0x10,0x08,0xF4,0x14,0x22,0x22,0x42,0x42,0x82,0x82,0x82,0x82,0x84,0x84,0x08,0x10, + /* 0xA2D6 [?] [148]*/ + 0x10,0x20,0x49,0x5A,0xAA,0x8A,0x89,0x88,0x89,0x8A,0x8A,0x8A,0x4A,0x49,0x20,0x10, + 0x10,0x08,0xE4,0x14,0x12,0x12,0x22,0xC2,0x22,0x12,0x12,0x12,0x14,0xE4,0x08,0x10, + /* 0xA2D7 [?] [149]*/ + 0x10,0x20,0x49,0x5A,0xAA,0x8A,0x8A,0x8A,0x89,0x88,0x88,0x88,0x48,0x48,0x20,0x10, + 0x10,0x08,0xE4,0x14,0x12,0x12,0x12,0x32,0xD2,0x12,0x22,0x22,0x44,0x84,0x08,0x10, + /* 0xA2D8 [?] [150]*/ + 0x10,0x20,0x4C,0x52,0x82,0x82,0x82,0x84,0x84,0x88,0x90,0x90,0x50,0x5E,0x20,0x10, + 0x10,0x08,0x64,0x94,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x94,0x64,0x08,0x10, + /* 0xA2D9 [?] [151]*/ + 0x07,0x18,0x20,0x41,0x43,0x85,0x81,0x81,0x81,0x81,0x41,0x41,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x30,0xC0,0x00, + /* 0xA2DA [?] [152]*/ + 0x07,0x18,0x20,0x43,0x44,0x80,0x80,0x80,0x81,0x82,0x44,0x47,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x84,0x44,0x42,0x42,0x82,0x02,0x02,0x04,0xC4,0x08,0x30,0xC0,0x00, + /* 0xA2DB [?] [153]*/ + 0x07,0x18,0x20,0x47,0x40,0x80,0x81,0x83,0x80,0x80,0x44,0x43,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0xC4,0x44,0x82,0x02,0x02,0x82,0x42,0x44,0x84,0x08,0x30,0xC0,0x00, + /* 0xA2DC [?] [154]*/ + 0x07,0x18,0x20,0x41,0x42,0x82,0x84,0x84,0x88,0x8F,0x40,0x40,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x04,0x04,0x02,0x82,0x82,0x82,0xE2,0x84,0x84,0x08,0x30,0xC0,0x00, + /* 0xA2DD [?] [155]*/ + 0x07,0x18,0x20,0x47,0x44,0x84,0x87,0x80,0x80,0x80,0x48,0x47,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0xC4,0x04,0x02,0x82,0x42,0x42,0x42,0x84,0x04,0x08,0x30,0xC0,0x00, + /* 0xA2DE [?] [156]*/ + 0x07,0x18,0x20,0x41,0x42,0x82,0x84,0x85,0x86,0x84,0x44,0x43,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x04,0x04,0x02,0x02,0x82,0x42,0x42,0x44,0x84,0x08,0x30,0xC0,0x00, + /* 0xA2DF [?] [157]*/ + 0x07,0x18,0x20,0x47,0x40,0x80,0x80,0x81,0x81,0x81,0x41,0x41,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0xC4,0x44,0x82,0x82,0x02,0x02,0x02,0x04,0x04,0x08,0x30,0xC0,0x00, + /* 0xA2E0 [?] [158]*/ + 0x07,0x18,0x20,0x43,0x44,0x84,0x84,0x83,0x84,0x84,0x44,0x43,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x84,0x44,0x42,0x42,0x82,0x42,0x42,0x44,0x84,0x08,0x30,0xC0,0x00, + /* 0xA2E1 [?] [159]*/ + 0x07,0x18,0x20,0x43,0x44,0x84,0x84,0x83,0x80,0x80,0x41,0x42,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0x84,0x44,0x42,0x42,0xC2,0x42,0x82,0x04,0x04,0x08,0x30,0xC0,0x00, + /* 0xA2E2 [?] [160]*/ + 0x07,0x18,0x20,0x49,0x5A,0xAA,0x8A,0x8A,0x8A,0x8A,0x4A,0x49,0x20,0x18,0x07,0x00, + 0xC0,0x30,0x08,0xC4,0x24,0x22,0x22,0x22,0x22,0x22,0x24,0xC4,0x08,0x30,0xC0,0x00, + /* 0xA2E3 [?] [161]*/ + 0x00,0x00,0x00,0x01,0x06,0x08,0x08,0x3F,0x18,0x1F,0x08,0x0C,0x06,0x01,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x10,0x00,0x00,0xE0,0x00,0xC0,0x00,0x00,0x30,0xC0,0x00,0x00, + /* 0xA2E4 [?] [162]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2E5 [?] [163]*/ + 0x10,0x20,0x40,0x40,0x80,0x80,0x80,0xBF,0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x02,0xFA,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10, + /* 0xA2E6 [?] [164]*/ + 0x10,0x20,0x40,0x40,0x9F,0x80,0x80,0x80,0x80,0x80,0xBF,0x80,0x40,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0xF2,0x02,0x02,0x02,0x02,0x02,0xFA,0x02,0x04,0x04,0x08,0x10, + /* 0xA2E7 [?] [165]*/ + 0x10,0x20,0x40,0x5F,0x80,0x80,0x80,0x8F,0x80,0x80,0x80,0xBF,0x40,0x40,0x20,0x10, + 0x10,0x08,0x04,0xF4,0x02,0x02,0x02,0xE2,0x02,0x02,0x02,0xFA,0x04,0x04,0x08,0x10, + /* 0xA2E8 [?] [166]*/ + 0x10,0x20,0x40,0x40,0x9F,0x92,0x92,0x92,0x94,0x98,0x90,0x9F,0x50,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0xF2,0x92,0x92,0x92,0x72,0x12,0x12,0xF2,0x14,0x04,0x08,0x10, + /* 0xA2E9 [?] [167]*/ + 0x10,0x20,0x40,0x4F,0x81,0x81,0x81,0x8F,0x82,0x82,0x82,0x82,0x5F,0x40,0x20,0x10, + 0x10,0x08,0x04,0xE4,0x02,0x02,0x02,0xE2,0x22,0x22,0x22,0x22,0xFC,0x04,0x08,0x10, + /* 0xA2EA [?] [168]*/ + 0x10,0x20,0x40,0x42,0x81,0x80,0xBF,0x80,0x80,0x84,0x84,0x88,0x50,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0xFA,0x02,0x02,0x42,0x22,0x12,0x14,0x04,0x08,0x10, + /* 0xA2EB [?] [169]*/ + 0x10,0x20,0x42,0x42,0x82,0x82,0x82,0x83,0xBE,0x82,0x82,0x82,0x42,0x41,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x02,0xF2,0x02,0x02,0x22,0x22,0x24,0xE4,0x08,0x10, + /* 0xA2EC [?] [170]*/ + 0x10,0x20,0x40,0x44,0x84,0x84,0x84,0x84,0x84,0x88,0x88,0x90,0x40,0x40,0x20,0x10, + 0x10,0x08,0x84,0x84,0x82,0x82,0x82,0x42,0x42,0x22,0x22,0x12,0x04,0x04,0x08,0x10, + /* 0xA2ED [?] [171]*/ + 0x10,0x20,0x42,0x42,0x82,0x9F,0x82,0x82,0x82,0x84,0x84,0x88,0x50,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0xC2,0x42,0x42,0x42,0x42,0x4A,0x4A,0x3C,0x04,0x08,0x10, + /* 0xA2EE [?] [172]*/ + 0x10,0x20,0x41,0x41,0x81,0x81,0x81,0xBF,0x81,0x81,0x81,0x81,0x41,0x40,0x20,0x10, + 0x10,0x08,0x04,0x04,0x02,0x02,0x02,0xFA,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10, + /* 0xA2EF [?] [173]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2F0 [?] [174]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2F1 [?] [175]*/ + 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00, + /* 0xA2F2 [?] [176]*/ + 0x00,0x0E,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0E,0x00, + 0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xE0,0x00, + /* 0xA2F3 [?] [177]*/ + 0x00,0x3B,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3B,0x00, + 0x00,0xB8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xB8,0x00, + /* 0xA2F4 [?] [178]*/ + 0x00,0x77,0x22,0x22,0x22,0x21,0x21,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + 0x00,0x1C,0x08,0x08,0x08,0x10,0x10,0x10,0x10,0xA0,0xA0,0xA0,0xA0,0x40,0x40,0x00, + /* 0xA2F5 [?] [179]*/ + 0x00,0x70,0x20,0x10,0x10,0x08,0x08,0x08,0x04,0x04,0x04,0x02,0x02,0x01,0x01,0x00, + 0x00,0x1C,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00, + /* 0xA2F6 [?] [180]*/ + 0x00,0x71,0x20,0x20,0x20,0x11,0x11,0x11,0x11,0x0A,0x0A,0x0A,0x0A,0x04,0x04,0x00, + 0x00,0xDC,0x88,0x88,0x88,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00, + /* 0xA2F7 [?] [181]*/ + 0x00,0xE3,0x41,0x41,0x41,0x22,0x22,0x22,0x22,0x14,0x14,0x14,0x14,0x08,0x08,0x00, + 0x00,0xFE,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x7E,0x00, + /* 0xA2F8 [?] [182]*/ + 0x00,0xE3,0x41,0x41,0x41,0x22,0x22,0x22,0x22,0x14,0x14,0x14,0x14,0x08,0x08,0x00, + 0x00,0xFE,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xA2F9 [?] [183]*/ + 0x00,0x77,0x22,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x21,0x22,0x77,0x00, + 0x00,0x1C,0x08,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0xA0,0x10,0x10,0x08,0x1C,0x00, + /* 0xA2FA [?] [184]*/ + 0x00,0x70,0x20,0x10,0x08,0x04,0x02,0x01,0x02,0x04,0x04,0x08,0x10,0x20,0x70,0x00, + 0x00,0x1C,0x08,0x10,0x20,0x40,0x80,0x00,0x80,0x40,0x40,0x20,0x10,0x08,0x1C,0x00, + /* 0xA2FB [?] [185]*/ + 0x00,0xE3,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x14,0x14,0x22,0x22,0x41,0xE3,0x00, + 0x00,0x9C,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x9C,0x00, + /* 0xA2FC [?] [186]*/ + 0x00,0xE3,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x14,0x14,0x22,0x22,0x41,0xE3,0x00, + 0x00,0xBE,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0xBE,0x00, + /* 0xA2FD [?] [187]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA2FE [?] [188]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3A1 [!] [189]*/ + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x10,0x10,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3A2 ["] [190]*/ + 0x00,0x0C,0x0C,0x0C,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xC0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3A3 [#] [191]*/ + 0x00,0x02,0x02,0x02,0x02,0x3F,0x04,0x04,0x04,0x04,0x3F,0x08,0x08,0x08,0x08,0x00, + 0x00,0x20,0x20,0x20,0x20,0xFC,0x40,0x40,0x40,0x40,0xFC,0x80,0x80,0x80,0x80,0x00, + /* 0xA3A4 [?] [192]*/ + 0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3A5 [%] [193]*/ + 0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x19,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + 0x00,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + /* 0xA3A6 [&] [194]*/ + 0x00,0x06,0x09,0x10,0x10,0x09,0x0A,0x04,0x0A,0x12,0x21,0x20,0x20,0x11,0x0E,0x00, + 0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x70,0x20,0xA0,0x40,0xA0,0x10,0x00, + /* 0xA3A7 ['] [195]*/ + 0x00,0x38,0x38,0x38,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3A8 [(] [196]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08,0x00, + /* 0xA3A9 [)] [197]*/ + 0x00,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3AA [*] [198]*/ + 0x00,0x00,0x01,0x01,0x01,0x01,0x31,0x0D,0x03,0x02,0x04,0x08,0x10,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x60,0x80,0x80,0x40,0x20,0x10,0x00,0x00,0x00, + /* 0xA3AB [+] [199]*/ + 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3AC [,] [200]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3AD [-] [201]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3AE [.] [202]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3AF [/] [203]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00, + 0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3B0 [0] [204]*/ + 0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0xC0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3B1 [1] [205]*/ + 0x01,0x03,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3B2 [2] [206]*/ + 0x07,0x08,0x10,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, + /* 0xA3B3 [3] [207]*/ + 0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x07,0x00,0x00,0x00,0x00, + 0xF0,0x20,0x40,0x80,0xC0,0x20,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3B4 [4] [208]*/ + 0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00, + /* 0xA3B5 [5] [209]*/ + 0x1F,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x10,0x0F,0x00,0x00,0x00,0x00, + 0xC0,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA3B6 [6] [210]*/ + 0x00,0x01,0x02,0x04,0x08,0x0F,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3B7 [7] [211]*/ + 0x1F,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00, + 0xF0,0x20,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3B8 [8] [212]*/ + 0x07,0x08,0x10,0x10,0x08,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x80,0x40,0x20,0x20,0x40,0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3B9 [9] [213]*/ + 0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00, + 0x80,0x40,0x20,0x20,0x20,0x20,0xC0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3BA [:] [214]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3BB [;] [215]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3BC [<] [216]*/ + 0x00,0x00,0x00,0x00,0x03,0x0C,0x30,0xC0,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00, + /* 0xA3BD [=] [217]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3BE [>] [218]*/ + 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x18,0x60,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x06,0x18,0x60,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA3BF [?] [219]*/ + 0x00,0x0E,0x11,0x21,0x31,0x31,0x03,0x06,0x06,0x06,0x06,0x00,0x06,0x06,0x00,0x00, + 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3C0 [@] [220]*/ + 0x00,0x1F,0x20,0x00,0x0E,0x11,0x20,0x20,0x20,0x20,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x10,0x08,0x88,0x88,0x88,0x88,0x88,0x88,0x90,0x60,0x00,0x00,0x00,0x00, + /* 0xA3C1 [A] [221]*/ + 0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x0F,0x10,0x10,0x20,0x70,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0xE0,0x10,0x10,0x08,0x1C,0x00,0x00,0x00,0x00, + /* 0xA3C2 [B] [222]*/ + 0x00,0x1F,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x10,0x10,0x10,0x20,0xC0,0x20,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,0x00, + /* 0xA3C3 [C] [223]*/ + 0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3C4 [D] [224]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3C5 [E] [225]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x80,0x80,0x80,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA3C6 [F] [226]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x40,0xC0,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3C7 [G] [227]*/ + 0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0xD0,0x30,0x10,0x00,0x00,0x00,0x78,0x10,0x10,0x30,0xD0,0x00,0x00,0x00,0x00, + /* 0xA3C8 [H] [228]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA3C9 [I] [229]*/ + 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA3CA [J] [230]*/ + 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x11,0x0E,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3CB [K] [231]*/ + 0x00,0x1C,0x08,0x08,0x09,0x0A,0x0E,0x09,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x70,0x40,0x80,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x38,0x00,0x00,0x00,0x00, + /* 0xA3CC [L] [232]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xE0,0x00,0x00,0x00,0x00, + /* 0xA3CD [M] [233]*/ + 0x00,0x30,0x18,0x14,0x14,0x12,0x12,0x11,0x11,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x18,0x30,0x50,0x50,0x90,0x90,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + /* 0xA3CE [N] [234]*/ + 0x00,0x30,0x18,0x14,0x14,0x12,0x11,0x11,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x60,0x20,0x00,0x00,0x00,0x00, + /* 0xA3CF [O] [235]*/ + 0x00,0x07,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3D0 [P] [236]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3D1 [Q] [237]*/ + 0x00,0x07,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x11,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0xA0,0x40,0xA0,0x18,0x00,0x00,0x00, + /* 0xA3D2 [R] [238]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x12,0x11,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x80,0x40,0x30,0x00,0x00,0x00,0x00, + /* 0xA3D3 [S] [239]*/ + 0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0x10,0x18,0x17,0x00,0x00,0x00,0x00, + 0x00,0xD0,0x30,0x10,0x00,0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3D4 [T] [240]*/ + 0x00,0x3F,0x21,0x21,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA3D5 [U] [241]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3D6 [V] [242]*/ + 0x00,0x70,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00, + 0x00,0x1C,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA3D7 [W] [243]*/ + 0x00,0x73,0x21,0x21,0x21,0x22,0x12,0x12,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00, + 0x00,0x9C,0x08,0x08,0x08,0x88,0x90,0x90,0x50,0x50,0x20,0x20,0x00,0x00,0x00,0x00, + /* 0xA3D8 [X] [244]*/ + 0x00,0x38,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x08,0x38,0x00,0x00,0x00,0x00, + 0x00,0x38,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x40,0x20,0x38,0x00,0x00,0x00,0x00, + /* 0xA3D9 [Y] [245]*/ + 0x00,0x38,0x10,0x08,0x04,0x04,0x02,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x38,0x10,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA3DA [Z] [246]*/ + 0x00,0x1F,0x10,0x10,0x00,0x00,0x01,0x02,0x02,0x04,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x80,0x00,0x00,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA3DB [[] [247]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x1C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1C,0x00, + /* 0xA3DC [\] [248]*/ + 0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00, + /* 0xA3DD []] [249]*/ + 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3DE [^] [250]*/ + 0x00,0x01,0x02,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3DF [_] [251]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, + /* 0xA3E0 [`] [252]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x20,0x20,0x20,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3E1 [a] [253]*/ + 0x00,0x00,0x00,0x00,0x0F,0x10,0x00,0x0F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x40,0xC0,0x40,0x40,0x40,0xA0,0x00,0x00,0x00,0x00, + /* 0xA3E2 [b] [254]*/ + 0x08,0x08,0x08,0x08,0x0B,0x0C,0x08,0x08,0x08,0x08,0x0C,0x0B,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3E3 [c] [255]*/ + 0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x20,0x00,0x00,0x00,0x00,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3E4 [d] [256]*/ + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x20,0x20,0x20,0x20,0xA0,0x60,0x20,0x20,0x20,0x20,0x60,0xA0,0x00,0x00,0x00,0x00, + /* 0xA3E5 [e] [257]*/ + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x0F,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3E6 [f] [258]*/ + 0x00,0x00,0x01,0x01,0x01,0x01,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0xC0,0x20,0x20,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3E7 [g] [259]*/ + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x08,0x07,0x00, + 0x00,0x00,0x00,0x00,0xA0,0x60,0x20,0x20,0x20,0x60,0xA0,0x20,0x20,0x40,0x80,0x00, + /* 0xA3E8 [h] [260]*/ + 0x08,0x08,0x08,0x08,0x09,0x0A,0x0C,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + /* 0xA3E9 [i] [261]*/ + 0x01,0x01,0x00,0x00,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3EA [j] [262]*/ + 0x01,0x01,0x00,0x00,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x09,0x06,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3EB [k] [263]*/ + 0x00,0x08,0x08,0x08,0x08,0x08,0x09,0x0A,0x0D,0x08,0x08,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x80,0x40,0x20,0x00,0x00,0x00,0x00, + /* 0xA3EC [l] [264]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xE0,0x00,0x00,0x00,0x00, + /* 0xA3ED [m] [265]*/ + 0x00,0x00,0x00,0x00,0x1A,0x0D,0x09,0x09,0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + /* 0xA3EE [n] [266]*/ + 0x00,0x00,0x00,0x00,0x0B,0x0C,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00, + /* 0xA3EF [o] [267]*/ + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3F0 [p] [268]*/ + 0x00,0x00,0x00,0x00,0x1B,0x0C,0x08,0x08,0x08,0x08,0x0C,0x0B,0x08,0x08,0x08,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3F1 [q] [269]*/ + 0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xA0,0x60,0x20,0x20,0x20,0x20,0x60,0xA0,0x20,0x20,0x30,0x00, + /* 0xA3F2 [r] [270]*/ + 0x00,0x00,0x00,0x00,0x05,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3F3 [s] [271]*/ + 0x00,0x00,0x00,0x00,0x07,0x08,0x08,0x06,0x01,0x00,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x40,0x00,0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3F4 [t] [272]*/ + 0x01,0x01,0x01,0x01,0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA3F5 [u] [273]*/ + 0x00,0x00,0x00,0x00,0x0C,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0xC0,0x40,0x00,0x00,0x00,0x00, + /* 0xA3F6 [v] [274]*/ + 0x00,0x00,0x00,0x00,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3F7 [w] [275]*/ + 0x00,0x00,0x00,0x00,0x11,0x11,0x11,0x09,0x0A,0x0A,0x04,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x20,0xA0,0xA0,0x40,0x40,0x00,0x00,0x00,0x00, + /* 0xA3F8 [x] [276]*/ + 0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x00,0x00,0x00,0x00, + /* 0xA3F9 [y] [277]*/ + 0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x02,0x02,0x01,0x01,0x02,0x02,0x04,0x08,0x00, + 0x00,0x00,0x00,0x00,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3FA [z] [278]*/ + 0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x01,0x02,0x04,0x08,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x40,0x80,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00, + /* 0xA3FB [{] [279]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x04,0x00, + /* 0xA3FC [|] [280]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3FD [}] [281]*/ + 0x20,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA3FE [?] [282]*/ + 0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4A1 [?] [283]*/ + 0x00,0x00,0x00,0x04,0x04,0x05,0x3E,0x04,0x07,0x0C,0x14,0x23,0x22,0x25,0x18,0x00, + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x40,0xE0,0x90,0x88,0x08,0x08,0x10,0x20,0xC0, + /* 0xA4A2 [?] [284]*/ + 0x04,0x04,0x04,0x07,0x7C,0x04,0x04,0x1F,0x24,0x44,0x45,0x42,0x26,0x19,0x00,0x00, + 0x00,0x00,0x60,0x80,0x00,0x40,0x40,0xF0,0x88,0x84,0x04,0x04,0x04,0x08,0x30,0x00, + /* 0xA4A3 [?] [285]*/ + 0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x09,0x0A,0x06,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x08,0x18,0x10,0x00,0x00,0x00,0x00, + /* 0xA4A4 [?] [286]*/ + 0x00,0x00,0x00,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x21,0x22,0x14,0x0C,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x28,0x04,0x02,0x02,0x06,0x04,0x00,0x00,0x00,0x00, + /* 0xA4A5 [?] [287]*/ + 0x00,0x08,0x07,0x00,0x01,0x00,0x11,0x0E,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x00, + 0x00,0x00,0x00,0x80,0x00,0x00,0xC0,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00, + /* 0xA4A6 [?] [288]*/ + 0x08,0x07,0x00,0x01,0x00,0x21,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00, + 0x00,0x80,0x40,0x80,0x00,0xE0,0x10,0x10,0x10,0x10,0x20,0x20,0xC0,0x00,0x00,0x00, + /* 0xA4A7 [?] [289]*/ + 0x00,0x00,0x04,0x03,0x00,0x01,0x00,0x03,0x1C,0x01,0x03,0x04,0x08,0x10,0x20,0x00, + 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xC0,0x80,0x00,0x00,0x80,0x80,0x40,0x38,0x00, + /* 0xA4A8 [?] [290]*/ + 0x08,0x07,0x00,0x01,0x00,0x03,0x3C,0x01,0x02,0x03,0x04,0x04,0x08,0x10,0x20,0x00, + 0x00,0x00,0x80,0x00,0x00,0xC0,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x40,0x3C,0x00, + /* 0xA4A9 [?] [291]*/ + 0x00,0x00,0x00,0x04,0x04,0x04,0x3F,0x04,0x05,0x06,0x0C,0x14,0x34,0x15,0x08,0x00, + 0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x02,0xE4,0x10,0x08,0x08,0x08,0x30,0xC0,0x00, + /* 0xA4AA [?] [292]*/ + 0x00,0x04,0x04,0x07,0x3C,0x04,0x04,0x05,0x06,0x1C,0x24,0x64,0x35,0x0C,0x04,0x00, + 0x00,0x00,0x08,0x84,0x02,0x0C,0x00,0xF0,0x08,0x04,0x04,0x04,0x18,0xE0,0x00,0x00, + /* 0xA4AB [?] [293]*/ + 0x00,0x02,0x02,0x02,0x02,0x23,0x1C,0x04,0x04,0x04,0x08,0x08,0x10,0x24,0x43,0x00, + 0x00,0x00,0x00,0x00,0x10,0x88,0x44,0x42,0x42,0x44,0x40,0x40,0x80,0x80,0x00,0x00, + /* 0xA4AC [?] [294]*/ + 0x00,0x04,0x04,0x04,0x04,0x47,0x38,0x08,0x08,0x08,0x10,0x10,0x21,0x49,0x86,0x00, + 0x08,0x04,0x12,0x08,0x24,0x10,0x88,0x84,0x84,0x88,0x90,0x80,0x00,0x00,0x00,0x00, + /* 0xA4AD [?] [295]*/ + 0x02,0x02,0x02,0x03,0x1D,0x00,0x03,0x1C,0x00,0x03,0x00,0x10,0x10,0x08,0x07,0x00, + 0x00,0x00,0x60,0x80,0x00,0xE0,0x80,0x40,0x40,0xE0,0x20,0x00,0x00,0x00,0xC0,0x00, + /* 0xA4AE [?] [296]*/ + 0x04,0x04,0x04,0x07,0x3A,0x01,0x07,0x38,0x00,0x07,0x00,0x20,0x20,0x10,0x0F,0x00, + 0x00,0x08,0xC4,0x12,0x08,0xC4,0x00,0x80,0x80,0xC0,0x40,0x00,0x00,0x00,0x80,0x00, + /* 0xA4AF [?] [297]*/ + 0x00,0x01,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00, + /* 0xA4B0 [?] [298]*/ + 0x00,0x01,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00, + 0x00,0x08,0x84,0x92,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00, + /* 0xA4B1 [?] [299]*/ + 0x00,0x20,0x10,0x10,0x10,0x20,0x20,0x47,0x40,0x40,0x50,0x50,0x60,0x20,0x01,0x00, + 0x00,0x80,0x40,0x40,0x40,0x40,0x7C,0xC0,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00, + /* 0xA4B2 [?] [300]*/ + 0x00,0x20,0x10,0x10,0x10,0x20,0x20,0x47,0x40,0x40,0x50,0x50,0x60,0x20,0x01,0x00, + 0x08,0x84,0x52,0x48,0x44,0x40,0x7C,0xC0,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00, + /* 0xA4B3 [?] [301]*/ + 0x00,0x00,0x10,0x0F,0x00,0x03,0x04,0x00,0x20,0x20,0x20,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xF8,0x00,0x00,0x00, + /* 0xA4B4 [?] [302]*/ + 0x00,0x00,0x10,0x0F,0x00,0x03,0x04,0x00,0x20,0x20,0x20,0x10,0x0F,0x00,0x00,0x00, + 0x00,0x08,0x04,0xD2,0x88,0x04,0x00,0x00,0x00,0x00,0x00,0x10,0xF8,0x00,0x00,0x00, + /* 0xA4B5 [?] [303]*/ + 0x00,0x04,0x02,0x02,0x3F,0x01,0x00,0x00,0x01,0x08,0x10,0x10,0x10,0x08,0x07,0x00, + 0x00,0x00,0x30,0xC0,0x00,0x00,0x80,0x40,0xE0,0x20,0x00,0x00,0x00,0x00,0xE0,0x00, + /* 0xA4B6 [?] [304]*/ + 0x00,0x04,0x02,0x02,0x3F,0x01,0x00,0x00,0x01,0x08,0x10,0x10,0x10,0x08,0x07,0x00, + 0x00,0x08,0x04,0xD2,0x08,0x04,0x80,0x40,0xE0,0x20,0x00,0x00,0x00,0x00,0xE0,0x00, + /* 0xA4B7 [?] [305]*/ + 0x00,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x09,0x06,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xA4B8 [?] [306]*/ + 0x00,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x09,0x06,0x00, + 0x00,0x10,0x08,0x24,0x10,0x08,0x00,0x00,0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xA4B9 [?] [307]*/ + 0x00,0x03,0x01,0x41,0x3F,0x01,0x07,0x09,0x09,0x09,0x06,0x00,0x00,0x00,0x01,0x06, + 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x80,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00, + /* 0xA4BA [?] [308]*/ + 0x03,0x01,0x01,0x41,0x3F,0x01,0x07,0x09,0x09,0x09,0x06,0x00,0x00,0x00,0x01,0x06, + 0x08,0x24,0x12,0x08,0xF0,0x00,0x00,0x80,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00, + /* 0xA4BB [?] [309]*/ + 0x00,0x00,0x10,0x08,0x08,0x0B,0x7C,0x08,0x08,0x0A,0x09,0x08,0x08,0x08,0x07,0x00, + 0x00,0x80,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0xF0,0x00, + /* 0xA4BC [?] [310]*/ + 0x00,0x00,0x10,0x08,0x08,0x0B,0x7C,0x08,0x08,0x0A,0x09,0x08,0x08,0x08,0x07,0x00, + 0x08,0x84,0x52,0x48,0x44,0xF0,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0xF0,0x00, + /* 0xA4BD [?] [311]*/ + 0x00,0x11,0x0E,0x00,0x01,0x06,0x18,0x7F,0x02,0x04,0x04,0x04,0x02,0x01,0x00,0x00, + 0x00,0x80,0x40,0x80,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00, + /* 0xA4BE [?] [312]*/ + 0x00,0x11,0x0E,0x00,0x01,0x06,0x18,0x7F,0x02,0x04,0x04,0x04,0x02,0x01,0x00,0x00, + 0x08,0xA4,0x52,0x88,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00, + /* 0xA4BF [?] [313]*/ + 0x00,0x04,0x04,0x47,0x3C,0x09,0x08,0x08,0x10,0x10,0x12,0x22,0x21,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x30,0x40,0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00, + /* 0xA4C0 [?] [314]*/ + 0x00,0x04,0x04,0x47,0x3C,0x09,0x08,0x08,0x10,0x10,0x12,0x22,0x21,0x40,0x00,0x00, + 0x08,0x04,0x12,0x08,0x04,0xE0,0x30,0x40,0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00, + /* 0xA4C1 [?] [315]*/ + 0x00,0x04,0x04,0x05,0x07,0x7C,0x08,0x0B,0x0C,0x18,0x10,0x00,0x00,0x00,0x00,0x03, + 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x20,0x20,0xC0,0x00, + /* 0xA4C2 [?] [316]*/ + 0x00,0x04,0x04,0x05,0x07,0x7C,0x08,0x0B,0x0C,0x18,0x10,0x00,0x00,0x00,0x00,0x03, + 0x00,0x08,0x04,0x12,0x88,0x04,0x00,0xC0,0x20,0x10,0x10,0x10,0x20,0x20,0xC0,0x00, + /* 0xA4C3 [?] [317]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x08,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x20,0x40,0x80,0x00, + /* 0xA4C4 [?] [318]*/ + 0x00,0x00,0x00,0x01,0x06,0x78,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x10,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0xC0,0x00,0x00,0x00, + /* 0xA4C5 [?] [319]*/ + 0x00,0x00,0x00,0x03,0x0C,0xF0,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,0x00, + 0x08,0x04,0x12,0xC8,0x24,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xA4C6 [?] [320]*/ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x21,0x02,0x04,0x04,0x04,0x04,0x04,0x02,0x01,0x00, + 0x00,0x00,0x00,0x08,0xFC,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + /* 0xA4C7 [?] [321]*/ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x21,0x02,0x04,0x04,0x04,0x04,0x04,0x02,0x01,0x00, + 0x00,0x00,0x00,0x08,0xFC,0xC0,0x08,0x04,0x12,0x08,0x04,0x00,0x00,0x00,0xF0,0x00, + /* 0xA4C8 [?] [322]*/ + 0x00,0x00,0x02,0x01,0x01,0x01,0x01,0x01,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + /* 0xA4C9 [?] [323]*/ + 0x00,0x00,0x02,0x01,0x01,0x01,0x01,0x01,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00, + 0x08,0x04,0x12,0x08,0x04,0x20,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + /* 0xA4CA [?] [324]*/ + 0x00,0x04,0x04,0x04,0x07,0x3C,0x04,0x08,0x08,0x10,0x10,0x23,0x44,0x04,0x03,0x00, + 0x00,0x00,0x10,0x08,0x84,0x04,0x08,0x20,0x20,0x20,0x40,0xE0,0x50,0x48,0x84,0x00, + /* 0xA4CB [?] [325]*/ + 0x00,0x20,0x10,0x10,0x13,0x20,0x20,0x20,0x40,0x40,0x4A,0x52,0x51,0x20,0x20,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00, + /* 0xA4CC [?] [326]*/ + 0x00,0x02,0x02,0x11,0x11,0x13,0x15,0x19,0x11,0x2A,0x2A,0x44,0x44,0x4A,0x32,0x00, + 0x00,0x00,0x00,0x00,0xF0,0x08,0x04,0x04,0x04,0x04,0x68,0x98,0x94,0x62,0x02,0x00, + /* 0xA4CD [?] [327]*/ + 0x00,0x08,0x08,0x08,0x08,0x3E,0x09,0x0A,0x0C,0x18,0x28,0x48,0x49,0x29,0x18,0x00, + 0x00,0x00,0x00,0x00,0x60,0x90,0x08,0x08,0x08,0x08,0x10,0xF0,0x18,0x24,0xC2,0x00, + /* 0xA4CE [?] [328]*/ + 0x00,0x00,0x00,0x07,0x19,0x21,0x42,0x42,0x42,0x44,0x44,0x28,0x10,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0x30,0x08,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0xC0,0x00, + /* 0xA4CF [?] [329]*/ + 0x00,0x20,0x10,0x10,0x14,0x23,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x00,0x80,0x40,0x40,0x40,0xF8,0x40,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4D0 [?] [330]*/ + 0x00,0x20,0x10,0x10,0x14,0x23,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x08,0x84,0x52,0x48,0x44,0xF0,0x40,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4D1 [?] [331]*/ + 0x00,0x20,0x10,0x10,0x14,0x23,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x0C,0x92,0x52,0x4C,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4D2 [?] [332]*/ + 0x00,0x00,0x02,0x3E,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00, + 0x00,0x00,0x00,0x20,0x20,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x00,0x00, + /* 0xA4D3 [?] [333]*/ + 0x00,0x00,0x02,0x3E,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00, + 0x08,0x04,0x12,0x08,0x24,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x00,0x00, + /* 0xA4D4 [?] [334]*/ + 0x00,0x00,0x02,0x3E,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00, + 0x0C,0x12,0x12,0x0C,0x20,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x00,0x00, + /* 0xA4D5 [?] [335]*/ + 0x00,0x03,0x00,0x00,0x01,0x02,0x02,0x01,0x00,0x03,0x04,0x44,0x58,0x26,0x01,0x00, + 0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0xE0,0x98,0x84,0x8C,0x80,0x80,0x00,0x00, + /* 0xA4D6 [?] [336]*/ + 0x00,0x03,0x00,0x00,0x01,0x02,0x02,0x01,0x00,0x03,0x04,0x44,0x58,0x26,0x01,0x00, + 0x08,0x04,0x92,0xC8,0x04,0x00,0x00,0x00,0xE0,0x98,0x84,0x8C,0x80,0x80,0x00,0x00, + /* 0xA4D7 [?] [337]*/ + 0x00,0x03,0x00,0x00,0x01,0x02,0x02,0x01,0x00,0x03,0x04,0x44,0x58,0x26,0x01,0x00, + 0x0C,0x12,0x92,0xCC,0x00,0x00,0x00,0x00,0xE0,0x98,0x84,0x8C,0x80,0x80,0x00,0x00, + /* 0xA4D8 [?] [338]*/ + 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4D9 [?] [339]*/ + 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x08,0x04,0x12,0x08,0x84,0x40,0x20,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4DA [?] [340]*/ + 0x00,0x00,0x00,0x00,0x06,0x09,0x10,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x24,0x24,0x18,0x80,0x40,0x20,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4DB [?] [341]*/ + 0x00,0x20,0x13,0x10,0x10,0x24,0x23,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x00,0x70,0xC0,0x40,0x40,0x40,0xF8,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4DC [?] [342]*/ + 0x00,0x20,0x13,0x10,0x10,0x24,0x23,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x08,0x64,0xC2,0x48,0x44,0x40,0xF8,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4DD [?] [343]*/ + 0x00,0x20,0x13,0x10,0x10,0x24,0x23,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x23,0x00, + 0x00,0x6C,0xD2,0x52,0x4C,0x40,0xF8,0x40,0x40,0x40,0x40,0xC0,0x70,0x48,0x84,0x00, + /* 0xA4DE [?] [344]*/ + 0x00,0x01,0x21,0x1F,0x01,0x01,0x11,0x0F,0x01,0x01,0x01,0x1D,0x23,0x21,0x1E,0x00, + 0x00,0x00,0x00,0xF0,0x20,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x00, + /* 0xA4DF [?] [345]*/ + 0x00,0x00,0x13,0x0C,0x00,0x00,0x01,0x01,0x01,0x1A,0x27,0x44,0x48,0x30,0x00,0x01, + 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x10,0x10,0x20,0xA0,0x70,0x48,0x44,0x80,0x00, + /* 0xA4E0 [?] [346]*/ + 0x00,0x08,0x04,0x04,0x07,0x7C,0x04,0x1C,0x26,0x26,0x16,0x0C,0x08,0x08,0x07,0x00, + 0x00,0x00,0x00,0x80,0xC0,0x08,0x04,0x02,0x06,0x08,0x00,0x10,0x10,0x18,0xF0,0x00, + /* 0xA4E1 [?] [347]*/ + 0x00,0x01,0x20,0x10,0x10,0x1F,0x11,0x29,0x45,0x42,0x45,0x48,0x30,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x80,0xC0,0x20,0x10,0x08,0x08,0x08,0x10,0x10,0x20,0xC0,0x00, + /* 0xA4E2 [?] [348]*/ + 0x02,0x02,0x02,0x02,0x23,0x1E,0x04,0x04,0x44,0x3F,0x04,0x04,0x04,0x04,0x03,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x00,0x10,0x08,0xC8,0x08,0x08,0x08,0x08,0x08,0xF0,0x00, + /* 0xA4E3 [?] [349]*/ + 0x00,0x00,0x00,0x03,0x00,0x00,0x09,0x24,0x1F,0x02,0x02,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x70,0x88,0x08,0x10,0x60,0x00,0x80,0x80,0x40, + /* 0xA4E4 [?] [350]*/ + 0x00,0x02,0x01,0x00,0x00,0x09,0x10,0x11,0x7E,0x08,0x08,0x04,0x02,0x02,0x01,0x00, + 0x00,0x00,0x80,0x40,0x40,0x80,0x30,0xC8,0x04,0x04,0x88,0x70,0x00,0x00,0x00,0x80, + /* 0xA4E5 [?] [351]*/ + 0x00,0x00,0x00,0x01,0x00,0x10,0x11,0x12,0x24,0x24,0x28,0x2A,0x31,0x10,0x01,0x02, + 0x00,0x00,0x00,0x00,0x80,0x80,0xE0,0x90,0x88,0x88,0x88,0x88,0x90,0xE0,0x00,0x00, + /* 0xA4E6 [?] [352]*/ + 0x00,0x00,0x10,0x10,0x11,0x12,0x22,0x24,0x24,0x24,0x28,0x2A,0x31,0x10,0x00,0x03, + 0x00,0x80,0x40,0x40,0xF0,0x48,0x44,0x44,0x42,0x42,0x42,0x44,0x58,0xE0,0x80,0x00, + /* 0xA4E7 [?] [353]*/ + 0x00,0x00,0x00,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x11,0x11,0x0E,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0xF0,0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x04,0x00, + /* 0xA4E8 [?] [354]*/ + 0x00,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x1F,0x21,0x41,0x42,0x3C,0x00, + 0x00,0x00,0x00,0x00,0x10,0x38,0xC0,0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x04,0x00, + /* 0xA4E9 [?] [355]*/ + 0x00,0x18,0x04,0x02,0x02,0x04,0x08,0x10,0x10,0x13,0x14,0x18,0x00,0x00,0x00,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x08,0x08,0x08,0x30,0xC0,0x00, + /* 0xA4EA [?] [356]*/ + 0x00,0x10,0x08,0x09,0x0A,0x0A,0x0A,0x0C,0x0C,0x08,0x08,0x00,0x00,0x00,0x01,0x02, + 0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, + /* 0xA4EB [?] [357]*/ + 0x00,0x00,0x07,0x04,0x00,0x00,0x01,0x02,0x07,0x08,0x00,0x01,0x02,0x02,0x01,0x00, + 0x00,0x40,0xA0,0x20,0x40,0x80,0x00,0xF0,0x08,0x04,0x04,0x84,0x44,0x48,0xF0,0x00, + /* 0xA4EC [?] [358]*/ + 0x00,0x08,0x08,0x08,0x0E,0x79,0x0A,0x0C,0x08,0x18,0x28,0x28,0x68,0x18,0x08,0x00, + 0x00,0x00,0x00,0xC0,0xA0,0x20,0x20,0x20,0x40,0x40,0x40,0x42,0x42,0x24,0x18,0x00, + /* 0xA4ED [?] [359]*/ + 0x00,0x03,0x1C,0x00,0x01,0x02,0x04,0x0F,0x18,0x20,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0xC0,0x40,0x80,0x00,0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0x10,0x60,0x80,0x00, + /* 0xA4EE [?] [360]*/ + 0x00,0x00,0x08,0x04,0x04,0x07,0x3C,0x07,0x0C,0x14,0x24,0x34,0x0C,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x08,0x08,0x08,0x10,0x20,0xC0,0x00,0x00, + /* 0xA4EF [?] [361]*/ + 0x00,0x10,0x08,0x08,0x0F,0x78,0x0B,0x0C,0x08,0x18,0x28,0x48,0x68,0x18,0x08,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x18,0x04,0x04,0x04,0x04,0x08,0x10,0x60,0x00, + /* 0xA4F0 [?] [362]*/ + 0x00,0x00,0x07,0x18,0x00,0x00,0x07,0x08,0x10,0x21,0x41,0x42,0x24,0x18,0x00,0x00, + 0x00,0x00,0x80,0x80,0x80,0x80,0xE0,0x90,0x88,0x04,0x04,0x64,0x94,0x88,0x70,0x00, + /* 0xA4F1 [?] [363]*/ + 0x00,0x0F,0x00,0x01,0x07,0x08,0x10,0x03,0x04,0x03,0x02,0x04,0x18,0x26,0x21,0x00, + 0x00,0x80,0x80,0x00,0xE0,0x10,0x10,0x90,0xA0,0xC0,0x00,0x00,0x38,0x44,0x88,0x00, + /* 0xA4F2 [?] [364]*/ + 0x00,0x02,0x01,0x11,0x0F,0x01,0x01,0x02,0x04,0x04,0x08,0x01,0x02,0x02,0x01,0x00, + 0x00,0x00,0x10,0xE0,0x00,0x08,0x88,0x50,0x50,0x60,0xC0,0x40,0x40,0x00,0xF8,0x00, + /* 0xA4F3 [?] [365]*/ + 0x00,0x03,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x06,0x04,0x04,0x08,0x08,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x48,0x70,0x00,0x00, + /* 0xA4F4 [?] [366]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4F5 [?] [367]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4F6 [?] [368]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4F7 [?] [369]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4F8 [?] [370]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4F9 [?] [371]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4FA [?] [372]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4FB [?] [373]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4FC [?] [374]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4FD [?] [375]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA4FE [?] [376]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A1 [?] [377]*/ + 0x00,0x00,0x00,0x00,0x1F,0x00,0x02,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x08,0x00, + 0x00,0x00,0x00,0x00,0xF0,0x10,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A2 [?] [378]*/ + 0x00,0x00,0x3F,0x00,0x00,0x00,0x02,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x08,0x00, + 0x00,0x00,0xF8,0x08,0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A3 [?] [379]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x09,0x11,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A4 [?] [380]*/ + 0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x09,0x11,0x21,0x01,0x01,0x01,0x01,0x01, + 0x00,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A5 [?] [381]*/ + 0x00,0x00,0x01,0x01,0x11,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x03,0x0C,0x00, + 0x00,0x00,0x00,0x00,0x10,0xF8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00, + /* 0xA5A6 [?] [382]*/ + 0x00,0x01,0x01,0x21,0x3F,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x00, + 0x00,0x00,0x00,0x08,0xFC,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xA5A7 [?] [383]*/ + 0x00,0x00,0x00,0x00,0x1F,0x01,0x01,0x01,0x01,0x01,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x20,0xF0,0x00,0x00,0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, + /* 0xA5A8 [?] [384]*/ + 0x00,0x00,0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x7F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00, + /* 0xA5A9 [?] [385]*/ + 0x00,0x00,0x01,0x01,0x01,0x3F,0x03,0x05,0x09,0x11,0x21,0x01,0x05,0x02,0x00,0x00, + 0x00,0x00,0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5AA [?] [386]*/ + 0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x42,0x01,0x00, + 0x00,0x80,0x80,0x80,0x88,0xFC,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00, + /* 0xA5AB [?] [387]*/ + 0x00,0x02,0x02,0x02,0x02,0x3F,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x21,0x40,0x00, + 0x00,0x00,0x00,0x00,0x20,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x00, + /* 0xA5AC [?] [388]*/ + 0x00,0x02,0x02,0x02,0x02,0x3F,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x21,0x40,0x00, + 0x08,0x04,0x12,0x08,0x24,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x00, + /* 0xA5AD [?] [389]*/ + 0x00,0x10,0x10,0x08,0x04,0x3F,0x02,0x02,0x01,0x3F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x70,0x80,0x80,0x40,0x40,0x20,0x10,0x00, + /* 0xA5AE [?] [390]*/ + 0x00,0x10,0x10,0x08,0x04,0x3F,0x02,0x02,0x01,0x3F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x04,0x12,0x08,0xE4,0x00,0x00,0x00,0x70,0x80,0x80,0x40,0x40,0x20,0x10,0x00, + /* 0xA5AF [?] [391]*/ + 0x00,0x02,0x02,0x02,0x03,0x04,0x04,0x08,0x10,0x20,0x00,0x01,0x02,0x0C,0x30,0x00, + 0x00,0x00,0x00,0x10,0xF8,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B0 [?] [392]*/ + 0x00,0x04,0x04,0x04,0x07,0x08,0x08,0x10,0x20,0x40,0x01,0x02,0x04,0x18,0x60,0x00, + 0x08,0x04,0x12,0x08,0xE4,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B1 [?] [393]*/ + 0x00,0x08,0x08,0x08,0x0F,0x10,0x20,0x40,0x00,0x01,0x01,0x02,0x04,0x08,0x30,0x00, + 0x00,0x00,0x00,0x10,0xF8,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B2 [?] [394]*/ + 0x00,0x08,0x08,0x08,0x0F,0x10,0x20,0x40,0x00,0x01,0x01,0x02,0x04,0x08,0x30,0x00, + 0x08,0x04,0x12,0x08,0xF4,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B3 [?] [395]*/ + 0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0xF8,0x10,0x10,0x10,0x20,0x20,0xF0,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B4 [?] [396]*/ + 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x08,0x04,0x12,0x08,0x24,0xF0,0x20,0x20,0x20,0x40,0xE0,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B5 [?] [397]*/ + 0x00,0x00,0x04,0x04,0x04,0x04,0x7F,0x04,0x04,0x04,0x04,0x04,0x00,0x01,0x02,0x00, + 0x00,0x40,0x40,0x40,0x40,0x48,0xFC,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00, + /* 0xA5B6 [?] [398]*/ + 0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x7F,0x04,0x04,0x04,0x04,0x04,0x00,0x01,0x02, + 0x08,0x04,0x52,0x48,0x44,0x40,0x48,0xFC,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00, + /* 0xA5B7 [?] [399]*/ + 0x00,0x00,0x18,0x04,0x02,0x30,0x08,0x04,0x00,0x00,0x01,0x02,0x24,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B8 [?] [400]*/ + 0x00,0x00,0x00,0x18,0x04,0x02,0x30,0x08,0x04,0x00,0x00,0x01,0x02,0x24,0x18,0x00, + 0x08,0x04,0x12,0x08,0x04,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA5B9 [?] [401]*/ + 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x08,0x00,0x00, + /* 0xA5BA [?] [402]*/ + 0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00, + 0x08,0x04,0x12,0x08,0xE4,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x08,0x00, + /* 0xA5BB [?] [403]*/ + 0x00,0x04,0x04,0x04,0x04,0x07,0x7C,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0xF0,0x00,0x00, + /* 0xA5BC [?] [404]*/ + 0x00,0x04,0x04,0x04,0x04,0x07,0x7C,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00, + 0x08,0x04,0x12,0x08,0x04,0xE0,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0xF0,0x00,0x00, + /* 0xA5BD [?] [405]*/ + 0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x06,0x02,0x00,0x00,0x01,0x02,0x0C,0x30,0x00, + 0x00,0x00,0x20,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA5BE [?] [406]*/ + 0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x08,0x0C,0x04,0x00,0x01,0x02,0x04,0x18,0x60, + 0x08,0x04,0x12,0x48,0x24,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA5BF [?] [407]*/ + 0x00,0x04,0x04,0x07,0x04,0x08,0x08,0x10,0x24,0x02,0x01,0x02,0x04,0x18,0x60,0x00, + 0x00,0x00,0x20,0xF0,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x80,0x40,0x00,0x00,0x00, + /* 0xA5C0 [?] [408]*/ + 0x00,0x08,0x08,0x0F,0x08,0x10,0x10,0x20,0x49,0x05,0x02,0x05,0x08,0x30,0xC0,0x00, + 0x08,0x04,0x52,0xE8,0x44,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C1 [?] [409]*/ + 0x00,0x00,0x01,0x1F,0x01,0x01,0x7F,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x00, + 0x00,0x20,0xF0,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C2 [?] [410]*/ + 0x00,0x00,0x00,0x03,0x3E,0x02,0x02,0xFF,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20, + 0x08,0x04,0x52,0xE8,0x04,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C3 [?] [411]*/ + 0x00,0x00,0x00,0x00,0x04,0x03,0x21,0x18,0x08,0x00,0x00,0x00,0x01,0x06,0x18,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA5C4 [?] [412]*/ + 0x00,0x00,0x04,0x02,0x21,0x11,0x08,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x30,0x00, + 0x00,0x00,0x00,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C5 [?] [413]*/ + 0x00,0x00,0x08,0x04,0x42,0x22,0x10,0x10,0x00,0x01,0x02,0x04,0x08,0x10,0x60,0x00, + 0x08,0x04,0x12,0x28,0x24,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C6 [?] [414]*/ + 0x00,0x00,0x1F,0x00,0x00,0x00,0x7F,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20, + 0x00,0x20,0xF0,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C7 [?] [415]*/ + 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0xFF,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20, + 0x08,0x04,0x52,0xE8,0x04,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C8 [?] [416]*/ + 0x00,0x04,0x04,0x04,0x04,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5C9 [?] [417]*/ + 0x00,0x04,0x04,0x04,0x04,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00, + 0x08,0x04,0x12,0x08,0x04,0x00,0x00,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5CA [?] [418]*/ + 0x00,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x00, + 0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5CB [?] [419]*/ + 0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0xF0,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00, + /* 0xA5CC [?] [420]*/ + 0x00,0x00,0x1F,0x00,0x00,0x0C,0x02,0x01,0x00,0x00,0x01,0x02,0x04,0x08,0x30,0x00, + 0x00,0x10,0xF8,0x10,0x20,0x20,0x40,0x40,0x80,0xC0,0x30,0x10,0x00,0x00,0x00,0x00, + /* 0xA5CD [?] [421]*/ + 0x02,0x01,0x00,0x00,0x1F,0x00,0x01,0x03,0x05,0x09,0x11,0x21,0x01,0x01,0x01,0x00, + 0x00,0x80,0x80,0x00,0xC0,0x80,0x00,0x00,0x40,0x30,0x10,0x00,0x00,0x00,0x00,0x00, + /* 0xA5CE [?] [422]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x08,0x10,0x00, + 0x00,0x00,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5CF [?] [423]*/ + 0x00,0x00,0x00,0x00,0x04,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x00,0x00,0x00,0x00, + /* 0xA5D0 [?] [424]*/ + 0x00,0x00,0x00,0x00,0x04,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + 0x08,0x04,0x12,0x08,0x44,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x00,0x00,0x00,0x00, + /* 0xA5D1 [?] [425]*/ + 0x00,0x00,0x00,0x00,0x04,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + 0x00,0x0C,0x12,0x12,0x4C,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x00,0x00,0x00,0x00, + /* 0xA5D2 [?] [426]*/ + 0x00,0x00,0x08,0x08,0x08,0x08,0x09,0x0E,0x08,0x08,0x08,0x08,0x07,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x60,0x80,0x00,0x00,0x00,0x00,0x20,0xF0,0x00,0x00,0x00, + /* 0xA5D3 [?] [427]*/ + 0x00,0x00,0x00,0x20,0x20,0x21,0x21,0x26,0x38,0x20,0x20,0x20,0x20,0x1F,0x00,0x00, + 0x08,0x04,0x12,0x08,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x00,0x00, + /* 0xA5D4 [?] [428]*/ + 0x00,0x00,0x00,0x20,0x20,0x21,0x21,0x26,0x38,0x20,0x20,0x20,0x20,0x1F,0x00,0x00, + 0x00,0x0C,0x12,0x12,0x0C,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x00,0x00, + /* 0xA5D5 [?] [429]*/ + 0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00, + 0x00,0x00,0x20,0xF0,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5D6 [?] [430]*/ + 0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x00, + 0x08,0x04,0x12,0x48,0xE4,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5D7 [?] [431]*/ + 0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x00, + 0x00,0x0C,0x12,0x52,0xEC,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5D8 [?] [432]*/ + 0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0E,0x00,0x00,0x00,0x00,0x00, + /* 0xA5D9 [?] [433]*/ + 0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x04,0x12,0x08,0x04,0x00,0x00,0x00,0xC0,0x30,0x0E,0x00,0x00,0x00,0x00,0x00, + /* 0xA5DA [?] [434]*/ + 0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0xC0,0x30,0x0E,0x00,0x00,0x00,0x00,0x00, + /* 0xA5DB [?] [435]*/ + 0x00,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x09,0x09,0x11,0x21,0x01,0x05,0x02,0x00, + 0x00,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x20,0x10,0x08,0x08,0x00,0x00,0x00,0x00, + /* 0xA5DC [?] [436]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x11,0x11,0x21,0x41,0x05,0x02,0x00, + 0x08,0x04,0x12,0x08,0x04,0x00,0xFC,0x00,0x00,0x20,0x10,0x08,0x08,0x00,0x00,0x00, + /* 0xA5DD [?] [437]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x11,0x11,0x21,0x41,0x05,0x02,0x00, + 0x0C,0x12,0x12,0x0C,0x00,0x08,0xFC,0x00,0x00,0x20,0x10,0x08,0x08,0x00,0x00,0x00, + /* 0xA5DE [?] [438]*/ + 0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0xF8,0x10,0x20,0x20,0x40,0x80,0x80,0x40,0x40,0x00,0x00,0x00, + /* 0xA5DF [?] [439]*/ + 0x00,0x00,0x0E,0x01,0x00,0x00,0x1C,0x03,0x00,0x00,0x1C,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x60,0x20,0x00,0x80,0x80,0x00,0x00,0x00,0xE0,0x20,0x00,0x00, + /* 0xA5E0 [?] [440]*/ + 0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x3F,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0xF8,0x08,0x08,0x00, + /* 0xA5E1 [?] [441]*/ + 0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x01,0x00,0x01,0x02,0x04,0x08,0x10,0x60,0x00, + 0x00,0x00,0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x60,0x20,0x00,0x00,0x00,0x00,0x00, + /* 0xA5E2 [?] [442]*/ + 0x00,0x00,0x03,0x3E,0x02,0x02,0x03,0x7E,0x02,0x02,0x02,0x02,0x02,0x01,0x00,0x00, + 0x00,0x40,0xE0,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x10,0xF8,0x00,0x00, + /* 0xA5E3 [?] [443]*/ + 0x00,0x00,0x00,0x00,0x10,0x08,0x08,0x24,0x1F,0x02,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x10,0x20,0x00,0x80,0x80,0x40,0x00, + /* 0xA5E4 [?] [444]*/ + 0x00,0x10,0x10,0x08,0x08,0x44,0x3F,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x10,0x20,0x00,0x00,0x80,0x80,0x40,0x20,0x00, + /* 0xA5E5 [?] [445]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0xF0,0x20,0x20,0x20,0x40,0x48,0xFC,0x00,0x00,0x00, + /* 0xA5E6 [?] [446]*/ + 0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0xF8,0x10,0x10,0x10,0x20,0x20,0x24,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xA5E7 [?] [447]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x1F,0x00,0x00,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0xF8,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x00,0x00, + /* 0xA5E8 [?] [448]*/ + 0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x10,0xF8,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0xF0,0x10,0x00,0x00,0x00,0x00, + /* 0xA5E9 [?] [449]*/ + 0x00,0x00,0x0F,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x18,0x00, + 0x00,0x40,0xE0,0x00,0x10,0xF8,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA5EA [?] [450]*/ + 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x01,0x01,0x02,0x0C, + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00, + /* 0xA5EB [?] [451]*/ + 0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x84,0x88,0x90,0xA0,0xC0,0x80,0x00,0x00, + /* 0xA5EC [?] [452]*/ + 0x00,0x00,0x00,0x20,0x10,0x10,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x10,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5ED [?] [453]*/ + 0x00,0x00,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x20,0xF0,0x20,0x20,0x20,0x20,0x40,0x40,0xE0,0x00,0x00,0x00,0x00,0x00, + /* 0xA5EE [?] [454]*/ + 0x00,0x00,0x10,0x1F,0x10,0x10,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x00,0x00,0x00, + 0x00,0x00,0x20,0xF0,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5EF [?] [455]*/ + 0x00,0x00,0x20,0x3F,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x00, + 0x00,0x00,0x10,0xF8,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA5F0 [?] [456]*/ + 0x00,0x01,0x01,0x01,0x1F,0x09,0x09,0x09,0x09,0x7F,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x40,0xE0,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F1 [?] [457]*/ + 0x00,0x00,0x00,0x1F,0x00,0x02,0x01,0x01,0x01,0x01,0x7F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x40,0x80,0x00,0x00,0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F2 [?] [458]*/ + 0x00,0x00,0x00,0x1F,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x00, + 0x00,0x00,0x10,0xF8,0x10,0x10,0xFC,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00, + /* 0xA5F3 [?] [459]*/ + 0x00,0x00,0x10,0x08,0x06,0x02,0x00,0x00,0x00,0x01,0x02,0x24,0x18,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F4 [?] [460]*/ + 0x00,0x02,0x02,0x22,0x3F,0x20,0x20,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x08,0x00, + 0x08,0x04,0x12,0x48,0xE4,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F5 [?] [461]*/ + 0x00,0x00,0x01,0x01,0x01,0x0F,0x01,0x02,0x02,0x02,0x04,0x05,0x08,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0xF0,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00, + /* 0xA5F6 [?] [462]*/ + 0x00,0x00,0x04,0x04,0x04,0x07,0x08,0x10,0x01,0x01,0x02,0x04,0x08,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F7 [?] [463]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F8 [?] [464]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5F9 [?] [465]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5FA [?] [466]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5FB [?] [467]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5FC [?] [468]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5FD [?] [469]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA5FE [?] [470]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6A1 [?] [471]*/ + 0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x0F,0x10,0x10,0x20,0x70,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0xE0,0x10,0x10,0x08,0x1C,0x00,0x00,0x00,0x00, + /* 0xA6A2 [?] [472]*/ + 0x00,0x1F,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x10,0x10,0x10,0x20,0xC0,0x20,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,0x00, + /* 0xA6A3 [G] [473]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6A4 [?] [474]*/ + 0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x7F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0xFC,0x00,0x00,0x00,0x00, + /* 0xA6A5 [?] [475]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x80,0x80,0x80,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA6A6 [?] [476]*/ + 0x00,0x1F,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x04,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, + /* 0xA6A7 [?] [477]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA6A8 [T] [478]*/ + 0x00,0x03,0x0C,0x10,0x10,0x24,0x27,0x24,0x10,0x10,0x0C,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x60,0x10,0x10,0x48,0xC8,0x48,0x10,0x10,0x60,0x80,0x00,0x00,0x00,0x00, + /* 0xA6A9 [?] [479]*/ + 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA6AA [?] [480]*/ + 0x00,0x1C,0x08,0x08,0x09,0x0A,0x0E,0x09,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x70,0x40,0x80,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x38,0x00,0x00,0x00,0x00, + /* 0xA6AB [?] [481]*/ + 0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x70,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x1C,0x00,0x00,0x00,0x00, + /* 0xA6AC [?] [482]*/ + 0x00,0x30,0x18,0x14,0x14,0x12,0x12,0x11,0x11,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x18,0x30,0x50,0x50,0x90,0x90,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + /* 0xA6AD [?] [483]*/ + 0x00,0x30,0x18,0x14,0x14,0x12,0x11,0x11,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x60,0x20,0x00,0x00,0x00,0x00, + /* 0xA6AE [?] [484]*/ + 0x00,0x3F,0x20,0x20,0x00,0x08,0x0F,0x08,0x00,0x20,0x20,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x40,0xC0,0x40,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA6AF [?] [485]*/ + 0x00,0x03,0x0C,0x10,0x10,0x20,0x20,0x20,0x10,0x10,0x0C,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x60,0x10,0x10,0x08,0x08,0x08,0x10,0x10,0x60,0x80,0x00,0x00,0x00,0x00, + /* 0xA6B0 [?] [486]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA6B1 [?] [487]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6B2 [S] [488]*/ + 0x00,0x3F,0x10,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA6B3 [?] [489]*/ + 0x00,0x3F,0x21,0x21,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA6B4 [?] [490]*/ + 0x00,0x00,0x06,0x09,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x40,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA6B5 [F] [491]*/ + 0x00,0x03,0x01,0x0F,0x11,0x21,0x21,0x21,0x11,0x0F,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA6B6 [?] [492]*/ + 0x00,0x38,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x08,0x38,0x00,0x00,0x00,0x00, + 0x00,0x38,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x40,0x20,0x38,0x00,0x00,0x00,0x00, + /* 0xA6B7 [?] [493]*/ + 0x00,0x43,0x21,0x11,0x11,0x11,0x11,0x0F,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x84,0x08,0x10,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA6B8 [O] [494]*/ + 0x00,0x07,0x08,0x10,0x20,0x20,0x20,0x20,0x10,0x08,0x24,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x10,0x10,0x10,0x10,0x20,0x40,0x90,0xF0,0x00,0x00,0x00,0x00, + /* 0xA6B9 [?] [495]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BA [?] [496]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BB [?] [497]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BC [?] [498]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BD [?] [499]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BE [?] [500]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6BF [?] [501]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6C0 [?] [502]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6C1 [a] [503]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0xC0,0x40,0x40,0x40,0x40,0x40,0xC0,0x30,0x00,0x00,0x00,0x00, + /* 0xA6C2 [ß] [504]*/ + 0x00,0x07,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x0C,0x0B,0x08,0x08,0x08,0x00, + 0x00,0x80,0x40,0x40,0x80,0x00,0xC0,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6C3 [?] [505]*/ + 0x00,0x00,0x00,0x0C,0x12,0x22,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6C4 [d] [506]*/ + 0x00,0x03,0x04,0x02,0x01,0x02,0x04,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6C5 [e] [507]*/ + 0x00,0x00,0x00,0x03,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x00,0x00,0x80,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6C6 [?] [508]*/ + 0x00,0x02,0x04,0x04,0x03,0x02,0x04,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x03,0x00, + 0x00,0x00,0x00,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0xC0,0x00, + /* 0xA6C7 [?] [509]*/ + 0x00,0x00,0x00,0x0D,0x16,0x14,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + /* 0xA6C8 [?] [510]*/ + 0x00,0x03,0x04,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6C9 [?] [511]*/ + 0x00,0x00,0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6CA [?] [512]*/ + 0x00,0x00,0x00,0x18,0x08,0x08,0x0D,0x0A,0x09,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x40,0x80,0x00,0x00,0x00,0x80,0x40,0x70,0x00,0x00,0x00,0x00, + /* 0xA6CB [?] [513]*/ + 0x00,0x04,0x0A,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x50,0x20,0x00,0x00,0x00,0x00, + /* 0xA6CC [µ] [514]*/ + 0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0C,0x0B,0x08,0x08,0x08,0x00, + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xD0,0x20,0x00,0x00,0x00,0x00, + /* 0xA6CD [?] [515]*/ + 0x00,0x00,0x00,0x18,0x08,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x20,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA6CE [?] [516]*/ + 0x00,0x04,0x08,0x07,0x08,0x08,0x07,0x04,0x08,0x08,0x08,0x07,0x00,0x04,0x03,0x00, + 0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0xC0,0x00, + /* 0xA6CF [?] [517]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6D0 [p] [518]*/ + 0x00,0x00,0x00,0x1F,0x24,0x04,0x04,0x04,0x04,0x04,0x08,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x40,0x40,0x40,0x40,0x40,0x40,0x50,0x20,0x00,0x00,0x00,0x00, + /* 0xA6D1 [?] [519]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x18,0x14,0x13,0x10,0x10,0x10,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6D2 [s] [520]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6D3 [t] [521]*/ + 0x00,0x00,0x00,0x07,0x09,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA6D4 [?] [522]*/ + 0x00,0x00,0x00,0x08,0x14,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA6D5 [f] [523]*/ + 0x00,0x01,0x01,0x07,0x09,0x11,0x11,0x11,0x11,0x11,0x09,0x07,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA6D6 [?] [524]*/ + 0x00,0x00,0x00,0x08,0x14,0x04,0x02,0x02,0x01,0x01,0x02,0x04,0x08,0x08,0x10,0x00, + 0x00,0x00,0x00,0x10,0x20,0x20,0x40,0x80,0x00,0x00,0x80,0x80,0x40,0x50,0x20,0x00, + /* 0xA6D7 [?] [525]*/ + 0x00,0x01,0x01,0x11,0x29,0x09,0x09,0x09,0x09,0x09,0x09,0x07,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA6D8 [?] [526]*/ + 0x00,0x00,0x00,0x04,0x08,0x10,0x11,0x11,0x11,0x11,0x0A,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0xA0,0x40,0x00,0x00,0x00,0x00, + /* 0xA6D9 [?] [527]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6DA [?] [528]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6DB [?] [529]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x40,0x20,0x30,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6DC [?] [530]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00, + /* 0xA6DD [?] [531]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6DE [?] [532]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, + /* 0xA6DF [?] [533]*/ + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x70,0x88,0x0C,0x8C,0x8C,0x18,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00, + /* 0xA6E0 [?] [534]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x04,0x00,0x00,0x00, + /* 0xA6E1 [?] [535]*/ + 0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x08,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6E2 [?] [536]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x04,0x00,0x00,0x00, + /* 0xA6E3 [?] [537]*/ + 0x00,0x00,0x00,0x40,0x20,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x08,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6E4 [?] [538]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x18,0x60,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00, + /* 0xA6E5 [?] [539]*/ + 0x00,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6E6 [?] [540]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x18,0x61,0x06,0x18,0x60,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0xC0,0x30,0x0C,0x00,0x00, + /* 0xA6E7 [?] [541]*/ + 0x00,0x00,0x60,0x18,0x06,0x61,0x18,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0C,0x30,0xC0,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6E8 [?] [542]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x00,0x00, + /* 0xA6E9 [?] [543]*/ + 0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6EA [?] [544]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x40,0x7F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0xF4,0x14,0x1C,0x00,0x00, + /* 0xA6EB [?] [545]*/ + 0x00,0x00,0x70,0x50,0x5F,0x40,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xFC,0x04,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6EC [?] [546]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x40,0x47,0x58,0x60,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x04,0xC4,0x34,0x0C,0x04,0x00,0x00, + /* 0xA6ED [?] [547]*/ + 0x00,0x00,0x40,0x60,0x58,0x47,0x40,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x04,0x0C,0x34,0xC4,0x04,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6EE [?] [548]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x78,0x60,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0x3C,0x0C,0x04,0x00,0x00, + /* 0xA6EF [?] [549]*/ + 0x00,0x00,0x40,0x60,0x78,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x04,0x0C,0x3C,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F0 [?] [550]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x3C,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x78,0x04,0x00,0x00,0x00, + /* 0xA6F1 [?] [551]*/ + 0x00,0x00,0x00,0x40,0x3C,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x78,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F2 [?] [552]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F3 [?] [553]*/ + 0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F4 [?] [554]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F5 [?] [555]*/ + 0x01,0x02,0x02,0x01,0x01,0x02,0x02,0x01,0x01,0x02,0x02,0x01,0x01,0x02,0x02,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F6 [?] [556]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F7 [?] [557]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F8 [?] [558]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6F9 [?] [559]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6FA [?] [560]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6FB [?] [561]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6FC [?] [562]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6FD [?] [563]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA6FE [?] [564]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7A1 [?] [565]*/ + 0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x0F,0x10,0x10,0x20,0x70,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0xE0,0x10,0x10,0x08,0x1C,0x00,0x00,0x00,0x00, + /* 0xA7A2 [?] [566]*/ + 0x00,0x1F,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,0x00, + /* 0xA7A3 [?] [567]*/ + 0x00,0x1F,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x10,0x10,0x10,0x20,0xC0,0x20,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,0x00, + /* 0xA7A4 [?] [568]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7A5 [?] [569]*/ + 0x00,0x0F,0x02,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x1F,0x20,0x20,0x00,0x00, + 0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xF0,0x08,0x08,0x00,0x00, + /* 0xA7A6 [?] [570]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x00,0x80,0x80,0x80,0x00,0x10,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA7A7 [?] [571]*/ + 0x04,0x00,0x3F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x40,0x00,0xF0,0x10,0x00,0x40,0xC0,0x40,0x00,0x00,0x10,0xF0,0x00,0x00,0x00,0x00, + /* 0xA7A8 [?] [572]*/ + 0x00,0x23,0x51,0x09,0x09,0x05,0x03,0x05,0x09,0x11,0x11,0x63,0x00,0x00,0x00,0x00, + 0x00,0x88,0x14,0x20,0x20,0x40,0x80,0x40,0x20,0x10,0x10,0x8C,0x00,0x00,0x00,0x00, + /* 0xA7A9 [?] [573]*/ + 0x00,0x0B,0x0C,0x08,0x00,0x00,0x01,0x00,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7AA [?] [574]*/ + 0x00,0x38,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x14,0x18,0x30,0x00,0x00,0x00,0x00, + 0x00,0x30,0x60,0xA0,0xA0,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7AB [?] [575]*/ + 0x04,0x04,0x73,0x20,0x20,0x20,0x21,0x22,0x24,0x28,0x30,0x60,0x00,0x00,0x00,0x00, + 0x40,0x40,0x98,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + /* 0xA7AC [?] [576]*/ + 0x00,0x38,0x10,0x11,0x11,0x12,0x1E,0x11,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x60,0x90,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x30,0x00,0x00,0x00,0x00, + /* 0xA7AD [?] [577]*/ + 0x00,0x1F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7AE [?] [578]*/ + 0x00,0x30,0x18,0x14,0x14,0x12,0x12,0x11,0x11,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x18,0x30,0x50,0x50,0x90,0x90,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + /* 0xA7AF [?] [579]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7B0 [?] [580]*/ + 0x00,0x07,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7B1 [?] [581]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7B2 [?] [582]*/ + 0x00,0x3F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7B3 [?] [583]*/ + 0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0xD0,0x30,0x10,0x00,0x00,0x00,0x00,0x08,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7B4 [?] [584]*/ + 0x00,0x3F,0x21,0x21,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA7B5 [?] [585]*/ + 0x00,0x1C,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x02,0x24,0x18,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7B6 [?] [586]*/ + 0x00,0x03,0x01,0x0F,0x11,0x21,0x21,0x21,0x11,0x0F,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA7B7 [?] [587]*/ + 0x00,0x38,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x08,0x38,0x00,0x00,0x00,0x00, + 0x00,0x38,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x40,0x20,0x38,0x00,0x00,0x00,0x00, + /* 0xA7B8 [?] [588]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xF0,0x08,0x08,0x00,0x00, + /* 0xA7B9 [?] [589]*/ + 0x00,0x38,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x60,0xA0,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7BA [?] [590]*/ + 0x00,0x3B,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xB8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, + /* 0xA7BB [?] [591]*/ + 0x00,0x3B,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xB8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0x04,0x04,0x00,0x00, + /* 0xA7BC [?] [592]*/ + 0x00,0x3E,0x24,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x00, + /* 0xA7BD [?] [593]*/ + 0x00,0x70,0x20,0x20,0x20,0x3C,0x22,0x21,0x21,0x21,0x22,0x7C,0x00,0x00,0x00,0x00, + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7BE [?] [594]*/ + 0x00,0x1C,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7BF [?] [595]*/ + 0x00,0x2F,0x30,0x20,0x00,0x00,0x07,0x00,0x00,0x20,0x10,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x80,0x40,0x20,0x10,0x10,0xF0,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7C0 [?] [596]*/ + 0x00,0x71,0x22,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x22,0x71,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7C1 [?] [597]*/ + 0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x01,0x02,0x04,0x08,0x30,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7C2 [?] [598]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C3 [?] [599]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C4 [?] [600]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C5 [?] [601]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C6 [?] [602]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C7 [?] [603]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C8 [?] [604]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7C9 [?] [605]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CA [?] [606]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CB [?] [607]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CC [?] [608]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CD [?] [609]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CE [?] [610]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7CF [?] [611]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7D0 [?] [612]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7D1 [?] [613]*/ + 0x00,0x00,0x00,0x07,0x08,0x00,0x0F,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0xC0,0x40,0x40,0xD0,0x20,0x00,0x00,0x00,0x00, + /* 0xA7D2 [?] [614]*/ + 0x00,0x07,0x08,0x10,0x17,0x18,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x20,0xC0,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7D3 [?] [615]*/ + 0x00,0x00,0x00,0x1F,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7D4 [?] [616]*/ + 0x00,0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7D5 [?] [617]*/ + 0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x1F,0x20,0x20,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xF0,0x08,0x08,0x00,0x00, + /* 0xA7D6 [?] [618]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x1F,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0xE0,0x00,0x00,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7D7 [?] [619]*/ + 0x00,0x04,0x00,0x07,0x08,0x10,0x10,0x1F,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x80,0x40,0x20,0x20,0xE0,0x00,0x00,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7D8 [?] [620]*/ + 0x00,0x00,0x00,0x33,0x09,0x09,0x05,0x07,0x09,0x09,0x11,0x23,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x98,0x20,0x20,0x40,0xC0,0x20,0x20,0x10,0x88,0x00,0x00,0x00,0x00, + /* 0xA7D9 [?] [621]*/ + 0x00,0x00,0x00,0x0B,0x0C,0x08,0x00,0x01,0x00,0x00,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7DA [?] [622]*/ + 0x00,0x00,0x00,0x38,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x30,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7DB [?] [623]*/ + 0x00,0x04,0x03,0x38,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x30,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x70,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7DC [?] [624]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x09,0x0E,0x0A,0x09,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0x80,0x80,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00, + /* 0xA7DD [?] [625]*/ + 0x00,0x00,0x00,0x0F,0x02,0x02,0x02,0x02,0x02,0x02,0x0A,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7DE [?] [626]*/ + 0x00,0x00,0x00,0x38,0x10,0x18,0x14,0x12,0x12,0x11,0x10,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x38,0x10,0x30,0x50,0x90,0x90,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + /* 0xA7DF [?] [627]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7E0 [?] [628]*/ + 0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7E1 [?] [629]*/ + 0x00,0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7E2 [?] [630]*/ + 0x00,0x00,0x00,0x0B,0x1C,0x08,0x08,0x08,0x08,0x0C,0x0B,0x08,0x08,0x08,0x1C,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + /* 0xA7E3 [?] [631]*/ + 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x40,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7E4 [?] [632]*/ + 0x00,0x00,0x00,0x1F,0x11,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, + /* 0xA7E5 [?] [633]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x02,0x24,0x18,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7E6 [?] [634]*/ + 0x00,0x01,0x01,0x01,0x0D,0x13,0x11,0x11,0x11,0x11,0x13,0x0D,0x01,0x01,0x03,0x00, + 0x00,0x00,0x00,0x00,0x60,0x90,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00,0x80,0x00, + /* 0xA7E7 [?] [635]*/ + 0x00,0x00,0x00,0x1C,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x1C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7E8 [?] [636]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xF0,0x08,0x08,0x00,0x00, + /* 0xA7E9 [?] [637]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xE0,0x40,0x40,0x40,0xC0,0x40,0x40,0x40,0xE0,0x00,0x00,0x00,0x00, + /* 0xA7EA [?] [638]*/ + 0x00,0x00,0x00,0x3B,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xB8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, + /* 0xA7EB [?] [639]*/ + 0x00,0x00,0x00,0x3B,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xB8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0x04,0x04,0x00,0x00, + /* 0xA7EC [?] [640]*/ + 0x00,0x00,0x00,0x7C,0x48,0x08,0x08,0x0F,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7ED [?] [641]*/ + 0x00,0x00,0x00,0x38,0x10,0x10,0x10,0x1E,0x11,0x11,0x11,0x3E,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7EE [?] [642]*/ + 0x00,0x00,0x00,0x1C,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x1F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x20,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7EF [?] [643]*/ + 0x00,0x00,0x00,0x07,0x08,0x00,0x00,0x03,0x00,0x00,0x08,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x40,0x20,0x20,0xE0,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xA7F0 [?] [644]*/ + 0x00,0x00,0x00,0x38,0x11,0x12,0x12,0x1E,0x12,0x12,0x11,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00, + /* 0xA7F1 [?] [645]*/ + 0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x01,0x02,0x0A,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + /* 0xA7F2 [?] [646]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F3 [?] [647]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F4 [?] [648]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F5 [?] [649]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F6 [?] [650]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F7 [?] [651]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F8 [?] [652]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7F9 [?] [653]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7FA [?] [654]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7FB [?] [655]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7FC [?] [656]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7FD [?] [657]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA7FE [?] [658]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A1 [a] [659]*/ + 0x00,0x00,0xFC,0x00,0x00,0x74,0x8C,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A2 [á] [660]*/ + 0x08,0x10,0x20,0x00,0x00,0x74,0x8C,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A3 [a] [661]*/ + 0x44,0x28,0x10,0x00,0x00,0x74,0x8C,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A4 [à] [662]*/ + 0x40,0x20,0x10,0x00,0x00,0x74,0x8C,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A5 [e] [663]*/ + 0x00,0x00,0xFC,0x00,0x00,0x38,0x44,0x82,0xFE,0x80,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A6 [é] [664]*/ + 0x08,0x10,0x20,0x00,0x00,0x38,0x44,0x82,0xFE,0x80,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A7 [e] [665]*/ + 0x44,0x28,0x10,0x00,0x00,0x38,0x44,0x82,0xFE,0x80,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A8 [è] [666]*/ + 0x40,0x20,0x10,0x00,0x00,0x38,0x44,0x82,0xFE,0x80,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8A9 [i] [667]*/ + 0x00,0x00,0x38,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AA [í] [668]*/ + 0x08,0x10,0x20,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AB [i] [669]*/ + 0x44,0x28,0x10,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AC [ì] [670]*/ + 0x20,0x10,0x08,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AD [o] [671]*/ + 0x00,0x00,0xFC,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AE [ó] [672]*/ + 0x08,0x10,0x20,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8AF [o] [673]*/ + 0x44,0x28,0x10,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B0 [ò] [674]*/ + 0x20,0x10,0x08,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B1 [u] [675]*/ + 0x00,0x00,0xFC,0x00,0x00,0x84,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B2 [ú] [676]*/ + 0x08,0x10,0x20,0x00,0x00,0x84,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B3 [u] [677]*/ + 0x44,0x28,0x10,0x00,0x00,0x84,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B4 [ù] [678]*/ + 0x20,0x10,0x08,0x00,0x00,0x84,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B5 [u] [679]*/ + 0x00,0x00,0xFC,0x00,0x48,0x00,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B6 [u] [680]*/ + 0x10,0x20,0x40,0x00,0x48,0x00,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B7 [u] [681]*/ + 0x88,0x50,0x20,0x00,0x48,0x00,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B8 [u] [682]*/ + 0x40,0x20,0x10,0x00,0x48,0x00,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8B9 [ü] [683]*/ + 0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BA [ê] [684]*/ + 0x10,0x28,0x44,0x00,0x00,0x38,0x44,0x82,0xFE,0x80,0x42,0x3C,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BB [?] [685]*/ + 0x00,0x00,0x00,0x00,0x00,0x74,0x8C,0x84,0x84,0x84,0x8C,0x76,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BC [?] [686]*/ + 0x08,0x10,0x20,0x00,0x00,0xAC,0xD2,0x92,0x92,0x92,0x92,0x92,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BD [n] [687]*/ + 0x08,0x10,0x20,0x00,0x00,0xB8,0xC4,0x84,0x84,0x84,0x84,0x84,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BE [n] [688]*/ + 0x44,0x28,0x10,0x00,0x00,0xB8,0xC4,0x84,0x84,0x84,0x84,0x84,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8BF [?] [689]*/ + 0x00,0x00,0x00,0x10,0x10,0x08,0x00,0x7C,0x42,0x42,0x42,0x42,0x42,0xE7,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C0 [g] [690]*/ + 0x00,0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x38,0x40,0x40,0x7C,0x82,0x82,0x7C,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C1 [?] [691]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C2 [?] [692]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C3 [?] [693]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C4 [?] [694]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8C5 [?] [695]*/ + 0x00,0x08,0x08,0x10,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0xA0,0x40, + /* 0xA8C6 [?] [696]*/ + 0x00,0x04,0x04,0x08,0x1F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x0C,0x30,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x10,0x10,0xA0,0x40,0xA0,0x10,0x10,0x00,0x00, + /* 0xA8C7 [?] [697]*/ + 0x00,0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00, + /* 0xA8C8 [?] [698]*/ + 0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x00,0x00, + 0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00, + /* 0xA8C9 [?] [699]*/ + 0x00,0x04,0x04,0x08,0x1F,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x08,0x11,0x20,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0xA0,0x40, + /* 0xA8CA [?] [700]*/ + 0x00,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x02,0x02,0x04,0x08,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x20,0xF0,0x08,0x00,0x00, + /* 0xA8CB [?] [701]*/ + 0x00,0x00,0x3F,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, + 0x00,0x00,0xC0,0x40,0x80,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0xA0,0x40, + /* 0xA8CC [?] [702]*/ + 0x00,0x01,0x09,0x09,0x11,0x11,0x3F,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x50,0x20, + /* 0xA8CD [?] [703]*/ + 0x00,0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x11,0x08,0x08,0x04,0x04,0x02,0x02,0x00, + 0x00,0x00,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x00, + /* 0xA8CE [?] [704]*/ + 0x00,0x00,0x7F,0x04,0x04,0x04,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x20,0xA0,0x40, + /* 0xA8CF [?] [705]*/ + 0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8D0 [?] [706]*/ + 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x09,0x0E,0x00,0x00,0x00,0x00,0x00, + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xA8D1 [?] [707]*/ + 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x00, + /* 0xA8D2 [?] [708]*/ + 0x00,0x00,0x7F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8D3 [?] [709]*/ + 0x00,0x01,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x1F,0x01,0x01,0x01,0x7F,0x00,0x00, + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0xFC,0x00,0x00, + /* 0xA8D4 [?] [710]*/ + 0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x11,0x03,0x05,0x09,0x11,0x01,0x01,0x01,0x01, + 0x00,0x40,0x80,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8D5 [?] [711]*/ + 0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8D6 [?] [712]*/ + 0x00,0x00,0x0F,0x08,0x08,0x08,0x0A,0x09,0x08,0x08,0x08,0x08,0x08,0x0F,0x00,0x00, + 0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0xA0,0x20,0x20,0x20,0x20,0xE0,0x00,0x00, + /* 0xA8D7 [?] [713]*/ + 0x00,0x00,0x3F,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x04,0x04,0x04,0x04,0x04,0x04, + 0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00, + /* 0xA8D8 [?] [714]*/ + 0x00,0x02,0x02,0x02,0x7F,0x04,0x04,0x04,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x80,0x00, + /* 0xA8D9 [?] [715]*/ + 0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x3F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0xF0,0x10,0x00,0x00, + /* 0xA8DA [?] [716]*/ + 0x00,0x10,0x08,0x04,0x02,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8DB [?] [717]*/ + 0x00,0x00,0x7F,0x01,0x01,0x01,0x0F,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xE0,0x00,0x00, + /* 0xA8DC [?] [718]*/ + 0x00,0x01,0x01,0x01,0x7F,0x01,0x01,0x0F,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00, + 0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xE0,0x00, + /* 0xA8DD [?] [719]*/ + 0x00,0x00,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0x08,0x09,0x08,0x07,0x00,0x00, + 0x00,0x00,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x80,0x80,0x00,0x00,0xF0,0x00,0x00, + /* 0xA8DE [?] [720]*/ + 0x00,0x00,0x7F,0x09,0x09,0x11,0x1F,0x01,0x01,0x01,0x02,0x02,0x04,0x08,0x10,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + /* 0xA8DF [?] [721]*/ + 0x00,0x00,0x1C,0x04,0x04,0x04,0x02,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x18,0x00, + /* 0xA8E0 [?] [722]*/ + 0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x1F,0x01,0x02,0x04,0x08,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x20,0x20,0x40,0x40,0x80,0x00,0x00,0x40,0x20,0xF0,0x10,0x00,0x00, + /* 0xA8E1 [?] [723]*/ + 0x00,0x00,0x00,0x1F,0x00,0x00,0x04,0x02,0x01,0x00,0x00,0x01,0x02,0x04,0x08,0x00, + 0x00,0x00,0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x40,0x20,0x00,0x00,0x00, + /* 0xA8E2 [?] [724]*/ + 0x00,0x3F,0x08,0x08,0x08,0x08,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x20,0x20,0x40,0x40,0x40,0xF8,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00, + /* 0xA8E3 [?] [725]*/ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + /* 0xA8E4 [?] [726]*/ + 0x00,0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0x04,0x04,0x04,0x08,0x10,0x60,0x00, + 0x00,0x00,0x00,0x00,0x00,0xFC,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7C,0x00, + /* 0xA8E5 [?] [727]*/ + 0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x3F,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00, + /* 0xA8E6 [?] [728]*/ + 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x60,0x00, + 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x7C,0x00, + /* 0xA8E7 [?] [729]*/ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8E8 [?] [730]*/ + 0x00,0x00,0x00,0x00,0x08,0x04,0x02,0x01,0x00,0x00,0x01,0x02,0x04,0x18,0x60,0x00, + 0x00,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x40,0x20,0x10,0x00,0x00,0x00, + /* 0xA8E9 [?] [731]*/ + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00, + /* 0xA8EA [?] [732]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8EB [?] [733]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8EC [?] [734]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8ED [?] [735]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8EE [?] [736]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8EF [?] [737]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F0 [?] [738]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F1 [?] [739]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F2 [?] [740]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F3 [?] [741]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F4 [?] [742]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F5 [?] [743]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F6 [?] [744]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F7 [?] [745]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F8 [?] [746]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8F9 [?] [747]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8FA [?] [748]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8FB [?] [749]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8FC [?] [750]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8FD [?] [751]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA8FE [?] [752]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A1 [?] [753]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A2 [?] [754]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A3 [?] [755]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A4 [-] [756]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A5 [?] [757]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A6 [¦] [758]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A7 [?] [759]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9A8 [?] [760]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9A9 [?] [761]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9AA [?] [762]*/ + 0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9AB [?] [763]*/ + 0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x00, + /* 0xA9AC [?] [764]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9AD [?] [765]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9AE [?] [766]*/ + 0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9AF [?] [767]*/ + 0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00, + 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, + /* 0xA9B0 [+] [768]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9B1 [?] [769]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9B2 [?] [770]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9B3 [?] [771]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9B4 [+] [772]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9B5 [?] [773]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9B6 [?] [774]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9B7 [?] [775]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9B8 [+] [776]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9B9 [?] [777]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BA [?] [778]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BB [?] [779]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BC [+] [780]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BD [?] [781]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BE [?] [782]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9BF [?] [783]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C0 [+] [784]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C1 [?] [785]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C2 [?] [786]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C3 [?] [787]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9C4 [?] [788]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9C5 [?] [789]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C6 [?] [790]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9C7 [?] [791]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9C8 [¦] [792]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9C9 [?] [793]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9CA [?] [794]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9CB [?] [795]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9CC [?] [796]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9CD [?] [797]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9CE [?] [798]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9CF [?] [799]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9D0 [-] [800]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9D1 [?] [801]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9D2 [?] [802]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9D3 [?] [803]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9D4 [?] [804]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9D5 [?] [805]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9D6 [?] [806]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9D7 [?] [807]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9D8 [-] [808]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9D9 [?] [809]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DA [?] [810]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DB [?] [811]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DC [?] [812]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DD [?] [813]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DE [?] [814]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9DF [?] [815]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E0 [+] [816]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E1 [?] [817]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E2 [?] [818]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E3 [?] [819]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E4 [?] [820]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E5 [?] [821]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9E6 [?] [822]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9E7 [?] [823]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E8 [?] [824]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9E9 [?] [825]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9EA [?] [826]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9EB [?] [827]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9EC [?] [828]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9ED [?] [829]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9EE [?] [830]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9EF [?] [831]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xA9F0 [?] [832]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F1 [?] [833]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F2 [?] [834]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F3 [?] [835]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F4 [?] [836]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F5 [?] [837]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F6 [?] [838]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F7 [?] [839]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F8 [?] [840]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9F9 [?] [841]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9FA [?] [842]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9FB [?] [843]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9FC [?] [844]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9FD [?] [845]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xA9FE [?] [846]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA1 [?] [847]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA2 [?] [848]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA3 [?] [849]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA4 [?] [850]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA5 [?] [851]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA6 [?] [852]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA7 [?] [853]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA8 [?] [854]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAA9 [?] [855]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAA [?] [856]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAB [?] [857]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAC [?] [858]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAD [?] [859]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAE [?] [860]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAAF [?] [861]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB0 [?] [862]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB1 [?] [863]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB2 [?] [864]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB3 [?] [865]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB4 [?] [866]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB5 [?] [867]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB6 [?] [868]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB7 [?] [869]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB8 [?] [870]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAB9 [?] [871]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABA [?] [872]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABB [?] [873]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABC [?] [874]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABD [?] [875]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABE [?] [876]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAABF [?] [877]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC0 [?] [878]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC1 [?] [879]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC2 [?] [880]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC3 [?] [881]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC4 [?] [882]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC5 [?] [883]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC6 [?] [884]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC7 [?] [885]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC8 [?] [886]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAC9 [?] [887]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACA [?] [888]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACB [?] [889]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACC [?] [890]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACD [?] [891]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACE [?] [892]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAACF [?] [893]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD0 [?] [894]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD1 [?] [895]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD2 [?] [896]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD3 [?] [897]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD4 [?] [898]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD5 [?] [899]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD6 [?] [900]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD7 [?] [901]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD8 [?] [902]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAD9 [?] [903]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADA [?] [904]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADB [?] [905]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADC [?] [906]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADD [?] [907]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADE [?] [908]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAADF [?] [909]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE0 [?] [910]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE1 [?] [911]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE2 [?] [912]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE3 [?] [913]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE4 [?] [914]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE5 [?] [915]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE6 [?] [916]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE7 [?] [917]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE8 [?] [918]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAE9 [?] [919]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAEA [?] [920]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAEB [?] [921]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAEC [?] [922]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAED [?] [923]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAEE [?] [924]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAEF [?] [925]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAF0 [?] [926]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAAF1 [?] [927]*/ + 0x00,0x10,0x20,0x24,0x39,0x21,0x7F,0x21,0x21,0x3C,0x24,0x27,0x1C,0x10,0x10,0x00, + 0x00,0x10,0x90,0x94,0x1C,0x10,0x32,0x52,0x12,0x2C,0x20,0xFE,0x20,0x20,0x20,0x00, + /* 0xAAF2 [?] [928]*/ + 0x00,0x10,0x11,0x21,0x25,0x4B,0x79,0x11,0x21,0x5B,0x63,0x05,0x31,0x41,0x01,0x00, + 0x00,0x00,0x10,0x10,0x10,0xEC,0x18,0xD8,0x58,0x34,0x34,0x52,0x50,0x10,0x10,0x00, + /* 0xAAF3 [?] [929]*/ + 0x00,0x00,0x04,0x38,0x21,0x20,0x20,0x7F,0x24,0x20,0x20,0x21,0x18,0x60,0x03,0x00, + 0x00,0x00,0x90,0x96,0xF8,0x10,0x02,0xFC,0x08,0xF0,0x48,0xF0,0x50,0x40,0xFE,0x00, + /* 0xAAF4 [?] [930]*/ + 0x00,0x00,0x11,0x10,0x10,0x3C,0x10,0x18,0x10,0x70,0x50,0x10,0x11,0x12,0x34,0x00, + 0x00,0x00,0x20,0xA0,0xA0,0x22,0xFE,0x22,0x42,0x64,0x94,0x84,0x04,0x04,0x1C,0x00, + /* 0xAAF5 [?] [931]*/ + 0x00,0x02,0x05,0x39,0x20,0x23,0x3E,0x2B,0x6A,0x2A,0x2A,0x2A,0x12,0x04,0x04,0x08, + 0x00,0x00,0x10,0x20,0xFE,0x50,0x24,0xF8,0x90,0x90,0xAC,0x98,0x98,0xA4,0x22,0x40, + /* 0xAAF6 [?] [932]*/ + 0x00,0x00,0x7D,0x11,0x11,0x11,0x11,0x39,0x11,0x11,0x11,0x16,0x3A,0x44,0x08,0x00, + 0x00,0x00,0xFC,0x04,0xFC,0x10,0x50,0x54,0x54,0x7C,0x10,0x92,0x92,0x92,0x6E,0x00, + /* 0xAAF7 [?] [933]*/ + 0x00,0x00,0x7C,0x11,0x12,0x12,0x13,0x3A,0x11,0x13,0x13,0x17,0x3D,0x45,0x09,0x10, + 0x00,0x40,0x20,0xFC,0x04,0x04,0xF8,0x00,0xFC,0x54,0x54,0xFC,0x54,0x54,0x0C,0x04, + /* 0xAAF8 [?] [934]*/ + 0x00,0x01,0x21,0x23,0x22,0x22,0x3F,0x22,0x23,0x22,0x22,0x12,0x63,0x02,0x00,0x00, + 0x00,0x00,0x1E,0xE4,0x64,0x64,0xFC,0x64,0xE4,0x3C,0xA4,0x64,0xE4,0x24,0x44,0x00, + /* 0xAAF9 [?] [935]*/ + 0x00,0x00,0x04,0x79,0x11,0x11,0x11,0x7D,0x10,0x10,0x11,0x15,0x7A,0x44,0x00,0x00, + 0x00,0x0C,0x70,0x80,0x10,0x20,0x20,0xFE,0x20,0xA8,0xA4,0x26,0x22,0x22,0x60,0x00, + /* 0xAAFA [?] [936]*/ + 0x00,0x18,0x11,0x10,0x14,0x3B,0x12,0x1E,0x36,0x32,0x52,0x92,0x12,0x12,0x10,0x10, + 0x00,0x00,0xFE,0x00,0x12,0xFC,0x54,0x54,0xDC,0xD4,0x54,0x54,0x54,0x54,0x5C,0x00, + /* 0xAAFB [?] [937]*/ + 0x00,0x04,0x04,0x04,0x3F,0x08,0x37,0x02,0x12,0x1F,0x12,0x15,0x14,0x19,0x12,0x00, + 0x00,0x20,0x20,0x26,0xF8,0x08,0xF0,0x40,0x4C,0xF8,0x48,0xA8,0x88,0x08,0x28,0x10, + /* 0xAAFC [?] [938]*/ + 0x00,0x18,0x11,0x2E,0x43,0x0F,0x01,0x3E,0x0F,0x09,0x09,0x09,0x0A,0x04,0x08,0x70, + 0x00,0x60,0x44,0xB8,0x08,0xF0,0x00,0xF8,0xF0,0x10,0x10,0x10,0x90,0x70,0x0C,0x04, + /* 0xAAFD [?] [939]*/ + 0x00,0x00,0x04,0x3B,0x10,0x10,0x13,0x70,0x13,0x12,0x12,0x12,0x3F,0x42,0x02,0x00, + 0x00,0x90,0x90,0xFC,0x90,0x00,0xFC,0xA0,0xFC,0xA4,0xD4,0xAC,0x24,0x04,0x0C,0x00, + /* 0xAAFE [?] [940]*/ + 0x00,0x00,0x00,0x0F,0x08,0x28,0x29,0x08,0x18,0x6F,0x12,0x12,0x12,0x22,0x43,0x00, + 0x00,0x80,0x40,0xBC,0x40,0x4C,0xB0,0x20,0x26,0xD8,0x28,0x08,0x08,0x08,0xF8,0x00, + /* 0xABA1 [?] [941]*/ + 0x00,0x00,0x00,0x3C,0x44,0x44,0x45,0x44,0x7C,0x47,0x44,0x44,0x7C,0x00,0x00,0x00, + 0x00,0x20,0x20,0x26,0xF8,0x20,0xFC,0x20,0x20,0xFC,0x24,0x24,0x24,0x3C,0x20,0x20, + /* 0xABA2 [?] [942]*/ + 0x00,0x00,0x05,0x38,0x10,0x10,0x10,0x38,0x10,0x10,0x13,0x18,0x60,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x04,0xFC,0x10,0x16,0xF8,0x90,0x90,0x10,0x30,0x00, + /* 0xABA3 [?] [943]*/ + 0x00,0x00,0x01,0x7D,0x45,0x45,0x45,0x3D,0x45,0x45,0x45,0x44,0x7C,0x41,0x02,0x0C, + 0x00,0x00,0x0C,0xF8,0x28,0x48,0x48,0x48,0x48,0x50,0x60,0x62,0xA2,0x22,0x12,0x0C, + /* 0xABA4 [?] [944]*/ + 0x00,0x10,0x11,0x11,0x25,0x47,0x79,0x11,0x21,0x21,0x7D,0x01,0x06,0x7A,0x44,0x08, + 0x00,0x04,0x02,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x00,0x00, + /* 0xABA5 [?] [945]*/ + 0x00,0x01,0x00,0x3F,0x21,0x22,0x27,0x22,0x25,0x29,0x30,0x28,0x4F,0x48,0x40,0xBF, + 0x00,0x00,0x84,0xFE,0x10,0x24,0xF8,0x00,0x08,0x24,0x80,0x84,0xF8,0x88,0x86,0x78, + /* 0xABA6 [?] [946]*/ + 0x00,0x00,0x44,0x28,0x11,0x2A,0x4D,0x08,0x1B,0x2A,0x2A,0x4A,0x0A,0x0A,0x39,0x16, + 0x00,0x40,0x40,0xB0,0x4C,0x70,0xA0,0x48,0xB8,0x68,0x48,0x48,0x40,0xB0,0x0C,0x04, + /* 0xABA7 [?] [947]*/ + 0x00,0x02,0x02,0x3F,0x04,0x04,0x0F,0x70,0x1F,0x0C,0x08,0x0F,0x00,0x1F,0x00,0x00, + 0x00,0x60,0x24,0xD8,0x98,0xE0,0x82,0x7C,0xF0,0x10,0x24,0xDC,0x28,0xD8,0x78,0x10, + /* 0xABA8 [?] [948]*/ + 0x00,0x10,0x10,0x24,0x38,0x20,0x7C,0x10,0x10,0x7E,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x00,0x04,0xF8,0x80,0x80,0x80,0x82,0xFC,0x88,0x88,0x08,0x08,0x08,0x08,0x08,0x00, + /* 0xABA9 [?] [949]*/ + 0x00,0x08,0x0A,0x13,0x12,0x12,0x32,0x52,0x13,0x12,0x12,0x14,0x14,0x14,0x18,0x01, + 0x00,0x00,0x06,0xF8,0x20,0x24,0x78,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0x22,0xDC, + /* 0xABAA [?] [950]*/ + 0x00,0x00,0x21,0x21,0x3F,0x04,0x08,0x3E,0x08,0x0E,0x19,0x29,0x29,0x49,0x08,0x00, + 0x00,0x80,0x04,0x04,0xFC,0x20,0x20,0xFC,0x30,0x70,0x68,0xA8,0x24,0x20,0x20,0x20, + /* 0xABAB [?] [951]*/ + 0x00,0x00,0x3C,0x04,0x04,0x24,0x58,0x40,0x40,0x7E,0x04,0x04,0x04,0x04,0x19,0x00, + 0x00,0x00,0x86,0xF8,0x84,0xC4,0xA8,0x98,0x88,0x98,0xA4,0xC4,0xC0,0x80,0xFE,0x00, + /* 0xABAC [?] [952]*/ + 0x00,0x00,0x14,0x14,0x7F,0x14,0x14,0x7F,0x54,0x7F,0x14,0x14,0x24,0x24,0x44,0x80, + 0x00,0x00,0x3E,0x24,0xA4,0xA8,0xA8,0x28,0x24,0xE4,0xA4,0xA4,0xBC,0x20,0x20,0x00, + /* 0xABAD [?] [953]*/ + 0x00,0x00,0x46,0x34,0x09,0x19,0x6A,0x08,0x14,0x15,0x26,0x44,0x04,0x08,0x38,0x00, + 0x00,0x40,0x80,0xFC,0x88,0x90,0x50,0x20,0x58,0x8E,0x30,0x10,0x00,0x60,0x10,0x00, + /* 0xABAE [?] [954]*/ + 0x00,0x00,0x02,0x7C,0x28,0x28,0x67,0x1A,0x18,0x19,0x29,0x49,0x09,0x09,0x19,0x00, + 0x00,0x00,0x60,0x60,0x90,0x88,0x04,0xF8,0x00,0x08,0xF8,0x08,0x08,0x08,0xF8,0x00, + /* 0xABAF [?] [955]*/ + 0x00,0x00,0x10,0x10,0x14,0x14,0x08,0x51,0x50,0x10,0x10,0x1D,0x17,0x22,0x44,0x00, + 0x00,0x00,0x04,0xF8,0x40,0x40,0x42,0xFC,0x60,0xA0,0xA0,0x20,0x24,0x22,0x1E,0x00, + /* 0xABB0 [?] [956]*/ + 0x00,0x04,0x0C,0x09,0x08,0x10,0x10,0x33,0x50,0x10,0x17,0x10,0x10,0x10,0x10,0x00, + 0x00,0x00,0x1C,0xE0,0x40,0x40,0x4C,0xF0,0x40,0x46,0xF8,0x40,0x44,0x42,0x7E,0x00, + /* 0xABB1 [?] [957]*/ + 0x00,0x00,0x10,0x10,0x01,0x00,0x10,0x31,0x10,0x10,0x10,0x14,0x1A,0x1A,0x00,0x00, + 0x00,0x20,0x20,0x20,0xFC,0x20,0x20,0xFC,0x00,0x20,0xA4,0xC2,0x82,0x88,0xFC,0x00, + /* 0xABB2 [?] [958]*/ + 0x00,0x10,0x10,0x14,0x28,0x21,0x7E,0x10,0x10,0x7F,0x10,0x11,0x14,0x18,0x01,0x00, + 0x00,0x20,0x60,0x60,0x90,0x0C,0x0C,0x70,0x40,0xFC,0x40,0x44,0xC8,0xC0,0xFE,0x00, + /* 0xABB3 [?] [959]*/ + 0x00,0x00,0x08,0x0B,0x3C,0x1A,0x28,0x49,0x08,0x08,0x09,0x3E,0x1A,0x28,0x49,0x00, + 0x00,0x10,0x20,0x26,0x38,0x68,0xA4,0x20,0x20,0x20,0x22,0x3C,0x68,0xA4,0x22,0x00, + /* 0xABB4 [?] [960]*/ + 0x00,0x00,0x47,0x39,0x10,0x28,0x49,0x09,0x19,0x18,0x28,0xC8,0x09,0x08,0x38,0x00, + 0x00,0x00,0xFE,0x44,0x40,0x84,0xF8,0x20,0x20,0xF8,0x20,0x22,0xFC,0x20,0x20,0x00, + /* 0xABB5 [?] [961]*/ + 0x00,0x00,0x44,0x38,0x11,0x2A,0x48,0x08,0x19,0x1A,0x29,0xC9,0x09,0x09,0x38,0x00, + 0x00,0x00,0xC8,0x84,0x04,0x50,0x50,0x88,0x06,0x08,0xF8,0x08,0x08,0x08,0xF8,0x00, + /* 0xABB6 [?] [962]*/ + 0x00,0x10,0x11,0x11,0x55,0x7D,0x54,0x54,0x54,0x7C,0x50,0x14,0x1A,0x61,0x02,0x04, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xF8,0x40,0x44,0xFC,0x44,0x84,0x84,0x04,0x18,0x00, + /* 0xABB7 [?] [963]*/ + 0x00,0x00,0x01,0x0E,0x00,0x1F,0x00,0x03,0x1C,0x0B,0x08,0x0F,0x08,0x0F,0x08,0x37, + 0x00,0x30,0xC0,0x08,0x70,0x84,0x38,0xC0,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x12,0xEC, + /* 0xABB8 [?] [964]*/ + 0x00,0x00,0x10,0x20,0x26,0x3C,0x40,0x90,0x11,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x00,0x00,0x80,0x8C,0x90,0xA0,0xC0,0x80,0xFC,0xC0,0xA0,0x90,0x98,0xAE,0xC4,0x80, + /* 0xABB9 [?] [965]*/ + 0x00,0x00,0x01,0x39,0x13,0x11,0x11,0x7D,0x11,0x10,0x13,0x14,0x39,0x42,0x0C,0x00, + 0x00,0x48,0x48,0x4A,0xFC,0x48,0x38,0x00,0xFC,0x40,0xFE,0xD0,0x48,0x46,0x40,0x00, + /* 0xABBA [?] [966]*/ + 0x00,0x00,0x10,0x10,0x00,0x00,0x13,0x30,0x10,0x10,0x11,0x1E,0x1C,0x18,0x00,0x00, + 0x00,0x08,0xFC,0x40,0x40,0x40,0xFC,0x60,0xD0,0xD0,0x48,0x4C,0x46,0x40,0x40,0x00, + /* 0xABBB [?] [967]*/ + 0x00,0x10,0x10,0x10,0x2C,0x20,0x3D,0x51,0x16,0x7F,0x10,0x10,0x14,0x18,0x11,0x00, + 0x00,0x20,0x60,0x60,0x90,0x90,0x08,0x06,0x08,0xF0,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xABBC [?] [968]*/ + 0x00,0x20,0x10,0x11,0x00,0x00,0x73,0x10,0x10,0x10,0x13,0x14,0x18,0x10,0x01,0x00, + 0x00,0x10,0x70,0x9C,0x94,0x90,0xFE,0x94,0x94,0xF4,0x98,0x98,0xA8,0xC6,0x82,0x00, + /* 0xABBD [?] [969]*/ + 0x00,0x08,0x13,0x1D,0x11,0x6F,0x47,0x6B,0x5B,0x53,0x5B,0x67,0x43,0x42,0x7E,0x00, + 0x00,0x10,0x10,0x10,0x10,0x12,0x74,0x98,0x10,0x10,0x10,0x10,0x72,0x92,0x1E,0x00, + /* 0xABBE [?] [970]*/ + 0x00,0x00,0x01,0x79,0x53,0x51,0x51,0x49,0x49,0x49,0x7F,0x41,0x02,0x02,0x04,0x08, + 0x00,0x00,0x02,0x1E,0x94,0x14,0x58,0x98,0x14,0x12,0x92,0x12,0x1E,0x10,0x10,0x00, + /* 0xABBF [?] [971]*/ + 0x00,0x00,0x10,0x11,0x01,0x05,0x69,0x29,0x09,0x11,0x11,0x30,0x20,0x20,0x20,0x00, + 0x00,0x00,0x04,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xABC0 [?] [972]*/ + 0x00,0x10,0x10,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1F,0x61,0x01,0x03,0x04,0x00, + 0x00,0x00,0x38,0xC0,0x00,0x00,0xF8,0x10,0x10,0x10,0xFE,0x00,0x88,0x04,0x04,0x00, + /* 0xABC1 [?] [973]*/ + 0x00,0x10,0x12,0x22,0x3A,0x42,0x4E,0x32,0x14,0x7C,0x13,0x12,0x16,0x1A,0x07,0x00, + 0x00,0x80,0x90,0x92,0xAC,0xA0,0xD8,0x84,0x00,0x00,0xF8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xABC2 [?] [974]*/ + 0x00,0x00,0x18,0x08,0x01,0x45,0x2A,0x0D,0x09,0x10,0x10,0x30,0x10,0x10,0x13,0x0C, + 0x00,0x00,0x90,0x88,0x04,0x06,0x10,0x18,0x10,0x90,0xA0,0x60,0x60,0x90,0x0E,0x00, + /* 0xABC3 [?] [975]*/ + 0x00,0x00,0x31,0x20,0x5F,0x42,0x7A,0xA3,0x22,0x79,0x20,0x23,0x29,0x12,0x04,0x00, + 0x00,0x00,0xFC,0xA0,0xFC,0xA4,0xA4,0x5C,0x48,0x50,0x62,0xDC,0x50,0x4C,0x46,0x40, + /* 0xABC4 [?] [976]*/ + 0x00,0x00,0x21,0x10,0x16,0x0B,0x0B,0x0A,0x13,0x12,0x30,0x11,0x10,0x30,0x01,0x06, + 0x00,0x00,0xFC,0x30,0x24,0xFC,0xFC,0x24,0xFC,0x44,0x44,0xBC,0x84,0x84,0x28,0x18, + /* 0xABC5 [?] [977]*/ + 0x00,0x04,0x09,0x1E,0x09,0x1E,0x7F,0x41,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x23,0x00, + 0x00,0x00,0x0C,0x08,0x10,0x20,0x86,0x08,0x10,0x20,0x42,0x04,0x08,0x10,0x60,0x80, + /* 0xABC6 [?] [978]*/ + 0x00,0x00,0x1F,0x00,0x01,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x43,0x40,0x3F,0x00, + 0x00,0x10,0xF8,0x60,0x80,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xABC7 [?] [979]*/ + 0x00,0x00,0x22,0x3E,0x22,0x22,0x22,0x2A,0x2A,0x22,0x22,0x23,0x43,0x82,0x00,0x00, + 0x00,0x00,0x7E,0x44,0x48,0x50,0x50,0x4C,0x42,0x42,0x42,0xCA,0x44,0x40,0x40,0x00, + /* 0xABC8 [?] [980]*/ + 0x00,0x00,0x33,0x10,0x00,0x00,0x70,0x10,0x11,0x10,0x10,0x14,0x18,0x10,0x00,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x22,0xFC,0x20,0x20,0x20,0x20,0x20,0xE0,0x00, + /* 0xABC9 [?] [981]*/ + 0x00,0x00,0x00,0x7E,0x10,0x10,0x10,0x7E,0x10,0x10,0x10,0x12,0x3C,0x40,0x00,0x00, + 0x00,0x04,0x04,0x44,0x44,0x44,0x44,0x44,0x44,0x5C,0x64,0x04,0x04,0x04,0x04,0x00, + /* 0xABCA [?] [982]*/ + 0x00,0x08,0x08,0x08,0x7F,0x08,0x09,0x7F,0x49,0x49,0x49,0x49,0x09,0x08,0x08,0x08, + 0x00,0x00,0x44,0x7C,0x48,0x50,0x60,0x58,0x44,0x42,0x42,0x42,0x4C,0x40,0x40,0x40, + /* 0xABCB [?] [983]*/ + 0x00,0x08,0x08,0x08,0x7F,0x08,0x08,0x0B,0x36,0x22,0x1C,0x0C,0x16,0x22,0x41,0x00, + 0x00,0x00,0x46,0x7C,0xC8,0x50,0x50,0x48,0x46,0x42,0x42,0x42,0x46,0x40,0x40,0x00, + /* 0xABCC [?] [984]*/ + 0x00,0x08,0x08,0x10,0x10,0x10,0x31,0x51,0x91,0x12,0x12,0x14,0x14,0x18,0x10,0x00, + 0x00,0x00,0x40,0x40,0x26,0xE8,0xD0,0x60,0x50,0x50,0x48,0x44,0x43,0x40,0xC0,0x00, + /* 0xABCD [?] [985]*/ + 0x00,0x01,0x00,0x3F,0x20,0x21,0x2F,0x21,0x21,0x27,0x59,0x41,0x41,0x81,0x80,0x00, + 0x00,0x00,0x84,0x78,0x10,0xE0,0x00,0x00,0x0C,0xF0,0x00,0x08,0x08,0x08,0xF8,0x00, + /* 0xABCE [?] [986]*/ + 0x00,0x00,0x10,0x11,0x00,0x48,0x28,0x10,0x10,0x10,0x10,0x21,0x22,0x22,0x20,0x00, + 0x00,0x00,0x02,0xFC,0x80,0x80,0xFC,0x84,0x84,0x88,0x88,0x08,0x08,0x38,0x10,0x00, + /* 0xABCF [?] [987]*/ + 0x00,0x10,0x10,0x10,0x10,0x14,0x52,0x51,0x50,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x04,0x78,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x00, + /* 0xABD0 [?] [988]*/ + 0x00,0x00,0x10,0x18,0x01,0x01,0x13,0x30,0x10,0x10,0x10,0x14,0x14,0x18,0x01,0x00, + 0x00,0x00,0x20,0x20,0x04,0xFE,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xFC,0x00, + /* 0xABD1 [?] [989]*/ + 0x00,0x00,0x7C,0x4B,0x4A,0x52,0x52,0x4B,0x4A,0x46,0x4E,0x7A,0x42,0x41,0x00,0x00, + 0x00,0x08,0x7C,0xA0,0x20,0x20,0x24,0xF8,0x20,0x20,0x20,0x50,0x92,0x0A,0x06,0x00, + /* 0xABD2 [?] [990]*/ + 0x00,0x00,0x08,0x10,0x10,0x7E,0x13,0x12,0x24,0x24,0x24,0x28,0x1C,0x12,0x20,0x40, + 0x00,0x00,0x48,0x44,0x44,0x44,0xF8,0x40,0x40,0x20,0x20,0x20,0x12,0x0A,0x06,0x00, + /* 0xABD3 [?] [991]*/ + 0x00,0x00,0x02,0x3C,0x10,0x10,0x10,0x1C,0x11,0x10,0x10,0x12,0x1C,0x60,0x00,0x00, + 0x00,0x00,0xFE,0x08,0x10,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x60,0x00, + /* 0xABD4 [?] [992]*/ + 0x00,0x00,0x11,0x12,0x12,0x12,0x16,0x3A,0x12,0x12,0x12,0x12,0x1A,0x62,0x01,0x00, + 0x00,0x00,0xFE,0x00,0x04,0x88,0x48,0x30,0x10,0x28,0x44,0x84,0x00,0x02,0xFC,0x00, + /* 0xABD5 [?] [993]*/ + 0x00,0x00,0x10,0x20,0x20,0x21,0x2E,0x75,0x21,0x21,0x20,0x21,0x19,0xE1,0x00,0x00, + 0x00,0x40,0x40,0xA0,0x90,0x08,0x06,0x80,0x18,0x20,0xC0,0x00,0x08,0x04,0xFC,0x00, + /* 0xABD6 [?] [994]*/ + 0x00,0x10,0x09,0x20,0x20,0x2F,0x2B,0x28,0x29,0x2A,0x2A,0x2D,0x2C,0x33,0x20,0x00, + 0x00,0x00,0xFE,0x84,0x94,0xE4,0xF4,0xB4,0xE4,0xA4,0x14,0xF4,0x14,0xF4,0x0C,0x04, + /* 0xABD7 [?] [995]*/ + 0x00,0x02,0x04,0x3F,0x04,0x0D,0x09,0x0F,0x11,0x21,0x01,0x3F,0x01,0x01,0x01,0x00, + 0x00,0x20,0x44,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x04,0xF8,0x00,0x00,0x00,0x00, + /* 0xABD8 [?] [996]*/ + 0x00,0x02,0x04,0x3F,0x10,0x08,0x09,0x3F,0x01,0x01,0x02,0x02,0x04,0x08,0x30,0x00, + 0x00,0x20,0x44,0xF8,0x80,0x80,0x00,0xFC,0x04,0x08,0x88,0x48,0x48,0x08,0x70,0x30, + /* 0xABD9 [?] [997]*/ + 0x00,0x10,0x10,0x11,0x6C,0x20,0x28,0x50,0x3C,0x10,0x14,0x78,0x09,0x09,0x0E,0x00, + 0x00,0x00,0x04,0xF8,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x1E,0x00, + /* 0xABDA [?] [998]*/ + 0x00,0x00,0x00,0x49,0x7A,0x48,0x48,0x49,0x49,0x48,0x78,0x40,0x40,0x01,0x0E,0x00, + 0x00,0x00,0x80,0x98,0x06,0x00,0x18,0x10,0x10,0xA0,0xA0,0x40,0xA0,0x18,0x04,0x00, + /* 0xABDB [?] [999]*/ + 0x00,0x00,0x11,0x21,0x21,0x25,0xA5,0xA5,0xA5,0xA5,0xA5,0xAE,0x76,0x02,0x05,0x00, + 0x00,0x00,0x02,0xFC,0x20,0x20,0x22,0x3C,0x24,0x24,0x24,0x24,0x44,0x84,0x0C,0x00, + /* 0xABDC [?] [1000]*/ + 0x00,0x18,0x10,0x1F,0x21,0x25,0x7D,0x25,0x25,0x39,0x21,0x23,0x20,0x20,0x1F,0x00, + 0x00,0x00,0x22,0xBE,0x24,0x24,0x28,0x28,0x24,0x22,0x22,0x22,0xAE,0x64,0xA0,0x20, + /* 0xABDD [?] [1001]*/ + 0x00,0x00,0x13,0x08,0x00,0x04,0x28,0x19,0x08,0x10,0x10,0x70,0x11,0x12,0x14,0x08, + 0x00,0x00,0xFC,0x40,0x40,0x40,0x44,0xF8,0x60,0xA0,0xA0,0xA0,0x24,0x22,0x1C,0x00, + /* 0xABDE [?] [1002]*/ + 0x00,0x00,0x10,0x10,0x03,0x00,0x2F,0x28,0x08,0x17,0x10,0x70,0x20,0x20,0x20,0x00, + 0x00,0x40,0x40,0x44,0xF8,0x40,0xF8,0x40,0x44,0xFC,0x44,0x44,0x44,0x48,0x40,0x40, + /* 0xABDF [?] [1003]*/ + 0x00,0x00,0x10,0x08,0x01,0x40,0x24,0x0B,0x08,0x10,0x10,0x30,0x10,0x20,0x10,0x00, + 0x00,0x20,0x20,0x40,0xF8,0x40,0x44,0xB8,0x80,0x88,0x78,0x10,0xA0,0x60,0x10,0x00, + /* 0xABE0 [?] [1004]*/ + 0x00,0x00,0x11,0x11,0x01,0x41,0x21,0x29,0x11,0x11,0x11,0x30,0x20,0x21,0x26,0x00, + 0x00,0x00,0xFC,0x08,0x28,0x48,0x48,0x48,0x48,0x48,0x40,0x60,0x98,0x06,0x02,0x00, + /* 0xABE1 [?] [1005]*/ + 0x00,0x00,0x20,0x10,0x10,0x00,0x11,0x70,0x17,0x10,0x10,0x14,0x18,0x11,0x16,0x00, + 0x00,0x40,0x90,0x88,0x88,0x70,0x80,0x4C,0xF0,0x48,0x50,0x20,0x60,0x94,0x0C,0x00, + /* 0xABE2 [?] [1006]*/ + 0x00,0x08,0x08,0x29,0x29,0x29,0x29,0x1F,0x0A,0x29,0x49,0x49,0x49,0x37,0x00,0x00, + 0x00,0x00,0x00,0x7E,0x44,0x48,0x48,0x50,0x48,0x44,0x44,0x44,0x5C,0x48,0x40,0x00, + /* 0xABE3 [?] [1007]*/ + 0x00,0x10,0x10,0x10,0x17,0x2C,0x25,0x24,0x24,0x4B,0x48,0x30,0x1C,0x20,0x40,0x80, + 0x00,0x20,0x40,0x46,0xF8,0x40,0xFC,0x40,0x40,0xFE,0x42,0x44,0x44,0x44,0x40,0x00, + /* 0xABE4 [?] [1008]*/ + 0x00,0x00,0x08,0x12,0x12,0x27,0x38,0x12,0x12,0x12,0x3F,0x12,0x12,0x22,0x42,0x00, + 0x00,0x00,0x22,0x3E,0x24,0x28,0x28,0x28,0x24,0xA4,0x24,0x22,0x3C,0x20,0x20,0x20, + /* 0xABE5 [?] [1009]*/ + 0x00,0x00,0x7C,0x04,0x27,0x25,0x24,0x48,0x7E,0x02,0x02,0xFC,0x04,0x04,0x1F,0x00, + 0x00,0x40,0x20,0x22,0xDC,0x08,0x88,0x88,0x90,0x50,0x60,0x20,0x50,0x88,0x06,0x00, + /* 0xABE6 [?] [1010]*/ + 0x00,0x00,0x10,0x10,0x21,0x26,0x4A,0x70,0x10,0x20,0x78,0x00,0x05,0x39,0x02,0x04, + 0x00,0x40,0x40,0x40,0xFC,0x48,0x40,0x60,0x60,0xA0,0xA0,0xA0,0x20,0x22,0x1E,0x00, + /* 0xABE7 [?] [1011]*/ + 0x00,0x00,0x7E,0x04,0x24,0x24,0x24,0x24,0x3E,0x03,0x06,0x7A,0x04,0x04,0x09,0x02, + 0x00,0x40,0x40,0x40,0xFC,0x48,0x48,0x48,0x4A,0xF4,0x60,0x50,0x88,0x8C,0x06,0x00, + /* 0xABE8 [?] [1012]*/ + 0x00,0x00,0x04,0x39,0x11,0x11,0x15,0x39,0x11,0x11,0x10,0x14,0x38,0x40,0x03,0x00, + 0x00,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x86,0x02,0x00, + /* 0xABE9 [?] [1013]*/ + 0x00,0x01,0x01,0x7D,0x11,0x11,0x11,0x15,0x39,0x11,0x11,0x12,0x1E,0x64,0x09,0x02, + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0xB0,0x70,0x28,0x28,0x28,0x44,0x84,0x02,0x00, + /* 0xABEA [?] [1014]*/ + 0x00,0x00,0x12,0x12,0x12,0x1F,0x12,0x12,0x7F,0x12,0x11,0x21,0x20,0x40,0x00,0x00, + 0x00,0x00,0x22,0x3E,0xA4,0x24,0x28,0x28,0xE4,0x24,0x22,0xA2,0xBE,0xA0,0x20,0x20, + /* 0xABEB [?] [1015]*/ + 0x00,0x04,0x04,0x7F,0x04,0x00,0x1F,0x10,0x10,0x10,0x0F,0x00,0x06,0x08,0x30,0x40, + 0x00,0x20,0x24,0xF8,0x20,0x10,0xF0,0x10,0x10,0x10,0xF0,0x40,0x30,0x0C,0x04,0x00, + /* 0xABEC [?] [1016]*/ + 0x00,0x10,0x10,0x11,0x7F,0x21,0x29,0x51,0x3F,0x11,0x17,0x79,0x09,0x09,0x09,0x00, + 0x00,0x00,0x1C,0xE0,0x20,0x20,0x20,0xFC,0x10,0x10,0x10,0x10,0x2A,0x46,0x82,0x00, + /* 0xABED [?] [1017]*/ + 0x00,0x00,0x10,0x10,0x22,0x3C,0x40,0x7D,0x90,0x12,0x7C,0x10,0x12,0x14,0x18,0x00, + 0x00,0x40,0x40,0x48,0x48,0x44,0x58,0xE0,0x40,0x20,0x20,0x20,0x10,0x1A,0x0E,0x02, + /* 0xABEE [?] [1018]*/ + 0x00,0x00,0x11,0x10,0x10,0x54,0x54,0x55,0x55,0x55,0x55,0x5C,0x64,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x14,0xE4,0x04,0xE4,0x24,0x24,0x24,0xC4,0x04,0x04,0x0C,0x08, + /* 0xABEF [?] [1019]*/ + 0x00,0x04,0x18,0x18,0x1F,0x28,0x28,0x09,0x16,0x14,0x14,0x14,0x15,0x22,0x20,0x00, + 0x00,0x00,0x04,0x7C,0x44,0x48,0x48,0x50,0x48,0x44,0x44,0xC4,0x5C,0x40,0x40,0x00, + /* 0xABF0 [?] [1020]*/ + 0x00,0x08,0x08,0x08,0x13,0x10,0x30,0x52,0x93,0x14,0x14,0x19,0x11,0x12,0x12,0x14, + 0x00,0x80,0x60,0x40,0xFE,0x90,0x90,0x90,0x94,0x96,0x92,0x12,0x10,0x10,0x30,0x00, + /* 0xABF1 [?] [1021]*/ + 0x00,0x08,0x0B,0x0A,0x10,0x10,0x31,0x51,0x91,0x10,0x10,0x10,0x11,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x40,0x40,0x84,0xF8,0x20,0x20,0xF8,0x20,0x20,0xFC,0x20,0x20,0x00, + /* 0xABF2 [?] [1022]*/ + 0x00,0x08,0x09,0x0B,0x14,0x14,0x32,0x51,0x90,0x10,0x12,0x12,0x12,0x12,0x13,0x10, + 0x00,0x00,0x24,0xC8,0x90,0x88,0x44,0x24,0x00,0x20,0x44,0x44,0x44,0x44,0xFC,0x00, + /* 0xABF3 [?] [1023]*/ + 0x00,0x00,0x04,0x0C,0x10,0x20,0x40,0x1F,0x08,0x0F,0x08,0x0F,0x08,0x77,0x00,0x00, + 0x00,0x40,0x40,0x20,0x18,0x0E,0x08,0xF0,0x20,0xE0,0x20,0xE0,0x24,0xF8,0x20,0x00, + /* 0xABF4 [?] [1024]*/ + 0x00,0x00,0x7E,0x42,0x46,0x5A,0x5A,0x4A,0x5B,0x56,0x66,0x45,0x80,0x80,0x00,0x00, + 0x00,0x20,0x20,0xFC,0x20,0x24,0x78,0x26,0xFA,0x24,0x24,0x3E,0xA2,0x62,0x1E,0x00, + /* 0xABF5 [?] [1025]*/ + 0x00,0x00,0x21,0x11,0x01,0x01,0x01,0x71,0x11,0x11,0x11,0x13,0x15,0x19,0x11,0x00, + 0x00,0x00,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x58,0x20,0x10,0x68,0x86,0x00, + /* 0xABF6 [?] [1026]*/ + 0x00,0x00,0x7F,0x01,0x3F,0x01,0x01,0x3F,0x01,0x02,0x3F,0x12,0x02,0x02,0x06,0x00, + 0x00,0x00,0x26,0x5C,0x44,0x48,0x50,0x48,0x48,0xC4,0x44,0x44,0x4C,0x40,0x40,0x00, + /* 0xABF7 [?] [1027]*/ + 0x00,0x00,0x3C,0x4A,0x4A,0x51,0x50,0x49,0x44,0x44,0x45,0x49,0x41,0x41,0x41,0x00, + 0x00,0x20,0x44,0x44,0x44,0xFC,0x00,0xFC,0x08,0x08,0xF0,0x00,0x00,0x04,0x86,0x78, + /* 0xABF8 [?] [1028]*/ + 0x00,0x00,0x3C,0x4B,0x49,0x50,0x50,0x48,0x45,0x47,0x45,0x79,0x41,0x42,0x46,0x08, + 0x00,0x80,0x40,0xFE,0x10,0xA0,0x60,0xE0,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xABF9 [?] [1029]*/ + 0x00,0x10,0x10,0x11,0x10,0x2C,0x24,0x24,0x45,0x4A,0x2C,0x18,0x14,0x20,0x43,0x00, + 0x00,0x00,0x04,0xF8,0x40,0x40,0xC0,0xD0,0x48,0x44,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xABFA [?] [1030]*/ + 0x00,0x18,0x10,0x10,0x10,0x2E,0x24,0x24,0x25,0x4A,0x28,0x18,0x14,0x20,0x40,0x00, + 0x00,0x10,0x20,0x20,0x5C,0x50,0x50,0xFC,0x94,0x94,0x94,0x94,0x94,0x1C,0x10,0x10, + /* 0xABFB [?] [1031]*/ + 0x00,0x10,0x10,0x10,0x10,0x2D,0x25,0x25,0x45,0x49,0x29,0x19,0x15,0x21,0x40,0x03, + 0x00,0x20,0x2C,0x24,0x22,0xFC,0x20,0x24,0x24,0x28,0x28,0x52,0x9A,0x2C,0xC6,0x00, + /* 0xABFC [?] [1032]*/ + 0x00,0x10,0x10,0x11,0x25,0x3F,0x24,0x24,0x28,0x48,0x48,0x30,0x1C,0x20,0x40,0x80, + 0x00,0x40,0x20,0x20,0xFE,0x04,0x00,0x06,0xF8,0x20,0x20,0x20,0x20,0x20,0xE0,0x40, + /* 0xABFD [?] [1033]*/ + 0x00,0x00,0x7C,0x0B,0x28,0x28,0x28,0x49,0x48,0x34,0x04,0x7C,0x04,0x04,0x38,0x01, + 0x00,0x00,0x04,0xF8,0x40,0x40,0xC0,0x50,0x48,0x44,0x40,0x40,0x40,0x40,0x06,0xF8, + /* 0xABFE [?] [1034]*/ + 0x00,0x00,0x1C,0x04,0x25,0x25,0x25,0x25,0x3F,0x03,0x03,0x7B,0x03,0x05,0x0D,0x01, + 0x00,0x20,0x20,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFE,0x04,0x04,0x04,0x1C,0x00, + /* 0xACA1 [?] [1035]*/ + 0x00,0x00,0x1D,0x05,0x25,0x25,0x25,0x25,0x3F,0x03,0x03,0x7B,0x03,0x05,0x0D,0x00, + 0x00,0x00,0xFE,0x02,0x02,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x02,0x02,0x02,0x0E,0x00, + /* 0xACA2 [?] [1036]*/ + 0x00,0x10,0x11,0x12,0x26,0x46,0x7A,0x12,0x22,0x2E,0x72,0x02,0x0E,0x72,0x02,0x00, + 0x00,0x00,0x02,0xFC,0x04,0x4C,0x74,0x54,0x54,0x54,0x74,0x44,0x04,0x04,0x0C,0x04, + /* 0xACA3 [?] [1037]*/ + 0x00,0x0C,0x09,0x3E,0x09,0x1E,0x7F,0x08,0x0B,0x02,0x7F,0x04,0x04,0x03,0x03,0x3C, + 0x00,0x00,0x00,0x3E,0x24,0x24,0x44,0x88,0x00,0x00,0xFC,0x20,0x40,0xE0,0x18,0x00, + /* 0xACA4 [?] [1038]*/ + 0x00,0x00,0x04,0x38,0x10,0x11,0x10,0x1C,0x31,0x11,0x11,0x12,0x1C,0x68,0x10,0x07, + 0x00,0x00,0x48,0x88,0x86,0xF8,0x80,0x84,0xFC,0x48,0x48,0x30,0x20,0x58,0x8E,0x00, + /* 0xACA5 [?] [1039]*/ + 0x00,0x00,0x04,0x38,0x10,0x11,0x11,0x1D,0x31,0x11,0x11,0x11,0x1E,0x62,0x04,0x08, + 0x00,0x20,0x40,0x46,0x78,0x44,0xBC,0x04,0x04,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xACA6 [?] [1040]*/ + 0x00,0x00,0x04,0x38,0x11,0x13,0x10,0x1C,0x30,0x10,0x13,0x11,0x19,0x62,0x04,0x08, + 0x00,0x00,0x40,0x80,0x0C,0xF4,0x00,0x90,0x90,0x92,0xFC,0x10,0x10,0x10,0x10,0x10, + /* 0xACA7 [?] [1041]*/ + 0x00,0x10,0x11,0x11,0x12,0x7F,0x14,0x18,0x1B,0x71,0x51,0x11,0x11,0x12,0x34,0x28, + 0x00,0x20,0x40,0x40,0x48,0xF0,0x40,0x44,0xB8,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xACA8 [?] [1042]*/ + 0x00,0x00,0x10,0x11,0x11,0x16,0x38,0x10,0x13,0x11,0x11,0x1D,0x63,0x00,0x00,0x00, + 0x00,0x80,0x88,0xF8,0x50,0x30,0x70,0xAE,0x30,0xFC,0x20,0x24,0xFE,0x20,0x20,0x20, + /* 0xACA9 [?] [1043]*/ + 0x00,0x04,0x04,0x7F,0x04,0x08,0x28,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x20,0x00, + 0x00,0x20,0x44,0xFE,0x20,0x04,0xF8,0x08,0xC8,0x48,0x48,0x88,0x08,0x08,0x18,0x08, + /* 0xACAA [?] [1044]*/ + 0x00,0x04,0x04,0x7F,0x04,0x00,0x3F,0x09,0x09,0x1F,0x09,0x1F,0x09,0x11,0x23,0x02, + 0x00,0x20,0x44,0xFE,0x20,0x00,0xFE,0x44,0x48,0x50,0x4C,0x44,0x5C,0x40,0x40,0x00, + /* 0xACAB [?] [1045]*/ + 0x00,0x08,0x10,0x10,0x12,0x3D,0x10,0x1C,0x35,0x30,0x50,0x91,0x11,0x12,0x13,0x00, + 0x00,0x20,0x40,0x40,0x44,0xF8,0x40,0x40,0xFE,0x40,0x80,0x10,0x08,0x04,0xF8,0x00, + /* 0xACAC [?] [1046]*/ + 0x00,0x00,0x00,0x3F,0x20,0x27,0x20,0x20,0x3F,0x2A,0x2B,0x29,0x29,0x4A,0x44,0x00, + 0x00,0x00,0xDE,0x22,0x24,0xE4,0x28,0x68,0xA4,0x62,0xA2,0x22,0x2E,0xA4,0x60,0x20, + /* 0xACAD [?] [1047]*/ + 0x00,0x00,0x00,0x3D,0x11,0x11,0x11,0x2D,0x25,0x65,0x25,0x25,0x25,0x39,0x01,0x00, + 0x00,0x00,0x06,0xF8,0x04,0x44,0x28,0x18,0x08,0x18,0x24,0x44,0x40,0x00,0xFE,0x00, + /* 0xACAE [?] [1048]*/ + 0x00,0x00,0x08,0x08,0x7F,0x2B,0x1A,0x1C,0x7F,0x0A,0x19,0x18,0x28,0x48,0x89,0x00, + 0x00,0x00,0x20,0x20,0x20,0x7E,0x22,0xA2,0xE2,0x22,0x24,0x44,0x44,0x84,0x1C,0x00, + /* 0xACAF [?] [1049]*/ + 0x00,0x00,0x3D,0x45,0x45,0x45,0x7D,0x45,0x45,0x7D,0x44,0x44,0x7C,0x01,0x02,0x0C, + 0x00,0x00,0xFC,0x04,0x24,0x44,0x44,0x44,0x44,0x70,0x60,0x60,0xA4,0x24,0x1E,0x00, + /* 0xACB0 [?] [1050]*/ + 0x00,0x00,0x11,0x11,0x3F,0x00,0x00,0x1F,0x10,0x1E,0x12,0x22,0x22,0x24,0x41,0x00, + 0x00,0x00,0x08,0x08,0xF8,0x90,0xAC,0x50,0x48,0x48,0x50,0x50,0x20,0x54,0x8E,0x00, + /* 0xACB1 [?] [1051]*/ + 0x00,0x00,0x10,0x10,0x51,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x4D,0x71,0x01,0x00, + 0x00,0x00,0x50,0x50,0x50,0xFC,0x54,0x54,0x54,0xFC,0x54,0x54,0x54,0x54,0xA8,0x00, + /* 0xACB2 [?] [1052]*/ + 0x00,0x10,0x10,0x24,0x38,0x21,0x7C,0x10,0x10,0x7F,0x10,0x10,0x14,0x19,0x12,0x04, + 0x00,0x20,0x20,0x20,0x24,0xF8,0x20,0x20,0x26,0xF8,0x50,0x50,0x88,0x0C,0x06,0x00, + /* 0xACB3 [?] [1053]*/ + 0x00,0x10,0x10,0x24,0x3B,0x20,0x7C,0x10,0x10,0x7F,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x20,0x20,0x26,0xF8,0x20,0xFC,0x20,0x22,0xFE,0x22,0x22,0x22,0x24,0x20,0x00, + /* 0xACB4 [?] [1054]*/ + 0x00,0x10,0x10,0x24,0x38,0x20,0x7C,0x10,0x11,0x7E,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x80,0x84,0x88,0x90,0xE0,0x80,0x86,0xF8,0xA0,0xA0,0x90,0x88,0xF6,0x80,0x00, + /* 0xACB5 [?] [1055]*/ + 0x00,0x00,0x02,0x3C,0x10,0x10,0x20,0x3E,0x64,0x64,0xA4,0x24,0x24,0x18,0x00,0x00, + 0x00,0x20,0x20,0x24,0xF8,0x20,0x24,0xF8,0x20,0x20,0x26,0xF8,0x20,0x20,0x20,0x20, + /* 0xACB6 [?] [1056]*/ + 0x00,0x00,0x10,0x24,0x38,0x41,0x46,0x38,0x10,0x14,0x38,0x10,0x14,0x18,0x10,0x00, + 0x00,0x60,0x40,0x60,0x90,0x08,0x06,0x80,0x98,0xA0,0xC0,0x80,0x88,0x88,0xF8,0x00, + /* 0xACB7 [?] [1057]*/ + 0x00,0x00,0x10,0x10,0x28,0x49,0x11,0x11,0x71,0x12,0x12,0x12,0x12,0x14,0x14,0x09, + 0x00,0x40,0x58,0x48,0x44,0xF8,0x48,0x48,0x48,0xA8,0x30,0x30,0x30,0x4C,0x84,0x00, + /* 0xACB8 [?] [1058]*/ + 0x00,0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x3C,0x24,0x25,0x46,0x46,0x48,0x00, + 0x00,0x00,0x0C,0xF0,0x00,0x00,0x06,0xF8,0x20,0xA8,0xAC,0x24,0x24,0x24,0x60,0x00, + /* 0xACB9 [?] [1059]*/ + 0x00,0x00,0x7E,0x42,0x46,0x5A,0x5A,0x49,0x5B,0x56,0x67,0x45,0x80,0x80,0x00,0x00, + 0x00,0x00,0x24,0x18,0x48,0x4C,0x52,0x62,0x44,0xC4,0x6C,0x12,0x82,0x62,0x1E,0x00, + /* 0xACBA [?] [1060]*/ + 0x00,0x00,0x11,0x11,0x13,0x15,0x49,0x51,0x11,0x10,0x19,0x15,0x13,0x22,0x42,0x00, + 0x00,0x00,0x02,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x26,0x00, + /* 0xACBB [?] [1061]*/ + 0x00,0x00,0x10,0x10,0x0E,0x0B,0x6A,0x2A,0x13,0x12,0x12,0x22,0x22,0x24,0x20,0x03, + 0x00,0x20,0x58,0x40,0x42,0xBC,0x20,0x24,0xA4,0xA8,0x28,0x10,0x38,0x6E,0x86,0x00, + /* 0xACBC [?] [1062]*/ + 0x00,0x00,0x40,0x24,0x24,0x00,0x20,0x3E,0x24,0x24,0x24,0x24,0x3C,0x36,0x29,0x00, + 0x00,0x20,0x20,0x24,0x58,0x50,0xA0,0xA4,0x78,0x20,0xFE,0x20,0x20,0x20,0xFE,0x00, + /* 0xACBD [?] [1063]*/ + 0x00,0x10,0x10,0x10,0x11,0x2F,0x24,0x24,0x24,0x48,0x48,0x39,0x14,0x20,0x40,0x00, + 0x00,0x50,0x90,0x96,0x9C,0x90,0xB0,0xD2,0x92,0x2C,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xACBE [?] [1064]*/ + 0x00,0x00,0x19,0x11,0x23,0x25,0x59,0x29,0x11,0x21,0x39,0x01,0x01,0x7D,0x01,0x00, + 0x00,0x00,0x02,0xFC,0x24,0x24,0xFC,0x24,0x24,0x34,0x4C,0x4C,0x84,0x04,0xF8,0x00, + /* 0xACBF [?] [1065]*/ + 0x00,0x00,0x04,0x3C,0x24,0x29,0x28,0x28,0x4F,0x34,0x04,0x7C,0x04,0x09,0x1E,0x00, + 0x00,0x20,0xA0,0xA0,0xFC,0x20,0x20,0x22,0xDC,0x50,0x90,0x90,0x90,0x12,0x1E,0x00, + /* 0xACC0 [?] [1066]*/ + 0x00,0x00,0x13,0x10,0x21,0x4D,0x4A,0x71,0x20,0x20,0x73,0x01,0x09,0x72,0x04,0x00, + 0x00,0x00,0xBC,0x90,0x10,0x10,0x14,0xF8,0x90,0x90,0x10,0x3C,0x80,0x60,0x1C,0x00, + /* 0xACC1 [?] [1067]*/ + 0x00,0x10,0x10,0x21,0x21,0x4A,0x72,0x13,0x20,0x41,0x75,0x03,0x11,0x62,0x04,0x00, + 0x00,0x00,0x8E,0x70,0x10,0x10,0x34,0xD8,0xD0,0x50,0x50,0x7E,0x00,0xC0,0x3C,0x00, + /* 0xACC2 [?] [1068]*/ + 0x00,0x00,0x00,0x7C,0x12,0x13,0x12,0x7F,0x12,0x12,0x12,0x1E,0x65,0x04,0x08,0x10, + 0x00,0x00,0x24,0x24,0x22,0xFC,0x20,0xE6,0x54,0x54,0x58,0x98,0x98,0x2A,0x46,0x02, + /* 0xACC3 [?] [1069]*/ + 0x00,0x00,0x00,0x7C,0x11,0x11,0x11,0x15,0x39,0x11,0x10,0x10,0x1C,0x61,0x42,0x00, + 0x00,0x20,0x40,0x44,0xFC,0x44,0xFC,0x44,0x44,0xBC,0x24,0x28,0x30,0xD2,0x0E,0x02, + /* 0xACC4 [?] [1070]*/ + 0x00,0x00,0x09,0x1E,0x3F,0x09,0x36,0x21,0x3E,0x2A,0x2A,0x2A,0x0E,0x11,0x21,0x00, + 0x00,0x10,0x10,0x10,0x10,0xFE,0x12,0x12,0x22,0x22,0x22,0x24,0x44,0x44,0x8C,0x08, + /* 0xACC5 [?] [1071]*/ + 0x00,0x00,0x04,0x38,0x10,0x11,0x15,0x7A,0x10,0x11,0x10,0x1C,0x61,0x06,0x08,0x00, + 0x00,0x00,0xF8,0x90,0x90,0x10,0x0E,0x20,0x44,0xF8,0xE0,0xD0,0x4C,0x46,0x00,0x00, + /* 0xACC6 [?] [1072]*/ + 0x00,0x10,0x10,0x13,0x10,0x14,0x3B,0x12,0x10,0x11,0x14,0x68,0x40,0x01,0x02,0x0C, + 0x00,0x90,0x90,0xFE,0x90,0xA0,0xFE,0x48,0x40,0xFC,0x48,0x88,0x88,0x08,0x30,0x00, + /* 0xACC7 [?] [1073]*/ + 0x00,0x04,0x04,0x7F,0x05,0x03,0x06,0x08,0x37,0x00,0x1F,0x01,0x0D,0x11,0x27,0x01, + 0x00,0x20,0x24,0xF8,0xA0,0x80,0x60,0x18,0xE4,0x08,0xF0,0x00,0x30,0x0C,0x04,0x00, + /* 0xACC8 [?] [1074]*/ + 0x00,0x00,0x04,0x04,0x1B,0x01,0x01,0x3E,0x00,0x07,0x00,0x08,0x0F,0x08,0x0F,0x00, + 0x00,0x00,0x20,0x24,0xF8,0x80,0x08,0xF0,0x30,0xE0,0x00,0x10,0xF0,0x10,0xE0,0x00, + /* 0xACC9 [?] [1075]*/ + 0x00,0x18,0x10,0x10,0x14,0x38,0x19,0x14,0x35,0x33,0x50,0x50,0x10,0x11,0x12,0x14, + 0x00,0x20,0x20,0x20,0x26,0xF8,0x28,0xA8,0x30,0xFE,0x60,0x50,0x98,0x0C,0x06,0x00, + /* 0xACCA [?] [1076]*/ + 0x00,0x08,0x11,0x11,0x7F,0x10,0x12,0x7E,0x42,0x24,0x14,0x08,0x14,0x20,0x40,0x01, + 0x00,0x02,0xFC,0x20,0x20,0xDC,0x84,0x94,0x94,0x94,0x94,0x90,0x28,0x24,0xC2,0x02, + /* 0xACCB [?] [1077]*/ + 0x00,0x10,0x10,0x21,0x7E,0x20,0x50,0x53,0x7C,0x10,0x12,0x3C,0x50,0x11,0x12,0x00, + 0x00,0x20,0x24,0x24,0xA8,0xA8,0xB0,0xFE,0x90,0x90,0x90,0x90,0x90,0x12,0x1E,0x00, + /* 0xACCC [?] [1078]*/ + 0x00,0x00,0x11,0x11,0x0F,0x02,0x1F,0x0E,0x12,0x6F,0x09,0x0F,0x01,0x7F,0x01,0x00, + 0x00,0x80,0x08,0x08,0xF0,0x00,0xFC,0x30,0x0E,0xF0,0x00,0xF0,0x04,0xF8,0x00,0x00, + /* 0xACCD [?] [1079]*/ + 0x00,0x10,0x10,0x24,0x38,0x20,0x7F,0x10,0x10,0x7C,0x10,0x11,0x16,0x18,0x10,0x00, + 0x00,0x00,0x40,0x48,0x48,0x44,0xF8,0x60,0x50,0xD0,0xC8,0x44,0x46,0x40,0x40,0x00, + /* 0xACCE [?] [1080]*/ + 0x00,0x10,0x10,0x24,0x38,0x21,0x7D,0x11,0x11,0x7D,0x13,0x11,0x15,0x1A,0x12,0x04, + 0x00,0x20,0x20,0x26,0x38,0x20,0xDC,0x04,0x04,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xACCF [?] [1081]*/ + 0x00,0x10,0x10,0x24,0x39,0x21,0x7D,0x11,0x11,0x7D,0x13,0x11,0x14,0x18,0x10,0x00, + 0x00,0x20,0x20,0x20,0x24,0xFC,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xACD0 [?] [1082]*/ + 0x00,0x10,0x11,0x24,0x38,0x20,0x7C,0x10,0x13,0x7C,0x11,0x11,0x15,0x19,0x11,0x00, + 0x00,0x00,0xFE,0x44,0x44,0x44,0x84,0x9C,0x10,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00, + /* 0xACD1 [?] [1083]*/ + 0x00,0x10,0x10,0x24,0x38,0x20,0x7C,0x11,0x11,0x7D,0x11,0x11,0x15,0x18,0x10,0x00, + 0x00,0x00,0xFC,0x88,0xE8,0xA8,0xAA,0xFE,0x48,0x28,0x08,0x0A,0xFC,0x08,0x38,0x10, + /* 0xACD2 [?] [1084]*/ + 0x00,0x08,0x08,0x38,0x28,0x2F,0x59,0x88,0x88,0x0D,0x78,0x48,0x08,0x09,0x0A,0x04, + 0x00,0x00,0x50,0x50,0x50,0x56,0x58,0x50,0x50,0xDC,0x90,0x90,0x92,0x12,0x1E,0x00, + /* 0xACD3 [?] [1085]*/ + 0x00,0x09,0x08,0x10,0x12,0x13,0x32,0x53,0x12,0x13,0x10,0x10,0x13,0x10,0x10,0x00, + 0x00,0x08,0x90,0xA0,0x24,0xDC,0x44,0xFC,0x44,0xFC,0x40,0x42,0xFC,0x40,0x40,0x00, + /* 0xACD4 [?] [1086]*/ + 0x00,0x08,0x08,0x3E,0x22,0x22,0x3E,0x22,0x3E,0x22,0x1E,0x0B,0x12,0x22,0x46,0x00, + 0x00,0x10,0x10,0x10,0x10,0x50,0x54,0x54,0x92,0x92,0x92,0x12,0x10,0x10,0x70,0x20, + /* 0xACD5 [?] [1087]*/ + 0x00,0x08,0x08,0x0E,0x11,0x22,0x5C,0x48,0x3F,0x08,0x09,0x36,0x22,0x22,0x1C,0x00, + 0x00,0x00,0x7E,0x44,0x48,0x48,0x50,0x48,0xC4,0x42,0x42,0x42,0x5E,0x44,0x40,0x40, + /* 0xACD6 [?] [1088]*/ + 0x00,0x04,0x3C,0x24,0x24,0x3C,0x27,0x24,0x24,0x3C,0x24,0x24,0x44,0x45,0x8E,0x00, + 0x00,0x08,0x98,0x70,0x58,0x84,0x20,0x20,0x26,0xF8,0x70,0xA8,0xA4,0x22,0x20,0x00, + /* 0xACD7 [?] [1089]*/ + 0x00,0x00,0x10,0x21,0x20,0x5F,0x45,0x19,0x11,0x11,0x10,0x10,0x17,0x1A,0x14,0x00, + 0x00,0x20,0x20,0xFE,0x20,0x24,0xFC,0x24,0x24,0xF8,0x70,0xA8,0x2C,0x26,0x20,0x20, + /* 0xACD8 [?] [1090]*/ + 0x00,0x44,0x24,0x28,0x17,0x38,0x10,0x7D,0x11,0x11,0x7D,0x11,0x10,0x20,0x40,0x00, + 0x00,0x10,0x20,0x20,0xFE,0x20,0x22,0xFC,0x24,0x24,0x24,0x24,0x24,0x20,0x20,0x00, + /* 0xACD9 [?] [1091]*/ + 0x00,0x44,0x24,0x08,0x0A,0x34,0x10,0x3F,0x11,0x12,0x7C,0x10,0x10,0x10,0x21,0x46, + 0x00,0x40,0x40,0x40,0x86,0xF8,0x88,0x48,0x50,0x50,0x30,0x20,0x30,0xC8,0x06,0x00, + /* 0xACDA [?] [1092]*/ + 0x00,0x00,0x08,0x08,0x0A,0x2C,0x29,0x68,0x08,0x0B,0x08,0x14,0x10,0x20,0x20,0x40, + 0x00,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x10,0x12,0xFC,0x90,0x90,0x10,0x10,0x30,0x10, + /* 0xACDB [?] [1093]*/ + 0x00,0x00,0x11,0x09,0x09,0x3F,0x40,0x00,0x3F,0x08,0x1F,0x28,0x48,0x08,0x0F,0x00, + 0x00,0x10,0x10,0x20,0x20,0xFE,0x04,0x04,0xF8,0x00,0xF8,0x10,0x10,0x10,0xE0,0x00, + /* 0xACDC [?] [1094]*/ + 0x00,0x00,0x7C,0x4B,0x4A,0x52,0x53,0x4A,0x49,0x44,0x48,0x40,0x40,0x41,0x42,0x00, + 0x00,0x40,0x84,0x0C,0x04,0x44,0x8C,0x04,0xFC,0x60,0xA0,0xA0,0xA0,0x14,0x1C,0x00, + /* 0xACDD [?] [1095]*/ + 0x00,0x00,0x0C,0x7A,0x4B,0x52,0x50,0x49,0x48,0x45,0x46,0x7A,0x43,0x44,0x48,0x10, + 0x00,0x40,0x20,0x04,0xFC,0x10,0x08,0xF0,0x40,0x48,0x70,0x40,0x40,0xC0,0x7C,0x00, + /* 0xACDE [?] [1096]*/ + 0x00,0x00,0x11,0x10,0x10,0x7F,0x25,0x25,0x25,0x25,0x49,0x38,0x16,0x12,0x23,0x40, + 0x00,0x00,0xFC,0x00,0x00,0xFC,0x08,0x08,0x08,0xF8,0x08,0x88,0x50,0x90,0xFE,0x00, + /* 0xACDF [?] [1097]*/ + 0x00,0x10,0x10,0x10,0x10,0x2F,0x24,0x25,0x26,0x48,0x68,0x18,0x15,0x22,0x44,0x80, + 0x00,0x20,0x20,0x24,0xF8,0x24,0xA8,0x32,0xEC,0x60,0xB0,0xA8,0x2C,0x26,0x20,0x20, + /* 0xACE0 [?] [1098]*/ + 0x00,0x10,0x10,0x20,0x20,0x7D,0x26,0x48,0x48,0x49,0x48,0x30,0x1D,0x22,0x44,0x80, + 0x00,0x20,0x60,0x50,0x88,0x04,0x0A,0x70,0x20,0xFE,0x20,0xA8,0x24,0x22,0xE0,0x00, + /* 0xACE1 [?] [1099]*/ + 0x00,0x00,0x10,0x10,0x10,0x2E,0x25,0x26,0x24,0x45,0x49,0x38,0x14,0x20,0x40,0x00, + 0x00,0x20,0x20,0x60,0x50,0x88,0x06,0xF8,0x00,0x44,0x28,0xA8,0xB0,0x10,0x16,0xE8, + /* 0xACE2 [?] [1100]*/ + 0x00,0x00,0x10,0x10,0x10,0x2F,0x25,0x25,0x25,0x45,0x49,0x39,0x15,0x23,0x41,0x00, + 0x00,0x04,0xFC,0x50,0x30,0xFE,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0x0C,0x00, + /* 0xACE3 [?] [1101]*/ + 0x00,0x00,0x3C,0x04,0x24,0x24,0x25,0x24,0x26,0x1B,0x04,0x7C,0x05,0x06,0x1C,0x00, + 0x00,0x20,0x20,0x50,0x48,0x86,0x0A,0x30,0x20,0xFC,0x20,0xAC,0x22,0x22,0x60,0x00, + /* 0xACE4 [?] [1102]*/ + 0x00,0x10,0x10,0x10,0x24,0x44,0x78,0x11,0x21,0x21,0x7F,0x05,0x0D,0x70,0x00,0x00, + 0x00,0x08,0x70,0x38,0xC0,0x40,0x46,0xB8,0x20,0xFC,0x24,0x24,0x24,0x2C,0x20,0x20, + /* 0xACE5 [?] [1103]*/ + 0x00,0x00,0x08,0x10,0x11,0x27,0x3C,0x08,0x10,0x23,0x3C,0x00,0x04,0x38,0x03,0x04, + 0x00,0x20,0x10,0x22,0xDE,0x04,0x04,0x78,0x02,0xFC,0x50,0x50,0x50,0x92,0x0F,0x00, + /* 0xACE6 [?] [1104]*/ + 0x00,0x00,0x04,0x3C,0x25,0x25,0x25,0x25,0x27,0x1B,0x0D,0x75,0x05,0x05,0x1D,0x00, + 0x00,0x20,0x20,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF0,0x2C,0x30,0x10,0x68,0x86,0x00, + /* 0xACE7 [?] [1105]*/ + 0x00,0x0C,0x08,0x1E,0x0A,0x1C,0x09,0x3E,0x0B,0x00,0x1F,0x04,0x0B,0x38,0x08,0x07, + 0x00,0x00,0x04,0x3C,0x24,0x44,0x44,0xAC,0x18,0x06,0xF8,0x08,0xF8,0x08,0x08,0xF0, + /* 0xACE8 [?] [1106]*/ + 0x00,0x00,0x04,0x3B,0x11,0x11,0x15,0x3A,0x10,0x11,0x11,0x0E,0x74,0x00,0x00,0x07, + 0x00,0x20,0x20,0x24,0x38,0x20,0x20,0xDC,0x20,0xA0,0x24,0x2C,0x58,0x20,0xC0,0x00, + /* 0xACE9 [?] [1107]*/ + 0x00,0x00,0x00,0x04,0x38,0x11,0x12,0x10,0x38,0x11,0x10,0x11,0x15,0x6A,0x04,0x00, + 0x00,0x60,0x60,0xA0,0x90,0x0C,0x1C,0x60,0x24,0xF8,0x20,0x38,0x24,0x24,0xE0,0x00, + /* 0xACEA [?] [1108]*/ + 0x00,0x00,0x08,0x10,0x10,0x11,0x3D,0x11,0x11,0x10,0x10,0x14,0x3B,0x00,0x00,0x00, + 0x00,0x80,0x48,0x50,0x12,0xEC,0x24,0xFC,0x24,0xFC,0x20,0x21,0xFE,0x20,0x20,0x00, + /* 0xACEB [?] [1109]*/ + 0x00,0x00,0x11,0x22,0x21,0x21,0x7A,0x24,0x27,0x24,0x23,0x19,0x62,0x04,0x08,0x00, + 0x00,0x04,0xFC,0xA8,0x18,0x9C,0x24,0x40,0xFC,0xA4,0x28,0x18,0x90,0xA8,0xC6,0x00, + /* 0xACEC [?] [1110]*/ + 0x00,0x00,0x04,0x3F,0x05,0x0F,0x02,0x0C,0x00,0x1F,0x0F,0x10,0x10,0x0F,0x00,0x00, + 0x00,0x20,0x46,0xF8,0xC0,0xF0,0xC0,0x20,0x06,0xF8,0x90,0x90,0x90,0x90,0x70,0x00, + /* 0xACED [?] [1111]*/ + 0x00,0x00,0x04,0x3F,0x01,0x01,0x11,0x1E,0x10,0x1F,0x1F,0x01,0x7F,0x01,0x01,0x00, + 0x00,0x00,0x44,0xF8,0x00,0x08,0xF0,0x10,0x10,0xF0,0xF0,0x04,0xF8,0x00,0x00,0x00, + /* 0xACEE [?] [1112]*/ + 0x00,0x02,0x04,0x3F,0x24,0x3F,0x64,0x04,0x0F,0x11,0x01,0x3F,0x11,0x11,0x11,0x1E, + 0x00,0x20,0x44,0xF8,0x40,0xFE,0x00,0x10,0xF0,0x00,0x04,0xF8,0x08,0x10,0x10,0xE0, + /* 0xACEF [?] [1113]*/ + 0x00,0x00,0x04,0x3F,0x04,0x1F,0x10,0x1F,0x10,0x18,0x28,0x2F,0x28,0x48,0x4F,0x00, + 0x00,0x00,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x80,0x88,0x88,0xF0,0x84,0x88,0x70,0x00, + /* 0xACF0 [?] [1114]*/ + 0x00,0x00,0x00,0x3E,0x21,0x20,0x20,0x39,0x69,0x69,0xA9,0x29,0x29,0x3A,0x24,0x00, + 0x00,0x10,0x10,0x10,0x10,0x16,0x38,0x10,0x10,0x28,0x24,0x40,0x80,0x80,0x7E,0x00, + /* 0xACF1 [?] [1115]*/ + 0x00,0x00,0x01,0x7C,0x49,0x4A,0x4A,0x7B,0x4A,0x4B,0x49,0x48,0x70,0x40,0x01,0x0E, + 0x00,0x04,0xF8,0x40,0xFC,0x48,0x48,0xF8,0x48,0xF4,0x40,0xC0,0x40,0xA0,0x1E,0x00, + /* 0xACF2 [?] [1116]*/ + 0x00,0x00,0x00,0x05,0x7D,0x45,0x45,0x45,0x7D,0x45,0x45,0x45,0x45,0x7D,0x01,0x00, + 0x00,0x40,0x20,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF4,0x48,0x30,0x10,0x68,0x86,0x00, + /* 0xACF3 [?] [1117]*/ + 0x00,0x08,0x10,0x10,0x10,0x7E,0x52,0x52,0x52,0x7E,0x52,0x52,0x52,0x7E,0x40,0x03, + 0x00,0x00,0x7C,0x20,0xA4,0xDC,0x84,0xA4,0xA4,0xA4,0xA4,0xA0,0x38,0x44,0x82,0x02, + /* 0xACF4 [?] [1118]*/ + 0x00,0x10,0x10,0x10,0x50,0x7C,0x54,0x55,0x55,0x54,0x7C,0x14,0x17,0x7A,0x00,0x00, + 0x00,0x20,0x20,0x42,0xFC,0x80,0x90,0x10,0xFE,0x10,0xD8,0x96,0x12,0x10,0x70,0x00, + /* 0xACF5 [?] [1119]*/ + 0x00,0x10,0x10,0x52,0x7C,0x54,0x54,0x7C,0x54,0x54,0x6F,0x45,0x44,0x44,0x4C,0x00, + 0x00,0x00,0xEE,0x22,0x22,0xBA,0xAA,0x22,0x22,0xEE,0x2A,0x32,0x22,0x22,0x66,0x00, + /* 0xACF6 [?] [1120]*/ + 0x00,0x10,0x10,0x24,0x38,0x20,0x7C,0x11,0x10,0x7C,0x10,0x11,0x14,0x18,0x11,0x00, + 0x00,0x20,0x20,0x24,0xF8,0x20,0x20,0xFE,0x20,0x20,0x24,0xF8,0x20,0x20,0xFE,0x00, + /* 0xACF7 [?] [1121]*/ + 0x00,0x10,0x11,0x25,0x39,0x23,0x7D,0x11,0x11,0x7D,0x13,0x10,0x15,0x19,0x16,0x08, + 0x00,0x90,0x10,0x10,0x14,0xF8,0x10,0x10,0x10,0x10,0xFE,0x90,0x88,0x04,0x02,0x00, + /* 0xACF8 [?] [1122]*/ + 0x00,0x10,0x10,0x25,0x39,0x21,0x7C,0x13,0x11,0x7D,0x11,0x11,0x15,0x19,0x12,0x00, + 0x00,0x00,0x10,0x10,0x10,0xFE,0x10,0x90,0x18,0x24,0x24,0x40,0x80,0x80,0x7E,0x00, + /* 0xACF9 [?] [1123]*/ + 0x00,0x10,0x10,0x3F,0x25,0x44,0x08,0x08,0x3F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x00, + 0x00,0x40,0x40,0xBC,0x10,0x30,0x20,0x26,0xF8,0x20,0x20,0xE0,0x20,0x20,0xC0,0x00, + /* 0xACFA [?] [1124]*/ + 0x00,0x08,0x11,0x29,0x69,0x25,0x19,0x29,0x0D,0x35,0x4D,0x15,0x25,0x05,0x1D,0x02, + 0x00,0x00,0xFC,0x00,0x0C,0x88,0x48,0x30,0x10,0x28,0x4C,0x44,0x80,0x00,0x06,0xF8, + /* 0xACFB [?] [1125]*/ + 0x00,0x00,0x24,0x38,0x28,0x28,0x38,0x29,0x29,0x39,0x28,0x28,0x48,0x49,0x5E,0x88, + 0x00,0x88,0x48,0x50,0xAE,0x24,0xA4,0x78,0x20,0xFE,0x62,0x62,0xAA,0x24,0x20,0x20, + /* 0xACFC [?] [1126]*/ + 0x00,0x08,0x37,0x42,0x4A,0x75,0x20,0x3F,0x24,0x24,0x28,0x28,0x2B,0x10,0x20,0x40, + 0x00,0x00,0xE6,0xBC,0xA4,0xA8,0xB0,0xA8,0xA4,0xA2,0xA2,0xA2,0x2E,0xA4,0x20,0x20, + /* 0xACFD [?] [1127]*/ + 0x00,0x10,0x10,0x10,0x14,0x18,0x50,0x50,0x10,0x10,0x11,0x1D,0x26,0x20,0x40,0x00, + 0x00,0x20,0x20,0x26,0xF8,0x44,0xF8,0x42,0xFC,0x8A,0xFC,0x48,0x08,0x08,0x18,0x00, + /* 0xACFE [?] [1128]*/ + 0x00,0x00,0x12,0x05,0x04,0x44,0x2C,0x2C,0x14,0x14,0x14,0x34,0x25,0x24,0x27,0x00, + 0x00,0x00,0x02,0xFE,0x0A,0xF2,0x42,0x42,0x72,0x52,0x4A,0x4A,0xB2,0x02,0xFE,0x00, + /* 0xADA1 [?] [1129]*/ + 0x00,0x10,0x08,0x40,0x3D,0x08,0x09,0x32,0x15,0x16,0x00,0x1F,0x01,0x0F,0x3F,0x00, + 0x00,0x08,0xF0,0x40,0x84,0xFC,0xA4,0x44,0xC4,0x38,0x04,0xF8,0x08,0xF0,0xFE,0x00, + /* 0xADA2 [?] [1130]*/ + 0x00,0x10,0x10,0x10,0x18,0x14,0x57,0x50,0x11,0x12,0x11,0x12,0x14,0x10,0x10,0x17, + 0x00,0x20,0x20,0x2C,0xF0,0x22,0xDC,0x8C,0x42,0x88,0xF8,0x50,0x20,0x70,0x8E,0x00, + /* 0xADA3 [?] [1131]*/ + 0x00,0x00,0x17,0x00,0x00,0x07,0x14,0x34,0x14,0x13,0x10,0x18,0x17,0x10,0x07,0x00, + 0x00,0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xA4,0x58,0x40,0x44,0xF8,0x40,0xFE,0x00, + /* 0xADA4 [?] [1132]*/ + 0x00,0x00,0x10,0x00,0x03,0x02,0x12,0x33,0x13,0x13,0x15,0x1D,0x15,0x14,0x08,0x00, + 0x00,0x10,0x2C,0x24,0xFE,0x10,0x14,0xF4,0x14,0xF4,0x58,0x48,0xD8,0x26,0x46,0x80, + /* 0xADA5 [?] [1133]*/ + 0x00,0x00,0x11,0x01,0x01,0x01,0x11,0x31,0x10,0x13,0x11,0x1A,0x13,0x14,0x08,0x00, + 0x00,0x00,0xF8,0x08,0xF8,0x08,0x08,0xF0,0x02,0xFC,0x44,0x78,0x40,0xC0,0x3E,0x00, + /* 0xADA6 [?] [1134]*/ + 0x00,0x00,0x10,0x03,0x02,0x03,0x12,0x32,0x13,0x10,0x13,0x19,0x10,0x10,0x03,0x0C, + 0x00,0x40,0xC4,0x4C,0x44,0x5C,0x44,0x44,0xFC,0x48,0xB8,0x10,0xA0,0xE0,0x1E,0x00, + /* 0xADA7 [?] [1135]*/ + 0x00,0x00,0x0C,0x7B,0x4A,0x52,0x55,0x4F,0x48,0x47,0x46,0x4A,0x42,0x40,0x41,0x06, + 0x00,0x00,0x40,0xFC,0x48,0x48,0xF0,0xFE,0x08,0xF8,0x48,0x48,0x48,0xB8,0x0C,0x04, + /* 0xADA8 [?] [1136]*/ + 0x00,0x10,0x10,0x10,0x10,0x6C,0x25,0x24,0x25,0x49,0x49,0x39,0x15,0x20,0x40,0x03, + 0x00,0x20,0x24,0xF8,0x24,0x78,0xFE,0x00,0xFC,0x24,0x24,0x24,0x48,0x48,0x86,0x00, + /* 0xADA9 [?] [1137]*/ + 0x00,0x00,0x10,0x10,0x10,0x2C,0x25,0x26,0x24,0x48,0x29,0x19,0x15,0x21,0x41,0x01, + 0x00,0x20,0x20,0x66,0xB8,0xA8,0x2C,0x26,0x60,0xFC,0x04,0x04,0xFC,0x04,0xFC,0x00, + /* 0xADAA [?] [1138]*/ + 0x00,0x10,0x10,0x11,0x20,0x44,0x78,0x09,0x10,0x25,0x38,0x01,0x05,0x79,0x01,0x00, + 0x00,0x20,0x20,0xFE,0x20,0xFC,0x22,0xDC,0x04,0xFC,0xFC,0x04,0xFC,0x04,0x1C,0x08, + /* 0xADAB [?] [1139]*/ + 0x00,0x00,0x7C,0x08,0x29,0x28,0x28,0x48,0x48,0x34,0x04,0x7F,0x04,0x04,0x38,0x00, + 0x00,0x50,0x50,0x50,0xDE,0x50,0x50,0x52,0xDC,0x50,0x50,0xDC,0x50,0x50,0x50,0x00, + /* 0xADAC [?] [1140]*/ + 0x00,0x00,0x7C,0x09,0x29,0x2A,0x29,0x2A,0x2C,0x17,0x05,0x7D,0x05,0x08,0x18,0x00, + 0x00,0x80,0x80,0x02,0xFE,0x82,0xF2,0x44,0x4C,0xF4,0x4C,0x54,0x54,0xA4,0x1C,0x08, + /* 0xADAD [?] [1141]*/ + 0x00,0x00,0x10,0x10,0x21,0x45,0x79,0x11,0x11,0x21,0x79,0x00,0x09,0x72,0x04,0x00, + 0x00,0x40,0x20,0x26,0xD8,0xFC,0x04,0x04,0x04,0xF8,0x20,0xAC,0x26,0x22,0xE0,0x40, + /* 0xADAE [?] [1142]*/ + 0x00,0x00,0x10,0x13,0x21,0x45,0x79,0x11,0x10,0x21,0x78,0x03,0x0C,0x70,0x01,0x00, + 0x00,0x40,0x40,0xFE,0x08,0xF8,0x08,0xF8,0x0C,0xF8,0x20,0xFE,0x40,0x40,0xC0,0x40, + /* 0xADAF [?] [1143]*/ + 0x00,0x00,0x7C,0x08,0x28,0x28,0x28,0x48,0x49,0x36,0x04,0x7C,0x05,0x05,0x38,0x00, + 0x00,0x00,0xFC,0x08,0xF8,0x08,0x0A,0xF4,0x20,0xB6,0xB8,0xA8,0xA4,0x26,0xE0,0x00, + /* 0xADB0 [?] [1144]*/ + 0x00,0x00,0x07,0x3A,0x12,0x12,0x13,0x7E,0x12,0x13,0x12,0x16,0x7B,0x02,0x00,0x00, + 0x00,0x00,0xE0,0x7E,0x54,0x54,0xD4,0x54,0x54,0xD8,0x48,0x68,0xD4,0x54,0x62,0x00, + /* 0xADB1 [?] [1145]*/ + 0x00,0x00,0x04,0x3B,0x10,0x17,0x10,0x7C,0x10,0x11,0x11,0x16,0x78,0x00,0x01,0x06, + 0x00,0x40,0x40,0xF8,0x40,0xFE,0x24,0xA0,0xA0,0x20,0x20,0xFC,0x40,0x78,0x84,0x00, + /* 0xADB2 [?] [1146]*/ + 0x00,0x00,0x07,0x3A,0x12,0x12,0x12,0x7E,0x12,0x12,0x12,0x16,0x7A,0x02,0x01,0x00, + 0x00,0x00,0xFE,0x04,0xF4,0x24,0xFC,0x34,0x6C,0x6C,0xA4,0x24,0x24,0x04,0xF8,0x00, + /* 0xADB3 [?] [1147]*/ + 0x00,0x00,0x04,0x3B,0x10,0x13,0x11,0x7D,0x17,0x11,0x11,0x15,0x7A,0x00,0x01,0x00, + 0x00,0x08,0x78,0xC0,0x40,0xFC,0x48,0x48,0xFE,0x48,0x48,0x4A,0xF4,0x40,0xFC,0x00, + /* 0xADB4 [?] [1148]*/ + 0x00,0x00,0x05,0x38,0x10,0x11,0x10,0x39,0x12,0x11,0x10,0x10,0x3F,0x40,0x00,0x00, + 0x00,0x08,0xF0,0x20,0x22,0xFC,0xA8,0x26,0x48,0xB8,0x20,0x22,0xFC,0x20,0xE0,0x40, + /* 0xADB5 [?] [1149]*/ + 0x00,0x00,0x04,0x3B,0x10,0x11,0x11,0x7D,0x13,0x15,0x11,0x15,0x79,0x01,0x01,0x00, + 0x00,0x40,0x20,0xFE,0xA0,0x20,0x5C,0x64,0x58,0xC8,0x28,0x30,0x10,0x28,0x46,0x80, + /* 0xADB6 [?] [1150]*/ + 0x00,0x02,0x09,0x31,0x20,0x23,0x2A,0x73,0x22,0x22,0x24,0x2C,0x74,0x08,0x11,0x00, + 0x00,0x10,0x10,0x18,0x58,0xA4,0x26,0xC2,0x90,0x88,0x80,0x80,0x90,0x8C,0x04,0x00, + /* 0xADB7 [?] [1151]*/ + 0x00,0x10,0x11,0x10,0x15,0x3B,0x11,0x11,0x1C,0x73,0x12,0x12,0x12,0x12,0x32,0x02, + 0x00,0x0C,0xF0,0x20,0xFC,0x28,0x28,0xF0,0x22,0xFE,0x24,0x2C,0xD4,0x04,0x04,0x04, + /* 0xADB8 [?] [1152]*/ + 0x00,0x10,0x11,0x10,0x10,0x17,0x39,0x11,0x12,0x10,0x1F,0x11,0x60,0x00,0x00,0x07, + 0x00,0x20,0x48,0xD0,0x44,0xF8,0x48,0x46,0x40,0x80,0xFC,0x10,0xA0,0x78,0x84,0x00, + /* 0xADB9 [?] [1153]*/ + 0x00,0x10,0x10,0x11,0x11,0x15,0x39,0x11,0x11,0x11,0x13,0x1D,0x62,0x02,0x04,0x00, + 0x00,0x20,0x10,0x02,0xFC,0x04,0xF8,0x00,0x82,0xFE,0xB2,0xFE,0xAA,0xAA,0xA2,0x00, + /* 0xADBA [?] [1154]*/ + 0x00,0x10,0x10,0x13,0x14,0x39,0x10,0x1B,0x34,0x53,0x51,0x93,0x13,0x14,0x18,0x10, + 0x00,0x00,0x40,0xFE,0x40,0xFC,0x4A,0xFC,0x48,0xF0,0x40,0x3C,0x40,0xC0,0x7E,0x06, + /* 0xADBB [?] [1155]*/ + 0x00,0x10,0x10,0x13,0x16,0x3A,0x12,0x1A,0x32,0x52,0x52,0x92,0x14,0x14,0x18,0x10, + 0x00,0x04,0x38,0xE0,0x20,0x7C,0x20,0xDC,0x84,0x94,0xA4,0xA4,0xA0,0x4C,0x84,0x00, + /* 0xADBC [?] [1156]*/ + 0x00,0x08,0x0E,0x0B,0x7C,0x08,0x3F,0x49,0x49,0x7F,0x49,0x7F,0x49,0x49,0x0B,0x00, + 0x00,0x00,0x20,0xDC,0xA4,0x94,0x94,0x88,0x80,0x7E,0x02,0xFA,0x02,0x02,0x0E,0x00, + /* 0xADBD [?] [1157]*/ + 0x00,0x00,0x3F,0x01,0x3F,0x21,0x1F,0x40,0x7F,0x52,0x54,0x5F,0x48,0x48,0x41,0x40, + 0x00,0x80,0x26,0x3C,0x24,0x28,0x30,0x28,0xE4,0xA2,0xA2,0xA2,0xAE,0xA4,0xA0,0x20, + /* 0xADBE [?] [1158]*/ + 0x00,0x10,0x10,0x13,0x6D,0x21,0x29,0x51,0x7F,0x11,0x12,0x3C,0x48,0x08,0x09,0x02, + 0x00,0x00,0x60,0x9E,0x04,0x44,0x84,0x04,0xFC,0x50,0x50,0x50,0x50,0x94,0x1E,0x00, + /* 0xADBF [?] [1159]*/ + 0x00,0x08,0x08,0x28,0x2C,0x28,0x7F,0x08,0x08,0x49,0x59,0x55,0x65,0x61,0x5F,0x20, + 0x00,0x00,0x10,0x30,0x48,0x44,0x82,0x24,0x28,0x48,0x48,0x48,0x48,0x88,0x88,0x00, + /* 0xADC0 [?] [1160]*/ + 0x00,0x00,0x09,0x7A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x4B,0x7A,0x02,0x00, + 0x00,0x00,0x82,0x1C,0x04,0x14,0x64,0x44,0x54,0x64,0x44,0x4C,0xB4,0x04,0x0C,0x04, + /* 0xADC1 [?] [1161]*/ + 0x00,0x00,0x48,0x7E,0x4B,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x4A,0x7A,0x42,0x00, + 0x00,0x00,0x82,0x9E,0x04,0x04,0xFC,0x94,0x94,0xF4,0x94,0xF4,0x84,0x04,0x0C,0x04, + /* 0xADC2 [?] [1162]*/ + 0x00,0x00,0x3C,0x44,0x44,0x44,0x38,0x11,0x31,0x5D,0x51,0x51,0x4F,0x70,0x00,0x00, + 0x00,0x00,0xFC,0x88,0xE8,0xA8,0xAA,0xFE,0x48,0x28,0x08,0x0A,0xFC,0x08,0x38,0x10, + /* 0xADC3 [?] [1163]*/ + 0x00,0x08,0x08,0x4A,0x4A,0x4A,0x34,0x7E,0x02,0x02,0x3E,0x20,0x23,0x2C,0x30,0x03, + 0x00,0x00,0xFC,0x20,0xA4,0xDC,0x84,0xA4,0xA4,0xA4,0xA4,0xA0,0x38,0x46,0x82,0x00, + /* 0xADC4 [?] [1164]*/ + 0x00,0x10,0x10,0x24,0x3B,0x20,0x7C,0x10,0x11,0x79,0x11,0x16,0x14,0x18,0x11,0x06, + 0x00,0x20,0x40,0x44,0xF8,0x48,0xF0,0x44,0xB8,0x08,0xF8,0x90,0x60,0x70,0x8E,0x00, + /* 0xADC5 [?] [1165]*/ + 0x00,0x01,0x11,0x21,0x3D,0x43,0x49,0x31,0x23,0x2D,0x35,0x29,0x29,0x11,0x01,0x01, + 0x00,0x00,0x00,0x10,0x10,0x90,0x10,0xFC,0x50,0x50,0x10,0x10,0x10,0x12,0x6C,0x00, + /* 0xADC6 [?] [1166]*/ + 0x00,0x10,0x10,0x24,0x38,0x21,0x7E,0x11,0x10,0x78,0x10,0x13,0x14,0x18,0x10,0x00, + 0x00,0x20,0x58,0x48,0x44,0xB8,0x24,0x64,0x78,0x50,0xC8,0x48,0x46,0x40,0xC0,0x00, + /* 0xADC7 [?] [1167]*/ + 0x00,0x10,0x11,0x15,0x29,0x20,0x3C,0x51,0x11,0x7F,0x11,0x11,0x11,0x1D,0x11,0x00, + 0x00,0x00,0xFC,0x08,0x08,0xF0,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0x1C,0x08, + /* 0xADC8 [?] [1168]*/ + 0x00,0x10,0x10,0x25,0x3B,0x23,0x7C,0x10,0x10,0x78,0x10,0x10,0x15,0x1A,0x1C,0x00, + 0x00,0x40,0x20,0x20,0xDE,0x60,0x40,0x46,0xF8,0xA0,0xA0,0xA0,0x48,0x84,0xFC,0x00, + /* 0xADC9 [?] [1169]*/ + 0x00,0x00,0x14,0x18,0x59,0x5A,0x1C,0x18,0x1E,0x79,0x58,0x29,0x2A,0x24,0x40,0x83, + 0x00,0x00,0xFC,0x20,0xA4,0xDC,0x84,0xA4,0xA4,0xA4,0xA4,0xA0,0x38,0x44,0x82,0x00, + /* 0xADCA [?] [1170]*/ + 0x00,0x00,0x3D,0x2A,0x2A,0x2A,0x3A,0x2A,0x2A,0x3A,0x2A,0x4A,0x4A,0x4A,0x99,0x00, + 0x00,0x00,0x02,0xFC,0x24,0x2C,0x74,0x24,0x74,0xAC,0xA4,0x24,0x04,0x04,0xF8,0x00, + /* 0xADCB [?] [1171]*/ + 0x00,0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x25,0x3C,0x24,0x24,0x24,0x44,0x4C,0x00, + 0x00,0x40,0x20,0x24,0xD8,0x88,0x50,0x50,0xAC,0x00,0xF8,0x88,0x88,0x88,0xF0,0x00, + /* 0xADCC [?] [1172]*/ + 0x00,0x10,0x10,0x1E,0x24,0x7F,0x20,0x2E,0x32,0x32,0x32,0x30,0x53,0x4C,0x00,0x03, + 0x00,0x02,0x7C,0x20,0x22,0xDC,0x84,0x94,0x94,0x94,0x94,0x90,0x28,0x44,0x82,0x00, + /* 0xADCD [?] [1173]*/ + 0x00,0x00,0x10,0x1C,0x28,0x7E,0x2A,0x2B,0x3E,0x2A,0x2A,0x36,0x02,0x3C,0x01,0x02, + 0x00,0x20,0x20,0x30,0x50,0x48,0x86,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x08,0x00, + /* 0xADCE [?] [1174]*/ + 0x00,0x24,0x18,0x28,0x34,0x44,0x18,0x01,0x0F,0x09,0x08,0x08,0x07,0x7F,0x00,0x00, + 0x00,0x04,0xF8,0x48,0xF0,0x40,0xBC,0x00,0xF0,0x10,0x20,0x04,0xFC,0xE4,0x28,0x10, + /* 0xADCF [?] [1175]*/ + 0x00,0x00,0x44,0x38,0x08,0x3B,0x48,0x0B,0x1A,0x19,0x2A,0xCA,0x0B,0x0A,0x3A,0x00, + 0x00,0x60,0x60,0x90,0x88,0xF7,0x00,0xE2,0x54,0xD4,0x54,0x54,0xD4,0x54,0xCC,0x44, + /* 0xADD0 [?] [1176]*/ + 0x00,0x01,0x00,0x10,0x2F,0x24,0x25,0x2A,0x29,0x26,0x25,0x26,0x44,0x45,0x02,0x00, + 0x00,0x00,0x80,0x84,0x78,0x20,0x24,0x5C,0x50,0x10,0x30,0x28,0x28,0x44,0x86,0x00, + /* 0xADD1 [?] [1177]*/ + 0x00,0x10,0x08,0x08,0x2F,0x22,0x2F,0x2A,0x2A,0x2D,0x21,0x27,0x21,0x26,0x20,0x00, + 0x00,0x00,0xFC,0x04,0xF4,0x84,0xF4,0x94,0x94,0xE4,0x14,0xE4,0x14,0xE4,0x1C,0x08, + /* 0xADD2 [?] [1178]*/ + 0x00,0x00,0x08,0x10,0x13,0x15,0x49,0x51,0x11,0x11,0x10,0x1C,0x13,0x20,0x20,0x40, + 0x00,0x00,0xC8,0x50,0xFC,0x24,0x24,0xFC,0x24,0xFC,0x20,0x26,0xF8,0x20,0x20,0x00, + /* 0xADD3 [?] [1179]*/ + 0x00,0x00,0x10,0x08,0x09,0x02,0x25,0x08,0x08,0x10,0x11,0x30,0x11,0x15,0x14,0x00, + 0x00,0x80,0x80,0xF8,0x20,0x24,0xDC,0x04,0xFC,0x04,0xF8,0x28,0x04,0x12,0xF8,0x00, + /* 0xADD4 [?] [1180]*/ + 0x00,0x10,0x11,0x11,0x11,0x2D,0x25,0x24,0x24,0x4B,0x49,0x39,0x15,0x21,0x41,0x00, + 0x00,0x00,0xFC,0x24,0x24,0xFC,0x24,0xDC,0x00,0xFE,0x24,0x28,0x10,0x28,0xC6,0x00, + /* 0xADD5 [?] [1181]*/ + 0x00,0x01,0x11,0x21,0x22,0x7E,0x2E,0x4E,0x4A,0x4A,0x52,0x32,0x1A,0x22,0x42,0x80, + 0x00,0x80,0x02,0x3C,0x10,0xFC,0x94,0x7C,0x94,0x94,0xF8,0x50,0x20,0x30,0x4E,0x80, + /* 0xADD6 [?] [1182]*/ + 0x00,0x00,0x7C,0x08,0x28,0x28,0x48,0x48,0x4E,0x35,0x0C,0x75,0x06,0x28,0x18,0x00, + 0x00,0x20,0x22,0xFC,0x24,0x78,0x26,0xF8,0x22,0xDC,0x80,0xFC,0x84,0x84,0xFC,0x00, + /* 0xADD7 [?] [1183]*/ + 0x00,0x00,0x7C,0x04,0x24,0x28,0x28,0x28,0x47,0x3C,0x0C,0x74,0x05,0x26,0x1A,0x04, + 0x00,0x00,0xFC,0x88,0xF8,0x88,0xF0,0x00,0xFE,0x20,0xA4,0xB8,0xA0,0x60,0x3E,0x00, + /* 0xADD8 [?] [1184]*/ + 0x00,0x00,0x7B,0x08,0x31,0x52,0x52,0x52,0x52,0x29,0x08,0x7B,0x08,0x08,0x39,0x10, + 0x00,0x00,0xDE,0x42,0x8C,0x94,0x94,0x94,0x94,0x4A,0x42,0xDE,0x42,0x42,0xCE,0x84, + /* 0xADD9 [?] [1185]*/ + 0x00,0x00,0x04,0x3F,0x11,0x11,0x16,0x3D,0x1A,0x13,0x12,0x1B,0x62,0x02,0x02,0x00, + 0x00,0x00,0x80,0xFE,0x08,0xF0,0x20,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x08,0x1C,0x08, + /* 0xADDA [?] [1186]*/ + 0x00,0x00,0x00,0x07,0x38,0x10,0x13,0x1A,0x30,0x11,0x11,0x15,0x39,0x41,0x00,0x00, + 0x00,0x40,0x20,0xFC,0x88,0x90,0xFE,0x24,0x44,0xFC,0x48,0x48,0x48,0x48,0x40,0x00, + /* 0xADDB [?] [1187]*/ + 0x00,0x00,0x00,0x7E,0x13,0x10,0x11,0x7A,0x14,0x10,0x11,0x14,0x78,0x41,0x06,0x00, + 0x00,0x40,0x20,0x24,0xDC,0x90,0x0C,0x54,0x48,0x46,0xF8,0xA0,0x90,0x08,0x06,0x00, + /* 0xADDC [?] [1188]*/ + 0x00,0x00,0x1F,0x01,0x7F,0x02,0x0C,0x32,0x02,0x1E,0x02,0x1E,0x02,0x3E,0x02,0x00, + 0x00,0x10,0xE0,0x00,0xFC,0x40,0x38,0x44,0x8C,0xF0,0x88,0xF0,0x86,0x78,0x40,0x00, + /* 0xADDD [?] [1189]*/ + 0x00,0x10,0x10,0x11,0x15,0x38,0x10,0x1F,0x14,0x30,0x51,0x50,0x11,0x12,0x14,0x10, + 0x00,0x40,0x20,0xFC,0x08,0x90,0xA2,0x5C,0x20,0x22,0xFC,0xF0,0xA8,0x26,0x20,0x00, + /* 0xADDE [?] [1190]*/ + 0x00,0x00,0x7E,0x28,0x29,0xFF,0xAC,0xAC,0xAC,0xC5,0x84,0xFC,0x84,0x84,0x78,0x00, + 0x00,0x20,0x20,0x20,0xFE,0x24,0x60,0x50,0xD4,0x98,0x88,0x88,0x84,0xA6,0xC0,0x00, + /* 0xADDF [?] [1191]*/ + 0x00,0x00,0x04,0x38,0x10,0x20,0x27,0x3C,0x65,0x65,0xA5,0x25,0x3D,0x21,0x21,0x00, + 0x00,0x10,0x20,0xA4,0xB8,0xA2,0x5C,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x1C,0x00, + /* 0xADE0 [?] [1192]*/ + 0x00,0x00,0x02,0x3C,0x11,0x11,0x15,0x2D,0x65,0x64,0xA4,0x24,0x1F,0x20,0x00,0x00, + 0x00,0x88,0x48,0x50,0xAE,0x24,0x24,0xFC,0x24,0xF8,0x20,0x22,0xFC,0x20,0x20,0x00, + /* 0xADE1 [?] [1193]*/ + 0x00,0x00,0x04,0x38,0x23,0x24,0x3C,0x24,0x64,0x58,0x08,0x13,0x10,0x20,0x43,0x00, + 0x00,0x10,0x90,0x90,0x9E,0x90,0x90,0x94,0x98,0x90,0x90,0x9C,0x90,0x90,0xFC,0x00, + /* 0xADE2 [?] [1194]*/ + 0x00,0x09,0x10,0x14,0x2B,0x20,0x29,0x4D,0x39,0x09,0x0D,0x79,0x49,0x09,0x09,0x00, + 0x00,0x08,0x88,0x90,0xFE,0x50,0x54,0xFC,0x94,0x9C,0x04,0x04,0xFC,0x04,0xFC,0x00, + /* 0xADE3 [?] [1195]*/ + 0x00,0x08,0x10,0x10,0x2C,0x20,0x28,0x48,0x3F,0x08,0x0D,0x78,0x48,0x09,0x0E,0x00, + 0x00,0x00,0x7C,0x20,0x20,0xFC,0x60,0xA0,0x60,0x20,0xFC,0x70,0xA8,0x2C,0x20,0x20, + /* 0xADE4 [?] [1196]*/ + 0x00,0x04,0x14,0x15,0x04,0x7B,0x41,0x3F,0x21,0x1F,0x04,0x04,0x1F,0x04,0x3B,0x00, + 0x00,0x00,0xBE,0x24,0x64,0xA8,0x28,0x28,0x24,0x22,0x22,0xA2,0x2C,0x20,0x20,0x20, + /* 0xADE5 [?] [1197]*/ + 0x00,0x00,0x07,0x00,0x70,0x52,0x52,0x51,0x50,0x53,0x70,0x46,0x06,0x06,0x01,0x00, + 0x00,0x00,0xFC,0xA0,0xA4,0xA4,0xA8,0xB0,0xA2,0xDC,0x44,0x2A,0x0A,0x08,0xF8,0x00, + /* 0xADE6 [?] [1198]*/ + 0x00,0x00,0x03,0x7A,0x49,0x4A,0x4A,0x7B,0x48,0x4C,0x4F,0x7C,0x04,0x04,0x07,0x00, + 0x00,0x00,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x00,0x04,0xF8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xADE7 [?] [1199]*/ + 0x00,0x08,0x0F,0x08,0x0F,0x1F,0x09,0x05,0x1A,0x02,0x1D,0x06,0x09,0x10,0x63,0x1C, + 0x00,0x10,0xF0,0x10,0xF0,0xE8,0x10,0x30,0xC0,0x0C,0xF0,0x30,0x40,0x80,0x7C,0x00, + /* 0xADE8 [?] [1200]*/ + 0x00,0x00,0x3C,0x44,0x45,0x44,0x38,0x10,0x50,0x58,0x51,0x50,0x54,0x38,0x41,0x06, + 0x00,0x20,0x20,0x24,0xF8,0x24,0xA4,0xA8,0x20,0x26,0xF8,0x50,0x50,0x88,0x06,0x00, + /* 0xADE9 [?] [1201]*/ + 0x00,0x10,0x10,0x13,0x7E,0x56,0x56,0x56,0x56,0x56,0x56,0x5A,0x13,0x15,0x16,0x18, + 0x00,0x04,0x78,0x90,0x20,0x38,0xE6,0xA8,0xF4,0x94,0x88,0xF0,0x50,0x52,0x4A,0x84, + /* 0xADEA [?] [1202]*/ + 0x00,0x10,0x10,0x12,0x2D,0x20,0x3E,0x50,0x10,0x7E,0x10,0x13,0x14,0x18,0x01,0x02, + 0x00,0x08,0x88,0x88,0xFC,0x88,0x78,0x88,0x88,0xF8,0x88,0x74,0x48,0x84,0x02,0x00, + /* 0xADEB [?] [1203]*/ + 0x00,0x00,0x11,0x22,0x3E,0x42,0x4F,0x32,0x12,0x1D,0x32,0x12,0x1A,0x12,0x15,0x00, + 0x00,0x00,0x72,0xDE,0x52,0x52,0xDE,0x52,0x52,0xDE,0x52,0x52,0x52,0x62,0xEE,0x00, + /* 0xADEC [?] [1204]*/ + 0x00,0x10,0x10,0x17,0x29,0x21,0x7D,0x10,0x10,0x3C,0x10,0x11,0x14,0x18,0x10,0x00, + 0x00,0x40,0x20,0xFE,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x20,0xFE,0x20,0x20,0xE0,0x00, + /* 0xADED [?] [1205]*/ + 0x00,0x20,0x22,0x29,0x31,0x45,0x7B,0x21,0x22,0x7A,0x26,0x22,0x22,0x39,0x02,0x00, + 0x00,0x08,0x10,0x10,0x7E,0x50,0x50,0x50,0x6C,0x64,0xA8,0x98,0x98,0x24,0x47,0x80, + /* 0xADEE [?] [1206]*/ + 0x00,0x10,0x10,0x2C,0x28,0x2A,0xFF,0x2A,0x3E,0x2A,0x2A,0x36,0x00,0x3C,0x40,0x00, + 0x00,0x40,0x40,0x40,0xBC,0x84,0x54,0xBC,0x94,0x94,0x94,0x74,0x04,0x04,0x1C,0x00, + /* 0xADEF [?] [1207]*/ + 0x00,0x10,0x10,0x2C,0x29,0x73,0x5E,0x52,0x7E,0x52,0x52,0x2E,0x00,0x3C,0x40,0x00, + 0x00,0x20,0x10,0x22,0xDC,0x00,0x40,0x44,0x4C,0x50,0x60,0x40,0x44,0x44,0x3C,0x00, + /* 0xADF0 [?] [1208]*/ + 0x00,0x00,0x39,0x29,0x29,0x28,0x38,0x29,0x2A,0x38,0x2B,0x29,0x48,0x48,0x58,0x07, + 0x00,0x00,0x4C,0x48,0x50,0xEC,0xD0,0x4C,0x46,0x40,0xFE,0x10,0xD0,0x38,0xC4,0x00, + /* 0xADF1 [?] [1209]*/ + 0x00,0x10,0x08,0x09,0x22,0x2D,0x2A,0x2D,0x22,0x21,0x27,0x25,0x29,0x31,0x20,0x00, + 0x00,0x00,0x04,0xFC,0x04,0xC4,0x44,0xC4,0x44,0x24,0xC4,0x64,0x24,0x04,0x1C,0x08, + /* 0xADF2 [?] [1210]*/ + 0x00,0x10,0x10,0x10,0x14,0x14,0x5B,0x52,0x10,0x11,0x10,0x1C,0x25,0x22,0x4C,0x00, + 0x00,0x10,0x90,0x96,0xF8,0x90,0x6E,0x20,0x40,0xFE,0x60,0xB0,0x28,0x26,0x20,0x20, + /* 0xADF3 [?] [1211]*/ + 0x00,0x00,0x18,0x00,0x04,0x38,0x08,0x17,0x19,0x79,0x15,0x13,0x11,0x10,0x11,0x02, + 0x00,0x20,0x24,0xF8,0x20,0xF8,0x26,0xDC,0x24,0x24,0x24,0x24,0x48,0x48,0x86,0x00, + /* 0xADF4 [?] [1212]*/ + 0x00,0x00,0x3E,0x12,0x13,0x3E,0x12,0x7E,0x10,0x32,0x2E,0x62,0x22,0x1E,0x00,0x01, + 0x00,0x02,0xFC,0x20,0x20,0xDC,0x84,0x94,0x94,0x94,0x94,0x10,0x28,0x26,0xC2,0x00, + /* 0xADF5 [?] [1213]*/ + 0x00,0x00,0x05,0x39,0x29,0x29,0x29,0x29,0x29,0x16,0x0E,0x76,0x0A,0x0A,0x1D,0x00, + 0x00,0x00,0xFE,0x10,0x20,0xDC,0x84,0xFC,0x84,0x7C,0x10,0x5C,0x76,0x92,0x70,0x20, + /* 0xADF6 [?] [1214]*/ + 0x00,0x00,0x04,0x39,0x28,0x28,0x28,0x29,0x28,0x15,0x0C,0x74,0x08,0x08,0x19,0x06, + 0x00,0x04,0xFC,0x24,0xA8,0x30,0x48,0xF0,0x48,0xFC,0x24,0x46,0xF8,0x90,0x0C,0x00, + /* 0xADF7 [?] [1215]*/ + 0x00,0x00,0x10,0x11,0x12,0x16,0x3A,0x12,0x12,0x12,0x16,0x1A,0x62,0x05,0x04,0x00, + 0x00,0x20,0x20,0xFE,0x20,0x78,0x2A,0x7C,0x28,0x30,0xF6,0x68,0xA8,0x24,0xE0,0x00, + /* 0xADF8 [?] [1216]*/ + 0x00,0x00,0x11,0x11,0x11,0x14,0x3B,0x10,0x10,0x11,0x1E,0x11,0x60,0x01,0x00,0x03, + 0x00,0x00,0xFC,0x4C,0x4C,0xDC,0x20,0x60,0x98,0x26,0x40,0x90,0x64,0x98,0x60,0x80, + /* 0xADF9 [?] [1217]*/ + 0x00,0x08,0x11,0x10,0x14,0x3B,0x12,0x1D,0x35,0x31,0x50,0x50,0x10,0x10,0x11,0x06, + 0x00,0x20,0x20,0xA8,0xB0,0x4E,0x08,0xF8,0x08,0x08,0xF8,0x60,0xA0,0xA2,0x12,0x0C, + /* 0xADFA [?] [1218]*/ + 0x00,0x00,0x43,0x7C,0x52,0x52,0x5E,0x5E,0x48,0x76,0x54,0x4D,0x4A,0x72,0x7F,0x00, + 0x00,0x20,0x20,0xDC,0xA4,0x94,0x88,0x98,0x90,0xEE,0x02,0xFC,0x04,0x04,0x0C,0x00, + /* 0xADFB [?] [1219]*/ + 0x00,0x00,0x0C,0x33,0x20,0x20,0x39,0x2A,0x69,0xA8,0xA8,0x2B,0x30,0x20,0x00,0x01, + 0x00,0x20,0x20,0xFE,0x50,0x88,0x46,0xB8,0x10,0x30,0xD2,0x2E,0xE4,0x08,0x30,0xC0, + /* 0xADFC [?] [1220]*/ + 0x00,0x00,0x06,0x3A,0x22,0x22,0x3C,0x28,0x29,0x69,0xA9,0x29,0x30,0x20,0x01,0x06, + 0x00,0x50,0x90,0xA4,0xB8,0xC8,0x84,0x80,0x7C,0x28,0x48,0x50,0x62,0xA2,0x12,0x0C, + /* 0xADFD [?] [1221]*/ + 0x00,0x00,0x07,0x3A,0x22,0x21,0x3C,0x28,0x28,0x69,0xA8,0x28,0x30,0x20,0x00,0x00, + 0x00,0x40,0xDC,0x54,0x54,0xD8,0x00,0xF8,0x02,0xFC,0x84,0x7C,0x04,0x08,0x38,0x00, + /* 0xADFE [?] [1222]*/ + 0x00,0x04,0x04,0x15,0x26,0x24,0x25,0x7A,0x02,0x05,0x1B,0x29,0x0F,0x08,0x1F,0x00, + 0x00,0x60,0x44,0x48,0xF0,0x40,0xC2,0x3E,0x20,0xC0,0x38,0x10,0xF0,0x00,0xFE,0x00, + /* 0xAEA1 [?] [1223]*/ + 0x00,0x00,0x1F,0x10,0x1F,0x0F,0x18,0x08,0x13,0x3C,0x0A,0x11,0x1F,0x24,0x22,0x40, + 0x00,0x00,0xF0,0x10,0xF0,0xF0,0x20,0x20,0x4C,0xF0,0x20,0x48,0xF4,0x88,0x44,0x00, + /* 0xAEA2 [?] [1224]*/ + 0x00,0x10,0x30,0x28,0x37,0x40,0x78,0x20,0x21,0x76,0x20,0x21,0x29,0x31,0x01,0x00, + 0x00,0x10,0x90,0x96,0xF8,0x60,0x60,0x90,0x1E,0xE2,0x08,0xF8,0x08,0x08,0xF8,0x00, + /* 0xAEA3 [?] [1225]*/ + 0x00,0x10,0x10,0x25,0x39,0x21,0x7D,0x11,0x12,0x7E,0x11,0x11,0x15,0x1A,0x14,0x00, + 0x00,0x20,0x40,0xFC,0x08,0xF8,0x08,0x08,0xF0,0xE4,0xD8,0x50,0x48,0x46,0xC0,0x40, + /* 0xAEA4 [?] [1226]*/ + 0x00,0x10,0x10,0x25,0x39,0x22,0x7D,0x13,0x11,0x7D,0x13,0x11,0x15,0x19,0x11,0x00, + 0x00,0x00,0xBC,0x08,0x0A,0x74,0x20,0x3C,0x50,0x90,0xFC,0x18,0x28,0x24,0x42,0x80, + /* 0xAEA5 [?] [1227]*/ + 0x00,0x10,0x11,0x2E,0x45,0x06,0x0F,0x01,0x1E,0x04,0x09,0x72,0x1D,0x06,0x09,0x1E, + 0x00,0x60,0x46,0xB8,0x04,0x20,0xF0,0x00,0xF8,0x40,0xBC,0x40,0x80,0x30,0xC0,0x00, + /* 0xAEA6 [?] [1228]*/ + 0x00,0x0C,0x0A,0x11,0x21,0xDE,0x3F,0x1A,0x29,0x49,0x09,0x01,0x1F,0x01,0x3F,0x00, + 0x00,0x08,0x48,0x28,0x08,0x68,0x4A,0x3C,0x08,0x08,0x08,0x08,0xF0,0x00,0xFE,0x00, + /* 0xAEA7 [?] [1229]*/ + 0x00,0x00,0x7D,0x49,0x48,0x48,0x79,0x49,0x4F,0x79,0x49,0x49,0x49,0x48,0x88,0x07, + 0x00,0x28,0x28,0x50,0xE8,0x46,0xB8,0x06,0xF8,0x28,0x48,0x48,0x48,0x48,0x86,0x02, + /* 0xAEA8 [?] [1230]*/ + 0x00,0x10,0x20,0x39,0x52,0x7E,0x5A,0x5A,0x7A,0x5A,0x5A,0x22,0x05,0x79,0x02,0x04, + 0x00,0x80,0x80,0x9C,0x90,0x92,0xFC,0xD4,0xD4,0xD4,0xD4,0xD4,0x10,0x10,0x10,0x00, + /* 0xAEA9 [?] [1231]*/ + 0x00,0x10,0x10,0x2C,0x28,0x2B,0xFE,0x2A,0x3E,0x2A,0x2B,0x36,0x00,0x3C,0x01,0x02, + 0x00,0x00,0x50,0x50,0x52,0xD4,0xC8,0x50,0x58,0xD6,0x52,0x50,0x52,0x92,0x0E,0x00, + /* 0xAEAA [?] [1232]*/ + 0x00,0x10,0x10,0x2C,0x28,0x2A,0xFF,0x2A,0x3E,0x2A,0x2A,0x36,0x00,0x3D,0x01,0x02, + 0x00,0x20,0x20,0x5C,0x90,0xD2,0xAC,0xA4,0xBC,0xA4,0xA4,0xA4,0xA0,0x22,0x3E,0x00, + /* 0xAEAB [?] [1233]*/ + 0x00,0x10,0x10,0x2C,0x28,0x2B,0xFE,0x2A,0x3E,0x2A,0x2A,0x36,0x00,0x3C,0x00,0x03, + 0x00,0x20,0x10,0xA2,0xDE,0x24,0x20,0x42,0x7C,0x48,0x88,0x70,0x18,0x26,0xC2,0x00, + /* 0xAEAC [?] [1234]*/ + 0x00,0x2A,0x11,0x72,0x1D,0x6A,0x11,0x20,0x01,0x0E,0x09,0x09,0x0F,0x00,0x1F,0x00, + 0x00,0x20,0x24,0x22,0xFC,0x28,0xC4,0x82,0x00,0xF0,0x20,0x20,0xFC,0x24,0xC8,0x18, + /* 0xAEAD [?] [1235]*/ + 0x00,0x20,0x10,0x13,0x7E,0x21,0x21,0x3D,0x25,0x25,0x25,0x24,0x44,0x48,0x98,0x00, + 0x00,0x28,0x2C,0xF0,0x24,0xFC,0x24,0xFC,0x24,0xFC,0x0A,0xFC,0x48,0x48,0x38,0x00, + /* 0xAEAE [?] [1236]*/ + 0x00,0x20,0x10,0x21,0x1E,0x0D,0x12,0x32,0x1B,0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08, + 0x00,0x40,0xC0,0x30,0x1E,0xE0,0x18,0x08,0xF8,0x20,0xFC,0x20,0xE0,0x20,0xE0,0x00, + /* 0xAEAF [?] [1237]*/ + 0x00,0x08,0x04,0x3B,0x3E,0x22,0x3C,0x22,0x3F,0x03,0x01,0x3F,0x02,0x0C,0x30,0x00, + 0x00,0x00,0x04,0xF8,0x78,0x88,0x78,0x88,0x88,0x00,0x02,0xFC,0xA0,0x98,0x84,0x00, + /* 0xAEB0 [?] [1238]*/ + 0x00,0x00,0x10,0x17,0x02,0x03,0x72,0x13,0x12,0x10,0x13,0x1C,0x15,0x15,0x0D,0x00, + 0x00,0x00,0x40,0xF8,0x40,0xFC,0x48,0xF8,0x48,0x48,0xF6,0x82,0x6E,0x0A,0xFA,0x00, + /* 0xAEB1 [?] [1239]*/ + 0x00,0x00,0x18,0x11,0x26,0x44,0x48,0x79,0x11,0x21,0x79,0x01,0x01,0x78,0x01,0x06, + 0x00,0x00,0x20,0xFE,0x04,0x04,0xF8,0x24,0xF8,0x28,0xF8,0x28,0xD8,0x8C,0x02,0x02, + /* 0xAEB2 [?] [1240]*/ + 0x00,0x00,0x00,0x7C,0x13,0x11,0x10,0x14,0x39,0x10,0x13,0x10,0x18,0x60,0x00,0x00, + 0x00,0x04,0xF8,0x22,0xFC,0xAC,0x20,0x20,0xFC,0x02,0xFC,0x84,0x7C,0x08,0x38,0x10, + /* 0xAEB3 [?] [1241]*/ + 0x00,0x00,0x20,0x20,0x27,0x78,0x68,0x69,0x6A,0x78,0x61,0x29,0x2D,0x54,0x00,0x00, + 0x00,0x28,0xA8,0xA8,0xFC,0xA8,0xA8,0xFE,0x24,0x24,0xFC,0x24,0x24,0x2C,0x20,0x20, + /* 0xAEB4 [?] [1242]*/ + 0x00,0x00,0x01,0x21,0x1E,0x08,0x08,0x77,0x3F,0x22,0x3E,0x2A,0x29,0x48,0x09,0x00, + 0x00,0x80,0x04,0x08,0xF0,0x20,0x48,0x48,0xFE,0x50,0x50,0x50,0x90,0x92,0x1E,0x00, + /* 0xAEB5 [?] [1243]*/ + 0x00,0x00,0x10,0x10,0x3D,0x22,0x44,0xB8,0x10,0x14,0x39,0x11,0x11,0x1E,0x11,0x00, + 0x00,0x10,0xD0,0x90,0x28,0x44,0x88,0xF8,0x44,0xCC,0x54,0x54,0xCC,0x74,0xDC,0x00, + /* 0xAEB6 [?] [1244]*/ + 0x00,0x10,0x10,0x3C,0x28,0x53,0xFD,0x55,0x3D,0x54,0x54,0x28,0x00,0x3C,0x41,0x02, + 0x00,0x00,0x40,0x88,0xF0,0x10,0xEE,0x24,0x24,0xFC,0x30,0x50,0x52,0x92,0x1E,0x00, + /* 0xAEB7 [?] [1245]*/ + 0x00,0x10,0x10,0x1C,0x28,0x2B,0x7E,0x2A,0x3E,0x2B,0x2B,0x36,0x00,0x1C,0x21,0x00, + 0x00,0x00,0x40,0x44,0xF8,0x50,0x30,0x28,0xE4,0x10,0xFE,0x20,0x6C,0xA2,0x20,0x00, + /* 0xAEB8 [?] [1246]*/ + 0x00,0x04,0x37,0x15,0x04,0x4C,0x34,0x34,0x16,0x16,0x25,0x24,0x29,0x29,0x2A,0x10, + 0x00,0x02,0xFC,0x48,0xD0,0xAE,0xD0,0xE8,0xC8,0xC8,0x98,0x98,0x18,0x24,0x46,0x00, + /* 0xAEB9 [?] [1247]*/ + 0x00,0x01,0x3F,0x44,0x3F,0x24,0x3F,0x09,0x3E,0x09,0x09,0x08,0x17,0x7F,0x00,0x00, + 0x00,0x00,0xFE,0x4C,0xF0,0x40,0xF8,0x10,0xFE,0x20,0x60,0x04,0xFC,0xE4,0x38,0x00, + /* 0xAEBA [?] [1248]*/ + 0x00,0x00,0x10,0x0F,0x00,0x3C,0x0B,0x0A,0x1A,0x36,0x52,0x12,0x12,0x12,0x12,0x10, + 0x00,0x40,0x20,0xFE,0x90,0xAC,0xD4,0x44,0x7C,0x54,0xB4,0x94,0xF4,0x04,0x1C,0x00, + /* 0xAEBB [?] [1249]*/ + 0x00,0x00,0x13,0x12,0x02,0x01,0x12,0x32,0x11,0x11,0x11,0x10,0x19,0x1E,0x10,0x00, + 0x00,0x00,0xFC,0x94,0x94,0x6C,0x90,0x00,0xF8,0x08,0xFA,0xA4,0x98,0xAC,0xC4,0x80, + /* 0xAEBC [?] [1250]*/ + 0x00,0x10,0x10,0x21,0x21,0x3E,0x2A,0x2D,0x48,0x49,0x4A,0x30,0x18,0x22,0x42,0x80, + 0x00,0x00,0x88,0x34,0xF2,0xB0,0xFC,0x58,0x98,0x24,0x42,0x80,0x94,0x5A,0x40,0x00, + /* 0xAEBD [?] [1251]*/ + 0x00,0x00,0x78,0x48,0x49,0x48,0x48,0x4B,0x7C,0x09,0x19,0x6B,0x08,0x09,0x12,0x04, + 0x00,0x20,0xA4,0xA8,0xFE,0x70,0xAC,0x20,0x80,0xDE,0x78,0x68,0x9E,0x08,0x08,0x00, + /* 0xAEBE [?] [1252]*/ + 0x00,0x00,0x04,0x3B,0x10,0x11,0x11,0x39,0x11,0x10,0x11,0x1F,0x61,0x01,0x00,0x00, + 0x00,0x48,0x92,0xEC,0x84,0x7C,0x84,0x04,0xF8,0xFE,0x22,0x32,0xCA,0x1A,0xFC,0x00, + /* 0xAEBF [?] [1253]*/ + 0x00,0x00,0x07,0x3A,0x13,0x13,0x11,0x3A,0x10,0x11,0x11,0x19,0x61,0x01,0x01,0x01, + 0x00,0x00,0xFE,0x98,0x28,0xDC,0x98,0xF6,0x20,0x0C,0xF8,0x08,0xF8,0x08,0xF8,0x00, + /* 0xAEC0 [?] [1254]*/ + 0x00,0x00,0x0D,0x33,0x24,0x24,0x2C,0x35,0x25,0x25,0x24,0x2A,0x73,0x02,0x02,0x00, + 0x00,0x00,0x7E,0x44,0x4C,0xF4,0x4C,0xFC,0x6C,0x4C,0xF4,0xCC,0x4C,0x04,0x0C,0x00, + /* 0xAEC1 [?] [1255]*/ + 0x00,0x00,0x03,0x39,0x12,0x12,0x12,0x7E,0x12,0x12,0x12,0x1E,0x65,0x04,0x08,0x01, + 0x00,0x00,0xFC,0xFC,0x08,0x78,0x12,0x7C,0x20,0x22,0x44,0x48,0xBC,0x88,0x98,0x80, + /* 0xAEC2 [?] [1256]*/ + 0x00,0x00,0x07,0x3A,0x13,0x12,0x11,0x38,0x10,0x11,0x10,0x18,0x61,0x00,0x03,0x04, + 0x00,0x40,0xFC,0x64,0xBC,0x12,0xDE,0x90,0x90,0xFC,0x90,0x90,0x6C,0xC4,0x02,0x00, + /* 0xAEC3 [?] [1257]*/ + 0x00,0x04,0x04,0x3F,0x0C,0x08,0x3A,0x2C,0x2A,0x1D,0x2A,0x2B,0x4C,0x08,0x30,0x43, + 0x00,0x20,0x46,0xF8,0x44,0xB8,0xC4,0xBC,0x84,0xB4,0xA4,0xA4,0xB4,0x4C,0x82,0x02, + /* 0xAEC4 [?] [1258]*/ + 0x00,0x09,0x12,0x0F,0x01,0x3F,0x21,0x1F,0x3F,0x52,0x3F,0x3F,0x11,0x0F,0x08,0x30, + 0x00,0x00,0xE4,0x3C,0x24,0x28,0x28,0x30,0xE8,0xA4,0xA2,0xA2,0x3E,0x24,0xA0,0x20, + /* 0xAEC5 [?] [1259]*/ + 0x00,0x10,0x10,0x22,0x31,0x20,0x50,0x54,0x7B,0x12,0x12,0x3E,0x51,0x16,0x10,0x00, + 0x00,0x00,0x44,0x28,0x12,0x2C,0x66,0x98,0x30,0x5C,0x2A,0x48,0xB0,0xA0,0x7E,0x00, + /* 0xAEC6 [?] [1260]*/ + 0x00,0x08,0x08,0x28,0x2C,0x28,0x7E,0x10,0x4B,0x52,0x5A,0x66,0x62,0x42,0x5E,0x20, + 0x00,0x20,0x20,0xFC,0x20,0x58,0x88,0x02,0xFC,0x78,0x98,0x98,0x78,0x08,0x08,0x08, + /* 0xAEC7 [?] [1261]*/ + 0x00,0x08,0x08,0x28,0x2C,0x28,0x2B,0x14,0x48,0x52,0x5A,0x5A,0x66,0x62,0x4E,0x71, + 0x00,0x20,0x44,0x84,0x84,0x84,0xC4,0x84,0x84,0xF8,0x50,0x50,0x52,0x52,0x8E,0x00, + /* 0xAEC8 [?] [1262]*/ + 0x00,0x01,0x01,0x78,0x57,0x52,0x53,0x70,0x53,0x52,0x53,0x72,0x43,0x02,0x02,0x00, + 0x00,0x08,0x08,0x50,0x90,0x6C,0xF4,0x54,0x94,0x98,0x98,0x88,0x88,0x94,0xA2,0x40, + /* 0xAEC9 [?] [1263]*/ + 0x00,0x01,0x21,0x21,0x22,0x7A,0x6E,0x6A,0x6A,0x6A,0x32,0x32,0x2A,0x72,0x02,0x02, + 0x00,0x10,0x22,0x7C,0x54,0x88,0xB6,0xC2,0xBC,0xA4,0xBC,0xA4,0xBC,0x24,0x2C,0x00, + /* 0xAECA [?] [1264]*/ + 0x00,0x10,0x10,0x11,0x55,0x7D,0x55,0x55,0x55,0x7D,0x59,0x16,0x3B,0x42,0x04,0x00, + 0x00,0x40,0x24,0xDC,0x04,0xFC,0x00,0xFE,0x24,0xBC,0xA4,0xEC,0x34,0x24,0x6C,0x00, + /* 0xAECB [?] [1265]*/ + 0x00,0x10,0x10,0x13,0x56,0x57,0x56,0x54,0x55,0x54,0x57,0x5C,0x67,0x00,0x03,0x00, + 0x00,0x00,0x92,0xEC,0x80,0x7E,0x0C,0x74,0xE8,0xCC,0x70,0xB8,0x58,0x94,0x70,0x20, + /* 0xAECC [?] [1266]*/ + 0x00,0x00,0x20,0x21,0x23,0x69,0x6E,0x6D,0x6F,0x6D,0x6D,0x5D,0x05,0x04,0x04,0x00, + 0x00,0x00,0x88,0x2E,0xCA,0x0A,0xFC,0xC8,0x4C,0x4C,0x54,0xD4,0x54,0x62,0x62,0x00, + /* 0xAECD [?] [1267]*/ + 0x00,0x10,0x10,0x27,0x38,0x21,0x7C,0x13,0x10,0x7D,0x12,0x10,0x14,0x18,0x13,0x00, + 0x00,0x88,0x88,0xDE,0x88,0xDC,0x88,0xDE,0xA8,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00, + /* 0xAECE [?] [1268]*/ + 0x00,0x10,0x10,0x25,0x38,0x20,0x7F,0x11,0x11,0x7D,0x11,0x11,0x15,0x19,0x12,0x04, + 0x00,0x90,0x90,0xFC,0x90,0x96,0x68,0x24,0xFC,0xFC,0x24,0x24,0xD8,0x84,0x02,0x00, + /* 0xAECF [?] [1269]*/ + 0x00,0x00,0x31,0x2B,0x37,0x41,0x7B,0x25,0x25,0x7D,0x27,0x27,0x2D,0x15,0x04,0x04, + 0x00,0x10,0x10,0x70,0x50,0xAC,0xF4,0x74,0xD4,0xD8,0x48,0x48,0x58,0x54,0xE2,0x00, + /* 0xAED0 [?] [1270]*/ + 0x00,0x18,0x11,0x2F,0x44,0x3F,0x08,0x0F,0x08,0x07,0x38,0x22,0x27,0x21,0x20,0x00, + 0x00,0x40,0x42,0xBC,0x10,0xFC,0x10,0xF0,0x10,0xE0,0x18,0x48,0xF8,0x08,0x38,0x00, + /* 0xAED1 [?] [1271]*/ + 0x00,0x00,0x10,0x20,0x27,0x3D,0x49,0x11,0x11,0x11,0x10,0x10,0x14,0x18,0x11,0x00, + 0x00,0x00,0x20,0x02,0xFC,0x04,0x74,0x54,0x24,0xDC,0xA4,0x88,0xF8,0x80,0xFE,0x00, + /* 0xAED2 [?] [1272]*/ + 0x00,0x10,0x0A,0x14,0x1A,0x12,0x2A,0x4F,0x08,0x09,0x09,0x0F,0x00,0x1F,0x00,0x00, + 0x00,0x40,0xB8,0x40,0xB8,0x70,0x48,0x84,0x70,0x50,0x20,0xFC,0x28,0xD8,0x38,0x00, + /* 0xAED3 [?] [1273]*/ + 0x00,0x20,0x21,0x23,0x10,0x28,0x68,0x67,0x20,0x23,0x22,0x23,0x22,0x22,0x22,0x01, + 0x00,0x00,0x10,0xFC,0x30,0x4C,0xF0,0xFE,0xC8,0x1C,0xE8,0xB4,0xA4,0xA4,0xA6,0x58, + /* 0xAED4 [?] [1274]*/ + 0x00,0x00,0x10,0x21,0x20,0x44,0x7B,0x10,0x21,0x29,0x11,0x01,0x18,0x62,0x00,0x00, + 0x00,0x00,0x20,0xFE,0x90,0x92,0x6C,0xFC,0x08,0xF8,0x00,0x20,0x82,0x82,0xF8,0x00, + /* 0xAED5 [?] [1275]*/ + 0x00,0x00,0x08,0x31,0x23,0x21,0x26,0x7D,0x27,0x25,0x25,0x25,0x3D,0x44,0x04,0x00, + 0x00,0x00,0x88,0x2E,0xCA,0x0A,0xFC,0xC8,0x4C,0x4C,0x54,0xD4,0x54,0x62,0x62,0x00, + /* 0xAED6 [?] [1276]*/ + 0x00,0x00,0x03,0x3E,0x22,0x23,0x21,0x2A,0x32,0x27,0x22,0x21,0x28,0x53,0x00,0x00, + 0x00,0x00,0xFC,0xA4,0xA4,0x5C,0x04,0xFA,0x52,0xF4,0x54,0xF4,0x54,0xAC,0x1C,0x00, + /* 0xAED7 [?] [1277]*/ + 0x00,0x10,0x10,0x27,0x38,0x21,0x44,0x39,0x10,0x14,0x38,0x11,0x15,0x19,0x11,0x00, + 0x00,0x20,0x20,0xFE,0x24,0xD8,0xFC,0x08,0xF8,0x48,0x50,0xAC,0x54,0x08,0x08,0xF0, + /* 0xAED8 [?] [1278]*/ + 0x00,0x10,0x10,0x25,0x39,0x21,0x45,0x38,0x10,0x14,0x38,0x10,0x14,0x1A,0x12,0x00, + 0x00,0x00,0xFE,0xAC,0x6C,0x54,0x24,0xFC,0x24,0xF8,0x20,0xDC,0x94,0x5A,0x4A,0x00, + /* 0xAED9 [?] [1279]*/ + 0x00,0x10,0x11,0x25,0x38,0x20,0x4F,0x30,0x11,0x1F,0x31,0x11,0x15,0x19,0x11,0x00, + 0x00,0x00,0xFC,0x24,0xA8,0x32,0xFC,0xA8,0x26,0x04,0xFC,0x24,0xFC,0x24,0xDC,0x00, + /* 0xAEDA [?] [1280]*/ + 0x00,0x10,0x10,0x24,0x39,0x20,0x4C,0x33,0x11,0x1D,0x33,0x11,0x14,0x19,0x12,0x04, + 0x00,0x20,0xAC,0xB0,0xFC,0x70,0xAE,0x28,0x88,0xDE,0x58,0x68,0xBC,0x08,0x08,0x00, + /* 0xAEDB [?] [1281]*/ + 0x00,0x10,0x10,0x24,0x3B,0x21,0x4D,0x31,0x11,0x1D,0x31,0x10,0x17,0x18,0x10,0x00, + 0x00,0x88,0x90,0x26,0xF8,0x64,0x54,0x9C,0x04,0xFC,0x08,0x0A,0xFC,0x08,0x38,0x00, + /* 0xAEDC [?] [1282]*/ + 0x00,0x00,0x30,0x2B,0x31,0x40,0x78,0x27,0x22,0x7E,0x22,0x22,0x2B,0x13,0x04,0x00, + 0x00,0x00,0x4C,0x30,0x16,0x28,0x22,0xD4,0x28,0x58,0x2E,0x4A,0x88,0x10,0xFE,0x00, + /* 0xAEDD [?] [1283]*/ + 0x00,0x10,0x10,0x24,0x39,0x20,0x4C,0x33,0x11,0x1D,0x31,0x11,0x15,0x19,0x11,0x00, + 0x00,0x04,0xF8,0x20,0xFE,0x64,0xA0,0x60,0xBE,0x4C,0xD4,0x74,0x54,0x24,0x0C,0x04, + /* 0xAEDE [?] [1284]*/ + 0x00,0x00,0x1E,0x2A,0x1A,0x05,0x3E,0x2B,0x2A,0x7F,0x2A,0x2A,0x3E,0x2A,0x34,0x00, + 0x00,0x10,0x20,0x7C,0xA4,0x94,0x84,0x88,0x80,0x7E,0x02,0x0A,0x72,0x02,0x1C,0x00, + /* 0xAEDF [?] [1285]*/ + 0x00,0x10,0x1C,0x24,0x28,0x36,0x7D,0x35,0x3D,0x34,0x35,0x2D,0x02,0x7C,0x00,0x00, + 0x00,0x00,0x84,0xA4,0xDC,0xAC,0xEC,0xAC,0xAC,0xEC,0x4C,0xAC,0x84,0x84,0x8C,0x00, + /* 0xAEE0 [?] [1286]*/ + 0x00,0x10,0x14,0x2D,0x28,0x73,0x5F,0x53,0x7F,0x53,0x53,0x2E,0x00,0x3F,0x02,0x00, + 0x00,0x20,0x20,0xFE,0x20,0x26,0xFC,0x6C,0xB4,0xFC,0x70,0x70,0xA8,0x26,0x20,0x20, + /* 0xAEE1 [?] [1287]*/ + 0x00,0x10,0x14,0x2D,0x29,0x73,0x5F,0x52,0x7E,0x52,0x53,0x2E,0x00,0x3C,0x00,0x03, + 0x00,0x20,0x60,0xAC,0x24,0xA4,0x24,0xFC,0x20,0x24,0xDC,0x48,0x30,0x70,0x8E,0x00, + /* 0xAEE2 [?] [1288]*/ + 0x00,0x10,0x25,0x3D,0x49,0x7F,0x55,0x55,0x7D,0x55,0x7D,0x55,0x56,0x97,0x0F,0x00, + 0x00,0x04,0x78,0x90,0x14,0x18,0xE6,0x94,0xFC,0x96,0xA8,0xB8,0xA8,0x28,0x4A,0x04, + /* 0xAEE3 [?] [1289]*/ + 0x00,0x00,0x3F,0x3E,0x22,0x3E,0x22,0x3E,0x27,0x08,0x11,0x7F,0x11,0x0E,0x3F,0x00, + 0x00,0x00,0xF8,0x80,0xA4,0x78,0x32,0x52,0xCE,0x40,0x88,0x78,0x88,0x78,0xFE,0x00, + /* 0xAEE4 [?] [1290]*/ + 0x00,0x00,0x11,0x12,0x27,0x4A,0x78,0x10,0x20,0x48,0x71,0x05,0x19,0x61,0x01,0x00, + 0x00,0x04,0xF8,0x20,0xFE,0x20,0x20,0x20,0x02,0xFC,0xFE,0x54,0x54,0x54,0x14,0x0C, + /* 0xAEE5 [?] [1291]*/ + 0x00,0x00,0x10,0x10,0x27,0x49,0x31,0x11,0x21,0x48,0x31,0x00,0x1F,0x60,0x02,0x00, + 0x00,0x00,0xF8,0x20,0xFC,0xFC,0xAC,0xB4,0xFC,0x24,0xF8,0x26,0xD8,0x72,0x52,0x00, + /* 0xAEE6 [?] [1292]*/ + 0x00,0x01,0x01,0x0F,0x31,0x10,0x11,0x1E,0x31,0x16,0x18,0x15,0x39,0x41,0x06,0x00, + 0x00,0x08,0x14,0xF8,0x10,0xF0,0x12,0xFC,0x48,0xB6,0x40,0xF8,0x40,0x4C,0xC4,0x40, + /* 0xAEE7 [?] [1293]*/ + 0x00,0x01,0x1E,0x11,0x1F,0x28,0x31,0x2E,0x1F,0x10,0x08,0x77,0x05,0x09,0x31,0x00, + 0x00,0x08,0x30,0xCC,0x30,0xC6,0x78,0x38,0xD0,0x90,0xA0,0xDC,0x20,0x18,0x06,0x00, + /* 0xAEE8 [?] [1294]*/ + 0x00,0x00,0x04,0x3F,0x02,0x1C,0x24,0x24,0x3C,0x7E,0x66,0x5E,0x52,0x52,0x46,0x40, + 0x00,0x20,0x46,0xB8,0x20,0x20,0xD8,0xA8,0x88,0x8C,0x82,0x7E,0x0A,0x74,0x04,0x0C, + /* 0xAEE9 [?] [1295]*/ + 0x00,0x01,0x21,0x23,0x24,0x78,0x69,0x69,0x6A,0x73,0x20,0x2F,0x2D,0x51,0x06,0x00, + 0x00,0x00,0x10,0x9C,0x22,0x44,0xB8,0x10,0x10,0xFC,0x90,0x10,0x3C,0x00,0xF6,0x08, + /* 0xAEEA [?] [1296]*/ + 0x00,0x00,0x3E,0x2C,0x3C,0x2C,0x53,0x42,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x0F,0x00, + 0x00,0x20,0x20,0xFC,0xA4,0xA4,0xFC,0xA4,0xFC,0x38,0x38,0x5C,0x5A,0x92,0x1E,0x00, + /* 0xAEEB [?] [1297]*/ + 0x00,0x08,0x11,0x2E,0x41,0x01,0x0E,0x02,0x3F,0x0F,0x11,0x1F,0x0F,0x01,0x0F,0x3F, + 0x00,0x60,0x46,0xB8,0x10,0x10,0xE0,0x40,0xFC,0xF0,0x10,0xF0,0xF0,0x18,0xE8,0xFC, + /* 0xAEEC [?] [1298]*/ + 0x00,0x10,0x08,0x34,0x14,0x09,0x36,0x49,0x4A,0x7E,0x3E,0x0A,0x3C,0x0B,0x3C,0x00, + 0x00,0x00,0x00,0x7E,0x24,0xA4,0x6C,0x64,0x24,0x2C,0xF4,0x24,0x24,0x24,0x64,0x00, + /* 0xAEED [?] [1299]*/ + 0x00,0x22,0x12,0x14,0x6B,0x4B,0x5D,0x49,0x37,0x02,0x3E,0x22,0x3E,0x22,0x3E,0x00, + 0x00,0x00,0x00,0x7E,0x24,0xA4,0x6C,0x64,0x24,0x2C,0xF4,0x24,0x24,0x24,0x64,0x00, + /* 0xAEEE [?] [1300]*/ + 0x00,0x10,0x10,0x11,0x21,0x3F,0x25,0x24,0x47,0x48,0x49,0x39,0x15,0x21,0x40,0x80, + 0x00,0x50,0x52,0xFC,0xFC,0x54,0x54,0xAA,0x56,0xFC,0x08,0xF8,0x08,0xF8,0xF8,0x00, + /* 0xAEEF [?] [1301]*/ + 0x00,0x00,0x11,0x11,0x27,0x24,0x78,0x08,0x11,0x21,0x3E,0x00,0x05,0x78,0x01,0x00, + 0x00,0x04,0xFC,0x74,0x24,0xF8,0x2C,0xF2,0x0C,0x56,0x42,0x20,0xFC,0x20,0xFE,0x00, + /* 0xAEF0 [?] [1302]*/ + 0x00,0x00,0x04,0x7F,0x0C,0x14,0x2D,0x55,0x75,0x55,0x27,0x05,0x08,0x08,0x10,0x60, + 0x00,0x04,0x04,0xD4,0x54,0x84,0x44,0xD4,0x54,0x46,0xFC,0x04,0x84,0x84,0x04,0x04, + /* 0xAEF1 [?] [1303]*/ + 0x00,0x10,0x13,0x10,0x7B,0x11,0x12,0x3C,0x30,0x50,0x53,0x14,0x10,0x13,0x10,0x00, + 0x00,0x40,0x90,0x9E,0xEA,0xCA,0xD2,0xEE,0x60,0xB8,0x26,0xF8,0x70,0xAC,0xE0,0x00, + /* 0xAEF2 [?] [1304]*/ + 0x00,0x00,0x10,0x10,0x13,0x7C,0x58,0x58,0x58,0x59,0x79,0x19,0x15,0x7D,0x01,0x00, + 0x00,0x00,0xF8,0x22,0xFC,0x20,0x20,0x20,0x04,0xFC,0x24,0xFC,0x24,0x24,0xDC,0x00, + /* 0xAEF3 [?] [1305]*/ + 0x00,0x2A,0x3B,0x2A,0x2A,0x3B,0x2A,0x14,0x14,0x2F,0x5F,0x24,0x1F,0x24,0x3B,0x00, + 0x00,0x80,0xBE,0xA4,0xA4,0xA8,0xA8,0x28,0xA4,0x24,0xA4,0x24,0xBC,0x20,0x20,0x00, + /* 0xAEF4 [?] [1306]*/ + 0x00,0x10,0x1C,0x25,0x28,0x7E,0xB4,0x34,0x3C,0x34,0x34,0x28,0x02,0x7C,0x00,0x00, + 0x00,0x10,0x22,0xFC,0x24,0x58,0xFC,0x84,0xFC,0x48,0x52,0xAC,0xFC,0x84,0xFC,0x00, + /* 0xAEF5 [?] [1307]*/ + 0x00,0x10,0x08,0x3F,0x24,0x19,0x19,0x21,0x41,0x02,0x0C,0x73,0x1F,0x05,0x3F,0x00, + 0x00,0x08,0x34,0xD4,0x78,0xB0,0xC8,0x04,0x04,0x80,0x7E,0x80,0xF8,0x20,0xFE,0x00, + /* 0xAEF6 [?] [1308]*/ + 0x00,0x00,0x10,0x10,0x17,0x19,0x10,0x51,0x11,0x12,0x16,0x2B,0x26,0x23,0x42,0x01, + 0x00,0x00,0xF8,0x42,0xFC,0xD8,0x40,0xC0,0x24,0xF8,0x24,0xF8,0x24,0xF8,0x26,0xD8, + /* 0xAEF7 [?] [1309]*/ + 0x00,0x00,0x10,0x11,0x22,0x4A,0x79,0x10,0x21,0x41,0x78,0x01,0x0C,0x73,0x04,0x00, + 0x00,0x40,0x24,0xD8,0x64,0x64,0xB8,0x94,0xF8,0xFC,0x92,0xEC,0xA8,0x98,0xE6,0x00, + /* 0xAEF8 [?] [1310]*/ + 0x00,0x02,0x02,0x3F,0x26,0x26,0x22,0x2B,0x34,0x28,0x23,0x21,0x10,0x60,0x03,0x04, + 0x00,0x40,0x58,0xAA,0xCC,0xE8,0xA8,0xEE,0xAA,0xD0,0x2C,0x18,0xB0,0x60,0x9C,0x04, + /* 0xAEF9 [?] [1311]*/ + 0x00,0x08,0x10,0x30,0x3F,0x30,0x4F,0x0A,0x52,0x5A,0x5A,0x46,0x42,0x3F,0x01,0x00, + 0x00,0x48,0x88,0x8A,0xFC,0xBC,0xAA,0x08,0x02,0x7C,0xA0,0x9C,0xA0,0x60,0x1E,0x00, + /* 0xAEFA [?] [1312]*/ + 0x00,0x00,0x00,0x79,0x48,0x4B,0x4A,0x79,0x49,0x49,0x4B,0x4D,0x71,0x41,0x01,0x00, + 0x00,0x90,0x90,0xFC,0xA4,0xBC,0xA4,0x98,0x20,0xFC,0x24,0xF8,0x24,0xF8,0xFE,0x00, + /* 0xAEFB [?] [1313]*/ + 0x00,0x00,0x03,0x7A,0x4B,0x4A,0x4A,0x49,0x79,0x49,0x4F,0x4D,0x49,0x71,0x01,0x00, + 0x00,0x00,0xFC,0x64,0xFC,0x64,0x64,0xB8,0x2C,0xF0,0x2C,0xF0,0xFC,0x20,0xFC,0x00, + /* 0xAEFC [?] [1314]*/ + 0x00,0x00,0x03,0x7A,0x4B,0x4A,0x7A,0x49,0x49,0x79,0x4F,0x4D,0x49,0x71,0x01,0x00, + 0x00,0x00,0xFC,0x64,0xFC,0x64,0x64,0xB8,0x2C,0xF0,0x2C,0xF0,0xFC,0x20,0xFC,0x00, + /* 0xAEFD [?] [1315]*/ + 0x00,0x08,0x10,0x10,0x13,0x15,0x49,0x51,0x11,0x11,0x19,0x15,0x13,0x20,0x40,0x00, + 0x00,0x00,0x00,0xFC,0x24,0x24,0x24,0x24,0xD8,0x00,0x00,0x00,0x02,0x82,0x7C,0x00, + /* 0xAEFE [?] [1316]*/ + 0x00,0x00,0x00,0x01,0x49,0x78,0x48,0x48,0x48,0x48,0x49,0x78,0x40,0x40,0x01,0x00, + 0x00,0x20,0x20,0x24,0xA8,0xB0,0x20,0xDC,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x00, + /* 0xAFA1 [?] [1317]*/ + 0x00,0x00,0x00,0x49,0x78,0x48,0x48,0x4B,0x48,0x48,0x78,0x40,0x41,0x03,0x04,0x08, + 0x00,0x00,0x3C,0xC0,0x40,0x40,0x40,0xFC,0x60,0x60,0x90,0x90,0x08,0x0C,0x06,0x00, + /* 0xAFA2 [?] [1318]*/ + 0x00,0x00,0x00,0x1F,0x50,0x30,0x31,0x10,0x31,0x53,0x10,0x10,0x10,0x20,0x40,0x00, + 0x00,0x80,0x80,0x78,0x00,0x08,0xF0,0x80,0x00,0xFC,0x08,0x08,0x10,0x10,0x70,0x00, + /* 0xAFA3 [?] [1319]*/ + 0x00,0x10,0x10,0x10,0x1B,0x1A,0x54,0x51,0x11,0x13,0x15,0x19,0x11,0x11,0x10,0x10, + 0x00,0x20,0x20,0x40,0xFE,0xC4,0xA0,0x24,0xAC,0x10,0x10,0x10,0x08,0x44,0x82,0x00, + /* 0xAFA4 [?] [1320]*/ + 0x00,0x10,0x13,0x22,0x22,0x4F,0x5A,0x72,0x22,0x23,0x73,0x02,0x0E,0x72,0x02,0x00, + 0x00,0x00,0xFE,0x02,0x46,0x66,0x9A,0x8A,0xCA,0x56,0x66,0x22,0x02,0x02,0x06,0x00, + /* 0xAFA5 [?] [1321]*/ + 0x00,0x00,0x10,0x10,0x10,0x11,0x78,0x12,0x12,0x11,0x11,0x19,0x60,0x40,0x07,0x00, + 0x00,0x00,0x88,0x90,0x14,0xF8,0x90,0x96,0x94,0x98,0x98,0x90,0x90,0x90,0xFE,0x00, + /* 0xAFA6 [?] [1322]*/ + 0x00,0x00,0x10,0x10,0x11,0x10,0x7C,0x11,0x11,0x13,0x15,0x15,0x39,0x40,0x00,0x00, + 0x00,0x40,0x40,0x40,0xBC,0xA0,0xA0,0xFE,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x20, + /* 0xAFA7 [?] [1323]*/ + 0x00,0x00,0x08,0x09,0x16,0x12,0x14,0x2F,0x49,0x08,0x7F,0x08,0x08,0x08,0x08,0x00, + 0x00,0x00,0x04,0xF8,0x40,0x48,0x78,0x48,0x68,0x48,0x48,0x48,0x94,0xB4,0xCE,0x00, + /* 0xAFA8 [?] [1324]*/ + 0x00,0x10,0x10,0x10,0x14,0x78,0x10,0x18,0x34,0x30,0x50,0x51,0x11,0x10,0x10,0x10, + 0x00,0x00,0x50,0x50,0x50,0x52,0xD4,0x48,0x50,0x50,0x50,0xD2,0x52,0x52,0x4C,0x00, + /* 0xAFA9 [?] [1325]*/ + 0x00,0x08,0x10,0x10,0x17,0x38,0x10,0x1D,0x14,0x30,0x50,0x53,0x10,0x10,0x10,0x00, + 0x00,0x20,0x20,0x24,0xF8,0x20,0x20,0xF8,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20, + /* 0xAFAA [?] [1326]*/ + 0x00,0x00,0x00,0x1F,0x50,0x30,0x17,0x10,0x72,0x54,0x15,0x19,0x21,0x22,0x44,0x00, + 0x00,0x80,0x40,0xB8,0x80,0x40,0xBC,0xA0,0xA8,0xA4,0x24,0x20,0x20,0x10,0x60,0x00, + /* 0xAFAB [?] [1327]*/ + 0x00,0x00,0x01,0x7F,0x41,0x7F,0x3F,0x09,0x09,0x2B,0x2C,0x28,0x0E,0x10,0x20,0x43, + 0x00,0x20,0x20,0x40,0x44,0x7C,0x98,0x10,0x30,0x30,0x30,0x30,0x48,0x44,0x86,0x00, + /* 0xAFAC [?] [1328]*/ + 0x00,0x10,0x19,0x09,0x01,0x01,0x71,0x11,0x11,0x11,0x11,0x11,0x29,0x46,0x01,0x00, + 0x00,0x00,0x04,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF0,0x00,0x00,0xFC,0x00, + /* 0xAFAD [?] [1329]*/ + 0x00,0x00,0x04,0x38,0x20,0x21,0x24,0x3F,0x67,0x25,0x24,0x25,0x3F,0x21,0x01,0x01, + 0x00,0x88,0x50,0x56,0xA8,0xFC,0x20,0xDC,0x10,0x20,0xDC,0x18,0x10,0x28,0x46,0x80, + /* 0xAFAE [?] [1330]*/ + 0x00,0x00,0x48,0x78,0x4B,0x48,0x79,0x49,0x4A,0x7A,0x4C,0x48,0x78,0x40,0x03,0x04, + 0x00,0x00,0x40,0x40,0xFC,0x40,0x48,0x24,0xAC,0xD0,0x60,0x50,0x90,0x88,0x06,0x00, + /* 0xAFAF [?] [1331]*/ + 0x00,0x00,0x10,0x10,0x21,0x46,0x48,0x78,0x10,0x21,0x78,0x00,0x04,0x38,0x40,0x00, + 0x00,0x40,0x80,0x84,0x78,0x00,0xA0,0xA4,0xFC,0xA4,0xA4,0xAC,0x82,0x82,0xFE,0x00, + /* 0xAFB0 [?] [1332]*/ + 0x00,0x00,0x11,0x11,0x21,0x46,0x48,0x79,0x11,0x23,0x7D,0x01,0x05,0x39,0x41,0x01, + 0x00,0x00,0x24,0x24,0xD8,0xA0,0xD0,0xFE,0x20,0x26,0xF8,0x24,0xF8,0x20,0xDC,0x00, + /* 0xAFB1 [?] [1333]*/ + 0x00,0x04,0x1E,0x30,0x10,0x11,0x3F,0x10,0x1C,0x37,0x52,0x90,0x10,0x11,0x12,0x04, + 0x00,0x10,0x90,0x90,0x94,0x94,0x98,0x90,0x90,0x9C,0x90,0x90,0x92,0x12,0x1E,0x00, + /* 0xAFB2 [?] [1334]*/ + 0x00,0x00,0x7E,0x08,0x7F,0x14,0x2B,0x48,0x16,0x25,0xEA,0x1C,0x3A,0x49,0x08,0x00, + 0x00,0x00,0x0E,0x30,0xD2,0x4C,0x84,0x10,0x6E,0x42,0x42,0x62,0x42,0x42,0x7E,0x00, + /* 0xAFB3 [?] [1335]*/ + 0x00,0x00,0x10,0x10,0x1B,0x56,0x56,0x51,0x12,0x12,0x12,0x11,0x10,0x11,0x12,0x04, + 0x00,0x10,0xA0,0xA4,0xFC,0xA4,0xA4,0xFC,0xA4,0xA4,0xA4,0x58,0x88,0x04,0x02,0x00, + /* 0xAFB4 [?] [1336]*/ + 0x00,0x08,0x08,0x08,0x10,0x10,0x3F,0x50,0x90,0x10,0x11,0x11,0x12,0x12,0x14,0x18, + 0x00,0x80,0x90,0x88,0x88,0x86,0xF8,0xA4,0xAC,0xA8,0x30,0x22,0x62,0xA2,0x3E,0x00, + /* 0xAFB5 [?] [1337]*/ + 0x00,0x10,0x10,0x24,0x38,0x41,0x7E,0x11,0x12,0x79,0x12,0x12,0x19,0x11,0x11,0x00, + 0x00,0x20,0x60,0x50,0x88,0x14,0xE0,0xE4,0x54,0xD4,0x54,0x54,0xC4,0x44,0xCC,0x00, + /* 0xAFB6 [?] [1338]*/ + 0x00,0x10,0x08,0x02,0x3C,0x24,0x14,0x0B,0x34,0x02,0x7E,0x42,0x42,0x3E,0x05,0x06, + 0x00,0x20,0x20,0x24,0x38,0x20,0x20,0xDC,0x88,0x88,0x50,0x50,0x20,0x50,0x8E,0x00, + /* 0xAFB7 [?] [1339]*/ + 0x00,0x14,0x24,0x3E,0x24,0x25,0x1A,0x3E,0x4A,0x3E,0x4A,0x4A,0x34,0x12,0x62,0x00, + 0x00,0x20,0x10,0xEC,0x84,0xFC,0x84,0x78,0x00,0x7C,0x10,0xFC,0x10,0x10,0x70,0x00, + /* 0xAFB8 [?] [1340]*/ + 0x00,0x10,0x30,0x24,0x38,0x40,0x7C,0x90,0x14,0x7C,0x10,0x10,0x14,0x18,0x11,0x00, + 0x00,0x04,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x8A,0x74,0x00, + /* 0xAFB9 [?] [1341]*/ + 0x00,0x00,0x18,0x08,0x20,0x21,0x22,0x2C,0x31,0x20,0x27,0x24,0x23,0x20,0x20,0x00, + 0x00,0x00,0x04,0xFC,0x04,0x84,0x44,0x7C,0x84,0x24,0xC4,0x44,0xC4,0x04,0x1C,0x08, + /* 0xAFBA [?] [1342]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFBB [?] [1343]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFBC [?] [1344]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFBD [?] [1345]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFBE [?] [1346]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFBF [?] [1347]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC0 [?] [1348]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC1 [?] [1349]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC2 [?] [1350]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC3 [?] [1351]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC4 [?] [1352]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC5 [?] [1353]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC6 [?] [1354]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC7 [?] [1355]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC8 [?] [1356]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFC9 [?] [1357]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCA [?] [1358]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCB [?] [1359]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCC [?] [1360]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCD [?] [1361]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCE [?] [1362]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFCF [?] [1363]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD0 [?] [1364]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD1 [?] [1365]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD2 [?] [1366]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD3 [?] [1367]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD4 [?] [1368]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD5 [?] [1369]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD6 [?] [1370]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD7 [?] [1371]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD8 [?] [1372]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFD9 [?] [1373]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDA [?] [1374]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDB [?] [1375]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDC [?] [1376]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDD [?] [1377]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDE [?] [1378]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFDF [?] [1379]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE0 [?] [1380]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE1 [?] [1381]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE2 [?] [1382]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE3 [?] [1383]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE4 [?] [1384]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE5 [?] [1385]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE6 [?] [1386]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE7 [?] [1387]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE8 [?] [1388]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFE9 [?] [1389]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFEA [?] [1390]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFEB [?] [1391]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFEC [?] [1392]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFED [?] [1393]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFEE [?] [1394]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFEF [?] [1395]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF0 [?] [1396]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF1 [?] [1397]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF2 [?] [1398]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF3 [?] [1399]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF4 [?] [1400]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF5 [?] [1401]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF6 [?] [1402]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF7 [?] [1403]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF8 [?] [1404]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFF9 [?] [1405]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFFA [?] [1406]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFFB [?] [1407]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFFC [?] [1408]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFFD [?] [1409]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xAFFE [?] [1410]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB0A1 [?] [1411]*/ + 0x00,0x0E,0xEA,0xAA,0xAA,0xAA,0xAC,0xAA,0xAA,0xAA,0xEA,0xAA,0x0C,0x08,0x08,0x08, + 0x00,0xFC,0x08,0x08,0xE8,0xA8,0xA8,0xA8,0xA8,0xA8,0xE8,0xA8,0x08,0x08,0x28,0x10, + /* 0xB0A2 [?] [1412]*/ + 0x00,0x7D,0x44,0x48,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x50,0x40,0x40,0x40, + 0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xB0A3 [?] [1413]*/ + 0x20,0x20,0x21,0x22,0x27,0xF9,0x21,0x23,0x24,0x20,0x27,0x38,0xE0,0x41,0x02,0x0C, + 0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xB0A4 [?] [1414]*/ + 0x20,0x20,0x21,0x22,0xF7,0x21,0x21,0x23,0x34,0xE0,0x2F,0x20,0x20,0x21,0xA2,0x4C, + 0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xB0A5 [?] [1415]*/ + 0x01,0x01,0x7B,0x49,0x49,0x48,0x4A,0x4A,0x49,0x49,0x78,0x48,0x00,0x01,0x02,0x0C, + 0x10,0x10,0xFC,0x10,0x10,0x00,0x08,0x08,0x10,0x10,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xB0A6 [?] [1416]*/ + 0x00,0x00,0xF1,0x92,0x97,0x91,0x91,0x93,0x94,0x90,0x9F,0xF0,0x90,0x01,0x02,0x0C, + 0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xB0A7 [?] [1417]*/ + 0x02,0x01,0xFF,0x00,0x00,0x1F,0x10,0x10,0x1F,0x02,0x04,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x80,0x44,0x28,0x10,0x08,0x06,0x00, + /* 0xB0A8 [?] [1418]*/ + 0x10,0x11,0x21,0x7D,0x45,0x44,0x45,0x44,0x7C,0x45,0x45,0x45,0x45,0x7D,0x44,0x00, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xB0A9 [?] [1419]*/ + 0x00,0x00,0x1F,0x10,0x93,0x52,0x53,0x10,0x37,0x54,0x97,0x10,0x24,0x24,0x47,0x80, + 0x80,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xBC,0xA4,0xBC,0x40,0x44,0x44,0xFC,0x04, + /* 0xB0AA [?] [1420]*/ + 0x08,0xFF,0x08,0x43,0x22,0x23,0x02,0xE3,0x21,0x23,0x24,0x22,0x2A,0x33,0x20,0x00, + 0x20,0xFE,0x20,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xA4,0x04,0xF4,0x14,0x08, + /* 0xB0AB [?] [1421]*/ + 0x20,0x21,0x3C,0x50,0x93,0x10,0x11,0xFE,0x10,0x13,0x10,0x29,0x24,0x44,0x40,0x81, + 0x1C,0xE0,0x20,0x20,0xFE,0xA8,0x24,0x42,0x40,0xFE,0x88,0x08,0xD0,0x30,0x48,0x84, + /* 0xB0AC [?] [1422]*/ + 0x04,0x04,0xFF,0x04,0x00,0x08,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x40,0x40,0xFE,0x40,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xB0AD [?] [1423]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3C,0x65,0x64,0xA7,0x24,0x25,0x3C,0x24,0x20,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x10,0xFE,0x10,0x10,0x90,0x10,0x50,0x20, + /* 0xB0AE [?] [1424]*/ + 0x00,0x01,0x7E,0x22,0x11,0x7F,0x42,0x82,0x7F,0x04,0x07,0x0A,0x11,0x20,0x43,0x1C, + 0x08,0xFC,0x10,0x10,0x20,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x10,0x20,0xC0,0x30,0x0E, + /* 0xB0AF [?] [1425]*/ + 0x02,0x79,0x49,0x48,0x57,0x50,0x61,0x52,0x4C,0x4B,0x4A,0x6A,0x52,0x42,0x4F,0x40, + 0x08,0x08,0x10,0x00,0xFC,0x00,0x10,0x08,0x04,0xF8,0xA8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xB0B0 [?] [1426]*/ + 0x28,0x28,0xFC,0x2B,0x3A,0x14,0x7C,0x57,0x54,0x7C,0x11,0xFC,0x10,0x10,0x10,0x13, + 0x40,0x20,0x20,0xFE,0x02,0x44,0x40,0xFE,0x88,0x88,0x08,0xD0,0x20,0x50,0x88,0x04, + /* 0xB0B1 [?] [1427]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x04,0x7F,0x40,0x08,0xFF,0x11,0x32,0x0C,0x1B,0x60, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x50,0x10,0xD0,0x12,0x0A,0x0A,0x06,0x82, + /* 0xB0B2 [?] [1428]*/ + 0x02,0x01,0x3F,0x20,0x42,0x02,0x02,0xFF,0x04,0x08,0x18,0x06,0x01,0x02,0x0C,0x70, + 0x00,0x00,0xFC,0x04,0x08,0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0x80,0x60,0x10,0x08, + /* 0xB0B3 [?] [1429]*/ + 0x08,0x08,0x0B,0x11,0x12,0x34,0x33,0x52,0x92,0x13,0x12,0x12,0x13,0x10,0x10,0x10, + 0x40,0x80,0xFC,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xB0B4 [?] [1430]*/ + 0x10,0x10,0x10,0x13,0xFA,0x14,0x10,0x1B,0x30,0xD0,0x11,0x10,0x10,0x10,0x50,0x23, + 0x40,0x20,0x20,0xFE,0x02,0x44,0x40,0xFE,0x88,0x88,0x08,0xD0,0x20,0x50,0x88,0x04, + /* 0xB0B5 [?] [1431]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4F,0x78,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0x80,0x40,0xFC,0x00,0x08,0x90,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB0B6 [?] [1432]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x20,0x2F,0x20,0x20,0x3F,0x20,0x40,0x40,0x80,0x00, + 0x00,0x08,0x08,0xF8,0x00,0xFC,0x00,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80, + /* 0xB0B7 [?] [1433]*/ + 0x00,0x78,0x48,0x4B,0x4A,0x7C,0x48,0x4B,0x48,0x78,0x49,0x48,0x48,0x48,0x48,0x9B, + 0x40,0x20,0x20,0xFE,0x02,0x44,0x40,0xFE,0x88,0x88,0x08,0xD0,0x20,0x50,0x88,0x04, + /* 0xB0B8 [?] [1434]*/ + 0x01,0x7F,0x40,0x04,0xFF,0x08,0x1E,0x03,0x3C,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xFC,0x04,0x00,0xFE,0x20,0x40,0xC0,0x38,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xB0B9 [?] [1435]*/ + 0x00,0x3C,0x24,0x25,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x45,0x55,0x8A, + 0x40,0x20,0x00,0xFC,0x00,0x00,0xF0,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xB0BA [?] [1436]*/ + 0x3F,0x20,0x3F,0x20,0x3F,0x00,0x0C,0x70,0x40,0x40,0x40,0x4C,0x70,0x40,0x00,0x00, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80, + /* 0xB0BB [?] [1437]*/ + 0x01,0x01,0x1F,0x11,0x11,0xFF,0x02,0x0C,0x30,0xC0,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0xF0,0x10,0x10,0xFE,0x80,0x60,0x18,0x06,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xB0BC [?] [1438]*/ + 0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x40,0x7F,0x40, + 0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xC4,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB0BD [?] [1439]*/ + 0x08,0x08,0x08,0x7F,0x08,0x3E,0x08,0xFF,0x10,0x1E,0x12,0x12,0x22,0x2A,0x44,0x81, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xB0BE [?] [1440]*/ + 0x08,0x08,0x7F,0x08,0x7E,0x08,0xFF,0x10,0x1E,0x22,0x46,0x80,0x24,0x22,0x42,0x80, + 0x20,0x20,0x20,0x7E,0x44,0xA4,0x28,0x10,0x28,0x44,0x82,0x00,0x88,0x44,0x44,0x04, + /* 0xB0BF [?] [1441]*/ + 0x10,0x21,0x7C,0x44,0x7D,0x44,0x7C,0x10,0xFE,0x28,0x55,0x92,0x7C,0x10,0x11,0x10, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0x44,0x4C,0xD4,0x64,0x44,0x44,0x44,0x54,0x88, + /* 0xB0C0 [?] [1442]*/ + 0x20,0x10,0x01,0xFC,0x08,0x10,0x11,0x34,0x58,0x94,0x14,0x10,0x10,0x10,0x11,0x12, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFE,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB0C1 [?] [1443]*/ + 0x12,0x12,0x1F,0x22,0x2F,0x62,0xBF,0x24,0x24,0x27,0x24,0x24,0x24,0x29,0x28,0x30, + 0x10,0x10,0xD0,0x20,0xBE,0x44,0xA4,0x24,0x24,0xA8,0xA8,0x90,0xA8,0xA8,0x44,0x82, + /* 0xB0C2 [?] [1444]*/ + 0x02,0x04,0x3F,0x20,0x29,0x25,0x2F,0x25,0x29,0x20,0x01,0xFF,0x02,0x0C,0x30,0xC0, + 0x00,0x00,0xF8,0x08,0x28,0x48,0xE8,0x48,0x28,0x08,0x00,0xFE,0x80,0x60,0x18,0x06, + /* 0xB0C3 [?] [1445]*/ + 0x20,0x21,0x27,0x24,0x35,0xAC,0xA7,0xA4,0xA5,0x24,0x20,0x2F,0x20,0x21,0x22,0x2C, + 0x80,0x00,0xFC,0x44,0x54,0x44,0xFC,0xE4,0x54,0x04,0x40,0xFE,0xA0,0x10,0x08,0x06, + /* 0xB0C4 [?] [1446]*/ + 0x00,0x21,0x17,0x14,0x85,0x44,0x47,0x14,0x15,0x24,0xE0,0x2F,0x20,0x21,0x22,0x0C, + 0x80,0x00,0xFC,0x44,0x54,0x44,0xFC,0xE4,0x54,0x04,0x40,0xFE,0xA0,0x10,0x08,0x06, + /* 0xB0C5 [?] [1447]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xB0C6 [?] [1448]*/ + 0x20,0x27,0x24,0x24,0xFC,0x27,0x22,0x2A,0x37,0xE2,0x22,0x22,0x24,0x24,0xA9,0x50, + 0x04,0xC4,0x44,0x54,0x54,0xD4,0x14,0x14,0xD4,0x54,0x54,0x54,0x44,0x44,0x54,0x88, + /* 0xB0C7 [?] [1449]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD2,0x12,0x12,0x14,0x54,0x28, + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x02, + /* 0xB0C8 [?] [1450]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x4A,0x02,0x04,0x08,0x10, + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x02, + /* 0xB0C9 [?] [1451]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x4A,0x4B,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x01,0x00, + 0x00,0xF8,0x48,0x48,0x48,0x48,0x48,0xF8,0x08,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xB0CA [?] [1452]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x1F, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x02,0xFE, + /* 0xB0CB [?] [1453]*/ + 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x40, + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x02, + /* 0xB0CC [?] [1454]*/ + 0x00,0x00,0x1F,0x10,0x90,0x53,0x52,0x12,0x32,0x52,0x93,0x12,0x22,0x22,0x41,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0xF8,0x00,0x02,0x02,0xFE,0x00, + /* 0xB0CD [?] [1455]*/ + 0x00,0x3F,0x21,0x21,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xB0CE [?] [1456]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x14,0x18,0x31,0xD1,0x11,0x11,0x12,0x12,0x54,0x21, + 0x50,0x48,0x48,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB0CF [?] [1457]*/ + 0x00,0x7C,0x44,0x44,0x47,0x7C,0x10,0x10,0x5D,0x51,0x51,0x51,0x5E,0xE2,0x04,0x01, + 0x50,0x48,0x48,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB0D0 [?] [1458]*/ + 0x28,0x29,0xFD,0x29,0x39,0x11,0x7D,0x55,0x55,0x7D,0x11,0xFD,0x11,0x11,0x10,0x10, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xB0D1 [?] [1459]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x50,0x20, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xB0D2 [?] [1460]*/ + 0x10,0x10,0x11,0xFD,0x11,0x79,0x11,0xFD,0x11,0x39,0x35,0x55,0x91,0x11,0x10,0x10, + 0x00,0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xB0D3 [?] [1461]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1C,0xE0,0x40,0x01,0x06, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x02,0x02, + /* 0xB0D4 [?] [1462]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x22,0x7F,0x22,0x3E,0x08,0x7F,0x49,0x7F,0x08,0xFF,0x08, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x54,0x88, + /* 0xB0D5 [?] [1463]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x04,0x08,0x10,0x3F,0x10, + 0x00,0xFC,0x44,0x44,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x20,0x10,0xF8,0x08, + /* 0xB0D6 [?] [1464]*/ + 0x04,0x08,0x18,0x24,0x03,0x0C,0x30,0xC0,0x1F,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F, + 0x40,0x20,0x50,0x88,0x00,0xC0,0x30,0x0E,0xF0,0x10,0x10,0xF0,0x10,0x04,0x04,0xFC, + /* 0xB0D7 [?] [1465]*/ + 0x01,0x02,0x04,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x3F,0x20, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB0D8 [?] [1466]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB0D9 [?] [1467]*/ + 0x00,0xFF,0x01,0x02,0x04,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20, + 0x00,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB0DA [?] [1468]*/ + 0x10,0x13,0x12,0x12,0xFB,0x10,0x14,0x19,0x30,0xD0,0x17,0x10,0x10,0x11,0x53,0x21, + 0x00,0xFE,0x52,0x52,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x40,0x88,0x04,0xFE,0x02, + /* 0xB0DB [?] [1469]*/ + 0x08,0x0B,0x08,0x10,0x10,0x31,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB0DC [?] [1470]*/ + 0x00,0x7C,0x44,0x54,0x54,0x55,0x56,0x54,0x54,0x54,0x54,0x10,0x28,0x24,0x45,0x82, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xB0DD [?] [1471]*/ + 0x04,0x1E,0xF0,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x11,0x10,0x20,0x20,0x40,0x80, + 0x00,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xB0DE [?] [1472]*/ + 0x08,0x1C,0xF1,0x11,0x11,0xFD,0x11,0x39,0x35,0x54,0x51,0x93,0x10,0x10,0x10,0x10, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xB0DF [?] [1473]*/ + 0x00,0x02,0xF9,0x21,0x2F,0x20,0x24,0xFA,0x22,0x21,0x21,0x3A,0xE2,0x44,0x08,0x00, + 0x00,0x00,0x3E,0x08,0xC8,0x88,0x88,0x88,0xBE,0x08,0x08,0x88,0x88,0x48,0x7E,0x00, + /* 0xB0E0 [?] [1474]*/ + 0x00,0x00,0xF8,0x22,0x22,0x22,0x22,0xFA,0x22,0x24,0x20,0x39,0xE1,0x42,0x04,0x08, + 0x80,0x80,0xBE,0x88,0x88,0x88,0x88,0xBE,0x88,0x88,0x88,0x08,0x08,0x3E,0x00,0x00, + /* 0xB0E1 [?] [1475]*/ + 0x21,0x22,0x27,0x24,0xF6,0x25,0x24,0x2F,0x34,0xE4,0x26,0x25,0x24,0x24,0xA4,0x49, + 0x00,0x3C,0xA4,0xA4,0xA4,0xA4,0xC2,0x80,0xBC,0xA4,0xA4,0xA4,0x94,0x88,0x94,0xA2, + /* 0xB0E2 [?] [1476]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xB0E3 [?] [1477]*/ + 0x08,0x10,0x3E,0x22,0x32,0x2A,0x2A,0xFE,0x22,0x32,0x2A,0x2A,0x22,0x42,0x4A,0x85, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB0E4 [?] [1478]*/ + 0x00,0x29,0x28,0x24,0x45,0x45,0x81,0x7D,0x25,0x25,0x25,0x25,0x24,0x44,0x55,0x8A, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xB0E5 [?] [1479]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xB0E6 [?] [1480]*/ + 0x08,0x48,0x49,0x49,0x49,0x7D,0x41,0x41,0x79,0x49,0x49,0x49,0x49,0x4A,0x4A,0x8C, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xB0E7 [?] [1481]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x12,0x15,0x18,0x30,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xB0E8 [?] [1482]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x11,0x14,0x18,0x30,0xD3,0x10,0x10,0x10,0x50,0x20, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xB0E9 [?] [1483]*/ + 0x08,0x0A,0x09,0x11,0x10,0x37,0x30,0x50,0x90,0x1F,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x44,0x48,0x50,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xB0EA [?] [1484]*/ + 0x40,0x21,0x27,0xFD,0x05,0x55,0x25,0xFD,0x25,0x25,0x75,0x25,0x25,0x49,0x49,0x91, + 0x90,0xC8,0x08,0x3E,0x80,0x54,0x48,0x7E,0x48,0x48,0x5C,0x28,0x08,0x48,0xA8,0x28, + /* 0xB0EB [?] [1485]*/ + 0x01,0x21,0x11,0x09,0x09,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x00,0x08,0x08,0x10,0x20,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xB0EC [?] [1486]*/ + 0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x12,0x12,0x24,0x44,0x08,0x08,0x10,0x20,0x40, + 0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x18,0x14,0x12,0x12,0x10,0x10,0x10,0xA0,0x40, + /* 0xB0ED [?] [1487]*/ + 0x10,0x10,0x21,0x24,0x44,0xF8,0x11,0x20,0x40,0xFC,0x43,0x00,0x1C,0xE0,0x40,0x00, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xB0EE [?] [1488]*/ + 0x08,0x08,0x08,0xFF,0x08,0x08,0x7E,0x08,0x08,0xFF,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xB0EF [?] [1489]*/ + 0x08,0x08,0xFF,0x08,0x7E,0x08,0xFF,0x10,0x20,0x41,0xBF,0x21,0x21,0x21,0x21,0x01, + 0x00,0x7C,0x48,0x50,0x48,0x44,0x54,0x48,0x40,0x00,0xF8,0x08,0x08,0x28,0x10,0x00, + /* 0xB0F0 [?] [1490]*/ + 0x21,0x21,0x21,0x2F,0xF1,0x21,0x27,0x71,0x69,0xAF,0xA1,0x21,0x22,0x22,0x24,0x28, + 0x00,0x1E,0x12,0xD2,0x14,0x14,0xD8,0x14,0x12,0xD2,0x12,0x1A,0x14,0x10,0x10,0x10, + /* 0xB0F1 [?] [1491]*/ + 0x10,0x10,0x13,0x11,0xFC,0x13,0x32,0x3C,0x54,0x53,0x90,0x10,0x10,0x11,0x11,0x12, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xB0F2 [?] [1492]*/ + 0x00,0x78,0x4B,0x49,0x48,0x7B,0x4A,0x4C,0x48,0x7B,0x48,0x48,0x48,0x49,0x49,0x9A, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xB0F3 [?] [1493]*/ + 0x21,0x21,0x21,0x47,0x51,0xF1,0x27,0x21,0x41,0xF7,0x41,0x01,0x31,0xC2,0x02,0x04, + 0x00,0x1E,0x12,0xD2,0x14,0x14,0xD8,0x14,0x12,0xD2,0x12,0x1A,0x14,0x10,0x10,0x10, + /* 0xB0F4 [?] [1494]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x33,0x38,0x55,0x52,0x90,0x10,0x13,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x24,0x22,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xB0F5 [?] [1495]*/ + 0x00,0x00,0xFB,0x21,0x20,0x43,0x7A,0x4C,0xC8,0x4B,0x48,0x48,0x78,0x49,0x01,0x02, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xB0F6 [?] [1496]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x54,0x55,0x7C,0x50,0x10,0x17,0x1C,0xE4,0x40,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xB0F7 [?] [1497]*/ + 0x20,0x20,0x3B,0x21,0x40,0x7B,0xA2,0x24,0xF8,0x23,0x20,0x20,0x28,0x31,0x21,0x02, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xB0F8 [?] [1498]*/ + 0x10,0x10,0x17,0x22,0x21,0x67,0x64,0xA8,0x20,0x27,0x21,0x21,0x21,0x22,0x22,0x24, + 0x80,0x40,0xFC,0x08,0x10,0xFE,0x02,0x84,0x40,0xFC,0x00,0xF8,0x08,0x08,0x28,0x10, + /* 0xB0F9 [?] [1499]*/ + 0x00,0x20,0x13,0x11,0x00,0x03,0xF2,0x14,0x10,0x13,0x10,0x10,0x14,0x19,0x11,0x02, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xB0FA [?] [1500]*/ + 0x04,0x04,0xFF,0x04,0x08,0x1F,0x20,0x5F,0x10,0x10,0x1F,0x10,0x10,0x10,0x0F,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF0,0x10,0x90,0x90,0x90,0x90,0x50,0x24,0x04,0xFC,0x00, + /* 0xB0FB [?] [1501]*/ + 0x00,0x78,0x49,0x49,0x4A,0x7D,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x49,0x48,0x98, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xB0FC [?] [1502]*/ + 0x08,0x08,0x1F,0x10,0x20,0x5F,0x90,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x0F,0x00, + 0x00,0x00,0xF0,0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xB0FD [?] [1503]*/ + 0x01,0xFF,0x08,0x0B,0x12,0x33,0x50,0x97,0x11,0x12,0x03,0x04,0x0C,0x35,0xC6,0x04, + 0x00,0xFE,0x00,0xF8,0x08,0xF8,0x40,0xFE,0x50,0x48,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xB0FE [?] [1504]*/ + 0x00,0x7E,0x02,0x3E,0x02,0xFF,0x08,0x09,0x49,0x2A,0x1C,0x2A,0xC9,0x09,0x28,0x10, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB1A1 [?] [1505]*/ + 0x08,0xFF,0x08,0x00,0x27,0x10,0x13,0x82,0x43,0x4A,0x0B,0x12,0xF0,0x27,0x22,0x21, + 0x20,0xFE,0x20,0x48,0xFC,0x40,0xF8,0x48,0xF8,0x48,0xF8,0x48,0x10,0xFC,0x10,0x30, + /* 0xB1A2 [?] [1506]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x08,0x1F,0x20,0x5F,0x10,0x1F,0x10,0x10,0x0F, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF0,0x10,0x90,0x90,0xD0,0x20,0x04,0xFC, + /* 0xB1A3 [?] [1507]*/ + 0x08,0x0B,0x0A,0x12,0x12,0x33,0x30,0x50,0x97,0x10,0x11,0x12,0x14,0x18,0x10,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x40,0x40,0xFC,0xE0,0x50,0x48,0x44,0x42,0x40,0x40, + /* 0xB1A4 [?] [1508]*/ + 0x08,0x0B,0x12,0x33,0x50,0x97,0x11,0x12,0x14,0x11,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0xF8,0x08,0xF8,0x40,0xFC,0x50,0x48,0x46,0x40,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB1A5 [?] [1509]*/ + 0x20,0x20,0x21,0x39,0x4A,0x55,0x81,0x21,0x21,0x21,0x21,0x21,0x29,0x31,0x20,0x00, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xB1A6 [?] [1510]*/ + 0x02,0x01,0x7F,0x40,0x80,0x00,0x7F,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x20,0x10,0xFE,0x00, + /* 0xB1A7 [?] [1511]*/ + 0x10,0x10,0x11,0x11,0xFA,0x15,0x11,0x19,0x31,0xD1,0x11,0x11,0x11,0x11,0x50,0x20, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xB1A8 [?] [1512]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x00,0xFC,0x04,0x04,0x14,0x08,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB1A9 [?] [1513]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x08,0x7F,0x08,0xFF,0x08,0x31,0xC9,0x05,0x09,0x15,0x22, + 0xF0,0x10,0xF0,0x10,0xF0,0x20,0xFC,0x20,0xFE,0x20,0x18,0x26,0x40,0x20,0x10,0x08, + /* 0xB1AA [?] [1514]*/ + 0x0C,0x30,0xC2,0x14,0x49,0x32,0xC8,0x15,0x24,0xCC,0x14,0x24,0xC4,0x04,0x28,0x10, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xB1AB [?] [1515]*/ + 0x20,0x20,0x7C,0x44,0x89,0x7E,0x54,0x54,0x7C,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x40,0x40,0xFC,0x84,0x04,0xF4,0x94,0x94,0xF4,0x84,0x94,0x88,0x82,0x82,0x7E,0x00, + /* 0xB1AC [?] [1516]*/ + 0x11,0x11,0x11,0x15,0x59,0x50,0x53,0x90,0x17,0x10,0x11,0x2A,0x24,0x40,0x41,0x80, + 0xFC,0x04,0xFC,0x04,0xFC,0x88,0xFE,0x88,0xFE,0x88,0x24,0xAA,0x70,0xA8,0x24,0x60, + /* 0xB1AD [?] [1517]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x38,0x34,0x51,0x52,0x94,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40, + /* 0xB1AE [?] [1518]*/ + 0x00,0x00,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA4,0x25,0x27,0x3C,0x24,0x20,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xB1AF [?] [1519]*/ + 0x04,0x04,0x7C,0x04,0x04,0x3C,0x04,0x04,0x7C,0x04,0x01,0x08,0x48,0x48,0x87,0x00, + 0x40,0x40,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x40,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xB1B0 [?] [1520]*/ + 0x02,0x04,0x3F,0x21,0x21,0x3F,0x22,0x22,0x3F,0x08,0x10,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80,0x80, + /* 0xB1B1 [?] [1521]*/ + 0x04,0x04,0x04,0x04,0x04,0x7C,0x04,0x04,0x04,0x04,0x04,0x04,0x1C,0xE4,0x44,0x04, + 0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xB1B2 [?] [1522]*/ + 0x04,0x7C,0x04,0x3C,0x04,0x7C,0x06,0x02,0x3F,0x05,0x09,0x1F,0x01,0xFF,0x01,0x01, + 0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x00,0xF8,0x00,0x00,0xF0,0x00,0xFE,0x00,0x00, + /* 0xB1B3 [?] [1523]*/ + 0x04,0x04,0x7C,0x04,0x1C,0xE4,0x40,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x80,0x98,0xE0,0x84,0x84,0x7C,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xB1B4 [?] [1524]*/ + 0x00,0x1F,0x10,0x10,0x10,0x11,0x11,0x11,0x11,0x11,0x12,0x02,0x04,0x08,0x10,0x20, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x40,0x20,0x10,0x08, + /* 0xB1B5 [?] [1525]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x10,0x14,0x18,0x11,0x06, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x02,0x02, + /* 0xB1B6 [?] [1526]*/ + 0x08,0x08,0x0B,0x10,0x12,0x31,0x31,0x57,0x90,0x10,0x13,0x12,0x12,0x12,0x13,0x12, + 0x80,0x40,0xFC,0x00,0x08,0x08,0x10,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB1B7 [?] [1527]*/ + 0x00,0x45,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x88,0x08,0x08,0x51,0x26, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x02,0x02, + /* 0xB1B8 [?] [1528]*/ + 0x04,0x04,0x0F,0x18,0x64,0x03,0x1C,0xE0,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x10, + 0x00,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xB1B9 [?] [1529]*/ + 0x08,0x0F,0x10,0x2C,0x03,0x1C,0xE0,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x48,0x48,0x87, + 0x00,0xF0,0x20,0x40,0x80,0x70,0x0E,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x84,0x12,0xF2, + /* 0xB1BA [?] [1530]*/ + 0x10,0x10,0x11,0x10,0x55,0x58,0x50,0x93,0x10,0x10,0x11,0x29,0x25,0x45,0x41,0x81, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB1BB [?] [1531]*/ + 0x20,0x10,0x00,0xF9,0x09,0x11,0x15,0x39,0x55,0x91,0x11,0x11,0x11,0x12,0x12,0x14, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB1BC [?] [1532]*/ + 0x02,0x02,0x7F,0x04,0x09,0x31,0xCF,0x01,0x09,0x08,0x7F,0x08,0x08,0x10,0x10,0x20, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xB1BD [?] [1533]*/ + 0x08,0x08,0xFF,0x08,0x01,0x01,0x7F,0x03,0x05,0x09,0x11,0x2F,0xC1,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xFC,0x80,0x40,0x20,0x10,0xE8,0x06,0x00,0x00,0x00, + /* 0xB1BE [?] [1534]*/ + 0x01,0x01,0x01,0x01,0x7F,0x03,0x05,0x05,0x09,0x11,0x21,0x4F,0x81,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0xFC,0x80,0x40,0x40,0x20,0x10,0x08,0xE4,0x02,0x00,0x00,0x00, + /* 0xB1BF [?] [1535]*/ + 0x10,0x10,0x3F,0x48,0x85,0x01,0x7F,0x03,0x05,0x09,0x11,0x2F,0xC1,0x01,0x01,0x01, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x80,0x40,0x20,0x10,0xE8,0x06,0x00,0x00,0x00, + /* 0xB1C0 [?] [1536]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x4A,0x85, + 0x00,0x08,0x08,0xF8,0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x44,0x94,0x08, + /* 0xB1C1 [?] [1537]*/ + 0x20,0x27,0x24,0x44,0x54,0xF7,0x24,0x24,0x44,0xF7,0x44,0x04,0x34,0xC4,0x0A,0x11, + 0x00,0xBC,0xA4,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0xA4,0xA4,0x4C, + /* 0xB1C2 [?] [1538]*/ + 0x7F,0x01,0x07,0x19,0xE1,0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x41,0x41,0x81, + 0xFC,0x00,0x70,0x0C,0x02,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x28,0x10, + /* 0xB1C3 [?] [1539]*/ + 0x00,0xFF,0x04,0x08,0x1F,0x28,0xC8,0x0F,0x01,0x01,0x7D,0x09,0x11,0x21,0xC5,0x02, + 0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x00,0x04,0x88,0x50,0x20,0x18,0x06,0x00, + /* 0xB1C4 [?] [1540]*/ + 0x00,0x7A,0x4A,0x4B,0x48,0x7B,0x12,0x12,0x53,0x5E,0x52,0x53,0x5A,0xE2,0x05,0x08, + 0x20,0x22,0x22,0xFE,0x00,0xDE,0x52,0x52,0xDE,0x52,0x52,0xDE,0x52,0x52,0x5A,0xA4, + /* 0xB1C5 [?] [1541]*/ + 0x02,0x21,0x10,0x17,0x01,0x01,0xF1,0x17,0x11,0x11,0x12,0x12,0x14,0x28,0x47,0x00, + 0x08,0x10,0x00,0xFC,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x00,0xFE,0x00, + /* 0xB1C6 [?] [1542]*/ + 0x00,0x27,0x10,0x13,0x02,0x03,0xF0,0x17,0x14,0x17,0x14,0x17,0x14,0x28,0x47,0x00, + 0x00,0xFC,0x00,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xFC,0x44,0xFC,0x04,0x00,0xFE,0x00, + /* 0xB1C7 [?] [1543]*/ + 0x02,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x21,0x3F,0x21,0x3F,0x00,0xFF,0x08,0x10, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x20,0x20, + /* 0xB1C8 [?] [1544]*/ + 0x00,0x20,0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0x20,0x20,0x26,0x38,0x20,0x00, + 0x80,0x80,0x80,0x84,0x88,0x90,0xA0,0xC0,0x80,0x80,0x80,0x82,0x82,0x82,0x7E,0x00, + /* 0xB1C9 [?] [1545]*/ + 0x1F,0x11,0x11,0x1F,0x04,0x7F,0x04,0x3F,0x20,0x2E,0x2A,0x2E,0x20,0x3F,0x20,0x00, + 0x00,0x3E,0x22,0x24,0x24,0xE8,0x24,0xA4,0xA2,0xA2,0xA2,0xB4,0xA8,0xA0,0xA0,0x20, + /* 0xB1CA [?] [1546]*/ + 0x10,0x10,0x3F,0x48,0x85,0x00,0x3F,0x01,0x01,0x3F,0x01,0x01,0x7F,0x01,0x01,0x00, + 0x40,0x40,0x7E,0x90,0x08,0xF8,0x00,0x00,0xF8,0x00,0x00,0xFC,0x02,0x02,0x02,0xFE, + /* 0xB1CB [?] [1547]*/ + 0x08,0x08,0x10,0x23,0x4A,0x0A,0x12,0x33,0x52,0x92,0x12,0x12,0x12,0x14,0x14,0x19, + 0x20,0x20,0x20,0xFE,0x22,0x24,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xB1CC [?] [1548]*/ + 0x00,0xFE,0x10,0x7C,0x10,0x1E,0xF0,0x00,0x7F,0x04,0x08,0x3F,0xC8,0x08,0x0F,0x08, + 0x20,0x40,0xFC,0x84,0xFC,0x84,0xFC,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xB1CD [?] [1549]*/ + 0x08,0xFF,0x08,0x02,0x3F,0x24,0x23,0x24,0x3F,0x00,0x20,0x3E,0x20,0x20,0x26,0x38, + 0x20,0xFE,0x20,0x00,0xF8,0x48,0x88,0x48,0xF8,0x00,0x84,0x98,0xE0,0x84,0x84,0x7C, + /* 0xB1CE [?] [1550]*/ + 0x04,0x04,0xFF,0x04,0x08,0x49,0x2A,0x7F,0x49,0x49,0x5D,0x6B,0x49,0x41,0x45,0x42, + 0x40,0x40,0xFE,0x40,0x20,0x20,0x3E,0x44,0xA4,0x24,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB1CF [?] [1551]*/ + 0x20,0x20,0x20,0x3E,0x20,0x20,0x26,0x38,0x21,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x80,0x88,0xB0,0xC0,0x80,0x84,0x84,0x7C,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xB1D0 [?] [1552]*/ + 0x41,0x41,0x7D,0x41,0x4D,0x70,0x00,0xFF,0x10,0x10,0x3E,0x42,0x14,0x08,0x30,0xC0, + 0x00,0x18,0xE0,0x04,0x04,0xFC,0x00,0xFE,0x80,0x88,0x90,0xE0,0x80,0x84,0x84,0x7C, + /* 0xB1D1 [?] [1553]*/ + 0x20,0x20,0x20,0x3E,0x20,0x20,0x26,0x38,0x01,0x00,0x48,0x48,0x89,0x0E,0x18,0xE7, + 0x80,0x88,0xB0,0xC0,0x80,0x84,0x84,0x7C,0x00,0x90,0xA4,0x42,0x82,0x10,0x10,0xF0, + /* 0xB1D2 [?] [1554]*/ + 0x00,0x01,0x7F,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x01,0x01,0x01, + 0x08,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00,0x00, + /* 0xB1D3 [?] [1555]*/ + 0x01,0x00,0x3F,0x20,0x24,0x24,0x24,0x24,0x27,0x24,0x24,0x24,0x45,0x46,0x84,0x00, + 0x00,0x80,0xFE,0x00,0x20,0x20,0x24,0x28,0x30,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xB1D4 [?] [1556]*/ + 0x00,0x00,0x1F,0x10,0x93,0x52,0x53,0x12,0x33,0x50,0x9F,0x11,0x21,0x21,0x42,0x84, + 0x80,0x40,0xFE,0x00,0xF8,0x48,0xF8,0x48,0xF8,0x00,0xFE,0x10,0x10,0x10,0x10,0x10, + /* 0xB1D5 [?] [1557]*/ + 0x20,0x17,0x00,0x40,0x40,0x5F,0x40,0x41,0x42,0x44,0x48,0x50,0x42,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x84,0x84,0xF4,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x14,0x08, + /* 0xB1D6 [?] [1558]*/ + 0x08,0x49,0x29,0x2A,0x08,0x7F,0x49,0x49,0x5D,0x6B,0x49,0x49,0x49,0x41,0x45,0x42, + 0x10,0x10,0x10,0x20,0x3E,0x44,0x24,0x24,0x24,0x28,0x28,0x10,0x28,0x28,0x44,0x82, + /* 0xB1D7 [?] [1559]*/ + 0x08,0x49,0x2A,0x7F,0x49,0x5D,0x6B,0x49,0x43,0x08,0x08,0xFF,0x08,0x10,0x20,0x40, + 0x20,0x20,0x3E,0x48,0x48,0xA8,0x10,0x28,0x46,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xB1D8 [?] [1560]*/ + 0x00,0x04,0x02,0x01,0x01,0x08,0x28,0x28,0x28,0x49,0x4A,0x8C,0x08,0x18,0x27,0x40, + 0x00,0x00,0x10,0x10,0x20,0x20,0x48,0x44,0x84,0x02,0x02,0x12,0x10,0x10,0xF0,0x00, + /* 0xB1D9 [?] [1561]*/ + 0x00,0x7C,0x44,0x45,0x44,0x7C,0x40,0x41,0x7C,0x64,0xA5,0xA4,0x24,0x3C,0x24,0x00, + 0x40,0x20,0x20,0xFC,0x00,0x88,0x50,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xB1DA [?] [1562]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3D,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB1DB [?] [1563]*/ + 0x3E,0x22,0x3E,0x20,0x7E,0xA2,0x3E,0x22,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10, + 0x10,0xFE,0x44,0x28,0xFE,0x10,0xFC,0x10,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x30, + /* 0xB1DC [?] [1564]*/ + 0x00,0x47,0x24,0x24,0x04,0x07,0xE4,0x28,0x2F,0x34,0x24,0x27,0x24,0x50,0x8F,0x00, + 0x10,0x88,0xBE,0x80,0xA2,0x94,0x3E,0x08,0x88,0xBE,0x88,0x88,0x88,0x00,0xFE,0x00, + /* 0xB1DD [?] [1565]*/ + 0x02,0x7A,0x4A,0x53,0x52,0x62,0x52,0x4B,0x48,0x48,0x6B,0x50,0x40,0x40,0x47,0x40, + 0x20,0x24,0x28,0xB0,0x20,0x22,0xA2,0x1E,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xB1DE [?] [1566]*/ + 0x28,0x28,0xFE,0x29,0x39,0x13,0x7D,0x55,0x55,0x7D,0x11,0xFF,0x11,0x11,0x11,0x11, + 0x80,0xFE,0x90,0x7C,0x54,0x54,0x7C,0x54,0x54,0x7C,0x90,0x50,0x20,0x30,0x48,0x86, + /* 0xB1DF [?] [1567]*/ + 0x00,0x20,0x10,0x13,0x00,0x00,0xF0,0x10,0x10,0x11,0x11,0x12,0x14,0x28,0x47,0x00, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x84,0x84,0x04,0x04,0x28,0x10,0x00,0xFE,0x00, + /* 0xB1E0 [?] [1568]*/ + 0x10,0x10,0x23,0x22,0x4A,0xFB,0x12,0x22,0x43,0xFB,0x43,0x05,0x1D,0xE5,0x49,0x01, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x54,0x54,0xFC,0x54,0x54,0x44,0x0C, + /* 0xB1E1 [?] [1569]*/ + 0x00,0x7C,0x45,0x44,0x54,0x54,0x55,0x54,0x54,0x54,0x54,0x10,0x28,0x25,0x42,0x80, + 0x08,0x3C,0xC0,0x00,0x20,0x10,0xFC,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x3E,0x00, + /* 0xB1E2 [?] [1570]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x29,0x29,0x2F,0x49,0x49,0x89,0x08, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0x0C, + /* 0xB1E3 [?] [1571]*/ + 0x10,0x17,0x10,0x27,0x24,0x64,0x67,0xA4,0x24,0x27,0x22,0x21,0x20,0x21,0x22,0x2C, + 0x00,0xFE,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0x80,0x40,0x30,0x0E, + /* 0xB1E4 [?] [1572]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x44,0x00,0x3F,0x08,0x04,0x02,0x01,0x06,0x18,0xE0, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x00,0xF0,0x20,0x40,0x80,0x00,0xC0,0x30,0x0E, + /* 0xB1E5 [?] [1573]*/ + 0x02,0x01,0x01,0x00,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x40,0x20,0x10,0x10,0x00,0x00,0x00,0x00,0x00, + /* 0xB1E6 [?] [1574]*/ + 0x20,0x10,0x10,0x7C,0x00,0x2A,0x12,0xFE,0x12,0x10,0x7C,0x11,0x11,0x22,0x24,0x40, + 0x10,0x88,0x88,0xBE,0x80,0x94,0x88,0xBE,0x88,0x88,0x9C,0x08,0x08,0x08,0x08,0x08, + /* 0xB1E7 [?] [1575]*/ + 0x20,0x12,0x11,0x7D,0x00,0x2B,0x11,0xFD,0x11,0x11,0x7D,0x11,0x11,0x21,0x20,0x40, + 0x10,0x08,0x08,0x3E,0x00,0x14,0x08,0x3E,0x08,0x08,0x1C,0x48,0x88,0x08,0x08,0x08, + /* 0xB1E8 [?] [1576]*/ + 0x20,0x10,0x10,0x7D,0x01,0x2B,0x10,0xFC,0x11,0x13,0x7C,0x10,0x10,0x23,0x20,0x40, + 0x10,0x88,0x88,0x3E,0x40,0xD4,0x88,0xBE,0x08,0xC8,0x1C,0x08,0xC8,0x08,0x08,0x08, + /* 0xB1E9 [?] [1577]*/ + 0x00,0x20,0x13,0x12,0x02,0x03,0xF2,0x13,0x13,0x15,0x15,0x19,0x11,0x11,0x28,0x47, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x54,0x54,0xFC,0x54,0x44,0x0C,0x00,0xFE, + /* 0xB1EA [?] [1578]*/ + 0x10,0x11,0x10,0x10,0xFC,0x13,0x30,0x38,0x55,0x55,0x92,0x12,0x14,0x10,0x10,0x10, + 0x00,0xFC,0x00,0x00,0x00,0xFE,0x20,0x20,0x28,0x24,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xB1EB [?] [1579]*/ + 0x04,0x07,0x04,0x3F,0x24,0x27,0x3C,0x23,0x20,0x2F,0x29,0x29,0x49,0x51,0x90,0x20, + 0x00,0x84,0x04,0xC8,0x50,0x24,0x84,0x88,0x10,0x24,0x04,0x08,0x12,0x22,0xFE,0x00, + /* 0xB1EC [?] [1580]*/ + 0x00,0x7B,0x48,0x49,0x49,0x79,0x49,0x48,0x49,0x78,0x4B,0x48,0x48,0x49,0x4A,0x98, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xB1ED [?] [1581]*/ + 0x01,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x05,0x08,0x18,0x28,0xC9,0x0A,0x0C, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x88,0x50,0x20,0x18,0x06,0x00, + /* 0xB1EE [?] [1582]*/ + 0x49,0x2A,0x7F,0x49,0x5D,0x6B,0x49,0x4F,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF, + 0x20,0x3E,0x48,0x48,0xA8,0x10,0x28,0xC6,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xB1EF [?] [1583]*/ + 0x08,0x49,0x2A,0x7F,0x49,0x5D,0x6B,0x49,0x49,0x43,0x01,0x08,0x48,0x48,0x87,0x00, + 0x20,0x20,0x3E,0x44,0xA4,0x28,0x28,0x10,0x28,0x46,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xB1F0 [?] [1584]*/ + 0x00,0x7F,0x41,0x41,0x41,0x7F,0x10,0x10,0xFF,0x11,0x11,0x11,0x21,0x21,0x4A,0x84, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB1F1 [?] [1585]*/ + 0x00,0x3F,0x21,0x27,0xA4,0x67,0x24,0x27,0x64,0xA7,0x21,0x26,0x3A,0x43,0x42,0x81, + 0x80,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x18,0x66,0x88,0x08,0xF8, + /* 0xB1F2 [?] [1586]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x30,0x39,0x55,0x52,0x92,0x14,0x10,0x10,0x10,0x10, + 0x82,0x82,0x84,0x88,0xD0,0x82,0x82,0xC4,0xA8,0x90,0x82,0x82,0x84,0x88,0x90,0xA0, + /* 0xB1F3 [?] [1587]*/ + 0x00,0x20,0x11,0x00,0xFC,0x0B,0x08,0x48,0x28,0x12,0x12,0x2A,0x2A,0x4A,0x87,0x02, + 0x10,0x14,0xD2,0x12,0x10,0xFE,0x10,0x90,0x90,0xD0,0x90,0x90,0x8A,0xEA,0x06,0x02, + /* 0xB1F4 [?] [1588]*/ + 0x42,0x22,0x2A,0x8B,0x4A,0x4A,0x1F,0x20,0x22,0x4A,0xCA,0x4B,0x51,0x42,0x44,0x18, + 0x00,0x7E,0x10,0xA0,0x7C,0x44,0xD4,0x54,0x54,0xD4,0xD4,0x54,0x20,0x28,0x44,0x82, + /* 0xB1F5 [?] [1589]*/ + 0x00,0x20,0x17,0x14,0x88,0x43,0x4A,0x0A,0x13,0x12,0xE2,0x2F,0x20,0x21,0x22,0x04, + 0x80,0x40,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x10,0x08,0x04, + /* 0xB1F6 [?] [1590]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x10,0x10,0x1F,0x10,0x10,0xFF,0x00,0x08,0x10,0x20, + 0x00,0x00,0xFE,0x02,0x74,0x80,0x00,0x00,0xF8,0x80,0x80,0xFE,0x00,0x40,0x20,0x10, + /* 0xB1F7 [?] [1591]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x11,0x15,0x19,0x31,0xD1,0x17,0x10,0x10,0x51,0x22, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xB1F8 [?] [1592]*/ + 0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0xFF,0x00,0x08,0x10,0x20,0x40, + 0x20,0xF0,0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0xFE,0x00,0x40,0x20,0x10,0x08, + /* 0xB1F9 [?] [1593]*/ + 0x00,0x40,0x20,0x20,0x00,0x07,0x11,0x11,0x21,0xE2,0x22,0x24,0x28,0x20,0x21,0x00, + 0x40,0x40,0x40,0x44,0x68,0x70,0x60,0x50,0x50,0x48,0x48,0x44,0x42,0x40,0x40,0x80, + /* 0xB1FA [?] [1594]*/ + 0x10,0x13,0x10,0x10,0xFC,0x13,0x32,0x3A,0x56,0x52,0x92,0x13,0x12,0x12,0x12,0x12, + 0x00,0xFE,0x20,0x20,0x20,0xFE,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xB1FB [?] [1595]*/ + 0x00,0xFF,0x01,0x01,0x01,0x7F,0x41,0x41,0x42,0x42,0x44,0x48,0x40,0x40,0x40,0x40, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x84,0x44,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB1FC [?] [1596]*/ + 0x00,0x3F,0x01,0x7F,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0xF8,0x00,0x00,0xFC,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xB1FD [?] [1597]*/ + 0x21,0x20,0x20,0x38,0x4B,0x50,0x80,0x20,0x20,0x27,0x20,0x20,0x29,0x31,0x22,0x04, + 0x04,0x84,0x88,0x00,0xFE,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xB1FE [?] [1598]*/ + 0x10,0x13,0x10,0x14,0x58,0x53,0x52,0x92,0x12,0x12,0x12,0x2B,0x26,0x42,0x42,0x82, + 0x00,0xFE,0x20,0x20,0x20,0xFE,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xB2A1 [?] [1599]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x37,0x54,0x94,0x15,0x26,0x24,0x44,0x84, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x40,0x40,0xFC,0x44,0xA4,0x14,0x14,0x04,0x14,0x08, + /* 0xB2A2 [?] [1600]*/ + 0x10,0x08,0x08,0x00,0x7F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x10,0x10,0x20,0x40, + 0x10,0x10,0x20,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xB2A3 [?] [1601]*/ + 0x00,0x00,0xF8,0x23,0x22,0x22,0x22,0xFB,0x22,0x22,0x22,0x3A,0xE2,0x44,0x04,0x09, + 0x20,0x20,0x20,0xFE,0x22,0x24,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xB2A4 [?] [1602]*/ + 0x04,0x04,0xFF,0x04,0x20,0x10,0x13,0x82,0x42,0x4B,0x0A,0x12,0xE2,0x24,0x24,0x29, + 0x40,0x40,0xFE,0x40,0x20,0x20,0xFC,0x24,0x20,0xF8,0x88,0x88,0x50,0x20,0x50,0x8C, + /* 0xB2A5 [?] [1603]*/ + 0x20,0x27,0x22,0x21,0xFB,0x21,0x22,0x2C,0x33,0xE2,0x22,0x23,0x22,0x22,0xA3,0x42, + 0x78,0xC0,0x48,0x50,0xFC,0x50,0x48,0x06,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x08, + /* 0xB2A6 [?] [1604]*/ + 0x10,0x10,0x12,0x12,0xFB,0x10,0x14,0x18,0x31,0xD1,0x11,0x12,0x12,0x14,0x58,0x23, + 0x40,0x48,0x44,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xB2A7 [?] [1605]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBC,0x10,0x10,0xFD,0x11,0x12,0x10,0x14,0x18,0x10,0x00, + 0x20,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0xF8,0x20,0x20,0x20,0x20, + /* 0xB2A8 [?] [1606]*/ + 0x00,0x20,0x10,0x13,0x82,0x42,0x4A,0x0B,0x12,0x12,0xE2,0x22,0x22,0x24,0x24,0x09, + 0x20,0x20,0x20,0xFE,0x22,0x24,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xB2A9 [?] [1607]*/ + 0x20,0x20,0x2F,0x20,0x27,0xFC,0x27,0x24,0x27,0x24,0x20,0x2F,0x22,0x21,0x21,0x20, + 0x50,0x48,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x08,0xFE,0x08,0x08,0x28,0x10, + /* 0xB2AA [?] [1608]*/ + 0x08,0x08,0x7F,0x08,0x08,0x7F,0x41,0x82,0x3C,0x04,0x08,0x0F,0x78,0x08,0x29,0x12, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xB2AB [?] [1609]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x11,0x15,0x19,0x31,0xD0,0x13,0x10,0x10,0x50,0x20, + 0x28,0x24,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x08,0xFE,0x88,0x48,0x48,0x18, + /* 0xB2AC [?] [1610]*/ + 0x10,0x10,0x3C,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB2AD [?] [1611]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x09,0x49,0x21,0x25,0x05,0x09,0x71,0x11,0x11,0x11, + 0x40,0x40,0x7E,0x90,0x28,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB2AE [?] [1612]*/ + 0x08,0x08,0x08,0x13,0x12,0x32,0x32,0x52,0x93,0x12,0x12,0x12,0x12,0x12,0x13,0x12, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB2AF [?] [1613]*/ + 0x01,0x02,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xB2B0 [?] [1614]*/ + 0x08,0x10,0x3E,0x22,0x32,0x2A,0x2A,0xFE,0x22,0x32,0x2A,0x2A,0x22,0x42,0x4A,0x84, + 0x10,0x10,0x20,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xB2B1 [?] [1615]*/ + 0x00,0x78,0x4B,0x48,0x48,0x7B,0x4A,0x4C,0x49,0x78,0x48,0x4B,0x48,0x48,0x48,0x98, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x02,0x04,0xF8,0x10,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xB2B2 [?] [1616]*/ + 0x00,0x78,0x4B,0x48,0x49,0x79,0x49,0x49,0x49,0x79,0x48,0x4B,0x48,0x48,0x48,0x98, + 0x28,0x24,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x08,0xFE,0x88,0x48,0x48,0x18, + /* 0xB2B3 [?] [1617]*/ + 0x02,0x82,0x5F,0x02,0x82,0x5F,0x50,0x20,0x2F,0x41,0xC2,0x43,0x5E,0x42,0x4A,0x04, + 0x10,0x10,0xD0,0x10,0x3E,0xD2,0x52,0x92,0x12,0x12,0x12,0x92,0x22,0x22,0x4A,0x84, + /* 0xB2B4 [?] [1618]*/ + 0x00,0x20,0x10,0x13,0x82,0x42,0x4A,0x0A,0x13,0x12,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB2B5 [?] [1619]*/ + 0x00,0xF8,0x08,0x48,0x48,0x48,0x49,0x7C,0x04,0x04,0x1C,0xE4,0x44,0x04,0x28,0x13, + 0x08,0x88,0x50,0x20,0x50,0x88,0x00,0x08,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xB2B6 [?] [1620]*/ + 0x10,0x10,0x17,0x10,0xFC,0x13,0x12,0x16,0x1B,0x32,0xD2,0x13,0x12,0x12,0x52,0x22, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xB2B7 [?] [1621]*/ + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB2B8 [?] [1622]*/ + 0x00,0x00,0xF7,0x90,0x90,0x93,0x92,0x92,0x93,0x92,0xF2,0x93,0x02,0x02,0x02,0x02, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xB2B9 [?] [1623]*/ + 0x10,0x08,0x00,0x7E,0x02,0x04,0x08,0x1A,0x2C,0x4A,0x0A,0x08,0x08,0x08,0x08,0x08, + 0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xB2BA [?] [1624]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x10,0x1C,0xE3,0x40,0x00,0x00,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xB2BB [?] [1625]*/ + 0x00,0x7F,0x00,0x00,0x01,0x01,0x03,0x05,0x09,0x11,0x21,0x41,0x81,0x01,0x01,0x01, + 0x00,0xFC,0x80,0x80,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x04,0x00,0x00,0x00,0x00, + /* 0xB2BC [?] [1626]*/ + 0x02,0x02,0x02,0xFF,0x04,0x09,0x11,0x3F,0x51,0x91,0x11,0x11,0x11,0x11,0x01,0x01, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xB2BD [?] [1627]*/ + 0x01,0x01,0x11,0x11,0x11,0x11,0xFF,0x01,0x01,0x11,0x11,0x21,0x40,0x03,0x1C,0xE0, + 0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x08,0x10,0x20,0xC0,0x00,0x00,0x00, + /* 0xB2BE [?] [1628]*/ + 0x20,0x3F,0x48,0x85,0x27,0x10,0x13,0x82,0x43,0x4A,0x0B,0x12,0xF0,0x27,0x22,0x21, + 0x40,0x7E,0x90,0x48,0xFC,0x40,0xF8,0x48,0xF8,0x48,0xF8,0x48,0x10,0xFC,0x10,0x30, + /* 0xB2BF [?] [1629]*/ + 0x10,0x08,0x7F,0x00,0x21,0x12,0xFF,0x00,0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x00, + 0x00,0x3E,0xA2,0x24,0x24,0x28,0xE4,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xB2C0 [?] [1630]*/ + 0x10,0x10,0x10,0x13,0x18,0x54,0x51,0x51,0x93,0x15,0x11,0x11,0x11,0x11,0x10,0x10, + 0x40,0x40,0x40,0xFE,0x80,0xA0,0x20,0xFC,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xB2C1 [?] [1631]*/ + 0x20,0x20,0x27,0x24,0xFA,0x23,0x24,0x2A,0x35,0xE2,0x24,0x2B,0x20,0x22,0xA4,0x40, + 0x80,0x40,0xFE,0x02,0x24,0xBC,0xA4,0xA8,0x10,0xE8,0x04,0xFA,0x40,0x48,0x44,0xC0, + /* 0xB2C2 [?] [1632]*/ + 0x00,0x44,0x2B,0x10,0x29,0x48,0x8B,0x08,0x19,0x29,0x49,0x89,0x09,0x09,0x51,0x21, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xB2C3 [?] [1633]*/ + 0x08,0x08,0x7F,0x08,0x08,0xFF,0x10,0x08,0xFF,0x10,0x29,0x66,0xA2,0x29,0x30,0x20, + 0x40,0x48,0x44,0x44,0x40,0xFE,0x40,0x44,0x44,0x44,0x28,0x2A,0x12,0x2A,0x46,0x82, + /* 0xB2C4 [?] [1634]*/ + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x18,0x28,0x28,0x48,0x88,0x08,0x08,0x28,0x10, + /* 0xB2C5 [?] [1635]*/ + 0x00,0x00,0x00,0x00,0xFF,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40,0x02,0x01, + 0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + /* 0xB2C6 [?] [1636]*/ + 0x00,0x7C,0x44,0x54,0x55,0x54,0x54,0x54,0x54,0x54,0x54,0x11,0x28,0x24,0x44,0x80, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x30,0x30,0x50,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xB2C7 [?] [1637]*/ + 0x00,0x00,0x7B,0x48,0x4A,0x79,0x49,0x48,0x7B,0x48,0x48,0x48,0x79,0x4A,0x04,0x00, + 0x08,0x3C,0xC0,0x44,0x24,0x28,0x00,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20, + /* 0xB2C8 [?] [1638]*/ + 0x00,0x7C,0x45,0x44,0x45,0x7C,0x10,0x10,0x5D,0x50,0x50,0x50,0x5D,0xE2,0x04,0x00, + 0x08,0x3C,0xC0,0x44,0x24,0xA8,0x80,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20, + /* 0xB2C9 [?] [1639]*/ + 0x00,0x00,0x3F,0x02,0x11,0x09,0x08,0x01,0x7F,0x03,0x05,0x09,0x11,0x21,0xC1,0x01, + 0x10,0xF8,0x00,0x00,0x10,0x10,0x20,0x00,0xFC,0x80,0x40,0x20,0x10,0x08,0x06,0x00, + /* 0xB2CA [?] [1640]*/ + 0x01,0x07,0x78,0x08,0x44,0x25,0x20,0x04,0x7F,0x0C,0x16,0x15,0x24,0x44,0x84,0x04, + 0x00,0x84,0x04,0x88,0x90,0x22,0x02,0x04,0x88,0x10,0x22,0x02,0x84,0x08,0x10,0x60, + /* 0xB2CB [?] [1641]*/ + 0x08,0x08,0xFF,0x08,0x00,0x00,0x3F,0x11,0x08,0x01,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0xFE,0x20,0x10,0xF8,0x00,0x10,0x20,0x00,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xB2CC [?] [1642]*/ + 0x04,0xFF,0x04,0x10,0x1E,0x22,0x54,0x28,0x17,0x20,0xDF,0x01,0x11,0x21,0x45,0x02, + 0x40,0xFE,0x40,0x80,0xF8,0x88,0x50,0x20,0xD8,0x06,0xF0,0x00,0x10,0x08,0x04,0x00, + /* 0xB2CD [?] [1643]*/ + 0x08,0x0F,0x28,0x7F,0xA1,0x17,0x3A,0xCD,0x3F,0xC8,0x0F,0x08,0x0F,0x08,0x0A,0x0C, + 0x00,0x78,0x08,0x28,0x10,0x28,0xC4,0x60,0xF8,0x26,0xE0,0x20,0xE8,0xD0,0x30,0x08, + /* 0xB2CE [?] [1644]*/ + 0x02,0x04,0x08,0x1F,0x02,0x7F,0x08,0x10,0x23,0xCC,0x01,0x06,0x18,0x00,0x07,0x78, + 0x00,0x40,0x20,0xF0,0x00,0xFC,0x20,0x90,0x08,0x46,0x80,0x10,0x20,0xC0,0x00,0x00, + /* 0xB2CF [?] [1645]*/ + 0x00,0x3F,0x01,0x02,0xFF,0x04,0x08,0x31,0xDF,0x11,0x11,0x1F,0x11,0x01,0x7F,0x20, + 0x00,0xF8,0x00,0x00,0xFE,0x40,0x20,0x18,0xF6,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xB2D0 [?] [1646]*/ + 0x00,0x00,0xFC,0x20,0x21,0x3C,0x44,0x47,0x64,0x94,0x08,0x08,0x10,0x20,0x43,0x80, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xB2D1 [?] [1647]*/ + 0x21,0x21,0x21,0x2F,0x32,0xAA,0xA5,0xA7,0xA1,0x21,0x21,0x2F,0x25,0x21,0x21,0x21, + 0x00,0x02,0x1C,0xD0,0x10,0x10,0x1E,0xD4,0x14,0x14,0xD4,0x14,0x14,0x24,0x24,0x44, + /* 0xB2D2 [?] [1648]*/ + 0x20,0x20,0x21,0x33,0xA8,0xA7,0xA1,0xA2,0x2C,0x23,0x20,0x20,0x23,0x20,0x20,0x27, + 0x80,0x90,0x08,0xFC,0x40,0xFE,0x10,0x48,0x86,0x10,0x20,0xC4,0x08,0x30,0xC0,0x00, + /* 0xB2D3 [?] [1649]*/ + 0x10,0x10,0x10,0x10,0x55,0x59,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x40,0x80, + 0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00, + /* 0xB2D4 [?] [1650]*/ + 0x08,0x08,0xFF,0x08,0x09,0x02,0x04,0x08,0x30,0xCF,0x08,0x08,0x08,0x08,0x08,0x07, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x40,0x20,0x18,0xE6,0x20,0x20,0xA8,0x48,0x08,0xF8, + /* 0xB2D5 [?] [1651]*/ + 0x10,0x20,0x7C,0x44,0x64,0x55,0x56,0xFC,0x44,0x64,0x54,0x54,0x44,0x44,0x54,0x88, + 0x20,0x20,0x50,0x50,0x88,0x04,0x02,0xF8,0x88,0x88,0xA8,0x90,0x82,0x82,0x7E,0x00, + /* 0xB2D6 [?] [1652]*/ + 0x01,0x01,0x02,0x04,0x08,0x30,0xC0,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x07,0x00, + 0x00,0x00,0x80,0x40,0x20,0x18,0x06,0xE0,0x20,0x20,0xA0,0x44,0x04,0x04,0xFC,0x00, + /* 0xB2D7 [?] [1653]*/ + 0x00,0x40,0x20,0x21,0x02,0x84,0x4B,0x42,0x12,0x22,0xE2,0x22,0x22,0x22,0x21,0x00, + 0x40,0x40,0xA0,0x10,0x08,0x04,0xF2,0x10,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xB2D8 [?] [1654]*/ + 0x04,0xFF,0x04,0x00,0x1F,0x50,0x57,0x75,0x17,0xF4,0x57,0x55,0x95,0x27,0x20,0x40, + 0x40,0xFE,0x48,0x24,0xFE,0x20,0xA0,0x24,0xA4,0xA8,0xA8,0x10,0x12,0xAA,0x46,0x82, + /* 0xB2D9 [?] [1655]*/ + 0x23,0x22,0x22,0x23,0xF8,0x27,0x24,0x2C,0x37,0xE0,0x2F,0x21,0x22,0x24,0xB8,0x40, + 0xF8,0x08,0x08,0xF8,0x00,0xBC,0xA4,0xA4,0xBC,0x40,0xFE,0x60,0x50,0x48,0x46,0x40, + /* 0xB2DA [?] [1656]*/ + 0x10,0x10,0x96,0x55,0x58,0x10,0xFC,0x33,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x14, + 0x10,0x50,0x50,0x7C,0x90,0x10,0xFE,0x00,0x7C,0x44,0x44,0x7C,0x44,0x00,0xFE,0x00, + /* 0xB2DB [?] [1657]*/ + 0x10,0x10,0x17,0x10,0xFB,0x12,0x33,0x3A,0x57,0x50,0x91,0x11,0x11,0x11,0x11,0x11, + 0x90,0x90,0xFE,0x90,0xFC,0x94,0xFC,0x94,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xB2DC [?] [1658]*/ + 0x04,0x04,0xFF,0x04,0x3F,0x24,0x3F,0x24,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x40,0x40,0xFE,0x40,0xF8,0x48,0xF8,0x48,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xB2DD [?] [1659]*/ + 0x04,0x04,0xFF,0x04,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x40,0x40,0xFE,0x40,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xB2DE [?] [1660]*/ + 0x00,0x3F,0x20,0x2F,0x28,0x28,0x2A,0x2A,0x2A,0x2A,0x2A,0x22,0x25,0x44,0x48,0x90, + 0x00,0xFE,0x00,0x84,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x24,0x04,0x84,0x94,0x08, + /* 0xB2DF [?] [1661]*/ + 0x10,0x10,0x3F,0x48,0x85,0x01,0xFF,0x01,0x3F,0x21,0x23,0x25,0x09,0x11,0x61,0x01, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFE,0x00,0xF8,0x08,0x88,0x58,0x20,0x10,0x0C,0x00, + /* 0xB2E0 [?] [1662]*/ + 0x10,0x17,0x14,0x24,0x25,0x65,0x65,0xA5,0x25,0x25,0x25,0x21,0x22,0x22,0x24,0x28, + 0x04,0xC4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x04,0x84,0x44,0x14,0x08, + /* 0xB2E1 [?] [1663]*/ + 0x00,0x1E,0x12,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x12,0x12,0x26,0x41, + 0x00,0x78,0x48,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x48,0x88,0xA8,0x10, + /* 0xB2E2 [?] [1664]*/ + 0x00,0x27,0x14,0x14,0x85,0x45,0x45,0x15,0x15,0x25,0xE5,0x21,0x22,0x22,0x24,0x08, + 0x04,0xC4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x04,0x84,0x44,0x14,0x08, + /* 0xB2E3 [?] [1665]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x20,0x20,0x3F,0x21,0x22,0x44,0x4F,0x84, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x00,0x00,0xFE,0x00,0x10,0x08,0xFC,0x04, + /* 0xB2E4 [?] [1666]*/ + 0x01,0x78,0x48,0x4B,0x4A,0x7A,0x12,0x12,0x53,0x5C,0x51,0x51,0x59,0xE1,0x01,0x01, + 0x04,0x88,0x00,0xFE,0x22,0xAA,0x72,0x22,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xB2E5 [?] [1667]*/ + 0x20,0x20,0x27,0x20,0xF8,0x2F,0x20,0x29,0x36,0xE4,0x24,0x27,0x24,0x24,0xA7,0x44, + 0x08,0x3C,0xC0,0x40,0x40,0xFE,0x40,0x40,0x5C,0x44,0x44,0x5C,0x44,0x44,0xFC,0x04, + /* 0xB2E6 [?] [1668]*/ + 0x00,0x3F,0x10,0x12,0x11,0x09,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0xF0,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xB2E7 [?] [1669]*/ + 0x08,0x08,0xFF,0x0A,0x02,0x04,0xFF,0x08,0x10,0x30,0x53,0x90,0x10,0x10,0x17,0x10, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xFE,0x00,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xB2E8 [?] [1670]*/ + 0x08,0x08,0xFF,0x08,0x09,0x02,0x04,0x09,0x31,0xDF,0x01,0x09,0x11,0x21,0x05,0x02, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x40,0x20,0x18,0xF6,0x00,0x20,0x10,0x08,0x00,0x00, + /* 0xB2E9 [?] [1671]*/ + 0x01,0x01,0x7F,0x05,0x09,0x31,0xC1,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x00,0xFF,0x00, + 0x00,0x00,0xFC,0x40,0x20,0x18,0x06,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x00,0xFE,0x00, + /* 0xB2EA [?] [1672]*/ + 0x00,0x00,0xFB,0x20,0x20,0x41,0x7A,0x49,0xC9,0x49,0x49,0x49,0x79,0x48,0x03,0x00, + 0x20,0x20,0xFE,0x70,0xA8,0x24,0x22,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xB2EB [?] [1673]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x15,0x1A,0x31,0xD0,0x10,0x11,0x12,0x50,0x20, + 0x88,0x88,0xFE,0x88,0xA8,0x50,0x88,0x24,0x22,0xFC,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xB2EC [?] [1674]*/ + 0x01,0x7F,0x40,0x90,0x1E,0x22,0x54,0x28,0x17,0x20,0xDF,0x01,0x11,0x21,0x45,0x02, + 0x00,0xFE,0x02,0x84,0xF8,0x88,0x50,0x20,0xD8,0x06,0xF0,0x00,0x10,0x08,0x04,0x00, + /* 0xB2ED [?] [1675]*/ + 0x04,0x08,0x10,0x2F,0xC4,0x04,0x08,0x10,0x60,0x01,0x01,0x21,0x21,0x21,0x3F,0x00, + 0x40,0x20,0x10,0xE8,0x26,0x20,0x20,0xA0,0x40,0x00,0x00,0x08,0x08,0x08,0xF8,0x08, + /* 0xB2EE [?] [1676]*/ + 0x08,0x04,0x7F,0x01,0x01,0x3F,0x02,0x02,0xFF,0x04,0x08,0x17,0x20,0x40,0x80,0x1F, + 0x20,0x40,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0xF8,0x80,0x80,0x80,0xFC, + /* 0xB2EF [?] [1677]*/ + 0x00,0x20,0x10,0x13,0x02,0x04,0xF0,0x13,0x10,0x10,0x10,0x17,0x14,0x18,0x10,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x38,0xC0,0x40,0x40,0x7E,0xC0,0x40,0x42,0x42,0x3E, + /* 0xB2F0 [?] [1678]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x30,0x18,0x14,0x12,0x10,0x10,0x10, + /* 0xB2F1 [?] [1679]*/ + 0x08,0x08,0x28,0x2E,0x28,0x28,0x2E,0xF0,0x01,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x80,0x88,0x90,0xA0,0xC0,0x84,0x84,0x7C,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xB2F2 [?] [1680]*/ + 0x0C,0x30,0xC2,0x14,0x49,0x30,0xC8,0x14,0x24,0xCC,0x14,0x25,0xC4,0x04,0x28,0x10, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x30,0x30,0x50,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xB2F3 [?] [1681]*/ + 0x21,0x21,0x22,0x24,0xFB,0x22,0x22,0x2B,0x30,0xE1,0x26,0x20,0x20,0x21,0xA0,0x40, + 0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFC,0xA0,0x22,0x1E,0xC0,0x30,0x80,0x60,0x10, + /* 0xB2F4 [?] [1682]*/ + 0x10,0x10,0x11,0x13,0xFC,0x17,0x11,0x12,0x1C,0x33,0xD0,0x10,0x13,0x10,0x50,0x27, + 0x80,0x90,0x08,0xFC,0x40,0xFE,0x10,0x48,0x86,0x10,0x20,0xC4,0x08,0x30,0xC0,0x00, + /* 0xB2F5 [?] [1683]*/ + 0x11,0x10,0x10,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x10,0x14,0x1D,0xE4,0x40,0x00, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xB2F6 [?] [1684]*/ + 0x21,0x21,0x22,0x3C,0x4B,0x52,0x82,0x23,0x20,0x21,0x26,0x20,0x28,0x31,0x20,0x00, + 0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFC,0xA0,0x22,0x1E,0xC0,0x30,0x80,0x60,0x10, + /* 0xB2F7 [?] [1685]*/ + 0x01,0x21,0x12,0x14,0x03,0x02,0xF2,0x13,0x10,0x11,0x16,0x10,0x14,0x19,0x10,0x00, + 0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFC,0xA0,0x22,0x1E,0xC0,0x30,0x80,0x60,0x10, + /* 0xB2F8 [?] [1686]*/ + 0x20,0x20,0x27,0x44,0x55,0xF5,0x25,0x25,0x45,0xF5,0x45,0x04,0x35,0xC8,0x08,0x13, + 0x40,0x20,0xFE,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFC,0x20,0x20,0xFE, + /* 0xB2F9 [?] [1687]*/ + 0x20,0x20,0x3B,0x20,0x41,0x78,0xA3,0x22,0xFA,0x22,0x22,0x22,0x2A,0x34,0x24,0x08, + 0x40,0x20,0xFC,0x00,0x08,0x90,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB2FA [?] [1688]*/ + 0x02,0x01,0x7F,0x00,0x08,0x04,0x04,0x3F,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0x00,0xFC,0x00,0x20,0x20,0x40,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB2FB [?] [1689]*/ + 0x20,0x17,0x00,0x44,0x42,0x4F,0x49,0x4F,0x49,0x4F,0x41,0x5F,0x41,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x44,0x84,0xE4,0x24,0xE4,0x24,0xE4,0x04,0xF4,0x04,0x04,0x14,0x08, + /* 0xB2FC [?] [1690]*/ + 0x08,0xFF,0x00,0xFF,0x81,0xBD,0xA5,0xFF,0x00,0x7E,0x42,0x7E,0x42,0x7E,0x00,0xFE, + 0x00,0x7E,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xB2FD [?] [1691]*/ + 0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB2FE [?] [1692]*/ + 0x01,0x45,0x29,0x11,0x29,0x49,0x89,0x08,0x1B,0x2A,0x4A,0x8B,0x0A,0x0A,0x53,0x22, + 0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB3A1 [?] [1693]*/ + 0x20,0x23,0x20,0x20,0x20,0xF9,0x23,0x21,0x21,0x21,0x22,0x3A,0xE4,0x48,0x01,0x02, + 0x00,0xF0,0x20,0x40,0x80,0x00,0xFC,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xB3A2 [?] [1694]*/ + 0x01,0x11,0x09,0x01,0x7F,0x40,0x80,0x1F,0x00,0x00,0x7F,0x04,0x08,0x10,0x3F,0x10, + 0x00,0x10,0x20,0x00,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x00,0x20,0x10,0xF8,0x08, + /* 0xB3A3 [?] [1695]*/ + 0x01,0x11,0x09,0x7F,0x40,0x9F,0x10,0x1F,0x01,0x3F,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0x10,0x20,0xFE,0x02,0xF4,0x10,0xF0,0x00,0xF8,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xB3A4 [?] [1696]*/ + 0x08,0x08,0x08,0x08,0x08,0x09,0x08,0xFF,0x0A,0x09,0x08,0x08,0x09,0x0A,0x0C,0x08, + 0x00,0x10,0x20,0x40,0x80,0x00,0x00,0xFE,0x00,0x00,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xB3A5 [?] [1697]*/ + 0x08,0x0A,0x09,0x10,0x17,0x34,0x38,0x51,0x90,0x10,0x17,0x10,0x11,0x12,0x17,0x12, + 0x40,0x48,0x50,0x40,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x80,0x10,0x08,0xFC,0x04, + /* 0xB3A6 [?] [1698]*/ + 0x00,0x3D,0x24,0x24,0x24,0x3C,0x25,0x24,0x24,0x3C,0x25,0x25,0x26,0x44,0x54,0x89, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xB3A7 [?] [1699]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB3A8 [?] [1700]*/ + 0x08,0x49,0x29,0x2A,0x08,0x7F,0x41,0x41,0x5D,0x55,0x55,0x55,0x5D,0x41,0x45,0x42, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xB3A9 [?] [1701]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x7D,0x54,0x54,0x54,0x7D,0x54,0x10,0x10,0x11,0x10, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFC,0x54,0x54,0x94,0x24,0x24,0x44,0x84,0x28,0x10, + /* 0xB3AA [?] [1702]*/ + 0x01,0x01,0x79,0x49,0x49,0x49,0x49,0x48,0x4B,0x4A,0x7A,0x4B,0x02,0x02,0x03,0x02, + 0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB3AB [?] [1703]*/ + 0x09,0x09,0x09,0x11,0x11,0x31,0x31,0x50,0x93,0x12,0x12,0x13,0x12,0x12,0x13,0x12, + 0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB3AC [?] [1704]*/ + 0x08,0x09,0x08,0x7E,0x08,0x08,0xFF,0x08,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x00,0xFC,0x44,0x44,0x44,0x94,0x08,0xFC,0x84,0x84,0x84,0xFC,0x00,0x00,0xFE,0x00, + /* 0xB3AD [?] [1705]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x11,0x15,0x1A,0x30,0xD0,0x10,0x10,0x10,0x50,0x23, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xB3AE [?] [1706]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x11,0x11,0xFE,0x10,0x10,0x10,0x14,0x18,0x10,0x03, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xB3AF [?] [1707]*/ + 0x08,0x08,0xFF,0x08,0x7F,0x41,0x7F,0x41,0x7F,0x49,0x08,0xFF,0x08,0x08,0x08,0x09, + 0x00,0x3E,0xA2,0x22,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22,0xA2,0x42,0x42,0x8A,0x04, + /* 0xB3B0 [?] [1708]*/ + 0x02,0x02,0xEF,0xA2,0xA2,0xAF,0xA8,0xAF,0xA8,0xAF,0xE2,0xA2,0x1F,0x02,0x02,0x02, + 0x00,0x3C,0xA4,0x24,0x24,0xBC,0xA4,0xA4,0xA4,0xBC,0x24,0x24,0xA4,0x44,0x54,0x88, + /* 0xB3B1 [?] [1709]*/ + 0x01,0x41,0x27,0x21,0x01,0x87,0x44,0x57,0x14,0x27,0xE1,0x21,0x2F,0x21,0x21,0x01, + 0x00,0x1E,0xD2,0x12,0x12,0xDE,0x52,0xD2,0x52,0xDE,0x12,0x12,0xD2,0x22,0x2A,0x44, + /* 0xB3B2 [?] [1710]*/ + 0x08,0x11,0x22,0x11,0x08,0x3F,0x21,0x3F,0x21,0x3F,0x01,0xFF,0x05,0x09,0x31,0xC1, + 0x88,0x10,0x20,0x10,0x88,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x40,0x20,0x18,0x06, + /* 0xB3B3 [?] [1711]*/ + 0x00,0x00,0x78,0x49,0x49,0x4A,0x4A,0x4C,0x48,0x48,0x78,0x48,0x00,0x00,0x01,0x06, + 0x40,0x40,0x40,0x48,0x44,0x42,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0x40,0x80,0x00, + /* 0xB3B4 [?] [1712]*/ + 0x10,0x10,0x10,0x10,0x54,0x58,0x51,0x91,0x12,0x10,0x10,0x28,0x24,0x44,0x40,0x83, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xB3B5 [?] [1713]*/ + 0x02,0x02,0x02,0x7F,0x04,0x09,0x11,0x21,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xB3B6 [?] [1714]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x57,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB3B7 [?] [1715]*/ + 0x22,0x21,0x27,0x22,0xF4,0x2F,0x20,0x27,0x34,0xE7,0x24,0x27,0x24,0x24,0xA4,0x45, + 0x08,0x08,0xC8,0x10,0x9E,0xD4,0x64,0x94,0x94,0x94,0x94,0x88,0x88,0x94,0xA4,0xC2, + /* 0xB3B8 [?] [1716]*/ + 0x24,0x3F,0x44,0xFF,0x04,0x3F,0x24,0x25,0x00,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x03, + 0x04,0xA4,0x24,0xA4,0x24,0x84,0x94,0x88,0x20,0xC0,0x00,0xF8,0x00,0xFC,0x00,0x00, + /* 0xB3B9 [?] [1717]*/ + 0x10,0x12,0x22,0x42,0x92,0x12,0x23,0x6E,0xA2,0x22,0x22,0x23,0x22,0x20,0x20,0x21, + 0x00,0x00,0xFC,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0xA4,0x24,0x44,0x44,0x94,0x08, + /* 0xB3BA [?] [1718]*/ + 0x02,0x21,0x17,0x12,0x84,0x4F,0x40,0x17,0x14,0x27,0xE4,0x27,0x24,0x24,0x24,0x05, + 0x08,0x08,0xC8,0x10,0x9E,0xD4,0x64,0x94,0x94,0x94,0x94,0x88,0x88,0x94,0xA4,0xC2, + /* 0xB3BB [?] [1719]*/ + 0x11,0x11,0x11,0x11,0x7B,0x11,0x11,0x33,0x3B,0x55,0x55,0x99,0x11,0x11,0x11,0x11, + 0x00,0x1E,0x12,0x12,0xD4,0x14,0x18,0x14,0x92,0x52,0x12,0x1A,0x14,0x10,0x10,0x10, + /* 0xB3BC [?] [1720]*/ + 0x00,0x3F,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x3F,0x21,0x21,0x21,0x3F,0x00, + 0x00,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0xFC,0x00, + /* 0xB3BD [?] [1721]*/ + 0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x3F,0x24,0x24,0x24,0x24,0x44,0x45,0x86,0x04, + 0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFC,0x80,0x88,0x50,0x20,0x10,0x08,0x06,0x00, + /* 0xB3BE [?] [1722]*/ + 0x01,0x01,0x09,0x09,0x11,0x21,0x41,0x00,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0x20,0x10,0x08,0x04,0x04,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xB3BF [?] [1723]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x20,0x2F,0x20,0x3F,0x29,0x28,0x48,0x4A,0x8C, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x08,0x90,0x60,0x18,0x06, + /* 0xB3C0 [?] [1724]*/ + 0x10,0x10,0x10,0x13,0x1A,0x54,0x50,0x50,0x90,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x40,0x40,0x40,0xFC,0x44,0x48,0x40,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xB3C1 [?] [1725]*/ + 0x00,0x20,0x13,0x12,0x84,0x40,0x41,0x11,0x11,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB3C2 [?] [1726]*/ + 0x00,0x78,0x48,0x57,0x50,0x61,0x51,0x4A,0x4B,0x48,0x69,0x51,0x42,0x44,0x40,0x40, + 0x40,0x40,0x40,0xFE,0x80,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xB3C3 [?] [1727]*/ + 0x08,0x08,0x08,0x7E,0x08,0x09,0xFE,0x08,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x20,0x20,0x50,0x50,0x88,0x24,0x42,0x90,0x20,0x44,0x88,0x10,0x20,0x40,0xFE,0x00, + /* 0xB3C4 [?] [1728]*/ + 0x20,0x10,0x00,0xFC,0x09,0x10,0x10,0x34,0x59,0x94,0x14,0x10,0x10,0x10,0x10,0x10, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xB3C5 [?] [1729]*/ + 0x11,0x10,0x13,0x12,0xFC,0x10,0x10,0x14,0x19,0x30,0xD1,0x10,0x13,0x10,0x50,0x20, + 0x24,0xA8,0xFE,0x02,0xF8,0x88,0xF8,0x0C,0xF0,0x20,0xFC,0x20,0xFE,0x20,0xA0,0x40, + /* 0xB3C6 [?] [1730]*/ + 0x08,0x1C,0xF0,0x10,0x11,0xFD,0x12,0x30,0x38,0x54,0x51,0x91,0x12,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x02,0x04,0x20,0x20,0xA8,0xA4,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xB3C7 [?] [1731]*/ + 0x20,0x20,0x20,0x27,0x24,0xFC,0x24,0x27,0x24,0x24,0x24,0x3C,0xE6,0x49,0x08,0x10, + 0x28,0x24,0x20,0xFE,0x20,0x20,0x24,0xA4,0xA4,0xA8,0xA8,0x90,0x92,0x2A,0x46,0x82, + /* 0xB3C8 [?] [1732]*/ + 0x10,0x17,0x10,0x12,0xF9,0x12,0x35,0x38,0x57,0x52,0x92,0x13,0x12,0x11,0x1F,0x10, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xB3C9 [?] [1733]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x3E,0x22,0x22,0x22,0x22,0x2A,0x44,0x40,0x81, + 0x50,0x48,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xB3CA [?] [1734]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x00,0x00,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB3CB [?] [1735]*/ + 0x00,0x3F,0x01,0x7F,0x01,0x09,0xF9,0x09,0x39,0xCB,0x05,0x09,0x31,0xC1,0x01,0x01, + 0xF8,0x00,0x00,0xFC,0x00,0x24,0x38,0x22,0x22,0x9E,0x40,0x20,0x18,0x06,0x00,0x00, + /* 0xB3CC [?] [1736]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x10,0x30,0x39,0x54,0x54,0x91,0x10,0x10,0x13,0x10, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xB3CD [?] [1737]*/ + 0x10,0x23,0x40,0x89,0x11,0x31,0x51,0x91,0x17,0x10,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xFE,0x20,0x20,0x3C,0x20,0x20,0x20,0xFE,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xB3CE [?] [1738]*/ + 0x00,0x27,0x10,0x12,0x81,0x42,0x55,0x18,0x13,0x22,0xE2,0x23,0x22,0x21,0x2F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xB3CF [?] [1739]*/ + 0x00,0x40,0x20,0x27,0x04,0x04,0xE4,0x27,0x24,0x24,0x24,0x2C,0x36,0x29,0x08,0x10, + 0x28,0x24,0x20,0xFE,0x20,0x20,0x24,0xA4,0xA4,0xA8,0xA8,0x90,0x92,0x2A,0x46,0x82, + /* 0xB3D0 [?] [1740]*/ + 0x1F,0x00,0x00,0x01,0x79,0x0F,0x09,0x11,0x17,0x21,0x21,0x4F,0x81,0x01,0x05,0x02, + 0xE0,0x40,0x80,0x04,0x28,0xF0,0x20,0x10,0xD0,0x08,0x08,0xE4,0x02,0x00,0x00,0x00, + /* 0xB3D1 [?] [1741]*/ + 0x03,0x22,0x12,0x12,0x03,0x00,0xF7,0x10,0x10,0x13,0x10,0x10,0x17,0x28,0x47,0x00, + 0xF8,0x08,0x08,0x08,0xF8,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFC,0x00,0xFE,0x00, + /* 0xB3D2 [?] [1742]*/ + 0x00,0xF8,0x09,0x49,0x49,0x49,0x49,0x7C,0x07,0x04,0x1D,0xE5,0x44,0x04,0x28,0x10, + 0x20,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE,0x80,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xB3D3 [?] [1743]*/ + 0x08,0x1D,0xF0,0x10,0x11,0xFC,0x10,0x30,0x3B,0x54,0x54,0x90,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xB3D4 [?] [1744]*/ + 0x00,0x00,0x79,0x49,0x4A,0x4C,0x49,0x48,0x48,0x48,0x78,0x49,0x02,0x02,0x01,0x00, + 0x80,0x80,0x00,0xFE,0x00,0x00,0xF8,0x08,0x10,0x60,0x80,0x00,0x02,0x02,0xFE,0x00, + /* 0xB3D5 [?] [1745]*/ + 0x00,0x00,0x1F,0x12,0x92,0x53,0x55,0x19,0x31,0x5F,0x91,0x11,0x22,0x22,0x44,0x88, + 0x80,0x40,0xFE,0x00,0x00,0xBC,0x24,0x24,0x24,0xE4,0x24,0x24,0xA4,0xBC,0x24,0x00, + /* 0xB3D6 [?] [1746]*/ + 0x10,0x10,0x10,0x11,0xFC,0x10,0x13,0x10,0x18,0x33,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x20,0x20,0x20,0xFC,0x20,0x20,0xFE,0x08,0x08,0xFE,0x08,0x88,0x48,0x08,0x28,0x10, + /* 0xB3D7 [?] [1747]*/ + 0x00,0x3E,0x22,0x3E,0x22,0x3E,0x00,0xFF,0x08,0x08,0x2F,0x28,0x28,0x58,0x4F,0x80, + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x40,0x44,0x44,0x44,0x3C,0x00,0x00,0xFE,0x00, + /* 0xB3D8 [?] [1748]*/ + 0x00,0x20,0x12,0x12,0x82,0x42,0x53,0x1E,0x12,0x22,0xE2,0x22,0x22,0x22,0x21,0x00, + 0x40,0x40,0x40,0x58,0x68,0xC8,0x48,0x48,0x48,0x48,0x58,0x42,0x02,0x02,0xFE,0x00, + /* 0xB3D9 [?] [1749]*/ + 0x00,0x21,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x12,0x12,0x14,0x10,0x28,0x47,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x20,0x10,0x08,0x04,0x04,0x00,0x00,0xFE,0x00, + /* 0xB3DA [?] [1750]*/ + 0x00,0xF8,0x08,0x09,0x09,0x79,0x41,0x43,0x41,0x79,0x09,0x09,0x09,0x09,0x50,0x20, + 0x20,0x20,0x20,0x20,0x2C,0x34,0x64,0xA4,0x24,0x34,0x28,0x22,0x22,0x02,0xFE,0x00, + /* 0xB3DB [?] [1751]*/ + 0x00,0xF8,0x08,0x49,0x49,0x49,0x49,0x7F,0x05,0x05,0x1D,0xE5,0x45,0x05,0x28,0x10, + 0x20,0x20,0x20,0x20,0x2C,0x34,0x64,0xA4,0x24,0x34,0x28,0x22,0x22,0x02,0xFE,0x00, + /* 0xB3DC [?] [1752]*/ + 0x00,0xFF,0x24,0x24,0x3C,0x24,0x24,0x3C,0x24,0x24,0x2E,0xF4,0x44,0x04,0x05,0x04, + 0x10,0x10,0x10,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xB3DD [?] [1753]*/ + 0x01,0x01,0x11,0x11,0x11,0x11,0xFF,0x00,0x21,0x21,0x22,0x24,0x28,0x20,0x3F,0x00, + 0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x08,0x08,0x88,0x48,0x28,0x08,0xF8,0x08, + /* 0xB3DE [?] [1754]*/ + 0x10,0x10,0x11,0x22,0x25,0x60,0x60,0xA3,0x2C,0x20,0x21,0x26,0x20,0x20,0x21,0x2E, + 0x80,0x80,0xF8,0x10,0x20,0xC0,0x90,0x20,0x7C,0x84,0x08,0x90,0x60,0x40,0x80,0x00, + /* 0xB3DF [?] [1755]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x80,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xB3E0 [?] [1756]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0xFF,0x04,0x04,0x24,0x24,0x44,0x88,0x08,0x11,0x20, + 0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x40,0x40,0x48,0x44,0x42,0x42,0x40,0x40,0x80, + /* 0xB3E1 [?] [1757]*/ + 0x10,0x11,0x10,0xFE,0x11,0x10,0xFC,0x44,0x45,0x28,0x28,0x11,0x18,0x24,0x43,0x80, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0xCC,0x54,0x44,0x44,0x54,0x88,0x00,0xFE,0x00, + /* 0xB3E2 [?] [1758]*/ + 0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x11,0x10,0x10,0x20,0x20,0x40,0x80, + 0x10,0xF8,0x00,0x00,0x00,0x00,0xFE,0x40,0x40,0xC0,0x60,0x50,0x48,0x40,0x40,0x40, + /* 0xB3E3 [?] [1759]*/ + 0x10,0x10,0x11,0x11,0x55,0x59,0x51,0x91,0x11,0x11,0x10,0x28,0x24,0x45,0x42,0x84, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xB3E4 [?] [1760]*/ + 0x02,0x01,0xFF,0x04,0x04,0x08,0x10,0x3F,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x60, + 0x00,0x00,0xFE,0x00,0x00,0x20,0x10,0xF8,0x48,0x40,0x40,0x40,0x44,0x44,0x44,0x3C, + /* 0xB3E5 [?] [1761]*/ + 0x00,0x40,0x20,0x20,0x07,0x04,0x14,0x14,0x24,0xE4,0x27,0x24,0x20,0x20,0x20,0x00, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x44,0x40,0x40,0x40,0x40, + /* 0xB3E6 [?] [1762]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x01,0x01,0x7E,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x10,0x08,0xFC,0x04,0x00, + /* 0xB3E7 [?] [1763]*/ + 0x01,0x21,0x21,0x3F,0x02,0x01,0x7F,0x40,0x9F,0x00,0x7F,0x01,0x11,0x21,0x45,0x02, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xFE,0x02,0xF4,0x00,0xFC,0x00,0x10,0x08,0x04,0x00, + /* 0xB3E8 [?] [1764]*/ + 0x02,0x01,0x7F,0x40,0x84,0x04,0x04,0xFF,0x04,0x08,0x08,0x10,0x10,0x20,0x41,0x86, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x10,0xFE,0x80,0x88,0x90,0xA0,0xC2,0x82,0x82,0x7E, + /* 0xB3E9 [?] [1765]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xB3EA [?] [1766]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAB,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x04,0x44,0x54,0x54,0x54,0x54,0xDC,0x74,0x54,0x54,0x54,0x54,0x54,0x54,0x84,0x04, + /* 0xB3EB [?] [1767]*/ + 0x00,0x00,0xFB,0xA8,0xA9,0xA8,0xFB,0xA8,0xA8,0xA8,0xA9,0xF9,0x8A,0x04,0x00,0x00, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x48,0x88,0xFE,0x08,0x48,0x28,0x08,0x28,0x10, + /* 0xB3EC [?] [1768]*/ + 0x00,0x7C,0x47,0x44,0x45,0x7C,0x13,0x10,0x5C,0x50,0x51,0x51,0x5E,0xE4,0x00,0x00, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x48,0x88,0xFE,0x08,0x48,0x28,0x08,0x28,0x10, + /* 0xB3ED [?] [1769]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x12,0x12,0x14, + 0x00,0xFC,0x24,0x24,0x74,0x24,0xFC,0x04,0x74,0x54,0x54,0x74,0x04,0x04,0x14,0x08, + /* 0xB3EE [?] [1770]*/ + 0x0E,0x78,0x08,0x08,0xFE,0x19,0x2C,0x4A,0x88,0x09,0x0A,0x01,0x28,0x28,0x48,0x07, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0x50,0x50,0x88,0x04,0x02,0x00,0x88,0xA4,0x24,0xE0, + /* 0xB3EF [?] [1771]*/ + 0x20,0x3F,0x48,0x85,0x01,0x7F,0x02,0x3F,0x04,0xFF,0x08,0x1F,0x24,0x42,0x80,0x00, + 0x40,0x7E,0x90,0x08,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0xFC,0x20,0x20,0xA0,0x40, + /* 0xB3F0 [?] [1772]*/ + 0x09,0x09,0x09,0x11,0x17,0x31,0x31,0x51,0x91,0x11,0x11,0x12,0x12,0x14,0x18,0x10, + 0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB3F1 [?] [1773]*/ + 0x10,0x13,0x22,0x22,0x4A,0xFA,0x12,0x23,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x42,0x04, + 0x00,0xFE,0x22,0x22,0xFA,0x22,0x22,0xFE,0x02,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xB3F2 [?] [1774]*/ + 0x00,0x01,0xF7,0x91,0x91,0xF1,0x97,0x91,0xF3,0x93,0x95,0x95,0xF9,0x91,0x01,0x01, + 0x88,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xB3F3 [?] [1775]*/ + 0x00,0x3F,0x02,0x02,0x02,0x02,0x02,0x3F,0x04,0x04,0x04,0x04,0x04,0x04,0xFF,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xB3F4 [?] [1776]*/ + 0x02,0x04,0x3F,0x20,0x3F,0x20,0x3F,0x20,0x3F,0x01,0x01,0xFF,0x02,0x04,0x18,0xE0, + 0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x10,0xFE,0x80,0x40,0x30,0x0E, + /* 0xB3F5 [?] [1777]*/ + 0x20,0x10,0x01,0xFC,0x08,0x10,0x10,0x34,0x58,0x94,0x14,0x10,0x10,0x11,0x12,0x14, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xB3F6 [?] [1778]*/ + 0x01,0x01,0x21,0x21,0x21,0x21,0x3F,0x01,0x01,0x01,0x41,0x41,0x41,0x41,0x7F,0x00, + 0x00,0x00,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB3F7 [?] [1779]*/ + 0x20,0x27,0x24,0x24,0xF7,0x24,0x25,0x75,0x6D,0xA5,0xA4,0x25,0x24,0x24,0x2B,0x20, + 0x00,0xFE,0x00,0x04,0xE4,0x04,0xDE,0x44,0x44,0xD4,0x0C,0x44,0x84,0xE4,0x14,0x08, + /* 0xB3F8 [?] [1780]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x2F,0x29,0x29,0x29,0x2F,0x20,0x29,0x26,0x43,0x5C,0x88, + 0x00,0xFE,0x08,0x88,0x08,0x08,0x7E,0x08,0x08,0x48,0x28,0x08,0x08,0x88,0x28,0x10, + /* 0xB3F9 [?] [1781]*/ + 0x00,0x78,0x4B,0x48,0x48,0x79,0x10,0x10,0x53,0x5C,0x50,0x51,0x5A,0xE4,0x00,0x00, + 0x88,0x88,0xFE,0xA8,0x22,0xFA,0x24,0x28,0xFE,0x40,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xB3FA [?] [1782]*/ + 0x20,0x20,0x3B,0x22,0x42,0x7A,0xA3,0x22,0xFA,0x23,0x22,0x22,0x2A,0x33,0x26,0x00, + 0x08,0x08,0xC8,0x48,0x5E,0x4A,0xCA,0x4A,0x4A,0xCA,0x4A,0x4A,0x6A,0xD2,0x12,0x26, + /* 0xB3FB [?] [1783]*/ + 0x20,0x20,0x3E,0x42,0x85,0x0A,0xFE,0x02,0x02,0x7E,0x02,0x02,0x02,0xFE,0x02,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xB3FC [?] [1784]*/ + 0x40,0x2F,0x29,0x8A,0x4A,0x4C,0x0A,0x29,0x29,0x49,0xCD,0x4A,0x48,0x49,0x48,0x08, + 0x10,0x10,0x28,0x28,0x44,0xBA,0x10,0x10,0xFE,0x10,0x58,0x54,0x92,0x12,0x50,0x20, + /* 0xB3FD [?] [1785]*/ + 0x00,0x78,0x48,0x51,0x52,0x65,0x50,0x48,0x4F,0x48,0x6A,0x52,0x44,0x48,0x41,0x40, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xB3FE [?] [1786]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC8,0x00,0x7F,0x01,0x11,0x11,0x11,0x29,0x47,0x80, + 0x20,0x20,0xFC,0x20,0x70,0xA8,0x24,0x00,0xFC,0x04,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB4A1 [?] [1787]*/ + 0x00,0x00,0xFD,0x11,0x11,0x21,0x3D,0x64,0x64,0xA5,0x25,0x25,0x3D,0x25,0x21,0x00, + 0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xB4A2 [?] [1788]*/ + 0x10,0x10,0x18,0x24,0x24,0x61,0x60,0xBC,0x24,0x25,0x26,0x24,0x25,0x26,0x24,0x20, + 0x20,0x20,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xB4A3 [?] [1789]*/ + 0x01,0x3F,0x01,0x0F,0x08,0x09,0x09,0x7F,0x08,0x7E,0x08,0x3E,0x22,0x2A,0x2A,0xFF, + 0x00,0xF8,0x00,0xE0,0x20,0x20,0x20,0xFC,0x20,0xFC,0x20,0xF8,0x88,0xA8,0xA8,0xFE, + /* 0xB4A4 [?] [1790]*/ + 0x20,0x20,0x27,0x20,0xF9,0x23,0x20,0x29,0x37,0xE0,0x27,0x24,0x27,0x24,0xA7,0x44, + 0x80,0x40,0xFC,0x80,0x08,0xF0,0x60,0x84,0xFE,0x02,0xFC,0x44,0xFC,0x44,0xFC,0x04, + /* 0xB4A5 [?] [1791]*/ + 0x20,0x20,0x78,0x49,0x91,0x7D,0x55,0x55,0x7D,0x55,0x54,0x7C,0x54,0x57,0x45,0x8C, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x28,0x24,0xFE,0x02,0x00, + /* 0xB4A6 [?] [1792]*/ + 0x10,0x10,0x10,0x1E,0x12,0x22,0x22,0x52,0x94,0x14,0x08,0x08,0x14,0x23,0x40,0x80, + 0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xB4A7 [?] [1793]*/ + 0x20,0x24,0x24,0x24,0xF7,0x20,0x2F,0x20,0x30,0xE7,0x24,0x24,0x24,0x24,0xA4,0x44, + 0x40,0x44,0x44,0x44,0xFC,0x00,0xFE,0x40,0x80,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0x0C, + /* 0xB4A8 [?] [1794]*/ + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x04, + /* 0xB4A9 [?] [1795]*/ + 0x02,0x01,0x7F,0x48,0x90,0x00,0x3F,0x00,0x10,0x20,0x3F,0x01,0x06,0x18,0x61,0x00, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xFC,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x80, + /* 0xB4AA [?] [1796]*/ + 0x21,0x21,0x22,0x23,0xF8,0x27,0x20,0x71,0x6E,0xA0,0xA1,0x26,0x20,0x21,0x26,0x20, + 0x00,0xF8,0x08,0xF0,0x10,0xFE,0x80,0x44,0x68,0xB0,0x28,0x68,0xA4,0x22,0xA0,0x40, + /* 0xB4AB [?] [1797]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x37,0x50,0x91,0x13,0x10,0x11,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0xF8,0x40,0x80,0xFE,0x80,0x00,0xF8,0x08,0x10,0xA0,0x40,0x20,0x20, + /* 0xB4AC [?] [1798]*/ + 0x08,0x10,0x3E,0x22,0x32,0x2A,0x2A,0xFF,0x22,0x32,0x2A,0x2A,0x22,0x42,0x4A,0x84, + 0x00,0x78,0x48,0x48,0x48,0x48,0x8E,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xB4AD [?] [1799]*/ + 0x00,0x04,0xF4,0x94,0x97,0x90,0x9F,0x90,0x90,0x97,0xF4,0x94,0x04,0x04,0x04,0x04, + 0x40,0x44,0x44,0x44,0xFC,0x00,0xFE,0x40,0x80,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0x0C, + /* 0xB4AE [?] [1800]*/ + 0x01,0x01,0x3F,0x21,0x21,0x3F,0x01,0x01,0x7F,0x41,0x41,0x7F,0x41,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04,0x00,0x00,0x00, + /* 0xB4AF [?] [1801]*/ + 0x00,0x00,0x1F,0x10,0x90,0x51,0x52,0x14,0x3B,0x52,0x92,0x12,0x22,0x22,0x42,0x81, + 0x80,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC, + /* 0xB4B0 [?] [1802]*/ + 0x02,0x01,0x7F,0x48,0x92,0x04,0x3F,0x22,0x23,0x24,0x2A,0x21,0x22,0x24,0x3F,0x20, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xF8,0x08,0xC8,0x48,0x88,0x08,0x88,0x08,0xF8,0x08, + /* 0xB4B1 [?] [1803]*/ + 0x10,0x11,0x10,0x7C,0x57,0x54,0x55,0x55,0x55,0x55,0x55,0x5C,0x11,0x10,0x13,0x10, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xB4B2 [?] [1804]*/ + 0x01,0x00,0x3F,0x20,0x20,0x20,0x2F,0x20,0x21,0x22,0x22,0x24,0x48,0x50,0x80,0x00, + 0x00,0x80,0xFE,0x00,0x80,0x80,0xFC,0x80,0xC0,0xA0,0xA0,0x90,0x88,0x86,0x80,0x80, + /* 0xB4B3 [?] [1805]*/ + 0x20,0x13,0x10,0x40,0x5F,0x40,0x48,0x48,0x4F,0x40,0x40,0x5F,0x40,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x84,0x84,0x84,0x84,0xE4,0x24,0x24,0xA4,0x24,0x44,0x94,0x08, + /* 0xB4B4 [?] [1806]*/ + 0x08,0x08,0x14,0x12,0x21,0x40,0xBE,0x22,0x22,0x22,0x2A,0x24,0x20,0x20,0x1F,0x00, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x84,0x84,0x94,0x08, + /* 0xB4B5 [?] [1807]*/ + 0x00,0x00,0x78,0x48,0x49,0x49,0x4A,0x4C,0x48,0x48,0x78,0x49,0x01,0x02,0x04,0x08, + 0x80,0x80,0x80,0xFC,0x04,0x08,0x40,0x40,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xB4B6 [?] [1808]*/ + 0x10,0x10,0x10,0x12,0x52,0x54,0x59,0x90,0x10,0x10,0x28,0x28,0x24,0x44,0x41,0x82, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB4B7 [?] [1809]*/ + 0x10,0x10,0x13,0x10,0xF8,0x17,0x12,0x1A,0x37,0xD2,0x12,0x17,0x10,0x10,0x57,0x20, + 0x10,0x78,0xC0,0x40,0x40,0xFC,0x48,0x48,0xFE,0x48,0x48,0xFC,0x40,0x40,0xFC,0x00, + /* 0xB4B8 [?] [1810]*/ + 0x20,0x20,0x39,0x20,0x40,0x7B,0xA1,0x21,0xFB,0x21,0x21,0x23,0x28,0x30,0x23,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x24,0x24,0xFE,0x24,0x24,0xFE,0x20,0x20,0xFE,0x00, + /* 0xB4B9 [?] [1811]*/ + 0x00,0x00,0x3F,0x01,0x01,0x7F,0x09,0x09,0xFF,0x09,0x09,0x7F,0x01,0x01,0x3F,0x00, + 0x10,0xF8,0x00,0x00,0x00,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xF8,0x00, + /* 0xB4BA [?] [1812]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x08,0x10,0x2F,0xC8,0x08,0x0F,0x08,0x08,0x0F, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0x10,0xE8,0x26,0x20,0xE0,0x20,0x20,0xE0, + /* 0xB4BB [?] [1813]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x33,0x38,0x55,0x52,0x90,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x88,0x88,0xF8,0x88,0x88,0xF8, + /* 0xB4BC [?] [1814]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x10,0xFE,0x00,0x7C,0x44,0x7C,0x00,0x7C,0x08,0x10,0xFE,0x10,0x10,0x50,0x20, + /* 0xB4BD [?] [1815]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x3F,0x24,0x24,0x25,0x26,0x20,0x2F,0x48,0x48,0x8F,0x08, + 0x00,0xFC,0x00,0xF8,0x00,0xFE,0x88,0x50,0x30,0x0E,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB4BE [?] [1816]*/ + 0x00,0x20,0x17,0x10,0x83,0x42,0x4B,0x08,0x13,0x10,0xE0,0x27,0x20,0x20,0x21,0x00, + 0x80,0x40,0xFC,0x00,0xF8,0x08,0xF8,0x00,0xF8,0x10,0x20,0xFC,0x40,0x40,0x40,0x80, + /* 0xB4BF [?] [1817]*/ + 0x10,0x10,0x20,0x23,0x48,0xFA,0x12,0x22,0x42,0xFB,0x40,0x00,0x18,0xE0,0x40,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xB4C0 [?] [1818]*/ + 0x01,0x7F,0x01,0x3F,0x02,0xFF,0x08,0x3F,0xC8,0x0F,0x10,0x7C,0x54,0x7C,0x12,0xFE, + 0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0xF8,0x26,0xE0,0x20,0xF8,0xA8,0xF8,0x24,0xFC, + /* 0xB4C1 [?] [1819]*/ + 0x00,0xEE,0x22,0xAA,0x66,0xAA,0x01,0x24,0x7F,0xC8,0x7E,0x48,0x7E,0x48,0x7F,0x41, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xB4C2 [?] [1820]*/ + 0x10,0x10,0x20,0x20,0x4B,0xFA,0x13,0x22,0x43,0xFA,0x40,0x07,0x18,0xE0,0x40,0x00, + 0x40,0x40,0x7E,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x44,0x40,0xFE,0x40,0x40,0x40,0x40, + /* 0xB4C3 [?] [1821]*/ + 0x00,0x00,0x1F,0x10,0x91,0x51,0x55,0x15,0x35,0x55,0x95,0x15,0x25,0x25,0x5E,0x88, + 0x80,0x40,0xFE,0x00,0x10,0x10,0x12,0x14,0xD8,0x10,0x10,0x10,0x12,0xD2,0x12,0x0E, + /* 0xB4C4 [?] [1822]*/ + 0x08,0x08,0xFF,0x08,0x40,0x20,0x20,0x09,0x12,0x14,0x20,0xE0,0x20,0x21,0x22,0x2C, + 0x20,0x20,0xFE,0x20,0x80,0x80,0xFC,0x04,0x48,0x40,0x40,0xA0,0xA0,0x10,0x08,0x06, + /* 0xB4C5 [?] [1823]*/ + 0x01,0x00,0xF0,0x27,0x21,0x41,0x72,0xD2,0x54,0x57,0x51,0x52,0x72,0x54,0x07,0x00, + 0x08,0x88,0x90,0xFE,0x08,0x08,0x10,0x94,0xA4,0x38,0x08,0x10,0x10,0xA4,0xBC,0x84, + /* 0xB4C6 [?] [1824]*/ + 0x14,0x14,0x14,0x54,0x55,0x5E,0x54,0x54,0x54,0x54,0x54,0x54,0x5D,0x76,0xC4,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xB4C7 [?] [1825]*/ + 0x08,0x1C,0x70,0x11,0x10,0xFC,0x10,0x11,0x7C,0x44,0x45,0x44,0x44,0x7C,0x44,0x00, + 0x40,0x20,0x20,0xFC,0x00,0x88,0x50,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xB4C8 [?] [1826]*/ + 0x08,0x04,0xFF,0x10,0x10,0x24,0x78,0x10,0x24,0x7E,0x02,0x01,0x28,0x28,0x48,0x07, + 0x20,0x40,0xFE,0x20,0x20,0x48,0xF0,0x20,0x48,0xFC,0x04,0x00,0x88,0xA4,0x24,0xE0, + /* 0xB4C9 [?] [1827]*/ + 0x01,0x41,0x21,0x0A,0x14,0xE0,0x21,0x26,0x00,0x7F,0x08,0x0F,0x09,0x10,0x16,0x18, + 0x00,0x00,0xFC,0x44,0x48,0xA0,0x10,0x0C,0x00,0xFC,0x00,0xE0,0x20,0xA4,0x24,0x1C, + /* 0xB4CA [?] [1828]*/ + 0x00,0x23,0x10,0x10,0x07,0x00,0xF0,0x13,0x12,0x12,0x12,0x13,0x14,0x18,0x10,0x00, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x14,0x08, + /* 0xB4CB [?] [1829]*/ + 0x04,0x04,0x04,0x24,0x24,0x27,0x24,0x24,0x24,0x24,0x24,0x24,0x2F,0xF0,0x40,0x00, + 0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xB4CC [?] [1830]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7F,0x49,0x49,0x4D,0x4A,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x04,0x04,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x84,0x14,0x08, + /* 0xB4CD [?] [1831]*/ + 0x00,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x55,0x12,0x28,0x25,0x44,0x80, + 0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x40,0xFE,0x2A,0x4A,0x92,0x22,0x4A,0x84, + /* 0xB4CE [?] [1832]*/ + 0x00,0x40,0x20,0x20,0x01,0x09,0x0A,0x14,0x10,0xE0,0x20,0x21,0x21,0x22,0x24,0x08, + 0x80,0x80,0x80,0xFC,0x04,0x08,0x40,0x40,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xB4CF [?] [1833]*/ + 0x00,0xFC,0x48,0x49,0x79,0x49,0x49,0x79,0x48,0x48,0x4C,0x79,0xC9,0x09,0x0A,0x08, + 0x88,0x48,0x50,0xFC,0x04,0x04,0x04,0xFC,0x20,0x10,0x54,0x42,0x42,0x4A,0x38,0x00, + /* 0xB4D0 [?] [1834]*/ + 0x04,0x04,0xFF,0x04,0x08,0x1F,0x2A,0x44,0x0A,0x11,0x22,0x04,0x01,0x48,0x48,0x87, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x48,0x48,0x88,0x08,0xA8,0x10,0x00,0x84,0x12,0xF2, + /* 0xB4D1 [?] [1835]*/ + 0x04,0x08,0x7F,0x42,0x42,0x47,0x48,0x52,0x41,0x40,0x41,0x46,0x58,0x40,0x7F,0x40, + 0x00,0x00,0xFC,0x04,0x04,0xF4,0x14,0x24,0x44,0x84,0x44,0x24,0x04,0x04,0xFC,0x04, + /* 0xB4D2 [?] [1836]*/ + 0x08,0x08,0x08,0x1F,0x12,0x22,0x42,0x9C,0x06,0x09,0x10,0x21,0x42,0x04,0x08,0x10, + 0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x84,0xC4,0x24,0x14,0x04,0x28,0x10, + /* 0xB4D3 [?] [1837]*/ + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x14,0x12,0x12,0x20,0x21,0x42,0x84, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x04,0x02, + /* 0xB4D4 [?] [1838]*/ + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x14,0x12,0x22,0x20,0x41,0x82,0x00,0xFF,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x88,0x04,0x02,0x00,0xFE,0x00, + /* 0xB4D5 [?] [1839]*/ + 0x00,0x40,0x27,0x20,0x03,0x00,0x17,0x11,0x22,0xE5,0x20,0x23,0x20,0x20,0x21,0x06, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x08,0xF6,0x40,0xF8,0x40,0xA0,0x10,0x08, + /* 0xB4D6 [?] [1840]*/ + 0x10,0x11,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x17,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xB4D7 [?] [1841]*/ + 0x00,0xFE,0x28,0x29,0xFE,0xAA,0xAB,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x48,0x48,0x48,0xFE,0x48,0x48,0xFE,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xB4D8 [?] [1842]*/ + 0x20,0x3F,0x48,0x85,0x20,0x10,0xFE,0x21,0x20,0x3C,0x25,0x24,0x25,0x44,0x54,0x89, + 0x40,0x7E,0x90,0x08,0x40,0x40,0xFE,0x20,0x40,0xFC,0x20,0x20,0xFE,0x50,0x88,0x06, + /* 0xB4D9 [?] [1843]*/ + 0x08,0x0B,0x0A,0x12,0x12,0x32,0x33,0x50,0x90,0x12,0x12,0x12,0x12,0x15,0x18,0x10, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x00, + /* 0xB4DA [?] [1844]*/ + 0x00,0x78,0x4B,0x4A,0x49,0x7A,0x11,0x11,0x51,0x5C,0x53,0x52,0x5B,0xE2,0x00,0x00, + 0x40,0x20,0xFE,0x8A,0x24,0x22,0xFC,0x24,0xFC,0x20,0xFE,0x22,0xFE,0x22,0x20,0x20, + /* 0xB4DB [?] [1845]*/ + 0x20,0x3F,0x48,0x9F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x02,0x7F,0x04,0x1A,0xE4,0x0F, + 0x40,0x7E,0x90,0xF8,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x40,0x30,0x4E,0xE0, + /* 0xB4DC [?] [1846]*/ + 0x02,0x01,0x7F,0x48,0x91,0x01,0x3F,0x21,0x3F,0x01,0x7F,0x41,0x7F,0x41,0x01,0x01, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xF8,0x08,0xF8,0x00,0xFC,0x04,0xFC,0x04,0x00,0x00, + /* 0xB4DD [?] [1847]*/ + 0x10,0x12,0x13,0x10,0xFC,0x11,0x13,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x22,0xFE,0x90,0x88,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xB4DE [?] [1848]*/ + 0x01,0x41,0x7F,0x09,0x08,0x1F,0x10,0x30,0x5F,0x90,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x04,0xFC,0x00,0x80,0xFC,0x80,0x80,0xF8,0x80,0x80,0xF8,0x80,0x80,0xFC,0x00, + /* 0xB4DF [?] [1849]*/ + 0x08,0x0A,0x0B,0x10,0x10,0x31,0x33,0x55,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x22,0xFE,0x90,0x88,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xB4E0 [?] [1850]*/ + 0x00,0x3C,0x24,0x25,0x26,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x8A, + 0x40,0x40,0xFC,0x04,0x08,0xFE,0x00,0x7C,0x44,0x44,0x54,0x48,0x42,0x42,0x3E,0x00, + /* 0xB4E1 [?] [1851]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x51,0x11,0x32,0x54,0x90,0x1F,0x20,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x40,0xFC,0x10,0x10,0xA8,0x44,0x40,0xFE,0x40,0x40,0x40,0x40, + /* 0xB4E2 [?] [1852]*/ + 0x10,0x10,0x95,0x54,0x58,0x10,0xFD,0x32,0x38,0x54,0x55,0x90,0x10,0x10,0x10,0x10, + 0x40,0x20,0xFE,0x00,0x88,0x88,0x54,0x22,0x00,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xB4E3 [?] [1853]*/ + 0x00,0x20,0x17,0x10,0x81,0x41,0x42,0x14,0x10,0x20,0xE7,0x20,0x20,0x20,0x20,0x00, + 0x80,0x40,0xFC,0x00,0x10,0x10,0xA8,0x44,0x00,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xB4E4 [?] [1854]*/ + 0x00,0x7E,0x22,0x12,0x1A,0x62,0x02,0x01,0x7F,0x08,0x14,0x22,0x01,0xFF,0x01,0x01, + 0x00,0xFC,0x44,0x24,0x34,0xC4,0x04,0x00,0xFC,0x20,0x50,0x88,0x00,0xFE,0x00,0x00, + /* 0xB4E5 [?] [1855]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x38,0x55,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xB4E6 [?] [1856]*/ + 0x04,0x04,0xFF,0x08,0x08,0x13,0x10,0x30,0x50,0x97,0x10,0x10,0x10,0x10,0x11,0x10, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x10,0x20,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xB4E7 [?] [1857]*/ + 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x10,0x08,0x08,0x00,0x00,0x00,0x01,0x00, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xB4E8 [?] [1858]*/ + 0x00,0x00,0xFC,0x11,0x10,0x20,0x3C,0x65,0x64,0xA4,0x24,0x25,0x3E,0x24,0x21,0x00, + 0x84,0x44,0x48,0xFE,0x20,0xFC,0x20,0xFE,0x40,0x80,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xB4E9 [?] [1859]*/ + 0x20,0x23,0x22,0x23,0xFA,0x23,0x20,0x2F,0x34,0xE7,0x24,0x27,0x24,0x2F,0xA0,0x40, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x80,0xBC,0x94,0x94,0xD4,0x88,0x94,0xA2, + /* 0xB4EA [?] [1860]*/ + 0x11,0x10,0x10,0x13,0xFC,0x11,0x10,0x17,0x18,0x31,0xD1,0x12,0x14,0x18,0x53,0x20, + 0x08,0x88,0x90,0xFC,0x40,0xF8,0x40,0xFE,0x80,0x00,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xB4EB [?] [1861]*/ + 0x10,0x10,0x10,0x13,0xF8,0x10,0x17,0x18,0x31,0xD1,0x11,0x11,0x11,0x11,0x51,0x21, + 0x88,0x88,0x88,0xFE,0x88,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB4EC [?] [1862]*/ + 0x20,0x20,0x22,0x22,0xF2,0x25,0x28,0x20,0x30,0xE7,0x20,0x20,0x20,0x20,0xAF,0x40, + 0x40,0x40,0x48,0x48,0x48,0x54,0xE2,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xB4ED [?] [1863]*/ + 0x21,0x21,0x39,0x27,0x41,0x79,0xAF,0x20,0xFB,0x22,0x22,0x23,0x2A,0x32,0x23,0x02, + 0x10,0x10,0x10,0xFC,0x10,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB4EE [?] [1864]*/ + 0x21,0x21,0x27,0x21,0xF8,0x20,0x21,0x2A,0x35,0xE0,0x20,0x23,0x22,0x22,0xA3,0x42, + 0x10,0x10,0xFC,0x10,0x40,0xA0,0x10,0x08,0xF6,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB4EF [?] [1865]*/ + 0x00,0x20,0x10,0x10,0x07,0x00,0xF0,0x10,0x10,0x11,0x12,0x14,0x10,0x28,0x47,0x00, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0xA0,0x90,0x08,0x04,0x04,0x00,0x00,0xFE,0x00, + /* 0xB4F0 [?] [1866]*/ + 0x10,0x10,0x3F,0x28,0x45,0x82,0x0C,0x30,0xCF,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x80,0x60,0x18,0xE6,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xB4F1 [?] [1867]*/ + 0x00,0x00,0x1F,0x11,0x91,0x57,0x51,0x10,0x31,0x52,0x9C,0x13,0x22,0x22,0x43,0x82, + 0x80,0x40,0xFE,0x10,0x10,0xFC,0x50,0xA0,0x10,0xE8,0x06,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB4F2 [?] [1868]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x14,0x18,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB4F3 [?] [1869]*/ + 0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xB4F4 [?] [1870]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x01,0x01,0x7F,0x03,0x05,0x09,0x11,0x21,0xC1,0x01, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xFC,0x80,0x40,0x20,0x10,0x08,0x06,0x00, + /* 0xB4F5 [?] [1871]*/ + 0x00,0xFF,0x02,0x02,0x04,0x07,0x08,0x10,0x24,0x42,0x01,0x00,0x01,0x02,0x0C,0x70, + 0x00,0xFE,0x00,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xB4F6 [?] [1872]*/ + 0x08,0x08,0x0F,0x10,0x13,0x30,0x37,0x51,0x92,0x14,0x12,0x11,0x12,0x14,0x11,0x10, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x48,0x46,0x48,0x50,0x48,0x44,0x40,0x80, + /* 0xB4F7 [?] [1873]*/ + 0x08,0x7F,0x08,0xFF,0x00,0x7F,0x49,0x7F,0x49,0x7F,0x22,0x7F,0x22,0xFF,0x22,0x41, + 0x20,0x28,0x24,0xFE,0x20,0x20,0x24,0x24,0x24,0x28,0x28,0x10,0x12,0xAA,0x46,0x82, + /* 0xB4F8 [?] [1874]*/ + 0x09,0x09,0x7F,0x09,0x09,0x00,0x7F,0x41,0x81,0x1F,0x11,0x11,0x11,0x11,0x01,0x01, + 0x20,0x20,0xFC,0x20,0x20,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0x50,0x20,0x00,0x00, + /* 0xB4F9 [?] [1875]*/ + 0x00,0xFC,0x20,0x20,0x20,0x3C,0x45,0x44,0x64,0x94,0x08,0x08,0x10,0x20,0x40,0x80, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xB4FA [?] [1876]*/ + 0x08,0x08,0x08,0x10,0x10,0x37,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x90,0x88,0x88,0x80,0xBE,0xC0,0x80,0x40,0x40,0x40,0x20,0x22,0x12,0x0A,0x06,0x02, + /* 0xB4FB [?] [1877]*/ + 0x08,0x10,0x30,0xD7,0x10,0x10,0x00,0x1F,0x10,0x11,0x11,0x11,0x12,0x04,0x18,0x60, + 0x90,0x88,0x7E,0xC0,0x22,0x1A,0x06,0xF0,0x10,0x10,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xB4FC [?] [1878]*/ + 0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x12,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0xA0,0x90,0xBE,0xC0,0x40,0x24,0x14,0x0C,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xB4FD [?] [1879]*/ + 0x08,0x08,0x10,0x23,0x48,0x08,0x17,0x30,0x50,0x97,0x10,0x12,0x11,0x11,0x10,0x10, + 0x40,0x40,0x40,0xFC,0x40,0x40,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xB4FE [?] [1880]*/ + 0x00,0x20,0x13,0x10,0x07,0x00,0xF3,0x14,0x12,0x11,0x12,0x14,0x11,0x28,0x47,0x00, + 0x40,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x44,0x48,0x50,0x48,0x44,0x40,0x80,0xFE,0x00, + /* 0xB5A1 [?] [1881]*/ + 0x02,0x04,0x08,0x10,0x3F,0x00,0x1F,0x10,0x10,0x1F,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0x20,0x10,0xF8,0x08,0xF0,0x10,0x10,0xF0,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xB5A2 [?] [1882]*/ + 0x00,0xFC,0x48,0x4B,0x7A,0x4C,0x48,0x78,0x48,0x48,0x4C,0x79,0xC9,0x0A,0x0C,0x08, + 0x40,0x40,0x40,0xFC,0x44,0x48,0x40,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xB5A3 [?] [1883]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x10,0x10,0x53,0x20, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xB5A4 [?] [1884]*/ + 0x00,0x1F,0x10,0x10,0x12,0x11,0x11,0x10,0xFF,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xB5A5 [?] [1885]*/ + 0x10,0x08,0x04,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01, + 0x10,0x20,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xB5A6 [?] [1886]*/ + 0x41,0x22,0x14,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x08,0x08,0xFF,0x08,0x08,0x08, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0xA8,0x20,0x20,0x20, + /* 0xB5A7 [?] [1887]*/ + 0x11,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD0,0x10,0x13,0x10,0x50,0x20, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xB5A8 [?] [1888]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x55,0x88, + 0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x00,0x00,0xFE,0x00, + /* 0xB5A9 [?] [1889]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0xFF,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0xFE,0x00, + /* 0xB5AA [?] [1890]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x04,0x24,0x0B,0x10,0x60,0x04,0x24,0x0B,0x10,0x60, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x10,0x90,0x50,0x12,0x8A,0x0A,0x86,0x42, + /* 0xB5AB [?] [1891]*/ + 0x08,0x08,0x0B,0x12,0x12,0x32,0x33,0x52,0x92,0x12,0x13,0x12,0x10,0x10,0x17,0x10, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xB5AC [?] [1892]*/ + 0x11,0x10,0x10,0x11,0x19,0x55,0x51,0x51,0x91,0x11,0x10,0x10,0x13,0x10,0x10,0x10, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xB5AD [?] [1893]*/ + 0x00,0x22,0x12,0x14,0x80,0x41,0x46,0x10,0x10,0x22,0xE2,0x24,0x20,0x21,0x22,0x0C, + 0x40,0x44,0x44,0x48,0xA0,0x10,0x08,0x44,0x40,0x48,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xB5AE [?] [1894]*/ + 0x00,0x40,0x2F,0x21,0x02,0x04,0xEF,0x21,0x29,0x29,0x25,0x2A,0x33,0x24,0x08,0x10, + 0x08,0x1C,0x70,0x10,0x10,0x50,0x5C,0x50,0x50,0x50,0x50,0x7C,0x00,0x80,0x7E,0x00, + /* 0xB5AF [?] [1895]*/ + 0x01,0xF8,0x08,0x09,0x09,0x79,0x41,0x41,0x41,0x79,0x08,0x08,0x0B,0x08,0x50,0x20, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xB5B0 [?] [1896]*/ + 0x7F,0x01,0x11,0x11,0x11,0x29,0x47,0x81,0x1F,0x11,0x11,0x1F,0x11,0x01,0x7F,0x20, + 0xFC,0x04,0x00,0xF8,0x00,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xB5B1 [?] [1897]*/ + 0x01,0x21,0x11,0x09,0x09,0x01,0x7F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x7F,0x00, + 0x00,0x08,0x08,0x10,0x20,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xB5B2 [?] [1898]*/ + 0x10,0x12,0x11,0x11,0xFD,0x10,0x17,0x10,0x18,0x30,0xD3,0x10,0x10,0x10,0x57,0x20, + 0x40,0x44,0x44,0x44,0x48,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB5B3 [?] [1899]*/ + 0x01,0x11,0x09,0x09,0x7F,0x40,0x80,0x1F,0x10,0x10,0x1F,0x04,0x04,0x08,0x30,0xC0, + 0x00,0x10,0x10,0x20,0xFE,0x02,0x04,0xF0,0x10,0x10,0xF0,0x40,0x40,0x42,0x42,0x3E, + /* 0xB5B4 [?] [1900]*/ + 0x08,0x08,0xFF,0x08,0x00,0x23,0x10,0x10,0x80,0x4B,0x48,0x11,0xE2,0x24,0x21,0x22, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x20,0x40,0x80,0xFC,0xA4,0x24,0x44,0x84,0x28,0x10, + /* 0xB5B5 [?] [1901]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x33,0x38,0x54,0x50,0x91,0x10,0x10,0x10,0x13,0x10, + 0x20,0x24,0xA4,0xA4,0xA8,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB5B6 [?] [1902]*/ + 0x00,0x00,0x3F,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB5B7 [?] [1903]*/ + 0x20,0x20,0x23,0x22,0xFA,0x22,0x22,0x2A,0x33,0xE0,0x24,0x24,0x27,0x20,0xA0,0x40, + 0x40,0x80,0xF8,0x08,0x88,0x48,0x18,0x00,0xFE,0x82,0x92,0x92,0xF2,0x02,0x14,0x08, + /* 0xB5B8 [?] [1904]*/ + 0x00,0x7D,0x44,0x45,0x44,0x7C,0x10,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01, + 0x1E,0xE0,0x22,0x12,0x94,0x80,0x20,0xCE,0x02,0x02,0xCE,0x02,0x02,0x02,0xFE,0x02, + /* 0xB5B9 [?] [1905]*/ + 0x10,0x10,0x1F,0x22,0x22,0x64,0x67,0xA1,0x21,0x27,0x21,0x21,0x21,0x2E,0x24,0x20, + 0x04,0x04,0xC4,0x14,0x14,0x94,0xD4,0x14,0x14,0xD4,0x14,0x14,0xC4,0x04,0x14,0x08, + /* 0xB5BA [?] [1906]*/ + 0x01,0x02,0x1F,0x10,0x12,0x11,0x10,0x10,0x1F,0x02,0x22,0x22,0x3F,0x00,0x00,0x00, + 0x00,0x00,0xF0,0x10,0x10,0x50,0x20,0x00,0xFC,0x04,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xB5BB [?] [1907]*/ + 0x20,0x10,0x13,0xF8,0x09,0x10,0x13,0x38,0x54,0x94,0x11,0x11,0x12,0x14,0x10,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x48,0x88,0xFE,0x08,0x48,0x28,0x08,0x28,0x10, + /* 0xB5BC [?] [1908]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x1F,0x00,0x00,0xFF,0x08,0x04,0x04,0x00,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xB5BD [?] [1909]*/ + 0x00,0xFF,0x08,0x10,0x22,0x41,0xFF,0x08,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF8,0x40, + 0x04,0x84,0x04,0x24,0x24,0x24,0xA4,0xA4,0x24,0x24,0x24,0x24,0x04,0x84,0x14,0x08, + /* 0xB5BE [?] [1910]*/ + 0x08,0x1D,0xF0,0x11,0x10,0xFC,0x10,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x1E,0xE0,0x22,0x12,0x94,0x80,0x20,0xCE,0x02,0x02,0xCE,0x02,0x02,0x02,0xFE,0x02, + /* 0xB5BF [?] [1911]*/ + 0x10,0x10,0x10,0x10,0x1B,0x56,0x53,0x52,0x93,0x12,0x10,0x17,0x10,0x10,0x10,0x10, + 0x40,0x40,0x7E,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x44,0x40,0xFE,0x40,0x40,0x40,0x40, + /* 0xB5C0 [?] [1912]*/ + 0x02,0x21,0x10,0x17,0x00,0x03,0xF2,0x13,0x12,0x13,0x12,0x13,0x12,0x28,0x47,0x00, + 0x08,0x10,0x00,0xFC,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xB5C1 [?] [1913]*/ + 0x40,0x20,0x09,0x12,0x24,0xE0,0x20,0x23,0x2C,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x80,0x80,0xFC,0x04,0x48,0x40,0xA0,0x18,0x06,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xB5C2 [?] [1914]*/ + 0x10,0x10,0x2F,0x40,0x97,0x14,0x24,0x67,0xA0,0x2F,0x20,0x20,0x25,0x25,0x29,0x20, + 0x40,0x40,0xFE,0x40,0xFC,0xA4,0xA4,0xFC,0x00,0xFE,0x40,0x24,0x22,0x0A,0x08,0xF8, + /* 0xB5C3 [?] [1915]*/ + 0x08,0x0B,0x12,0x23,0x4A,0x0B,0x10,0x33,0x50,0x97,0x10,0x12,0x11,0x10,0x10,0x10, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x10,0xFE,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xB5C4 [?] [1916]*/ + 0x10,0x10,0x20,0x7E,0x42,0x42,0x43,0x42,0x7E,0x42,0x42,0x42,0x42,0x7E,0x42,0x00, + 0x40,0x40,0x40,0x7C,0x84,0x84,0x04,0x44,0x24,0x24,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xB5C5 [?] [1917]*/ + 0x00,0x7B,0x48,0x49,0x48,0x79,0x12,0x14,0x51,0x5D,0x51,0x51,0x59,0xE0,0x07,0x00, + 0x10,0xD2,0x54,0x48,0x8A,0x04,0xFA,0x00,0xFC,0x04,0x04,0xFC,0x04,0x88,0xFE,0x00, + /* 0xB5C6 [?] [1918]*/ + 0x10,0x10,0x13,0x10,0x54,0x58,0x50,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x40,0x80, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB5C7 [?] [1919]*/ + 0x00,0x3E,0x02,0x24,0x14,0x08,0x17,0x20,0xDF,0x10,0x10,0x1F,0x08,0x04,0x7F,0x00, + 0x80,0x90,0xA4,0x48,0x50,0x20,0xD0,0x08,0xF6,0x10,0x10,0xF0,0x20,0x40,0xFC,0x00, + /* 0xB5C8 [?] [1920]*/ + 0x20,0x3F,0x48,0x85,0x01,0x3F,0x01,0x01,0xFF,0x00,0x00,0x7F,0x08,0x04,0x04,0x00, + 0x40,0x7E,0x90,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00,0x20,0xFC,0x20,0x20,0xA0,0x40, + /* 0xB5C9 [?] [1921]*/ + 0x00,0x07,0xF0,0x92,0x91,0xF2,0x95,0x98,0xF3,0x92,0x92,0x93,0xF2,0x91,0x0F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xB5CA [?] [1922]*/ + 0x00,0x7E,0x04,0x2B,0x10,0x2F,0xC8,0x0F,0x04,0x7F,0x00,0x0F,0x08,0x08,0x10,0x60, + 0x90,0xA0,0x44,0xA8,0x10,0xE8,0x26,0xE0,0x40,0xFC,0x00,0xE0,0x20,0x22,0x22,0x1E, + /* 0xB5CB [?] [1923]*/ + 0x00,0x7E,0x02,0x02,0x42,0x24,0x14,0x08,0x08,0x14,0x14,0x22,0x42,0x80,0x00,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xB5CC [?] [1924]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x10,0x13,0x10,0x1D,0xE1,0x41,0x02,0x04, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x20,0x20,0x3C,0x20,0xA0,0x7E, + /* 0xB5CD [?] [1925]*/ + 0x08,0x08,0x0B,0x12,0x12,0x32,0x32,0x53,0x92,0x12,0x12,0x12,0x12,0x12,0x13,0x12, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xB5CE [?] [1926]*/ + 0x00,0x20,0x17,0x11,0x80,0x47,0x44,0x15,0x14,0x25,0xE5,0x25,0x25,0x24,0x24,0x04, + 0x80,0x40,0xFC,0x10,0xA0,0xFC,0x44,0xF4,0x44,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xB5CF [?] [1927]*/ + 0x00,0x40,0x20,0x27,0x04,0x04,0xE4,0x27,0x24,0x24,0x24,0x27,0x20,0x50,0x8F,0x00, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x00,0x00,0xFE,0x00, + /* 0xB5D0 [?] [1928]*/ + 0x04,0x0E,0x38,0x08,0x08,0xFF,0x08,0x08,0x3E,0x22,0x22,0x22,0x22,0x3E,0x22,0x01, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xB5D1 [?] [1929]*/ + 0x10,0x10,0x3F,0x28,0x45,0x81,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x20, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xB5D2 [?] [1930]*/ + 0x00,0x44,0x28,0x10,0x29,0x49,0x89,0x0A,0x18,0x28,0x48,0x88,0x09,0x09,0x52,0x24, + 0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x50,0x40,0xA0,0xA0,0x90,0x10,0x08,0x04,0x02, + /* 0xB5D3 [?] [1931]*/ + 0x00,0x20,0x11,0x13,0x84,0x40,0x41,0x16,0x10,0x27,0xE0,0x22,0x22,0x24,0x21,0x00, + 0x80,0x80,0xF8,0x08,0x90,0x60,0x98,0x46,0x40,0xFC,0x40,0x48,0x44,0x44,0x40,0x80, + /* 0xB5D4 [?] [1932]*/ + 0x00,0x7E,0x22,0x12,0x1A,0x62,0x02,0x09,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x10, + 0x00,0xFC,0x44,0x24,0x34,0xC4,0x04,0x00,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00, + /* 0xB5D5 [?] [1933]*/ + 0x20,0x20,0x23,0x20,0xF8,0x4B,0x4A,0x4A,0x4A,0x92,0x52,0x22,0x32,0x4A,0x4A,0x82, + 0x40,0x20,0xFE,0x88,0x50,0xFE,0x22,0xFA,0x22,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xB5D6 [?] [1934]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x12,0x13,0x1A,0x32,0xD2,0x12,0x12,0x12,0x53,0x22, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xB5D7 [?] [1935]*/ + 0x01,0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x24,0x24,0x24,0x45,0x46,0x84, + 0x00,0x80,0xFE,0x00,0x3C,0xC0,0x40,0x40,0x40,0xFE,0x20,0x20,0x12,0x0A,0x46,0x22, + /* 0xB5D8 [?] [1936]*/ + 0x10,0x10,0x10,0x11,0x11,0xFD,0x11,0x13,0x11,0x11,0x11,0x1D,0xE1,0x41,0x00,0x00, + 0x20,0x20,0x20,0x20,0x2C,0x34,0x64,0xA4,0x24,0x34,0x28,0x22,0x22,0x02,0xFE,0x00, + /* 0xB5D9 [?] [1937]*/ + 0x08,0xFF,0x0A,0x01,0x3F,0x08,0x04,0x7F,0x41,0x81,0x1F,0x11,0x11,0x11,0x01,0x01, + 0x20,0xFE,0x20,0x00,0xF8,0x20,0x40,0xFE,0x02,0x04,0xF0,0x10,0x50,0x20,0x00,0x00, + /* 0xB5DA [?] [1938]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x01,0x01,0x3F,0x21,0x21,0x3F,0x03,0x05,0x19,0xE1,0x01, + 0x40,0x7E,0x90,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x28,0x10,0x00, + /* 0xB5DB [?] [1939]*/ + 0x02,0x01,0x3F,0x00,0x08,0x04,0x7F,0x41,0x81,0x1F,0x11,0x11,0x11,0x11,0x01,0x01, + 0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x02,0x04,0xF0,0x10,0x10,0x50,0x20,0x00,0x00, + /* 0xB5DC [?] [1940]*/ + 0x08,0x04,0x04,0x7F,0x01,0x01,0x3F,0x21,0x21,0x3F,0x03,0x05,0x09,0x11,0x61,0x01, + 0x20,0x20,0x40,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x14,0x08,0x00,0x00, + /* 0xB5DD [?] [1941]*/ + 0x01,0x20,0x13,0x10,0x00,0x03,0xF2,0x12,0x13,0x10,0x11,0x12,0x14,0x28,0x47,0x00, + 0x10,0xA0,0xF8,0x48,0x48,0xF8,0x40,0x40,0xFC,0xC4,0x44,0x54,0x48,0x40,0xFE,0x00, + /* 0xB5DE [?] [1942]*/ + 0x10,0x10,0x21,0x24,0x44,0xF8,0x13,0x22,0x44,0xFD,0x41,0x01,0x1D,0xE1,0x40,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xB5DF [?] [1943]*/ + 0x08,0x08,0x7F,0x08,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x7F,0x14,0x22,0x41, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xB5E0 [?] [1944]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x12,0x12,0x1A,0x32,0xD2,0x12,0x12,0x14,0x54,0x28, + 0x40,0x20,0xFE,0x00,0x20,0x20,0x3E,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xB5E1 [?] [1945]*/ + 0x00,0x20,0x17,0x10,0x83,0x42,0x43,0x12,0x13,0x22,0xE3,0x22,0x2F,0x21,0x22,0x04, + 0x40,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFE,0x10,0x08,0x04, + /* 0xB5E2 [?] [1946]*/ + 0x00,0x00,0xFC,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x27,0x3C,0x24,0x21,0x02, + 0x50,0x50,0x50,0xFC,0x54,0x54,0x54,0xFC,0x54,0x54,0x54,0xFE,0x00,0x88,0x04,0x02, + /* 0xB5E3 [?] [1947]*/ + 0x02,0x02,0x02,0x03,0x02,0x02,0x3F,0x20,0x20,0x20,0x3F,0x00,0x24,0x22,0x42,0x80, + 0x00,0x00,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x88,0x44,0x44,0x04, + /* 0xB5E4 [?] [1948]*/ + 0x04,0x04,0x04,0x3F,0x24,0x24,0x24,0x3F,0x24,0x24,0x24,0xFF,0x04,0x08,0x10,0x20, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0xF8,0x48,0x48,0x48,0xFE,0x40,0x20,0x10,0x08, + /* 0xB5E5 [?] [1949]*/ + 0x10,0x10,0xFE,0x10,0x7D,0x10,0xFE,0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x55,0x4A, + 0x20,0x10,0xFE,0x82,0x04,0x00,0xFE,0x10,0x10,0x90,0x9E,0x90,0x90,0xD0,0x3E,0x00, + /* 0xB5E6 [?] [1950]*/ + 0x08,0x08,0x7D,0x08,0x0C,0x19,0x68,0x08,0x28,0x11,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x40,0x40,0xF8,0x48,0x48,0xC8,0x4A,0xAA,0x86,0x02,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB5E7 [?] [1951]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x0A,0x02,0x02,0xFE, + /* 0xB5E8 [?] [1952]*/ + 0x10,0x10,0x17,0x24,0x24,0x64,0x64,0xA7,0x24,0x24,0x24,0x24,0x24,0x27,0x24,0x20, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x04,0x00, + /* 0xB5E9 [?] [1953]*/ + 0x08,0x08,0x10,0x1F,0x20,0x40,0xBF,0x24,0x24,0x3F,0x24,0x24,0x3F,0x20,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x50,0x20, + /* 0xB5EA [?] [1954]*/ + 0x01,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x27,0x24,0x24,0x44,0x44,0x87,0x04, + 0x00,0x80,0xFE,0x80,0x80,0x80,0xFC,0x80,0x80,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB5EB [?] [1955]*/ + 0x10,0x10,0x13,0x12,0x1A,0x56,0x52,0x52,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18, + 0x40,0x20,0xFE,0x00,0x20,0x20,0x3E,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xB5EC [?] [1956]*/ + 0x08,0x04,0xFF,0x04,0x3F,0x28,0x30,0x27,0x20,0x3F,0x01,0x7F,0x02,0x04,0x18,0xE0, + 0x20,0x40,0xFE,0x40,0xF8,0x48,0x38,0xC8,0x08,0xF8,0x00,0xFC,0x80,0x40,0x30,0x0E, + /* 0xB5ED [?] [1957]*/ + 0x00,0x20,0x13,0x12,0x84,0x40,0x43,0x10,0x10,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xB5EE [?] [1958]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x20,0x2A,0x2A,0x3F,0x2A,0x2A,0x3F,0x20,0x4A,0x91,0x21, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB5EF [?] [1959]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x22,0x02,0x04, + 0x00,0xFC,0x24,0x24,0x74,0x24,0xFC,0x04,0x74,0x54,0x54,0x74,0x04,0x04,0x14,0x08, + /* 0xB5F0 [?] [1960]*/ + 0x00,0x03,0x78,0x48,0x48,0x48,0x48,0x48,0x48,0x49,0x4A,0x78,0x48,0x00,0x00,0x00, + 0x00,0xFC,0x04,0x04,0x04,0x14,0x24,0x44,0x84,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xB5F1 [?] [1961]*/ + 0x00,0x7F,0x49,0x49,0x5D,0x49,0x7F,0x41,0x5D,0x55,0x55,0x5D,0x41,0x41,0x45,0x82, + 0x28,0x24,0x40,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x48,0x7E,0x40,0x40, + /* 0xB5F2 [?] [1962]*/ + 0x00,0x47,0x24,0x24,0x05,0x04,0x14,0x17,0x24,0xE5,0x25,0x25,0x25,0x24,0x24,0x08, + 0x00,0xFC,0x44,0x44,0xF4,0x44,0x44,0xFC,0x04,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xB5F3 [?] [1963]*/ + 0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x60,0x00,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x48,0x88,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB5F4 [?] [1964]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x15,0x19,0x31,0xD1,0x10,0x13,0x10,0x10,0x50,0x20, + 0x20,0x20,0x3E,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xB5F5 [?] [1965]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xB5F6 [?] [1966]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBE,0x10,0x11,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xB5F7 [?] [1967]*/ + 0x00,0x47,0x24,0x24,0x05,0x04,0xE4,0x27,0x24,0x25,0x25,0x2D,0x35,0x24,0x04,0x08, + 0x00,0xFC,0x44,0x44,0xF4,0x44,0x44,0xFC,0x04,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xB5F8 [?] [1968]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x12,0x10,0x11,0x5C,0x50,0x50,0x50,0x5C,0xE1,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB5F9 [?] [1969]*/ + 0x04,0x08,0x18,0x24,0x03,0x0C,0x32,0xC7,0x1A,0x01,0x1E,0x01,0x0E,0x00,0x03,0x3C, + 0x40,0x20,0x50,0x88,0x00,0xC0,0x30,0xCE,0x40,0xA0,0x78,0x88,0x90,0x60,0x80,0x00, + /* 0xB5FA [?] [1970]*/ + 0x00,0x02,0xFA,0x27,0x22,0x42,0x7A,0xCA,0x4B,0x48,0x4F,0x48,0x79,0x42,0x0C,0x00, + 0x90,0x90,0x90,0xFE,0x90,0x90,0xF0,0x00,0xFC,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xB5FB [?] [1971]*/ + 0x20,0x21,0x21,0xFB,0xA9,0xA9,0xA9,0xA9,0xF9,0xA0,0x23,0x28,0x38,0xE9,0x46,0x00, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xB5FC [?] [1972]*/ + 0x00,0x22,0x12,0x13,0x02,0x04,0xF0,0x17,0x10,0x10,0x10,0x11,0x12,0x28,0x47,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0xA0,0x90,0x08,0x08,0x00,0xFE,0x00, + /* 0xB5FD [?] [1973]*/ + 0x00,0x42,0x22,0x27,0x02,0x02,0xE2,0x22,0x23,0x20,0x27,0x20,0x29,0x32,0x2C,0x00, + 0x90,0x90,0x90,0xFE,0x90,0x90,0xF0,0x00,0xFC,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xB5FE [?] [1974]*/ + 0x1F,0x04,0x03,0x0C,0x7E,0x22,0x1C,0x62,0x00,0xFF,0x90,0x1F,0x10,0x1F,0x10,0xFF, + 0xE0,0x40,0x80,0x40,0xFC,0x44,0x38,0x44,0x00,0xFE,0x12,0xF0,0x10,0xF0,0x10,0xFE, + /* 0xB6A1 [?] [1975]*/ + 0x00,0x7F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB6A2 [?] [1976]*/ + 0x00,0x00,0x7B,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x48,0x78,0x48,0x00,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB6A3 [?] [1977]*/ + 0x00,0x00,0x7B,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB6A4 [?] [1978]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB6A5 [?] [1979]*/ + 0x00,0x01,0xFE,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x50,0x21,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xB6A6 [?] [1980]*/ + 0x0F,0x08,0x0F,0x48,0x4F,0x48,0x4F,0x40,0x7C,0x04,0x04,0xFC,0x24,0x24,0x44,0x84, + 0xE0,0x20,0xE0,0x24,0xE4,0x24,0xE4,0x04,0x7C,0x40,0x40,0x7C,0x44,0x44,0x44,0x44, + /* 0xB6A7 [?] [1981]*/ + 0x20,0x20,0x3B,0x22,0x44,0x78,0xA3,0x20,0xF8,0x21,0x21,0x21,0x2A,0x32,0x24,0x08, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xB6A8 [?] [1982]*/ + 0x02,0x01,0x7F,0x40,0x80,0x00,0x3F,0x01,0x01,0x11,0x11,0x11,0x11,0x29,0x47,0x80, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xB6A9 [?] [1983]*/ + 0x00,0x20,0x13,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xB6AA [?] [1984]*/ + 0x00,0x00,0x3F,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x02,0x04,0x08,0x10,0x3F,0x10, + 0x10,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x20,0x10,0xF8,0x08, + /* 0xB6AB [?] [1985]*/ + 0x02,0x02,0x02,0x7F,0x04,0x09,0x11,0x21,0x3F,0x01,0x09,0x11,0x21,0x41,0x05,0x02, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x20,0x10,0x08,0x04,0x00,0x00, + /* 0xB6AC [?] [1986]*/ + 0x04,0x04,0x0F,0x10,0x28,0x44,0x03,0x0C,0x30,0xC0,0x07,0x00,0x00,0x0E,0x01,0x00, + 0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x60,0x18,0x06,0x00,0xC0,0x20,0x00,0x80,0x40, + /* 0xB6AD [?] [1987]*/ + 0x08,0xFF,0x08,0x1F,0x01,0x7F,0x01,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x3F,0x01,0xFF, + 0x20,0xFE,0x20,0xF0,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x00,0xFE, + /* 0xB6AE [?] [1988]*/ + 0x21,0x27,0x21,0x23,0x30,0xAF,0xA0,0xA3,0xA2,0x23,0x22,0x23,0x20,0x27,0x20,0x2F, + 0x10,0xFE,0x10,0xF8,0x40,0xFC,0x40,0xF8,0x48,0xF8,0x48,0xF8,0x40,0xFC,0x40,0xFE, + /* 0xB6AF [?] [1989]*/ + 0x00,0x00,0x7C,0x00,0x01,0x00,0xFE,0x20,0x20,0x20,0x48,0x44,0xFD,0x45,0x02,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xB6B0 [?] [1990]*/ + 0x10,0x10,0x10,0x17,0xF8,0x11,0x31,0x3A,0x57,0x50,0x91,0x11,0x12,0x14,0x10,0x10, + 0x40,0x40,0x40,0xFE,0x80,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xB6B1 [?] [1991]*/ + 0x10,0x17,0x14,0x24,0x25,0x64,0x64,0xA5,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x04,0x14,0x08, + /* 0xB6B2 [?] [1992]*/ + 0x20,0x27,0x24,0x24,0x35,0xAC,0xA4,0xA5,0xA5,0x25,0x25,0x25,0x24,0x24,0x24,0x24, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x04,0x14,0x08, + /* 0xB6B3 [?] [1993]*/ + 0x00,0x40,0x20,0x27,0x00,0x09,0x09,0x12,0x13,0xE0,0x21,0x21,0x22,0x24,0x20,0x00, + 0x40,0x40,0x40,0xFE,0x80,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xB6B4 [?] [1994]*/ + 0x00,0x27,0x14,0x14,0x85,0x44,0x44,0x15,0x15,0x25,0xE5,0x25,0x24,0x24,0x24,0x04, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x04,0x14,0x08, + /* 0xB6B5 [?] [1995]*/ + 0x01,0x12,0x67,0x44,0x44,0x47,0x44,0x44,0x57,0x60,0x04,0x04,0x04,0x08,0x10,0x60, + 0x00,0x00,0xDC,0x44,0x44,0xC4,0x44,0x44,0xC4,0x1C,0x40,0x40,0x40,0x44,0x44,0x3C, + /* 0xB6B6 [?] [1996]*/ + 0x10,0x11,0x10,0x10,0xFC,0x11,0x10,0x14,0x18,0x30,0xD3,0x10,0x10,0x10,0x50,0x20, + 0x10,0x10,0x90,0x90,0x10,0x10,0x90,0x90,0x10,0x1E,0xF0,0x10,0x10,0x10,0x10,0x10, + /* 0xB6B7 [?] [1997]*/ + 0x00,0x04,0x02,0x02,0x10,0x08,0x08,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xB6B8 [?] [1998]*/ + 0x00,0x7C,0x45,0x48,0x48,0x50,0x4B,0x48,0x44,0x45,0x45,0x69,0x52,0x42,0x44,0x48, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xB6B9 [?] [1999]*/ + 0x00,0x7F,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x10,0x08,0x04,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x00,0x10,0x20,0x40,0xFE,0x00, + /* 0xB6BA [?] [2000]*/ + 0x00,0x27,0x10,0x10,0x03,0x02,0xF2,0x13,0x10,0x12,0x11,0x17,0x10,0x28,0x47,0x00, + 0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x00,0x08,0x10,0xFC,0x00,0x00,0xFE,0x00, + /* 0xB6BB [?] [2001]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x13,0x32,0x52,0x93,0x10,0x21,0x20,0x4F,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x00,0xF8,0x08,0x08,0xF8,0x00,0x10,0xA0,0xFE,0x00, + /* 0xB6BC [?] [2002]*/ + 0x08,0x08,0x7E,0x09,0x0A,0xFF,0x08,0x10,0x3F,0x61,0xA1,0x3F,0x21,0x21,0x3F,0x21, + 0x00,0xBE,0xA2,0x24,0x24,0xE8,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xB6BD [?] [2003]*/ + 0x08,0x0E,0x08,0xFF,0x08,0x2A,0x49,0x08,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0xFC,0x44,0x44,0x28,0x10,0x28,0x44,0xF2,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xB6BE [?] [2004]*/ + 0x01,0x3F,0x01,0x1F,0x01,0x7F,0x00,0x1F,0x12,0x11,0xFF,0x22,0x21,0x3F,0x00,0x00, + 0x00,0xF8,0x00,0xF0,0x00,0xFC,0x00,0xF0,0x10,0x10,0xFE,0x10,0x10,0xFC,0x10,0x60, + /* 0xB6BF [?] [2005]*/ + 0x10,0x10,0x51,0x50,0x7C,0x53,0x90,0x10,0x1C,0xF1,0x50,0x13,0x10,0x10,0x10,0x13, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x10,0x90,0xFE,0x28,0x44,0x82,0x02, + /* 0xB6C0 [?] [2006]*/ + 0x00,0x44,0x28,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x48,0x88,0x08,0x0B,0x51,0x20, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x28,0x24,0xFE,0x02,0x00, + /* 0xB6C1 [?] [2007]*/ + 0x00,0x20,0x11,0x10,0x00,0x03,0xF0,0x10,0x10,0x11,0x10,0x13,0x14,0x18,0x10,0x03, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x10,0x90,0xFE,0x28,0x44,0x82,0x02, + /* 0xB6C2 [?] [2008]*/ + 0x20,0x20,0x23,0x20,0xF8,0x27,0x20,0x20,0x21,0x2B,0x35,0x21,0xC1,0x01,0x01,0x01, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB6C3 [?] [2009]*/ + 0x00,0x00,0x7B,0x48,0x48,0x7F,0x48,0x48,0x79,0x4B,0x4D,0x49,0x79,0x49,0x01,0x01, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB6C4 [?] [2010]*/ + 0x00,0x7C,0x45,0x54,0x54,0x57,0x54,0x54,0x54,0x55,0x56,0x10,0x28,0x24,0x44,0x80, + 0x20,0x22,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xB6C5 [?] [2011]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x17,0x10, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB6C6 [?] [2012]*/ + 0x20,0x20,0x3B,0x22,0x42,0x7B,0xA2,0x22,0xFA,0x22,0x22,0x22,0x2A,0x34,0x24,0x09, + 0x40,0x20,0xFE,0x48,0x48,0xFE,0x48,0x78,0x00,0xFC,0x44,0x48,0x28,0x10,0x68,0x86, + /* 0xB6C7 [?] [2013]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x25,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x57,0x88, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB6C8 [?] [2014]*/ + 0x01,0x00,0x3F,0x22,0x22,0x3F,0x22,0x22,0x23,0x20,0x2F,0x24,0x42,0x41,0x86,0x38, + 0x00,0x80,0xFE,0x20,0x20,0xFC,0x20,0x20,0xE0,0x00,0xF0,0x10,0x20,0xC0,0x30,0x0E, + /* 0xB6C9 [?] [2015]*/ + 0x00,0x20,0x17,0x14,0x84,0x47,0x44,0x14,0x14,0x25,0xE4,0x24,0x24,0x28,0x28,0x13, + 0x40,0x20,0xFE,0x88,0x88,0xFE,0x88,0xF8,0x00,0xFC,0x84,0x88,0x50,0x20,0xD8,0x06, + /* 0xB6CA [?] [2016]*/ + 0x10,0x10,0x10,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x2A,0x46,0x84,0x08, + 0x40,0x20,0x20,0xFE,0x02,0x02,0x02,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB6CB [?] [2017]*/ + 0x20,0x11,0x11,0xFD,0x01,0x08,0x8B,0x88,0x48,0x49,0x51,0x51,0x1D,0xE1,0x41,0x01, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFE,0x20,0x40,0xFC,0x54,0x54,0x54,0x54,0x54,0x0C, + /* 0xB6CC [?] [2018]*/ + 0x20,0x21,0x3C,0x50,0x90,0x10,0x10,0xFE,0x10,0x10,0x10,0x28,0x24,0x44,0x41,0x80, + 0x00,0xFE,0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x84,0x44,0x48,0x00,0xFE,0x00, + /* 0xB6CD [?] [2019]*/ + 0x20,0x23,0x3A,0x22,0x43,0x7A,0xA2,0x22,0xFB,0x22,0x22,0x23,0x2E,0x32,0x22,0x02, + 0x80,0x38,0x28,0x28,0xA8,0x46,0x00,0x7C,0xA4,0x24,0x28,0xA8,0x10,0x28,0x44,0x82, + /* 0xB6CE [?] [2020]*/ + 0x06,0x38,0x20,0x20,0x20,0x3C,0x21,0x20,0x3D,0x20,0x20,0x2C,0xF0,0x20,0x20,0x23, + 0x00,0xF8,0x88,0x88,0x88,0x86,0x00,0x00,0xFC,0x84,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xB6CF [?] [2021]*/ + 0x04,0x04,0x55,0x4E,0x44,0x7F,0x44,0x4E,0x55,0x65,0x44,0x44,0x40,0x7F,0x00,0x01, + 0x00,0x04,0x78,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xB6D0 [?] [2022]*/ + 0x10,0x13,0x22,0x22,0x4B,0xFA,0x12,0x22,0x43,0xFA,0x42,0x03,0x1E,0xE2,0x42,0x02, + 0x80,0x38,0x28,0x28,0xA8,0x46,0x00,0x7C,0xA4,0x24,0x28,0xA8,0x10,0x28,0x44,0x82, + /* 0xB6D1 [?] [2023]*/ + 0x21,0x21,0x21,0x23,0x22,0xFE,0x2B,0x22,0x22,0x23,0x22,0x3A,0xE2,0x43,0x02,0x02, + 0x40,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00, + /* 0xB6D2 [?] [2024]*/ + 0x10,0x08,0x04,0x00,0x1F,0x10,0x10,0x10,0x1F,0x14,0x04,0x04,0x08,0x08,0x10,0x60, + 0x10,0x20,0x40,0x00,0xF0,0x10,0x10,0x10,0xF0,0x50,0x40,0x40,0x44,0x44,0x44,0x3C, + /* 0xB6D3 [?] [2025]*/ + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x69,0x51,0x42,0x44,0x48, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xB6D4 [?] [2026]*/ + 0x00,0x00,0x00,0x7E,0x02,0x02,0x24,0x14,0x08,0x08,0x14,0x12,0x22,0x40,0x00,0x00, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xB6D5 [?] [2027]*/ + 0x22,0x21,0x2F,0x20,0x27,0xFC,0x27,0x20,0x27,0x20,0x21,0x39,0xEF,0x41,0x05,0x02, + 0x10,0x10,0xD0,0x10,0xBE,0xA4,0xD4,0x14,0x94,0x94,0x14,0xC8,0x08,0x14,0x14,0x22, + /* 0xB6D6 [?] [2028]*/ + 0x00,0x00,0x78,0x4B,0x48,0x4A,0x4A,0x4A,0x4A,0x4B,0x78,0x48,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xB6D7 [?] [2029]*/ + 0x00,0x78,0x4B,0x48,0x49,0x79,0x11,0x11,0x51,0x5D,0x50,0x53,0x59,0xE0,0x00,0x00, + 0x88,0x50,0xFE,0x50,0xFC,0x54,0x8C,0x74,0x04,0xFC,0x08,0xFE,0x08,0x88,0xA8,0x10, + /* 0xB6D8 [?] [2030]*/ + 0x10,0x08,0xFF,0x00,0x7E,0x42,0x7E,0x00,0x7E,0x04,0x08,0x0F,0xF8,0x08,0x28,0x11, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xB6D9 [?] [2031]*/ + 0x10,0x11,0x10,0xFE,0x11,0x55,0x55,0x55,0x55,0x7D,0x11,0x11,0x14,0x18,0x11,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xB6DA [?] [2032]*/ + 0x00,0x7F,0x41,0x41,0x5F,0x41,0x49,0x49,0x4F,0x41,0x41,0x41,0x40,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x24,0x24,0xE4,0x14,0x14,0x14,0xF4,0x04,0xFC,0x04, + /* 0xB6DB [?] [2033]*/ + 0x20,0x20,0x38,0x27,0x40,0x7A,0xA2,0x22,0xFA,0x23,0x20,0x20,0x28,0x30,0x20,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xB6DC [?] [2034]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x2F,0x28,0x28,0x2F,0x28,0x28,0x2F,0x48,0x48,0x8F,0x08, + 0x7C,0x80,0x80,0xFC,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB6DD [?] [2035]*/ + 0x00,0x23,0x12,0x12,0x03,0x02,0xF2,0x12,0x12,0x12,0x12,0x14,0x14,0x28,0x47,0x00, + 0x1E,0xE0,0x20,0x20,0xFE,0x20,0xFC,0x84,0xFC,0x84,0xFC,0x84,0xFC,0x00,0xFE,0x00, + /* 0xB6DE [?] [2036]*/ + 0x20,0x27,0x20,0x22,0xF9,0x22,0x24,0x28,0x30,0xE7,0x20,0x22,0x21,0x22,0xA4,0x48, + 0x00,0xBC,0x84,0x94,0x08,0x94,0xA4,0x40,0x00,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xB6DF [?] [2037]*/ + 0x00,0x00,0xF1,0x92,0x95,0x90,0x90,0x93,0x9C,0x90,0xF1,0x96,0x00,0x00,0x01,0x0E, + 0x80,0x80,0xF8,0x10,0x20,0xC0,0x90,0x20,0x7C,0x84,0x08,0x90,0x60,0x40,0x80,0x00, + /* 0xB6E0 [?] [2038]*/ + 0x02,0x02,0x07,0x08,0x38,0x04,0x03,0x0C,0x71,0x02,0x0C,0x32,0x01,0x01,0x0E,0x70, + 0x00,0x00,0xF0,0x20,0x40,0x80,0x40,0x80,0xF8,0x08,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xB6E1 [?] [2039]*/ + 0x01,0x01,0x7F,0x02,0x04,0x08,0x30,0xC0,0x00,0xFF,0x00,0x10,0x08,0x08,0x01,0x00, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x46,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xB6E2 [?] [2040]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x12,0x14,0x13,0x10,0x1C,0xE1,0x42,0x04,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x4E,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xB6E3 [?] [2041]*/ + 0x10,0x20,0x7C,0x44,0x7C,0x44,0x7D,0x46,0x45,0xFC,0x0C,0x14,0x25,0x46,0x94,0x08, + 0x00,0xF8,0x88,0x88,0x88,0x88,0x26,0x20,0xFE,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xB6E4 [?] [2042]*/ + 0x00,0x0F,0x08,0x08,0x08,0x10,0x20,0xC1,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x1E,0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xB6E5 [?] [2043]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x11,0x12,0x5D,0x50,0x50,0x50,0x5D,0xE2,0x00,0x00, + 0x00,0xF8,0x88,0x88,0x88,0x88,0x26,0x20,0xFE,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xB6E6 [?] [2044]*/ + 0x08,0x10,0x3E,0x22,0x32,0x2A,0x2A,0xFE,0x22,0x32,0x2A,0x2A,0x22,0x42,0x4A,0x84, + 0x20,0x10,0x10,0xFE,0x82,0x84,0x40,0x44,0x48,0x50,0x60,0x42,0x42,0x42,0x3E,0x00, + /* 0xB6E7 [?] [2045]*/ + 0x00,0x3E,0x22,0x22,0x22,0x49,0x88,0x08,0xFF,0x08,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0xA4,0x24,0x24,0x24,0x04,0x84,0x14,0x08, + /* 0xB6E8 [?] [2046]*/ + 0x10,0x10,0x13,0x10,0x19,0x56,0x55,0x50,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x40,0x40,0xFE,0x80,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xB6E9 [?] [2047]*/ + 0x00,0x7B,0x48,0x48,0x51,0x4A,0x48,0x68,0x50,0x41,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x20,0xFE,0x40,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x8C,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xB6EA [?] [2048]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xAB,0xA8,0xA8,0xF8,0xA0,0x23,0x28,0x38,0xE8,0x42,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x02, + /* 0xB6EB [?] [2049]*/ + 0x10,0x10,0x13,0x10,0x54,0x57,0x54,0x54,0x54,0x54,0x57,0x5C,0x64,0x00,0x02,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x02, + /* 0xB6EC [?] [2050]*/ + 0x04,0x36,0xE5,0x25,0x24,0xFF,0x24,0x25,0x25,0x36,0xE6,0x24,0x2A,0x32,0xA1,0x40, + 0x10,0x20,0x7C,0x44,0x64,0xD4,0x44,0x4C,0x40,0x7E,0x02,0x02,0xFA,0x82,0x8A,0x84, + /* 0xB6ED [?] [2051]*/ + 0x10,0x11,0x17,0x21,0x21,0x6F,0x61,0xA1,0x21,0x23,0x2D,0x21,0x21,0x21,0x25,0x22, + 0x28,0xA4,0x24,0x20,0x20,0xFE,0x20,0x24,0xA4,0x28,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xB6EE [?] [2052]*/ + 0x10,0x08,0x7F,0x41,0x10,0x1E,0x22,0x54,0x08,0x14,0x22,0x7F,0xA2,0x22,0x3E,0x22, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xB6EF [?] [2053]*/ + 0x00,0x20,0x10,0x11,0x01,0x03,0xF5,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0xA0,0xA0,0xA0,0x24,0x24,0x28,0x30,0x20,0x60,0xA0,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xB6F0 [?] [2054]*/ + 0x10,0x10,0x13,0x10,0xFC,0x27,0x24,0x24,0x24,0x48,0x2B,0x10,0x28,0x44,0x84,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x82, + /* 0xB6F1 [?] [2055]*/ + 0x00,0x7F,0x04,0x24,0x14,0x14,0x04,0xFF,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0xFC,0x40,0x48,0x48,0x50,0x40,0xFE,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xB6F2 [?] [2056]*/ + 0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x43,0x80, + 0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x50,0x20,0x04,0x04,0x04,0xFC,0x00, + /* 0xB6F3 [?] [2057]*/ + 0x20,0x23,0x22,0x22,0xFA,0x22,0x22,0x2A,0x32,0xE2,0x22,0x22,0x24,0x24,0xA8,0x50, + 0x00,0xFE,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xA8,0x90,0x82,0x82,0x82,0x7E,0x00, + /* 0xB6F4 [?] [2058]*/ + 0x00,0x23,0x12,0x13,0x02,0x03,0xF1,0x13,0x14,0x1A,0x12,0x13,0x10,0x28,0x47,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xA4,0x04,0xF4,0x14,0x08,0xFE,0x00, + /* 0xB6F5 [?] [2059]*/ + 0x00,0x77,0x55,0x55,0x77,0x00,0x7F,0x00,0xFF,0x20,0x3F,0x01,0x01,0x01,0x0A,0x04, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0xA2,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xB6F6 [?] [2060]*/ + 0x20,0x20,0x23,0x3C,0x44,0x4B,0xA0,0x20,0x20,0x20,0x23,0x20,0x28,0x30,0x22,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x02, + /* 0xB6F7 [?] [2061]*/ + 0x00,0x3F,0x21,0x21,0x2F,0x21,0x22,0x24,0x28,0x3F,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xF8,0x08,0x08,0xE8,0x08,0x88,0x48,0x28,0xF8,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xB6F8 [?] [2062]*/ + 0x00,0x7F,0x01,0x01,0x02,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x20, + 0x00,0xFC,0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x28,0x10, + /* 0xB6F9 [?] [2063]*/ + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xB6FA [?] [2064]*/ + 0x00,0x7F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x17,0xF8,0x00,0x00,0x00, + 0x00,0xFC,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0x3E,0xD0,0x10,0x10,0x10,0x10, + /* 0xB6FB [?] [2065]*/ + 0x08,0x08,0x08,0x1F,0x10,0x21,0x41,0x81,0x01,0x11,0x11,0x21,0x41,0x81,0x05,0x02, + 0x00,0x00,0x00,0xFC,0x04,0x08,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x02,0x00,0x00, + /* 0xB6FC [?] [2066]*/ + 0x20,0x23,0x21,0x3D,0x45,0x49,0xA1,0x21,0x21,0x21,0x21,0x21,0x2B,0x30,0x20,0x00, + 0x00,0xFE,0x08,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x1E,0xE8,0x08,0x08,0x08, + /* 0xB6FD [?] [2067]*/ + 0x00,0x27,0x12,0x12,0x83,0x42,0x42,0x13,0x12,0x22,0xE2,0x23,0x2E,0x20,0x20,0x00, + 0x00,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x0E,0xF8,0x08,0x08,0x08,0x08, + /* 0xB6FE [?] [2068]*/ + 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xB7A1 [?] [2069]*/ + 0x00,0x00,0xFF,0x00,0x3F,0x00,0x7F,0x00,0x3F,0x20,0x24,0x24,0x24,0x0A,0x11,0x60, + 0x28,0x24,0xFE,0x20,0xA0,0x20,0xA0,0x20,0xA0,0x90,0x90,0x90,0x8A,0x0A,0x06,0x82, + /* 0xB7A2 [?] [2070]*/ + 0x01,0x11,0x11,0x22,0x3F,0x02,0x04,0x07,0x0A,0x09,0x11,0x10,0x20,0x40,0x03,0x1C, + 0x00,0x10,0x08,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xB7A3 [?] [2071]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x00,0x20,0x10,0x00,0xF0,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0xFC,0x44,0x44,0xFC,0x00,0x08,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x28,0x10, + /* 0xB7A4 [?] [2072]*/ + 0x10,0x10,0x3F,0x28,0x45,0x88,0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x10,0x11,0x16, + 0x40,0x40,0x7E,0x90,0x08,0xA0,0x90,0x80,0xFC,0x80,0x48,0x50,0x24,0x54,0x8C,0x04, + /* 0xB7A5 [?] [2073]*/ + 0x08,0x08,0x08,0x10,0x10,0x37,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x11,0x16,0x10, + 0x90,0x88,0x88,0x80,0xBE,0xC0,0x80,0x44,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xB7A6 [?] [2074]*/ + 0x00,0x01,0x7E,0x00,0x02,0x01,0x01,0x7F,0x00,0x00,0x03,0x0C,0x30,0x48,0x87,0x00, + 0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0x30,0xC0,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xB7A7 [?] [2075]*/ + 0x20,0x17,0x00,0x45,0x45,0x49,0x59,0x6F,0x49,0x49,0x48,0x48,0x49,0x4A,0x48,0x40, + 0x00,0xFC,0x04,0x44,0x24,0x04,0xF4,0x04,0x24,0x24,0xC4,0x94,0x54,0x34,0x14,0x08, + /* 0xB7A8 [?] [2076]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x40,0x10,0x1F,0x20,0xE0,0x21,0x22,0x24,0x2F,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0x80,0x00,0x10,0x08,0xFC,0x04, + /* 0xB7A9 [?] [2077]*/ + 0x00,0x00,0xFC,0x11,0x10,0x10,0x10,0x7D,0x10,0x10,0x10,0x10,0x1C,0xE1,0x40,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00, + /* 0xB7AA [?] [2078]*/ + 0x08,0xFF,0x08,0x20,0x17,0x12,0x81,0x47,0x52,0x14,0x2B,0xE2,0x23,0x22,0x23,0x22, + 0x20,0xFE,0x20,0x38,0xC0,0x48,0x50,0xFC,0x48,0x04,0xFA,0x48,0xF8,0x48,0xF8,0x08, + /* 0xB7AB [?] [2079]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x11,0x12,0x12,0x14, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB7AC [?] [2080]*/ + 0x00,0x3F,0x11,0x09,0x01,0xFF,0x09,0x10,0x3F,0xD1,0x11,0x1F,0x11,0x11,0x1F,0x10, + 0xF8,0x00,0x10,0x20,0x00,0xFE,0x20,0x10,0xF8,0x16,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xB7AD [?] [2081]*/ + 0x0E,0xF1,0x92,0x54,0xFF,0x38,0x54,0x82,0x7C,0x54,0x55,0x7C,0x54,0x54,0x7D,0x44, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0x44,0x4C,0xD4,0x64,0x44,0x44,0x44,0x54,0x88, + /* 0xB7AE [?] [2082]*/ + 0x24,0x22,0xF9,0x22,0x64,0x72,0xA9,0x22,0x25,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x48,0x88,0x3E,0x88,0x58,0x9C,0x2A,0x88,0x48,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xB7AF [?] [2083]*/ + 0x00,0x01,0xF9,0x21,0x21,0x41,0x79,0xC9,0x49,0x49,0x49,0x49,0x7A,0x42,0x04,0x08, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB7B0 [?] [2084]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB7B1 [?] [2085]*/ + 0x20,0x3F,0x40,0xBE,0x2A,0xFF,0x4A,0x7F,0x04,0x08,0x1F,0x02,0x3F,0x01,0x15,0x22, + 0x20,0x20,0x3E,0x48,0xA8,0x28,0x10,0x28,0x46,0x80,0x00,0x10,0xF8,0x08,0x20,0x10, + /* 0xB7B2 [?] [2086]*/ + 0x00,0x0F,0x08,0x08,0x08,0x0A,0x09,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xB7B3 [?] [2087]*/ + 0x10,0x13,0x10,0x10,0x55,0x59,0x51,0x91,0x11,0x11,0x11,0x29,0x24,0x44,0x41,0x82, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x04, + /* 0xB7B4 [?] [2088]*/ + 0x00,0x00,0x3F,0x20,0x20,0x3F,0x24,0x24,0x22,0x22,0x21,0x20,0x41,0x42,0x8C,0x30, + 0x10,0xF8,0x00,0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x40,0x80,0x40,0x20,0x18,0x06, + /* 0xB7B5 [?] [2089]*/ + 0x00,0x20,0x13,0x12,0x02,0x03,0xF2,0x12,0x12,0x12,0x12,0x14,0x15,0x28,0x47,0x00, + 0x08,0x3C,0xC0,0x00,0x00,0xFC,0x04,0x88,0x50,0x20,0x50,0x88,0x04,0x00,0xFE,0x00, + /* 0xB7B6 [?] [2090]*/ + 0x04,0x04,0xFF,0x04,0x10,0x09,0x49,0x21,0x25,0x05,0x09,0x71,0x11,0x11,0x10,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0x08,0x28,0x10,0x02,0x02,0x02,0xFE,0x00, + /* 0xB7B7 [?] [2091]*/ + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x29,0x25,0x42,0x80, + 0x04,0x0E,0xF0,0x80,0x80,0xFC,0xA4,0xA4,0xA4,0xA8,0xA8,0x90,0x10,0x28,0x44,0x82, + /* 0xB7B8 [?] [2092]*/ + 0x00,0x44,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x50,0x20, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xB7B9 [?] [2093]*/ + 0x20,0x20,0x21,0x3D,0x45,0x49,0xA1,0x21,0x21,0x21,0x21,0x21,0x29,0x32,0x22,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xB7BA [?] [2094]*/ + 0x00,0x20,0x17,0x10,0x80,0x40,0x47,0x10,0x10,0x20,0xE0,0x21,0x22,0x25,0x28,0x00, + 0x10,0x78,0x80,0x00,0x80,0x40,0xF8,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0xFC,0x00, + /* 0xB7BB [?] [2095]*/ + 0x10,0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x10,0x10,0x10,0x1C,0xE1,0x41,0x02,0x04, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xB7BC [?] [2096]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x01,0xFF,0x04,0x04,0x07,0x04,0x08,0x08,0x10,0x20,0x40, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xB7BD [?] [2097]*/ + 0x02,0x01,0x01,0xFF,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xB7BE [?] [2098]*/ + 0x00,0x3C,0x24,0x25,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x40,0x20,0x20,0xFE,0x40,0x40,0x40,0x7C,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xB7BF [?] [2099]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x21,0x20,0x3F,0x22,0x22,0x23,0x44,0x44,0x88,0x10, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x00,0x80,0xFC,0x00,0x00,0xF8,0x08,0x08,0x28,0x10, + /* 0xB7C0 [?] [2100]*/ + 0x00,0x7C,0x44,0x4B,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xB7C1 [?] [2101]*/ + 0x10,0x10,0x10,0x11,0xFC,0x24,0x24,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x81,0x02, + 0x40,0x20,0x20,0xFE,0x40,0x40,0x40,0x7C,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xB7C2 [?] [2102]*/ + 0x08,0x08,0x08,0x17,0x11,0x31,0x31,0x51,0x91,0x11,0x11,0x11,0x12,0x12,0x14,0x18, + 0x80,0x40,0x40,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB7C3 [?] [2103]*/ + 0x00,0x20,0x10,0x17,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x1A,0x12,0x04,0x08, + 0x80,0x40,0x40,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB7C4 [?] [2104]*/ + 0x10,0x10,0x20,0x27,0x44,0xF8,0x10,0x20,0x40,0xFC,0x40,0x00,0x1D,0xE1,0x42,0x04, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xB7C5 [?] [2105]*/ + 0x20,0x10,0x00,0xFE,0x20,0x21,0x3E,0x24,0x24,0x24,0x24,0x24,0x44,0x54,0x89,0x02, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xB7C6 [?] [2106]*/ + 0x08,0x08,0xFF,0x08,0x08,0x04,0x7C,0x04,0x04,0x7C,0x04,0x04,0xFC,0x04,0x04,0x04, + 0x20,0x20,0xFE,0x20,0x20,0x40,0x7C,0x40,0x40,0x7C,0x40,0x40,0x7E,0x40,0x40,0x40, + /* 0xB7C7 [?] [2107]*/ + 0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x7C,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04, + 0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x7E,0x40,0x40,0x40, + /* 0xB7C8 [?] [2108]*/ + 0x00,0x00,0xF0,0x97,0x90,0x90,0x90,0x93,0x90,0x90,0xF0,0x97,0x00,0x00,0x00,0x00, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xB7C9 [?] [2109]*/ + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xC0,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x20,0x20,0x12,0x0A,0x06,0x02, + /* 0xB7CA [?] [2110]*/ + 0x00,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x54,0x88, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xB7CB [?] [2111]*/ + 0x00,0x7F,0x42,0x42,0x7E,0x42,0x42,0x5E,0x42,0x42,0x7E,0x42,0x42,0x42,0x7F,0x00, + 0x00,0xFC,0x40,0x40,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x00, + /* 0xB7CC [?] [2112]*/ + 0x00,0x20,0x10,0x17,0x00,0x00,0xF0,0x13,0x10,0x10,0x10,0x17,0x18,0x10,0x00,0x00, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xB7CD [?] [2113]*/ + 0x00,0x00,0x78,0x48,0x48,0x4F,0x48,0x48,0x48,0x48,0x48,0x79,0x49,0x02,0x04,0x08, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xB7CE [?] [2114]*/ + 0x00,0x3C,0x24,0x27,0x24,0x3C,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x44,0x54,0x88, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,0x20, + /* 0xB7CF [?] [2115]*/ + 0x01,0x00,0x3F,0x20,0x24,0x28,0x2F,0x21,0x21,0x22,0x22,0x24,0x24,0x48,0x51,0x86, + 0x00,0x80,0xFE,0x80,0x90,0x88,0xFE,0x00,0xFC,0x84,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xB7D0 [?] [2116]*/ + 0x01,0x21,0x11,0x17,0x81,0x41,0x47,0x15,0x15,0x27,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x20,0x20,0x20,0xF8,0x28,0x28,0xF8,0x20,0x20,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xB7D1 [?] [2117]*/ + 0x04,0x7F,0x04,0x3F,0x24,0x3F,0x08,0x10,0x20,0x5F,0x10,0x11,0x11,0x02,0x0C,0x30, + 0x40,0xF8,0x48,0xF8,0x40,0xFC,0x44,0x54,0x08,0xF0,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xB7D2 [?] [2118]*/ + 0x08,0x08,0xFF,0x08,0x00,0x04,0x08,0x10,0x20,0xDF,0x04,0x04,0x08,0x10,0x21,0x40, + 0x20,0x20,0xFE,0x20,0x40,0x40,0x20,0x10,0x08,0xE6,0x20,0x20,0x20,0x20,0x40,0x80, + /* 0xB7D3 [?] [2119]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAB,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x08,0x28,0x28,0x28,0x44,0x44,0x82,0x7C,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x08, + /* 0xB7D4 [?] [2120]*/ + 0x00,0x00,0x78,0x48,0x49,0x49,0x4A,0x4D,0x48,0x48,0x48,0x78,0x49,0x01,0x02,0x04, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xB7D5 [?] [2121]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x12,0x21,0x40,0xBF,0x11,0x11,0x11,0x25,0x42, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x90,0x50,0x12,0x0A,0x0A,0x06,0x02, + /* 0xB7D6 [?] [2122]*/ + 0x00,0x04,0x04,0x08,0x10,0x20,0x40,0x9F,0x04,0x04,0x04,0x08,0x08,0x10,0x21,0x40, + 0x40,0x40,0x20,0x20,0x10,0x08,0x04,0xE2,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80, + /* 0xB7D7 [?] [2123]*/ + 0x10,0x10,0x20,0x20,0x49,0xF9,0x12,0x25,0x40,0xF8,0x40,0x00,0x19,0xE1,0x42,0x04, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xB7D8 [?] [2124]*/ + 0x10,0x10,0x10,0x17,0x11,0xFD,0x11,0x11,0x11,0x10,0x10,0x1C,0xE0,0x41,0x02,0x0C, + 0x80,0x40,0x40,0xFC,0x10,0x10,0x10,0x10,0x10,0xA0,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xB7D9 [?] [2125]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC9,0x08,0x09,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x20,0x20,0xFC,0x30,0x68,0xA4,0x22,0x20,0x20,0x10,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xB7DA [?] [2126]*/ + 0x00,0x21,0x11,0x12,0x82,0x44,0x58,0x13,0x11,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x10,0x10,0x10,0x08,0x08,0x04,0x02,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB7DB [?] [2127]*/ + 0x10,0x10,0x94,0x54,0x58,0x10,0xFD,0x32,0x38,0x54,0x54,0x90,0x10,0x10,0x11,0x12, + 0x10,0x50,0x50,0x50,0x88,0x88,0x04,0xFA,0x48,0x48,0x48,0x48,0x88,0x88,0x28,0x10, + /* 0xB7DC [?] [2128]*/ + 0x01,0x01,0x7F,0x02,0x04,0x08,0x30,0xC0,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x10, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xB7DD [?] [2129]*/ + 0x08,0x08,0x08,0x10,0x11,0x31,0x32,0x55,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xB7DE [?] [2130]*/ + 0x04,0x08,0x10,0x2F,0xC4,0x04,0x08,0x10,0x60,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x40,0x20,0x10,0xE8,0x26,0x20,0x20,0xA0,0x40,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xB7DF [?] [2131]*/ + 0x10,0x11,0x10,0x10,0x1B,0x54,0x50,0x51,0x91,0x11,0x11,0x11,0x11,0x10,0x10,0x13, + 0x20,0xFC,0x20,0x88,0xFE,0x88,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xB7E0 [?] [2132]*/ + 0x01,0x11,0x09,0x7F,0x05,0x09,0x31,0xC4,0x04,0x3F,0x04,0x04,0xFF,0x08,0x10,0x20, + 0x00,0x10,0x20,0xFC,0x40,0x20,0x18,0x46,0x40,0xF8,0x40,0x40,0xFE,0x20,0x10,0x08, + /* 0xB7E1 [?] [2133]*/ + 0x01,0x01,0x01,0x7F,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xB7E2 [?] [2134]*/ + 0x08,0x08,0x08,0x7F,0x08,0x08,0xFF,0x00,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40, + 0x08,0x08,0x08,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xB7E3 [?] [2135]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x72,0x6A,0xA2,0xA2,0x23,0x24,0x24,0x28,0x30, + 0x00,0xF8,0x08,0x08,0x28,0xA8,0xA8,0x48,0x48,0xA8,0xA8,0x2A,0x0A,0x0A,0x06,0x02, + /* 0xB7E4 [?] [2136]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x57,0x7C,0x50,0x10,0x14,0x1F,0xE4,0x40,0x00, + 0x40,0x40,0xFC,0x88,0x50,0x20,0xD8,0x26,0xF8,0x20,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xB7E5 [?] [2137]*/ + 0x10,0x10,0x10,0x10,0x55,0x54,0x54,0x57,0x54,0x54,0x54,0x5C,0x67,0x00,0x00,0x00, + 0x40,0x40,0xFC,0x88,0x50,0x20,0xD8,0x26,0xF8,0x20,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xB7E6 [?] [2138]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBC,0x10,0x13,0xFC,0x10,0x10,0x10,0x17,0x18,0x10,0x00, + 0x40,0x40,0xFC,0x88,0x50,0x20,0xD8,0x26,0xF8,0x20,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xB7E7 [?] [2139]*/ + 0x00,0x3F,0x20,0x20,0x28,0x24,0x22,0x22,0x21,0x21,0x22,0x22,0x24,0x48,0x40,0x80, + 0x00,0xF0,0x10,0x10,0x50,0x50,0x90,0x90,0x10,0x10,0x90,0x92,0x4A,0x4A,0x06,0x02, + /* 0xB7E8 [?] [2140]*/ + 0x00,0x00,0x1F,0x10,0x90,0x53,0x52,0x13,0x32,0x52,0x92,0x12,0x25,0x24,0x48,0x90, + 0x80,0x40,0xFE,0x00,0x00,0xF8,0x08,0x28,0xA8,0x48,0x48,0xA8,0x2A,0x0A,0x06,0x02, + /* 0xB7E9 [?] [2141]*/ + 0x10,0x10,0x10,0x10,0x55,0x58,0x50,0x93,0x10,0x10,0x10,0x28,0x27,0x44,0x40,0x80, + 0x40,0x40,0xFC,0x88,0x50,0x20,0xD8,0x26,0xF8,0x20,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xB7EA [?] [2142]*/ + 0x01,0x21,0x13,0x14,0x00,0x01,0xF6,0x10,0x13,0x10,0x13,0x10,0x17,0x10,0x28,0x47, + 0x00,0xF8,0x08,0x90,0x60,0x98,0x06,0x40,0xF8,0x40,0xF8,0x40,0xFC,0x40,0x40,0xFE, + /* 0xB7EB [?] [2143]*/ + 0x00,0x47,0x20,0x20,0x02,0x0A,0x0A,0x13,0x10,0xE0,0x20,0x27,0x20,0x20,0x20,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xB7EC [?] [2144]*/ + 0x10,0x14,0x22,0x21,0x48,0xF8,0x16,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x45,0x08, + 0x20,0x7C,0x84,0x48,0x30,0xCE,0x10,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xB7ED [?] [2145]*/ + 0x00,0x43,0x22,0x22,0x03,0x02,0xE2,0x22,0x22,0x22,0x22,0x2B,0x34,0x24,0x08,0x10, + 0x00,0xF8,0x08,0x08,0x28,0xA8,0xA8,0x48,0x48,0xA8,0xA8,0x2A,0x0A,0x0A,0x06,0x02, + /* 0xB7EE [?] [2146]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x09,0x31,0xCF,0x01,0x01,0x3F,0x01,0x01, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x40,0x20,0x18,0xE6,0x00,0x00,0xF8,0x00,0x00, + /* 0xB7EF [?] [2147]*/ + 0x00,0x3F,0x20,0x20,0x2F,0x20,0x28,0x24,0x22,0x21,0x22,0x24,0x28,0x40,0x40,0x80, + 0x00,0xF8,0x08,0x08,0xC8,0x48,0x48,0x88,0x88,0x08,0x88,0x4A,0x4A,0x0A,0x06,0x02, + /* 0xB7F0 [?] [2148]*/ + 0x11,0x11,0x11,0x2F,0x21,0x61,0x67,0xA5,0x29,0x2F,0x21,0x21,0x22,0x22,0x24,0x28, + 0x20,0x20,0x20,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xB7F1 [?] [2149]*/ + 0x00,0x7F,0x00,0x01,0x03,0x05,0x09,0x31,0xC1,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xFC,0x80,0x00,0x00,0x60,0x18,0x04,0x02,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xB7F2 [?] [2150]*/ + 0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xB7F3 [?] [2151]*/ + 0x0A,0x09,0xFF,0x08,0x7F,0x49,0x7F,0x49,0x7F,0x49,0x10,0xFF,0x20,0x3E,0x42,0x86, + 0x20,0x20,0xA0,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x90,0x28,0x28,0x44,0x82, + /* 0xB7F4 [?] [2152]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x27,0x3C,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB7F5 [?] [2153]*/ + 0x20,0xCE,0x8A,0xAA,0xAA,0xEE,0xAA,0xAA,0xAA,0xAA,0xEE,0xA8,0x28,0x48,0x48,0x88, + 0x0E,0xF0,0x22,0x92,0x54,0x00,0x7C,0x08,0x10,0x10,0xFE,0x10,0x10,0x10,0x50,0x20, + /* 0xB7F6 [?] [2154]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x10,0x14,0x1B,0x30,0xD0,0x10,0x10,0x10,0x51,0x22, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB7F7 [?] [2155]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x13,0x16,0x1A,0x33,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x90,0x90,0x90,0xFC,0x94,0x94,0xFC,0x90,0x90,0xFE,0x92,0x92,0x1A,0x14,0x10,0x10, + /* 0xB7F8 [?] [2156]*/ + 0x20,0x21,0x20,0xFC,0x40,0x50,0x90,0xFC,0x11,0x11,0x1D,0xF1,0x51,0x11,0x11,0x11, + 0x00,0xFE,0x00,0xFC,0x84,0x84,0xFC,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xB7F9 [?] [2157]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x5D,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x00,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xB7FA [?] [2158]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x12,0x7F,0x12,0x7F,0x52,0x7F,0x12,0x13,0x22,0x42, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x90,0x90,0x10,0xD2,0x4A,0x4A,0x86,0x02, + /* 0xB7FB [?] [2159]*/ + 0x10,0x10,0x3F,0x48,0x85,0x08,0x08,0x13,0x30,0x51,0x90,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x10,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20, + /* 0xB7FC [?] [2160]*/ + 0x08,0x08,0x08,0x10,0x10,0x37,0x30,0x50,0x90,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xB7FD [?] [2161]*/ + 0x08,0x08,0x0B,0x10,0x12,0x31,0x30,0x53,0x90,0x10,0x17,0x10,0x10,0x10,0x10,0x10, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xB7FE [?] [2162]*/ + 0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x42,0x4A,0x84, + 0x00,0xFC,0x84,0x84,0x94,0x88,0x80,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0xA8,0xC4,0x82, + /* 0xB8A1 [?] [2163]*/ + 0x00,0x20,0x13,0x10,0x82,0x41,0x48,0x0B,0x10,0x10,0xE7,0x20,0x20,0x20,0x20,0x00, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xB8A2 [?] [2164]*/ + 0x00,0x20,0x13,0x10,0x82,0x41,0x41,0x17,0x10,0x20,0xE3,0x22,0x22,0x22,0x23,0x02, + 0x80,0x40,0xFC,0x00,0x08,0x08,0x10,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xB8A3 [?] [2165]*/ + 0x40,0x23,0x20,0xF9,0x11,0x11,0x21,0x30,0x6B,0xAA,0x22,0x23,0x22,0x22,0x23,0x22, + 0x00,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xB8A4 [?] [2166]*/ + 0x20,0x10,0x00,0xF9,0x09,0x13,0x15,0x31,0x55,0x99,0x15,0x11,0x11,0x11,0x11,0x11, + 0x90,0x94,0x92,0x12,0x10,0x7E,0x10,0x10,0x10,0x28,0x28,0x28,0x28,0x44,0x44,0x82, + /* 0xB8A5 [?] [2167]*/ + 0x04,0x04,0x04,0x7F,0x04,0x04,0x3F,0x24,0x24,0x3F,0x04,0x08,0x08,0x10,0x20,0x40, + 0x40,0x40,0x40,0xF8,0x48,0x48,0xF8,0x40,0x40,0xFC,0x44,0x44,0x54,0x48,0x40,0x40, + /* 0xB8A6 [?] [2168]*/ + 0x01,0x01,0xFF,0x01,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21,0x21,0x21,0x20, + 0x20,0x10,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xB8A7 [?] [2169]*/ + 0x10,0x13,0x10,0x10,0xFC,0x10,0x17,0x10,0x18,0x30,0xD0,0x11,0x11,0x12,0x54,0x28, + 0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xB8A8 [?] [2170]*/ + 0x20,0x20,0x23,0xFC,0x40,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x11,0x11,0x11, + 0x28,0x24,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0x0C, + /* 0xB8A9 [?] [2171]*/ + 0x10,0x10,0x17,0x24,0x24,0x64,0x65,0xA5,0x27,0x25,0x25,0x25,0x29,0x29,0x31,0x21, + 0x40,0x20,0xFE,0x00,0x88,0x88,0x08,0x7E,0x08,0x48,0x28,0x28,0x08,0x08,0x28,0x10, + /* 0xB8AA [?] [2172]*/ + 0x04,0x08,0x18,0x24,0x03,0x0C,0x30,0xC0,0x1F,0x01,0x01,0x3F,0x01,0x11,0x09,0x7F, + 0x40,0x20,0x50,0x88,0x00,0xC0,0x30,0x0E,0xF0,0x00,0x00,0xF8,0x00,0x10,0x20,0xFC, + /* 0xB8AB [?] [2173]*/ + 0x04,0x08,0x18,0x24,0x03,0x0C,0x30,0xC0,0x1F,0x10,0x10,0x1F,0x10,0x10,0x20,0x40, + 0x40,0x20,0x50,0x88,0x00,0xC0,0x30,0xEE,0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0x80, + /* 0xB8AC [?] [2174]*/ + 0x00,0x78,0x4B,0x48,0x48,0x7B,0x4A,0x4A,0x4B,0x7A,0x4A,0x4B,0x4A,0x4A,0x4A,0x9A, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xB8AD [?] [2175]*/ + 0x00,0x78,0x4B,0x4A,0x4A,0x7A,0x4A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4C,0x4C,0x48,0x98, + 0x20,0x10,0xFE,0x00,0x44,0x44,0x84,0xBE,0x84,0xA4,0x94,0x94,0x84,0x84,0x94,0x88, + /* 0xB8AE [?] [2176]*/ + 0x01,0x00,0x3F,0x20,0x22,0x22,0x24,0x24,0x2C,0x34,0x24,0x24,0x44,0x44,0x84,0x04, + 0x00,0x80,0xFE,0x00,0x08,0x08,0x08,0xFE,0x08,0x88,0x48,0x48,0x08,0x08,0x28,0x10, + /* 0xB8AF [?] [2177]*/ + 0x00,0x3F,0x22,0x22,0x25,0x2C,0x34,0x24,0x20,0x2F,0x29,0x2A,0x48,0x49,0x8A,0x08, + 0x80,0xFE,0x08,0x08,0xFE,0x88,0x48,0x58,0x80,0xFC,0x44,0xA4,0x84,0x44,0x24,0x0C, + /* 0xB8B0 [?] [2178]*/ + 0x04,0x04,0x04,0x3F,0x04,0x04,0x7F,0x04,0x04,0x24,0x27,0x24,0x24,0x54,0x4F,0x80, + 0x20,0x20,0x20,0x20,0x30,0x28,0xA4,0x24,0x20,0x20,0xA0,0x20,0x20,0x00,0xFE,0x00, + /* 0xB8B1 [?] [2179]*/ + 0x00,0x7F,0x00,0x3F,0x20,0x20,0x3F,0x00,0x7F,0x44,0x44,0x7F,0x44,0x44,0x7F,0x40, + 0x02,0xC2,0x02,0x82,0x92,0x92,0x92,0x12,0xD2,0x52,0x52,0xD2,0x42,0x42,0xCA,0x44, + /* 0xB8B2 [?] [2180]*/ + 0xFF,0x04,0x3F,0x24,0x3F,0x12,0x27,0x42,0x8B,0x12,0x33,0x51,0x93,0x15,0x10,0x17, + 0xFE,0x40,0xF8,0x48,0xF8,0x00,0xFC,0x08,0xF8,0x08,0xF8,0x00,0xF8,0x10,0xE0,0x1E, + /* 0xB8B3 [?] [2181]*/ + 0x00,0x7C,0x44,0x44,0x54,0x55,0x54,0x54,0x55,0x55,0x55,0x11,0x29,0x25,0x43,0x81, + 0x08,0x0C,0xEA,0x0A,0x08,0xFE,0x48,0x48,0x48,0x68,0x48,0x48,0x4A,0x6A,0x86,0x02, + /* 0xB8B4 [?] [2182]*/ + 0x10,0x10,0x1F,0x20,0x5F,0x90,0x1F,0x10,0x1F,0x04,0x0F,0x18,0x64,0x03,0x1C,0xE0, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E, + /* 0xB8B5 [?] [2183]*/ + 0x08,0x08,0x0F,0x10,0x17,0x34,0x37,0x54,0x97,0x14,0x10,0x1F,0x12,0x11,0x11,0x10, + 0x50,0x48,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x08,0xFE,0x08,0x08,0x28,0x10, + /* 0xB8B6 [?] [2184]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x50,0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xB8B7 [?] [2185]*/ + 0x02,0x04,0x3F,0x20,0x3F,0x20,0x3F,0x20,0x20,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01, + 0x00,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xB8B8 [?] [2186]*/ + 0x04,0x08,0x10,0x20,0x40,0x08,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x40,0x20,0x10,0x08,0x24,0x20,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xB8B9 [?] [2187]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3E,0x24,0x24,0x24,0x3C,0x24,0x24,0x25,0x44,0x54,0x89, + 0x40,0x40,0xFE,0x80,0xFC,0x84,0xFC,0x84,0xFC,0x40,0x7C,0xC4,0x28,0x10,0x68,0x86, + /* 0xB8BA [?] [2188]*/ + 0x04,0x04,0x0F,0x10,0x20,0x5F,0x10,0x11,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0x00,0x00,0xE0,0x20,0x40,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xC0,0x20,0x10,0x08, + /* 0xB8BB [?] [2189]*/ + 0x02,0x01,0x7F,0x40,0xBF,0x00,0x1F,0x10,0x1F,0x00,0x3F,0x21,0x3F,0x21,0x3F,0x20, + 0x00,0x00,0xFE,0x02,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xB8BC [?] [2190]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x80,0x80,0x80,0x80,0x80,0xA0,0x90,0x88,0x84,0x84,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xB8BD [?] [2191]*/ + 0x00,0x7C,0x44,0x49,0x49,0x53,0x4D,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41, + 0x88,0x88,0x88,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xB8BE [?] [2192]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x24,0x25,0x24,0x48,0x28,0x10,0x28,0x45,0x80,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xB8BF [?] [2193]*/ + 0x10,0x10,0x27,0x20,0x4B,0xFA,0x13,0x22,0x43,0xFA,0x40,0x03,0x19,0xE0,0x40,0x00, + 0x50,0x48,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x08,0xFE,0x08,0x88,0xA8,0x10, + /* 0xB8C0 [?] [2194]*/ + 0x00,0x00,0x78,0x49,0x49,0x4B,0x4D,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x88,0x88,0x88,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xB8C1 [?] [2195]*/ + 0x00,0x03,0x78,0x49,0x49,0x49,0x49,0x49,0x48,0x49,0x7A,0x4D,0x01,0x01,0x00,0x00, + 0x88,0xFE,0x88,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFE,0x22,0x52,0x02,0xFA,0x0A,0x04, + /* 0xB8C2 [?] [2196]*/ + 0x07,0x00,0x7B,0x4A,0x4B,0x4A,0x4B,0x4A,0x4B,0x49,0x79,0x4F,0x00,0x00,0x01,0x0E, + 0xFC,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x10,0x7C,0x80,0x90,0x62,0xB2,0x0E, + /* 0xB8C3 [?] [2197]*/ + 0x00,0x40,0x2F,0x20,0x01,0x01,0xE2,0x27,0x20,0x20,0x21,0x2A,0x34,0x20,0x03,0x0C, + 0x80,0x40,0xFE,0x80,0x10,0x10,0x24,0xE4,0x48,0x88,0x10,0x20,0x50,0x88,0x04,0x04, + /* 0xB8C4 [?] [2198]*/ + 0x00,0x00,0xFC,0x04,0x05,0x05,0x06,0x7C,0x40,0x40,0x40,0x44,0x58,0x60,0x41,0x02, + 0x40,0x40,0x80,0xFE,0x08,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xB8C5 [?] [2199]*/ + 0x20,0x27,0x24,0x24,0xFF,0x24,0x24,0x77,0x6C,0xA5,0xA4,0x25,0x26,0x24,0x20,0x20, + 0x00,0xBE,0x88,0x88,0xA8,0xA8,0xA8,0xBE,0x10,0x18,0x98,0xA8,0xAA,0x4A,0x46,0x80, + /* 0xB8C6 [?] [2200]*/ + 0x10,0x13,0x3C,0x20,0x41,0xBD,0x11,0x11,0xFD,0x11,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0xFE,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFE,0x02,0x02,0x02,0x02,0x14,0x08, + /* 0xB8C7 [?] [2201]*/ + 0x08,0x04,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00,0x00,0x3F,0x24,0x24,0x24,0xFF, + 0x20,0x40,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0xF8,0x48,0x48,0x48,0xFE, + /* 0xB8C8 [?] [2202]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x17,0x14,0x25,0xE4,0x25,0x26,0x24,0x20,0x00, + 0x00,0xBE,0x88,0x88,0xA8,0xA8,0xA8,0xBE,0x10,0x18,0x98,0xA8,0xAA,0x4A,0x46,0x80, + /* 0xB8C9 [?] [2203]*/ + 0x00,0x3F,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB8CA [?] [2204]*/ + 0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x0F,0x08, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xB8CB [?] [2205]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x30,0x3B,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xB8CC [?] [2206]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xB8CD [?] [2207]*/ + 0x10,0x10,0x3F,0x48,0x85,0x00,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xB8CE [?] [2208]*/ + 0x00,0x3D,0x24,0x24,0x24,0x3C,0x24,0x27,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xB8CF [?] [2209]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFE,0x09,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB8D0 [?] [2210]*/ + 0x00,0x00,0x3F,0x20,0x2F,0x20,0x2F,0x28,0x28,0x4F,0x40,0x80,0x01,0x48,0x48,0x87, + 0x28,0x24,0xFE,0x20,0xA4,0x24,0xA8,0x98,0x92,0xAA,0x46,0x82,0x00,0x84,0x12,0xF2, + /* 0xB8D1 [?] [2211]*/ + 0x08,0x1D,0xF0,0x10,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xB8D2 [?] [2212]*/ + 0x00,0x7E,0x02,0x04,0xFF,0x22,0x22,0x3E,0x22,0x3E,0x22,0x22,0x2F,0xF2,0x42,0x02, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xB8D3 [?] [2213]*/ + 0x10,0xFE,0x44,0x29,0xFE,0x01,0x7C,0x44,0x7D,0x44,0x7C,0x10,0xFE,0x10,0x10,0x11, + 0x40,0x78,0xD0,0x20,0x58,0x86,0xF8,0x20,0xFC,0x00,0xF8,0x88,0xA8,0xA8,0x50,0x88, + /* 0xB8D4 [?] [2214]*/ + 0x00,0x7F,0x40,0x40,0x40,0x48,0x44,0x42,0x41,0x42,0x44,0x48,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x24,0x44,0x84,0x04,0x84,0x44,0x24,0x04,0x04,0x14,0x08, + /* 0xB8D5 [?] [2215]*/ + 0x00,0x7F,0x41,0x41,0x65,0x55,0x55,0x49,0x49,0x55,0x55,0x65,0x41,0x41,0x45,0x42, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB8D6 [?] [2216]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x04,0x04,0x94,0x54,0x54,0x24,0x24,0x54,0x54,0x94,0x04,0x04,0x14,0x08, + /* 0xB8D7 [?] [2217]*/ + 0x20,0x20,0x3F,0x48,0x88,0x08,0xFF,0x08,0x08,0x49,0x49,0x49,0x4F,0x79,0x01,0x00, + 0x00,0x00,0x7E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xB8D8 [?] [2218]*/ + 0x00,0x3C,0x25,0x24,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x57,0x88, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB8D9 [?] [2219]*/ + 0x10,0x13,0x22,0x22,0x4A,0xFA,0x12,0x22,0x42,0xFA,0x42,0x03,0x1A,0xE2,0x42,0x02, + 0x00,0xFC,0x04,0x04,0x94,0x54,0x24,0x24,0x54,0x54,0x94,0x04,0x04,0x04,0x14,0x08, + /* 0xB8DA [?] [2220]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x20,0x20,0x24,0x22,0x21,0x22,0x24,0x28,0x20,0x20, + 0x00,0x08,0x08,0xF8,0x00,0xF8,0x08,0x48,0x48,0x88,0x08,0x88,0x48,0x08,0x28,0x10, + /* 0xB8DB [?] [2221]*/ + 0x01,0x21,0x17,0x11,0x81,0x4F,0x41,0x12,0x17,0x2A,0xE2,0x23,0x22,0x22,0x21,0x00, + 0x10,0x10,0xFC,0x10,0x10,0xFE,0x10,0x08,0xF4,0x12,0x10,0xF0,0x04,0x04,0xFC,0x00, + /* 0xB8DC [?] [2222]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x13,0x10, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xB8DD [?] [2223]*/ + 0x20,0x3E,0x48,0x82,0xFF,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x4F,0x48,0x4F,0x40, + 0x40,0x7E,0x90,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x00,0xFC,0x04,0xE4,0x24,0xE4,0x0C, + /* 0xB8DE [?] [2224]*/ + 0x02,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x02,0x7F,0x04,0x09,0x31,0xCF,0x01,0x01,0x01, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x40,0x20,0x18,0xE6,0x00,0x00,0x00, + /* 0xB8DF [?] [2225]*/ + 0x02,0x01,0xFF,0x00,0x0F,0x08,0x08,0x0F,0x00,0x7F,0x40,0x4F,0x48,0x48,0x4F,0x40, + 0x00,0x00,0xFE,0x00,0xE0,0x20,0x20,0xE0,0x00,0xFC,0x04,0xE4,0x24,0x24,0xE4,0x0C, + /* 0xB8E0 [?] [2226]*/ + 0x01,0x7F,0x08,0x0F,0x00,0x7F,0x48,0x8F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10, + 0x00,0xFC,0x20,0xE0,0x00,0xFE,0x22,0xE4,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x30, + /* 0xB8E1 [?] [2227]*/ + 0x08,0x04,0x04,0x7F,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00,0x48,0x44,0x84, + 0x20,0x20,0x40,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x88,0x44,0x44, + /* 0xB8E2 [?] [2228]*/ + 0x11,0x10,0x94,0x54,0x5B,0x10,0xFC,0x31,0x38,0x54,0x57,0x90,0x12,0x12,0x14,0x10, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0xA4,0x52,0x52,0x00, + /* 0xB8E3 [?] [2229]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x11,0x14,0x1B,0x32,0xD2,0x12,0x12,0x12,0x52,0x22, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xB8E4 [?] [2230]*/ + 0x20,0x20,0x3B,0x20,0x41,0x79,0xA1,0x20,0xFB,0x22,0x22,0x22,0x2A,0x32,0x22,0x02, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xB8E5 [?] [2231]*/ + 0x08,0x1C,0xF3,0x10,0x11,0xFD,0x11,0x38,0x37,0x52,0x52,0x92,0x12,0x12,0x12,0x12, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xB8E6 [?] [2232]*/ + 0x01,0x11,0x11,0x1F,0x21,0x41,0x01,0xFF,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xB8E7 [?] [2233]*/ + 0x00,0x7F,0x00,0x1F,0x10,0x10,0x1F,0x00,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x00,0x00, + 0x00,0xFC,0x10,0x90,0x90,0x90,0x90,0x00,0xFE,0x10,0x90,0x90,0x90,0x90,0x50,0x20, + /* 0xB8E8 [?] [2234]*/ + 0x00,0xFF,0x02,0x7A,0x4A,0x7A,0x00,0xFF,0x02,0x7A,0x4A,0x4A,0x7A,0x02,0x0A,0x04, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82, + /* 0xB8E9 [?] [2235]*/ + 0x22,0x21,0x25,0x24,0xF4,0x25,0x26,0x24,0x34,0xE7,0x25,0x25,0x25,0x25,0xA5,0x44, + 0x00,0x7C,0x04,0x84,0xF4,0x14,0xA4,0x44,0xA4,0x1C,0xF4,0x14,0x14,0xF4,0x14,0x08, + /* 0xB8EA [?] [2236]*/ + 0x02,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x01,0x01,0x00,0x03,0x0C,0x70,0x00, + 0x20,0x10,0x10,0x00,0xFE,0x00,0x08,0x08,0x10,0x20,0x40,0x80,0x42,0x22,0x1A,0x06, + /* 0xB8EB [?] [2237]*/ + 0x10,0x10,0x28,0x24,0x42,0x80,0x7C,0x00,0x00,0x7C,0x44,0x44,0x45,0x7C,0x44,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xB8EC [?] [2238]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xB8ED [?] [2239]*/ + 0x00,0x00,0x1F,0x11,0x91,0x53,0x54,0x18,0x33,0x50,0x90,0x10,0x21,0x22,0x42,0x81, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x00,0x00,0xF8,0x10,0x60,0x80,0x00,0x02,0x02,0xFE, + /* 0xB8EE [?] [2240]*/ + 0x10,0x08,0xFF,0x80,0x09,0x7F,0x08,0x7F,0x08,0xFF,0x08,0x7F,0x41,0x41,0x7F,0x41, + 0x04,0x04,0x84,0xA4,0x24,0x24,0x24,0x24,0x24,0xA4,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB8EF [?] [2241]*/ + 0x08,0x08,0x7F,0x08,0x08,0x0F,0x01,0x3F,0x21,0x21,0x3F,0x01,0xFF,0x01,0x01,0x01, + 0x20,0x20,0xFC,0x20,0x20,0xE0,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x00,0x00,0x00, + /* 0xB8F0 [?] [2242]*/ + 0x08,0xFF,0x08,0x1F,0x10,0x1F,0x10,0x1F,0x08,0x1F,0x21,0x52,0x94,0x10,0x1F,0x00, + 0x20,0xFE,0x20,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x04,0x84,0x44,0x04,0xA8,0x10, + /* 0xB8F1 [?] [2243]*/ + 0x10,0x10,0x10,0x11,0xFB,0x14,0x30,0x38,0x55,0x52,0x95,0x11,0x11,0x11,0x11,0x11, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xB8F2 [?] [2244]*/ + 0x10,0x10,0x10,0x7C,0x54,0x55,0x56,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x20,0x20,0x50,0x50,0x88,0x04,0xFA,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xB8F3 [?] [2245]*/ + 0x20,0x17,0x02,0x42,0x47,0x4C,0x52,0x41,0x42,0x4C,0x77,0x44,0x44,0x47,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x44,0x84,0x04,0x84,0x64,0xDC,0x44,0x44,0xC4,0x14,0x08, + /* 0xB8F4 [?] [2246]*/ + 0x00,0x7B,0x48,0x51,0x51,0x61,0x51,0x48,0x4B,0x4A,0x6A,0x53,0x42,0x42,0x42,0x42, + 0x00,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x8A,0x52,0xFE,0x22,0x22,0x2A,0x04, + /* 0xB8F5 [?] [2247]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBC,0x10,0x10,0xFD,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xB8F6 [?] [2248]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x21,0xC1,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB8F7 [?] [2249]*/ + 0x04,0x04,0x0F,0x18,0x24,0x03,0x0C,0x30,0xC0,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xF0,0x20,0xC0,0x00,0xC0,0x30,0x0E,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xB8F8 [?] [2250]*/ + 0x10,0x10,0x20,0x21,0x4A,0xF4,0x13,0x20,0x40,0xFB,0x42,0x02,0x1A,0xE2,0x43,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB8F9 [?] [2251]*/ + 0x10,0x13,0x12,0x12,0xFB,0x12,0x32,0x3B,0x56,0x52,0x92,0x12,0x12,0x12,0x13,0x12, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xB8FA [?] [2252]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xB8FB [?] [2253]*/ + 0x10,0x10,0x10,0xFE,0x11,0x7C,0x10,0xFE,0x13,0x38,0x34,0x54,0x50,0x91,0x11,0x12, + 0x88,0x88,0x88,0x88,0xFC,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xB8FC [?] [2254]*/ + 0x00,0xFF,0x01,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x11,0x0A,0x06,0x19,0xE0, + 0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0x00,0xC0,0x3E, + /* 0xB8FD [?] [2255]*/ + 0x01,0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x41,0x42,0x8C,0x30, + 0x00,0x80,0xFE,0x00,0x80,0xF8,0x88,0x88,0xFE,0x88,0x88,0xF8,0x40,0x20,0x18,0x06, + /* 0xB8FE [?] [2256]*/ + 0x04,0x7F,0x01,0x3F,0x01,0xFF,0x48,0x82,0x3F,0x01,0x1F,0x01,0xFF,0x02,0x0C,0x70, + 0x40,0xFC,0x00,0xF8,0x00,0xFE,0x24,0x82,0xF8,0x00,0xF0,0x00,0xFE,0x80,0x60,0x1C, + /* 0xB9A1 [?] [2257]*/ + 0x10,0x13,0x10,0x10,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE0,0x40,0x00,0x03, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xB9A2 [?] [2258]*/ + 0x00,0xFF,0x24,0x24,0x3C,0x24,0x24,0x3D,0x24,0x24,0x2E,0xF4,0x44,0x04,0x05,0x06, + 0x20,0x20,0x20,0x24,0xA4,0xA4,0xA8,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xB9A3 [?] [2259]*/ + 0x10,0x13,0x10,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x10,0x13, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xB9A4 [?] [2260]*/ + 0x00,0x00,0x7F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00, + /* 0xB9A5 [?] [2261]*/ + 0x00,0x00,0x00,0xFE,0x10,0x11,0x12,0x10,0x10,0x10,0x10,0x1E,0xF0,0x40,0x01,0x02, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xB9A6 [?] [2262]*/ + 0x00,0x00,0x00,0xFE,0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0xF1,0x41,0x02,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xB9A7 [?] [2263]*/ + 0x04,0x04,0x3F,0x04,0x04,0xFF,0x04,0x08,0x12,0x22,0xC2,0x12,0x12,0x22,0x0A,0x04, + 0x40,0x40,0xF8,0x40,0x40,0xFE,0x40,0x20,0x10,0x08,0x26,0x90,0x48,0x48,0x00,0x00, + /* 0xB9A8 [?] [2264]*/ + 0x04,0x04,0x7F,0x09,0x09,0x17,0x20,0xC4,0x04,0x3F,0x04,0x04,0xFF,0x08,0x10,0x20, + 0x20,0x10,0xFC,0x20,0xC4,0x04,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x20,0x10,0x08, + /* 0xB9A9 [?] [2265]*/ + 0x09,0x09,0x09,0x11,0x13,0x31,0x31,0x51,0x91,0x17,0x10,0x11,0x11,0x12,0x14,0x18, + 0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x10,0x10,0xFE,0x00,0x10,0x08,0x08,0x04,0x04, + /* 0xB9AA [?] [2266]*/ + 0x08,0x10,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x22,0xFE,0x06,0x0A,0x12,0x22,0x4A,0x04, + 0x00,0xFC,0x04,0x04,0x04,0x7C,0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xB9AB [?] [2267]*/ + 0x00,0x04,0x04,0x08,0x08,0x10,0x20,0x42,0x82,0x04,0x04,0x08,0x10,0x3F,0x10,0x00, + 0x80,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06,0x00,0x40,0x20,0x20,0xF0,0x10,0x00, + /* 0xB9AC [?] [2268]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x20,0x20,0x20,0x3F,0x20, + 0x00,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xB9AD [?] [2269]*/ + 0x00,0x7F,0x00,0x00,0x00,0x3F,0x20,0x20,0x40,0x7F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xB9AE [?] [2270]*/ + 0x00,0x01,0x7D,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04,0x08, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xB9AF [?] [2271]*/ + 0x00,0x3F,0x01,0x01,0x01,0xFF,0x00,0x01,0x01,0x7D,0x05,0x09,0x11,0x21,0xC5,0x02, + 0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x04,0x88,0x50,0x20,0x10,0x08,0x06,0x00, + /* 0xB9B0 [?] [2272]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x10,0x14,0x18,0x33,0xD0,0x10,0x10,0x11,0x52,0x24, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xFE,0x00,0x88,0x84,0x04,0x02,0x02, + /* 0xB9B1 [?] [2273]*/ + 0x00,0x3F,0x01,0x01,0x7F,0x00,0x00,0x1F,0x10,0x11,0x11,0x11,0x12,0x04,0x18,0x60, + 0x00,0xF8,0x00,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xB9B2 [?] [2274]*/ + 0x04,0x04,0x04,0x04,0x3F,0x04,0x04,0x04,0x04,0x04,0x7F,0x00,0x04,0x08,0x10,0x20, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00,0x20,0x10,0x08,0x04, + /* 0xB9B3 [?] [2275]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBD,0x12,0x10,0xFC,0x10,0x11,0x11,0x14,0x18,0x10,0x00, + 0x80,0x80,0x80,0xFC,0x04,0x04,0x44,0x44,0x84,0xA4,0x14,0xF4,0x14,0x04,0x28,0x10, + /* 0xB9B4 [?] [2276]*/ + 0x08,0x08,0x10,0x1F,0x20,0x42,0x82,0x04,0x04,0x08,0x10,0x3F,0x10,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x88,0x48,0xE8,0x28,0x08,0x50,0x20, + /* 0xB9B5 [?] [2277]*/ + 0x01,0x21,0x11,0x11,0x82,0x44,0x40,0x11,0x11,0x22,0xE7,0x22,0x20,0x20,0x20,0x00, + 0x00,0x00,0x00,0xFC,0x04,0x84,0x84,0x04,0x44,0x24,0xF4,0x14,0x04,0x04,0x28,0x10, + /* 0xB9B6 [?] [2278]*/ + 0x04,0x04,0xFF,0x04,0x10,0x1F,0x20,0x40,0x9F,0x10,0x10,0x1F,0x10,0x00,0x00,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0x88,0x88,0x08,0x50,0x20, + /* 0xB9B7 [?] [2279]*/ + 0x00,0x44,0x29,0x11,0x2A,0x4C,0x89,0x09,0x19,0x29,0x49,0x89,0x08,0x08,0x50,0x20, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x04,0x28,0x10, + /* 0xB9B8 [?] [2280]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0xFE,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x00, + /* 0xB9B9 [?] [2281]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x32,0x38,0x54,0x54,0x91,0x11,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFC,0x04,0x04,0x44,0x44,0x84,0xA4,0x14,0xF4,0x14,0x04,0x28,0x10, + /* 0xB9BA [?] [2282]*/ + 0x00,0x7C,0x44,0x54,0x55,0x55,0x56,0x54,0x54,0x54,0x55,0x11,0x28,0x24,0x44,0x80, + 0x80,0x80,0x80,0xFC,0x04,0x04,0x44,0x44,0x84,0xA4,0x14,0xF4,0x14,0x04,0x28,0x10, + /* 0xB9BB [?] [2283]*/ + 0x20,0x20,0x40,0x7E,0x82,0x02,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x14,0x08, + 0x20,0x20,0x7C,0x44,0xA8,0x10,0x20,0xD0,0x1E,0x22,0x64,0x94,0x08,0x10,0x20,0xC0, + /* 0xB9BC [?] [2284]*/ + 0x01,0x7F,0x01,0x1F,0x10,0x1F,0x01,0x3F,0x08,0x04,0xFF,0x01,0x3F,0x01,0x01,0x01, + 0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x20,0x40,0xFE,0x00,0xF8,0x00,0x00,0x00, + /* 0xB9BD [?] [2285]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0xFE,0x12,0x22,0x22,0x64,0x14,0x08,0x14,0x22,0xC0, + 0x40,0x40,0xFE,0x40,0x10,0x10,0xFE,0x10,0x10,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xB9BE [?] [2286]*/ + 0x00,0x00,0x78,0x48,0x4B,0x48,0x48,0x48,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB9BF [?] [2287]*/ + 0x20,0x3F,0x48,0x85,0x10,0x13,0x12,0xFE,0x12,0x12,0x1E,0xF2,0x12,0x12,0x52,0x23, + 0x40,0x7E,0x90,0x08,0x00,0xFE,0x20,0x20,0xFC,0xA4,0xA4,0xA4,0xB4,0xA8,0x20,0xFE, + /* 0xB9C0 [?] [2288]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x50,0x93,0x12,0x12,0x12,0x12,0x12,0x13,0x12, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB9C1 [?] [2289]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x48,0x08,0x13,0x12,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xB9C2 [?] [2290]*/ + 0x00,0xF8,0x0B,0x12,0x22,0x22,0x2A,0x32,0x22,0xE2,0x22,0x22,0x22,0x24,0xA4,0x48, + 0x08,0x3C,0xD0,0x90,0x90,0x90,0x90,0x90,0x90,0x88,0x88,0xC8,0xA4,0xD4,0x92,0x00, + /* 0xB9C3 [?] [2291]*/ + 0x10,0x10,0x10,0x10,0xFD,0x24,0x24,0x24,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xB9C4 [?] [2292]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7E,0x00,0x7E,0x42,0x42,0x7E,0x42,0x24,0x0F,0xF0,0x40, + 0x10,0x10,0x10,0xFE,0x10,0x10,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xB9C5 [?] [2293]*/ + 0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xB9C6 [?] [2294]*/ + 0x01,0x01,0x3F,0x21,0x21,0x3F,0x01,0x01,0x7F,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0xF8,0x08,0x08,0xF8,0x00,0x08,0xFC,0x04,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xB9C7 [?] [2295]*/ + 0x1F,0x10,0x1F,0x10,0x10,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0xF0,0x10,0x90,0x90,0x90,0xFE,0x02,0xF4,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xB9C8 [?] [2296]*/ + 0x08,0x08,0x11,0x21,0x42,0x04,0x08,0x30,0xC0,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x20,0x10,0x08,0x04,0x80,0x40,0x20,0x18,0x06,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xB9C9 [?] [2297]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3D,0x26,0x25,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x8B, + 0x00,0xF8,0x88,0x88,0x88,0x06,0x00,0xFC,0x84,0x84,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xB9CA [?] [2298]*/ + 0x10,0x10,0x10,0x10,0xFE,0x11,0x12,0x10,0x7C,0x44,0x44,0x44,0x44,0x7C,0x45,0x02, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xB9CB [?] [2299]*/ + 0x00,0x7E,0x40,0x40,0x5E,0x52,0x52,0x52,0x5A,0x54,0x50,0x52,0x54,0x58,0x50,0x83, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xB9CC [?] [2300]*/ + 0x00,0x7F,0x41,0x41,0x5F,0x41,0x41,0x4F,0x48,0x48,0x48,0x4F,0x48,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0xFC,0x04, + /* 0xB9CD [?] [2301]*/ + 0x01,0x00,0x3F,0x20,0x3F,0x22,0x22,0x27,0x2C,0x37,0x24,0x27,0x44,0x44,0x87,0x04, + 0x00,0x80,0xFC,0x04,0xFC,0x80,0x40,0xFC,0x40,0xF8,0x40,0xF8,0x40,0x40,0xFC,0x00, + /* 0xB9CE [?] [2302]*/ + 0x02,0x0F,0x78,0x08,0x08,0xFF,0x08,0x08,0x08,0x7F,0x41,0x41,0x41,0x41,0x7F,0x41, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB9CF [?] [2303]*/ + 0x00,0x00,0x1F,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x43,0x42,0x80, + 0x10,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x90,0x50,0xA8,0x28,0x04,0x02, + /* 0xB9D0 [?] [2304]*/ + 0x00,0x7F,0x41,0x41,0x41,0x7F,0x08,0x08,0xFF,0x88,0x94,0xA2,0xC2,0x80,0x82,0x81, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0xA4,0xA4,0xA4,0xA4,0x84,0x84,0x94,0x08, + /* 0xB9D1 [?] [2305]*/ + 0x01,0x7F,0x40,0xBF,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10,0xFF,0x08,0x37,0xC2,0x0C, + 0x00,0xFE,0x02,0xF4,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xFE,0x20,0xD8,0x46,0xC0, + /* 0xB9D2 [?] [2306]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x13,0x10,0x18,0x30,0xD1,0x10,0x10,0x10,0x53,0x20, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xB9D3 [?] [2307]*/ + 0x21,0x11,0x07,0xF1,0x11,0x21,0x2F,0x68,0xB1,0x29,0x27,0x21,0x21,0x21,0x2E,0x24, + 0x10,0x10,0xD0,0x10,0x10,0x18,0xF4,0x12,0x12,0x10,0xD0,0x10,0x10,0xD0,0x10,0x10, + /* 0xB9D4 [?] [2308]*/ + 0x00,0x1F,0x01,0x01,0xFF,0x01,0x09,0x09,0x79,0x09,0x09,0x19,0xE9,0x01,0x01,0x01, + 0x70,0x80,0x00,0x00,0xFE,0x00,0x20,0x24,0x28,0x30,0x22,0x22,0x1E,0x00,0x00,0x00, + /* 0xB9D5 [?] [2309]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x10,0x14,0x1B,0x30,0xD0,0x10,0x10,0x11,0x52,0x24, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x40,0x40,0xFC,0x44,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xB9D6 [?] [2310]*/ + 0x10,0x17,0x12,0x11,0x18,0x54,0x50,0x53,0x9C,0x10,0x17,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x46,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xB9D7 [?] [2311]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB9D8 [?] [2312]*/ + 0x10,0x08,0x08,0x00,0x3F,0x01,0x01,0x01,0xFF,0x01,0x02,0x02,0x04,0x08,0x30,0xC0, + 0x10,0x10,0x20,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x80,0x80,0x40,0x20,0x18,0x06, + /* 0xB9D9 [?] [2313]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xB9DA [?] [2314]*/ + 0x00,0x7F,0x40,0x80,0x3E,0x00,0x00,0x7E,0x14,0x14,0x14,0x14,0x24,0x24,0x43,0x80, + 0x00,0xFE,0x02,0x04,0x08,0x08,0xFE,0x08,0x48,0x28,0x08,0x2A,0x12,0x02,0xFE,0x00, + /* 0xB9DB [?] [2315]*/ + 0x00,0x01,0x01,0xFD,0x05,0x05,0x49,0x29,0x11,0x11,0x28,0x24,0x44,0x81,0x02,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xB9DC [?] [2316]*/ + 0x20,0x3F,0x48,0x85,0x01,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x40,0x7E,0x90,0x08,0x00,0xFE,0x02,0xE4,0x20,0xE0,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xB9DD [?] [2317]*/ + 0x20,0x20,0x23,0x3A,0x4C,0x51,0x81,0x21,0x21,0x21,0x21,0x21,0x29,0x31,0x21,0x01, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xB9DE [?] [2318]*/ + 0x40,0x43,0x78,0xA3,0x22,0x23,0xF8,0x20,0x21,0xA9,0xAB,0xAD,0xB9,0xC9,0x01,0x01, + 0x88,0xFE,0x88,0xDE,0x52,0xDE,0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xB9DF [?] [2319]*/ + 0x11,0x11,0x11,0x13,0x19,0x55,0x51,0x50,0x91,0x11,0x11,0x11,0x11,0x10,0x10,0x13, + 0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x00,0xFC,0x04,0x24,0x24,0x24,0x58,0x84,0x02, + /* 0xB9E0 [?] [2320]*/ + 0x01,0x4F,0x21,0x27,0x04,0x87,0x41,0x51,0x13,0x22,0xE7,0x2A,0x23,0x22,0x23,0x02, + 0x10,0xFE,0x10,0xBC,0xA4,0xBC,0x40,0x20,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xB9E1 [?] [2321]*/ + 0x1F,0x11,0x11,0xFF,0x11,0x11,0x1F,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0xF0,0x10,0x10,0xFE,0x10,0x10,0xF0,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xB9E2 [?] [2322]*/ + 0x01,0x21,0x11,0x09,0x09,0x01,0xFF,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x08,0x08,0x10,0x20,0x00,0xFE,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xB9E3 [?] [2323]*/ + 0x01,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0x80,0x80,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xB9E4 [?] [2324]*/ + 0x00,0x48,0x25,0x22,0x0D,0x01,0xE1,0x23,0x2D,0x21,0x21,0x2A,0x24,0x50,0x8F,0x00, + 0x00,0x80,0x7C,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x7E,0x00,0x00,0xFE,0x00, + /* 0xB9E5 [?] [2325]*/ + 0x00,0x00,0xFB,0x22,0x22,0x23,0x22,0xFA,0x23,0x20,0x20,0x38,0xE1,0x41,0x02,0x04, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x40,0xA8,0xB4,0x3C,0x22,0x22,0x1E, + /* 0xB9E6 [?] [2326]*/ + 0x10,0x11,0x11,0x7D,0x11,0x11,0x11,0xFF,0x11,0x11,0x10,0x28,0x24,0x45,0x82,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xB9E7 [?] [2327]*/ + 0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xB9E8 [?] [2328]*/ + 0x00,0x00,0xF9,0x20,0x20,0x40,0x7B,0x48,0xC8,0x48,0x49,0x48,0x78,0x48,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xB9E9 [?] [2329]*/ + 0x08,0x08,0x4B,0x48,0x48,0x48,0x48,0x49,0x48,0x48,0x48,0x08,0x10,0x13,0x20,0x40, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xB9EA [?] [2330]*/ + 0x04,0x04,0x0F,0x10,0x20,0x7F,0xA1,0x21,0x3F,0x21,0x21,0x3F,0x21,0x01,0x01,0x00, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x02,0x02,0xFE, + /* 0xB9EB [?] [2331]*/ + 0x20,0x17,0x00,0x41,0x4F,0x41,0x41,0x5F,0x40,0x41,0x4F,0x41,0x41,0x5F,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x04,0x04,0xF4,0x04,0x04,0xE4,0x04,0x04,0xF4,0x04,0x0C, + /* 0xB9EC [?] [2332]*/ + 0x20,0x20,0x20,0xFC,0x43,0x50,0x90,0xFC,0x10,0x10,0x1C,0xF0,0x51,0x11,0x12,0x14, + 0x80,0x80,0x80,0x80,0xF0,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xB9ED [?] [2333]*/ + 0x02,0x04,0x3F,0x21,0x21,0x3F,0x22,0x22,0x3F,0x05,0x09,0x09,0x11,0x21,0x41,0x80, + 0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x10,0x20,0x48,0x7C,0x02,0x02,0xFE, + /* 0xB9EE [?] [2334]*/ + 0x01,0x41,0x23,0x22,0x04,0x0B,0xE2,0x22,0x22,0x22,0x22,0x22,0x2A,0x34,0x24,0x08, + 0x00,0x00,0xF8,0x08,0x10,0xFE,0x00,0xF8,0x88,0x88,0xA8,0x90,0x82,0x82,0x7E,0x00, + /* 0xB9EF [?] [2335]*/ + 0x00,0x7E,0x02,0x44,0x28,0x10,0x20,0xCF,0x01,0x01,0x7F,0x01,0x02,0x04,0x18,0x60, + 0x90,0xA0,0x44,0x48,0x30,0x10,0x08,0xE6,0x00,0x00,0xFC,0x00,0xC0,0x20,0x10,0x08, + /* 0xB9F0 [?] [2336]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x91,0x10,0x10,0x10,0x13,0x10, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xB9F1 [?] [2337]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x10, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xB9F2 [?] [2338]*/ + 0x00,0x7C,0x44,0x45,0x46,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x40,0x40,0xFC,0x04,0x08,0xFE,0x00,0x7C,0x44,0x44,0x54,0x48,0x42,0x42,0x3E,0x00, + /* 0xB9F3 [?] [2339]*/ + 0x01,0x1F,0x11,0x11,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0xFE,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xB9F4 [?] [2340]*/ + 0x08,0x08,0x14,0x22,0x41,0xBE,0x00,0x00,0xFF,0x10,0x10,0x22,0x41,0xFF,0x41,0x00, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0xA4,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xB9F5 [?] [2341]*/ + 0x20,0x21,0x21,0xFD,0x41,0x51,0x91,0xFD,0x10,0x11,0x1D,0xF1,0x51,0x11,0x11,0x11, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xB9F6 [?] [2342]*/ + 0x00,0x20,0x17,0x11,0x82,0x44,0x41,0x13,0x10,0x20,0xE1,0x23,0x25,0x29,0x21,0x01, + 0x80,0x40,0xFC,0x10,0x48,0x84,0x20,0xF0,0x10,0x88,0x50,0x20,0x10,0x48,0x86,0x00, + /* 0xB9F7 [?] [2343]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x54,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xB9F8 [?] [2344]*/ + 0x20,0x21,0x39,0x21,0x41,0x79,0xA0,0x20,0xFB,0x22,0x22,0x22,0x2B,0x32,0x22,0x02, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xB9F9 [?] [2345]*/ + 0x10,0x08,0xFF,0x00,0x7E,0x42,0x7E,0x00,0x7E,0x04,0x08,0x0F,0xF8,0x08,0x28,0x10, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xB9FA [?] [2346]*/ + 0x00,0x7F,0x40,0x40,0x5F,0x41,0x41,0x4F,0x41,0x41,0x41,0x5F,0x40,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x04,0x44,0x24,0xF4,0x04,0x04,0xFC,0x04, + /* 0xB9FB [?] [2347]*/ + 0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x11,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xB9FC [?] [2348]*/ + 0x01,0xFF,0x00,0x1F,0x11,0x1F,0x11,0x1F,0x01,0xFF,0x13,0x65,0x0C,0x35,0xC6,0x04, + 0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0x88,0x50,0x30,0x0E,0x00, + /* 0xB9FD [?] [2349]*/ + 0x00,0x20,0x10,0x17,0x00,0x00,0xF2,0x11,0x11,0x10,0x10,0x10,0x10,0x28,0x47,0x00, + 0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,0x00,0xFE,0x00, + /* 0xB9FE [?] [2350]*/ + 0x00,0x00,0x78,0x49,0x4A,0x4C,0x4B,0x48,0x48,0x4B,0x7A,0x4A,0x02,0x02,0x03,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xBAA1 [?] [2351]*/ + 0x00,0x7C,0x44,0x75,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7D,0x44,0x44,0x54,0x49, + 0x20,0x10,0x10,0xFE,0x20,0x24,0x44,0xF8,0x12,0x22,0x44,0x88,0x10,0x28,0x44,0x82, + /* 0xBAA2 [?] [2352]*/ + 0x00,0xFC,0x04,0x0B,0x10,0x10,0x14,0x19,0x30,0xD0,0x10,0x13,0x10,0x10,0x50,0x23, + 0x20,0x10,0x10,0xFE,0x20,0x42,0x84,0xF8,0x10,0x22,0xC4,0x08,0x10,0x28,0xC4,0x02, + /* 0xBAA3 [?] [2353]*/ + 0x01,0x21,0x11,0x12,0x85,0x41,0x49,0x09,0x17,0x11,0xE2,0x22,0x23,0x20,0x20,0x00, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xBAA4 [?] [2354]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x04,0x7F,0x08,0x11,0x3E,0x04,0x19,0x62,0x0D,0x30, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x10,0x10,0x10,0x92,0x0A,0x0A,0x06,0x82, + /* 0xBAA5 [?] [2355]*/ + 0x02,0x01,0x00,0x7F,0x02,0x04,0x08,0x10,0x3F,0x01,0x06,0x18,0x60,0x03,0x0C,0x70, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x20,0x40,0x88,0x10,0x20,0x40,0xA0,0x10,0x08,0x04, + /* 0xBAA6 [?] [2356]*/ + 0x02,0x01,0x7F,0x40,0x81,0x3F,0x01,0x1F,0x01,0xFF,0x01,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xBAA7 [?] [2357]*/ + 0x00,0xF8,0x08,0x49,0x48,0x48,0x48,0x7C,0x04,0x04,0x1C,0xE5,0x44,0x04,0x28,0x11, + 0x20,0x10,0x10,0xFE,0x20,0x24,0x44,0xF8,0x12,0x22,0x44,0x88,0x10,0x28,0x44,0x82, + /* 0xBAA8 [?] [2358]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x44,0x44,0x44,0x44,0xFE,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xBAA9 [?] [2359]*/ + 0x7C,0x04,0xFF,0x22,0x3E,0x22,0x3E,0x23,0xFE,0x42,0x02,0x01,0x28,0x28,0x48,0x07, + 0x20,0x20,0x3E,0x44,0xA4,0x28,0x28,0x90,0x28,0x44,0x82,0x00,0x88,0xA4,0x24,0xE0, + /* 0xBAAA [?] [2360]*/ + 0x22,0x22,0x22,0x22,0xFF,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x22,0x3E,0x22,0x00, + 0x00,0x3E,0x22,0x24,0xA4,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xBAAB [?] [2361]*/ + 0x10,0x10,0x10,0xFE,0x10,0x7C,0x44,0x7C,0x44,0x7D,0x10,0xFE,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xBAAC [?] [2362]*/ + 0x01,0x01,0x02,0x04,0x0A,0x31,0xC1,0x0F,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x80,0x40,0x20,0x18,0x06,0xE0,0x40,0x80,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xBAAD [?] [2363]*/ + 0x00,0x23,0x10,0x10,0x84,0x45,0x44,0x14,0x14,0x25,0xE6,0x25,0x24,0x24,0x27,0x00, + 0x00,0xF8,0x10,0x20,0x44,0x54,0xE4,0x44,0xE4,0x54,0x4C,0x44,0x84,0x04,0xFC,0x04, + /* 0xBAAE [?] [2364]*/ + 0x02,0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x13,0x20,0xC0,0x06,0x01,0x00, + 0x00,0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0x10,0x88,0x46,0x00,0x80,0x40, + /* 0xBAAF [?] [2365]*/ + 0x00,0x3F,0x00,0x00,0x51,0x49,0x45,0x41,0x45,0x49,0x51,0x45,0x42,0x40,0x7F,0x00, + 0x00,0xF0,0x20,0x40,0x94,0x24,0x44,0x04,0x44,0x24,0x14,0x04,0x04,0x04,0xFC,0x04, + /* 0xBAB0 [?] [2366]*/ + 0x00,0x00,0x70,0x57,0x54,0x54,0x55,0x54,0x54,0x55,0x75,0x55,0x05,0x04,0x08,0x10, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD0,0x12,0x12,0xD4,0x54,0x48,0xDA,0x2A,0x46,0x82, + /* 0xBAB1 [?] [2367]*/ + 0x00,0x7F,0x40,0x88,0x10,0x20,0x1F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x00,0xFE,0x02,0x24,0x10,0x08,0xF0,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xBAB2 [?] [2368]*/ + 0x10,0x10,0x10,0xFE,0x11,0x7C,0x45,0x7C,0x45,0x7C,0x10,0xFE,0x11,0x10,0x11,0x10, + 0x20,0x20,0x50,0x88,0x06,0x00,0xDC,0x44,0x54,0xCC,0x44,0xCC,0x54,0x44,0x54,0x88, + /* 0xBAB3 [?] [2369]*/ + 0x20,0x20,0x27,0x24,0xF5,0x24,0x25,0x25,0x35,0xE4,0x24,0x28,0x22,0x22,0xA4,0x40, + 0x14,0x12,0xFE,0x10,0xD0,0x14,0xD4,0x58,0xCA,0x16,0x42,0x24,0xA2,0x8A,0x78,0x00, + /* 0xBAB4 [?] [2370]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x10,0x14,0x19,0x30,0xD0,0x13,0x10,0x10,0x50,0x20, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0x00,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xBAB5 [?] [2371]*/ + 0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01,0x01, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xBAB6 [?] [2372]*/ + 0x20,0x20,0x27,0x24,0x35,0xAC,0xA5,0xA5,0xA5,0x24,0x24,0x28,0x22,0x22,0x24,0x20, + 0x14,0x12,0xFE,0x10,0xD0,0x14,0xD4,0x58,0xCA,0x16,0x42,0x24,0xA2,0x8A,0x78,0x00, + /* 0xBAB7 [?] [2373]*/ + 0x10,0x11,0x11,0x11,0x19,0x55,0x50,0x50,0x91,0x10,0x10,0x13,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0x00,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xBAB8 [?] [2374]*/ + 0x10,0x11,0x11,0x11,0x55,0x59,0x50,0x90,0x11,0x10,0x10,0x2B,0x24,0x44,0x40,0x80, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0x00,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xBAB9 [?] [2375]*/ + 0x00,0x20,0x13,0x10,0x80,0x40,0x48,0x08,0x17,0x10,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xBABA [?] [2376]*/ + 0x00,0x27,0x12,0x12,0x82,0x41,0x49,0x09,0x10,0x10,0xE0,0x20,0x20,0x21,0x22,0x0C, + 0x00,0xF8,0x08,0x08,0x08,0x10,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0x10,0x08,0x06, + /* 0xBABB [?] [2377]*/ + 0x01,0x01,0x7F,0x02,0x04,0x08,0x30,0xC1,0x01,0x3F,0x02,0x02,0x04,0x08,0x10,0x60, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xBABC [?] [2378]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBABD [?] [2379]*/ + 0x10,0x20,0x7C,0x45,0x64,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x44,0x45,0x55,0x8A, + 0x40,0x20,0x00,0xFC,0x00,0x00,0xF0,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xBABE [?] [2380]*/ + 0x20,0x27,0x20,0x21,0xF9,0x21,0x20,0x27,0x24,0x23,0x29,0x36,0xE1,0x46,0x01,0x0E, + 0x40,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xFE,0x02,0xF8,0x80,0x44,0xB8,0x68,0xA6,0x60, + /* 0xBABF [?] [2381]*/ + 0x00,0x07,0xF0,0x91,0x91,0x91,0x90,0x97,0x94,0x93,0xF1,0x96,0x01,0x06,0x01,0x0E, + 0x40,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xFE,0x02,0xF8,0x80,0x44,0xB8,0x68,0xA6,0x60, + /* 0xBAC0 [?] [2382]*/ + 0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x9F,0x06,0x19,0x06,0x39,0x06,0x39, + 0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0x20,0xC0,0xB0,0x8C,0x80, + /* 0xBAC1 [?] [2383]*/ + 0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x81,0x3E,0x03,0x3E,0x03,0x7E,0x01, + 0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0xF0,0x00,0xFA,0x02,0xFE, + /* 0xBAC2 [?] [2384]*/ + 0x08,0x08,0x7F,0x08,0x08,0x08,0xFF,0x12,0x12,0x53,0x52,0x92,0x22,0x22,0x4A,0x84, + 0x00,0x3E,0x22,0x24,0x24,0x28,0xA4,0x24,0x22,0x22,0xA2,0xB4,0x28,0x20,0x20,0x20, + /* 0xBAC3 [?] [2385]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x24,0x25,0x24,0x48,0x28,0x10,0x28,0x44,0x84,0x00, + 0x00,0xFC,0x04,0x08,0x10,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xBAC4 [?] [2386]*/ + 0x10,0x10,0x10,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x38,0x35,0x54,0x50,0x90,0x10,0x10, + 0x08,0x1C,0xE0,0x20,0x20,0x3C,0xE0,0x20,0x20,0x3E,0xE0,0x20,0x22,0x22,0x22,0x1E, + /* 0xBAC5 [?] [2387]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x00,0xFF,0x08,0x10,0x1F,0x00,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0xA0,0x40, + /* 0xBAC6 [?] [2388]*/ + 0x00,0x22,0x12,0x13,0x84,0x48,0x40,0x17,0x10,0x20,0xE3,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBAC7 [?] [2389]*/ + 0x00,0x00,0x7B,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xBAC8 [?] [2390]*/ + 0x00,0x03,0x7A,0x4B,0x4A,0x4B,0x49,0x4B,0x4C,0x4A,0x7A,0x4A,0x03,0x00,0x00,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xBAC9 [?] [2391]*/ + 0x04,0x04,0xFF,0x04,0x10,0x17,0x20,0x60,0xA7,0x24,0x24,0x24,0x27,0x20,0x20,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xBACA [?] [2392]*/ + 0x04,0x04,0xFF,0x04,0x20,0x17,0x10,0x80,0x4B,0x4A,0x12,0xE3,0x22,0x20,0x20,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0xC8,0x48,0x08,0x28,0x10, + /* 0xBACB [?] [2393]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x30,0x39,0x54,0x54,0x90,0x13,0x10,0x10,0x10,0x13, + 0x20,0x10,0x10,0xFE,0x20,0x42,0x84,0xF8,0x10,0x22,0xC4,0x08,0x10,0x28,0xC4,0x02, + /* 0xBACC [?] [2394]*/ + 0x00,0x00,0x3F,0x01,0x01,0x01,0x7F,0x03,0x05,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x10,0xF8,0x00,0x00,0x00,0x00,0xFC,0x80,0x40,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xBACD [?] [2395]*/ + 0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08, + 0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + /* 0xBACE [?] [2396]*/ + 0x08,0x08,0x0F,0x10,0x10,0x33,0x32,0x52,0x92,0x12,0x13,0x12,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0xC8,0x48,0x08,0x08,0x28,0x10, + /* 0xBACF [?] [2397]*/ + 0x01,0x01,0x02,0x04,0x08,0x30,0xCF,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xBAD0 [?] [2398]*/ + 0x01,0x02,0x0C,0x30,0xCF,0x00,0x1F,0x10,0x1F,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x80,0x60,0x18,0xE6,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xBAD1 [?] [2399]*/ + 0x10,0x20,0xD4,0x09,0x53,0x24,0xD0,0x18,0x29,0xCA,0x1D,0x29,0xC9,0x09,0x51,0x21, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBAD2 [?] [2400]*/ + 0x20,0x17,0x00,0x42,0x41,0x5F,0x42,0x44,0x4F,0x41,0x46,0x58,0x43,0x4C,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x44,0x84,0x24,0x44,0x84,0x44,0x24,0x04,0x0C, + /* 0xBAD3 [?] [2401]*/ + 0x00,0x20,0x17,0x10,0x80,0x43,0x42,0x12,0x12,0x22,0xE3,0x22,0x20,0x20,0x20,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0xC8,0x48,0x08,0x08,0x28,0x10, + /* 0xBAD4 [?] [2402]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x15,0x15,0x25,0xE5,0x25,0x25,0x24,0x27,0x04, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xF4,0x14,0x14,0x14,0xF4,0x14,0x04,0xFC,0x04, + /* 0xBAD5 [?] [2403]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFE,0x14,0x14,0x56,0x55,0x94,0x24,0x24,0x54,0x89, + 0x20,0x20,0x20,0xF8,0x20,0x20,0xFE,0x50,0x50,0xD8,0x54,0x52,0x50,0x90,0x90,0x30, + /* 0xBAD6 [?] [2404]*/ + 0x20,0x13,0x02,0xF3,0x12,0x23,0x21,0x6B,0xB4,0x2A,0x22,0x22,0x23,0x20,0x20,0x20, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xBAD7 [?] [2405]*/ + 0x08,0x08,0x7F,0x55,0x12,0x3F,0x64,0xA4,0x3F,0x24,0x24,0x3F,0x24,0x24,0x3F,0x20, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xBAD8 [?] [2406]*/ + 0x10,0x10,0x7E,0x12,0x22,0x2A,0x44,0x9F,0x10,0x11,0x11,0x11,0x12,0x04,0x18,0x60, + 0x00,0x00,0x7C,0x44,0x44,0x7C,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xBAD9 [?] [2407]*/ + 0x00,0x07,0xF4,0x95,0x94,0x94,0x97,0x90,0x97,0x90,0xF0,0x9F,0x00,0x05,0x04,0x08, + 0x00,0xFC,0x44,0x54,0xE4,0x44,0xFC,0x40,0xFC,0x40,0x40,0xFE,0x00,0x24,0x92,0x92, + /* 0xBADA [?] [2408]*/ + 0x00,0x3F,0x21,0x29,0x25,0x3F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00,0x48,0x44,0x84, + 0x00,0xF8,0x08,0x28,0x48,0xF8,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x88,0x44,0x44, + /* 0xBADB [?] [2409]*/ + 0x00,0x00,0x1F,0x10,0x97,0x54,0x57,0x14,0x37,0x54,0x94,0x14,0x24,0x25,0x46,0x84, + 0x80,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x84,0x88,0x50,0x20,0x18,0x06,0x00, + /* 0xBADC [?] [2410]*/ + 0x08,0x0B,0x12,0x22,0x4B,0x0A,0x12,0x33,0x52,0x92,0x12,0x12,0x12,0x12,0x13,0x12, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xBADD [?] [2411]*/ + 0x00,0x45,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x51,0x21, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xBADE [?] [2412]*/ + 0x10,0x13,0x12,0x12,0x1B,0x56,0x52,0x53,0x92,0x12,0x12,0x12,0x12,0x12,0x13,0x12, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xBADF [?] [2413]*/ + 0x00,0x00,0x7B,0x48,0x49,0x49,0x49,0x49,0x48,0x4B,0x78,0x48,0x00,0x00,0x00,0x00, + 0x40,0x20,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x08,0x30,0x20,0x20,0xA0,0x40, + /* 0xBAE0 [?] [2414]*/ + 0x02,0x01,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x00,0x01,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x00,0xF0,0x60,0x80,0x00,0x00,0x00,0x00, + /* 0xBAE1 [?] [2415]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x11,0x12, + 0x88,0x88,0xFC,0x88,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0x88,0x04,0x02, + /* 0xBAE2 [?] [2416]*/ + 0x12,0x13,0x24,0x48,0x87,0x15,0x25,0x67,0xA5,0x25,0x27,0x21,0x2F,0x21,0x22,0x24, + 0x00,0xC0,0x4E,0x80,0xC0,0x40,0x5E,0xC4,0x44,0x44,0xC4,0x04,0xE4,0x04,0x94,0x48, + /* 0xBAE3 [?] [2417]*/ + 0x10,0x13,0x10,0x10,0x19,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x10,0x10,0x13,0x10, + 0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xBAE4 [?] [2418]*/ + 0x02,0x02,0x7F,0x08,0x11,0x3F,0x01,0xFF,0x01,0x01,0x3E,0x02,0x14,0x08,0x34,0xC2, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0xFE,0x00,0x00,0xF8,0x88,0x50,0x20,0x58,0x86, + /* 0xBAE5 [?] [2419]*/ + 0x01,0x01,0x79,0x49,0x4B,0x49,0x49,0x49,0x49,0x4F,0x78,0x49,0x01,0x02,0x04,0x08, + 0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x10,0x10,0xFE,0x00,0x10,0x08,0x08,0x04,0x04, + /* 0xBAE6 [?] [2420]*/ + 0x10,0x10,0x10,0x10,0x55,0x58,0x50,0x90,0x10,0x13,0x10,0x28,0x24,0x45,0x42,0x84, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xFE,0x00,0x88,0x84,0x04,0x02,0x02, + /* 0xBAE7 [?] [2421]*/ + 0x10,0x10,0x11,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x43,0x00, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBAE8 [?] [2422]*/ + 0x00,0x80,0x40,0x1F,0x84,0x44,0x44,0x04,0x24,0x44,0xC4,0x47,0x5C,0x48,0x40,0x00, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xBAE9 [?] [2423]*/ + 0x01,0x21,0x11,0x11,0x87,0x41,0x41,0x11,0x11,0x2F,0xE0,0x21,0x21,0x22,0x24,0x08, + 0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x10,0x10,0xFE,0x00,0x10,0x08,0x08,0x04,0x04, + /* 0xBAEA [?] [2424]*/ + 0x02,0x01,0x7F,0x40,0x82,0x02,0x7F,0x04,0x04,0x08,0x09,0x11,0x22,0x44,0x8F,0x04, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xFC,0x00,0x80,0x80,0x00,0x00,0x20,0x10,0xF8,0x08, + /* 0xBAEB [?] [2425]*/ + 0x00,0x7C,0x04,0x04,0x04,0x7C,0x40,0x40,0x40,0x7C,0x04,0x05,0x07,0x05,0x28,0x10, + 0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x80,0x88,0x84,0x04,0xFE,0x02,0x02,0x00, + /* 0xBAEC [?] [2426]*/ + 0x10,0x10,0x21,0x24,0x44,0xF8,0x10,0x20,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x43,0x00, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBAED [?] [2427]*/ + 0x01,0x01,0x71,0x52,0x52,0x56,0x5A,0x52,0x52,0x52,0x72,0x52,0x02,0x02,0x02,0x02, + 0x00,0x78,0x08,0x08,0xFE,0x40,0x40,0x7C,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xBAEE [?] [2428]*/ + 0x08,0x0B,0x08,0x10,0x17,0x31,0x31,0x53,0x94,0x10,0x1F,0x10,0x10,0x11,0x12,0x1C, + 0x00,0xF8,0x08,0x08,0xFE,0x00,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xBAEF [?] [2429]*/ + 0x01,0x89,0x51,0x22,0x52,0x96,0x1A,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0xA2,0x42, + 0x00,0x78,0x08,0x08,0xFE,0x40,0x40,0x7C,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xBAF0 [?] [2430]*/ + 0x00,0x07,0x78,0x48,0x49,0x49,0x49,0x49,0x49,0x4F,0x79,0x49,0x01,0x01,0x05,0x02, + 0x10,0xD0,0x50,0x90,0x10,0x10,0x50,0x90,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBAF1 [?] [2431]*/ + 0x00,0x3F,0x20,0x27,0x24,0x27,0x24,0x27,0x20,0x27,0x20,0x20,0x2F,0x40,0x41,0x80, + 0x00,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xF8,0x10,0x20,0xFE,0x40,0x40,0x80, + /* 0xBAF2 [?] [2432]*/ + 0x10,0x13,0x10,0x28,0x2F,0x69,0x69,0xAB,0x2C,0x28,0x2F,0x28,0x28,0x21,0x22,0x2C, + 0x00,0xF8,0x08,0x08,0xFE,0x00,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xBAF3 [?] [2433]*/ + 0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x17,0x14,0x24,0x24,0x44,0x87,0x04, + 0x10,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xBAF4 [?] [2434]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x48,0x48,0x4B,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x08,0x3C,0xE0,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xBAF5 [?] [2435]*/ + 0x00,0x00,0x3F,0x01,0x11,0x09,0x09,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x10,0xF8,0x00,0x00,0x10,0x10,0x20,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xBAF6 [?] [2436]*/ + 0x08,0x08,0x1F,0x12,0x22,0x44,0x08,0x11,0x22,0x04,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0xF8,0x48,0x48,0x88,0x88,0x08,0x28,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xBAF7 [?] [2437]*/ + 0x01,0x01,0xF9,0x27,0x21,0x21,0x21,0xFB,0x22,0x22,0x22,0x3A,0xE3,0x40,0x00,0x00, + 0x00,0x3C,0x24,0xE4,0x24,0x3C,0x24,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0x44,0x54,0x88, + /* 0xBAF8 [?] [2438]*/ + 0x01,0x01,0x7F,0x01,0x01,0x1F,0x00,0x7F,0x40,0x84,0x04,0x24,0x14,0x14,0x04,0x7F, + 0x00,0x00,0xFC,0x00,0x00,0xF0,0x00,0xFE,0x02,0x44,0x40,0x48,0x48,0x50,0x40,0xFC, + /* 0xBAF9 [?] [2439]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x7F,0x08,0x08,0x3E,0x22,0x22,0x22,0x3E,0x22,0x01, + 0x40,0x40,0xFE,0x40,0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x84,0x94,0x08, + /* 0xBAFA [?] [2440]*/ + 0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x3E,0x22,0x22,0x22,0x22,0x3E,0x22,0x01,0x02, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x84,0x84,0x14,0x08, + /* 0xBAFB [?] [2441]*/ + 0x21,0x21,0x21,0xFB,0xA9,0xA9,0xA9,0xAB,0xFA,0xA2,0x22,0x2A,0x3B,0xE8,0x40,0x00, + 0x00,0x3C,0x24,0xA4,0x24,0x3C,0x24,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0x44,0x54,0x88, + /* 0xBAFC [?] [2442]*/ + 0x00,0x88,0x53,0x22,0x52,0x92,0x12,0x12,0x32,0x52,0x92,0x12,0x12,0x14,0xA4,0x48, + 0x08,0x3C,0xD0,0x90,0x90,0x90,0x90,0x90,0x90,0x88,0x88,0xC8,0xA4,0xD4,0x92,0x00, + /* 0xBAFD [?] [2443]*/ + 0x10,0x10,0x94,0x55,0x58,0x10,0xFC,0x31,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x10, + 0x80,0x9E,0x92,0xD2,0x92,0x9E,0x92,0xD2,0x52,0x5E,0x52,0x52,0xD2,0x22,0x2A,0x44, + /* 0xBAFE [?] [2444]*/ + 0x01,0x21,0x11,0x17,0x81,0x41,0x41,0x17,0x14,0x24,0xE4,0x27,0x24,0x20,0x20,0x00, + 0x00,0x1E,0x12,0xD2,0x12,0x1E,0x12,0xD2,0x52,0x5E,0x52,0xD2,0x52,0x22,0x2A,0x44, + /* 0xBBA1 [?] [2445]*/ + 0x00,0xF8,0x0B,0x0A,0x0A,0x7A,0x42,0x42,0x42,0x7A,0x0A,0x0A,0x0A,0x0C,0x54,0x28, + 0x08,0x3C,0xD0,0x90,0x90,0x90,0x90,0x90,0x90,0x88,0x88,0xC8,0xA4,0xD4,0x92,0x00, + /* 0xBBA2 [?] [2446]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x21,0x20,0x20,0x23,0x22,0x22,0x44,0x48,0x90, + 0x00,0xF8,0x00,0xFC,0x04,0x60,0x88,0x08,0xF8,0x00,0xE0,0x20,0x20,0x24,0x24,0x1C, + /* 0xBBA3 [?] [2447]*/ + 0x00,0x00,0x78,0x48,0x4B,0x4A,0x4A,0x4B,0x4A,0x4A,0x7A,0x4A,0x04,0x04,0x09,0x12, + 0x40,0x40,0x7C,0x40,0xFC,0x44,0x70,0xC0,0x44,0x3C,0x00,0xF0,0x90,0x92,0x12,0x0E, + /* 0xBBA4 [?] [2448]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x12,0x12,0x54,0x28, + 0x40,0x20,0x20,0xFE,0x02,0x02,0x02,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xBBA5 [?] [2449]*/ + 0x00,0x7F,0x04,0x04,0x04,0x0F,0x08,0x08,0x10,0x10,0x1F,0x00,0x00,0x00,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x20,0xE0,0x20,0x40,0x40,0xFE,0x00, + /* 0xBBA6 [?] [2450]*/ + 0x00,0x20,0x10,0x13,0x82,0x42,0x42,0x13,0x12,0x22,0xE2,0x22,0x24,0x24,0x28,0x10, + 0x80,0x40,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xBBA7 [?] [2451]*/ + 0x02,0x01,0x01,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xBBA8 [?] [2452]*/ + 0x08,0x08,0xFF,0x08,0x00,0x08,0x08,0x10,0x30,0x50,0x91,0x12,0x14,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x00,0x88,0x90,0xA0,0xC0,0x80,0x80,0x82,0x82,0x82,0x7E,0x00, + /* 0xBBA9 [?] [2453]*/ + 0x00,0x00,0x79,0x49,0x4B,0x4D,0x49,0x49,0x49,0x48,0x7B,0x48,0x00,0x00,0x00,0x00, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xBBAA [?] [2454]*/ + 0x08,0x08,0x10,0x30,0x51,0x96,0x10,0x10,0x11,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x80,0x88,0x90,0xE0,0x80,0x84,0x84,0x7C,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xBBAB [?] [2455]*/ + 0x00,0x8B,0x52,0x23,0x52,0x9F,0x18,0x13,0x32,0x53,0x92,0x13,0x12,0x12,0xA2,0x42, + 0x00,0xF8,0x08,0xC8,0x48,0xFE,0x02,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xBBAC [?] [2456]*/ + 0x00,0x23,0x12,0x13,0x82,0x4F,0x48,0x13,0x12,0x23,0xE2,0x23,0x22,0x22,0x22,0x02, + 0x00,0xF8,0x08,0xC8,0x48,0xFE,0x02,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xBBAD [?] [2457]*/ + 0x00,0xFF,0x00,0x00,0x4F,0x49,0x49,0x4F,0x49,0x49,0x49,0x4F,0x40,0x40,0x7F,0x00, + 0x00,0xFE,0x00,0x00,0xE4,0x24,0x24,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0xFC,0x04, + /* 0xBBAE [?] [2458]*/ + 0x10,0x14,0x12,0x10,0x13,0xFC,0x10,0x11,0x11,0x12,0x0C,0x08,0x14,0x22,0xC1,0x00, + 0x04,0x04,0x04,0x24,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0xA4,0x84,0x84,0x94,0x88, + /* 0xBBAF [?] [2459]*/ + 0x08,0x08,0x08,0x10,0x10,0x30,0x30,0x50,0x91,0x12,0x14,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x84,0x88,0x90,0xA0,0xC0,0x80,0x80,0x80,0x80,0x82,0x82,0x82,0x7E,0x00, + /* 0xBBB0 [?] [2460]*/ + 0x00,0x20,0x11,0x10,0x00,0x03,0xF0,0x10,0x10,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xBBB1 [?] [2461]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x40,0xB0,0xA4,0x3C,0x22,0x22,0x1E, + /* 0xBBB2 [?] [2462]*/ + 0x08,0x08,0x13,0x22,0x4A,0x0A,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x10, + 0x00,0x00,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0xFC,0x04,0x00, + /* 0xBBB3 [?] [2463]*/ + 0x10,0x10,0x17,0x10,0x18,0x54,0x50,0x50,0x91,0x12,0x14,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x42,0x40,0x40,0x40,0x40,0x40, + /* 0xBBB4 [?] [2464]*/ + 0x01,0x21,0x11,0x13,0x82,0x46,0x4B,0x12,0x12,0x23,0xE2,0x22,0x22,0x23,0x22,0x02, + 0x40,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00, + /* 0xBBB5 [?] [2465]*/ + 0x10,0x10,0x13,0x10,0x10,0xFC,0x10,0x10,0x10,0x10,0x1D,0xE2,0x44,0x00,0x00,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x68,0x64,0xA4,0x22,0x22,0x20,0x20,0x20,0x20, + /* 0xBBB6 [?] [2466]*/ + 0x00,0x00,0xFC,0x04,0x05,0x49,0x2A,0x14,0x10,0x28,0x24,0x45,0x81,0x02,0x04,0x08, + 0x80,0x80,0x80,0xFC,0x04,0x08,0x40,0x40,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xBBB7 [?] [2467]*/ + 0x00,0x00,0xFD,0x10,0x10,0x10,0x10,0x7C,0x10,0x11,0x12,0x10,0x1C,0xE0,0x40,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x68,0xA4,0x22,0x22,0x20,0x20,0x20,0x20,0x20, + /* 0xBBB8 [?] [2468]*/ + 0x10,0x13,0x10,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x13,0x10, + 0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xBBB9 [?] [2469]*/ + 0x00,0x23,0x10,0x10,0x00,0x00,0xF0,0x11,0x12,0x14,0x10,0x10,0x10,0x28,0x47,0x00, + 0x00,0xFC,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x44,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xBBBA [?] [2470]*/ + 0x10,0x17,0x22,0x21,0x48,0xFB,0x10,0x20,0x47,0xF9,0x41,0x02,0x1A,0xE4,0x48,0x03, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xBBBB [?] [2471]*/ + 0x10,0x10,0x10,0x11,0xFA,0x15,0x11,0x19,0x31,0xD1,0x17,0x10,0x10,0x10,0x51,0x26, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0x24,0xFE,0x50,0x50,0x88,0x04,0x02, + /* 0xBBBC [?] [2472]*/ + 0x01,0x1F,0x11,0x11,0x1F,0x01,0x3F,0x21,0x21,0x3F,0x01,0x02,0x51,0x51,0x90,0x0F, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0x04,0x12,0x12,0xF0, + /* 0xBBBD [?] [2473]*/ + 0x01,0x01,0xF1,0x92,0x94,0x9B,0x92,0x92,0x92,0x92,0xF7,0x90,0x00,0x01,0x02,0x0C, + 0x00,0x00,0xF0,0x10,0x20,0xF8,0x48,0x48,0x48,0x48,0xFE,0xA0,0xA0,0x10,0x08,0x06, + /* 0xBBBE [?] [2474]*/ + 0x00,0x00,0x1F,0x11,0x91,0x52,0x54,0x1B,0x32,0x52,0x92,0x1F,0x20,0x21,0x42,0x8C, + 0x80,0x40,0xFE,0x00,0xF0,0x10,0x20,0xF8,0x48,0x48,0x48,0xFE,0xA0,0x10,0x08,0x06, + /* 0xBBBF [?] [2475]*/ + 0x11,0x09,0x7F,0x04,0xFF,0x10,0x2F,0xC6,0x19,0x62,0x0C,0x71,0x06,0x18,0xE2,0x01, + 0x10,0x20,0xFC,0x00,0xFE,0x10,0xC8,0x06,0x10,0xA0,0xC0,0xB0,0x88,0x84,0x80,0x00, + /* 0xBBC0 [?] [2476]*/ + 0x10,0x10,0x10,0x15,0x5A,0x55,0x51,0x91,0x11,0x11,0x13,0x28,0x24,0x44,0x41,0x86, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0x24,0xFE,0x50,0x50,0x88,0x04,0x02, + /* 0xBBC1 [?] [2477]*/ + 0x01,0x21,0x11,0x12,0x84,0x4B,0x42,0x12,0x12,0x22,0xEF,0x20,0x20,0x21,0x22,0x0C, + 0x00,0x00,0xF0,0x10,0x20,0xF8,0x48,0x48,0x48,0x48,0xFE,0xA0,0xA0,0x10,0x08,0x06, + /* 0xBBC2 [?] [2478]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3F,0x21,0x21,0x3F,0x20,0x20,0x20,0x3F,0x21,0x21,0x3F, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xFC, + /* 0xBBC3 [?] [2479]*/ + 0x08,0x08,0x11,0x10,0x22,0x42,0xFC,0x04,0x08,0x10,0x24,0x42,0xFE,0x42,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xBBC4 [?] [2480]*/ + 0x08,0x08,0xFF,0x0A,0x01,0xFF,0x10,0x10,0x1F,0x00,0x11,0x11,0x11,0x21,0x41,0x81, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x00,0x00,0xF8,0x00,0x10,0x10,0x10,0x12,0x12,0x0E, + /* 0xBBC5 [?] [2481]*/ + 0x21,0x21,0x27,0x21,0x30,0xAF,0xA2,0xA2,0xA3,0x20,0x22,0x22,0x22,0x24,0x24,0x28, + 0x08,0x08,0xFE,0x48,0x20,0xFE,0x00,0x00,0xFC,0x00,0x48,0x48,0x48,0x4A,0x4A,0x46, + /* 0xBBC6 [?] [2482]*/ + 0x04,0x3F,0x04,0x04,0xFF,0x01,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x04,0x08,0x10, + 0x40,0xF8,0x40,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x40,0x20,0x10, + /* 0xBBC7 [?] [2483]*/ + 0x00,0x00,0xFD,0x10,0x10,0x23,0x3C,0x65,0x65,0xA5,0x25,0x25,0x3C,0x24,0x21,0x02, + 0x88,0x88,0xFC,0x88,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0x88,0x04,0x02, + /* 0xBBC8 [?] [2484]*/ + 0x20,0x20,0x21,0xF9,0xA9,0xA9,0xA9,0xA8,0xFB,0xA0,0x20,0x29,0x38,0xE8,0x43,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xBBC9 [?] [2485]*/ + 0x20,0x3E,0x48,0x84,0x3F,0x04,0xFF,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x08,0x10,0x20, + 0x40,0x7E,0x90,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x10,0x08, + /* 0xBBCA [?] [2486]*/ + 0x02,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xBBCB [?] [2487]*/ + 0x00,0x3F,0x22,0x27,0x24,0x27,0x24,0x27,0x20,0x2F,0x21,0x27,0x21,0x4F,0x40,0x80, + 0x00,0xF8,0x08,0xC8,0x48,0xC8,0x48,0xC8,0x08,0xE8,0x08,0xCA,0x0A,0xEA,0x06,0x02, + /* 0xBBCC [?] [2488]*/ + 0x10,0x10,0x11,0x11,0x19,0x55,0x51,0x50,0x93,0x10,0x10,0x11,0x10,0x10,0x13,0x10, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xBBCD [?] [2489]*/ + 0x10,0x10,0x11,0x15,0x59,0x51,0x51,0x90,0x13,0x10,0x10,0x29,0x24,0x40,0x43,0x80, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xBBCE [?] [2490]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x11,0x09,0x01,0xFF,0x04,0x04,0x08,0x10,0x60, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x10,0x20,0x00,0xFE,0x40,0x40,0x42,0x42,0x3E, + /* 0xBBCF [?] [2491]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x54,0x55,0x54,0x54,0x57,0x5C,0x10,0x11,0x12,0x14, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x24,0xA8,0x20,0xFE,0x90,0x90,0x12,0x12,0x0E, + /* 0xBBD0 [?] [2492]*/ + 0x10,0x10,0x12,0x19,0x55,0x50,0x57,0x90,0x10,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x40,0x44,0x44,0x48,0x50,0x40,0xFE,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xBBD1 [?] [2493]*/ + 0x01,0x41,0x27,0x21,0x00,0x07,0xE2,0x22,0x23,0x20,0x22,0x22,0x2A,0x34,0x24,0x08, + 0x08,0x08,0xFE,0x48,0x20,0xFE,0x00,0x00,0xFC,0x00,0x48,0x48,0x48,0x4A,0x4A,0x46, + /* 0xBBD2 [?] [2494]*/ + 0x04,0x04,0x04,0xFF,0x08,0x08,0x08,0x12,0x12,0x24,0x29,0x41,0x82,0x04,0x18,0x60, + 0x00,0x00,0x00,0xFE,0x00,0x80,0x84,0x84,0x88,0x90,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xBBD3 [?] [2495]*/ + 0x10,0x13,0x12,0x14,0xFC,0x13,0x10,0x14,0x19,0x31,0xD0,0x10,0x17,0x10,0x50,0x20, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xBBD4 [?] [2496]*/ + 0x10,0x13,0x92,0x54,0x58,0x13,0xFC,0x28,0x29,0x29,0x28,0x28,0x2B,0x4C,0x48,0x80, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xBBD5 [?] [2497]*/ + 0x12,0x1A,0x2A,0x4F,0x80,0x1F,0x24,0x68,0xAF,0x22,0x24,0x3F,0x22,0x2A,0x32,0x26, + 0x10,0x90,0x90,0xA0,0x3E,0xC4,0x24,0xA4,0x24,0x28,0xA8,0xD0,0x28,0xA8,0x44,0x82, + /* 0xBBD6 [?] [2498]*/ + 0x10,0x10,0x10,0x13,0x18,0x54,0x50,0x51,0x91,0x11,0x12,0x12,0x14,0x10,0x10,0x11, + 0x40,0x40,0x40,0xFE,0x80,0x90,0x90,0x12,0x52,0x54,0x90,0x28,0x28,0x44,0x84,0x02, + /* 0xBBD7 [?] [2499]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x00, + 0x00,0x00,0xFE,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x7A,0x02,0x02,0xFE,0x02,0x00, + /* 0xBBD8 [?] [2500]*/ + 0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x27,0x20,0x20,0x3F,0x20,0x00, + 0x00,0xF8,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0x48,0xC8,0x08,0x08,0xF8,0x08,0x00, + /* 0xBBD9 [?] [2501]*/ + 0x20,0xCE,0x82,0x82,0xEE,0x82,0x82,0xFE,0x00,0x00,0xFE,0x10,0x10,0x1E,0xF0,0x41, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xBBDA [?] [2502]*/ + 0x11,0x11,0x11,0x1A,0x55,0x51,0x51,0x91,0x17,0x11,0x12,0x12,0x13,0x10,0x10,0x10, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xBBDB [?] [2503]*/ + 0x10,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x3F,0x00,0x1F,0x00,0x3F,0x01,0x48,0x48,0x87, + 0x10,0xFE,0x10,0x7C,0x10,0xFE,0x10,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x84,0x12,0xF2, + /* 0xBBDC [?] [2504]*/ + 0x01,0x01,0x01,0x7F,0x01,0x01,0x09,0x08,0x08,0xFF,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBBDD [?] [2505]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x01,0xFF,0x01,0x28,0x28,0x48,0x07, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x04,0xFE,0x02,0x88,0xA4,0x24,0xE0, + /* 0xBBDE [?] [2506]*/ + 0x01,0x01,0x79,0x4A,0x4D,0x49,0x49,0x79,0x4F,0x49,0x4A,0x4A,0x7B,0x48,0x00,0x00, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xBBDF [?] [2507]*/ + 0x00,0x7C,0x45,0x54,0x54,0x54,0x54,0x55,0x56,0x54,0x54,0x10,0x28,0x24,0x44,0x80, + 0x20,0x20,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0x94,0x88, + /* 0xBBE0 [?] [2508]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFC,0x10,0x38,0x35,0x52,0x50,0x90,0x10,0x10,0x10,0x13, + 0x20,0x24,0x24,0x24,0xFC,0x40,0x40,0xFC,0x04,0x84,0x48,0x50,0x20,0x40,0x80,0x00, + /* 0xBBE1 [?] [2509]*/ + 0x01,0x01,0x02,0x04,0x08,0x30,0xCF,0x00,0x00,0x7F,0x02,0x04,0x08,0x10,0x3F,0x10, + 0x00,0x00,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xFC,0x00,0x00,0x20,0x10,0xF8,0x08, + /* 0xBBE2 [?] [2510]*/ + 0x10,0x10,0x10,0x14,0x59,0x52,0x50,0x90,0x10,0x13,0x10,0x28,0x24,0x41,0x43,0x81, + 0x20,0x20,0x50,0x88,0x04,0x02,0xF8,0x00,0x00,0xFE,0x20,0x40,0x88,0x04,0xFE,0x02, + /* 0xBBE3 [?] [2511]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x22,0x22,0x23,0x00, + 0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xBBE4 [?] [2512]*/ + 0x00,0x20,0x10,0x17,0x00,0x00,0xF3,0x10,0x10,0x17,0x10,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x40,0x40,0xFE,0x42,0x42,0x4A,0x44,0x40,0x40, + /* 0xBBE5 [?] [2513]*/ + 0x01,0x21,0x11,0x12,0x05,0x01,0xF1,0x11,0x17,0x11,0x12,0x12,0x17,0x18,0x10,0x00, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xBBE6 [?] [2514]*/ + 0x10,0x10,0x20,0x21,0x4A,0xF4,0x11,0x20,0x40,0xFB,0x40,0x00,0x19,0xE2,0x47,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xBBE7 [?] [2515]*/ + 0x08,0xFF,0x08,0x00,0x7F,0x42,0x82,0x3F,0x09,0x11,0x1F,0x01,0x01,0xFF,0x01,0x01, + 0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF8,0x00,0x00,0xF0,0x00,0x00,0xFE,0x00,0x00, + /* 0xBBE8 [?] [2516]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x28,0x30,0x20,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F, + 0x78,0x80,0x80,0x80,0xFC,0x40,0x22,0x1A,0x06,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0, + /* 0xBBE9 [?] [2517]*/ + 0x20,0x23,0x22,0x23,0xFA,0x4A,0x4B,0x4A,0x49,0x91,0x51,0x21,0x31,0x49,0x49,0x81, + 0x1C,0xE0,0x20,0xFE,0x20,0x92,0x0A,0x06,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xBBEA [?] [2518]*/ + 0x00,0x00,0x7D,0x01,0x01,0x01,0xFF,0x21,0x21,0x20,0x48,0x44,0xFC,0x45,0x01,0x02, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x40,0x68,0xB2,0xBE,0x20,0x22,0x1E, + /* 0xBBEB [?] [2519]*/ + 0x00,0x23,0x12,0x14,0x80,0x43,0x48,0x08,0x11,0x11,0xE0,0x20,0x27,0x20,0x20,0x00, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xBBEC [?] [2520]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x17,0x10,0x24,0xE4,0x27,0x24,0x24,0x25,0x06, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x20,0x22,0xAC,0x30,0x22,0xA2,0x1E, + /* 0xBBED [?] [2521]*/ + 0x20,0x10,0xFE,0x82,0x11,0x7C,0x10,0x7C,0x11,0xFE,0x10,0x7C,0x44,0x44,0x7C,0x44, + 0x00,0x50,0x48,0x84,0x24,0x20,0x50,0x88,0x04,0xFA,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xBBEE [?] [2522]*/ + 0x00,0x20,0x13,0x10,0x80,0x47,0x40,0x10,0x10,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x10,0x78,0xC0,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xBBEF [?] [2523]*/ + 0x08,0x08,0x08,0x10,0x12,0x32,0x32,0x54,0x90,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x50,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xBBF0 [?] [2524]*/ + 0x01,0x01,0x01,0x11,0x11,0x11,0x21,0x21,0x42,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0x08,0x08,0x10,0x20,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xBBF1 [?] [2525]*/ + 0x08,0x08,0xFF,0x08,0x44,0x28,0x10,0x28,0x4F,0x98,0x28,0x48,0x89,0x09,0x52,0x24, + 0x20,0x20,0xFE,0x20,0x40,0x50,0x48,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x06, + /* 0xBBF2 [?] [2526]*/ + 0x00,0x00,0x00,0xFF,0x00,0x00,0x3E,0x22,0x22,0x22,0x3E,0x00,0x07,0x78,0x20,0x03, + 0x48,0x44,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xBBF3 [?] [2527]*/ + 0x00,0x00,0xFF,0x00,0x3E,0x22,0x3E,0x00,0x0E,0x70,0x03,0x01,0x28,0x28,0x48,0x07, + 0x50,0x48,0xFE,0x40,0x40,0x24,0x28,0x12,0x2A,0xC6,0x02,0x00,0x88,0xA4,0x24,0xE0, + /* 0xBBF4 [?] [2528]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x10, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00, + /* 0xBBF5 [?] [2529]*/ + 0x08,0x08,0x10,0x30,0x57,0x90,0x10,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x80,0x80,0x98,0xE0,0x84,0x84,0x7C,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xBBF6 [?] [2530]*/ + 0x20,0x11,0x11,0xF9,0x09,0x11,0x18,0x34,0x53,0x92,0x12,0x12,0x13,0x12,0x12,0x12, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xBBF7 [?] [2531]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x21,0x21,0x21,0x21,0x3F,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xBBF8 [?] [2532]*/ + 0x10,0x17,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x12,0x1E,0xE2,0x44,0x04,0x08,0x03, + 0x00,0xF8,0x08,0x10,0x10,0x20,0x3C,0x04,0x04,0x88,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBBF9 [?] [2533]*/ + 0x08,0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x08,0x11,0x21,0xCF,0x01,0x01,0x3F, + 0x20,0x20,0xFC,0x20,0xE0,0x20,0xE0,0x20,0xFE,0x20,0x10,0x08,0xE6,0x00,0x00,0xF8, + /* 0xBBFA [?] [2534]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBBFB [?] [2535]*/ + 0x00,0x00,0x7D,0x54,0x54,0x55,0x57,0x7C,0x55,0x55,0x55,0x55,0x7D,0x44,0x00,0x00, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFE,0x08,0xE8,0x28,0x28,0xE8,0x28,0x08,0x28,0x10, + /* 0xBBFC [?] [2536]*/ + 0x08,0x1C,0xF3,0x10,0x11,0xFE,0x11,0x31,0x39,0x54,0x54,0x91,0x11,0x11,0x11,0x11, + 0x50,0x48,0xFC,0xA0,0x22,0x1E,0x10,0xE0,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC, + /* 0xBBFD [?] [2537]*/ + 0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x09, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84,0x00,0x48,0x44,0x84,0x82,0x02, + /* 0xBBFE [?] [2538]*/ + 0x20,0x3F,0x48,0x85,0x08,0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x08,0x10,0x20, + 0x40,0x7E,0x90,0x08,0x20,0x20,0xFC,0x20,0xE0,0x20,0xE0,0x20,0xFE,0x20,0x10,0x08, + /* 0xBCA1 [?] [2539]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x45,0x55,0x8A, + 0x00,0xF0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xBCA2 [?] [2540]*/ + 0x20,0x21,0x21,0x3D,0x45,0x49,0xA1,0x21,0x21,0x21,0x21,0x21,0x29,0x32,0x22,0x04, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBCA3 [?] [2541]*/ + 0x00,0x20,0x10,0x17,0x00,0x00,0xF2,0x12,0x14,0x11,0x11,0x12,0x14,0x28,0x47,0x00, + 0x40,0x20,0x20,0xFE,0x90,0x90,0x94,0x92,0x92,0x10,0x10,0x50,0x20,0x00,0xFE,0x00, + /* 0xBCA4 [?] [2542]*/ + 0x02,0x44,0x2F,0x28,0x0F,0x88,0x4F,0x54,0x12,0x2F,0xE4,0x27,0x24,0x28,0x2A,0x11, + 0x10,0x10,0x90,0x90,0xBE,0xA4,0xD4,0x14,0x14,0xD4,0x14,0x88,0x88,0x94,0x94,0x22, + /* 0xBCA5 [?] [2543]*/ + 0x00,0x21,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x12,0x02,0x04, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBCA6 [?] [2544]*/ + 0x00,0x00,0x00,0xFC,0x04,0x04,0x48,0x28,0x10,0x10,0x28,0x24,0x45,0x80,0x00,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xBCA7 [?] [2545]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x00, + 0x00,0xFE,0x10,0x10,0x10,0x7C,0x44,0x44,0x44,0x44,0x7C,0x10,0x10,0x10,0xFE,0x00, + /* 0xBCA8 [?] [2546]*/ + 0x10,0x10,0x27,0x20,0x4B,0xF0,0x17,0x20,0x43,0xFA,0x42,0x02,0x1A,0xE0,0x41,0x06, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0x48,0xA0,0x10,0x08, + /* 0xBCA9 [?] [2547]*/ + 0x10,0x11,0x21,0x21,0x49,0xF0,0x17,0x21,0x41,0xF9,0x41,0x01,0x19,0xE7,0x40,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x3E,0xC8,0x08,0x08, + /* 0xBCAA [?] [2548]*/ + 0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x3F,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xBCAB [?] [2549]*/ + 0x10,0x13,0x10,0x10,0xFC,0x10,0x30,0x38,0x55,0x55,0x91,0x11,0x12,0x12,0x14,0x11, + 0x00,0xFC,0x84,0x88,0x88,0x90,0x9C,0x84,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xBCAC [?] [2550]*/ + 0x10,0x10,0xFD,0x10,0x10,0x7C,0x54,0x54,0x54,0x5C,0x10,0x38,0x54,0x95,0x10,0x10, + 0x20,0x20,0xFC,0x20,0x20,0xF8,0xA8,0xA8,0xA8,0xB8,0x20,0x70,0xA8,0x26,0x20,0x20, + /* 0xBCAD [?] [2551]*/ + 0x20,0x21,0x21,0xFD,0x41,0x50,0x97,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x17,0x10,0x10, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x3E,0xC8,0x08,0x08, + /* 0xBCAE [?] [2552]*/ + 0x20,0x3F,0x48,0x85,0x10,0x7C,0x10,0x7C,0x11,0xFE,0x10,0x38,0x54,0x94,0x10,0x10, + 0x40,0x7E,0x90,0x08,0x48,0xFC,0x48,0x48,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xBCAF [?] [2553]*/ + 0x09,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x11,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xBCB0 [?] [2554]*/ + 0x00,0x3F,0x08,0x08,0x08,0x08,0x0C,0x0A,0x0A,0x09,0x11,0x10,0x20,0x20,0x43,0x8C, + 0x00,0xE0,0x20,0x20,0x40,0x40,0xF8,0x08,0x08,0x10,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xBCB1 [?] [2555]*/ + 0x08,0x0F,0x10,0x20,0x5F,0x00,0x00,0x1F,0x00,0x00,0x3F,0x02,0x51,0x51,0x90,0x0F, + 0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x04,0x12,0x12,0xF0, + /* 0xBCB2 [?] [2556]*/ + 0x00,0x00,0x1F,0x12,0x92,0x53,0x52,0x14,0x30,0x5F,0x90,0x10,0x20,0x21,0x42,0x8C, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x06, + /* 0xBCB3 [?] [2557]*/ + 0x00,0x27,0x11,0x11,0x81,0x41,0x49,0x09,0x11,0x12,0xE2,0x22,0x24,0x24,0x28,0x03, + 0x00,0xF8,0x08,0x10,0x10,0x20,0x3C,0x04,0x04,0x88,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBCB4 [?] [2558]*/ + 0x00,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x40,0x48,0x44,0x4A,0x52,0x60,0x00,0x00, + 0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40,0x40, + /* 0xBCB5 [?] [2559]*/ + 0x20,0x20,0x21,0x21,0xF9,0x4D,0x4B,0x49,0x89,0x4B,0x35,0x11,0x29,0x4A,0x82,0x04, + 0x20,0x10,0xFE,0x00,0x20,0x20,0x3C,0x50,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xBCB6 [?] [2560]*/ + 0x10,0x13,0x20,0x20,0x48,0xF8,0x10,0x20,0x41,0xF9,0x41,0x01,0x1A,0xE2,0x44,0x01, + 0x00,0xFC,0x84,0x88,0x88,0x90,0x9C,0x84,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xBCB7 [?] [2561]*/ + 0x10,0x10,0x17,0x12,0xFD,0x10,0x14,0x19,0x36,0xD1,0x11,0x11,0x11,0x12,0x52,0x24, + 0x80,0x40,0xFE,0x08,0x10,0xA0,0x40,0xB0,0x0E,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xBCB8 [?] [2562]*/ + 0x00,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xBCB9 [?] [2563]*/ + 0x21,0x11,0x09,0x12,0x24,0x08,0x3F,0xC8,0x08,0x0F,0x08,0x08,0x0F,0x08,0x08,0x08, + 0x08,0x10,0x20,0x90,0x48,0x20,0xF8,0x26,0x20,0xE0,0x20,0x20,0xE0,0x20,0xA0,0x40, + /* 0xBCBA [?] [2564]*/ + 0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xBCBB [?] [2565]*/ + 0x04,0x04,0xFF,0x04,0x10,0x1F,0x22,0x7F,0xA4,0x3F,0x24,0x3F,0x00,0x07,0x78,0x20, + 0x40,0x40,0xFE,0x40,0x04,0x04,0x24,0xA4,0xA4,0xA4,0xA4,0xA4,0x04,0x84,0x14,0x08, + /* 0xBCBC [?] [2566]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x10,0x15,0x18,0x30,0xD0,0x10,0x10,0x10,0x51,0x26, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xBCBD [?] [2567]*/ + 0x04,0x7C,0x04,0x1C,0xE4,0x3F,0x21,0x3F,0x21,0x3F,0x04,0x3F,0x04,0xFF,0x10,0x20, + 0x44,0x78,0x42,0x3E,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xF8,0x40,0xFE,0x10,0x08, + /* 0xBCBE [?] [2568]*/ + 0x00,0x1F,0x01,0x01,0x7F,0x05,0x09,0x31,0xCF,0x00,0x00,0xFF,0x01,0x01,0x05,0x02, + 0x70,0x80,0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x40,0x80,0xFE,0x00,0x00,0x00,0x00, + /* 0xBCBF [?] [2569]*/ + 0x08,0x08,0x08,0x17,0x10,0x30,0x30,0x57,0x92,0x12,0x11,0x10,0x10,0x10,0x11,0x16, + 0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x08,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xBCC0 [?] [2570]*/ + 0x10,0x10,0x3E,0x62,0x94,0x48,0x30,0x27,0xC0,0x00,0x1F,0x01,0x09,0x11,0x25,0x02, + 0x80,0x80,0xFC,0x44,0x48,0x30,0x10,0xC8,0x06,0x00,0xF0,0x00,0x20,0x10,0x08,0x00, + /* 0xBCC1 [?] [2571]*/ + 0x10,0x08,0xFF,0x02,0x64,0x18,0x26,0xC1,0x22,0x22,0x22,0x22,0x22,0x42,0x42,0x82, + 0x04,0x04,0x84,0x24,0x24,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xBCC2 [?] [2572]*/ + 0x20,0x23,0x20,0x27,0x30,0xA9,0xA2,0xAC,0xA3,0x20,0x20,0x27,0x20,0x20,0x21,0x20, + 0x38,0xC0,0x40,0xFC,0xE0,0x50,0x48,0x46,0xF0,0x20,0x40,0xFC,0x40,0x40,0x40,0x80, + /* 0xBCC3 [?] [2573]*/ + 0x00,0x20,0x17,0x12,0x81,0x40,0x40,0x11,0x16,0x21,0xE1,0x21,0x21,0x22,0x22,0x04, + 0x80,0x40,0xFE,0x08,0x10,0xA0,0x40,0xB0,0x0E,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xBCC4 [?] [2574]*/ + 0x02,0x01,0x7F,0x42,0x82,0x3F,0x04,0x08,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x00,0x00, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x80,0x40,0xFE,0x10,0x90,0x90,0x90,0x90,0x50,0x20, + /* 0xBCC5 [?] [2575]*/ + 0x02,0x01,0x7F,0x40,0x88,0x0F,0x08,0x08,0xFF,0x00,0x08,0x2A,0x49,0x89,0x28,0x10, + 0x00,0x00,0xFE,0x02,0x04,0x7C,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xBCC6 [?] [2576]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF7,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xBCC7 [?] [2577]*/ + 0x00,0x20,0x11,0x10,0x00,0x00,0xF0,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xBCC8 [?] [2578]*/ + 0x00,0x7D,0x44,0x44,0x7D,0x45,0x45,0x7C,0x40,0x48,0x44,0x4A,0x52,0x60,0x41,0x02, + 0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x30,0x50,0x50,0x92,0x92,0x0E,0x00, + /* 0xBCC9 [?] [2579]*/ + 0x00,0x3F,0x00,0x00,0x3F,0x20,0x20,0x20,0x1F,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0x04,0x04,0xFC,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xBCCA [?] [2580]*/ + 0x00,0x79,0x48,0x50,0x50,0x63,0x50,0x48,0x49,0x49,0x6A,0x52,0x44,0x40,0x40,0x40, + 0x00,0xFC,0x00,0x00,0x00,0xFE,0x20,0x20,0x28,0x24,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xBCCB [?] [2581]*/ + 0x10,0x10,0x10,0x13,0xFC,0x24,0x24,0x25,0x24,0x48,0x28,0x10,0x28,0x44,0x81,0x06, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xBCCC [?] [2582]*/ + 0x10,0x12,0x22,0x23,0x4A,0xF2,0x13,0x22,0x42,0xFA,0x43,0x02,0x1A,0xE2,0x43,0x00, + 0x20,0x20,0x20,0x24,0xA8,0x20,0xFC,0x20,0x70,0xA8,0x24,0x20,0x20,0x20,0xFE,0x00, + /* 0xBCCD [?] [2583]*/ + 0x10,0x10,0x23,0x20,0x48,0xF0,0x10,0x23,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x41,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xBCCE [?] [2584]*/ + 0x01,0xFF,0x01,0x3F,0x00,0x1F,0x10,0x1F,0x08,0xFF,0x10,0x7F,0x11,0x21,0x45,0x82, + 0x00,0xFE,0x00,0xF8,0x00,0xF0,0x10,0xF0,0x20,0xFE,0x00,0x7C,0x44,0x44,0x7C,0x44, + /* 0xBCCF [?] [2585]*/ + 0x22,0x22,0x22,0xFA,0x27,0x22,0x72,0x6A,0xAA,0xA2,0x22,0x22,0x24,0x24,0x29,0x30, + 0x00,0x00,0x00,0x1E,0xD2,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x5E,0x52,0x80, + /* 0xBCD0 [?] [2586]*/ + 0x01,0x01,0x01,0x7F,0x01,0x11,0x09,0x01,0xFF,0x01,0x02,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xFC,0x00,0x10,0x20,0x00,0xFE,0x00,0x80,0x80,0x40,0x20,0x18,0x06, + /* 0xBCD1 [?] [2587]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x3F,0x50,0x90,0x10,0x13,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xBCD2 [?] [2588]*/ + 0x02,0x01,0x7F,0x40,0x80,0x7F,0x02,0x0D,0x71,0x02,0x0C,0x71,0x06,0x18,0xE2,0x01, + 0x00,0x00,0xFE,0x02,0x04,0xFC,0x00,0x08,0x90,0xA0,0xC0,0xA0,0x98,0x86,0x80,0x00, + /* 0xBCD3 [?] [2589]*/ + 0x10,0x10,0x10,0x10,0xFE,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x4A,0x84, + 0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00, + /* 0xBCD4 [?] [2590]*/ + 0x08,0x08,0xFF,0x08,0x01,0x01,0x3F,0x01,0x11,0x09,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xF8,0x00,0x10,0x20,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xBCD5 [?] [2591]*/ + 0x08,0x08,0x08,0x7E,0x08,0x4A,0x2A,0x2C,0x08,0xFE,0x08,0x14,0x12,0x22,0x40,0x83, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xBCD6 [?] [2592]*/ + 0x00,0x7F,0x04,0x3F,0x24,0x24,0x3F,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0xFC,0x40,0xF8,0x48,0x48,0xF8,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xBCD7 [?] [2593]*/ + 0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x01,0x01,0x01, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, + /* 0xBCD8 [?] [2594]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x10,0x14,0x18,0x10,0x00, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xBCD9 [?] [2595]*/ + 0x10,0x17,0x14,0x24,0x24,0x67,0x64,0xA4,0x27,0x24,0x24,0x27,0x24,0x24,0x24,0x24, + 0x00,0xBC,0x84,0x84,0x84,0xBC,0x00,0x00,0xBC,0x24,0x24,0xA8,0x10,0x28,0x44,0x82, + /* 0xBCDA [?] [2596]*/ + 0x08,0x1C,0xF3,0x12,0x10,0xFD,0x10,0x30,0x3B,0x54,0x50,0x93,0x10,0x10,0x13,0x10, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x40,0xA2,0x34,0x58,0x94,0x34,0x52,0x90,0x50,0x20, + /* 0xBCDB [?] [2597]*/ + 0x08,0x08,0x08,0x10,0x11,0x32,0x34,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xBCDC [?] [2598]*/ + 0x08,0x08,0x7F,0x09,0x11,0x11,0x25,0x42,0x01,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xBCDD [?] [2599]*/ + 0x08,0x08,0x7F,0x11,0x11,0x25,0x42,0x1F,0x00,0x08,0x08,0x0F,0x00,0x7F,0x00,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x7C,0x00,0xE0,0x20,0x20,0x20,0xFC,0x04,0xC4,0x14,0x08, + /* 0xBCDE [?] [2600]*/ + 0x20,0x20,0x23,0x22,0xF8,0x49,0x48,0x48,0x4B,0x90,0x50,0x23,0x30,0x48,0x4B,0x80, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x40,0xA2,0x34,0x58,0x94,0x34,0x52,0x90,0x50,0x20, + /* 0xBCDF [?] [2601]*/ + 0x00,0x00,0xFD,0x20,0x20,0x3C,0x44,0x47,0x64,0x94,0x08,0x08,0x10,0x20,0x40,0x80, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBCE0 [?] [2602]*/ + 0x04,0x24,0x24,0x24,0x24,0x24,0x25,0x04,0x00,0x3F,0x24,0x24,0x24,0x24,0xFF,0x00, + 0x40,0x40,0x7C,0x40,0x90,0x88,0x08,0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xBCE1 [?] [2603]*/ + 0x04,0x25,0x25,0x24,0x24,0x24,0x24,0x25,0x04,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0xFC,0x04,0x88,0x50,0x20,0x58,0x86,0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xBCE2 [?] [2604]*/ + 0x01,0x01,0x09,0x09,0x11,0x21,0x40,0x01,0x01,0xFF,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x20,0x10,0x08,0x04,0x04,0x00,0x00,0xFE,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xBCE3 [?] [2605]*/ + 0x20,0x3F,0x48,0x85,0x02,0x02,0x03,0x7E,0x02,0x03,0xFE,0x01,0x00,0x07,0x38,0x00, + 0x40,0x7E,0x90,0x08,0x40,0x20,0xF8,0x00,0x00,0xFC,0x10,0x20,0xC0,0x44,0x34,0x0C, + /* 0xBCE4 [?] [2606]*/ + 0x20,0x13,0x10,0x40,0x47,0x44,0x44,0x44,0x47,0x44,0x44,0x44,0x47,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xC4,0x44,0x44,0x44,0xC4,0x44,0x44,0x44,0xC4,0x04,0x14,0x08, + /* 0xBCE5 [?] [2607]*/ + 0x10,0x08,0xFF,0x00,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x2A,0x24,0x00,0x48,0x44,0x84, + 0x10,0x20,0xFE,0x00,0x48,0x48,0x48,0x48,0x08,0x08,0x28,0x10,0x00,0x88,0x44,0x44, + /* 0xBCE6 [?] [2608]*/ + 0x10,0x08,0x7F,0x04,0x04,0x3F,0x04,0xFF,0x04,0x3F,0x0C,0x14,0x24,0xC4,0x04,0x04, + 0x20,0x40,0xFC,0x80,0x80,0xF0,0x90,0xFE,0x90,0xF0,0xC0,0xA0,0x98,0x86,0x80,0x80, + /* 0xBCE7 [?] [2609]*/ + 0x01,0x00,0x1F,0x10,0x10,0x1F,0x10,0x17,0x14,0x17,0x14,0x27,0x24,0x44,0x84,0x04, + 0x00,0x80,0xF8,0x08,0x08,0xF8,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xBCE8 [?] [2610]*/ + 0x00,0x01,0xFD,0x05,0x45,0x45,0x29,0x29,0x11,0x11,0x29,0x29,0x45,0x45,0x81,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xBCE9 [?] [2611]*/ + 0x10,0x11,0x10,0x10,0xFE,0x22,0x22,0x23,0x42,0x24,0x14,0x08,0x14,0x22,0x42,0x80, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBCEA [?] [2612]*/ + 0x20,0x20,0x20,0x47,0x54,0xF4,0x25,0x24,0x44,0xF5,0x45,0x05,0x35,0xC4,0x08,0x10, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD0,0x12,0x12,0xD4,0x54,0x48,0xDA,0x2A,0x46,0x82, + /* 0xBCEB [?] [2613]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x3F,0x21,0x21,0x21,0x3F,0x01,0x01,0x01,0x7F,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x10,0xF8,0x04,0x04, + /* 0xBCEC [?] [2614]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x35,0x38,0x54,0x50,0x92,0x11,0x11,0x10,0x17,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xBCED [?] [2615]*/ + 0x01,0x01,0xFF,0x01,0x01,0x3F,0x21,0x29,0x25,0x3F,0x23,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x28,0x48,0xF8,0x88,0x40,0x20,0x18,0x06,0x00, + /* 0xBCEE [?] [2616]*/ + 0x00,0x00,0xF0,0x27,0x24,0x44,0x75,0xD4,0x54,0x55,0x55,0x55,0x75,0x54,0x08,0x10, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD0,0x12,0x12,0xD4,0x54,0x48,0xDA,0x2A,0x46,0x82, + /* 0xBCEF [?] [2617]*/ + 0x00,0x00,0xF8,0x20,0x21,0x42,0x7D,0x48,0xC8,0x48,0x4A,0x49,0x79,0x48,0x07,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xBCF0 [?] [2618]*/ + 0x10,0x10,0x17,0x10,0xFC,0x13,0x11,0x12,0x1B,0x30,0xD1,0x11,0x12,0x14,0x50,0x20, + 0x40,0x40,0xFC,0x80,0x80,0xE0,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xBCF1 [?] [2619]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x15,0x10,0x18,0x30,0xD2,0x11,0x11,0x10,0x57,0x20, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xBCF2 [?] [2620]*/ + 0x20,0x3F,0x48,0x85,0x10,0x0B,0x20,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x20,0x20, + 0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0xC8,0x48,0x48,0xC8,0x48,0x48,0xC8,0x08,0x18, + /* 0xBCF3 [?] [2621]*/ + 0x08,0x08,0x08,0x10,0x11,0x32,0x35,0x50,0x90,0x10,0x12,0x11,0x11,0x10,0x17,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xBCF4 [?] [2622]*/ + 0x08,0xFF,0x00,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x26,0x00,0x7F,0x04,0x08,0x10,0x60, + 0x20,0xFE,0x00,0x08,0x48,0x48,0x48,0x48,0x08,0x18,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xBCF5 [?] [2623]*/ + 0x00,0x40,0x20,0x27,0x04,0x04,0x15,0x14,0x24,0xE5,0x25,0x25,0x25,0x24,0x28,0x10, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD0,0x12,0x12,0xD4,0x54,0x48,0xDA,0x2A,0x46,0x82, + /* 0xBCF6 [?] [2624]*/ + 0x08,0x08,0xFF,0x0A,0x02,0x7F,0x04,0x09,0x08,0x18,0x2B,0x48,0x88,0x08,0x08,0x08, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xBCF7 [?] [2625]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x38,0x54,0x55,0x91,0x11,0x11,0x11,0x17,0x10, + 0x48,0x48,0x4E,0x50,0x68,0x44,0x44,0x40,0x00,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xBCF8 [?] [2626]*/ + 0x04,0x24,0x24,0x24,0x24,0x25,0x02,0x0C,0x30,0xCF,0x01,0x3F,0x09,0x05,0x7F,0x00, + 0x40,0x40,0x7C,0x90,0x88,0x08,0x80,0x60,0x18,0xE6,0x00,0xF8,0x20,0x40,0xFC,0x00, + /* 0xBCF9 [?] [2627]*/ + 0x00,0x7C,0x44,0x44,0x45,0x7C,0x10,0x11,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x03,0x00, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xBCFA [?] [2628]*/ + 0x00,0x7C,0x44,0x44,0x55,0x54,0x54,0x57,0x54,0x54,0x54,0x10,0x28,0x24,0x43,0x80, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xBCFB [?] [2629]*/ + 0x00,0x1F,0x10,0x10,0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x04,0x04,0x08,0x30,0xC0, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x90,0x80,0x80,0x82,0x82,0x7E, + /* 0xBCFC [?] [2630]*/ + 0x20,0x20,0x3B,0x21,0x41,0x7A,0xA2,0x27,0xF9,0x25,0x25,0x22,0x2A,0x35,0x28,0x00, + 0x10,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x10,0x00,0xFE,0x00, + /* 0xBCFD [?] [2631]*/ + 0x20,0x3F,0x48,0x85,0x10,0x08,0xFF,0x00,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x2A,0x24, + 0x40,0x7E,0x90,0x08,0x10,0x20,0xFE,0x00,0x48,0x48,0x48,0x48,0x08,0x08,0x28,0x10, + /* 0xBCFE [?] [2632]*/ + 0x08,0x08,0x09,0x11,0x11,0x32,0x32,0x54,0x90,0x17,0x10,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBDA1 [?] [2633]*/ + 0x10,0x10,0x10,0x2E,0x23,0x62,0x64,0xA4,0x2E,0x22,0x22,0x2B,0x24,0x26,0x29,0x30, + 0x20,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFE,0x00, + /* 0xBDA2 [?] [2634]*/ + 0x10,0x21,0x7D,0x45,0x65,0x55,0x55,0xFD,0x45,0x65,0x54,0x54,0x44,0x44,0x55,0x8A, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x50,0x90,0x92,0x12,0x0E, + /* 0xBDA3 [?] [2635]*/ + 0x08,0x08,0x14,0x12,0x21,0x40,0xBE,0x00,0x11,0x09,0x49,0x22,0x22,0x07,0x78,0x20, + 0x04,0x04,0x04,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x84,0x14,0x08, + /* 0xBDA4 [?] [2636]*/ + 0x20,0x20,0x20,0x3C,0x45,0x48,0xA0,0x23,0x20,0x20,0x20,0x20,0x28,0x30,0x23,0x00, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xBDA5 [?] [2637]*/ + 0x01,0x41,0x21,0x2F,0x02,0x82,0x45,0x57,0x11,0x21,0xE1,0x2F,0x25,0x21,0x21,0x01, + 0x00,0x02,0x1C,0xD0,0x10,0x10,0x1E,0xD4,0x14,0x14,0xD4,0x14,0x14,0x24,0x24,0x44, + /* 0xBDA6 [?] [2638]*/ + 0x00,0x4F,0x28,0x28,0x0A,0x8A,0x4A,0x5A,0x1A,0x2A,0xEA,0x22,0x25,0x24,0x28,0x10, + 0x10,0x94,0x92,0x90,0x9E,0xF0,0x90,0x9E,0xF0,0x94,0x94,0x08,0x0A,0x9A,0x26,0x42, + /* 0xBDA7 [?] [2639]*/ + 0x02,0x21,0x15,0x14,0x84,0x45,0x45,0x15,0x15,0x25,0xE5,0x25,0x24,0x24,0x24,0x04, + 0x00,0x7C,0x04,0x04,0x04,0xF4,0x14,0x14,0xF4,0x14,0x14,0xF4,0x04,0x04,0x14,0x08, + /* 0xBDA8 [?] [2640]*/ + 0x00,0x00,0xFB,0x08,0x17,0x10,0x23,0x78,0x0B,0x08,0x48,0x37,0x10,0x2C,0x43,0x80, + 0x40,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0xFE,0x00, + /* 0xBDA9 [?] [2641]*/ + 0x10,0x1F,0x10,0x27,0x24,0x67,0x64,0xAF,0x20,0x27,0x24,0x27,0x24,0x27,0x20,0x2F, + 0x00,0xFE,0x00,0xFC,0x44,0xFC,0x44,0xFE,0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE, + /* 0xBDAA [?] [2642]*/ + 0x08,0x04,0x7F,0x01,0x3F,0x01,0xFF,0x02,0x04,0xFF,0x08,0x10,0x1C,0x03,0x0C,0x70, + 0x20,0x40,0xFC,0x00,0xF8,0x00,0xFE,0x00,0x00,0xFE,0x20,0x20,0x40,0x80,0x70,0x08, + /* 0xBDAB [?] [2643]*/ + 0x08,0x08,0x09,0x4A,0x28,0x28,0x08,0x0B,0x18,0x2B,0xC8,0x09,0x08,0x08,0x08,0x08, + 0x80,0xF8,0x08,0x10,0xA0,0x40,0x90,0x10,0x10,0xFE,0x10,0x10,0x90,0x10,0x50,0x20, + /* 0xBDAC [?] [2644]*/ + 0x08,0x48,0x28,0x09,0x1A,0x28,0x48,0x89,0x01,0x7D,0x05,0x09,0x11,0x21,0xC5,0x02, + 0x40,0x40,0xFC,0x04,0x88,0x50,0x60,0x80,0x04,0x88,0x50,0x20,0x10,0x08,0x06,0x00, + /* 0xBDAD [?] [2645]*/ + 0x00,0x20,0x17,0x10,0x80,0x40,0x48,0x08,0x10,0x10,0xE0,0x20,0x20,0x2F,0x20,0x00, + 0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00,0x00, + /* 0xBDAE [?] [2646]*/ + 0x00,0xFB,0x08,0x09,0xF9,0x81,0x81,0xFB,0x48,0x49,0xE9,0x49,0x69,0x89,0x50,0x23, + 0x00,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE, + /* 0xBDAF [?] [2647]*/ + 0x08,0x08,0xFF,0x08,0x00,0x08,0x49,0x2A,0x28,0x08,0x1B,0x29,0x48,0x88,0x08,0x08, + 0x20,0x20,0xFE,0x20,0x80,0xF8,0x10,0xA0,0x50,0x90,0xFE,0x10,0x90,0x90,0x10,0x30, + /* 0xBDB0 [?] [2648]*/ + 0x08,0x48,0x28,0x09,0x1A,0x28,0x48,0x89,0x01,0xFF,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x40,0x40,0xFC,0x04,0x88,0x50,0x60,0x80,0x00,0xFE,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xBDB1 [?] [2649]*/ + 0x08,0x48,0x28,0x09,0x1A,0x28,0x48,0x88,0x09,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x40,0x40,0xFC,0x04,0x88,0x50,0x20,0x40,0x80,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xBDB2 [?] [2650]*/ + 0x01,0x21,0x11,0x11,0x07,0x01,0xF1,0x11,0x1F,0x11,0x11,0x15,0x19,0x12,0x02,0x04, + 0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xBDB3 [?] [2651]*/ + 0x00,0x7F,0x40,0x40,0x47,0x44,0x44,0x47,0x44,0x44,0x44,0x48,0x48,0x50,0x7F,0x00, + 0x00,0xFC,0x00,0x38,0xC0,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBDB4 [?] [2652]*/ + 0x08,0x48,0x29,0x1A,0x28,0xC9,0x08,0xFF,0x04,0x3F,0x24,0x28,0x30,0x3F,0x20,0x3F, + 0x40,0x80,0xFC,0x48,0x30,0xC0,0x00,0xFE,0x80,0xF8,0x88,0x78,0x08,0xF8,0x08,0xF8, + /* 0xBDB5 [?] [2653]*/ + 0x00,0x7C,0x44,0x49,0x4A,0x50,0x49,0x4E,0x44,0x45,0x44,0x6A,0x53,0x40,0x40,0x40, + 0x80,0x80,0xFC,0x08,0x90,0x60,0x98,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xBDB6 [?] [2654]*/ + 0x08,0x08,0xFF,0x09,0x08,0x1F,0x30,0x5F,0x10,0x1F,0x10,0x1F,0x10,0x24,0x22,0x42, + 0x20,0x20,0xFE,0x20,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00,0x88,0x44,0x44, + /* 0xBDB7 [?] [2655]*/ + 0x21,0x21,0x21,0x21,0xF9,0x21,0x27,0x70,0x69,0xA1,0xA5,0x25,0x29,0x21,0x25,0x22, + 0x00,0x00,0xDC,0x14,0x14,0x14,0xD4,0x14,0x14,0x14,0x88,0x48,0x48,0x14,0x14,0x22, + /* 0xBDB8 [?] [2656]*/ + 0x00,0x00,0xF9,0x21,0x23,0x45,0x79,0x49,0xC9,0x49,0x49,0x49,0x79,0x4A,0x02,0x04, + 0xA0,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0xA4,0x52,0x52, + /* 0xBDB9 [?] [2657]*/ + 0x09,0x08,0x1F,0x10,0x30,0x5F,0x90,0x10,0x1F,0x10,0x10,0x1F,0x10,0x48,0x44,0x84, + 0x00,0x80,0xFC,0x80,0x80,0xF8,0x80,0x80,0xF8,0x80,0x80,0xFC,0x00,0x88,0x44,0x44, + /* 0xBDBA [?] [2658]*/ + 0x00,0x78,0x48,0x4B,0x48,0x78,0x49,0x4A,0x48,0x78,0x48,0x48,0x48,0x48,0x48,0x9B, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDBB [?] [2659]*/ + 0x02,0x01,0x01,0xFF,0x00,0x10,0x10,0x20,0x48,0x04,0x02,0x01,0x02,0x0C,0x30,0xC0, + 0x00,0x00,0x00,0xFE,0x00,0x10,0x08,0x24,0x24,0x40,0x80,0x00,0x80,0x40,0x30,0x0E, + /* 0xBDBC [?] [2660]*/ + 0x10,0x08,0x00,0xFF,0x00,0x24,0x42,0x81,0x24,0x14,0x08,0x14,0x22,0x42,0x80,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xBDBD [?] [2661]*/ + 0x00,0x20,0x10,0x13,0x80,0x40,0x48,0x0B,0x10,0x17,0xE0,0x20,0x21,0x21,0x22,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xBDBE [?] [2662]*/ + 0x00,0xF8,0x09,0x48,0x48,0x4B,0x48,0x7C,0x05,0x06,0x1C,0xE4,0x44,0x05,0x29,0x12, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xBDBF [?] [2663]*/ + 0x10,0x10,0x10,0x10,0xFC,0x25,0x24,0x24,0x25,0x4A,0x28,0x10,0x28,0x44,0x84,0x01, + 0x08,0x1C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x88,0x88,0x08, + /* 0xBDC0 [?] [2664]*/ + 0x00,0x07,0x72,0x51,0x57,0x54,0x57,0x50,0x57,0x54,0x77,0x54,0x07,0x05,0x05,0x06, + 0x3C,0xC0,0x44,0x28,0xFC,0xA4,0xFC,0x08,0x88,0xFE,0x88,0xA8,0x98,0x08,0xA8,0x90, + /* 0xBDC1 [?] [2665]*/ + 0x24,0x22,0x22,0x27,0xFC,0x28,0x23,0x2A,0x32,0xE2,0x22,0x22,0x20,0x21,0xA2,0x4C, + 0x84,0x44,0x48,0xFE,0x02,0x04,0xF8,0x08,0x48,0x48,0x48,0xA8,0xA0,0x22,0x22,0x1E, + /* 0xBDC2 [?] [2666]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBC,0x11,0x12,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDC3 [?] [2667]*/ + 0x20,0x20,0x21,0x7C,0x50,0x93,0x10,0xFC,0x11,0x12,0x10,0x28,0x24,0x45,0x41,0x82, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xBDC4 [?] [2668]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x30,0x53,0x90,0x17,0x10,0x10,0x11,0x11,0x12,0x14, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xBDC5 [?] [2669]*/ + 0x01,0x79,0x49,0x4B,0x49,0x79,0x49,0x4F,0x49,0x79,0x4A,0x4A,0x4F,0x4A,0x48,0x98, + 0x00,0x00,0x1E,0x92,0x12,0x12,0x12,0xD2,0x12,0x12,0x1A,0x94,0xD0,0x50,0x10,0x10, + /* 0xBDC6 [?] [2670]*/ + 0x00,0x44,0x28,0x13,0x28,0x48,0x89,0x0A,0x18,0x28,0x48,0x88,0x08,0x08,0x50,0x23, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDC7 [?] [2671]*/ + 0x08,0x08,0x1F,0x20,0x40,0xBF,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21,0x41,0x41,0x80, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xBDC8 [?] [2672]*/ + 0x20,0x20,0x20,0x3D,0x44,0x48,0xA1,0x22,0x20,0x20,0x20,0x20,0x28,0x30,0x20,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDC9 [?] [2673]*/ + 0x21,0x22,0x27,0x44,0x57,0xF4,0x27,0x22,0x41,0xF7,0x42,0x03,0x32,0xC4,0x05,0x08, + 0x08,0x08,0xC8,0x50,0xDE,0x64,0xD4,0x14,0x14,0xD4,0x14,0xC8,0x48,0x54,0x54,0xA2, + /* 0xBDCA [?] [2674]*/ + 0x10,0x10,0x20,0x25,0x44,0xF8,0x11,0x22,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDCB [?] [2675]*/ + 0x49,0x92,0x49,0x00,0x7F,0x49,0x7F,0x49,0x7F,0x08,0xFF,0x1C,0x2A,0x49,0x88,0x08, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xA4,0x24,0x04,0x04,0x14,0x08, + /* 0xBDCC [?] [2676]*/ + 0x08,0x08,0x7E,0x09,0x0A,0xFF,0x08,0x7E,0x24,0x48,0x8F,0x78,0x08,0x08,0x28,0x11, + 0x20,0x20,0xA0,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xBDCD [?] [2677]*/ + 0x00,0xFE,0x29,0x28,0xFE,0xAB,0xAA,0xAA,0xAF,0xC2,0x83,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x22,0xFA,0x24,0x24,0xFE,0x10,0x20,0xFC,0x88,0x10,0xFE,0x10,0x10,0x50,0x20, + /* 0xBDCE [?] [2678]*/ + 0x20,0x20,0x21,0xFC,0x40,0x53,0x90,0xFC,0x11,0x12,0x1C,0xF0,0x50,0x11,0x11,0x12, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xBDCF [?] [2679]*/ + 0x20,0x20,0x20,0xFD,0x40,0x50,0x91,0xFE,0x10,0x10,0x1C,0xF0,0x50,0x10,0x10,0x13, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xBDD0 [?] [2680]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,0x00,0x00, + 0x04,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x8C,0xB4,0xC4,0x84,0x04,0x04,0x04,0x04, + /* 0xBDD1 [?] [2681]*/ + 0x02,0x01,0x7F,0x48,0x91,0x09,0x0F,0x11,0x01,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xF0,0x00,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xBDD2 [?] [2682]*/ + 0x10,0x13,0x12,0x13,0xFE,0x13,0x11,0x13,0x1C,0x32,0xD2,0x12,0x13,0x10,0x50,0x20, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xBDD3 [?] [2683]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x17,0x10,0x18,0x37,0xD0,0x11,0x10,0x10,0x51,0x26, + 0x80,0x40,0xFC,0x00,0x08,0x90,0xFE,0x40,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xBDD4 [?] [2684]*/ + 0x20,0x20,0x3C,0x20,0x20,0x2C,0x31,0x02,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x80,0x88,0xB0,0xC0,0x84,0x84,0x7C,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xBDD5 [?] [2685]*/ + 0x08,0x1C,0xF0,0x13,0x10,0xFC,0x11,0x30,0x38,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xBDD6 [?] [2686]*/ + 0x11,0x11,0x27,0x41,0x81,0x17,0x20,0x61,0xA1,0x27,0x21,0x21,0x21,0x2E,0x24,0x20, + 0x00,0x00,0xDC,0x00,0x00,0xC0,0x3E,0x08,0x08,0xC8,0x08,0x08,0xC8,0x08,0x28,0x10, + /* 0xBDD7 [?] [2687]*/ + 0x00,0x7C,0x44,0x48,0x48,0x51,0x4A,0x48,0x44,0x44,0x44,0x68,0x50,0x41,0x41,0x42, + 0x20,0x20,0x50,0x50,0x88,0x04,0x02,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xBDD8 [?] [2688]*/ + 0x08,0x08,0x7F,0x08,0xFF,0x14,0x22,0x7F,0xA4,0x3F,0x24,0x3F,0x24,0x3F,0x20,0x20, + 0x20,0x28,0x24,0x20,0xFE,0x20,0x24,0xA4,0x24,0x28,0x28,0x10,0x12,0xAA,0x46,0x82, + /* 0xBDD9 [?] [2689]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0x08,0xFF,0x10,0x10,0x20,0x44,0xFE,0x42,0x01,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xBDDA [?] [2690]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20,0x00,0x00,0x00, + /* 0xBDDB [?] [2691]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x31,0x38,0x54,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xBDDC [?] [2692]*/ + 0x01,0x01,0x01,0x7F,0x03,0x05,0x09,0x11,0x21,0xC1,0x01,0x00,0x24,0x22,0x42,0x80, + 0x00,0x00,0x00,0xFC,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00,0x88,0x44,0x44,0x04, + /* 0xBDDD [?] [2693]*/ + 0x20,0x20,0x27,0x20,0xFB,0x20,0x27,0x28,0x33,0xE0,0x22,0x22,0x22,0x25,0xA4,0x48, + 0x40,0x40,0xFE,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x40,0x40,0x7C,0x40,0x40,0xFE,0x00, + /* 0xBDDE [?] [2694]*/ + 0x00,0x00,0x7B,0x48,0x49,0x78,0x4B,0x48,0x79,0x48,0x49,0x49,0x79,0x4A,0x02,0x04, + 0x20,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0x20,0x3E,0x20,0xA0,0x7E,0x00, + /* 0xBDDF [?] [2695]*/ + 0x20,0x11,0x11,0xFD,0x01,0x09,0x88,0x89,0x4A,0x49,0x51,0x51,0x1D,0xE0,0x40,0x00, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFE,0x22,0x22,0x52,0x02,0xFA,0x02,0x14,0x08, + /* 0xBDE0 [?] [2696]*/ + 0x00,0x40,0x20,0x2F,0x00,0x80,0x47,0x50,0x10,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xBDE1 [?] [2697]*/ + 0x10,0x10,0x20,0x27,0x44,0xF8,0x11,0x20,0x40,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xBDE2 [?] [2698]*/ + 0x10,0x10,0x3C,0x24,0x48,0xBE,0x2A,0x2A,0x3E,0x2A,0x2A,0x3E,0x2A,0x4A,0x42,0x86, + 0x00,0xFC,0x24,0x24,0x54,0x88,0x10,0x50,0x7C,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xBDE3 [?] [2699]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x87,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xBDE4 [?] [2700]*/ + 0x00,0x00,0x00,0xFF,0x00,0x12,0x12,0x12,0x7F,0x12,0x12,0x12,0x22,0x22,0x40,0x03, + 0x48,0x44,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xBDE5 [?] [2701]*/ + 0x08,0x08,0xFF,0x08,0x10,0x7C,0x10,0x7C,0x11,0xFE,0x10,0x38,0x54,0x94,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x48,0xFC,0x48,0x48,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xBDE6 [?] [2702]*/ + 0x08,0x08,0xFF,0x08,0x09,0x02,0x04,0x08,0x34,0xC4,0x04,0x04,0x08,0x08,0x10,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x40,0x20,0x58,0x46,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xBDE7 [?] [2703]*/ + 0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x02,0x0C,0x34,0xC4,0x04,0x08,0x08,0x10, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x80,0x60,0x58,0x46,0x40,0x40,0x40,0x40, + /* 0xBDE8 [?] [2704]*/ + 0x09,0x09,0x09,0x17,0x11,0x31,0x3F,0x50,0x93,0x12,0x12,0x13,0x12,0x12,0x13,0x12, + 0x10,0x10,0x10,0xFC,0x10,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xBDE9 [?] [2705]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x20,0xC8,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x26,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBDEA [?] [2706]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x51,0x12,0x3D,0x51,0x91,0x11,0x21,0x22,0x42,0x84, + 0x80,0x40,0xFE,0x40,0x40,0xA0,0x10,0x08,0x16,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xBDEB [?] [2707]*/ + 0x00,0x40,0x20,0x2F,0x00,0x02,0xE2,0x22,0x2F,0x22,0x22,0x2A,0x32,0x24,0x04,0x08, + 0x14,0x12,0x10,0xFE,0x10,0x90,0x92,0x92,0xD2,0x94,0x94,0x88,0x8A,0x9A,0x26,0x42, + /* 0xBDEC [?] [2708]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x2F,0x28,0x28,0x2F,0x48,0x48,0x8F,0x08, + 0x00,0xF8,0x08,0x08,0xF8,0x80,0x80,0x80,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0x08, + /* 0xBDED [?] [2709]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x01,0x01,0x01, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00,0x00, + /* 0xBDEE [?] [2710]*/ + 0x10,0x10,0x3F,0x48,0x85,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x42,0x4A,0x85, + 0x40,0x40,0x7E,0x90,0x08,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x08, + /* 0xBDEF [?] [2711]*/ + 0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x10,0xF8,0x00,0x00,0x00,0x00,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xBDF0 [?] [2712]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x2F,0xC1,0x01,0x3F,0x01,0x11,0x09,0x09,0xFF,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0xE8,0x06,0x00,0xF8,0x00,0x10,0x10,0x20,0xFE,0x00, + /* 0xBDF1 [?] [2713]*/ + 0x01,0x01,0x02,0x04,0x08,0x12,0x21,0xC1,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x01, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0xF0,0x10,0x20,0x20,0x40,0x80,0x00, + /* 0xBDF2 [?] [2714]*/ + 0x00,0x20,0x13,0x10,0x87,0x40,0x4B,0x08,0x10,0x13,0xE0,0x20,0x27,0x20,0x20,0x00, + 0x40,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x40,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40, + /* 0xBDF3 [?] [2715]*/ + 0x21,0x11,0x07,0xF1,0x13,0x25,0x29,0x68,0xB3,0x28,0x27,0x20,0x22,0x24,0x29,0x20, + 0x10,0x10,0xBC,0x10,0xB8,0x54,0x12,0x00,0xF8,0x00,0xFC,0x40,0x48,0x44,0x42,0x80, + /* 0xBDF4 [?] [2716]*/ + 0x04,0x25,0x24,0x24,0x24,0x24,0x02,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0xFC,0x88,0x50,0x20,0x50,0x8C,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xBDF5 [?] [2717]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x11,0x10,0xFC,0x13,0x12,0x12,0x16,0x1A,0x10,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xBDF6 [?] [2718]*/ + 0x08,0x0B,0x09,0x11,0x11,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x11,0x16, + 0x00,0xFC,0x04,0x04,0x04,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xBDF7 [?] [2719]*/ + 0x01,0x41,0x2F,0x21,0x01,0x00,0xE7,0x24,0x27,0x20,0x2F,0x20,0x2F,0x30,0x2F,0x00, + 0x10,0x10,0xFE,0x10,0xF0,0x40,0xFC,0x44,0xFC,0x40,0xFE,0x40,0xFC,0x40,0xFE,0x00, + /* 0xBDF8 [?] [2720]*/ + 0x00,0x20,0x10,0x13,0x00,0x00,0xF0,0x17,0x10,0x10,0x11,0x11,0x12,0x28,0x47,0x00, + 0x90,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x90,0x90,0x10,0x10,0x10,0x00,0xFE,0x00, + /* 0xBDF9 [?] [2721]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x08,0x7F,0x49,0x49,0x7F,0x08,0xFF,0x08,0x08,0x08,0x09, + 0x04,0x0E,0x70,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0xC8,0x48,0x88,0x88,0x08, + /* 0xBDFA [?] [2722]*/ + 0x00,0x7F,0x04,0x24,0x14,0x04,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0xFC,0x40,0x48,0x50,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xBDFB [?] [2723]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC8,0x00,0x3F,0x00,0x00,0xFF,0x01,0x11,0x25,0x42, + 0x20,0x20,0xFC,0x20,0x70,0xA8,0x26,0x00,0xF8,0x00,0x00,0xFE,0x00,0x10,0x08,0x04, + /* 0xBDFC [?] [2724]*/ + 0x00,0x20,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x12,0x12,0x14,0x28,0x47,0x00, + 0x08,0x1C,0xE0,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0xFE,0x00, + /* 0xBDFD [?] [2725]*/ + 0x10,0x11,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x12,0x14,0x28,0x24,0x44,0x40,0x80, + 0x00,0xFC,0x04,0x04,0xFC,0x10,0x10,0x08,0x04,0x62,0x10,0x00,0xE0,0x18,0x04,0x00, + /* 0xBDFE [?] [2726]*/ + 0x00,0x23,0x10,0x11,0x80,0x43,0x40,0x17,0x14,0x23,0xE1,0x21,0x20,0x20,0x21,0x06, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x04,0xF0,0x10,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xBEA1 [?] [2727]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x23,0x20,0x40,0x8C,0x03,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x48,0x40,0x20,0x10,0x88,0x06,0x00,0x00,0x80,0x40, + /* 0xBEA2 [?] [2728]*/ + 0x00,0x7E,0x04,0x08,0x18,0x24,0x42,0x81,0x00,0x7E,0x08,0x08,0x08,0x0E,0xF1,0x42, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xBEA3 [?] [2729]*/ + 0x12,0x12,0xFF,0x12,0x00,0x7F,0x12,0x12,0x12,0xFF,0x12,0x12,0x22,0x22,0x42,0x82, + 0x04,0x04,0xC4,0x24,0x24,0xA4,0x24,0x24,0x24,0xE4,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xBEA4 [?] [2730]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0x7E,0x42,0x42,0x7E,0x14,0x14,0x25,0x26,0x44,0x81, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0xFC,0x50,0x50,0x50,0x92,0x92,0x0E, + /* 0xBEA5 [?] [2731]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x00,0x01,0x0E,0x70,0x1F,0x01,0x01,0x01,0xFF,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF0,0x60,0x80,0x70,0x0C,0xF0,0x00,0x00,0x00,0xFE,0x00, + /* 0xBEA6 [?] [2732]*/ + 0x00,0x00,0x7B,0x48,0x49,0x78,0x4B,0x48,0x79,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xBEA7 [?] [2733]*/ + 0x0F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x00,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x42, + 0xE0,0x20,0x20,0xE0,0x20,0x20,0xE0,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xBEA8 [?] [2734]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x54,0x54,0x7C,0x54,0x54,0x7C,0x01,0x1E,0xE0,0x40, + 0x40,0x20,0xFE,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xBEA9 [?] [2735]*/ + 0x02,0x01,0xFF,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xBEAA [?] [2736]*/ + 0x10,0x10,0x13,0x10,0x18,0x55,0x51,0x51,0x91,0x10,0x11,0x11,0x12,0x14,0x10,0x10, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xBEAB [?] [2737]*/ + 0x10,0x10,0x95,0x54,0x58,0x10,0xFD,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x94,0x88, + /* 0xBEAC [?] [2738]*/ + 0x10,0x11,0x94,0x54,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x10,0x10,0x10,0x13, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xBEAD [?] [2739]*/ + 0x10,0x11,0x20,0x24,0x44,0xF8,0x10,0x23,0x40,0xFD,0x40,0x00,0x1C,0xE0,0x43,0x00, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBEAE [?] [2740]*/ + 0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x10,0x10,0x20,0x40, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBEAF [?] [2741]*/ + 0x24,0xFF,0x24,0x7E,0x82,0x7A,0x4A,0x7A,0x05,0xFF,0x00,0x3F,0x00,0x3F,0x20,0x3F, + 0x20,0x20,0x7E,0xC4,0x28,0x10,0x28,0xC6,0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8, + /* 0xBEB0 [?] [2742]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x01,0x21,0x45,0x02, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x00,0x08,0x04,0x00, + /* 0xBEB1 [?] [2743]*/ + 0x00,0x7E,0x04,0x08,0x18,0x24,0x42,0x81,0x00,0x7E,0x08,0x08,0x08,0x0E,0xF0,0x40, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xBEB2 [?] [2744]*/ + 0x10,0x10,0xFE,0x10,0x7C,0x11,0xFE,0x00,0x7D,0x44,0x7C,0x45,0x7C,0x44,0x54,0x48, + 0x40,0x40,0x78,0x88,0x10,0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x24,0x20,0xA0,0x40, + /* 0xBEB3 [?] [2745]*/ + 0x20,0x20,0x23,0x21,0xF8,0x27,0x20,0x23,0x22,0x23,0x22,0x3B,0xE1,0x41,0x02,0x0C, + 0x80,0x40,0xF8,0x10,0xA0,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x22,0x22,0x1E, + /* 0xBEB4 [?] [2746]*/ + 0x22,0x22,0xFF,0x22,0x40,0x7F,0x41,0x81,0x7D,0x45,0x45,0x7D,0x45,0x01,0x0A,0x04, + 0x20,0x20,0xA0,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xBEB5 [?] [2747]*/ + 0x20,0x20,0x3B,0x21,0x40,0x77,0xA0,0x23,0xFA,0x23,0x22,0x23,0x29,0x31,0x22,0x0C, + 0x80,0x40,0xF8,0x10,0xA0,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x22,0x22,0x1E, + /* 0xBEB6 [?] [2748]*/ + 0x08,0x0B,0x10,0x20,0x48,0x08,0x11,0x36,0x50,0x93,0x10,0x10,0x10,0x10,0x17,0x10, + 0x00,0xF8,0x10,0x20,0x60,0x98,0x04,0x02,0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xBEB7 [?] [2749]*/ + 0x00,0x00,0x1F,0x10,0x97,0x50,0x50,0x10,0x33,0x5C,0x93,0x10,0x20,0x20,0x4F,0x80, + 0x80,0x40,0xFE,0x00,0xF8,0x10,0x20,0xD8,0x04,0x02,0xF8,0x40,0x40,0x40,0xFE,0x00, + /* 0xBEB8 [?] [2750]*/ + 0x20,0x10,0x13,0xFC,0x01,0x08,0x8B,0x88,0x49,0x49,0x51,0x51,0x1D,0xE1,0x41,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xBEB9 [?] [2751]*/ + 0x02,0x01,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x04,0x08,0x10,0x60, + 0x00,0x00,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x40,0x42,0x42,0x3E, + /* 0xBEBA [?] [2752]*/ + 0x02,0x01,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x04,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x40,0x40,0x42,0x42,0x3E, + /* 0xBEBB [?] [2753]*/ + 0x01,0x41,0x23,0x24,0x00,0x17,0x10,0x10,0x2F,0x20,0xE0,0x27,0x20,0x20,0x21,0x00, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x44,0x40,0x40,0x80, + /* 0xBEBC [?] [2754]*/ + 0x10,0x11,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x81, + 0x00,0xFE,0x02,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x0A,0x04, + /* 0xBEBD [?] [2755]*/ + 0x02,0x01,0x7F,0x48,0x90,0x3F,0x04,0xFF,0x04,0x3F,0x08,0x1F,0x28,0x48,0x8F,0x08, + 0x00,0x00,0xFE,0x22,0x14,0xF8,0x08,0xFE,0x08,0xF8,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xBEBE [?] [2756]*/ + 0x20,0x21,0x27,0x21,0xF9,0x21,0x27,0x29,0x33,0xE3,0x25,0x25,0x29,0x21,0xA1,0x41, + 0x88,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xBEBF [?] [2757]*/ + 0x02,0x01,0x7F,0x40,0x88,0x12,0x22,0x02,0x3F,0x02,0x04,0x04,0x08,0x10,0x20,0x40, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x08,0x00,0xE0,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xBEC0 [?] [2758]*/ + 0x10,0x10,0x20,0x24,0x44,0xF8,0x10,0x20,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x04,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x8C,0xB4,0xC4,0x84,0x04,0x04,0x04,0x04, + /* 0xBEC1 [?] [2759]*/ + 0x00,0x00,0xFC,0x10,0x11,0x11,0x7D,0x12,0x10,0x10,0x10,0x1C,0xE0,0x41,0x02,0x04, + 0x80,0x80,0x80,0xF8,0x08,0x08,0x10,0x10,0x20,0x20,0x50,0x50,0x88,0x08,0x04,0x02, + /* 0xBEC2 [?] [2760]*/ + 0x04,0x04,0x7C,0x04,0x04,0x04,0x7C,0x04,0x04,0x04,0x7C,0x04,0x04,0x04,0xFF,0x00, + 0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x00, + /* 0xBEC3 [?] [2761]*/ + 0x04,0x04,0x04,0x07,0x08,0x08,0x10,0x20,0x40,0x00,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xE0,0x20,0x20,0x40,0x40,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xBEC4 [?] [2762]*/ + 0x04,0x04,0x0F,0x10,0x20,0x03,0x0C,0x70,0x01,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xE0,0x40,0x80,0x60,0x18,0x04,0x00,0x10,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xBEC5 [?] [2763]*/ + 0x04,0x04,0x04,0x04,0x7F,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xBEC6 [?] [2764]*/ + 0x00,0x4F,0x20,0x20,0x07,0x84,0x44,0x54,0x15,0x26,0xE4,0x27,0x24,0x24,0x27,0x04, + 0x00,0xFE,0xA0,0xA0,0xFC,0xA4,0xA4,0xA4,0x1C,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xBEC7 [?] [2765]*/ + 0x00,0x3F,0x20,0x2F,0x29,0x29,0x2F,0x29,0x29,0x2F,0x28,0x2A,0x29,0x4B,0x4D,0x88, + 0x00,0xFE,0x00,0x7E,0x10,0x10,0x50,0x50,0x7E,0x10,0x28,0x28,0x28,0x4A,0x4A,0x86, + /* 0xBEC8 [?] [2766]*/ + 0x10,0x14,0x12,0x10,0xFE,0x11,0x10,0x92,0x54,0x10,0x38,0x54,0x92,0x10,0x51,0x22, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xBEC9 [?] [2767]*/ + 0x20,0x23,0x22,0x22,0x22,0x22,0x22,0x23,0x22,0x22,0x22,0x22,0x22,0x23,0x22,0x20, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xBECA [?] [2768]*/ + 0x00,0x04,0x38,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x00, + 0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x78,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00, + /* 0xBECB [?] [2769]*/ + 0x3E,0x20,0x3C,0x20,0x3F,0x00,0x1F,0x11,0x1F,0x11,0x1F,0x02,0x7F,0x04,0x18,0x60, + 0x78,0x08,0x78,0x08,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x28,0x10, + /* 0xBECC [?] [2770]*/ + 0x10,0x10,0x1E,0x22,0x22,0x54,0x08,0x14,0x23,0xC0,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0xFE,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xBECD [?] [2771]*/ + 0x20,0x10,0xFE,0x00,0x00,0x7D,0x44,0x44,0x44,0x7C,0x10,0x54,0x92,0x11,0x51,0x22, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x50,0x50,0x50,0x50,0x90,0x90,0x92,0x12,0x0E,0x00, + /* 0xBECE [?] [2772]*/ + 0x00,0x00,0x1F,0x11,0x91,0x51,0x53,0x12,0x34,0x58,0x90,0x10,0x20,0x21,0x46,0x98, + 0x80,0x40,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0xA0,0x10,0x08,0x06, + /* 0xBECF [?] [2773]*/ + 0x28,0x28,0xFE,0x29,0x3A,0x10,0x7C,0x54,0x55,0x7C,0x10,0xFE,0x11,0x10,0x10,0x10, + 0x80,0x80,0xFE,0x02,0x22,0xAA,0x72,0x22,0xFE,0x22,0x72,0xAA,0x22,0x22,0x0A,0x04, + /* 0xBED0 [?] [2774]*/ + 0x10,0x10,0x11,0x11,0xFA,0x14,0x11,0x19,0x31,0xD1,0x11,0x11,0x10,0x10,0x50,0x20, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x04,0x28,0x10, + /* 0xBED1 [?] [2775]*/ + 0x00,0x45,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x57,0x20, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xBED2 [?] [2776]*/ + 0x00,0x00,0x1F,0x10,0x90,0x53,0x52,0x12,0x33,0x52,0x92,0x13,0x22,0x22,0x4F,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00, + /* 0xBED3 [?] [2777]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x28,0x48,0x48,0x8F,0x08, + 0x00,0xF8,0x08,0x08,0xF8,0x80,0x80,0xFE,0x80,0x80,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBED4 [?] [2778]*/ + 0x00,0xF8,0x09,0x49,0x4A,0x4C,0x49,0x7D,0x05,0x05,0x1D,0xE5,0x44,0x04,0x28,0x10, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x04,0x28,0x10, + /* 0xBED5 [?] [2779]*/ + 0x04,0x04,0xFF,0x04,0x10,0x1F,0x22,0x52,0x8A,0x02,0x7F,0x07,0x0A,0x12,0x62,0x02, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x04,0x44,0x84,0x04,0xF4,0x04,0x84,0x44,0x14,0x08, + /* 0xBED6 [?] [2780]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x27,0x24,0x24,0x47,0x40,0x80,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xBED7 [?] [2781]*/ + 0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x07,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xBED8 [?] [2782]*/ + 0x20,0x21,0x3D,0x51,0x91,0x11,0x11,0xFF,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x80, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xBED9 [?] [2783]*/ + 0x22,0x11,0x11,0x00,0xFF,0x08,0x11,0x21,0xCF,0x01,0x01,0x7F,0x01,0x01,0x01,0x01, + 0x08,0x08,0x10,0x20,0xFE,0x20,0x10,0x08,0xE6,0x00,0x00,0xFC,0x00,0x00,0x00,0x00, + /* 0xBEDA [?] [2784]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x4A,0x0A,0x12,0x13,0xE2,0x22,0x22,0x22,0x2F,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xBEDB [?] [2785]*/ + 0x7F,0x22,0x3E,0x22,0x3E,0x23,0xFE,0x02,0x00,0x7F,0x09,0x11,0x63,0x05,0x19,0xE1, + 0x00,0x7C,0x04,0x28,0x10,0xA8,0x44,0x00,0xF8,0x00,0x04,0x88,0x50,0x20,0x18,0x06, + /* 0xBEDC [?] [2786]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x20, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xBEDD [?] [2787]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x2B,0x32,0xE2,0x22,0x22,0x22,0x24,0xA4,0x48, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xBEDE [?] [2788]*/ + 0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x00, + 0x00,0xF8,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xBEDF [?] [2789]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0xFF,0x04,0x08,0x10,0x20, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0xFE,0x40,0x20,0x10,0x08, + /* 0xBEE0 [?] [2790]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01,0x00, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xBEE1 [?] [2791]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x00,0xFE,0x02,0x02,0xFE,0x10,0x10,0xFE,0x10,0x10,0x7E,0x42,0x42,0x42,0x7E,0x42, + /* 0xBEE2 [?] [2792]*/ + 0x20,0x23,0x3A,0x22,0x43,0x7A,0xA2,0x23,0xFA,0x22,0x22,0x22,0x2A,0x34,0x24,0x08, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xBEE3 [?] [2793]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x32,0x33,0x52,0x93,0x12,0x12,0x1F,0x10,0x11,0x12,0x14, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x00,0x10,0x08,0x04, + /* 0xBEE4 [?] [2794]*/ + 0x08,0x08,0x10,0x1F,0x20,0x40,0x9F,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x50,0x20, + /* 0xBEE5 [?] [2795]*/ + 0x10,0x13,0x12,0x12,0x1B,0x56,0x53,0x52,0x93,0x12,0x12,0x1F,0x10,0x11,0x12,0x14, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x00,0x10,0x08,0x04, + /* 0xBEE6 [?] [2796]*/ + 0x10,0x11,0x11,0x11,0x55,0x59,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x80, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xBEE7 [?] [2797]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x24,0x24,0x3F,0x24,0x24,0x3F,0x50,0x50,0x90,0x1F,0x10, + 0x04,0x84,0x84,0xA4,0xA4,0x24,0x24,0xA4,0x24,0x24,0xA4,0xA4,0x84,0x84,0x94,0x88, + /* 0xBEE8 [?] [2798]*/ + 0x10,0x11,0x11,0x11,0xFD,0x10,0x13,0x16,0x1A,0x33,0xD2,0x12,0x13,0x12,0x52,0x22, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x14,0x08, + /* 0xBEE9 [?] [2799]*/ + 0x00,0x3E,0x22,0x22,0x3E,0x00,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x41,0x45,0x42, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xBEEA [?] [2800]*/ + 0x20,0x21,0x21,0x21,0xF9,0x48,0x4B,0x4A,0x4A,0x93,0x52,0x22,0x33,0x4A,0x4A,0x82, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x14,0x08, + /* 0xBEEB [?] [2801]*/ + 0x10,0x12,0x11,0x27,0x20,0x61,0x6F,0xA2,0x24,0x2B,0x32,0x22,0x22,0x22,0x22,0x21, + 0x40,0x48,0x50,0xFC,0x80,0x00,0xFE,0x10,0x08,0xF4,0x12,0x10,0x50,0x24,0x04,0xFC, + /* 0xBEEC [?] [2802]*/ + 0x01,0x11,0x09,0x3F,0x02,0x7F,0x08,0x10,0x2F,0xC8,0x0F,0x08,0x0F,0x08,0x0F,0x08, + 0x00,0x10,0x20,0xF8,0x00,0xFC,0x20,0x10,0xE8,0x26,0xE0,0x20,0xE0,0x20,0xE0,0x20, + /* 0xBEED [?] [2803]*/ + 0x01,0x11,0x09,0x3F,0x02,0x02,0x7F,0x08,0x10,0x2F,0xC8,0x08,0x08,0x08,0x08,0x07, + 0x00,0x10,0x20,0xF8,0x00,0x00,0xFC,0x20,0x10,0xE8,0x26,0x20,0xA8,0x48,0x08,0xF8, + /* 0xBEEE [?] [2804]*/ + 0x10,0x11,0x21,0x21,0x49,0xF8,0x13,0x22,0x42,0xFB,0x42,0x02,0x1B,0xE2,0x42,0x02, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x14,0x08, + /* 0xBEEF [?] [2805]*/ + 0x20,0x2F,0x28,0x2A,0xF9,0x2B,0x28,0x28,0x3A,0xEA,0x2B,0x28,0x28,0x29,0xA9,0x52, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xBEF0 [?] [2806]*/ + 0x13,0x12,0x13,0x12,0xFB,0x10,0x11,0x1B,0x35,0xD1,0x11,0x10,0x11,0x10,0x50,0x27, + 0xDE,0x52,0xDE,0x52,0xDE,0xA0,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x70,0x8E, + /* 0xBEF1 [?] [2807]*/ + 0x10,0x10,0x10,0x13,0xF8,0x10,0x14,0x18,0x37,0xD0,0x10,0x10,0x11,0x11,0x52,0x24, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x06, + /* 0xBEF2 [?] [2808]*/ + 0x20,0x27,0x24,0x24,0xF7,0x24,0x25,0x25,0x35,0xE5,0x24,0x25,0x25,0x29,0xA9,0x50, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x24,0x24,0x24,0xFC,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xBEF3 [?] [2809]*/ + 0x10,0x17,0x14,0x24,0x27,0x64,0x65,0xA5,0x25,0x25,0x24,0x25,0x25,0x29,0x29,0x30, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x24,0x24,0x24,0xFC,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xBEF4 [?] [2810]*/ + 0x00,0x7F,0x22,0x11,0x7F,0x44,0x7F,0x00,0x7E,0x42,0x7E,0x42,0x7E,0x48,0x74,0x42, + 0xFC,0x00,0x08,0x10,0xFC,0x44,0xFC,0x08,0x08,0xFE,0x08,0x48,0x28,0x08,0x28,0x10, + /* 0xBEF5 [?] [2811]*/ + 0x22,0x11,0x00,0x7F,0x40,0x80,0x1F,0x10,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0x08,0x10,0x20,0xFE,0x02,0x04,0xF0,0x10,0x10,0x10,0x10,0x90,0x80,0x84,0x84,0x7C, + /* 0xBEF6 [?] [2812]*/ + 0x00,0x40,0x20,0x27,0x00,0x00,0x10,0x10,0x2F,0xE0,0x21,0x21,0x22,0x24,0x28,0x10, + 0x80,0x80,0x80,0xF8,0x88,0x88,0x88,0x88,0xFE,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xBEF7 [?] [2813]*/ + 0x00,0x20,0x10,0x13,0x00,0x00,0xF0,0x10,0x17,0x10,0x10,0x14,0x19,0x12,0x04,0x08, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x04,0x02, + /* 0xBEF8 [?] [2814]*/ + 0x10,0x10,0x20,0x21,0x4A,0xF5,0x11,0x21,0x41,0xF9,0x41,0x01,0x19,0xE1,0x40,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xBEF9 [?] [2815]*/ + 0x10,0x10,0x10,0x10,0x11,0xFE,0x10,0x10,0x10,0x10,0x10,0x1C,0xE1,0x40,0x00,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x84,0x44,0x44,0x14,0x24,0x44,0x84,0x04,0x28,0x10, + /* 0xBEFA [?] [2816]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x20,0x20,0x27,0x21,0x2F,0x23,0x25,0x29,0x21,0x3F,0x20, + 0x20,0xFE,0x20,0x00,0xF8,0x08,0xC8,0x08,0x08,0xE8,0x88,0x48,0x28,0x08,0xF8,0x08, + /* 0xBEFB [?] [2817]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBE,0x10,0x10,0xFC,0x10,0x10,0x10,0x15,0x18,0x10,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x84,0x44,0x44,0x14,0x24,0x44,0x84,0x04,0x28,0x10, + /* 0xBEFC [?] [2818]*/ + 0x00,0x7F,0x40,0x82,0x02,0x3F,0x04,0x09,0x11,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01, + 0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xBEFD [?] [2819]*/ + 0x00,0x3F,0x04,0x04,0xFF,0x04,0x04,0x3F,0x08,0x08,0x1F,0x18,0x28,0x48,0x8F,0x08, + 0x00,0xF8,0x08,0x08,0xFE,0x08,0x08,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBEFE [?] [2820]*/ + 0x20,0x20,0x20,0x21,0xAB,0xA8,0xA8,0xA9,0xAA,0xA8,0xA9,0xBA,0xC8,0x00,0x01,0x06, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBFA1 [?] [2821]*/ + 0x08,0x08,0x08,0x11,0x13,0x30,0x30,0x51,0x92,0x10,0x11,0x12,0x10,0x10,0x11,0x16, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBFA2 [?] [2822]*/ + 0x20,0x10,0x10,0xFD,0x03,0x08,0x88,0x89,0x4A,0x48,0x51,0x52,0x1C,0xE0,0x41,0x06, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBFA3 [?] [2823]*/ + 0x00,0x20,0x11,0x12,0x87,0x40,0x41,0x12,0x14,0x21,0xE3,0x24,0x20,0x20,0x23,0x0C, + 0x80,0x80,0x10,0x08,0xFC,0x04,0x10,0x88,0x84,0xF0,0x10,0xA0,0x40,0xA0,0x10,0x0C, + /* 0xBFA4 [?] [2824]*/ + 0x00,0x7F,0x11,0x11,0xFF,0x11,0x11,0x7F,0x20,0x20,0x7F,0xA1,0x21,0x21,0x3F,0x21, + 0x00,0x3E,0x22,0x24,0xE4,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xBFA5 [?] [2825]*/ + 0x00,0xF8,0x08,0x49,0x4B,0x48,0x48,0x7D,0x06,0x04,0x1D,0xE6,0x44,0x04,0x29,0x16, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xBFA6 [?] [2826]*/ + 0x00,0x00,0x7B,0x4A,0x48,0x48,0x49,0x4A,0x48,0x49,0x7E,0x49,0x01,0x01,0x01,0x01, + 0x40,0x20,0xFE,0x02,0x80,0xF8,0x08,0x90,0x60,0x98,0x06,0xF8,0x08,0x08,0xF8,0x08, + /* 0xBFA7 [?] [2827]*/ + 0x04,0x04,0xF4,0x94,0x9F,0x94,0x94,0x94,0x94,0x94,0xF4,0x94,0x08,0x08,0x12,0x21, + 0x00,0x00,0x00,0x3C,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xBC,0xA4,0x00, + /* 0xBFA8 [?] [2828]*/ + 0x02,0x02,0x03,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x40,0x20,0x10,0x08,0x00,0x00,0x00, + /* 0xBFA9 [?] [2829]*/ + 0x00,0x00,0x78,0x49,0x4B,0x4C,0x48,0x48,0x49,0x4A,0x7D,0x49,0x01,0x01,0x01,0x01, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBFAA [?] [2830]*/ + 0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xBFAB [?] [2831]*/ + 0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x14,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x10,0x12,0xD4,0x18,0x52,0x92,0x2E,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xBFAC [?] [2832]*/ + 0x11,0x11,0x11,0x11,0xFD,0x11,0x31,0x38,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11, + 0x10,0x12,0xD4,0x18,0x52,0x92,0x2E,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xBFAD [?] [2833]*/ + 0x10,0x92,0x92,0x92,0xFE,0x00,0xFE,0x02,0x02,0x7E,0x40,0x40,0x46,0x59,0x61,0x02, + 0x00,0xF0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xBFAE [?] [2834]*/ + 0x20,0x27,0x24,0x24,0x37,0xAC,0xA4,0xA7,0xA4,0x25,0x24,0x25,0x26,0x24,0x20,0x20, + 0x00,0xBE,0x88,0x88,0xA8,0xA8,0xA8,0xBE,0x10,0x18,0x98,0xA8,0xAA,0x4A,0x46,0x80, + /* 0xBFAF [?] [2835]*/ + 0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xBFB0 [?] [2836]*/ + 0x10,0x10,0x13,0x10,0x10,0xFC,0x10,0x10,0x10,0x13,0x11,0x1D,0xE1,0x41,0x01,0x00, + 0x88,0x88,0xFE,0x88,0xF8,0x88,0xF8,0x88,0x88,0xFE,0x00,0x48,0x84,0x00,0xFE,0x00, + /* 0xBFB1 [?] [2837]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x22,0x3E,0x22,0x22,0xFF,0x40,0x54,0x62,0x40,0x7F,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xBFB2 [?] [2838]*/ + 0x10,0x10,0x10,0x10,0x11,0xFD,0x12,0x14,0x10,0x10,0x10,0x1D,0xE1,0x42,0x04,0x08, + 0x80,0x80,0x80,0xFC,0x04,0x08,0x40,0x40,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xBFB3 [?] [2839]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3D,0x64,0x64,0xA4,0x24,0x24,0x3C,0x24,0x21,0x02, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xBFB4 [?] [2840]*/ + 0x00,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x08,0x1F,0x28,0x4F,0x88,0x0F,0x08,0x0F,0x08, + 0xF8,0x00,0x00,0xF8,0x00,0xFE,0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xBFB5 [?] [2841]*/ + 0x01,0x00,0x3F,0x20,0x2F,0x20,0x3F,0x20,0x2F,0x28,0x24,0x22,0x44,0x48,0x92,0x01, + 0x00,0x80,0xFE,0x80,0xF8,0x88,0xFE,0x88,0xF8,0x80,0xC4,0xA8,0x90,0x88,0x86,0x00, + /* 0xBFB6 [?] [2842]*/ + 0x20,0x20,0x27,0x24,0x35,0xAC,0xA7,0xA4,0xA5,0x24,0x25,0x24,0x29,0x2A,0x30,0x20, + 0x40,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0x62,0xB4,0x28,0x26,0xA0,0x40, + /* 0xBFB7 [?] [2843]*/ + 0x10,0x10,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x12,0x12,0x14, + 0x20,0x10,0xFE,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x92,0x54,0x38,0x54,0x92,0x30, + /* 0xBFB8 [?] [2844]*/ + 0x10,0x10,0x11,0x10,0xFE,0x10,0x10,0x12,0x1C,0x30,0xD0,0x10,0x10,0x10,0x53,0x20, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBFB9 [?] [2845]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBFBA [?] [2846]*/ + 0x02,0x01,0x01,0xFF,0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0x00,0x00,0xFE,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xBFBB [?] [2847]*/ + 0x10,0x10,0x10,0x13,0x54,0x58,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x46,0x42,0x84, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBFBC [?] [2848]*/ + 0x02,0x02,0x3F,0x02,0x02,0xFF,0x01,0x02,0x0F,0x12,0x24,0x47,0x80,0x00,0x00,0x00, + 0x00,0x08,0xD0,0x20,0x40,0xFE,0x00,0x00,0xF8,0x00,0x00,0xF0,0x10,0x10,0xA0,0x40, + /* 0xBFBD [?] [2849]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x10,0x14,0x19,0x32,0xD4,0x10,0x10,0x10,0x50,0x20, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xBFBE [?] [2850]*/ + 0x10,0x10,0x11,0x10,0x54,0x5B,0x50,0x90,0x11,0x12,0x14,0x28,0x24,0x44,0x40,0x80, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xBFBF [?] [2851]*/ + 0x11,0x1F,0x21,0xFF,0x00,0x1F,0x10,0x1F,0x04,0x7C,0x04,0x3C,0x04,0x7C,0x04,0x04, + 0x00,0xF0,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x40, + /* 0xBFC0 [?] [2852]*/ + 0x20,0x20,0x27,0x20,0x20,0xFB,0x22,0x22,0x22,0x22,0x23,0x3A,0xE0,0x40,0x00,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0xC8,0x48,0x08,0x08,0x28,0x10, + /* 0xBFC1 [?] [2853]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x00,0x00,0x1F,0x11,0x11,0x1F,0x11,0x00,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xBFC2 [?] [2854]*/ + 0x10,0x10,0x17,0x10,0xFC,0x13,0x32,0x3A,0x56,0x52,0x93,0x12,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0xC8,0x48,0x08,0x08,0x28,0x10, + /* 0xBFC3 [?] [2855]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x54,0x53,0x90,0x10,0x11,0x12,0x10,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xBFC4 [?] [2856]*/ + 0x00,0x00,0xFC,0x10,0x10,0x21,0x3C,0x64,0x65,0xA4,0x25,0x25,0x3D,0x25,0x23,0x00, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x40,0x84,0xFE,0x02,0xFC,0x54,0x54,0x54,0xFE,0x00, + /* 0xBFC5 [?] [2857]*/ + 0x00,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x08,0xFF,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x00,0x7E,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xBFC6 [?] [2858]*/ + 0x08,0x1D,0xF0,0x10,0x10,0xFD,0x10,0x38,0x34,0x50,0x53,0x90,0x10,0x10,0x10,0x10, + 0x10,0x10,0x90,0x90,0x10,0x10,0x90,0x90,0x10,0x1E,0xF0,0x10,0x10,0x10,0x10,0x10, + /* 0xBFC7 [?] [2859]*/ + 0x01,0x01,0x7F,0x01,0x01,0x1F,0x00,0x7F,0x40,0x80,0x0F,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xFC,0x00,0x00,0xF0,0x00,0xFE,0x02,0x04,0xE0,0x20,0x20,0x22,0x22,0x1E, + /* 0xBFC8 [?] [2860]*/ + 0x00,0x00,0xF0,0x97,0x90,0x90,0x91,0x93,0x90,0x90,0xF1,0x96,0x00,0x00,0x01,0x06, + 0x40,0x20,0x20,0xFE,0x40,0x84,0x08,0xF0,0x22,0x44,0x88,0x10,0x20,0x50,0x88,0x04, + /* 0xBFC9 [?] [2861]*/ + 0x00,0x7F,0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0x11,0x1F,0x11,0x00,0x00,0x00,0x00, + 0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xBFCA [?] [2862]*/ + 0x00,0x23,0x12,0x13,0x82,0x43,0x49,0x0B,0x14,0x12,0xE2,0x22,0x23,0x20,0x20,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xBFCB [?] [2863]*/ + 0x01,0x01,0xFF,0x01,0x01,0x3F,0x20,0x20,0x20,0x3F,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xBFCC [?] [2864]*/ + 0x10,0x08,0x00,0xFF,0x08,0x11,0x21,0x7E,0x04,0x09,0x12,0x24,0xCC,0x12,0x21,0xC0, + 0x04,0x04,0x04,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x88, + /* 0xBFCD [?] [2865]*/ + 0x02,0x01,0x7F,0x40,0x88,0x0F,0x10,0x2C,0x03,0x1C,0xE0,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x02,0x04,0xF0,0x20,0x40,0x80,0x70,0x0E,0xF0,0x10,0x10,0xF0,0x10, + /* 0xBFCE [?] [2866]*/ + 0x00,0x43,0x22,0x22,0x03,0x02,0xE2,0x23,0x20,0x27,0x20,0x29,0x32,0x24,0x00,0x00, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xBFCF [?] [2867]*/ + 0x01,0x01,0x11,0x11,0x11,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xBFD0 [?] [2868]*/ + 0x00,0x01,0x79,0x49,0x49,0x4F,0x48,0x4B,0x4A,0x4B,0x7A,0x4B,0x02,0x02,0x02,0x02, + 0x20,0x20,0x3C,0x20,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xBFD1 [?] [2869]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x3F,0x22,0x21,0x2C,0x31,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x08,0x90,0x60,0x1C,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xBFD2 [?] [2870]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x3F,0x22,0x21,0x2C,0x30,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x08,0x90,0x60,0x1C,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xBFD3 [?] [2871]*/ + 0x10,0x10,0x10,0x13,0x10,0xFC,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBFD4 [?] [2872]*/ + 0x00,0x00,0x78,0x4F,0x48,0x48,0x49,0x49,0x49,0x49,0x79,0x49,0x02,0x02,0x04,0x08, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xBFD5 [?] [2873]*/ + 0x02,0x01,0x7F,0x40,0x88,0x10,0x20,0x00,0x1F,0x01,0x01,0x01,0x01,0x01,0x7F,0x00, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x08,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xBFD6 [?] [2874]*/ + 0x00,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE2,0x44,0x08,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xF0,0x10,0x10,0x90,0x50,0x12,0x12,0x0E,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xBFD7 [?] [2875]*/ + 0x00,0x7E,0x02,0x04,0x08,0x08,0x0A,0x0C,0x38,0xC8,0x08,0x08,0x08,0x08,0x28,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xBFD8 [?] [2876]*/ + 0x10,0x10,0x10,0x13,0xFA,0x14,0x11,0x1A,0x30,0xD1,0x10,0x10,0x10,0x10,0x57,0x20, + 0x40,0x20,0x20,0xFE,0x02,0x94,0x08,0x04,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBFD9 [?] [2877]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x20, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xBFDA [?] [2878]*/ + 0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00, + /* 0xBFDB [?] [2879]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x20, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xBFDC [?] [2880]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3E,0x00,0x00,0x7E,0x14,0x14,0x14,0x14,0x24,0x24,0x43, + 0x00,0x00,0xFE,0x02,0x24,0x38,0x20,0x20,0xF8,0x08,0x50,0x20,0x54,0x84,0x04,0xFC, + /* 0xBFDD [?] [2881]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x38,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xBFDE [?] [2882]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x00,0x01,0x01,0xFF,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x78,0x48,0x48,0x48,0x78,0x00,0x10,0x08,0xFE,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xBFDF [?] [2883]*/ + 0x02,0x01,0x7F,0x48,0x90,0x3F,0x20,0x3F,0x20,0x24,0x24,0x27,0x20,0x48,0x48,0x8F, + 0x00,0x00,0xFE,0x22,0x14,0xF8,0x08,0xF8,0x80,0x90,0x90,0xF0,0x80,0x88,0x88,0xF8, + /* 0xBFE0 [?] [2884]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x01,0xFF,0x01,0x01,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xBFE1 [?] [2885]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x10,0x50,0x50,0x7C,0x50,0x90,0x10,0xFE,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xBFE2 [?] [2886]*/ + 0x01,0x00,0x3F,0x21,0x21,0x3F,0x22,0x24,0x28,0x2F,0x20,0x20,0x5F,0x40,0x80,0x00, + 0x00,0x80,0xFE,0x00,0x00,0xFC,0x00,0x80,0x80,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80, + /* 0xBFE3 [?] [2887]*/ + 0x20,0x10,0x01,0xFD,0x09,0x11,0x11,0x35,0x59,0x95,0x15,0x11,0x11,0x12,0x12,0x14, + 0x10,0x08,0xFE,0x10,0x10,0xFE,0x20,0x28,0x48,0x7E,0x08,0x08,0xFE,0x08,0x08,0x08, + /* 0xBFE4 [?] [2888]*/ + 0x01,0x01,0x7F,0x04,0x08,0x17,0x20,0xC0,0x3F,0x04,0x08,0x0F,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x40,0x20,0xD0,0x08,0x06,0xF8,0x00,0x00,0xF0,0x10,0x10,0xA0,0x40, + /* 0xBFE5 [?] [2889]*/ + 0x20,0x20,0x27,0x20,0x21,0xFA,0x2D,0x20,0x27,0x20,0x21,0x3B,0xE0,0x40,0x00,0x00, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xF6,0x00,0xFC,0x80,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xBFE6 [?] [2890]*/ + 0x20,0x20,0x27,0x20,0xF1,0x22,0x2D,0x20,0x37,0xE0,0x21,0x23,0x20,0x20,0xA0,0x40, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xF6,0x00,0xFC,0x80,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xBFE7 [?] [2891]*/ + 0x00,0x78,0x4B,0x48,0x48,0x79,0x16,0x10,0x53,0x5C,0x50,0x51,0x58,0xE0,0x00,0x00, + 0x20,0x20,0xFE,0x50,0x88,0x04,0xFA,0x00,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xBFE8 [?] [2892]*/ + 0x00,0x3C,0x25,0x24,0x24,0x3D,0x26,0x24,0x27,0x3C,0x24,0x25,0x24,0x44,0x54,0x88, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFA,0x00,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xBFE9 [?] [2893]*/ + 0x10,0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x13,0x10,0x10,0x1C,0xE1,0x42,0x04,0x08, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x04,0x02, + /* 0xBFEA [?] [2894]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x11,0x18,0x54,0x50,0x53,0x90,0x10,0x11,0x12,0x14, + 0x40,0x40,0x7E,0x90,0x08,0x40,0xF8,0x48,0x48,0x48,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xBFEB [?] [2895]*/ + 0x08,0x08,0x08,0x11,0x12,0x34,0x31,0x50,0x90,0x17,0x10,0x10,0x11,0x12,0x17,0x12, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xBFEC [?] [2896]*/ + 0x10,0x10,0x10,0x13,0x18,0x54,0x50,0x50,0x97,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x06, + /* 0xBFED [?] [2897]*/ + 0x02,0x01,0x7F,0x40,0x84,0x3F,0x04,0x00,0x1F,0x10,0x11,0x11,0x12,0x04,0x18,0xE0, + 0x00,0x00,0xFE,0x02,0x44,0xF8,0x40,0x00,0xF0,0x10,0x10,0x10,0x90,0x82,0x82,0x7E, + /* 0xBFEE [?] [2898]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7E,0x00,0x7E,0x00,0xFF,0x08,0x4A,0x49,0x89,0x28,0x11, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xBFEF [?] [2899]*/ + 0x00,0x7F,0x40,0x40,0x4F,0x40,0x40,0x47,0x40,0x40,0x40,0x4F,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0xF8,0x00,0x00,0xFE,0x00, + /* 0xBFF0 [?] [2900]*/ + 0x20,0x3F,0x48,0x85,0x00,0x3F,0x20,0x2F,0x20,0x20,0x27,0x20,0x20,0x2F,0x20,0x3F, + 0x40,0x7E,0x90,0x08,0x00,0xFE,0x00,0xFC,0x80,0x80,0xF8,0x80,0x80,0xFC,0x00,0xFE, + /* 0xBFF1 [?] [2901]*/ + 0x00,0x44,0x29,0x10,0x28,0x48,0x88,0x08,0x19,0x28,0x48,0x88,0x08,0x08,0x53,0x20, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xBFF2 [?] [2902]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x10, + 0x00,0xFE,0x00,0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0x10,0xFE,0x00,0x00,0xFE,0x00, + /* 0xBFF3 [?] [2903]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3C,0x25,0x21,0x02, + 0x20,0x10,0x10,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00, + /* 0xBFF4 [?] [2904]*/ + 0x00,0x01,0x7D,0x45,0x45,0x7D,0x45,0x45,0x7D,0x45,0x45,0x45,0x7D,0x45,0x01,0x00, + 0x00,0xFE,0x00,0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0x10,0xFE,0x00,0x00,0xFE,0x00, + /* 0xBFF5 [?] [2905]*/ + 0x00,0x00,0x78,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x49,0x79,0x49,0x02,0x02,0x04, + 0x40,0x20,0x20,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xBFF6 [?] [2906]*/ + 0x00,0x47,0x24,0x24,0x04,0x04,0x17,0x11,0x21,0xE1,0x21,0x22,0x22,0x24,0x28,0x10, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xBFF7 [?] [2907]*/ + 0x00,0x3F,0x00,0x00,0x00,0xFF,0x04,0x04,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xBFF8 [?] [2908]*/ + 0x04,0x04,0x7F,0x08,0x12,0x12,0x24,0x41,0x82,0x0C,0x00,0x3F,0x24,0x24,0x24,0xFF, + 0x00,0x00,0xFC,0x40,0x48,0x50,0xA0,0x10,0x08,0x06,0x00,0xF8,0x48,0x48,0x48,0xFE, + /* 0xBFF9 [?] [2909]*/ + 0x01,0x21,0x21,0x3F,0x00,0x08,0x4B,0x48,0x48,0x48,0x49,0x48,0x48,0x10,0x13,0x20, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xBFFA [?] [2910]*/ + 0x02,0x01,0x7F,0x48,0x90,0x00,0x11,0x7D,0x11,0x11,0xFD,0x11,0x28,0x24,0x41,0x86, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xFC,0x04,0x24,0x24,0x24,0x54,0x50,0x90,0x12,0x0E, + /* 0xBFFB [?] [2911]*/ + 0x08,0xFF,0x08,0x00,0x7E,0x04,0x28,0x10,0x2F,0xC1,0x01,0x7F,0x01,0x02,0x0C,0x70, + 0x20,0xFE,0x20,0x90,0xA0,0x44,0x28,0x10,0xE8,0x06,0x00,0xFC,0x00,0xC0,0x30,0x08, + /* 0xBFFC [?] [2912]*/ + 0x02,0x02,0x7F,0x04,0x09,0x31,0xCF,0x01,0x01,0x7F,0x00,0x01,0x3F,0x01,0x01,0xFF, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE, + /* 0xBFFD [?] [2913]*/ + 0x08,0x10,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x10,0x1A,0x2C,0x2F,0x48,0x48,0x87, + 0x08,0x48,0x28,0x28,0x08,0x48,0x28,0x28,0x0E,0xF8,0x08,0x88,0x88,0x08,0x02,0xFE, + /* 0xBFFE [?] [2914]*/ + 0x10,0x10,0x17,0x24,0x24,0x67,0x64,0xA4,0x27,0x20,0x21,0x21,0x22,0x24,0x28,0x30, + 0x40,0x80,0xFC,0x44,0x44,0xFC,0x44,0x84,0xFC,0x80,0x50,0x64,0x7C,0x42,0x42,0x3E, + /* 0xC0A1 [?] [2915]*/ + 0x20,0x20,0x21,0x3D,0x45,0x48,0x83,0x20,0x21,0x21,0x21,0x25,0x29,0x30,0x20,0x03, + 0x20,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xC0A2 [?] [2916]*/ + 0x20,0x20,0x27,0x24,0x34,0xAF,0xA4,0xA4,0xA7,0x20,0x21,0x21,0x22,0x24,0x28,0x30, + 0x40,0x80,0xFC,0x44,0x44,0xFC,0x44,0x84,0xFC,0x80,0x50,0x64,0x7C,0x42,0x42,0x3E, + /* 0xC0A3 [?] [2917]*/ + 0x00,0x20,0x13,0x12,0x83,0x40,0x4F,0x10,0x13,0x22,0xE2,0x22,0x22,0x20,0x21,0x06, + 0x40,0x40,0xF8,0x48,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0x48,0xA0,0x10,0x08, + /* 0xC0A4 [?] [2918]*/ + 0x10,0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x40,0x00,0x00, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xC0A5 [?] [2919]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x00,0x20,0x20,0x3E,0x20,0x20,0x26,0x38, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x80,0x84,0x98,0xE0,0x84,0x84,0x7C, + /* 0xC0A6 [?] [2920]*/ + 0x20,0x27,0x24,0x24,0xFC,0x27,0x24,0x2C,0x34,0xE5,0x26,0x24,0x24,0x24,0xA7,0x44, + 0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0xC4,0xE4,0x54,0x44,0x44,0x44,0x04,0xFC,0x04, + /* 0xC0A7 [?] [2921]*/ + 0x00,0x7F,0x41,0x41,0x41,0x5F,0x41,0x43,0x43,0x45,0x49,0x51,0x41,0x41,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x84,0x44,0x24,0x14,0x14,0x04,0x04,0xFC,0x04, + /* 0xC0A8 [?] [2922]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x10,0x14,0x18,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC0A9 [?] [2923]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x20,0x10,0x10,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC0AA [?] [2924]*/ + 0x00,0x3F,0x22,0x3F,0x20,0x2F,0x28,0x2F,0x20,0x2F,0x21,0x23,0x5E,0x42,0x8A,0x04, + 0x80,0xFE,0x00,0xBC,0x24,0xA4,0xA8,0xA8,0x24,0xA4,0x24,0xF4,0x28,0x20,0x20,0x20, + /* 0xC0AB [?] [2925]*/ + 0x20,0x17,0x00,0x48,0x45,0x64,0x50,0x51,0x44,0x48,0x79,0x49,0x49,0x49,0x40,0x40, + 0x00,0xFC,0x04,0x34,0xC4,0x44,0x44,0xF4,0x44,0x44,0xF4,0x14,0x14,0xF4,0x04,0x0C, + /* 0xC0AC [?] [2926]*/ + 0x10,0x10,0x10,0x10,0x13,0xFC,0x10,0x11,0x11,0x10,0x10,0x1C,0xE0,0x40,0x07,0x00, + 0x80,0x40,0x40,0x00,0xFC,0x00,0x08,0x08,0x08,0x90,0x90,0x90,0xA0,0x20,0xFE,0x00, + /* 0xC0AD [?] [2927]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x14,0x19,0x31,0xD0,0x10,0x10,0x10,0x10,0x57,0x20, + 0x40,0x20,0x20,0x00,0xFE,0x00,0x04,0x04,0x04,0x88,0x88,0x88,0x90,0x10,0xFE,0x00, + /* 0xC0AE [?] [2928]*/ + 0x01,0x01,0x77,0x51,0x51,0x57,0x55,0x55,0x57,0x51,0x73,0x55,0x09,0x01,0x01,0x01, + 0x04,0x04,0xC4,0x04,0x14,0xD4,0x54,0x54,0xD4,0x14,0x94,0x54,0x44,0x04,0x14,0x08, + /* 0xC0AF [?] [2929]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x55,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x48,0x48,0x48,0xFE,0x48,0x48,0xFE,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xC0B0 [?] [2930]*/ + 0x00,0x78,0x48,0x4B,0x48,0x78,0x4F,0x48,0x49,0x79,0x49,0x49,0x49,0x49,0x49,0x99, + 0x88,0x88,0x88,0xFE,0x88,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xC0B1 [?] [2931]*/ + 0x20,0x10,0x11,0xFC,0x00,0x45,0x29,0xFD,0x11,0x10,0xFC,0x10,0x21,0x22,0x40,0x80, + 0x20,0x20,0xFC,0x20,0x20,0xFC,0x24,0x24,0xFC,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xC0B2 [?] [2932]*/ + 0x01,0x01,0x71,0x51,0x57,0x51,0x51,0x51,0x51,0x53,0x75,0x51,0x01,0x01,0x05,0x02, + 0x20,0x10,0x10,0x7E,0x80,0x04,0x44,0xC4,0x24,0x24,0x28,0x28,0x08,0x10,0x7E,0x00, + /* 0xC0B3 [?] [2933]*/ + 0x08,0x08,0xFF,0x09,0x01,0x3F,0x01,0x11,0x09,0x7F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0x10,0x20,0xFC,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xC0B4 [?] [2934]*/ + 0x01,0x01,0x01,0x7F,0x01,0x11,0x09,0x09,0xFF,0x03,0x05,0x09,0x31,0xC1,0x01,0x01, + 0x00,0x00,0x00,0xFC,0x00,0x10,0x10,0x20,0xFE,0x80,0x40,0x20,0x18,0x06,0x00,0x00, + /* 0xC0B5 [?] [2935]*/ + 0x10,0x10,0xFE,0x11,0x12,0x7D,0x55,0x55,0x55,0x7D,0x11,0x39,0x54,0x90,0x11,0x12, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x88,0x04,0x02, + /* 0xC0B6 [?] [2936]*/ + 0x08,0x08,0xFF,0x08,0x04,0x24,0x24,0x24,0x25,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x80,0x80,0xFC,0xA0,0x10,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xC0B7 [?] [2937]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC9,0x08,0x0A,0x7F,0x04,0x08,0x1C,0x03,0x06,0x38, + 0x20,0x20,0xFC,0x30,0x68,0xA4,0x22,0x20,0x20,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xC0B8 [?] [2938]*/ + 0x10,0x11,0x10,0x10,0xFC,0x13,0x30,0x38,0x54,0x55,0x90,0x10,0x10,0x10,0x13,0x10, + 0x00,0x08,0x88,0x90,0x00,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC0B9 [?] [2939]*/ + 0x10,0x11,0x10,0x10,0xFC,0x13,0x10,0x14,0x18,0x31,0xD0,0x10,0x10,0x10,0x53,0x20, + 0x00,0x08,0x88,0x90,0x00,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC0BA [?] [2940]*/ + 0x20,0x3F,0x48,0x85,0x04,0x24,0x24,0x24,0x25,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x40,0x7E,0x90,0x08,0x80,0x80,0xFC,0xA0,0x10,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xC0BB [?] [2941]*/ + 0x20,0x17,0x01,0x41,0x5F,0x41,0x5F,0x51,0x55,0x53,0x5F,0x45,0x49,0x51,0x41,0x41, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0xF4,0x14,0x54,0x94,0xF4,0x44,0x24,0x24,0x04,0x0C, + /* 0xC0BC [?] [2942]*/ + 0x10,0x08,0x04,0x04,0x00,0x7F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xFF,0x00, + 0x10,0x10,0x20,0x40,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC0BD [?] [2943]*/ + 0x02,0x21,0x15,0x14,0x85,0x44,0x45,0x15,0x15,0x25,0xE5,0x25,0x24,0x25,0x24,0x04, + 0x00,0x7C,0x04,0x44,0xF4,0x44,0xF4,0x54,0x74,0xD4,0x54,0xF4,0xE4,0x54,0x44,0x4C, + /* 0xC0BE [?] [2944]*/ + 0x02,0x41,0x25,0x24,0x05,0x04,0xE5,0x25,0x25,0x25,0x25,0x25,0x2C,0x35,0x24,0x04, + 0x00,0x7C,0x04,0x44,0xF4,0x44,0xF4,0x54,0x74,0xD4,0x54,0xF4,0xE4,0x54,0x44,0x4C, + /* 0xC0BF [?] [2945]*/ + 0x10,0x12,0x12,0x12,0xFA,0x10,0x15,0x19,0x31,0xD1,0x11,0x11,0x10,0x10,0x51,0x26, + 0x90,0x90,0x9E,0xA8,0xC4,0x80,0xFC,0x04,0x24,0x24,0x24,0x54,0x50,0x90,0x12,0x0E, + /* 0xC0C0 [?] [2946]*/ + 0x04,0x24,0x24,0x24,0x25,0x04,0x1F,0x10,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0x40,0x40,0x7C,0x90,0x08,0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x80,0x84,0x84,0x7C, + /* 0xC0C1 [?] [2947]*/ + 0x22,0x22,0x2F,0x22,0x32,0xAF,0xAA,0xAA,0xAF,0x22,0x27,0x2A,0x32,0x22,0x22,0x22, + 0x10,0x10,0x9C,0x24,0x48,0xBE,0xA2,0xAA,0xAA,0x2A,0x2A,0xAA,0x88,0x14,0x22,0x42, + /* 0xC0C2 [?] [2948]*/ + 0x10,0x12,0x22,0x22,0x4A,0xF8,0x11,0x21,0x41,0xF9,0x41,0x01,0x18,0xE0,0x41,0x06, + 0x90,0x90,0x9E,0xA8,0xC4,0x80,0xFC,0x04,0x24,0x24,0x24,0x54,0x50,0x90,0x12,0x0E, + /* 0xC0C3 [?] [2949]*/ + 0x10,0x11,0x10,0x14,0x58,0x53,0x50,0x90,0x10,0x11,0x10,0x28,0x24,0x40,0x43,0x80, + 0x00,0x08,0x88,0x90,0x00,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC0C4 [?] [2950]*/ + 0x00,0x24,0x14,0x14,0x84,0x44,0x44,0x10,0x10,0x27,0xE4,0x24,0x24,0x24,0x2F,0x00, + 0x90,0x90,0x9E,0x90,0xA8,0xA4,0xC4,0x80,0x00,0xFC,0xA4,0xA4,0xA4,0xA4,0xFE,0x00, + /* 0xC0C5 [?] [2951]*/ + 0x00,0x00,0xFD,0x11,0x11,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xC0C6 [?] [2952]*/ + 0x11,0x10,0x13,0x12,0xFE,0x13,0x32,0x3A,0x57,0x52,0x92,0x12,0x12,0x13,0x12,0x10, + 0x00,0x9E,0xD2,0x52,0x54,0xD4,0x58,0x54,0xD2,0x12,0x92,0x5A,0xD4,0x50,0x10,0x10, + /* 0xC0C7 [?] [2953]*/ + 0x00,0x44,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x51,0x21, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xC0C8 [?] [2954]*/ + 0x01,0x00,0x3F,0x22,0x21,0x2F,0x28,0x2F,0x28,0x2F,0x2A,0x29,0x2A,0x4C,0x48,0x80, + 0x00,0x80,0xFE,0x00,0x00,0xBE,0xA2,0xA4,0xA8,0xA4,0x22,0x22,0xAA,0xA4,0x20,0x20, + /* 0xC0C9 [?] [2955]*/ + 0x08,0x04,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x20,0x24,0x22,0x25,0x29,0x30,0x20, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xC0CA [?] [2956]*/ + 0x10,0x08,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x40,0x48,0x44,0x5A,0x62,0x41,0x02, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x84,0x84,0x14,0x08, + /* 0xC0CB [?] [2957]*/ + 0x00,0x20,0x13,0x12,0x82,0x43,0x4A,0x0A,0x13,0x12,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x80,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x40,0x44,0x28,0x10,0x88,0x06,0x00, + /* 0xC0CC [?] [2958]*/ + 0x10,0x10,0x13,0x10,0xFC,0x13,0x12,0x14,0x18,0x33,0xD0,0x10,0x10,0x11,0x52,0x24, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x44,0x40,0xFC,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xC0CD [?] [2959]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x42,0x82,0x3F,0x02,0x02,0x04,0x04,0x08,0x10,0x20, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xC0CE [?] [2960]*/ + 0x02,0x01,0x7F,0x40,0x81,0x11,0x11,0x1F,0x21,0x41,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0xFE,0x02,0x04,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xC0CF [?] [2961]*/ + 0x02,0x02,0x3F,0x02,0x02,0xFF,0x01,0x02,0x0C,0x18,0x2F,0x48,0x88,0x08,0x07,0x00, + 0x00,0x08,0xD0,0x20,0x40,0xFE,0x00,0x00,0x10,0xE0,0x00,0x08,0x08,0x08,0xF8,0x00, + /* 0xC0D0 [?] [2962]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x37,0x50,0x90,0x11,0x12,0x14,0x18,0x10,0x10,0x10, + 0x40,0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0x84,0x98,0xE0,0x82,0x82,0x7E,0x00, + /* 0xC0D1 [?] [2963]*/ + 0x10,0x10,0x10,0x11,0xFC,0x24,0x27,0x24,0x24,0x49,0x2A,0x10,0x28,0x44,0x84,0x00, + 0x40,0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0x84,0x98,0xE0,0x82,0x82,0x7E,0x00, + /* 0xC0D2 [?] [2964]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x20,0x3C,0x44,0xA8,0x10,0x28,0x44,0x82,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xC0D3 [?] [2965]*/ + 0x10,0x10,0x10,0x15,0x5B,0x54,0x50,0x90,0x11,0x12,0x15,0x29,0x25,0x45,0x41,0x81, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC0D4 [?] [2966]*/ + 0x01,0x21,0x17,0x11,0x80,0x47,0x54,0x18,0x10,0x27,0xE0,0x21,0x21,0x22,0x24,0x08, + 0x08,0x08,0xFE,0x08,0x00,0xFE,0x02,0x84,0x80,0xFC,0x84,0x04,0x04,0x04,0x28,0x10, + /* 0xC0D5 [?] [2967]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x08,0x7F,0x49,0x49,0x7F,0x08,0xFF,0x08,0x08,0x09,0x0A, + 0x20,0x20,0xA0,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0xC4,0x44,0x84,0x28,0x10, + /* 0xC0D6 [?] [2968]*/ + 0x00,0x00,0x1F,0x10,0x11,0x21,0x21,0x3F,0x01,0x09,0x09,0x11,0x21,0x41,0x05,0x02, + 0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x20,0x10,0x08,0x04,0x04,0x00,0x00, + /* 0xC0D7 [?] [2969]*/ + 0x00,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F, + 0x00,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8, + /* 0xC0D8 [?] [2970]*/ + 0x10,0x11,0x3C,0x23,0x42,0xBD,0x10,0x11,0xFC,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC, + /* 0xC0D9 [?] [2971]*/ + 0x08,0xFF,0x08,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x21,0x3F,0x21,0x3F, + 0x20,0xFE,0x20,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xC0DA [?] [2972]*/ + 0x7F,0x04,0x08,0x1F,0x28,0x48,0x8F,0x00,0x7E,0x10,0x20,0x7E,0xA3,0x22,0x3E,0x22, + 0xFC,0x00,0x00,0xF0,0x10,0x10,0xF0,0x00,0xFE,0x20,0x40,0xFC,0x44,0x44,0x7C,0x44, + /* 0xC0DB [?] [2973]*/ + 0x00,0x3F,0x21,0x3F,0x21,0x3F,0x02,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xC0DC [?] [2974]*/ + 0x13,0x12,0x12,0x23,0x22,0x62,0x63,0xA0,0x2F,0x2A,0x2A,0x2F,0x2A,0x2A,0x2F,0x28, + 0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x00,0xBE,0xAA,0xAA,0xBE,0xAA,0xAA,0xBE,0xA2, + /* 0xC0DD [?] [2975]*/ + 0x04,0x08,0x10,0x3F,0x08,0x10,0x24,0x7E,0x02,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x20,0x10,0xF8,0x10,0x20,0x48,0xFC,0x04,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xC0DE [?] [2976]*/ + 0x20,0x27,0x20,0x2F,0xF8,0x23,0x20,0x2B,0x30,0xE7,0x24,0x24,0x27,0x24,0xA4,0x47, + 0x00,0xFC,0x40,0xFE,0x42,0x58,0x40,0x58,0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC, + /* 0xC0DF [?] [2977]*/ + 0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x42,0x4A,0x85, + 0x20,0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x22,0x42,0x42,0x42,0x82,0x94,0x08, + /* 0xC0E0 [?] [2978]*/ + 0x01,0x11,0x09,0x01,0x7F,0x05,0x09,0x11,0x60,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x10,0x20,0x00,0xFC,0x40,0x20,0x10,0x08,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xC0E1 [?] [2979]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x4A,0x0A,0x12,0x13,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC0E2 [?] [2980]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x39,0x56,0x54,0x91,0x12,0x10,0x10,0x11,0x16, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xC0E3 [?] [2981]*/ + 0x10,0x13,0x12,0x12,0xFE,0x13,0x30,0x38,0x57,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x00,0xFC,0x94,0x94,0x94,0xFC,0x80,0x40,0xFE,0x80,0xF8,0x88,0x08,0x08,0x28,0x10, + /* 0xC0E4 [?] [2982]*/ + 0x00,0x40,0x20,0x20,0x01,0x02,0x14,0x10,0x23,0xE0,0x20,0x21,0x20,0x20,0x20,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xC0E5 [?] [2983]*/ + 0x00,0x3F,0x20,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x20,0x20,0x27,0x40,0x40,0x8F, + 0x00,0xFE,0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0xFC,0x40,0x40,0xFE, + /* 0xC0E6 [?] [2984]*/ + 0x03,0x3C,0x04,0x7F,0x0C,0x16,0x25,0x44,0x05,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x08,0x08,0x48,0x48,0x48,0x48,0x08,0x28,0x10,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC0E7 [?] [2985]*/ + 0x03,0x3C,0x04,0x7F,0x0C,0x16,0x25,0x44,0x05,0x11,0x1F,0x21,0x01,0xFF,0x01,0x01, + 0x08,0x08,0x48,0x48,0x48,0x48,0x08,0x28,0x10,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00, + /* 0xC0E8 [?] [2986]*/ + 0x06,0x38,0x08,0x7E,0x1C,0x2A,0x49,0x02,0x0C,0x31,0xC9,0x05,0x09,0x11,0x25,0x02, + 0x40,0x7C,0x94,0x24,0x44,0x94,0x08,0x80,0x60,0x18,0x26,0x40,0x20,0x10,0x08,0x00, + /* 0xC0E9 [?] [2987]*/ + 0x20,0x3F,0x48,0x85,0x00,0xFF,0x04,0x13,0x14,0x1F,0x01,0x7F,0x44,0x4F,0x44,0x40, + 0x40,0x7E,0x90,0x08,0x80,0xFE,0x40,0x90,0x50,0xF0,0x00,0xFC,0x44,0xE4,0x24,0x0C, + /* 0xC0EA [?] [2988]*/ + 0x00,0x45,0x29,0x11,0x29,0x49,0x89,0x09,0x18,0x28,0x49,0x88,0x08,0x08,0x53,0x20, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC0EB [?] [2989]*/ + 0x02,0x01,0xFF,0x00,0x14,0x13,0x14,0x1F,0x01,0x7F,0x42,0x44,0x4F,0x44,0x40,0x40, + 0x00,0x00,0xFE,0x00,0x50,0x90,0x50,0xF0,0x00,0xFC,0x04,0x44,0xE4,0x24,0x14,0x08, + /* 0xC0EC [?] [2990]*/ + 0x00,0x20,0x17,0x10,0x82,0x42,0x42,0x13,0x10,0x27,0xE4,0x25,0x25,0x24,0x24,0x04, + 0x80,0x40,0xFE,0x00,0xA8,0x48,0xA8,0xF8,0x40,0xFC,0x84,0x24,0xF4,0x14,0x04,0x0C, + /* 0xC0ED [?] [2991]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7D,0x10,0x10,0x11,0x10,0x1C,0xE0,0x43,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC0EE [?] [2992]*/ + 0x01,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x0F,0x00,0x00,0xFF,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00, + /* 0xC0EF [?] [2993]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xC0F0 [?] [2994]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7C,0x54,0x55,0x7C,0x00,0x1C,0xE3,0x40, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC0F1 [?] [2995]*/ + 0x20,0x10,0x10,0xF8,0x08,0x10,0x10,0x38,0x54,0x94,0x10,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xC0F2 [?] [2996]*/ + 0x04,0x04,0xFF,0x04,0x00,0x06,0x78,0x08,0x08,0xFF,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x40,0x40,0xFE,0x40,0x00,0x08,0x08,0x48,0x48,0x48,0x48,0x48,0x48,0x08,0x28,0x10, + /* 0xC0F3 [?] [2997]*/ + 0x08,0xFF,0x0A,0x02,0x3F,0x04,0x18,0x60,0x10,0x10,0x7E,0x12,0x22,0x22,0x4A,0x85, + 0x20,0xFE,0x20,0x00,0xF0,0x10,0xA0,0x40,0x20,0x20,0xFC,0x24,0x44,0x44,0x94,0x08, + /* 0xC0F4 [?] [2998]*/ + 0x01,0x01,0xFF,0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x11,0x09,0x06,0x05,0x18,0xE0, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x80,0x70,0x0E, + /* 0xC0F5 [?] [2999]*/ + 0x00,0x7F,0x04,0x04,0x3F,0x24,0x24,0x3F,0x01,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xFC,0x40,0x40,0xF8,0x48,0x48,0xF8,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC0F6 [?] [3000]*/ + 0x00,0xFF,0x00,0x00,0x3E,0x22,0x22,0x22,0x32,0x2A,0x2A,0x22,0x22,0x22,0x2A,0x24, + 0x00,0xFE,0x00,0x00,0xF8,0x88,0x88,0x88,0xC8,0xA8,0xA8,0x88,0x88,0x88,0xA8,0x90, + /* 0xC0F7 [?] [3001]*/ + 0x00,0x3F,0x20,0x20,0x2F,0x21,0x21,0x21,0x21,0x21,0x21,0x22,0x22,0x44,0x48,0x90, + 0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC0F8 [?] [3002]*/ + 0x00,0x7F,0x40,0x40,0x5F,0x48,0x48,0x4F,0x49,0x49,0x49,0x49,0x49,0x51,0x95,0x22, + 0x10,0xD0,0x10,0x10,0x7E,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x2A,0x44, + /* 0xC0F9 [?] [3003]*/ + 0x00,0x00,0xFD,0x11,0x11,0x21,0x3D,0x65,0x64,0xA4,0x24,0x24,0x3D,0x26,0x20,0x00, + 0x08,0x1C,0xE0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xC0FA [?] [3004]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x2F,0x20,0x20,0x21,0x21,0x22,0x22,0x44,0x48,0x90, + 0x00,0xFE,0x00,0x80,0x80,0x80,0xFC,0x84,0x84,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC0FB [?] [3005]*/ + 0x01,0x07,0x7C,0x04,0x04,0x04,0xFF,0x0C,0x16,0x15,0x24,0x24,0x44,0x84,0x04,0x04, + 0x04,0x84,0x04,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0xA4,0x24,0x04,0x04,0x14,0x08, + /* 0xC0FC [?] [3006]*/ + 0x10,0x17,0x10,0x20,0x27,0x64,0x64,0xA7,0x20,0x20,0x27,0x20,0x21,0x22,0x2C,0x20, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xFC,0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xC0FD [?] [3007]*/ + 0x10,0x10,0x17,0x22,0x22,0x63,0x62,0xA4,0x26,0x25,0x28,0x20,0x21,0x22,0x24,0x28, + 0x04,0x04,0xC4,0x14,0x14,0xD4,0x54,0x54,0x54,0x54,0x94,0x94,0x04,0x04,0x14,0x08, + /* 0xC0FE [?] [3008]*/ + 0x10,0x11,0x17,0x21,0x21,0x61,0x6F,0xA1,0x23,0x23,0x25,0x25,0x29,0x21,0x21,0x21, + 0x84,0xC4,0x04,0x14,0x14,0x14,0xD4,0x14,0x14,0x94,0x54,0x04,0x04,0x04,0x14,0x08, + /* 0xC1A1 [?] [3009]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x51,0x11,0x3F,0x53,0x93,0x15,0x25,0x29,0x41,0x81, + 0x80,0x40,0xFE,0x00,0xC4,0x04,0x14,0x14,0xD4,0x14,0x94,0x54,0x04,0x04,0x14,0x08, + /* 0xC1A2 [?] [3010]*/ + 0x02,0x01,0x01,0x00,0x7F,0x00,0x00,0x10,0x08,0x08,0x04,0x04,0x04,0x00,0xFF,0x00, + 0x00,0x00,0x00,0x00,0xFC,0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00,0xFE,0x00, + /* 0xC1A3 [?] [3011]*/ + 0x08,0x08,0x4A,0x2A,0x2D,0x08,0xFE,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x09,0x08, + 0x20,0x10,0x10,0x00,0xFE,0x00,0x04,0x84,0x84,0x48,0x48,0x48,0x50,0x10,0xFE,0x00, + /* 0xC1A4 [?] [3012]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x24,0x24,0x29,0x12, + 0x00,0xFE,0x00,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xC1A5 [?] [3013]*/ + 0x01,0x01,0x3F,0x01,0x01,0xFF,0x01,0x01,0x3F,0x21,0x11,0x05,0x09,0x31,0xC5,0x02, + 0x00,0x00,0xF8,0x08,0x08,0xFE,0x08,0x08,0xF8,0x08,0x90,0x60,0x20,0x18,0x06,0x00, + /* 0xC1A6 [?] [3014]*/ + 0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x50,0x20, + /* 0xC1A7 [?] [3015]*/ + 0x00,0x00,0xFB,0x20,0x21,0x21,0x21,0xF9,0x20,0x23,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x40,0x20,0xFE,0x00,0x54,0x24,0x54,0xFC,0x20,0xFE,0x42,0x92,0xFA,0x0A,0x02,0x06, + /* 0xC1A8 [?] [3016]*/ + 0x00,0x07,0xF4,0x94,0x97,0x94,0x94,0x97,0x90,0x90,0xF7,0x90,0x00,0x00,0x0F,0x00, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xC1A9 [?] [3017]*/ + 0x10,0x1F,0x11,0x21,0x21,0x6F,0x69,0xA9,0x29,0x2A,0x2A,0x2C,0x28,0x28,0x28,0x28, + 0x00,0xFE,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xA4,0x54,0x4C,0x84,0x04,0x14,0x08, + /* 0xC1AA [?] [3018]*/ + 0x00,0xFC,0x48,0x48,0x79,0x48,0x48,0x78,0x4B,0x48,0x4C,0x78,0xC8,0x08,0x09,0x0A, + 0x88,0x48,0x50,0x00,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC1AB [?] [3019]*/ + 0x08,0x08,0xFF,0x08,0x20,0x17,0x11,0x02,0x73,0x10,0x10,0x17,0x10,0x28,0x47,0x00, + 0x20,0x20,0xFE,0x20,0x80,0xFC,0x40,0x40,0xFC,0x40,0x40,0xFE,0x40,0x40,0xFE,0x00, + /* 0xC1AC [?] [3020]*/ + 0x00,0x20,0x17,0x10,0x00,0x01,0xF3,0x10,0x10,0x10,0x17,0x10,0x10,0x28,0x47,0x00, + 0x40,0x40,0xFE,0x80,0xA0,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFE,0x00, + /* 0xC1AD [?] [3021]*/ + 0x20,0x23,0x3A,0x22,0x43,0x7A,0xA2,0x22,0xFB,0x22,0x22,0x22,0x2A,0x35,0x26,0x08, + 0x20,0xFE,0x88,0x50,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50, + /* 0xC1AE [?] [3022]*/ + 0x01,0x00,0x3F,0x22,0x21,0x2F,0x21,0x27,0x21,0x3F,0x21,0x27,0x23,0x45,0x59,0x81, + 0x00,0x80,0xFE,0x08,0x10,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x30,0x28,0x26,0x20, + /* 0xC1AF [?] [3023]*/ + 0x10,0x10,0x10,0x18,0x55,0x52,0x54,0x90,0x13,0x10,0x10,0x11,0x10,0x10,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xC1B0 [?] [3024]*/ + 0x00,0x24,0x12,0x12,0x80,0x40,0x4E,0x12,0x12,0x22,0xE3,0x22,0x22,0x25,0x28,0x00, + 0x20,0x20,0x20,0xFE,0x40,0x50,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xC1B1 [?] [3025]*/ + 0x02,0x01,0x7F,0x40,0x88,0x10,0x21,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x08,0x00,0xF8,0x08,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xC1B2 [?] [3026]*/ + 0x08,0x08,0x14,0x12,0x21,0x40,0xBE,0x00,0x11,0x09,0x49,0x22,0x22,0x07,0x78,0x21, + 0x20,0x20,0x20,0x3E,0x44,0xC4,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xC1B3 [?] [3027]*/ + 0x00,0x78,0x48,0x48,0x48,0x79,0x4A,0x48,0x48,0x78,0x49,0x48,0x48,0x48,0x4B,0x98, + 0x20,0x20,0x50,0x50,0x88,0x04,0xFA,0x00,0x44,0x24,0x24,0xA8,0x88,0x10,0xFE,0x00, + /* 0xC1B4 [?] [3028]*/ + 0x20,0x22,0x39,0x21,0x40,0x78,0xA7,0x21,0xF9,0x21,0x21,0x21,0x29,0x32,0x24,0x00, + 0x10,0x10,0x10,0x7E,0x20,0x28,0x48,0x7E,0x08,0x08,0xFE,0x08,0x08,0x88,0x7E,0x00, + /* 0xC1B5 [?] [3029]*/ + 0x02,0x01,0xFF,0x04,0x14,0x14,0x24,0x44,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x44,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xC1B6 [?] [3030]*/ + 0x10,0x10,0x17,0x10,0x54,0x5B,0x51,0x92,0x13,0x10,0x11,0x29,0x26,0x44,0x40,0x80, + 0x40,0x40,0xFC,0x80,0x80,0xE0,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xC1B7 [?] [3031]*/ + 0x10,0x10,0x27,0x20,0x48,0xFB,0x11,0x22,0x43,0xF8,0x41,0x01,0x1A,0xE4,0x40,0x00, + 0x40,0x40,0xFC,0x80,0x80,0xE0,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xC1B8 [?] [3032]*/ + 0x10,0x10,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xC1B9 [?] [3033]*/ + 0x00,0x40,0x2F,0x20,0x00,0x03,0x12,0x12,0x23,0xE0,0x22,0x22,0x24,0x28,0x21,0x00, + 0x80,0x40,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xC1BA [?] [3034]*/ + 0x00,0x23,0x10,0x82,0x52,0x24,0xE1,0x22,0x25,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xF0,0x90,0x94,0x92,0x92,0x10,0x50,0x20,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC1BB [?] [3035]*/ + 0x00,0x23,0x90,0x42,0x12,0xE5,0x22,0x24,0x11,0x09,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xF0,0x90,0x94,0x92,0x12,0x50,0x20,0x10,0x20,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xC1BC [?] [3036]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x22,0x21,0x20,0x20,0x24,0x28,0x30, + 0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x08,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xC1BD [?] [3037]*/ + 0x00,0xFF,0x04,0x04,0x04,0x7F,0x44,0x44,0x44,0x4A,0x4A,0x51,0x42,0x40,0x40,0x40, + 0x00,0xFE,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0xA4,0x94,0x14,0x04,0x04,0x14,0x08, + /* 0xC1BE [?] [3038]*/ + 0x20,0x23,0x20,0xFC,0x40,0x53,0x92,0xFE,0x12,0x12,0x1E,0xF3,0x52,0x12,0x12,0x12, + 0x00,0xFE,0x50,0x50,0x50,0xFE,0x52,0x52,0x52,0xAA,0xA6,0x02,0x02,0x02,0x0A,0x04, + /* 0xC1BF [?] [3039]*/ + 0x00,0x1F,0x10,0x1F,0x10,0xFF,0x00,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x1F,0x01,0x7F, + 0x00,0xF0,0x10,0xF0,0x10,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF0,0x00,0xFC, + /* 0xC1C0 [?] [3040]*/ + 0x00,0x00,0x7B,0x48,0x48,0x49,0x49,0x79,0x49,0x49,0x48,0x48,0x79,0x4A,0x00,0x00, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xC1C1 [?] [3041]*/ + 0x02,0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x8F,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xE4,0x20,0x20,0x22,0x22,0x1E, + /* 0xC1C2 [?] [3042]*/ + 0x00,0x20,0x13,0x10,0x00,0x01,0xF1,0x11,0x11,0x11,0x10,0x14,0x19,0x12,0x00,0x00, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xC1C3 [?] [3043]*/ + 0x20,0x20,0x27,0x20,0xF5,0x22,0x27,0x2A,0x33,0xE2,0x23,0x20,0x22,0x24,0xA9,0x40, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xC1C4 [?] [3044]*/ + 0x00,0xFC,0x4B,0x4A,0x7A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4F,0x7A,0xC8,0x08,0x09,0x0A, + 0x00,0x80,0x1E,0x52,0x52,0x52,0x52,0x52,0x52,0xD2,0x5A,0x54,0x90,0x90,0x10,0x10, + /* 0xC1C5 [?] [3045]*/ + 0x10,0x10,0x17,0x20,0x25,0x62,0x67,0xAA,0x23,0x22,0x23,0x20,0x22,0x24,0x29,0x20, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xC1C6 [?] [3046]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x30,0x50,0x90,0x10,0x20,0x20,0x41,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xC1C7 [?] [3047]*/ + 0x20,0x20,0x27,0x20,0xAD,0xB2,0xA7,0xAA,0x23,0x22,0x23,0x20,0x52,0x4C,0x49,0x80, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xC1C8 [?] [3048]*/ + 0x01,0x7F,0x40,0xBC,0x24,0x14,0x25,0x06,0x18,0xE3,0x0C,0x31,0x06,0x38,0x07,0x38, + 0x00,0xFE,0x02,0xFC,0x48,0x28,0x48,0xC0,0x30,0x0E,0x40,0x80,0x30,0xC0,0x00,0x00, + /* 0xC1C9 [?] [3049]*/ + 0x00,0x23,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x11,0x10,0x28,0x47,0x00, + 0x00,0xF8,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0xFE,0x00, + /* 0xC1CA [?] [3050]*/ + 0x00,0x20,0x17,0x10,0x85,0x42,0x47,0x1A,0x13,0x22,0xE3,0x20,0x22,0x24,0x29,0x00, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xC1CB [?] [3051]*/ + 0x00,0x7F,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC1CC [?] [3052]*/ + 0x20,0x27,0x24,0x27,0xFC,0x27,0x21,0x2B,0x35,0xE0,0x23,0x2C,0x23,0x22,0xA3,0x42, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06,0xF8,0x08,0xF8,0x08, + /* 0xC1CD [?] [3053]*/ + 0x20,0x20,0x3B,0x20,0x42,0x79,0xA3,0x25,0xF9,0x21,0x21,0x20,0x29,0x32,0x24,0x00, + 0x20,0x20,0xFE,0x50,0x8A,0x04,0xFE,0x04,0xFC,0x04,0xFC,0x20,0x24,0x22,0xA2,0x40, + /* 0xC1CE [?] [3054]*/ + 0x00,0x3F,0x20,0x2F,0x29,0x25,0x29,0x21,0x26,0x38,0x23,0x2C,0x41,0x4E,0x81,0x0E, + 0x80,0xFE,0x00,0x7C,0x24,0x14,0xA4,0x60,0x18,0x86,0x20,0x40,0x88,0x30,0xC0,0x00, + /* 0xC1CF [?] [3055]*/ + 0x08,0x08,0x4A,0x2A,0x2C,0x08,0xFE,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08, + 0x08,0x88,0x48,0x48,0x08,0x88,0x48,0x48,0x08,0x0E,0xF8,0x08,0x08,0x08,0x08,0x08, + /* 0xC1D0 [?] [3056]*/ + 0x00,0x7F,0x08,0x08,0x1F,0x11,0x21,0x21,0x52,0x8A,0x04,0x04,0x08,0x10,0x20,0x40, + 0x04,0x84,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xC1D1 [?] [3057]*/ + 0x00,0x7F,0x08,0x1F,0x21,0x52,0x0C,0x30,0xC2,0x01,0xFF,0x04,0x0C,0x34,0xC5,0x06, + 0x04,0x84,0x24,0x24,0x24,0x24,0x24,0x04,0x0C,0x00,0xFE,0x88,0x50,0x20,0x18,0x06, + /* 0xC1D2 [?] [3058]*/ + 0x00,0x7F,0x08,0x08,0x1F,0x21,0x51,0x0A,0x04,0x08,0x30,0xC0,0x24,0x22,0x42,0x80, + 0x04,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x14,0x08,0x00,0x88,0x44,0x44,0x04, + /* 0xC1D3 [?] [3059]*/ + 0x01,0x11,0x11,0x21,0x41,0x01,0x0E,0xF1,0x01,0x3F,0x02,0x02,0x04,0x08,0x10,0x60, + 0x00,0x10,0x08,0x24,0x44,0x80,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC1D4 [?] [3060]*/ + 0x00,0x44,0x28,0x13,0x28,0x48,0x8F,0x08,0x19,0x29,0x49,0x89,0x09,0x09,0x51,0x21, + 0x88,0x88,0x88,0xFE,0x88,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xC1D5 [?] [3061]*/ + 0x01,0x01,0xF9,0x21,0x27,0x21,0x21,0xFB,0x23,0x25,0x25,0x39,0xE1,0x41,0x01,0x01, + 0x10,0x10,0x10,0x10,0xBC,0x10,0x10,0x38,0xB8,0x54,0x54,0x92,0x10,0x10,0x10,0x10, + /* 0xC1D6 [?] [3062]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x38,0x54,0x50,0x91,0x12,0x14,0x10,0x10,0x10, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x70,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20,0x20,0x20, + /* 0xC1D7 [?] [3063]*/ + 0x00,0x01,0xF8,0x23,0x20,0x41,0x7A,0x49,0xC9,0x49,0x4A,0x4D,0x78,0x49,0x02,0x04, + 0x20,0x24,0xA8,0xFE,0xA8,0x24,0x22,0x04,0x04,0xDE,0x44,0x54,0x9E,0x04,0x04,0x04, + /* 0xC1D8 [?] [3064]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC9,0x08,0x08, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x20,0x20,0xFC,0x30,0x68,0xA4,0x22,0x20,0x20, + /* 0xC1D9 [?] [3065]*/ + 0x08,0x08,0x08,0x49,0x49,0x4A,0x4C,0x48,0x49,0x49,0x49,0x49,0x49,0x09,0x09,0x08, + 0x80,0x80,0x80,0xFE,0x40,0x20,0x20,0x00,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04,0x00, + /* 0xC1DA [?] [3066]*/ + 0x08,0x08,0x14,0x12,0x21,0x48,0x84,0x04,0x7F,0x01,0x22,0x14,0x08,0x04,0x04,0x00, + 0x00,0x7C,0x44,0x48,0x48,0xD0,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xC1DB [?] [3067]*/ + 0x40,0x41,0x78,0x8B,0x10,0xF9,0xAA,0xA9,0xF9,0xA9,0xAA,0xFD,0x00,0x19,0xE2,0x44, + 0x20,0x24,0xA8,0xFE,0xA8,0x24,0x22,0x04,0x04,0xDE,0x44,0x54,0x9E,0x04,0x04,0x04, + /* 0xC1DC [?] [3068]*/ + 0x01,0x21,0x11,0x11,0x87,0x41,0x41,0x13,0x13,0x25,0xE5,0x29,0x21,0x21,0x21,0x01, + 0x10,0x10,0x10,0x10,0xBC,0x10,0x10,0x38,0xB8,0x54,0x54,0x92,0x10,0x10,0x10,0x10, + /* 0xC1DD [?] [3069]*/ + 0x00,0x4F,0x20,0x27,0x04,0x05,0x15,0x15,0x24,0xE7,0x20,0x23,0x20,0x2F,0x22,0x04, + 0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xF4,0x04,0xFC,0x00,0xF8,0x00,0xFE,0x48,0xC4, + /* 0xC1DE [?] [3070]*/ + 0x08,0x13,0x30,0x50,0x97,0x10,0x10,0x13,0x00,0x1F,0x10,0x11,0x11,0x02,0x0C,0x30, + 0x38,0xC0,0x40,0x40,0xFC,0x40,0x40,0xF8,0x00,0xF0,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xC1DF [?] [3071]*/ + 0x02,0x01,0x7F,0x08,0x04,0x03,0x0C,0x30,0xC0,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFC,0x20,0x40,0x80,0x60,0x18,0x06,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xC1E0 [?] [3072]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x14,0x10,0x1B,0x30,0xD0,0x11,0x10,0x10,0x50,0x20, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xC1E1 [?] [3073]*/ + 0x00,0x00,0xFC,0x10,0x10,0x11,0x12,0x7C,0x11,0x10,0x10,0x10,0x1C,0xE0,0x40,0x00, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xC1E2 [?] [3074]*/ + 0x08,0x08,0xFF,0x08,0x01,0x3F,0x01,0xFF,0x10,0x22,0x47,0x08,0x14,0x03,0x1C,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0xFE,0x10,0x08,0xE4,0x20,0x40,0x80,0x70,0x0E, + /* 0xC1E3 [?] [3075]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x02,0x0C,0x32,0xC1,0x1F,0x00,0x06,0x01,0x00, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x80,0x60,0x18,0x06,0xE0,0x20,0x40,0x80,0x40, + /* 0xC1E4 [?] [3076]*/ + 0x10,0x10,0x50,0x5E,0x50,0x51,0xFE,0x00,0x93,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x02, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xC1E5 [?] [3077]*/ + 0x20,0x20,0x38,0x20,0x41,0x7A,0xA4,0x20,0xFB,0x20,0x20,0x21,0x28,0x30,0x20,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xC1E6 [?] [3078]*/ + 0x08,0x08,0x08,0x10,0x11,0x32,0x34,0x50,0x93,0x10,0x10,0x11,0x10,0x10,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xC1E7 [?] [3079]*/ + 0x44,0x24,0x28,0xFC,0x10,0x11,0x7E,0x10,0x11,0xFC,0x10,0x10,0x20,0x20,0x40,0x80, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xC1E8 [?] [3080]*/ + 0x00,0x40,0x23,0x20,0x00,0x07,0x11,0x12,0x24,0xE1,0x23,0x24,0x20,0x20,0x23,0x0C, + 0x40,0x40,0xF8,0x40,0x40,0xFE,0x10,0x88,0x84,0xF0,0x10,0xA0,0x40,0xA0,0x10,0x0C, + /* 0xC1E9 [?] [3081]*/ + 0x00,0x3F,0x00,0x00,0x1F,0x00,0x00,0x3F,0x01,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x10,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xC1EA [?] [3082]*/ + 0x00,0x78,0x49,0x50,0x50,0x63,0x50,0x49,0x4A,0x48,0x69,0x52,0x40,0x40,0x41,0x46, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xC1EB [?] [3083]*/ + 0x10,0x10,0x10,0x10,0x54,0x55,0x56,0x54,0x55,0x54,0x54,0x5C,0x64,0x00,0x00,0x00, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xC1EC [?] [3084]*/ + 0x10,0x11,0x28,0x24,0x43,0x91,0x09,0x01,0xFD,0x05,0x09,0x51,0x20,0x10,0x11,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xC1ED [?] [3085]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x02,0x02,0x7F,0x02,0x04,0x04,0x08,0x10,0x20,0x40, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC1EE [?] [3086]*/ + 0x01,0x01,0x02,0x04,0x0A,0x11,0x21,0xC0,0x1F,0x00,0x00,0x04,0x02,0x01,0x00,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0xF0,0x10,0x20,0x40,0x80,0x00,0x80,0x80, + /* 0xC1EF [?] [3087]*/ + 0x00,0x27,0x14,0x15,0x84,0x45,0x46,0x10,0x17,0x24,0xE4,0x27,0x24,0x24,0x27,0x04, + 0x80,0x7C,0x24,0x24,0xA4,0x54,0x48,0x80,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x04, + /* 0xC1F0 [?] [3088]*/ + 0x00,0x00,0xFB,0x20,0x20,0x21,0x23,0xF8,0x21,0x21,0x21,0x39,0xE2,0x42,0x04,0x08, + 0x40,0x20,0xFC,0x40,0x90,0x08,0xFC,0x04,0x50,0x50,0x50,0x50,0x50,0x52,0x52,0x0E, + /* 0xC1F1 [?] [3089]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x33,0x38,0x57,0x52,0x92,0x13,0x12,0x12,0x13,0x12, + 0x40,0xBE,0x12,0x92,0x52,0xAA,0x24,0x40,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xC1F2 [?] [3090]*/ + 0x00,0x00,0xFB,0x20,0x20,0x41,0x7B,0x48,0xC9,0x49,0x49,0x49,0x7A,0x4A,0x04,0x08, + 0x40,0x20,0xFC,0x40,0x90,0x08,0xFC,0x04,0x50,0x50,0x50,0x50,0x50,0x52,0x52,0x0E, + /* 0xC1F3 [?] [3091]*/ + 0x20,0x23,0x22,0x3A,0x4A,0x52,0x83,0x20,0x23,0x22,0x22,0x23,0x2A,0x32,0x23,0x02, + 0x40,0xBE,0x12,0x92,0x52,0xAA,0x24,0x40,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xC1F4 [?] [3092]*/ + 0x06,0x78,0x40,0x48,0x44,0x5A,0x61,0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x20, + 0x00,0xFC,0x44,0x44,0x44,0x94,0x08,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC1F5 [?] [3093]*/ + 0x10,0x08,0x08,0xFF,0x02,0x42,0x22,0x14,0x14,0x08,0x08,0x14,0x24,0x42,0x82,0x00, + 0x04,0x04,0x04,0xA4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xC1F6 [?] [3094]*/ + 0x00,0x00,0x1F,0x10,0x97,0x54,0x55,0x15,0x36,0x50,0x97,0x14,0x27,0x24,0x47,0x84, + 0x80,0x40,0xFE,0x80,0x7C,0x24,0xA4,0x54,0x48,0x80,0xFC,0x44,0xFC,0x44,0xFC,0x04, + /* 0xC1F7 [?] [3095]*/ + 0x00,0x20,0x17,0x10,0x81,0x42,0x47,0x10,0x10,0x22,0xE2,0x22,0x22,0x22,0x24,0x08, + 0x80,0x40,0xFE,0x80,0x10,0x08,0xFC,0x04,0x00,0x48,0x48,0x48,0x48,0x4A,0x4A,0x46, + /* 0xC1F8 [?] [3096]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x32,0x3A,0x56,0x52,0x93,0x12,0x10,0x10,0x11,0x12, + 0x00,0x80,0x1E,0x52,0x52,0x52,0x52,0x52,0x52,0xD2,0x5A,0x54,0x90,0x90,0x10,0x10, + /* 0xC1F9 [?] [3097]*/ + 0x02,0x01,0x00,0x00,0x00,0xFF,0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x00, + 0x00,0x00,0x80,0x80,0x00,0xFE,0x00,0x00,0x40,0x20,0x10,0x08,0x08,0x04,0x04,0x00, + /* 0xC1FA [?] [3098]*/ + 0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x11,0x22,0x44,0x80, + 0x20,0x10,0x10,0x00,0xFE,0x80,0x88,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xC1FB [?] [3099]*/ + 0x04,0x04,0xFF,0x09,0x11,0x66,0x00,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x00,0x00, + 0x80,0x40,0xFE,0x40,0x84,0xFC,0x00,0xFC,0x20,0xE0,0x20,0xE0,0x3E,0xE0,0x20,0x20, + /* 0xC1FC [?] [3100]*/ + 0x00,0x00,0x78,0x48,0x4B,0x48,0x48,0x48,0x48,0x49,0x79,0x49,0x02,0x02,0x04,0x08, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0x28,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xC1FD [?] [3101]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x04,0x7F,0x04,0x04,0x08,0x08,0x10,0x23,0x4C,0x80, + 0x40,0x40,0x7E,0x90,0x08,0x40,0x20,0xFC,0x80,0x88,0x90,0xA0,0xC2,0x82,0x82,0x7E, + /* 0xC1FE [?] [3102]*/ + 0x01,0x7F,0x48,0x91,0x79,0x4A,0x50,0x61,0x56,0x49,0x4A,0x6B,0x54,0x43,0x40,0x47, + 0x00,0xFE,0x22,0x14,0xF0,0x90,0x60,0x98,0x06,0xF0,0x40,0xF8,0x40,0xF8,0x40,0xFC, + /* 0xC2A1 [?] [3103]*/ + 0x00,0x79,0x4A,0x55,0x50,0x63,0x5C,0x4B,0x48,0x4A,0x6B,0x54,0x43,0x40,0x4F,0x40, + 0x80,0xF8,0x08,0x10,0xE0,0x18,0x06,0xF8,0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00, + /* 0xC2A2 [?] [3104]*/ + 0x04,0x04,0xFF,0x09,0x11,0x11,0x23,0x4D,0x80,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x40,0x20,0xFE,0x10,0x20,0xC0,0x04,0x04,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xC2A3 [?] [3105]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x14,0x18,0x30,0xD1,0x11,0x11,0x12,0x12,0x54,0x28, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0x28,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xC2A4 [?] [3106]*/ + 0x00,0x7C,0x44,0x48,0x4B,0x50,0x48,0x48,0x44,0x45,0x45,0x69,0x52,0x42,0x44,0x48, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0x28,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xC2A5 [?] [3107]*/ + 0x20,0x21,0x20,0x20,0xFB,0x20,0x21,0x72,0x68,0xA7,0xA0,0x21,0x21,0x20,0x21,0x26, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xC2A6 [?] [3108]*/ + 0x01,0x11,0x09,0xFF,0x05,0x09,0x31,0xC0,0x02,0xFF,0x04,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0x10,0x20,0xFE,0x40,0x20,0x18,0x06,0x00,0xFE,0x20,0x20,0x40,0x80,0x70,0x08, + /* 0xC2A7 [?] [3109]*/ + 0x10,0x11,0x10,0x10,0xFB,0x10,0x11,0x1A,0x30,0xD7,0x10,0x11,0x11,0x10,0x51,0x26, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xC2A8 [?] [3110]*/ + 0x20,0x3F,0x48,0x85,0x11,0x09,0x7F,0x05,0x19,0x61,0x04,0xFF,0x08,0x1E,0x03,0x3C, + 0x40,0x7E,0x90,0x08,0x10,0x20,0xFC,0x40,0x30,0x0C,0x00,0xFE,0x20,0x40,0xC0,0x38, + /* 0xC2A9 [?] [3111]*/ + 0x00,0x47,0x24,0x24,0x07,0x84,0x47,0x54,0x17,0x26,0xE6,0x2A,0x2A,0x32,0x22,0x02, + 0x00,0xFE,0x02,0x02,0xFE,0x00,0xFE,0x20,0xFE,0x22,0xAA,0x22,0xAA,0x22,0x2A,0x04, + /* 0xC2AA [?] [3112]*/ + 0x00,0x7B,0x48,0x50,0x52,0x62,0x52,0x4A,0x4A,0x4A,0x6A,0x52,0x42,0x42,0x43,0x40, + 0x00,0xFE,0x20,0x20,0xFC,0xA4,0xA4,0xA4,0xD4,0x84,0x84,0x94,0x88,0x00,0xFE,0x00, + /* 0xC2AB [?] [3113]*/ + 0x08,0x08,0xFF,0x08,0x09,0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x40,0x40,0x80, + 0x20,0x20,0xFE,0x20,0x20,0x80,0xF8,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, + /* 0xC2AC [?] [3114]*/ + 0x01,0x01,0x01,0x01,0x01,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, + /* 0xC2AD [?] [3115]*/ + 0x10,0x10,0x1E,0x10,0x10,0x7C,0x44,0x44,0x44,0x7C,0x44,0x40,0x40,0x40,0x80,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xC2AE [?] [3116]*/ + 0x01,0x00,0x3F,0x21,0x20,0x27,0x24,0x24,0x24,0x27,0x24,0x24,0x44,0x48,0x88,0x10, + 0x00,0x80,0xFE,0x00,0x80,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, + /* 0xC2AF [?] [3117]*/ + 0x10,0x10,0x10,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x29,0x26,0x42,0x44,0x88, + 0x80,0x40,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC2B0 [?] [3118]*/ + 0x20,0x20,0x20,0x23,0xFA,0x22,0x23,0x2A,0x32,0xE2,0x23,0x22,0x24,0x24,0xA9,0x42, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x40,0x40,0xFC,0x44,0x84,0x84,0x14,0x08, + /* 0xC2B1 [?] [3119]*/ + 0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x24,0x22,0x21,0x22,0x24,0x28,0x20,0x3F,0x20, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x48,0x88,0x08,0x88,0x48,0x28,0x08,0xF8,0x08, + /* 0xC2B2 [?] [3120]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x21,0x20,0x21,0x2F,0x21,0x21,0x42,0x44,0x98, + 0x00,0xF8,0x00,0xFC,0x04,0x60,0x88,0x08,0xF8,0x00,0xF8,0x08,0x08,0x08,0x50,0x20, + /* 0xC2B3 [?] [3121]*/ + 0x08,0x1F,0x20,0x7F,0xA1,0x3F,0x21,0x3F,0x00,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F, + 0x00,0xE0,0x20,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xC2B4 [?] [3122]*/ + 0x08,0x08,0x7E,0x1C,0x2A,0xC9,0x08,0x3F,0x22,0x3F,0x22,0x3F,0x28,0x2F,0x48,0x8F, + 0x20,0x20,0xFC,0x70,0xA8,0x26,0xA0,0xFC,0x40,0xF8,0x48,0xF8,0x44,0x78,0x42,0x3E, + /* 0xC2B5 [?] [3123]*/ + 0x00,0x01,0xF8,0x20,0x21,0x40,0x78,0x4B,0xC8,0x4A,0x49,0x48,0x79,0x4A,0x00,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x20,0x22,0x74,0xA8,0x24,0x22,0xA0,0x40, + /* 0xC2B6 [?] [3124]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x7C,0x45,0x7C,0x11,0x5C,0x50,0x5C,0xE0, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x40,0xF8,0x48,0x30,0xCE,0x00,0xF8,0x88,0xF8, + /* 0xC2B7 [?] [3125]*/ + 0x00,0x7C,0x44,0x44,0x45,0x7C,0x10,0x10,0x11,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x00, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xC2B8 [?] [3126]*/ + 0x00,0x7C,0x44,0x54,0x55,0x54,0x54,0x54,0x55,0x54,0x54,0x10,0x28,0x24,0x44,0x80, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xC2B9 [?] [3127]*/ + 0x01,0x00,0x3F,0x22,0x22,0x3F,0x22,0x22,0x3F,0x28,0x28,0x2F,0x48,0x48,0x8B,0x0C, + 0x00,0x80,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x40,0x44,0x58,0x60,0x44,0x44,0x3C, + /* 0xC2BA [?] [3128]*/ + 0x00,0x27,0x14,0x14,0x84,0x47,0x41,0x11,0x11,0x25,0xE5,0x25,0x25,0x25,0x2E,0x00, + 0x10,0x90,0xBC,0xA4,0xC4,0xA8,0x10,0x28,0x46,0xC0,0x3C,0x24,0x24,0xA4,0x3C,0x24, + /* 0xC2BB [?] [3129]*/ + 0x40,0x21,0x20,0xF8,0x11,0x10,0x20,0x33,0x68,0xAA,0x21,0x20,0x21,0x22,0x20,0x20, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x20,0x22,0x74,0xA8,0x24,0x22,0xA0,0x40, + /* 0xC2BC [?] [3130]*/ + 0x00,0x3F,0x00,0x00,0x1F,0x00,0x00,0xFF,0x01,0x21,0x11,0x05,0x09,0x31,0xC5,0x02, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xFE,0x00,0x08,0x90,0x60,0x20,0x18,0x06,0x00, + /* 0xC2BD [?] [3131]*/ + 0x00,0x7C,0x44,0x49,0x48,0x50,0x48,0x4B,0x44,0x44,0x45,0x69,0x51,0x41,0x41,0x40, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xC2BE [?] [3132]*/ + 0x00,0x77,0x11,0x55,0x33,0x55,0x0C,0x33,0xC4,0x18,0x62,0x0C,0x71,0x06,0x18,0xE0, + 0x10,0x14,0x12,0x10,0x16,0x78,0x12,0x12,0x92,0x14,0x14,0x88,0x1A,0x2A,0x46,0x82, + /* 0xC2BF [?] [3133]*/ + 0x00,0xF8,0x08,0x48,0x48,0x48,0x48,0x7C,0x04,0x04,0x1C,0xE4,0x44,0x05,0x29,0x12, + 0x40,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84,0x80,0x80,0x80,0x80,0x00,0x00,0x00, + /* 0xC2C0 [?] [3134]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2C1 [?] [3135]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x10,0x10,0xFC,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x00,0x00,0xFE,0x02,0x02,0x02,0x02,0xFE,0x02, + /* 0xC2C2 [?] [3136]*/ + 0x10,0x13,0x12,0x22,0x22,0x62,0x63,0xA0,0x20,0x27,0x24,0x24,0x24,0x24,0x27,0x24, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC2C3 [?] [3137]*/ + 0x20,0x10,0x10,0x01,0xFE,0x20,0x20,0x3C,0x24,0x24,0x24,0x24,0x24,0x44,0x54,0x88, + 0x80,0x80,0xFE,0x00,0x0C,0xF0,0x90,0x90,0x92,0x94,0x88,0x88,0x84,0xA4,0xC2,0x80, + /* 0xC2C4 [?] [3138]*/ + 0x3F,0x20,0x3F,0x21,0x29,0x32,0x21,0x25,0x29,0x39,0x29,0x28,0x49,0x4A,0x88,0x0B, + 0xFC,0x04,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFC,0x88,0x70,0x8E, + /* 0xC2C5 [?] [3139]*/ + 0x3F,0x20,0x3F,0x24,0x22,0x3F,0x22,0x24,0x28,0x21,0x3F,0x22,0x47,0x40,0x83,0x0C, + 0xFC,0x04,0xFC,0x90,0xA0,0xFC,0xA0,0x90,0x88,0x00,0xFC,0x10,0x20,0xC0,0x30,0x08, + /* 0xC2C6 [?] [3140]*/ + 0x10,0x11,0x20,0x20,0x4B,0xF8,0x11,0x22,0x40,0xFB,0x40,0x01,0x19,0xE0,0x41,0x06, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xC2C7 [?] [3141]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x21,0x20,0x20,0x20,0x20,0x2A,0x4A,0x52,0x81, + 0x00,0xF8,0x00,0xFC,0x04,0x60,0x88,0x08,0xF8,0x00,0x80,0x44,0x42,0x12,0x10,0xF0, + /* 0xC2C8 [?] [3142]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x7F,0x00,0x3F,0x00,0xFF,0x24,0x15,0x24,0x4C, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x90,0x90,0x90,0xF2,0x8A,0x0A,0x86,0x42, + /* 0xC2C9 [?] [3143]*/ + 0x08,0x08,0x13,0x20,0x4F,0x08,0x13,0x30,0x50,0x93,0x10,0x10,0x17,0x10,0x10,0x10, + 0x40,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x40,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40, + /* 0xC2CA [?] [3144]*/ + 0x02,0x01,0x7F,0x02,0x44,0x2F,0x11,0x22,0x4F,0x00,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0xFC,0x00,0x44,0x88,0x10,0x48,0xE4,0x20,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xC2CB [?] [3145]*/ + 0x00,0x20,0x10,0x17,0x84,0x44,0x47,0x14,0x14,0x24,0xE4,0x24,0x25,0x29,0x29,0x12, + 0x40,0x7C,0x40,0xFE,0x42,0x70,0xC4,0x44,0x3C,0x20,0x10,0x54,0x42,0x42,0x4A,0x38, + /* 0xC2CC [?] [3146]*/ + 0x10,0x11,0x20,0x20,0x49,0xF8,0x10,0x23,0x40,0xFA,0x41,0x00,0x19,0xE2,0x40,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x20,0x22,0x74,0xA8,0x24,0x22,0xA0,0x40, + /* 0xC2CD [?] [3147]*/ + 0x02,0x01,0xFF,0x04,0x14,0x14,0x24,0x44,0x01,0x01,0x21,0x21,0x21,0x21,0x3F,0x00, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x44,0x00,0x00,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2CE [?] [3148]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x44,0x00,0x3F,0x01,0x3F,0x01,0x7F,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0xF0,0x00,0x00,0xF8,0x00,0xFC,0x00,0x00,0x00, + /* 0xC2CF [?] [3149]*/ + 0x02,0x01,0xFF,0x04,0x14,0x14,0x24,0x44,0x00,0x3F,0x00,0x01,0xFF,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x44,0x00,0xE0,0x80,0x00,0xFE,0x00,0x00,0x00, + /* 0xC2D0 [?] [3150]*/ + 0x00,0x40,0x2F,0x20,0x02,0x82,0x44,0x50,0x10,0x27,0xE0,0x21,0x22,0x24,0x28,0x00, + 0x80,0x40,0xFE,0xA0,0xA8,0xA4,0xA4,0x40,0x40,0xFE,0xE0,0x50,0x48,0x44,0x42,0x40, + /* 0xC2D1 [?] [3151]*/ + 0x0C,0x70,0x44,0x44,0x64,0x54,0x54,0x44,0x44,0x4C,0x74,0x04,0x08,0x08,0x10,0x20, + 0x00,0xFC,0x84,0x84,0xA4,0x94,0x94,0x84,0x84,0x84,0xA8,0x90,0x80,0x80,0x80,0x80, + /* 0xC2D2 [?] [3152]*/ + 0x04,0x0E,0x38,0x08,0x08,0xFF,0x08,0x08,0x3E,0x22,0x22,0x22,0x22,0x3E,0x22,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xC2D3 [?] [3153]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x11,0x15,0x19,0x30,0xD1,0x11,0x12,0x14,0x50,0x20, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xC2D4 [?] [3154]*/ + 0x00,0x00,0xF8,0xA9,0xAB,0xAC,0xF8,0xA8,0xA9,0xAA,0xAD,0xF9,0x89,0x01,0x01,0x01, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2D5 [?] [3155]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x14,0x11,0x19,0x31,0xD1,0x11,0x11,0x11,0x50,0x20, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2D6 [?] [3156]*/ + 0x20,0x20,0x20,0xFC,0x41,0x52,0x94,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x11,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2D7 [?] [3157]*/ + 0x08,0x08,0x08,0x10,0x11,0x32,0x34,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2D8 [?] [3158]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x20,0xC8,0x08,0x08,0x0F,0x08,0x08,0x08,0x07,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0x30,0xC0,0x00,0x08,0x08,0x08,0xF8,0x00, + /* 0xC2D9 [?] [3159]*/ + 0x00,0x20,0x10,0x10,0x81,0x42,0x44,0x11,0x11,0x21,0xE1,0x21,0x21,0x21,0x20,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2DA [?] [3160]*/ + 0x10,0x10,0x20,0x20,0x49,0xFA,0x14,0x21,0x41,0xF9,0x41,0x01,0x19,0xE1,0x40,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2DB [?] [3161]*/ + 0x00,0x20,0x10,0x10,0x01,0x02,0xF4,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0x10,0x20,0x40,0x80,0x00,0x04,0x04,0xFC,0x00, + /* 0xC2DC [?] [3162]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x24,0x24,0x3F,0x02,0x07,0x08,0x34,0x02,0x01,0x0E,0x70, + 0x20,0xFE,0x20,0x00,0xF8,0x48,0x48,0xF8,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xC2DD [?] [3163]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x54,0x54,0x7D,0x50,0x10,0x17,0x1C,0xE5,0x42,0x00, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x40,0x88,0xF0,0x20,0x44,0xFE,0x22,0x24,0x22,0x60, + /* 0xC2DE [?] [3164]*/ + 0x00,0x3F,0x24,0x24,0x24,0x3F,0x02,0x04,0x0F,0x10,0x68,0x04,0x02,0x03,0x1C,0xE0, + 0x00,0xF8,0x48,0x48,0x48,0xF8,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xC2DF [?] [3165]*/ + 0x00,0x47,0x24,0x24,0x07,0x00,0xE1,0x22,0x25,0x20,0x20,0x21,0x2E,0x50,0x8F,0x00, + 0x00,0xFC,0xA4,0xA4,0xFC,0x80,0xF8,0x08,0x10,0xA0,0x40,0x80,0x00,0x00,0xFE,0x00, + /* 0xC2E0 [?] [3166]*/ + 0x20,0x23,0x3A,0x22,0x42,0x7B,0xA0,0x20,0xF8,0x21,0x22,0x20,0x28,0x30,0x21,0x06, + 0x00,0xFE,0x52,0x52,0x52,0xFE,0x20,0x40,0xFC,0x04,0x88,0x50,0x20,0x40,0x80,0x00, + /* 0xC2E1 [?] [3167]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x24,0x24,0x3F,0x02,0x07,0x08,0x34,0x02,0x01,0x0E,0x70, + 0x40,0x7E,0x90,0x08,0xF8,0x48,0x48,0xF8,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xC2E2 [?] [3168]*/ + 0x00,0xF9,0x09,0x49,0x49,0x49,0x48,0x7C,0x05,0x04,0x1C,0xE7,0x44,0x05,0x2A,0x10, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x40,0x88,0xF0,0x20,0x44,0xFE,0x22,0x24,0x22,0x60, + /* 0xC2E3 [?] [3169]*/ + 0x20,0x11,0x01,0xF9,0x09,0x11,0x15,0x39,0x54,0x93,0x10,0x10,0x11,0x12,0x10,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xC2E4 [?] [3170]*/ + 0x08,0x08,0xFF,0x08,0x20,0x10,0x11,0x82,0x48,0x49,0x16,0xE1,0x21,0x21,0x21,0x21, + 0x20,0x20,0xFE,0x20,0x80,0xF8,0x08,0x90,0x60,0x98,0x06,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC2E5 [?] [3171]*/ + 0x00,0x20,0x11,0x12,0x85,0x40,0x40,0x10,0x13,0x2C,0xE3,0x22,0x22,0x22,0x23,0x02, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2E6 [?] [3172]*/ + 0x00,0xF8,0x08,0x49,0x4B,0x4C,0x48,0x7C,0x05,0x06,0x1D,0xE5,0x45,0x05,0x29,0x11, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2E7 [?] [3173]*/ + 0x10,0x10,0x20,0x21,0x4B,0xFC,0x10,0x20,0x41,0xFA,0x45,0x01,0x19,0xE1,0x41,0x01, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC2E8 [?] [3174]*/ + 0x10,0x13,0x10,0x10,0xFD,0x25,0x25,0x25,0x24,0x48,0x28,0x13,0x28,0x44,0x84,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xC2E9 [?] [3175]*/ + 0x01,0x00,0x3F,0x22,0x22,0x22,0x3F,0x22,0x26,0x27,0x2A,0x2A,0x52,0x42,0x82,0x02, + 0x00,0x80,0xFE,0x10,0x10,0x10,0xBE,0x10,0x10,0x38,0xB4,0x54,0x92,0x10,0x10,0x10, + /* 0xC2EA [?] [3176]*/ + 0x00,0x03,0xFC,0x10,0x11,0x11,0x11,0x7D,0x10,0x10,0x10,0x13,0x1C,0xE0,0x40,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xFE,0x02,0x02,0x02,0xFA,0x02,0x02,0x14,0x08, + /* 0xC2EB [?] [3177]*/ + 0x00,0x01,0xFC,0x10,0x10,0x20,0x3C,0x64,0x64,0xA4,0x24,0x25,0x3C,0x24,0x20,0x00, + 0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0xFE,0x02,0x02,0x02,0xFA,0x02,0x02,0x14,0x08, + /* 0xC2EC [?] [3178]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x15,0x1C,0xE4,0x40,0x00, + 0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0xFE,0x02,0x02,0x02,0xFA,0x02,0x02,0x14,0x08, + /* 0xC2ED [?] [3179]*/ + 0x00,0x7F,0x00,0x00,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0xE4,0x04,0x04,0x28,0x10, + /* 0xC2EE [?] [3180]*/ + 0x00,0x7C,0x44,0x44,0x7C,0x00,0x3F,0x00,0x08,0x08,0x0F,0x00,0x7F,0x00,0x00,0x00, + 0x00,0xF8,0x88,0x88,0xF8,0x00,0xE0,0x20,0x20,0x20,0xFC,0x04,0xE4,0x04,0x28,0x10, + /* 0xC2EF [?] [3181]*/ + 0x00,0x00,0xF7,0x94,0x94,0x94,0x97,0x94,0x94,0x95,0xF5,0x96,0x08,0x08,0x10,0x00, + 0x40,0x20,0xFE,0x90,0x90,0x90,0xFC,0x90,0xD8,0xB8,0xB4,0xD4,0x92,0x90,0x90,0x90, + /* 0xC2F0 [?] [3182]*/ + 0x00,0x03,0x78,0x48,0x49,0x49,0x49,0x49,0x48,0x48,0x78,0x4B,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xC2F1 [?] [3183]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x10,0x10,0x11,0x1C,0xE0,0x40,0x03,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC2F2 [?] [3184]*/ + 0x00,0x7F,0x00,0x08,0x04,0x24,0x10,0x10,0x01,0xFF,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0xFC,0x04,0x88,0x80,0x80,0x80,0x80,0x00,0xFE,0x00,0xC0,0x20,0x10,0x08,0x04, + /* 0xC2F3 [?] [3185]*/ + 0x01,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x08,0x1F,0x28,0x44,0x03,0x1C,0xE0, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E, + /* 0xC2F4 [?] [3186]*/ + 0x01,0x01,0x3F,0x01,0x01,0x7F,0x04,0x02,0x12,0x08,0x09,0xFF,0x02,0x04,0x18,0x60, + 0x00,0x00,0xF8,0x00,0x00,0xFC,0x04,0x88,0x80,0x80,0x00,0xFE,0x40,0x20,0x10,0x08, + /* 0xC2F5 [?] [3187]*/ + 0x00,0x20,0x17,0x10,0x00,0x00,0xF0,0x10,0x10,0x11,0x11,0x12,0x14,0x28,0x47,0x00, + 0x00,0x00,0xFE,0x80,0x80,0xFC,0x84,0x84,0x84,0x04,0x04,0x28,0x10,0x00,0xFE,0x00, + /* 0xC2F6 [?] [3188]*/ + 0x00,0x78,0x48,0x49,0x48,0x78,0x4B,0x48,0x48,0x78,0x49,0x49,0x4A,0x4C,0x48,0x98, + 0x40,0x20,0x10,0xE0,0x22,0x34,0xB8,0xB0,0xA8,0xA8,0x28,0x24,0x24,0x22,0xA0,0x40, + /* 0xC2F7 [?] [3189]*/ + 0x01,0x01,0xF7,0x91,0x90,0xF7,0x90,0x90,0xF7,0x94,0x94,0x95,0xF6,0x94,0x04,0x04, + 0x08,0x08,0xFE,0x08,0x00,0xFE,0x90,0x90,0xFE,0x92,0x92,0x6A,0x46,0x02,0x0A,0x04, + /* 0xC2F8 [?] [3190]*/ + 0x23,0x22,0x23,0x3A,0x4B,0x50,0x87,0x24,0x24,0x27,0x20,0x23,0x29,0x30,0x23,0x0C, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xC2F9 [?] [3191]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x44,0x01,0x1F,0x11,0x11,0x1F,0x11,0x01,0x7F,0x20, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x00,0xF0,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xC2FA [?] [3192]*/ + 0x01,0x21,0x17,0x11,0x80,0x47,0x40,0x10,0x17,0x24,0xE4,0x25,0x26,0x24,0x24,0x04, + 0x08,0x08,0xFE,0x08,0x00,0xFE,0x90,0x90,0xFE,0x92,0x92,0x6A,0x46,0x02,0x0A,0x04, + /* 0xC2FB [?] [3193]*/ + 0x08,0xFF,0x08,0x1F,0x10,0x1F,0x10,0x7F,0x44,0x7F,0x00,0x3F,0x08,0x07,0x18,0xE0, + 0x20,0xFE,0x20,0xF0,0x10,0xF0,0x10,0xFC,0x44,0xFC,0x00,0xF0,0x20,0xC0,0x30,0x0E, + /* 0xC2FC [?] [3194]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x7F,0x44,0x7F,0x00,0x3F,0x08,0x07,0x18,0xE0, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x44,0xFC,0x00,0xF0,0x20,0xC0,0x30,0x0E, + /* 0xC2FD [?] [3195]*/ + 0x23,0x22,0x23,0x32,0xAB,0xA0,0xA7,0xA4,0x24,0x27,0x20,0x23,0x21,0x20,0x23,0x2C, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xC2FE [?] [3196]*/ + 0x03,0x22,0x13,0x12,0x83,0x40,0x47,0x14,0x14,0x27,0xE0,0x23,0x21,0x20,0x23,0x0C, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xC3A1 [?] [3197]*/ + 0x03,0x42,0x23,0x22,0x03,0x00,0xE7,0x24,0x24,0x27,0x20,0x23,0x29,0x30,0x23,0x0C, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xC3A2 [?] [3198]*/ + 0x08,0x08,0xFF,0x08,0x08,0x02,0x01,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x0F,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xC3A3 [?] [3199]*/ + 0x08,0x08,0xFF,0x08,0x08,0x20,0x10,0x87,0x49,0x09,0x11,0xE1,0x21,0x21,0x21,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x40,0x20,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xC3A4 [?] [3200]*/ + 0x02,0x01,0xFF,0x10,0x10,0x10,0x1F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xC3A5 [?] [3201]*/ + 0x20,0x13,0x12,0x02,0xFA,0x43,0x42,0x42,0x43,0x42,0x42,0x42,0x7A,0x02,0x03,0x02, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x8A,0x06,0x02, + /* 0xC3A6 [?] [3202]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x20,0x10,0x10,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00, + /* 0xC3A7 [?] [3203]*/ + 0x08,0xFF,0x08,0x02,0x02,0x7F,0x04,0x08,0x30,0xC8,0x08,0x7F,0x08,0x10,0x20,0x40, + 0x20,0xFE,0x20,0x40,0x20,0xFC,0x40,0x20,0x18,0x26,0x20,0xFC,0x20,0x20,0x20,0x20, + /* 0xC3A8 [?] [3204]*/ + 0x00,0x44,0x2B,0x10,0x28,0x48,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x51,0x21, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x04, + /* 0xC3A9 [?] [3205]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x00,0x06,0x01,0xFF,0x02,0x04,0x08,0x30,0xC2,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x20,0x40,0x80,0xFE,0x82,0x84,0x80,0x80,0x80,0x00, + /* 0xC3AA [?] [3206]*/ + 0x20,0x20,0x3B,0x20,0x40,0x78,0xA1,0x21,0xF9,0x21,0x21,0x21,0x29,0x31,0x21,0x01, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x04, + /* 0xC3AB [?] [3207]*/ + 0x00,0x01,0x7E,0x02,0x02,0x03,0x3E,0x02,0x02,0x03,0xFE,0x02,0x02,0x02,0x02,0x01, + 0x10,0xF8,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xFC,0x00,0x00,0x04,0x04,0x04,0xFC, + /* 0xC3AC [?] [3208]*/ + 0x00,0x1F,0x00,0x02,0x01,0x00,0x7F,0x01,0x02,0x04,0x08,0x10,0x20,0xC0,0x02,0x01, + 0x00,0xF0,0x10,0x20,0x40,0x80,0xFE,0x82,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + /* 0xC3AD [?] [3209]*/ + 0x20,0x20,0x3B,0x22,0x42,0x7A,0xA2,0x22,0xFA,0x22,0x23,0x22,0x28,0x30,0x21,0x02, + 0x00,0x80,0x1E,0x52,0x52,0x52,0x52,0x52,0x52,0xD2,0x5A,0x54,0x90,0x90,0x10,0x10, + /* 0xC3AE [?] [3210]*/ + 0x0C,0x70,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x4C,0x74,0x04,0x08,0x08,0x10,0x20, + 0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xA8,0x90,0x80,0x80,0x80,0x80, + /* 0xC3AF [?] [3211]*/ + 0x08,0x08,0xFF,0x08,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x41,0x86, + 0x20,0x20,0xFE,0x20,0x90,0x88,0xFC,0x80,0x88,0x88,0x50,0x50,0x24,0x54,0x8C,0x04, + /* 0xC3B0 [?] [3212]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x2F,0x20,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0xF8,0x08,0xE8,0x08,0xE8,0x08,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xC3B1 [?] [3213]*/ + 0x20,0x23,0x22,0xFA,0xAA,0xAA,0xAA,0xA8,0xA9,0xA9,0xA9,0xB9,0x21,0x21,0x21,0x21, + 0x00,0xFC,0x04,0xF4,0x04,0xF4,0x04,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xC3B2 [?] [3214]*/ + 0x0C,0x30,0xC3,0x15,0x49,0x31,0xC9,0x15,0x25,0xCC,0x14,0x24,0xC4,0x04,0x29,0x12, + 0x20,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x50,0x50,0x50,0x92,0x92,0x0E,0x00, + /* 0xC3B3 [?] [3215]*/ + 0x06,0x78,0x40,0x48,0x44,0x5A,0x61,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0xFC,0x44,0x44,0x44,0x94,0x08,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xC3B4 [?] [3216]*/ + 0x01,0x01,0x02,0x02,0x04,0x08,0x10,0x20,0x41,0x02,0x04,0x08,0x10,0x3F,0x10,0x00, + 0x00,0x00,0x00,0x00,0x40,0x40,0x80,0x80,0x00,0x00,0x20,0x10,0x08,0xFC,0x04,0x00, + /* 0xC3B5 [?] [3217]*/ + 0x00,0x00,0xFE,0x10,0x10,0x11,0x7E,0x10,0x10,0x10,0x10,0x1E,0xF0,0x40,0x01,0x02, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xC3B6 [?] [3218]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x32,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x11,0x12, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xC3B7 [?] [3219]*/ + 0x11,0x11,0x11,0x12,0xFD,0x11,0x39,0x35,0x57,0x51,0x92,0x12,0x13,0x10,0x10,0x10, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xC3B8 [?] [3220]*/ + 0x00,0xFE,0x28,0x28,0xFF,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x40,0x40,0x7E,0x80,0x7C,0x44,0x64,0x54,0xFE,0x44,0xA4,0x94,0xFE,0x04,0x28,0x10, + /* 0xC3B9 [?] [3221]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x10,0x1F,0x20,0x5F,0x12,0xFF,0x20,0x3F,0x00, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFC,0x00,0xF0,0x10,0xFE,0x90,0xFC,0x30, + /* 0xC3BA [?] [3222]*/ + 0x10,0x10,0x13,0x10,0x54,0x58,0x50,0x90,0x10,0x10,0x13,0x28,0x24,0x45,0x42,0x80, + 0x88,0x88,0xFE,0x88,0x88,0xF8,0x88,0x88,0xF8,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xC3BB [?] [3223]*/ + 0x00,0x21,0x11,0x11,0x81,0x42,0x54,0x18,0x13,0x22,0xE1,0x21,0x20,0x20,0x21,0x0E, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x0E,0x00,0xF8,0x08,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xC3BC [?] [3224]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x20,0x2F,0x28,0x28,0x2F,0x28,0x2F,0x48,0x48,0x8F,0x08, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xF8,0x08,0x08,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC3BD [?] [3225]*/ + 0x10,0x10,0x13,0x10,0xFC,0x24,0x24,0x24,0x24,0x48,0x2B,0x10,0x28,0x45,0x86,0x00, + 0x88,0x88,0xFE,0x88,0x88,0xF8,0x88,0x88,0xF8,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xC3BE [?] [3226]*/ + 0x21,0x20,0x3B,0x20,0x40,0x79,0xA0,0x20,0xFB,0x20,0x20,0x23,0x28,0x30,0x20,0x03, + 0x04,0x88,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x20,0xFE,0x20,0x50,0x88,0x06, + /* 0xC3BF [?] [3227]*/ + 0x10,0x1F,0x20,0x20,0x5F,0x90,0x12,0x11,0xFF,0x20,0x22,0x21,0x3F,0x00,0x00,0x00, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0xFC,0x10,0xA0,0x40, + /* 0xC3C0 [?] [3228]*/ + 0x08,0x04,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x01,0x01,0x7F,0x02,0x04,0x18,0xE0, + 0x20,0x40,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0xFC,0x80,0x40,0x30,0x0E, + /* 0xC3C1 [?] [3229]*/ + 0x00,0x00,0x78,0x49,0x48,0x48,0x48,0x7B,0x48,0x48,0x48,0x49,0x79,0x4A,0x00,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xC3C2 [?] [3230]*/ + 0x02,0x01,0x7F,0x40,0x84,0x24,0x25,0x3C,0x04,0x07,0x7C,0x24,0x25,0x26,0x44,0x84, + 0x00,0x00,0xFE,0x02,0x24,0x20,0xFC,0x20,0x20,0xFE,0x60,0xB0,0x28,0x26,0x20,0x20, + /* 0xC3C3 [?] [3231]*/ + 0x10,0x10,0x10,0x11,0xFC,0x24,0x24,0x27,0x24,0x48,0x28,0x11,0x29,0x46,0x84,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xC3C4 [?] [3232]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x46,0x82,0x04, + 0x00,0xFC,0x24,0x24,0xFC,0x00,0x7C,0x44,0x44,0x7C,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xC3C5 [?] [3233]*/ + 0x20,0x13,0x10,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xC3C6 [?] [3234]*/ + 0x20,0x17,0x00,0x42,0x41,0x41,0x44,0x54,0x54,0x64,0x44,0x43,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x24,0x14,0x54,0x44,0xC4,0x04,0x04,0x14,0x08, + /* 0xC3C7 [?] [3235]*/ + 0x09,0x08,0x08,0x12,0x12,0x32,0x32,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12, + 0x00,0x80,0xBC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xC3C8 [?] [3236]*/ + 0x08,0x08,0xFF,0x08,0x00,0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x01,0x02, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0x14,0x08, + /* 0xC3C9 [?] [3237]*/ + 0x08,0xFF,0x08,0x7F,0x40,0x8F,0x00,0x7F,0x06,0x3B,0x04,0x19,0x62,0x0C,0x72,0x01, + 0x20,0xFE,0x20,0xFE,0x02,0xE4,0x00,0xFC,0x00,0x08,0xB0,0xC0,0xA0,0x98,0x86,0x00, + /* 0xC3CA [?] [3238]*/ + 0x21,0x27,0x21,0x27,0xF4,0x23,0x20,0x77,0x68,0xA1,0xA6,0x21,0x26,0x21,0x26,0x20, + 0x10,0xFC,0x10,0xFC,0x04,0xF8,0x00,0xFC,0x80,0x44,0xA8,0x70,0xA8,0x26,0xA0,0x40, + /* 0xC3CB [?] [3239]*/ + 0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x01,0x02,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x84,0x14,0x08,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xC3CC [?] [3240]*/ + 0x20,0x21,0x38,0x20,0x40,0x7B,0xA0,0x20,0xF8,0x21,0x21,0x21,0x29,0x31,0x27,0x00, + 0x00,0xFC,0x08,0x10,0x20,0xFE,0x20,0xA0,0x40,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xC3CD [?] [3241]*/ + 0x00,0x45,0x28,0x10,0x28,0x4B,0x88,0x08,0x18,0x29,0x49,0x89,0x09,0x09,0x57,0x20, + 0x00,0xFC,0x08,0x10,0x20,0xFE,0x20,0xA0,0x40,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xC3CE [?] [3242]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC8,0x04,0x07,0x08,0x14,0x22,0x01,0x02,0x0C,0x70, + 0x20,0x20,0xFC,0x20,0x70,0xA8,0x26,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xC3CF [?] [3243]*/ + 0x00,0x1F,0x00,0x01,0xFF,0x01,0x01,0x05,0x02,0x3F,0x24,0x24,0x24,0x24,0xFF,0x00, + 0x00,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xC3D0 [?] [3244]*/ + 0x00,0x00,0x79,0x48,0x48,0x78,0x48,0x4B,0x78,0x48,0x48,0x49,0x79,0x4A,0x00,0x00, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xC3D1 [?] [3245]*/ + 0x00,0xFE,0x29,0x28,0xFE,0xAA,0xAA,0xAB,0xAE,0xC2,0x82,0xFE,0x82,0x83,0xFE,0x82, + 0x08,0x4A,0x2A,0xAC,0x88,0x3E,0x08,0x98,0x9C,0xAA,0xCA,0x88,0x88,0x40,0x3E,0x00, + /* 0xC3D2 [?] [3246]*/ + 0x00,0x3F,0x24,0x3F,0x26,0x2D,0x34,0x21,0x21,0x3F,0x21,0x2F,0x21,0x5F,0x41,0x81, + 0x80,0xFE,0x10,0x7C,0x38,0x54,0x12,0x20,0x20,0x3E,0x20,0x3C,0x20,0x3E,0x20,0x20, + /* 0xC3D3 [?] [3247]*/ + 0x01,0x00,0x3F,0x22,0x2F,0x26,0x2B,0x32,0x20,0x24,0x22,0x3F,0x21,0x42,0x44,0x98, + 0x00,0x80,0xFE,0x10,0x7C,0x38,0x54,0x92,0x80,0x90,0xA0,0xFC,0xC0,0xA0,0x98,0x86, + /* 0xC3D4 [?] [3248]*/ + 0x00,0x22,0x11,0x11,0x00,0x07,0xF0,0x10,0x11,0x12,0x14,0x10,0x10,0x28,0x47,0x00, + 0x40,0x48,0x48,0x50,0x40,0xFC,0x40,0xE0,0x50,0x48,0x44,0x40,0x40,0x00,0xFE,0x00, + /* 0xC3D5 [?] [3249]*/ + 0x00,0x40,0x24,0x22,0x02,0x00,0xE0,0x26,0x22,0x22,0x23,0x22,0x2A,0x35,0x28,0x00, + 0x10,0x92,0x52,0x54,0x10,0xFE,0x10,0x38,0x54,0x92,0x10,0x10,0x10,0x00,0xFE,0x00, + /* 0xC3D6 [?] [3250]*/ + 0x00,0xF8,0x08,0x09,0x09,0x7A,0x44,0x40,0x41,0x79,0x0A,0x0A,0x0C,0x08,0x50,0x20, + 0x80,0x80,0x80,0xFE,0x02,0x04,0x20,0x20,0x28,0x24,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xC3D7 [?] [3251]*/ + 0x01,0x21,0x11,0x09,0x09,0x01,0x7F,0x03,0x05,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x00,0x08,0x08,0x10,0x20,0x00,0xFC,0x80,0x40,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xC3D8 [?] [3252]*/ + 0x08,0x1C,0xF0,0x10,0x10,0xFC,0x10,0x3A,0x36,0x52,0x54,0x90,0x11,0x12,0x14,0x10, + 0x00,0x40,0x20,0x28,0x08,0x88,0x90,0x94,0xA2,0xA2,0xC2,0x88,0x88,0x88,0x78,0x00, + /* 0xC3D9 [?] [3253]*/ + 0x01,0x7E,0x12,0x09,0x09,0x00,0x1F,0x10,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0xF8,0x00,0x10,0x10,0x20,0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x80,0x82,0x82,0x7E, + /* 0xC3DA [?] [3254]*/ + 0x00,0x20,0x10,0x10,0x81,0x41,0x41,0x15,0x15,0x25,0xE5,0x29,0x21,0x23,0x24,0x08, + 0x00,0x80,0x40,0x28,0x28,0x08,0x10,0x14,0x22,0x22,0x42,0x88,0x08,0x08,0xF8,0x00, + /* 0xC3DB [?] [3255]*/ + 0x02,0x01,0x7F,0x42,0x89,0x28,0x49,0x0E,0x77,0x01,0x3F,0x21,0x3F,0x01,0x7F,0x00, + 0x00,0x00,0xFE,0x02,0x24,0x48,0x94,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x08,0xFC,0x04, + /* 0xC3DC [?] [3256]*/ + 0x02,0x01,0x7F,0x40,0x82,0x09,0x28,0x4B,0x1C,0xE7,0x01,0x21,0x21,0x21,0x3F,0x00, + 0x00,0x00,0xFE,0x02,0x24,0x40,0x88,0x14,0x10,0xF0,0x00,0x08,0x08,0x08,0xF8,0x08, + /* 0xC3DD [?] [3257]*/ + 0x00,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x02,0xFF,0x09,0x3F,0xD1,0x11,0x11,0x01, + 0x00,0xFE,0x02,0xF4,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x20,0xF8,0x16,0x50,0x20,0x00, + /* 0xC3DE [?] [3258]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x38,0x54,0x53,0x92,0x12,0x12,0x12,0x10,0x10, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xC3DF [?] [3259]*/ + 0x00,0x01,0x7D,0x45,0x45,0x7D,0x45,0x45,0x7D,0x45,0x45,0x45,0x7D,0x45,0x01,0x01, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x4A,0x86,0x02, + /* 0xC3E0 [?] [3260]*/ + 0x10,0x10,0x21,0x21,0x49,0xF1,0x11,0x20,0x40,0xFB,0x42,0x02,0x1A,0xE2,0x40,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xC3E1 [?] [3261]*/ + 0x7F,0x40,0x5F,0x40,0x5F,0x04,0x0F,0x10,0x3F,0x51,0x11,0x1F,0x02,0x04,0x18,0x60, + 0xFC,0x04,0xF4,0x04,0xF4,0x00,0xE0,0x20,0xF8,0x08,0x08,0xF8,0x80,0x82,0x82,0x7E, + /* 0xC3E2 [?] [3262]*/ + 0x08,0x08,0x0F,0x10,0x20,0x7F,0xA1,0x21,0x21,0x3F,0x22,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0x08,0xF8,0x88,0x80,0x80,0x82,0x82,0x7E, + /* 0xC3E3 [?] [3263]*/ + 0x20,0x20,0x3E,0x44,0x88,0x7F,0x49,0x49,0x49,0x7F,0x14,0x14,0x25,0x24,0x43,0x80, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x0A,0x02,0xFE,0x00, + /* 0xC3E4 [?] [3264]*/ + 0x10,0x10,0x10,0x11,0xFE,0x25,0x25,0x25,0x25,0x49,0x28,0x10,0x28,0x44,0x81,0x02, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0xFC,0x50,0x50,0x90,0x92,0x12,0x0E, + /* 0xC3E5 [?] [3265]*/ + 0x10,0x17,0x20,0x20,0x4B,0xF2,0x12,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x43,0x02, + 0x00,0xFE,0x40,0x80,0xFC,0x94,0x94,0xF4,0x94,0x94,0xF4,0x94,0x94,0x94,0xFC,0x04, + /* 0xC3E6 [?] [3266]*/ + 0x00,0xFF,0x02,0x02,0x04,0x3F,0x24,0x24,0x27,0x24,0x24,0x27,0x24,0x24,0x3F,0x20, + 0x00,0xFE,0x00,0x00,0x00,0xF8,0x48,0x48,0xC8,0x48,0x48,0xC8,0x48,0x48,0xF8,0x08, + /* 0xC3E7 [?] [3267]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC3E8 [?] [3268]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x04, + /* 0xC3E9 [?] [3269]*/ + 0x00,0x00,0x7B,0x48,0x48,0x78,0x49,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x04, + /* 0xC3EA [?] [3270]*/ + 0x08,0xFF,0x08,0x08,0x30,0xCA,0x2C,0x30,0xC8,0x14,0x24,0xCC,0x14,0x24,0xD4,0x09, + 0x20,0xFE,0x20,0x10,0x20,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x48,0x4A,0x8A,0x06, + /* 0xC3EB [?] [3271]*/ + 0x08,0x1C,0xF0,0x10,0x10,0xFC,0x11,0x31,0x3A,0x54,0x54,0x90,0x10,0x10,0x10,0x13, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xC3EC [?] [3272]*/ + 0x40,0x20,0x2F,0x89,0x49,0x4F,0x09,0x29,0x2F,0x49,0xC9,0x4F,0x49,0x40,0x40,0x01, + 0x10,0x10,0x10,0x10,0x14,0x52,0x52,0x92,0x10,0x14,0x04,0x08,0x10,0x20,0x40,0x80, + /* 0xC3ED [?] [3273]*/ + 0x01,0x00,0x3F,0x20,0x20,0x20,0x2F,0x28,0x28,0x28,0x2F,0x28,0x48,0x48,0x8F,0x08, + 0x00,0x80,0xFE,0x00,0x80,0x80,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0xF8,0x08, + /* 0xC3EE [?] [3274]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x25,0x25,0x26,0x48,0x28,0x10,0x28,0x44,0x80,0x03, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xC3EF [?] [3275]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x24,0x24,0x3F,0x00,0x3F,0x20,0x30,0x28,0x24,0x40,0x83, + 0x20,0xFE,0x20,0x00,0xF8,0x48,0x48,0xF8,0x90,0xFC,0x80,0x48,0x50,0x24,0xD4,0x0C, + /* 0xC3F0 [?] [3276]*/ + 0x00,0xFF,0x01,0x01,0x11,0x11,0x11,0x21,0x42,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0xFE,0x00,0x00,0x08,0x08,0x10,0x20,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xC3F1 [?] [3277]*/ + 0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x24,0x28,0x30,0x20, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x80,0x80,0xFC,0x80,0x40,0x40,0x24,0x14,0x0C,0x04, + /* 0xC3F2 [?] [3278]*/ + 0x10,0x13,0x12,0x12,0xFE,0x13,0x12,0x16,0x1B,0x32,0xD2,0x12,0x12,0x12,0x53,0x22, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x8A,0x06,0x02, + /* 0xC3F3 [?] [3279]*/ + 0x00,0x00,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFF,0x00,0x00, + 0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xFE,0x00,0x00, + /* 0xC3F4 [?] [3280]*/ + 0x40,0x40,0x7F,0x80,0x7E,0x42,0x52,0x4A,0xFF,0x42,0x92,0x8A,0xFF,0x02,0x14,0x09, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0xA8,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xC3F5 [?] [3281]*/ + 0x11,0x10,0x12,0x12,0x1A,0x56,0x53,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x12,0x12, + 0x00,0xBE,0x82,0x02,0x42,0x22,0xFE,0x92,0x52,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xC3F6 [?] [3282]*/ + 0x20,0x17,0x00,0x41,0x41,0x4F,0x49,0x49,0x49,0x4F,0x49,0x41,0x41,0x5E,0x48,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x24,0xF4,0x14,0x04,0x0C, + /* 0xC3F7 [?] [3283]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x01,0x01,0x02,0x04, + 0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x04,0x04,0x14,0x08, + /* 0xC3F8 [?] [3284]*/ + 0x20,0x23,0x22,0xF8,0xA9,0xA9,0xA9,0xA9,0xF9,0xA0,0x20,0x2B,0x38,0xE8,0x41,0x02, + 0x00,0xFE,0x02,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xFE,0x00,0x88,0x04,0x02, + /* 0xC3F9 [?] [3285]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x78,0x48,0x03,0x00,0x00,0x00, + 0x20,0x40,0xFC,0x04,0x44,0x24,0x24,0x0C,0x00,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xC3FA [?] [3286]*/ + 0x10,0x10,0x3C,0x21,0x42,0xBC,0x10,0x10,0xFC,0x11,0x12,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0xFC,0x04,0x88,0x50,0x20,0x40,0x80,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xC3FB [?] [3287]*/ + 0x02,0x02,0x07,0x08,0x14,0x62,0x02,0x01,0x06,0x1F,0xE8,0x08,0x08,0x08,0x0F,0x08, + 0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC3FC [?] [3288]*/ + 0x01,0x01,0x02,0x04,0x08,0x37,0xC0,0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x00,0x00, + 0x00,0x00,0x80,0x40,0x20,0xD8,0x06,0x00,0xF8,0x88,0x88,0x88,0xA8,0x90,0x80,0x80, + /* 0xC3FD [?] [3289]*/ + 0x00,0x47,0x20,0x24,0x02,0x04,0xE0,0x21,0x26,0x20,0x23,0x20,0x2B,0x30,0x20,0x07, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x50,0x88,0x26,0xC0,0x10,0x64,0x88,0x30,0xC0,0x00, + /* 0xC3FE [?] [3290]*/ + 0x11,0x11,0x17,0x11,0xFC,0x13,0x12,0x17,0x1A,0x33,0xD0,0x17,0x10,0x11,0x52,0x24, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xC4A1 [?] [3291]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x10,0x27,0xC1,0x1F,0x01,0x03, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x50,0x88,0x06,0xF0,0x00,0x00, + /* 0xC4A2 [?] [3292]*/ + 0x08,0xFF,0x08,0x3F,0x22,0x2F,0x23,0x26,0x2A,0x20,0x3F,0x44,0x4F,0x94,0x27,0x04, + 0x20,0xFE,0xA0,0xFE,0x10,0xBC,0x18,0xB4,0x52,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08, + /* 0xC4A3 [?] [3293]*/ + 0x11,0x11,0x17,0x11,0xFC,0x13,0x32,0x3B,0x56,0x53,0x90,0x17,0x10,0x11,0x12,0x14, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xC4A4 [?] [3294]*/ + 0x00,0x78,0x4B,0x48,0x48,0x79,0x49,0x49,0x49,0x79,0x48,0x4B,0x48,0x48,0x49,0x9A, + 0x88,0x88,0xFE,0x88,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xC4A5 [?] [3295]*/ + 0x00,0x3F,0x22,0x2F,0x22,0x27,0x2A,0x22,0x2F,0x21,0x22,0x27,0x4A,0x52,0x83,0x02, + 0x80,0xFE,0x10,0x7C,0x10,0x38,0xD4,0x10,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC4A6 [?] [3296]*/ + 0x00,0x3F,0x24,0x3F,0x26,0x2D,0x34,0x20,0x27,0x20,0x27,0x20,0x2F,0x40,0x41,0x80, + 0x80,0xFE,0x10,0x7C,0x38,0x54,0x12,0x38,0xC0,0x40,0xF8,0x40,0xFE,0x40,0x40,0x80, + /* 0xC4A7 [?] [3297]*/ + 0x00,0x3F,0x24,0x3F,0x26,0x2D,0x35,0x2F,0x28,0x2F,0x28,0x2F,0x21,0x42,0x4C,0xB0, + 0x80,0xFE,0x10,0x7C,0x38,0x54,0x12,0xF8,0x88,0xF8,0x88,0xF8,0x50,0xF8,0x8A,0x7E, + /* 0xC4A8 [?] [3298]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x10,0x15,0x18,0x30,0xD0,0x11,0x11,0x12,0x50,0x20, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xC4A9 [?] [3299]*/ + 0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x7F,0x03,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFC,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xC4AA [?] [3300]*/ + 0x08,0x08,0xFF,0x08,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x7F,0x02,0x04,0x18,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x80,0x40,0x30,0x0E, + /* 0xC4AB [?] [3301]*/ + 0x00,0x3F,0x29,0x25,0x3F,0x01,0x3F,0x01,0xFF,0x24,0x42,0x01,0x3F,0x01,0x01,0xFF, + 0x00,0xF8,0x28,0x48,0xF8,0x00,0xF8,0x00,0xFE,0x48,0x24,0x00,0xF8,0x00,0x00,0xFE, + /* 0xC4AC [?] [3302]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x93,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA9,0x82, + 0x20,0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC4AD [?] [3303]*/ + 0x00,0x20,0x10,0x17,0x80,0x40,0x48,0x0B,0x10,0x10,0xE1,0x22,0x24,0x28,0x20,0x00, + 0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40,0x40, + /* 0xC4AE [?] [3304]*/ + 0x01,0x21,0x17,0x11,0x80,0x43,0x4A,0x0B,0x12,0x13,0xE0,0x27,0x20,0x21,0x22,0x0C, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xC4AF [?] [3305]*/ + 0x01,0x7F,0x40,0x84,0x3F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x02,0x7F,0x04,0x18,0xE0, + 0x00,0xFE,0x02,0x44,0xF8,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x40,0x30,0x0E, + /* 0xC4B0 [?] [3306]*/ + 0x00,0x7D,0x44,0x48,0x48,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41, + 0x00,0xFE,0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC4B1 [?] [3307]*/ + 0x02,0x42,0x2F,0x22,0x02,0x03,0xE2,0x22,0x23,0x20,0x2F,0x20,0x29,0x32,0x2C,0x00, + 0x08,0x08,0xFE,0x08,0x08,0xF8,0x08,0x08,0xF8,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xC4B2 [?] [3308]*/ + 0x02,0x04,0x08,0x10,0x3F,0x00,0x01,0x11,0x1F,0x21,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0x20,0x10,0xF8,0x08,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xC4B3 [?] [3309]*/ + 0x08,0x08,0xFF,0x08,0x08,0x0F,0x08,0x08,0x0F,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0xFE,0x20,0x20,0xE0,0x20,0x20,0xE0,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC4B4 [?] [3310]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x17,0x1A,0x32,0xD2,0x12,0x13,0x10,0x50,0x20, + 0x00,0xF8,0x08,0x48,0x28,0x08,0x08,0xFE,0x08,0x88,0x48,0x08,0xFE,0x08,0x50,0x20, + /* 0xC4B5 [?] [3311]*/ + 0x08,0x08,0x48,0x48,0x7E,0x48,0x89,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08,0x0B,0x08, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xC4B6 [?] [3312]*/ + 0x02,0x01,0x01,0xFF,0x00,0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x20, + 0x00,0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC4B7 [?] [3313]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x24,0x27,0x25,0x49,0x29,0x11,0x29,0x44,0x84,0x00, + 0x00,0xFC,0x84,0xA4,0x94,0x84,0x84,0xFE,0x04,0x44,0x24,0x04,0xFE,0x04,0x28,0x10, + /* 0xC4B8 [?] [3314]*/ + 0x00,0x1F,0x10,0x12,0x11,0x11,0xFF,0x20,0x22,0x21,0x21,0x3F,0x00,0x00,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0xA0,0x40, + /* 0xC4B9 [?] [3315]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x10,0x21,0xCF,0x01,0x01,0x3F, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0x08,0xE6,0x00,0x00,0xF8, + /* 0xC4BA [?] [3316]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x10,0x2F,0xC8,0x0F,0x08,0x0F, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0xE8,0x26,0xE0,0x20,0xE0, + /* 0xC4BB [?] [3317]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x11,0x3F,0xD1,0x11,0x11,0x01, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0xF8,0x16,0x50,0x20,0x00, + /* 0xC4BC [?] [3318]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x10,0x22,0xDF,0x04,0x08,0x30, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0x08,0xF6,0x10,0x50,0x20, + /* 0xC4BD [?] [3319]*/ + 0x04,0x7F,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x12,0x22,0xCB,0x12,0x2A,0x04, + 0x40,0xFC,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x10,0x08,0x26,0x90,0x90,0x00, + /* 0xC4BE [?] [3320]*/ + 0x01,0x01,0x01,0x01,0x7F,0x03,0x05,0x05,0x09,0x11,0x21,0x41,0x81,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0xFC,0x80,0x40,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00, + /* 0xC4BF [?] [3321]*/ + 0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC4C0 [?] [3322]*/ + 0x00,0x00,0x79,0x48,0x48,0x7B,0x48,0x49,0x7A,0x48,0x49,0x48,0x78,0x48,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x88,0x04,0x22,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC4C1 [?] [3323]*/ + 0x08,0x08,0x48,0x48,0x7E,0x49,0x8A,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08,0x09,0x0A, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xC4C2 [?] [3324]*/ + 0x08,0x1C,0xF1,0x11,0x11,0xFD,0x11,0x38,0x35,0x56,0x50,0x93,0x10,0x11,0x10,0x13, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x24,0x32,0xC0,0x18,0x60,0x8C,0x30,0xC0, + /* 0xC4C3 [?] [3325]*/ + 0x01,0x06,0x18,0xEF,0x00,0x1F,0x10,0x1F,0x00,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x03, + 0x00,0xC0,0x30,0xEE,0x00,0xF0,0x10,0xF0,0x20,0xC0,0x00,0xF8,0x00,0xFC,0x00,0x00, + /* 0xC4C4 [?] [3326]*/ + 0x00,0x0F,0x72,0x52,0x52,0x57,0x52,0x52,0x52,0x5F,0x72,0x52,0x02,0x04,0x05,0x08, + 0x00,0xDE,0x52,0x52,0x54,0xD4,0x58,0x54,0x52,0xD2,0x52,0x5A,0x54,0x50,0x50,0x90, + /* 0xC4C5 [?] [3327]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7B,0x4A,0x02,0x02,0x02,0x02, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xA4,0x94,0x14,0x04,0x04,0x04,0x14,0x08, + /* 0xC4C6 [?] [3328]*/ + 0x10,0x10,0x3C,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xC4C7 [?] [3329]*/ + 0x00,0x7E,0x12,0x12,0x12,0x7E,0x12,0x12,0x7E,0x12,0x12,0x22,0x22,0x4A,0x84,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xC4C8 [?] [3330]*/ + 0x20,0x2F,0x22,0x22,0xF2,0x57,0x52,0x52,0x52,0x9F,0x52,0x22,0x22,0x54,0x55,0x88, + 0x00,0xDE,0x52,0x52,0x54,0xD4,0x58,0x54,0x52,0xD2,0x52,0x5A,0x54,0x50,0x50,0x90, + /* 0xC4C9 [?] [3331]*/ + 0x10,0x10,0x20,0x20,0x4B,0xF2,0x12,0x22,0x42,0xFA,0x42,0x03,0x1A,0xE2,0x42,0x02, + 0x20,0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xC4CA [?] [3332]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x3F,0x11,0x12,0x17,0x20,0x20,0x42,0x81, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x10,0xD0,0x4A,0x4A,0x86,0x02, + /* 0xC4CB [?] [3333]*/ + 0x00,0x3F,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0xF0,0x10,0x20,0x20,0x40,0x7C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC4CC [?] [3334]*/ + 0x10,0x10,0x13,0x10,0xFC,0x24,0x24,0x24,0x24,0x48,0x29,0x11,0x29,0x46,0x82,0x04, + 0x00,0x00,0xF8,0x88,0x90,0x90,0xA0,0xBC,0x84,0x84,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC4CD [?] [3335]*/ + 0x00,0xFF,0x08,0x08,0x10,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x41,0x43, + 0x08,0x88,0x08,0x08,0xFE,0x08,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x28,0x10, + /* 0xC4CE [?] [3336]*/ + 0x02,0x02,0x7F,0x04,0x08,0x30,0xCF,0x00,0x00,0x7F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x00,0x00,0xFC,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xC4CF [?] [3337]*/ + 0x01,0x01,0xFF,0x01,0x01,0x7F,0x48,0x44,0x4F,0x41,0x41,0x5F,0x41,0x41,0x41,0x40, + 0x00,0x00,0xFE,0x00,0x00,0xFC,0x24,0x44,0xE4,0x04,0x04,0xF4,0x04,0x04,0x14,0x08, + /* 0xC4D0 [?] [3338]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x01,0x01,0x7F,0x02,0x04,0x08,0x30,0xC0, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x04,0x28,0x10, + /* 0xC4D1 [?] [3339]*/ + 0x00,0x00,0xFC,0x05,0x05,0x4B,0x2D,0x29,0x11,0x11,0x29,0x25,0x45,0x81,0x01,0x01, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xC4D2 [?] [3340]*/ + 0x01,0x7F,0x11,0x1F,0x01,0xFF,0x92,0x1E,0x04,0x3F,0x04,0xFF,0x04,0x0C,0x35,0xC6, + 0x00,0xFC,0x10,0xF0,0x00,0xFE,0x92,0xF0,0x40,0xF8,0x40,0xFE,0x88,0x50,0x30,0x0E, + /* 0xC4D3 [?] [3341]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x10,0x13,0x18,0x33,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xC4D4 [?] [3342]*/ + 0x00,0x78,0x48,0x4F,0x48,0x78,0x48,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x4A,0x4B,0x98, + 0x40,0x20,0x20,0xFE,0x00,0x00,0x90,0x54,0x24,0x24,0x54,0x94,0x04,0x04,0xFC,0x04, + /* 0xC4D5 [?] [3343]*/ + 0x10,0x10,0x10,0x17,0x18,0x54,0x50,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x13,0x10, + 0x40,0x20,0x20,0xFE,0x00,0x00,0x90,0x54,0x24,0x24,0x54,0x94,0x04,0x04,0xFC,0x04, + /* 0xC4D6 [?] [3344]*/ + 0x20,0x17,0x00,0x42,0x41,0x5F,0x41,0x41,0x4F,0x49,0x49,0x49,0x49,0x41,0x41,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0xA4,0x44,0x04,0x14,0x08, + /* 0xC4D7 [?] [3345]*/ + 0x00,0x20,0x10,0x10,0x83,0x42,0x4B,0x0A,0x13,0x12,0xE0,0x27,0x20,0x20,0x20,0x00, + 0x40,0x40,0x7E,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x44,0x40,0xFE,0x40,0x40,0x40,0x40, + /* 0xC4D8 [?] [3346]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4B,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x04,0x04,0x08,0x10, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xC4D9 [?] [3347]*/ + 0x20,0x20,0x23,0x38,0x4A,0x51,0x81,0x20,0x23,0x20,0x21,0x23,0x28,0x30,0x21,0x06, + 0x08,0x3C,0xC0,0x44,0x24,0x28,0x00,0x40,0xFE,0x88,0x08,0x90,0x60,0x50,0x88,0x04, + /* 0xC4DA [?] [3348]*/ + 0x01,0x01,0x01,0x7F,0x41,0x41,0x41,0x42,0x42,0x44,0x48,0x50,0x40,0x40,0x40,0x40, + 0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x84,0x44,0x24,0x14,0x14,0x04,0x04,0x14,0x08, + /* 0xC4DB [?] [3349]*/ + 0x21,0x21,0x27,0x21,0xF1,0x57,0x55,0x55,0x57,0x91,0x53,0x25,0x29,0x51,0x51,0x81, + 0x08,0x08,0xC8,0x10,0x1E,0xE4,0x54,0x54,0xD4,0x14,0x94,0x48,0x48,0x14,0x14,0x22, + /* 0xC4DC [?] [3350]*/ + 0x10,0x24,0x42,0xFF,0x01,0x00,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x42,0x4A,0x44, + 0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00,0x44,0x48,0x70,0x40,0x42,0x42,0x3E, + /* 0xC4DD [?] [3351]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x46,0x82,0x04, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xC4DE [?] [3352]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x06,0x38,0x20,0x3C,0x20,0x3F,0x08,0x10,0xE0, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x42,0x42,0x3E, + /* 0xC4DF [?] [3353]*/ + 0x08,0x08,0x0B,0x12,0x12,0x33,0x32,0x52,0x93,0x10,0x10,0x10,0x10,0x11,0x12,0x14, + 0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0xFC,0x90,0x90,0x90,0x90,0x12,0x12,0x0E, + /* 0xC4E0 [?] [3354]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x24,0x24,0x28,0x10, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xC4E1 [?] [3355]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x12,0x12,0x12,0x13,0x12,0x22,0x22,0x41,0x80, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0x0C,0x30,0xC0,0x02,0x02,0x02,0xFE,0x00, + /* 0xC4E2 [?] [3356]*/ + 0x10,0x10,0x10,0x12,0xFA,0x12,0x12,0x1A,0x32,0xD2,0x12,0x12,0x13,0x12,0x50,0x20, + 0x08,0x88,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x10,0x98,0x24,0x24,0x42,0x82, + /* 0xC4E3 [?] [3357]*/ + 0x08,0x08,0x08,0x11,0x11,0x32,0x34,0x50,0x91,0x11,0x12,0x12,0x14,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x02,0x04,0x20,0x20,0x28,0x24,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xC4E4 [?] [3358]*/ + 0x00,0x7F,0x40,0x44,0x7F,0x44,0x41,0x7F,0x44,0x4F,0x54,0x64,0x47,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x10,0xFE,0x10,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x00, + /* 0xC4E5 [?] [3359]*/ + 0x00,0x78,0x4F,0x48,0x4B,0x78,0x4B,0x48,0x4B,0x7A,0x4A,0x4A,0x4A,0x49,0x4A,0x9C, + 0x18,0x14,0xFE,0x10,0xD0,0x10,0xF0,0x10,0xE8,0x28,0xA8,0xA8,0xAA,0x4A,0x26,0x22, + /* 0xC4E6 [?] [3360]*/ + 0x02,0x41,0x21,0x2F,0x00,0x00,0xE4,0x24,0x24,0x27,0x20,0x21,0x22,0x54,0x8F,0x00, + 0x08,0x08,0x10,0xFE,0x40,0x40,0x44,0x44,0x44,0xFC,0x84,0x00,0x00,0x00,0xFE,0x00, + /* 0xC4E7 [?] [3361]*/ + 0x00,0x27,0x10,0x10,0x87,0x44,0x44,0x17,0x10,0x24,0xE2,0x22,0x24,0x20,0x25,0x02, + 0x00,0xBC,0x84,0x84,0xBC,0x20,0x20,0xBC,0x84,0xA4,0x94,0x94,0xA4,0x84,0x28,0x10, + /* 0xC4E8 [?] [3362]*/ + 0x08,0xFF,0x08,0x7F,0x01,0x11,0x11,0xFF,0x10,0x1F,0x20,0x3F,0x00,0x49,0x84,0x00, + 0x20,0xFE,0x20,0xFC,0x00,0xF8,0x00,0xFE,0x00,0xF8,0x00,0xFC,0x04,0x24,0x94,0x08, + /* 0xC4E9 [?] [3363]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x14,0x18,0x33,0xD2,0x12,0x12,0x12,0x12,0x53,0x22, + 0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC4EA [?] [3364]*/ + 0x10,0x10,0x1F,0x20,0x20,0x40,0x1F,0x10,0x10,0x10,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFE,0x80,0x80,0x80,0x80,0x80, + /* 0xC4EB [?] [3365]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x26,0x22,0x04, + 0x00,0xFE,0x02,0x02,0xFE,0x24,0x24,0x7E,0x24,0x24,0xFE,0x52,0x54,0x48,0x64,0x42, + /* 0xC4EC [?] [3366]*/ + 0x10,0x10,0x13,0x10,0xFB,0x10,0x11,0x1A,0x33,0xD0,0x11,0x13,0x10,0x17,0x50,0x20, + 0x88,0x88,0xDE,0x88,0xDE,0x88,0x54,0x22,0xFC,0x80,0x20,0xFC,0x20,0xFE,0x20,0x20, + /* 0xC4ED [?] [3367]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x11,0x14,0x18,0x30,0xD0,0x12,0x12,0x12,0x54,0x20, + 0x20,0x20,0x50,0x88,0x44,0x22,0xF8,0x08,0x50,0x20,0xA4,0x82,0x8A,0x8A,0x78,0x00, + /* 0xC4EE [?] [3368]*/ + 0x01,0x01,0x02,0x04,0x0A,0x31,0xC1,0x0F,0x00,0x00,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0x80,0x40,0x20,0x18,0x06,0xE0,0x40,0x80,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xC4EF [?] [3369]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xC4F0 [?] [3370]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x10,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0xA2,0xA4,0x98,0x90,0x88,0xC4,0x82, + /* 0xC4F1 [?] [3371]*/ + 0x01,0x02,0x1F,0x10,0x12,0x11,0x11,0x10,0x10,0x1F,0x00,0x00,0x7F,0x00,0x00,0x00, + 0x00,0x00,0xF0,0x10,0x10,0x10,0x50,0x20,0x00,0xFC,0x04,0x04,0xE4,0x04,0x28,0x10, + /* 0xC4F2 [?] [3372]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x2E,0x22,0x22,0x24,0x44,0x48,0x92,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x80,0x80,0x88,0xD0,0xE0,0xA0,0xA0,0x90,0x88,0x84,0x00, + /* 0xC4F3 [?] [3373]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x18,0x30,0xD1,0x10,0x10,0x10,0x53,0x20, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC4F4 [?] [3374]*/ + 0x00,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x00,0x3E,0x02,0x22,0x14,0x08,0x34,0xC3, + 0x00,0xFC,0x20,0xE0,0x20,0xE0,0x3E,0xE0,0x20,0xF8,0x88,0x88,0x50,0x20,0xD8,0x06, + /* 0xC4F5 [?] [3375]*/ + 0x08,0xFF,0x28,0x7D,0x44,0x7C,0x41,0x7C,0x45,0x7C,0x00,0x1F,0x00,0xFF,0x01,0x03, + 0x20,0xFE,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x00,0xE0,0x40,0xFE,0x00,0x00, + /* 0xC4F6 [?] [3376]*/ + 0x00,0x00,0xF2,0x92,0x92,0x92,0x9F,0x90,0x94,0x94,0xF4,0x94,0x05,0x04,0x07,0x00, + 0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x00,0x44,0x44,0xA4,0x94,0x14,0x04,0xFC,0x04, + /* 0xC4F7 [?] [3377]*/ + 0x20,0x23,0x39,0x21,0x41,0x79,0xA1,0x27,0xF8,0x27,0x20,0x22,0x29,0x32,0x24,0x08, + 0x00,0xFC,0x08,0xF8,0x08,0xF8,0x0E,0xF8,0x08,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xC4F8 [?] [3378]*/ + 0x20,0x20,0x3B,0x22,0x43,0x7A,0xA3,0x22,0xFB,0x20,0x27,0x20,0x29,0x32,0x24,0x00, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xC4F9 [?] [3379]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x17,0x10,0x20,0xE7,0x20,0x20,0x20,0x2F,0x00, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xC4FA [?] [3380]*/ + 0x09,0x09,0x11,0x32,0x54,0x99,0x11,0x12,0x14,0x11,0x10,0x02,0x51,0x51,0x90,0x0F, + 0x00,0x00,0xFC,0x04,0x48,0x50,0x48,0x44,0x44,0x40,0x80,0x00,0x04,0x12,0x12,0xF0, + /* 0xC4FB [?] [3381]*/ + 0x20,0x20,0x20,0x23,0xFA,0x24,0x20,0x70,0x6B,0xA0,0xA0,0x20,0x20,0x20,0x20,0x20, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xC4FC [?] [3382]*/ + 0x00,0x44,0x28,0x13,0x2A,0x4C,0x88,0x08,0x1B,0x28,0x48,0x88,0x08,0x08,0x50,0x20, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xC4FD [?] [3383]*/ + 0x04,0x45,0x26,0x24,0x03,0x10,0x14,0x17,0x2A,0x22,0xEF,0x22,0x25,0x24,0x28,0x01, + 0x00,0x7C,0x04,0xA8,0x90,0x7C,0x14,0x94,0x50,0x50,0xDC,0x50,0x50,0xB0,0x9E,0x00, + /* 0xC4FE [?] [3384]*/ + 0x02,0x01,0x01,0x7F,0x40,0x80,0x00,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0x00,0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC5A1 [?] [3385]*/ + 0x10,0x10,0x10,0x13,0xFA,0x14,0x10,0x18,0x33,0xD0,0x10,0x10,0x10,0x10,0x50,0x20, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xC5A2 [?] [3386]*/ + 0x00,0x20,0x10,0x17,0x84,0x48,0x40,0x10,0x17,0x20,0xE0,0x20,0x20,0x20,0x21,0x00, + 0x80,0x40,0x40,0xFC,0x04,0x08,0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xC5A3 [?] [3387]*/ + 0x01,0x11,0x11,0x11,0x1F,0x21,0x41,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC5A4 [?] [3388]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x10,0x15,0x18,0x30,0xD0,0x10,0x10,0x10,0x57,0x20, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFE,0x00, + /* 0xC5A5 [?] [3389]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBC,0x10,0x11,0xFC,0x10,0x10,0x10,0x14,0x18,0x13,0x00, + 0x00,0xF8,0x48,0x48,0x48,0x48,0x48,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0xFE,0x00, + /* 0xC5A6 [?] [3390]*/ + 0x10,0x11,0x20,0x24,0x44,0xF8,0x10,0x21,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x47,0x00, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFE,0x00, + /* 0xC5A7 [?] [3391]*/ + 0x00,0x78,0x48,0x4B,0x4A,0x7C,0x48,0x48,0x49,0x7A,0x4C,0x48,0x48,0x48,0x48,0x98, + 0x20,0x20,0x20,0xFE,0x42,0x44,0xA0,0xA2,0xA4,0x98,0x90,0x88,0x84,0xA2,0xC0,0x80, + /* 0xC5A8 [?] [3392]*/ + 0x00,0x20,0x10,0x17,0x84,0x48,0x41,0x11,0x13,0x25,0xE9,0x21,0x21,0x21,0x21,0x01, + 0x40,0x40,0x40,0xFC,0x84,0x88,0x40,0x44,0x48,0x30,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xC5A9 [?] [3393]*/ + 0x01,0x01,0x01,0x7F,0x42,0x82,0x05,0x05,0x08,0x18,0x28,0x48,0x88,0x0A,0x0C,0x08, + 0x00,0x00,0x00,0xFC,0x04,0x08,0x00,0x08,0x90,0xA0,0x40,0x20,0x10,0x08,0x06,0x00, + /* 0xC5AA [?] [3394]*/ + 0x00,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00,0x08,0x08,0xFF,0x08,0x10,0x20,0x40, + 0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xC5AB [?] [3395]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x24,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x81,0x02, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xC5AC [?] [3396]*/ + 0x10,0x10,0xFE,0x22,0x44,0x28,0x10,0x28,0xC5,0x02,0x02,0x7F,0x04,0x08,0x10,0x60, + 0x00,0x00,0xFC,0x84,0x88,0x50,0x20,0x58,0x86,0x00,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xC5AD [?] [3397]*/ + 0x10,0x10,0xFE,0x22,0x44,0x28,0x10,0x28,0xC5,0x00,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0xFC,0x84,0x88,0x50,0x20,0x58,0x86,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xC5AE [?] [3398]*/ + 0x02,0x02,0x02,0x02,0x04,0xFF,0x04,0x08,0x08,0x10,0x18,0x06,0x01,0x06,0x18,0x60, + 0x00,0x00,0x00,0x00,0x00,0xFE,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x60,0x10,0x08, + /* 0xC5AF [?] [3399]*/ + 0x00,0x07,0x7A,0x49,0x48,0x4B,0x78,0x48,0x4F,0x49,0x49,0x7A,0x4A,0x04,0x08,0x03, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xC5B0 [?] [3400]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x21,0x20,0x20,0x27,0x24,0x3F,0x44,0x47,0x80, + 0x00,0xF8,0x00,0xFC,0x04,0x60,0x88,0x08,0xF8,0x00,0xF8,0x00,0xFE,0x00,0xF8,0x00, + /* 0xC5B1 [?] [3401]*/ + 0x00,0x00,0x1F,0x10,0x90,0x53,0x52,0x12,0x32,0x5F,0x92,0x12,0x22,0x23,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00, + /* 0xC5B2 [?] [3402]*/ + 0x10,0x17,0x12,0x12,0xFA,0x17,0x12,0x1A,0x32,0xDF,0x12,0x12,0x12,0x14,0x55,0x28, + 0x00,0xDE,0x52,0x52,0x54,0xD4,0x58,0x54,0x52,0xD2,0x52,0x5A,0x54,0x50,0x50,0x90, + /* 0xC5B3 [?] [3403]*/ + 0x20,0x27,0x20,0x2F,0x38,0xAB,0xA0,0xA3,0xA0,0x2F,0x20,0x27,0x24,0x24,0x24,0x24, + 0x00,0xFC,0x40,0xFE,0x42,0x58,0x40,0x58,0x00,0xFE,0x40,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xC5B4 [?] [3404]*/ + 0x10,0x11,0x94,0x57,0x5A,0x11,0xFC,0x31,0x38,0x57,0x54,0x91,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFE,0x20,0xFC,0x54,0x54,0x54,0x0C, + /* 0xC5B5 [?] [3405]*/ + 0x01,0x41,0x27,0x21,0x01,0x00,0xE7,0x20,0x21,0x23,0x25,0x29,0x29,0x31,0x21,0x01, + 0x08,0x08,0xFE,0x08,0x48,0x40,0xFE,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5B6 [?] [3406]*/ + 0x00,0x01,0xF7,0x91,0x91,0x9F,0x91,0x91,0x91,0x93,0xFD,0x91,0x01,0x01,0x05,0x02, + 0x28,0xA4,0x24,0x20,0x20,0xFE,0x20,0x24,0xA4,0x28,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xC5B7 [?] [3407]*/ + 0x00,0x7E,0x40,0x44,0x64,0x54,0x49,0x48,0x54,0x54,0x64,0x40,0x40,0x7E,0x01,0x02, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC5B8 [?] [3408]*/ + 0x00,0x7E,0x40,0x44,0x64,0x54,0x48,0x48,0x54,0x54,0x64,0x40,0x41,0x7E,0x00,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xC5B9 [?] [3409]*/ + 0x00,0x7E,0x40,0x44,0x64,0x54,0x49,0x48,0x55,0x54,0x64,0x40,0x40,0x7E,0x00,0x03, + 0x00,0xF8,0x88,0x88,0x88,0x86,0x00,0x00,0xFC,0x84,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xC5BA [?] [3410]*/ + 0x08,0xFF,0x08,0x10,0x11,0x7D,0x11,0x7D,0x11,0xFC,0x13,0x3A,0x56,0x92,0x12,0x12, + 0x20,0xFE,0x20,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFE,0x22,0x2A,0xFA,0x0A,0x06, + /* 0xC5BB [?] [3411]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x03,0x02,0x03,0x00, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xC5BC [?] [3412]*/ + 0x10,0x17,0x14,0x24,0x27,0x64,0x64,0xA7,0x20,0x2F,0x28,0x28,0x2B,0x29,0x28,0x28, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0xFE,0x42,0x52,0xF2,0x12,0x0A,0x04, + /* 0xC5BD [?] [3413]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x23,0x22,0x23,0x00, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xC5BE [?] [3414]*/ + 0x02,0x02,0x72,0x52,0x5F,0x52,0x52,0x52,0x53,0x5E,0x72,0x52,0x02,0x02,0x0A,0x04, + 0x10,0x10,0x20,0x7C,0xC4,0x44,0x44,0xC4,0x7C,0x44,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xC5BF [?] [3415]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x52,0x5E,0xE4,0x08,0x10, + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x02, + /* 0xC5C0 [?] [3416]*/ + 0x0E,0x74,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x52,0x52,0x51,0x90,0x10, + 0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00,0x00,0xFE,0x00, + /* 0xC5C1 [?] [3417]*/ + 0x10,0x10,0x10,0x7D,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x11,0x11,0x11,0x11, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5C2 [?] [3418]*/ + 0x10,0x10,0x10,0x11,0x19,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5C3 [?] [3419]*/ + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00,0x3F,0x21,0x21,0x3F,0x20,0x20,0x1F, + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x02,0x02,0xFE, + /* 0xC5C4 [?] [3420]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5C5 [?] [3421]*/ + 0x10,0x10,0x10,0x17,0xF8,0x10,0x10,0x1B,0x30,0xD0,0x10,0x17,0x10,0x10,0x50,0x20, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xC5C6 [?] [3422]*/ + 0x08,0x48,0x49,0x49,0x49,0x7D,0x41,0x41,0x79,0x48,0x49,0x4B,0x48,0x48,0x48,0x88, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xC5C7 [?] [3423]*/ + 0x08,0x08,0x10,0x27,0x48,0x08,0x10,0x33,0x50,0x90,0x10,0x17,0x10,0x10,0x10,0x10, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xC5C8 [?] [3424]*/ + 0x01,0x43,0x2E,0x22,0x02,0x8F,0x42,0x52,0x12,0x2F,0xE2,0x22,0x22,0x22,0x24,0x08, + 0x00,0xBC,0x10,0x10,0x3C,0x90,0x10,0x3C,0x10,0x90,0x7E,0x10,0x10,0x10,0x10,0x10, + /* 0xC5C9 [?] [3425]*/ + 0x00,0x20,0x17,0x14,0x84,0x45,0x45,0x15,0x15,0x25,0xE5,0x25,0x25,0x29,0x29,0x11, + 0x08,0x3C,0xC0,0x00,0x1C,0xE0,0x20,0x22,0x24,0x28,0x10,0x10,0x08,0x44,0x82,0x00, + /* 0xC5CA [?] [3426]*/ + 0x22,0x21,0xFA,0x20,0x72,0xA9,0x22,0xFF,0x08,0x37,0xC1,0x1F,0x01,0x7F,0x01,0x03, + 0x88,0x08,0xBE,0x08,0x9C,0x2A,0x88,0xFE,0x20,0xD8,0x06,0xF0,0x00,0xFC,0x00,0x00, + /* 0xC5CB [?] [3427]*/ + 0x00,0x27,0x12,0x11,0x87,0x41,0x42,0x14,0x13,0x22,0xE2,0x23,0x22,0x22,0x23,0x02, + 0x78,0xC0,0x48,0x50,0xFC,0x50,0x48,0x06,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x08, + /* 0xC5CC [?] [3428]*/ + 0x02,0x04,0x1F,0x11,0x10,0xFF,0x10,0x12,0x21,0x40,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0xF0,0x10,0x90,0xFE,0x10,0x10,0x50,0x20,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xC5CD [?] [3429]*/ + 0x08,0x3E,0x22,0x2A,0x7E,0x22,0x2A,0x46,0x00,0xFF,0x08,0x1F,0x28,0xC8,0x0F,0x08, + 0x78,0x48,0x8E,0x00,0xF8,0x48,0x30,0xCC,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC5CE [?] [3430]*/ + 0x00,0x00,0x78,0x48,0x49,0x79,0x4A,0x4D,0x78,0x48,0x48,0x48,0x79,0x49,0x02,0x04, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xC5CF [?] [3431]*/ + 0x00,0x00,0x7D,0x54,0x54,0x54,0x55,0x7C,0x54,0x54,0x57,0x54,0x7C,0x44,0x00,0x00, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xC5D0 [?] [3432]*/ + 0x04,0x44,0x24,0x25,0x04,0x7F,0x04,0x04,0x04,0xFF,0x04,0x08,0x08,0x10,0x20,0x40, + 0x04,0x84,0x84,0x24,0x24,0xA4,0x24,0x24,0x24,0xE4,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xC5D1 [?] [3433]*/ + 0x10,0x10,0x95,0x59,0x11,0x7D,0x11,0x11,0xFF,0x11,0x11,0x11,0x21,0x22,0x42,0x84, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xC5D2 [?] [3434]*/ + 0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0xFF,0x00,0x00,0x00,0x00,0x00, + 0x20,0xF0,0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0xFE,0x00,0x40,0x20,0x10,0x08, + /* 0xC5D3 [?] [3435]*/ + 0x01,0x00,0x3F,0x22,0x22,0x22,0x2F,0x22,0x22,0x22,0x24,0x24,0x48,0x48,0x93,0x20, + 0x00,0x80,0xFE,0x20,0x10,0x00,0xFC,0x40,0x40,0x48,0x50,0x60,0x42,0xC2,0x3E,0x00, + /* 0xC5D4 [?] [3436]*/ + 0x02,0x01,0x3F,0x08,0x04,0x7F,0x42,0x81,0x3F,0x04,0x04,0x07,0x08,0x08,0x10,0x20, + 0x00,0x00,0xF8,0x20,0x40,0xFE,0x02,0x04,0xF8,0x00,0x00,0xF0,0x10,0x10,0x50,0x20, + /* 0xC5D5 [?] [3437]*/ + 0x10,0x10,0x13,0xFD,0x10,0x7B,0x12,0xFC,0x10,0x3B,0x34,0x54,0x90,0x11,0x11,0x12, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xC5D6 [?] [3438]*/ + 0x00,0x3C,0x25,0x24,0x24,0x3C,0x25,0x24,0x24,0x3C,0x27,0x24,0x24,0x44,0x54,0x88, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xC5D7 [?] [3439]*/ + 0x12,0x12,0x12,0x12,0xFA,0x17,0x12,0x1A,0x32,0xD2,0x12,0x12,0x14,0x14,0x58,0x30, + 0x10,0x10,0x10,0x7C,0x14,0x94,0x94,0x94,0xA4,0xA4,0xD4,0x8A,0x82,0x82,0x7E,0x00, + /* 0xC5D8 [?] [3440]*/ + 0x00,0x00,0x79,0x49,0x4A,0x4D,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x00,0x00, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xC5D9 [?] [3441]*/ + 0x10,0x10,0x3F,0x21,0x41,0xBD,0x25,0x25,0x3D,0x21,0x25,0x22,0x20,0x20,0x1F,0x00, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x84,0x84,0x94,0x08, + /* 0xC5DA [?] [3442]*/ + 0x10,0x10,0x11,0x15,0x5A,0x55,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x40,0x80, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xC5DB [?] [3443]*/ + 0x20,0x10,0x01,0xF9,0x0A,0x15,0x11,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x10,0x10, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xC5DC [?] [3444]*/ + 0x00,0x7C,0x45,0x45,0x46,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x00,0x00, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xC5DD [?] [3445]*/ + 0x01,0x21,0x11,0x12,0x82,0x47,0x4A,0x12,0x12,0x23,0xE2,0x22,0x22,0x22,0x21,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x14,0x08,0x02,0x02,0xFE,0x00, + /* 0xC5DE [?] [3446]*/ + 0x00,0x03,0x78,0x48,0x48,0x48,0x48,0x49,0x4A,0x4C,0x78,0x48,0x00,0x00,0x07,0x00, + 0x00,0xFC,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x44,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xC5DF [?] [3447]*/ + 0x00,0x7B,0x48,0x48,0x48,0x78,0x48,0x49,0x4A,0x7C,0x48,0x48,0x48,0x48,0x4F,0x98, + 0x00,0xFC,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x44,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xC5E0 [?] [3448]*/ + 0x10,0x10,0x11,0x10,0x11,0xFC,0x10,0x13,0x10,0x10,0x11,0x1D,0xE1,0x41,0x01,0x01, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5E1 [?] [3449]*/ + 0x04,0x04,0x7C,0x04,0x3C,0x04,0x7C,0x06,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x40,0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xC5E2 [?] [3450]*/ + 0x00,0x7C,0x45,0x54,0x55,0x54,0x54,0x57,0x54,0x54,0x55,0x11,0x29,0x25,0x45,0x81, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5E3 [?] [3451]*/ + 0x00,0x7C,0x45,0x48,0x49,0x50,0x48,0x4B,0x44,0x44,0x45,0x69,0x51,0x41,0x41,0x41, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xC5E4 [?] [3452]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x88,0x80,0x80,0x80,0x82,0x82,0x7E,0x00, + /* 0xC5E5 [?] [3453]*/ + 0x10,0x17,0x14,0x24,0x25,0x64,0x64,0xA5,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x28, + 0x00,0xFC,0x04,0x04,0xF4,0x44,0x44,0xF4,0x54,0x54,0x54,0x54,0x74,0x46,0x46,0x42, + /* 0xC5E6 [?] [3454]*/ + 0x00,0x40,0x20,0x2F,0x00,0x80,0x47,0x54,0x14,0x24,0xE4,0x24,0x24,0x20,0x20,0x00, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40, + /* 0xC5E7 [?] [3455]*/ + 0x00,0x01,0x78,0x48,0x4B,0x48,0x48,0x49,0x49,0x49,0x79,0x49,0x01,0x00,0x00,0x03, + 0x20,0xFC,0x20,0x88,0xFE,0x88,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xC5E8 [?] [3456]*/ + 0x04,0x08,0x10,0x2F,0xC4,0x04,0x08,0x10,0x60,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x40,0x20,0x10,0xE8,0x26,0x20,0x20,0xA0,0x40,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xC5E9 [?] [3457]*/ + 0x00,0x01,0xFC,0x10,0x11,0x20,0x3C,0x64,0x67,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC5EA [?] [3458]*/ + 0x10,0x11,0x10,0x10,0xFD,0x10,0x10,0x14,0x1B,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC5EB [?] [3459]*/ + 0x01,0xFF,0x00,0x1F,0x10,0x1F,0x00,0x3F,0x00,0x01,0x01,0x05,0x02,0x48,0x44,0x84, + 0x00,0xFE,0x00,0xF0,0x10,0xF0,0x00,0xF0,0x60,0x80,0x00,0x00,0x00,0x88,0x44,0x44, + /* 0xC5EC [?] [3460]*/ + 0x01,0x41,0x2F,0x21,0x01,0x87,0x40,0x57,0x14,0x24,0xE7,0x24,0x22,0x20,0x2F,0x04, + 0x04,0x04,0xE8,0x10,0x00,0xC4,0x04,0xC8,0x50,0x42,0xC2,0x44,0x84,0xE8,0x10,0x20, + /* 0xC5ED [?] [3461]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7F,0x00,0x7F,0x41,0x41,0x7F,0x00,0x22,0x17,0xF8,0x40, + 0x00,0x04,0x84,0x08,0x10,0x22,0x02,0x04,0x08,0x10,0x22,0x02,0x04,0x88,0x10,0x60, + /* 0xC5EE [?] [3462]*/ + 0x08,0xFF,0x08,0x01,0x23,0x15,0x10,0x07,0x70,0x13,0x10,0x11,0x10,0x17,0x28,0x47, + 0x20,0xFE,0x20,0x00,0xF0,0x10,0xE0,0x1C,0x40,0xF8,0x40,0xF0,0x40,0xFC,0x40,0xFE, + /* 0xC5EF [?] [3463]*/ + 0x10,0x13,0x12,0x12,0xFE,0x13,0x32,0x3A,0x56,0x53,0x92,0x12,0x12,0x12,0x15,0x18, + 0x00,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0x52,0x52,0xA6, + /* 0xC5F0 [?] [3464]*/ + 0x00,0x03,0xFA,0x22,0x22,0x43,0x7A,0x4A,0xCA,0x4B,0x4A,0x4A,0x7A,0x4A,0x05,0x08, + 0x00,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0x52,0x52,0xA6, + /* 0xC5F1 [?] [3465]*/ + 0x20,0x3F,0x48,0x85,0x23,0x15,0x10,0x07,0x70,0x13,0x10,0x11,0x10,0x17,0x28,0x47, + 0x40,0x7E,0x90,0x08,0xF0,0x10,0xE0,0x1C,0x40,0xF8,0x40,0xF0,0x40,0xFC,0x40,0xFE, + /* 0xC5F2 [?] [3466]*/ + 0x00,0x78,0x4F,0x48,0x48,0x7B,0x48,0x4B,0x4A,0x7A,0x4B,0x4A,0x49,0x48,0x4F,0x9A, + 0x82,0x82,0xF4,0x88,0x80,0xE2,0x02,0xE4,0x28,0x20,0xE0,0x22,0x42,0x74,0x88,0x10, + /* 0xC5F3 [?] [3467]*/ + 0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x42,0x4A,0x85, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x84,0x94,0x08, + /* 0xC5F4 [?] [3468]*/ + 0x00,0x77,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0xB5,0x89,0x13, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xC5F5 [?] [3469]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x13,0x14,0x19,0x32,0xD0,0x10,0x13,0x10,0x50,0x20, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x24,0x22,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xC5F6 [?] [3470]*/ + 0x01,0x00,0xF8,0x23,0x20,0x40,0x78,0x4C,0xCA,0x4A,0x48,0x48,0x78,0x48,0x07,0x00, + 0x08,0x90,0x00,0xFC,0x90,0x90,0x92,0x92,0x94,0x98,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xC5F7 [?] [3471]*/ + 0x10,0x13,0x10,0x10,0x10,0xFE,0x10,0x11,0x12,0x14,0x16,0x18,0xE0,0x40,0x07,0x00, + 0x00,0xFC,0x20,0x20,0x40,0x40,0xD0,0x48,0x44,0x44,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xC5F8 [?] [3472]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x00, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xC5F9 [?] [3473]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x7E,0x42,0x7E,0x40,0x7E,0x62,0xBE,0x22, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x10,0xFE,0x44,0x28,0xFE,0x10,0x7C,0x10,0x10, + /* 0xC5FA [?] [3474]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x20, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xC5FB [?] [3475]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xC5FC [?] [3476]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3C,0x00,0x7F,0x04,0x08,0x10,0x60, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xC5FD [?] [3477]*/ + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00,0x20,0x20,0x3E,0x20,0x20,0x26,0x38, + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00,0x80,0x84,0x98,0xE0,0x84,0x84,0x7C, + /* 0xC5FE [?] [3478]*/ + 0x00,0x01,0x7D,0x55,0x55,0x55,0x55,0x7D,0x55,0x55,0x55,0x55,0x7D,0x45,0x01,0x00, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xC6A1 [?] [3479]*/ + 0x00,0x00,0x7B,0x4A,0x4A,0x4B,0x4A,0x4A,0x4B,0x48,0x79,0x4F,0x00,0x00,0x00,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xC6A2 [?] [3480]*/ + 0x00,0x78,0x4B,0x4A,0x4A,0x7B,0x4A,0x4A,0x4B,0x78,0x49,0x4F,0x48,0x48,0x48,0x98, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xC6A3 [?] [3481]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x54,0x14,0x37,0x55,0x95,0x14,0x24,0x28,0x49,0x96, + 0x80,0x40,0xFE,0x40,0x40,0xFC,0x44,0x40,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xC6A4 [?] [3482]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x2F,0x24,0x24,0x22,0x21,0x20,0x41,0x46,0x98, + 0x80,0x80,0x80,0xFC,0x84,0x88,0x80,0xF0,0x10,0x10,0x20,0x40,0x80,0x40,0x30,0x0E, + /* 0xC6A5 [?] [3483]*/ + 0x00,0x7F,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x48,0x50,0x40,0x7F,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x3C,0x00,0x00,0xFE,0x00, + /* 0xC6A6 [?] [3484]*/ + 0x00,0x00,0x1F,0x10,0x97,0x50,0x50,0x11,0x36,0x50,0x90,0x13,0x22,0x22,0x42,0x83, + 0x80,0x40,0xFE,0x00,0xFC,0x20,0x40,0xD0,0x48,0x44,0x00,0xF8,0x08,0x08,0x08,0xF8, + /* 0xC6A7 [?] [3485]*/ + 0x10,0x10,0x17,0x24,0x24,0x64,0x67,0xA4,0x24,0x27,0x26,0x2A,0x2A,0x2B,0x32,0x20, + 0x10,0x08,0x88,0xBE,0x80,0x94,0x88,0x7E,0x08,0x88,0xBE,0x88,0x88,0x88,0x88,0x08, + /* 0xC6A8 [?] [3486]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x28,0x28,0x28,0x2F,0x28,0x28,0x48,0x49,0x8A,0x0C, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x44,0x44,0x44,0x3C, + /* 0xC6A9 [?] [3487]*/ + 0x3E,0x22,0x3E,0x20,0x7E,0xA2,0x3E,0x22,0x01,0xFF,0x00,0x3F,0x00,0x3F,0x20,0x3F, + 0x10,0xFE,0x44,0x28,0xFE,0x10,0xFC,0x10,0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8, + /* 0xC6AA [?] [3488]*/ + 0x20,0x3F,0x48,0x85,0x00,0x3F,0x20,0x3F,0x20,0x2F,0x29,0x29,0x2F,0x49,0x49,0x88, + 0x40,0x7E,0x90,0x08,0x80,0xFC,0x04,0xFC,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0x0C, + /* 0xC6AB [?] [3489]*/ + 0x10,0x10,0x17,0x24,0x24,0x67,0x64,0xA4,0x27,0x26,0x2A,0x2B,0x2A,0x2A,0x32,0x22, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0xA4,0xA4,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xC6AC [?] [3490]*/ + 0x00,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x20,0x20,0x40, + 0x40,0x40,0x40,0x40,0x40,0xFC,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC6AD [?] [3491]*/ + 0x00,0xF8,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1E,0xE6,0x44,0x04,0x28,0x10, + 0x40,0x20,0xFE,0x02,0x02,0xFE,0x00,0x00,0xFE,0xAA,0xAA,0xFE,0xAA,0xAA,0xA2,0x86, + /* 0xC6AE [?] [3492]*/ + 0x00,0xFE,0x28,0xFE,0xAA,0xAA,0xFE,0x00,0x7C,0x00,0xFE,0x10,0x54,0x93,0x51,0x22, + 0x00,0xF8,0x88,0x88,0x88,0x98,0xD8,0xA8,0xA8,0xA8,0xD8,0x8A,0x8A,0x0A,0x06,0x02, + /* 0xC6AF [?] [3493]*/ + 0x00,0x4F,0x20,0x27,0x04,0x84,0x47,0x50,0x17,0x20,0xEF,0x20,0x22,0x24,0x29,0x00, + 0x00,0xFE,0xA0,0xFC,0xA4,0xA4,0xFC,0x00,0xFC,0x00,0xFE,0x40,0x48,0x44,0x42,0x80, + /* 0xC6B0 [?] [3494]*/ + 0x00,0xFE,0x28,0xFE,0xAA,0xAA,0xFE,0x00,0x7C,0x00,0xFE,0x10,0x54,0x93,0x51,0x22, + 0x08,0x1C,0xE8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA4,0xA4,0xA4,0xA2,0x28,0x34,0x24, + /* 0xC6B1 [?] [3495]*/ + 0x00,0x7F,0x04,0x3F,0x24,0x24,0x3F,0x00,0x3F,0x00,0xFF,0x01,0x11,0x21,0x45,0x02, + 0x00,0xFC,0x40,0xF8,0x48,0x48,0xF8,0x00,0xF8,0x00,0xFE,0x00,0x10,0x08,0x04,0x00, + /* 0xC6B2 [?] [3496]*/ + 0x21,0x21,0x25,0x23,0xF9,0x27,0x25,0x2D,0x35,0xE7,0x25,0x25,0x25,0x25,0xA4,0x44, + 0x08,0x08,0x48,0x90,0x1E,0xD4,0x64,0x54,0x54,0x54,0xD4,0x48,0x48,0x54,0x64,0xC2, + /* 0xC6B3 [?] [3497]*/ + 0x08,0x49,0x2A,0x7F,0x49,0x5D,0x6B,0x49,0x43,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F, + 0x20,0x20,0x3E,0x48,0x48,0xA8,0x10,0x28,0x46,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xC6B4 [?] [3498]*/ + 0x11,0x10,0x10,0x10,0xFD,0x10,0x10,0x14,0x18,0x33,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x04,0x84,0x88,0x00,0xFE,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xC6B5 [?] [3499]*/ + 0x10,0x11,0x50,0x5C,0x51,0x51,0xFF,0x01,0x11,0x55,0x55,0x55,0x84,0x08,0x31,0xC2, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xC6B6 [?] [3500]*/ + 0x04,0x08,0x30,0xDF,0x04,0x04,0x08,0x10,0x3F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x40,0x20,0x18,0xE6,0x20,0x20,0xA0,0x40,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xC6B7 [?] [3501]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xC6B8 [?] [3502]*/ + 0x00,0xFC,0x49,0x49,0x79,0x49,0x49,0x78,0x4B,0x48,0x4D,0x79,0xC8,0x08,0x08,0x08, + 0x20,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE,0x80,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xC6B9 [?] [3503]*/ + 0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0xFF,0x00,0x08,0x10,0x20,0x40, + 0x20,0xF0,0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xC6BA [?] [3504]*/ + 0x10,0x11,0x10,0x10,0x11,0xFC,0x10,0x10,0x13,0x10,0x10,0x1C,0xE0,0x40,0x00,0x00, + 0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC6BB [?] [3505]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x01,0x11,0x09,0x09,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0x10,0x10,0x20,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xC6BC [?] [3506]*/ + 0x08,0x08,0xFF,0x08,0x20,0x17,0x90,0x42,0x49,0x08,0x17,0xE0,0x20,0x20,0x20,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x40,0x48,0x50,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xC6BD [?] [3507]*/ + 0x00,0x7F,0x01,0x01,0x11,0x09,0x09,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0xFC,0x00,0x00,0x10,0x10,0x20,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC6BE [?] [3508]*/ + 0x08,0x0B,0x10,0x30,0x57,0x90,0x10,0x10,0x13,0x00,0x0F,0x08,0x08,0x10,0x20,0xC0, + 0x38,0xC0,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x00,0xE0,0x20,0x20,0x22,0x22,0x1E, + /* 0xC6BF [?] [3509]*/ + 0x42,0x24,0x00,0x7E,0x24,0x24,0x24,0x24,0xFE,0x24,0x24,0x24,0x24,0x44,0x44,0x84, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xC6C0 [?] [3510]*/ + 0x00,0x23,0x10,0x10,0x02,0x01,0xF1,0x10,0x17,0x10,0x10,0x14,0x18,0x10,0x00,0x00, + 0x00,0xF8,0x40,0x40,0x48,0x48,0x50,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xC6C1 [?] [3511]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x24,0x22,0x2F,0x22,0x22,0x3F,0x22,0x42,0x44,0x84,0x08, + 0x00,0xF8,0x08,0x08,0xF8,0x10,0x20,0xF8,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xC6C2 [?] [3512]*/ + 0x20,0x20,0x20,0x23,0x22,0xFA,0x22,0x23,0x22,0x22,0x22,0x3A,0xE2,0x44,0x04,0x09, + 0x20,0x20,0x20,0xFE,0x22,0x24,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xC6C3 [?] [3513]*/ + 0x00,0x20,0x12,0x12,0x83,0x40,0x48,0x08,0x11,0x11,0xE1,0x22,0x22,0x24,0x28,0x03, + 0x40,0x48,0x44,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xC6C4 [?] [3514]*/ + 0x08,0x08,0x08,0x7F,0x49,0x4A,0x48,0x7F,0x41,0x52,0x4A,0x44,0x4A,0x91,0x21,0x00, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xC6C5 [?] [3515]*/ + 0x20,0x13,0x92,0x42,0x4B,0x12,0xE4,0x24,0x29,0x04,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x20,0xFE,0x22,0x20,0xFC,0x84,0x48,0x30,0xCE,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xC6C6 [?] [3516]*/ + 0x00,0x00,0xFC,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x26,0x22,0x04, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xC6C7 [?] [3517]*/ + 0x10,0x10,0x21,0x7D,0x45,0x45,0x45,0x7D,0x45,0x44,0x44,0x44,0x7C,0x45,0x01,0x02, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x40,0x68,0xB2,0xBE,0x20,0x22,0x1E, + /* 0xC6C8 [?] [3518]*/ + 0x00,0x20,0x10,0x13,0x02,0x02,0xF2,0x13,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0x40,0x40,0x80,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xC6C9 [?] [3519]*/ + 0x10,0x10,0x94,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC6CA [?] [3520]*/ + 0x10,0x08,0x7F,0x00,0x21,0x12,0xFF,0x00,0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x00, + 0x04,0x04,0x84,0x24,0x24,0x24,0xE4,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xC6CB [?] [3521]*/ + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x12,0x1C,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x80,0x80,0x80,0x80,0x80,0xA0,0x90,0x88,0x84,0x84,0x80,0x80,0x80,0x80,0x80,0x80, + /* 0xC6CC [?] [3522]*/ + 0x20,0x20,0x3B,0x20,0x40,0x7B,0xA2,0x22,0xFB,0x22,0x22,0x23,0x2A,0x32,0x22,0x02, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xC6CD [?] [3523]*/ + 0x08,0x08,0x08,0x10,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xC6CE [?] [3524]*/ + 0x08,0x08,0xFF,0x09,0x01,0xFF,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x21,0x21,0x21, + 0x20,0x20,0xFE,0x20,0x10,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xC6CF [?] [3525]*/ + 0x04,0x04,0xFF,0x24,0x3F,0x42,0x7F,0x82,0x3F,0x22,0x3F,0x22,0x3F,0x22,0x22,0x20, + 0x40,0x40,0xFE,0x40,0xFC,0x24,0xF4,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0xA4,0x4C, + /* 0xC6D0 [?] [3526]*/ + 0x08,0x08,0xFF,0x08,0x01,0x3F,0x08,0x04,0xFF,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x20,0x40,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xC6D1 [?] [3527]*/ + 0x08,0x08,0xFF,0x08,0x40,0x27,0x20,0x87,0x44,0x57,0x14,0xE7,0x24,0x24,0x24,0x04, + 0x20,0x20,0xFE,0x28,0x44,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xC6D2 [?] [3528]*/ + 0x20,0x20,0x27,0x20,0x20,0xFB,0x22,0x22,0x23,0x22,0x22,0x3B,0xE2,0x42,0x02,0x02, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xC6D3 [?] [3529]*/ + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08,0x08, + 0x40,0x40,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xC6D4 [?] [3530]*/ + 0x00,0x7F,0x41,0x41,0x5F,0x41,0x4F,0x49,0x4F,0x49,0x4F,0x49,0x49,0x40,0x7F,0x40, + 0x00,0xFC,0x44,0x24,0xF4,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0x64,0x04,0xFC,0x04, + /* 0xC6D5 [?] [3531]*/ + 0x08,0x04,0x7F,0x04,0x24,0x14,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x40,0xFC,0x40,0x48,0x50,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xC6D6 [?] [3532]*/ + 0x00,0x40,0x2F,0x20,0x00,0x87,0x44,0x54,0x17,0x24,0xE4,0x27,0x24,0x24,0x24,0x04, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xC6D7 [?] [3533]*/ + 0x02,0x41,0x27,0x20,0x04,0x02,0xEF,0x20,0x23,0x22,0x22,0x23,0x2A,0x32,0x23,0x02, + 0x08,0x10,0xFC,0xA0,0xA4,0xA8,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC6D8 [?] [3534]*/ + 0x03,0x02,0xF3,0x92,0x93,0x91,0x97,0xF1,0x9F,0x91,0x92,0x95,0xF0,0x91,0x02,0x00, + 0xF8,0x08,0xF8,0x08,0xF8,0x10,0xFC,0x10,0xFE,0x10,0x48,0x54,0xE0,0x50,0x48,0xC0, + /* 0xC6D9 [?] [3535]*/ + 0x03,0x22,0x13,0x12,0x83,0x41,0x47,0x11,0x1F,0x21,0xE2,0x25,0x20,0x21,0x22,0x00, + 0xF8,0x08,0xF8,0x08,0xF8,0x10,0xFC,0x10,0xFE,0x10,0x48,0x54,0xE0,0x50,0x48,0xC0, + /* 0xC6DA [?] [3536]*/ + 0x22,0x22,0x7F,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0xFF,0x04,0x22,0x41,0x82, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x84,0x84,0x14,0x08, + /* 0xC6DB [?] [3537]*/ + 0x22,0x22,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0xFF,0x24,0x22,0x42,0x81, + 0x20,0x20,0xA0,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0xA8,0x48,0x44,0x84,0x02, + /* 0xC6DC [?] [3538]*/ + 0x10,0x17,0x10,0x10,0xFC,0x13,0x32,0x3A,0x56,0x52,0x92,0x13,0x12,0x12,0x13,0x12, + 0x00,0xFE,0x90,0x90,0x90,0xFC,0x94,0x94,0x94,0x94,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xC6DD [?] [3539]*/ + 0x00,0x00,0x00,0x3F,0x22,0x23,0x22,0x22,0x3F,0x20,0x22,0x2A,0x32,0x42,0x4A,0x84, + 0x28,0x24,0x20,0xFE,0x20,0xA0,0x24,0x24,0xE4,0x28,0x28,0x90,0x52,0x2A,0x46,0x82, + /* 0xC6DE [?] [3540]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x02,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xC6DF [?] [3541]*/ + 0x02,0x02,0x02,0x02,0x02,0x02,0x07,0xFA,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0x3C,0xC0,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xC6E0 [?] [3542]*/ + 0x00,0x40,0x27,0x20,0x03,0x00,0x17,0x10,0x23,0xE0,0x27,0x21,0x23,0x20,0x21,0x06, + 0x40,0x40,0xFC,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x80,0xFE,0x08,0x90,0x60,0x98,0x04, + /* 0xC6E1 [?] [3543]*/ + 0x00,0x20,0x17,0x10,0x81,0x46,0x40,0x11,0x12,0x2C,0xE2,0x21,0x22,0x24,0x21,0x00, + 0x40,0x40,0xFC,0xE0,0x58,0x44,0xA0,0x10,0x48,0x46,0x48,0x50,0x48,0x44,0x40,0x80, + /* 0xC6E2 [?] [3544]*/ + 0x20,0x10,0x00,0x47,0x20,0x08,0x10,0x60,0x21,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x80,0x80,0x9C,0xE0,0x80,0x84,0x84,0x7C,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC6E3 [?] [3545]*/ + 0x00,0x22,0x12,0x12,0x82,0x42,0x53,0x1E,0x12,0x22,0xE2,0x23,0x22,0x20,0x20,0x01, + 0x00,0x00,0xFC,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0xA4,0x24,0x44,0x44,0x94,0x08, + /* 0xC6E4 [?] [3546]*/ + 0x08,0x08,0x7F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x08,0x08,0xFF,0x00,0x08,0x10,0x20, + 0x20,0x20,0xFC,0x20,0x20,0xE0,0x20,0x20,0xE0,0x20,0x20,0xFE,0x00,0x20,0x10,0x08, + /* 0xC6E5 [?] [3547]*/ + 0x11,0x11,0x13,0x11,0xFD,0x11,0x31,0x39,0x55,0x51,0x91,0x17,0x10,0x10,0x11,0x12, + 0x08,0x08,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00,0x90,0x08,0x04, + /* 0xC6E6 [?] [3548]*/ + 0x01,0x01,0x3F,0x02,0x04,0x08,0xFF,0x00,0x00,0x1F,0x10,0x10,0x1F,0x00,0x00,0x00, + 0x00,0x00,0xF8,0x80,0x40,0x20,0xFE,0x10,0x10,0x90,0x90,0x90,0x90,0x10,0x50,0x20, + /* 0xC6E7 [?] [3549]*/ + 0x08,0x08,0x08,0x0B,0x48,0x4E,0x48,0x49,0x48,0x48,0x48,0x4E,0x58,0xE0,0x01,0x06, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xC6E8 [?] [3550]*/ + 0x00,0x00,0x7D,0x54,0x54,0x54,0x57,0x7C,0x54,0x54,0x55,0x54,0x7C,0x44,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xC6E9 [?] [3551]*/ + 0x10,0x10,0x11,0x10,0x54,0x55,0x57,0x54,0x55,0x55,0x55,0x5D,0x65,0x00,0x00,0x00, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFE,0x08,0xE8,0x28,0x28,0xE8,0x28,0x08,0x28,0x10, + /* 0xC6EA [?] [3552]*/ + 0x00,0x78,0x4B,0x49,0x48,0x78,0x48,0x48,0x4B,0x78,0x48,0x48,0x48,0x49,0x49,0x9A, + 0x40,0x20,0xFE,0x04,0x88,0x50,0x20,0xD8,0x06,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xC6EB [?] [3553]*/ + 0x02,0x01,0x7F,0x08,0x04,0x03,0x0C,0x30,0xC8,0x08,0x08,0x08,0x08,0x10,0x10,0x20, + 0x00,0x00,0xFC,0x20,0x40,0x80,0x60,0x18,0x26,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC6EC [?] [3554]*/ + 0x21,0x11,0x11,0x02,0xFC,0x21,0x20,0x3C,0x24,0x24,0x24,0x24,0x27,0x44,0x54,0x89, + 0x00,0x00,0xFE,0x00,0x88,0xFC,0x88,0xF8,0x88,0xF8,0x88,0x88,0xFE,0x50,0x88,0x04, + /* 0xC6ED [?] [3555]*/ + 0x20,0x10,0x11,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x11,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xC6EE [?] [3556]*/ + 0x20,0x10,0x10,0xFC,0x04,0x08,0x10,0x38,0x54,0x92,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x84,0x88,0x88,0x90,0x88,0x88,0x84,0x84,0xC4,0xA8,0x90,0x80,0x80,0x80, + /* 0xC6EF [?] [3557]*/ + 0x00,0xF8,0x09,0x48,0x48,0x49,0x4B,0x7C,0x05,0x05,0x1D,0xE5,0x45,0x04,0x28,0x10, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFE,0x08,0xE8,0x28,0x28,0xE8,0x28,0x08,0x28,0x10, + /* 0xC6F0 [?] [3558]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFE,0x08,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x88,0x80,0x80,0x84,0x84,0x7C,0x00,0xFE,0x00, + /* 0xC6F1 [?] [3559]*/ + 0x01,0x21,0x21,0x21,0x3F,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x1F, + 0x00,0x08,0x08,0x08,0xF8,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x04,0x04,0xFC, + /* 0xC6F2 [?] [3560]*/ + 0x08,0x08,0x1F,0x10,0x20,0x40,0x9F,0x00,0x00,0x01,0x06,0x08,0x10,0x10,0x0F,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xE0,0x20,0x40,0x80,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xC6F3 [?] [3561]*/ + 0x01,0x01,0x02,0x04,0x08,0x31,0xC1,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x00,0x00,0x80,0x40,0x20,0x18,0x06,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC6F4 [?] [3562]*/ + 0x01,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x17,0x24,0x24,0x44,0x87,0x04, + 0x00,0x80,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xC6F5 [?] [3563]*/ + 0x08,0x08,0x7F,0x08,0x3E,0x08,0x7F,0x08,0x09,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x7C,0x24,0x24,0x24,0x44,0x54,0x88,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xC6F6 [?] [3564]*/ + 0x00,0x01,0xF9,0x21,0x21,0x41,0x79,0x4F,0xC9,0x49,0x49,0x49,0x79,0x48,0x00,0x00, + 0x00,0x00,0x7E,0x12,0x12,0x12,0xD2,0x12,0x12,0x12,0x52,0x92,0x22,0x22,0x4A,0x84, + /* 0xC6F7 [?] [3565]*/ + 0x00,0x3E,0x22,0x22,0x3E,0x01,0x01,0xFF,0x02,0x0C,0x30,0xC0,0x3E,0x22,0x22,0x3E, + 0x00,0x7C,0x44,0x44,0x7C,0x20,0x10,0xFE,0x80,0x60,0x18,0x06,0x7C,0x44,0x44,0x7C, + /* 0xC6F8 [?] [3566]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x0A,0x0A,0x06,0x02, + /* 0xC6F9 [?] [3567]*/ + 0x01,0x21,0x11,0x12,0x04,0x01,0xF0,0x10,0x10,0x11,0x11,0x10,0x10,0x28,0x47,0x00, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x10,0x60,0x80,0x04,0x04,0xFC,0x00,0x00,0xFE,0x00, + /* 0xC6FA [?] [3568]*/ + 0x01,0x00,0x3F,0x02,0x04,0x08,0x1F,0x00,0x04,0x04,0x7F,0x04,0x04,0x08,0x10,0x20, + 0x00,0x80,0xFC,0x00,0x20,0x10,0xF8,0x08,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xC6FB [?] [3569]*/ + 0x01,0x21,0x11,0x12,0x84,0x41,0x48,0x08,0x13,0x10,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x0A,0x0A,0x06,0x02, + /* 0xC6FC [?] [3570]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x40,0x12,0x12,0x21,0xE1,0x21,0x21,0x20,0x2F,0x00, + 0x80,0x40,0x40,0x00,0xFC,0x00,0x08,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0xFE,0x00, + /* 0xC6FD [?] [3571]*/ + 0x00,0x20,0x11,0x11,0x02,0x04,0xF1,0x10,0x10,0x10,0x10,0x15,0x1A,0x12,0x01,0x00, + 0x80,0x80,0x00,0xFE,0x00,0x00,0xF8,0x08,0x10,0x60,0x80,0x00,0x02,0x02,0xFE,0x00, + /* 0xC6FE [?] [3572]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x10,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x40,0x40,0x7C,0x84,0x08,0x00,0x20,0xCE,0x02,0x02,0xCE,0x02,0x02,0x02,0xFE,0x02, + /* 0xC7A1 [?] [3573]*/ + 0x10,0x10,0x10,0x11,0x1A,0x54,0x53,0x50,0x90,0x13,0x12,0x12,0x12,0x12,0x13,0x12, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC7A2 [?] [3574]*/ + 0x00,0x20,0x10,0x11,0x82,0x44,0x43,0x10,0x10,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xC7A3 [?] [3575]*/ + 0x01,0x01,0x3F,0x02,0x04,0x08,0x7F,0x41,0x89,0x0F,0x11,0x01,0x7F,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x80,0x40,0x20,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x00,0x00,0x00, + /* 0xC7A4 [?] [3576]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x10,0x17,0x18,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC7A5 [?] [3577]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x13,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC7A6 [?] [3578]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x11,0x12,0xFC,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xF8,0x88,0x88,0x88,0x88,0x06,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC7A7 [?] [3579]*/ + 0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC7A8 [?] [3580]*/ + 0x00,0x20,0x13,0x10,0x00,0x00,0xF7,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x00, + 0x10,0x78,0xC0,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0xFE,0x00, + /* 0xC7A9 [?] [3581]*/ + 0x10,0x10,0x3F,0x28,0x45,0x82,0x04,0x08,0x37,0xC0,0x02,0x11,0x09,0x08,0x7F,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x80,0x40,0x20,0xD8,0x06,0x10,0x10,0x20,0x40,0xFC,0x00, + /* 0xC7AA [?] [3582]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x78,0xC0,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xC7AB [?] [3583]*/ + 0x02,0x41,0x20,0x27,0x00,0x07,0xE0,0x2F,0x20,0x27,0x20,0x29,0x32,0x2C,0x00,0x00, + 0x08,0x10,0x00,0xFE,0xA0,0xFC,0xA4,0xFE,0xA4,0xFC,0xA0,0xB0,0xA8,0xA6,0xA0,0xA0, + /* 0xC7AC [?] [3584]*/ + 0x10,0x10,0x10,0xFE,0x11,0x7E,0x44,0x7C,0x44,0x7C,0x10,0xFE,0x11,0x11,0x10,0x10, + 0x40,0x40,0x80,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xC7AD [?] [3585]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x92,0xFF,0x12,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x20,0x20,0x20,0x50,0x50,0x88,0x44,0x22,0x20,0xF8,0x08,0x08,0x10,0x10,0x20,0x20, + /* 0xC7AE [?] [3586]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBC,0x10,0x11,0xFC,0x10,0x10,0x10,0x14,0x18,0x13,0x00, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xC7AF [?] [3587]*/ + 0x10,0x10,0x3C,0x20,0x43,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xC7B0 [?] [3588]*/ + 0x10,0x08,0x08,0xFF,0x00,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x2A,0x24, + 0x10,0x10,0x20,0xFE,0x00,0x08,0x48,0x48,0x48,0x48,0x48,0x48,0x08,0x08,0x28,0x10, + /* 0xC7B1 [?] [3589]*/ + 0x01,0x41,0x27,0x21,0x0F,0x81,0x42,0x54,0x13,0x22,0xE2,0x23,0x22,0x22,0x23,0x02, + 0x10,0x10,0xBC,0x10,0xFE,0x10,0xA8,0x44,0xFA,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC7B2 [?] [3590]*/ + 0x00,0x23,0x12,0x13,0x00,0x07,0xF0,0x13,0x12,0x13,0x12,0x13,0x12,0x13,0x28,0x47, + 0x40,0xF8,0x48,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xC7B3 [?] [3591]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x40,0x17,0x10,0x20,0xE0,0x20,0x20,0x21,0x26,0x00, + 0xA0,0x90,0x80,0xB8,0xC0,0x80,0xBC,0xC0,0x88,0x90,0x60,0x44,0xA4,0x14,0x0C,0x04, + /* 0xC7B4 [?] [3592]*/ + 0x00,0x44,0x22,0x22,0x00,0x01,0xE0,0x2E,0x22,0x22,0x22,0x22,0x2A,0x32,0x25,0x08, + 0x10,0xFE,0x92,0xFE,0x10,0xFE,0x00,0xFE,0x82,0xFE,0x80,0xFE,0x82,0xFE,0x00,0xFE, + /* 0xC7B5 [?] [3593]*/ + 0x10,0xFE,0x20,0x48,0x7E,0x08,0x0E,0xF9,0x4A,0x09,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xC7B6 [?] [3594]*/ + 0x01,0x21,0x21,0x3F,0x00,0x22,0x22,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x00, + 0x00,0x08,0x08,0xF8,0x20,0x20,0x3E,0x42,0x94,0x10,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xC7B7 [?] [3595]*/ + 0x08,0x08,0x08,0x0F,0x10,0x11,0x21,0x41,0x01,0x02,0x02,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0xFC,0x04,0x08,0x10,0x00,0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x06, + /* 0xC7B8 [?] [3596]*/ + 0x22,0x14,0xFF,0x14,0x14,0x7F,0x15,0xFF,0x15,0x7F,0x14,0x36,0x55,0x94,0x14,0x14, + 0x20,0x20,0xA0,0x7E,0x42,0x84,0x10,0x90,0x10,0x10,0x28,0x28,0x28,0xC4,0x44,0x82, + /* 0xC7B9 [?] [3597]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x34,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xC7BA [?] [3598]*/ + 0x00,0x00,0x78,0x48,0x49,0x4A,0x4C,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x00,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xC7BB [?] [3599]*/ + 0x00,0x78,0x48,0x4B,0x4A,0x7C,0x49,0x4A,0x48,0x79,0x48,0x48,0x48,0x48,0x4F,0x98, + 0x40,0x20,0x20,0xFE,0x02,0x94,0x08,0x04,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xC7BC [?] [3600]*/ + 0x08,0x04,0x04,0x7F,0x01,0x01,0x3F,0x02,0x02,0xFF,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x20,0x20,0x40,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x80,0x80,0x80,0x82,0x82,0x7E, + /* 0xC7BD [?] [3601]*/ + 0x20,0x20,0x27,0x20,0x22,0xF9,0x27,0x20,0x23,0x22,0x22,0x3A,0xE2,0x42,0x03,0x02, + 0x40,0x40,0xFC,0x40,0x48,0x50,0xFE,0x00,0xF8,0x08,0xE8,0xA8,0xE8,0x08,0xF8,0x08, + /* 0xC7BE [?] [3602]*/ + 0x08,0xFF,0x08,0x01,0x3F,0x11,0x09,0xFF,0x00,0x3F,0x20,0x27,0x24,0x27,0x20,0x3F, + 0x20,0xFE,0x20,0x00,0xF8,0x10,0x20,0xFE,0x00,0xF8,0x08,0xC8,0x48,0xC8,0x08,0xF8, + /* 0xC7BF [?] [3603]*/ + 0x00,0xF9,0x09,0x09,0x09,0x78,0x40,0x43,0x42,0x7A,0x0B,0x08,0x08,0x08,0x57,0x20, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x22,0xFE,0x20,0x24,0x22,0xFE,0x02, + /* 0xC7C0 [?] [3604]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x14,0x11,0x19,0x31,0xD1,0x11,0x11,0x11,0x50,0x20, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xC7C1 [?] [3605]*/ + 0x10,0x13,0x10,0x13,0xFC,0x13,0x38,0x34,0x50,0x57,0x91,0x17,0x11,0x17,0x11,0x11, + 0x38,0xC0,0x78,0xC0,0x78,0xC4,0x3C,0x00,0xC6,0x38,0xCE,0x38,0xCE,0x38,0x4A,0x86, + /* 0xC7C2 [?] [3606]*/ + 0x20,0x20,0x3B,0x21,0x41,0x79,0xA3,0x21,0xF9,0x23,0x25,0x21,0x29,0x31,0x21,0x01, + 0x08,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xC7C3 [?] [3607]*/ + 0x10,0x08,0xFF,0x00,0x7E,0x42,0x7E,0x00,0xFF,0x81,0xBD,0xA5,0xBD,0x81,0x85,0x82, + 0x10,0x10,0x10,0x1E,0x10,0x10,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xC7C4 [?] [3608]*/ + 0x10,0x11,0x10,0x10,0x18,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC7C5 [?] [3609]*/ + 0x20,0x20,0x23,0x20,0xF8,0x27,0x20,0x71,0x6A,0xA5,0xA1,0x21,0x21,0x22,0x22,0x24, + 0x10,0x78,0xC0,0x40,0x40,0xFE,0xA0,0x10,0x08,0x16,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xC7C6 [?] [3610]*/ + 0x00,0x00,0x79,0x49,0x4B,0x7D,0x49,0x49,0x79,0x49,0x49,0x49,0x79,0x4A,0x02,0x04, + 0xA0,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0xA4,0x52,0x52, + /* 0xC7C7 [?] [3611]*/ + 0x00,0x00,0x3F,0x01,0x02,0x7F,0x04,0x08,0x30,0xC8,0x08,0x08,0x08,0x10,0x10,0x20, + 0x10,0xF8,0x00,0x00,0x00,0xFC,0x40,0x20,0x18,0x26,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC7C8 [?] [3612]*/ + 0x08,0x08,0x0B,0x10,0x10,0x37,0x30,0x51,0x92,0x15,0x11,0x11,0x11,0x12,0x12,0x14, + 0x10,0x78,0xC0,0x40,0x40,0xFE,0xA0,0x10,0x08,0x16,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xC7C9 [?] [3613]*/ + 0x00,0x03,0xFC,0x10,0x10,0x10,0x11,0x11,0x10,0x10,0x1E,0xE0,0x40,0x00,0x00,0x00, + 0x00,0xFE,0x40,0x40,0x80,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC7CA [?] [3614]*/ + 0x28,0x28,0xFE,0x28,0x38,0x10,0x7C,0x54,0x54,0x7C,0x10,0xFE,0x10,0x10,0x10,0x10, + 0x10,0x92,0x52,0x54,0x10,0xFE,0x82,0x82,0xFE,0x82,0x82,0xFE,0x82,0x82,0x8A,0x84, + /* 0xC7CB [?] [3615]*/ + 0x10,0x13,0x10,0x13,0xFC,0x13,0x10,0x14,0x18,0x37,0xD1,0x17,0x11,0x17,0x51,0x21, + 0x38,0xC0,0x78,0xC0,0x78,0xC4,0x3C,0x00,0xC6,0x38,0xCE,0x38,0xCE,0x38,0x4A,0x86, + /* 0xC7CC [?] [3616]*/ + 0x20,0x21,0xFE,0x24,0x29,0x12,0x2A,0xC6,0x01,0xFC,0x28,0x29,0x28,0x48,0x47,0x80, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0xCC,0x54,0x44,0x44,0x54,0x8A,0x02,0xFE,0x00, + /* 0xC7CD [?] [3617]*/ + 0x10,0x11,0x10,0x10,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC7CE [?] [3618]*/ + 0x08,0x0A,0x09,0x11,0x10,0x33,0x32,0x52,0x93,0x12,0x12,0x13,0x12,0x12,0x12,0x12, + 0x40,0x48,0x48,0x50,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xC7CF [?] [3619]*/ + 0x02,0x01,0x7F,0x48,0x90,0x20,0x00,0x7D,0x10,0x10,0x11,0x10,0x1E,0xE0,0x40,0x00, + 0x00,0x00,0xFE,0x22,0x14,0x08,0x00,0xFE,0x40,0x80,0xFC,0x04,0x04,0x04,0x28,0x10, + /* 0xC7D0 [?] [3620]*/ + 0x10,0x10,0x11,0x10,0x10,0x1E,0xF0,0x10,0x10,0x12,0x14,0x18,0x10,0x01,0x02,0x04, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xC7D1 [?] [3621]*/ + 0x08,0x08,0xFF,0x08,0x00,0x10,0x10,0x7E,0x12,0x12,0x12,0x12,0x22,0x22,0x4A,0x84, + 0x20,0x20,0xFE,0x20,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xC7D2 [?] [3622]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0xFF,0x00, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xC7D3 [?] [3623]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x97,0x10,0x10,0x10,0x11,0x12,0x17,0x12, + 0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0x80,0x80,0x10,0x08,0xFC,0x04, + /* 0xC7D4 [?] [3624]*/ + 0x02,0x01,0x7F,0x48,0x90,0x20,0x21,0x2C,0xF0,0x20,0x20,0x24,0x28,0x31,0x22,0x04, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xC7D5 [?] [3625]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x11,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x11,0x02, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC7D6 [?] [3626]*/ + 0x08,0x0B,0x08,0x11,0x10,0x33,0x30,0x57,0x94,0x13,0x11,0x11,0x10,0x10,0x11,0x16, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x04,0xF0,0x10,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xC7D7 [?] [3627]*/ + 0x02,0x01,0x3F,0x00,0x08,0x04,0xFF,0x01,0x01,0x7F,0x01,0x09,0x11,0x21,0x45,0x02, + 0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00,0x00,0xFC,0x00,0x20,0x10,0x08,0x04,0x00, + /* 0xC7D8 [?] [3628]*/ + 0x01,0x7F,0x01,0x3F,0x02,0xFF,0x08,0x10,0x2F,0xC1,0x1F,0x05,0x09,0x11,0x61,0x01, + 0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0xD0,0x08,0x06,0xF0,0x40,0x20,0x10,0x08,0x00, + /* 0xC7D9 [?] [3629]*/ + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x01,0x06,0x1A,0xE1,0x1F,0x00,0x00,0x01, + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00,0xC0,0x30,0x0E,0xE0,0x40,0x80,0x00, + /* 0xC7DA [?] [3630]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x08,0x7F,0x49,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x0F,0xF2, + 0x20,0x20,0xA0,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xC7DB [?] [3631]*/ + 0x08,0x08,0xFF,0x08,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x20,0x20,0xFE,0x20,0x38,0xC0,0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xC7DC [?] [3632]*/ + 0x20,0x20,0x21,0x22,0xFD,0x20,0x22,0x2A,0x33,0xE0,0x27,0x24,0x25,0x25,0xA4,0x44, + 0x40,0xA0,0x10,0x48,0xF6,0xA0,0x48,0xA8,0xF8,0x40,0xFC,0x84,0x24,0xF4,0x14,0x0C, + /* 0xC7DD [?] [3633]*/ + 0x01,0x02,0x0C,0x31,0xCF,0x04,0x13,0x14,0x1F,0x01,0x7F,0x42,0x44,0x4F,0x44,0x40, + 0x00,0x80,0x60,0x18,0xE6,0x40,0x90,0x50,0xF0,0x00,0xFC,0x04,0x44,0xE4,0x24,0x0C, + /* 0xC7DE [?] [3634]*/ + 0x01,0x7F,0x40,0x80,0x13,0x10,0x91,0x50,0x53,0x10,0x37,0x54,0x93,0x11,0x10,0x17, + 0x00,0xFE,0x02,0x04,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x04,0xF8,0x10,0xE0,0x1C, + /* 0xC7DF [?] [3635]*/ + 0x00,0x20,0x10,0x10,0x81,0x41,0x41,0x15,0x15,0x25,0xE5,0x29,0x21,0x21,0x20,0x00, + 0x00,0x80,0x40,0x20,0x20,0x00,0x00,0x04,0x02,0x02,0x02,0x08,0x08,0x08,0xF8,0x00, + /* 0xC7E0 [?] [3636]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x01,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x50,0x20, + /* 0xC7E1 [?] [3637]*/ + 0x20,0x21,0x20,0xFC,0x40,0x50,0x90,0xFF,0x10,0x11,0x1C,0xF0,0x50,0x10,0x13,0x10, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xC7E2 [?] [3638]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x3F,0x03,0x0C,0x70,0x1F,0x02,0x02,0x7F,0x00, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x10,0xD0,0x30,0xD2,0x0A,0x0A,0xF6,0x02, + /* 0xC7E3 [?] [3639]*/ + 0x10,0x10,0x14,0x24,0x24,0x64,0x67,0xA4,0x24,0x24,0x25,0x26,0x24,0x20,0x20,0x20, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xC7E4 [?] [3640]*/ + 0x08,0x73,0x42,0x4A,0x4A,0x4B,0x4A,0x4A,0x4A,0x5B,0x6A,0x4A,0x12,0x12,0x23,0x42, + 0x00,0xDE,0x52,0x52,0x52,0xD2,0x52,0x52,0x52,0xD2,0x12,0x9A,0x54,0xB0,0x10,0x10, + /* 0xC7E5 [?] [3641]*/ + 0x00,0x20,0x17,0x10,0x83,0x40,0x47,0x10,0x13,0x22,0xE3,0x22,0x23,0x22,0x22,0x02, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xC7E6 [?] [3642]*/ + 0x24,0xFF,0x24,0x7E,0x82,0x7A,0x4A,0x7A,0x04,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x03, + 0x20,0x20,0x7E,0xC4,0x28,0x10,0x28,0xC6,0x20,0xC0,0x00,0xF8,0x00,0xFC,0x00,0x00, + /* 0xC7E7 [?] [3643]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4B,0x78,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xC7E8 [?] [3644]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x04,0x7F,0x04,0x3F,0x04,0xFF,0x20,0x3F,0x20,0x21, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x10,0x90,0x10,0xF2,0x8A,0x8A,0x86,0x82, + /* 0xC7E9 [?] [3645]*/ + 0x10,0x10,0x17,0x10,0x1B,0x54,0x57,0x50,0x93,0x12,0x13,0x12,0x13,0x12,0x12,0x12, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xC7EA [?] [3646]*/ + 0x00,0x21,0x20,0x20,0x21,0x3D,0x21,0x21,0x21,0x25,0x29,0x31,0x20,0x00,0x01,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xC7EB [?] [3647]*/ + 0x00,0x40,0x27,0x20,0x03,0x00,0xE7,0x20,0x23,0x22,0x23,0x22,0x2B,0x32,0x22,0x02, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xC7EC [?] [3648]*/ + 0x01,0x00,0x3F,0x20,0x20,0x20,0x20,0x2F,0x20,0x21,0x21,0x22,0x42,0x44,0x88,0x10, + 0x00,0x80,0xFE,0x00,0x80,0x80,0x80,0xFC,0x80,0x40,0x40,0x20,0x20,0x10,0x08,0x06, + /* 0xC7ED [?] [3649]*/ + 0x00,0x00,0xFB,0x20,0x20,0x21,0xF9,0x21,0x21,0x20,0x21,0x39,0xE2,0x44,0x00,0x00, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xC7EE [?] [3650]*/ + 0x02,0x01,0x7F,0x40,0x88,0x10,0x22,0x02,0x7F,0x02,0x04,0x04,0x08,0x10,0x20,0x40, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x08,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xC7EF [?] [3651]*/ + 0x08,0x1C,0xF0,0x10,0x11,0xFD,0x11,0x32,0x38,0x54,0x54,0x90,0x11,0x11,0x12,0x14, + 0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x50,0x40,0xA0,0xA0,0x90,0x10,0x08,0x04,0x02, + /* 0xC7F0 [?] [3652]*/ + 0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0x00, + 0x10,0x78,0x80,0x00,0x00,0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xC7F1 [?] [3653]*/ + 0x00,0x03,0x3C,0x20,0x20,0x20,0x3F,0x22,0x22,0x22,0x22,0x22,0x27,0xF8,0x40,0x00, + 0x00,0x3E,0x22,0x24,0x24,0x28,0xA4,0x24,0x22,0x22,0x22,0x34,0xA8,0x20,0x20,0x20, + /* 0xC7F2 [?] [3654]*/ + 0x00,0x00,0xFC,0x10,0x13,0x10,0x11,0x7C,0x10,0x10,0x10,0x11,0x1E,0xE0,0x40,0x00, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0xB2,0xB4,0x68,0xA8,0x24,0x22,0x20,0xA0,0x40, + /* 0xC7F3 [?] [3655]*/ + 0x01,0x01,0x01,0x7F,0x01,0x21,0x11,0x09,0x03,0x05,0x09,0x11,0x61,0x01,0x05,0x02, + 0x20,0x10,0x00,0xFC,0x00,0x08,0x10,0xA0,0x40,0x20,0x10,0x08,0x06,0x00,0x00,0x00, + /* 0xC7F4 [?] [3656]*/ + 0x00,0x7F,0x40,0x41,0x41,0x41,0x41,0x42,0x42,0x44,0x44,0x48,0x50,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x24,0x24,0x24,0x04,0xFC,0x04, + /* 0xC7F5 [?] [3657]*/ + 0x10,0x08,0x08,0xFF,0x04,0x04,0x7F,0x44,0x48,0x50,0x60,0x7F,0x40,0x40,0x7F,0x40, + 0x10,0x10,0x20,0xFE,0x40,0x40,0xFC,0x44,0x44,0x3C,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xC7F6 [?] [3658]*/ + 0x00,0x27,0x14,0x14,0x84,0x44,0x44,0x14,0x14,0x24,0xE4,0x25,0x26,0x24,0x27,0x04, + 0x00,0xFC,0x04,0x44,0x44,0x44,0x44,0x44,0x44,0xA4,0x94,0x14,0x04,0x04,0xFC,0x04, + /* 0xC7F7 [?] [3659]*/ + 0x08,0x08,0x08,0x7E,0x09,0x08,0xFE,0x08,0x28,0x28,0x2E,0x29,0x28,0x58,0x4F,0x80, + 0x40,0x40,0x78,0x88,0x10,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFE,0x00, + /* 0xC7F8 [?] [3660]*/ + 0x00,0x7F,0x40,0x40,0x44,0x42,0x41,0x40,0x41,0x42,0x44,0x48,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x10,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x10,0x00,0x00,0xFE,0x00, + /* 0xC7F9 [?] [3661]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1C,0xE4,0x43,0x00, + 0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0x84,0xFE,0x00, + /* 0xC7FA [?] [3662]*/ + 0x04,0x04,0x04,0x04,0x7F,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x44,0x7F,0x40, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0xFC,0x04, + /* 0xC7FB [?] [3663]*/ + 0x10,0x21,0x7D,0x45,0x7D,0x45,0x7D,0x45,0x45,0xFD,0x0D,0x15,0x25,0x45,0x95,0x08, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xC7FC [?] [3664]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x28,0x28,0x28,0x2F,0x20,0x30,0x50,0x50,0x9F,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x80,0x88,0x88,0x88,0xF8,0x80,0x84,0x84,0x84,0xFC,0x04, + /* 0xC7FD [?] [3665]*/ + 0x00,0xF9,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1D,0xE5,0x45,0x05,0x29,0x10, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xC7FE [?] [3666]*/ + 0x23,0x12,0x83,0x4A,0x0A,0x13,0xE2,0x23,0x21,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0xFC,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC8A1 [?] [3667]*/ + 0x00,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x27,0xFA,0x42,0x02,0x02,0x02, + 0x00,0x80,0xFC,0x44,0x44,0x44,0x44,0x44,0x28,0x28,0xA8,0x10,0x10,0x28,0x44,0x82, + /* 0xC8A2 [?] [3668]*/ + 0x00,0x7F,0x22,0x3E,0x22,0x3E,0x23,0xFE,0x02,0x04,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0x7C,0x44,0x44,0x28,0x10,0xA8,0x44,0x82,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xC8A3 [?] [3669]*/ + 0x10,0x11,0x50,0x5E,0x50,0x50,0xFE,0x00,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x02, + 0x0E,0xF0,0x10,0xFE,0x92,0x92,0xFE,0x10,0xFE,0x92,0x9A,0x96,0xFE,0x82,0x8A,0x84, + /* 0xC8A4 [?] [3670]*/ + 0x10,0x13,0x11,0x7D,0x11,0x11,0xFD,0x11,0x11,0x51,0x5D,0x53,0x70,0x50,0x4F,0x80, + 0x00,0xE0,0x5E,0x42,0xD2,0x4A,0x4A,0xC4,0x44,0x64,0xCA,0x4A,0x52,0x40,0xFE,0x00, + /* 0xC8A5 [?] [3671]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0xFF,0x02,0x02,0x04,0x08,0x10,0x3F,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x20,0x10,0xF8,0x08, + /* 0xC8A6 [?] [3672]*/ + 0x00,0x7F,0x49,0x45,0x5F,0x42,0x7F,0x48,0x57,0x64,0x44,0x44,0x43,0x40,0x7F,0x40, + 0x00,0xFC,0x24,0x44,0xF4,0x04,0xFC,0x24,0xD4,0x4C,0xC4,0x24,0xE4,0x04,0xFC,0x04, + /* 0xC8A7 [?] [3673]*/ + 0x22,0x22,0xFF,0x22,0x77,0x55,0x77,0x12,0x3F,0x64,0xBF,0x24,0x3F,0x24,0x3F,0x20, + 0x00,0x7E,0x90,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xC8A8 [?] [3674]*/ + 0x10,0x13,0x11,0x11,0xFD,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x11,0x16, + 0x00,0xFC,0x04,0x04,0x04,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xC8A9 [?] [3675]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x44,0x44,0xFE,0x44,0x10,0x28,0x44,0x82,0x7C,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00, + /* 0xC8AA [?] [3676]*/ + 0x01,0x02,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x01,0x7D,0x09,0x11,0x21,0xC5,0x02, + 0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x04,0x88,0x50,0x20,0x18,0x06,0x00, + /* 0xC8AB [?] [3677]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x2F,0xC1,0x01,0x01,0x1F,0x01,0x01,0x01,0x7F,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0xE8,0x06,0x00,0x00,0xF0,0x00,0x00,0x00,0xFC,0x00, + /* 0xC8AC [?] [3678]*/ + 0x00,0x00,0x1F,0x10,0x90,0x51,0x52,0x1D,0x30,0x50,0x93,0x10,0x20,0x20,0x4F,0x80, + 0x80,0x40,0xFE,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xF8,0x40,0x40,0x40,0xFE,0x00, + /* 0xC8AD [?] [3679]*/ + 0x01,0x11,0x09,0x3F,0x02,0x7F,0x08,0x10,0x3F,0xC1,0x1F,0x01,0x3F,0x01,0x05,0x02, + 0x00,0x10,0x20,0xF8,0x00,0xFC,0x20,0xF0,0x08,0x06,0xE0,0x00,0xF8,0x00,0x00,0x00, + /* 0xC8AE [?] [3680]*/ + 0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x20,0x10,0x10,0x00,0xFE,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xC8AF [?] [3681]*/ + 0x01,0x11,0x09,0x3F,0x02,0x02,0x7F,0x08,0x10,0x2F,0xC4,0x04,0x08,0x08,0x11,0x20, + 0x00,0x10,0x20,0xF8,0x00,0x00,0xFC,0x20,0x10,0xE8,0x26,0x20,0x20,0x20,0x40,0x80, + /* 0xC8B0 [?] [3682]*/ + 0x00,0x00,0x00,0xFC,0x05,0x04,0x48,0x28,0x10,0x10,0x28,0x24,0x45,0x81,0x02,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xC8B1 [?] [3683]*/ + 0x20,0x20,0x3C,0x51,0x90,0x10,0xFE,0x10,0x13,0x54,0x54,0x54,0x5C,0x64,0x05,0x02, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC8B2 [?] [3684]*/ + 0x10,0x10,0x10,0x17,0x58,0x50,0x50,0x90,0x17,0x10,0x10,0x28,0x25,0x41,0x42,0x84, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x06, + /* 0xC8B3 [?] [3685]*/ + 0x00,0x00,0x1F,0x12,0x97,0x52,0x54,0x15,0x38,0x57,0x94,0x15,0x24,0x24,0x45,0x84, + 0x80,0x40,0xFE,0x00,0xBC,0xA4,0xA4,0xBC,0x40,0xFC,0xA4,0x54,0x44,0xA4,0x14,0x0C, + /* 0xC8B4 [?] [3686]*/ + 0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0xFF,0x10,0x10,0x24,0x42,0xFF,0x41,0x00,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0xC4,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40, + /* 0xC8B5 [?] [3687]*/ + 0x24,0x24,0x24,0xFF,0x24,0x24,0xFF,0x00,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x42, + 0x10,0x20,0x7C,0x44,0x64,0x54,0xC4,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xC8B6 [?] [3688]*/ + 0x10,0x10,0x17,0x15,0xFD,0x13,0x36,0x3A,0x57,0x52,0x92,0x13,0x12,0x12,0x13,0x12, + 0x80,0x80,0xFE,0x22,0x10,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xC8B7 [?] [3689]*/ + 0x00,0x00,0xFC,0x10,0x11,0x22,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3C,0x25,0x21,0x02, + 0x40,0x40,0x7C,0x84,0x08,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x92,0x12,0x0A,0x04, + /* 0xC8B8 [?] [3690]*/ + 0x01,0x11,0x11,0x21,0x40,0x03,0x0C,0x30,0xDF,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0x10,0x08,0x24,0xC0,0x00,0x80,0x40,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00, + /* 0xC8B9 [?] [3691]*/ + 0x20,0x11,0x00,0xF8,0x0B,0x10,0x10,0x35,0x58,0x94,0x15,0x12,0x14,0x10,0x10,0x10, + 0x00,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x80,0x80,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xC8BA [?] [3692]*/ + 0x00,0x7E,0x12,0x12,0xFF,0x12,0x12,0x7E,0x20,0x20,0x7E,0x62,0xA2,0x22,0x3E,0x22, + 0x82,0x44,0x28,0xFE,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xC8BB [?] [3693]*/ + 0x10,0x10,0x1E,0x22,0x33,0x4A,0xA4,0x14,0x08,0x10,0x21,0x42,0x00,0x48,0x44,0x84, + 0x20,0x28,0x24,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02,0x00,0x88,0x44,0x44, + /* 0xC8BC [?] [3694]*/ + 0x11,0x11,0x11,0x16,0x5A,0x55,0x50,0x92,0x11,0x11,0x12,0x2C,0x24,0x42,0x42,0x84, + 0x10,0x14,0xD2,0x50,0x7E,0x50,0x90,0xA8,0x28,0x44,0x44,0x82,0x08,0xA4,0x52,0x52, + /* 0xC8BD [?] [3695]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x21,0xFF,0x20,0x20,0x20,0x20,0x20, + 0x00,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x28,0x10, + /* 0xC8BE [?] [3696]*/ + 0x20,0x10,0x03,0x40,0x21,0x09,0x12,0x64,0x29,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x80,0x80,0xF0,0x90,0x10,0x12,0x12,0x0E,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC8BF [?] [3697]*/ + 0x10,0xFE,0x00,0xEE,0xAA,0xEE,0x44,0xFE,0x44,0xFE,0x44,0xFE,0x50,0xCB,0x65,0x42, + 0x08,0x1C,0xE8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA4,0xA4,0xA4,0xA2,0x28,0x34,0x24, + /* 0xC8C0 [?] [3698]*/ + 0x20,0x27,0x20,0x23,0xF2,0x23,0x21,0x27,0x21,0x27,0x31,0xEF,0x41,0x03,0x0D,0x01, + 0x40,0xFC,0x00,0xB8,0xA8,0xB8,0x10,0xFC,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xC8C1 [?] [3699]*/ + 0x20,0x27,0x20,0x23,0xFA,0x23,0x21,0x2F,0x31,0xE7,0x21,0x2F,0x21,0x23,0xAD,0x41, + 0x40,0xFC,0x00,0xB8,0xA8,0xB8,0x10,0xFC,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xC8C2 [?] [3700]*/ + 0x00,0x07,0xF0,0x93,0x92,0x93,0x91,0x97,0x91,0x97,0xF1,0x9F,0x01,0x03,0x0D,0x01, + 0x40,0xFC,0x00,0xB8,0xA8,0xB8,0x10,0xFC,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xC8C3 [?] [3701]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0F,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xC8C4 [?] [3702]*/ + 0x20,0x20,0x20,0x3B,0x48,0x50,0x80,0x23,0x20,0x27,0x20,0x20,0x29,0x31,0x22,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xC8C5 [?] [3703]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x10,0x14,0x18,0x30,0xD0,0x10,0x10,0x11,0x51,0x22, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x50,0x50,0x50,0x50,0x90,0x90,0x92,0x12,0x0E,0x00, + /* 0xC8C6 [?] [3704]*/ + 0x10,0x10,0x20,0x23,0x48,0xF8,0x10,0x23,0x40,0xFB,0x40,0x00,0x19,0xE1,0x42,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xC8C7 [?] [3705]*/ + 0x08,0x7F,0x08,0x02,0xFF,0x08,0x1F,0x28,0xC8,0x0F,0x01,0x08,0x48,0x48,0x87,0x00, + 0x20,0xFC,0x20,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xC8C8 [?] [3706]*/ + 0x10,0x10,0x10,0xFD,0x10,0x10,0x1C,0x30,0xD0,0x10,0x51,0x22,0x00,0x48,0x44,0x84, + 0x40,0x40,0x40,0xF8,0x48,0x48,0xC8,0x48,0xAA,0xAA,0x06,0x02,0x00,0x88,0x44,0x44, + /* 0xC8C9 [?] [3707]*/ + 0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x00, + 0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, + /* 0xC8CA [?] [3708]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x17,0x10,0x10,0x10, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xC8CB [?] [3709]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x08,0x04,0x02, + /* 0xC8CC [?] [3710]*/ + 0x00,0x3F,0x02,0x12,0x12,0x24,0x08,0x10,0x60,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x50,0x20,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xC8CD [?] [3711]*/ + 0x20,0x20,0x21,0xFC,0x20,0x20,0xF8,0x20,0x21,0xFC,0x24,0x24,0x34,0x28,0x21,0x22, + 0x00,0x00,0xFC,0x24,0x24,0xA4,0xA4,0xA4,0x24,0x24,0x24,0x44,0x44,0x84,0x14,0x08, + /* 0xC8CE [?] [3712]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x5F,0x90,0x10,0x10,0x10,0x10,0x10,0x17,0x10, + 0x10,0x78,0xC0,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0xFC,0x00, + /* 0xC8CF [?] [3713]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x15,0x19,0x12,0x04,0x08, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xC8D0 [?] [3714]*/ + 0x00,0x3F,0x02,0x02,0x02,0x22,0x22,0x22,0x42,0x02,0x04,0x04,0x08,0x08,0x10,0x60, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC8D1 [?] [3715]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x24,0x27,0x24,0x48,0x28,0x10,0x28,0x44,0x85,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00, + /* 0xC8D2 [?] [3716]*/ + 0x10,0x10,0x23,0x20,0x48,0xFA,0x12,0x22,0x44,0xF8,0x40,0x01,0x19,0xE2,0x44,0x08, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x04,0x28,0x10, + /* 0xC8D3 [?] [3717]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x14,0x18,0x30,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x00,0x00,0xF8,0x88,0x90,0x90,0xA0,0xBC,0x84,0x84,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC8D4 [?] [3718]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x50,0x90,0x10,0x11,0x11,0x11,0x12,0x12,0x14, + 0x00,0x00,0xF8,0x88,0x90,0x90,0xA0,0xBC,0x84,0x84,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xC8D5 [?] [3719]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xC8D6 [?] [3720]*/ + 0x00,0x00,0x00,0xFF,0x00,0x08,0x08,0x08,0x7F,0x08,0x08,0x10,0x10,0x20,0x40,0x03, + 0x48,0x44,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xC8D7 [?] [3721]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x10,0x1F,0x10,0x1F,0x10,0x10,0xFF,0x00,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x10,0xF0,0x10,0xF0,0x10,0x3E,0xD0,0x10,0x10,0x10, + /* 0xC8D8 [?] [3722]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x7F,0x40,0x89,0x12,0x24,0x08,0x3F,0xC8,0x08,0x0F,0x08, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x24,0x90,0x48,0x20,0xF8,0x26,0x20,0xE0,0x20, + /* 0xC8D9 [?] [3723]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x81,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xC8DA [?] [3724]*/ + 0x00,0xFE,0x00,0x7C,0x44,0x7C,0x00,0xFE,0x82,0xAA,0x92,0xFE,0x92,0x92,0x92,0x86, + 0x20,0x20,0x20,0xFC,0xA4,0xA4,0xA4,0xA4,0xFC,0xA4,0x20,0x28,0x24,0xFE,0x42,0x00, + /* 0xC8DB [?] [3725]*/ + 0x10,0x10,0x13,0x16,0x58,0x50,0x51,0x90,0x10,0x11,0x12,0x28,0x24,0x44,0x40,0x80, + 0x40,0x20,0xFE,0x02,0x50,0x88,0x24,0x50,0x88,0x04,0xFA,0x88,0x88,0x88,0xF8,0x88, + /* 0xC8DC [?] [3726]*/ + 0x00,0x20,0x13,0x12,0x84,0x41,0x4A,0x08,0x11,0x12,0xE5,0x21,0x21,0x21,0x21,0x01, + 0x40,0x20,0xFE,0x02,0x94,0x08,0x64,0x90,0x08,0x04,0xFA,0x08,0x08,0x08,0xF8,0x08, + /* 0xC8DD [?] [3727]*/ + 0x02,0x01,0x7F,0x40,0x88,0x11,0x22,0x04,0x08,0x30,0xDF,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x88,0x40,0x20,0x18,0xF6,0x10,0x10,0x10,0xF0,0x10, + /* 0xC8DE [?] [3728]*/ + 0x10,0x10,0x20,0x20,0x4B,0xF8,0x11,0x21,0x41,0xFB,0x41,0x01,0x1A,0xE2,0x44,0x00, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x24,0x24,0x24,0xA8,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xC8DF [?] [3729]*/ + 0x00,0x00,0x7F,0x40,0x80,0x00,0x0F,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xC0,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xC8E0 [?] [3730]*/ + 0x20,0x21,0x20,0x20,0xFB,0x20,0x20,0x29,0x32,0xE0,0x23,0x20,0x20,0x21,0xA6,0x40, + 0x00,0xFC,0x48,0x30,0xFE,0x52,0x94,0x10,0x30,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xC8E1 [?] [3731]*/ + 0x00,0x1F,0x02,0x01,0x7F,0x04,0x18,0x62,0x01,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xF0,0x20,0x40,0xFC,0x84,0x88,0x80,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xC8E2 [?] [3732]*/ + 0x01,0x01,0x01,0x7F,0x41,0x42,0x44,0x49,0x51,0x41,0x42,0x42,0x44,0x48,0x40,0x40, + 0x00,0x00,0x00,0xFC,0x04,0x84,0x44,0x24,0x04,0x04,0x84,0x44,0x44,0x04,0x14,0x08, + /* 0xC8E3 [?] [3733]*/ + 0x08,0x08,0xFF,0x08,0x10,0x10,0xFE,0x12,0x22,0x22,0x64,0x14,0x08,0x14,0x22,0xC0, + 0x20,0x20,0xFE,0x20,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00, + /* 0xC8E4 [?] [3734]*/ + 0x20,0x21,0x20,0xFB,0xAA,0xA9,0xA8,0xA9,0xF8,0xA3,0x20,0x29,0x39,0xE9,0x41,0x01, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFE,0x20,0xFC,0x54,0x54,0x54,0x0C, + /* 0xC8E5 [?] [3735]*/ + 0x10,0x17,0x10,0x2F,0x28,0x63,0x60,0xA3,0x20,0x2F,0x20,0x27,0x24,0x24,0x24,0x24, + 0x00,0xFC,0x40,0xFE,0x42,0x58,0x40,0x58,0x00,0xFE,0x40,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xC8E6 [?] [3736]*/ + 0x00,0xFD,0x04,0x0B,0x12,0x11,0x14,0x19,0x30,0xD3,0x10,0x11,0x11,0x11,0x51,0x21, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFE,0x20,0xFC,0x54,0x54,0x54,0x0C, + /* 0xC8E7 [?] [3737]*/ + 0x10,0x10,0x10,0x10,0xFE,0x22,0x22,0x22,0x42,0x24,0x14,0x08,0x14,0x22,0x42,0x80, + 0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00, + /* 0xC8E8 [?] [3738]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x3F,0x28,0x48,0x4A,0x8C,0x00,0xFF,0x08,0x04,0x04,0x00, + 0x00,0xFC,0x00,0xF8,0x00,0xFE,0x88,0x50,0x30,0x0E,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xC8E9 [?] [3739]*/ + 0x02,0x0F,0xF0,0x01,0x91,0x4A,0x00,0xFE,0x04,0x08,0x0F,0xF8,0x48,0x08,0x28,0x10, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xC8EA [?] [3740]*/ + 0x00,0x20,0x10,0x10,0x8F,0x41,0x41,0x12,0x12,0x26,0xE1,0x20,0x20,0x21,0x22,0x0C, + 0x80,0x80,0x80,0x80,0xFE,0x08,0x08,0x08,0x10,0x10,0xA0,0x40,0xA0,0x10,0x08,0x04, + /* 0xC8EB [?] [3741]*/ + 0x04,0x02,0x01,0x01,0x01,0x02,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x06, + /* 0xC8EC [?] [3742]*/ + 0x20,0x13,0x02,0xF2,0x12,0x23,0x22,0x6A,0xB2,0x2A,0x22,0x23,0x22,0x24,0x24,0x28, + 0x00,0xFE,0x00,0xFC,0x00,0xFE,0xA8,0x90,0xC8,0x86,0x08,0xFE,0x88,0x48,0x08,0x18, + /* 0xC8ED [?] [3743]*/ + 0x10,0x10,0x10,0xFE,0x20,0x28,0x49,0x7E,0x08,0x08,0x0E,0xF8,0x48,0x08,0x09,0x0A, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xC8EE [?] [3744]*/ + 0x00,0x7D,0x44,0x48,0x48,0x53,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44, + 0x00,0xFC,0x00,0x00,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xC8EF [?] [3745]*/ + 0x08,0x08,0xFF,0x08,0x08,0x01,0x24,0x24,0x43,0x00,0x24,0x12,0xA0,0xA4,0x1C,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x88,0x24,0xE4,0x00,0x24,0x12,0xA0,0xA4,0x1C,0x00, + /* 0xC8F0 [?] [3746]*/ + 0x00,0x02,0xFA,0x22,0x23,0x20,0x27,0xF8,0x20,0x23,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x20,0x22,0x22,0x22,0xFE,0x00,0xFE,0x20,0x40,0xFE,0x52,0x52,0x52,0x52,0x52,0x06, + /* 0xC8F1 [?] [3747]*/ + 0x22,0x21,0x39,0x40,0x43,0x7A,0xA2,0x22,0xFB,0x20,0x20,0x29,0x31,0x22,0x04,0x08, + 0x08,0x08,0x10,0x20,0xF8,0x08,0x08,0x08,0xF8,0xA0,0xA0,0x20,0x24,0x24,0x1C,0x00, + /* 0xC8F2 [?] [3748]*/ + 0x20,0x13,0x10,0x40,0x40,0x5F,0x41,0x41,0x4F,0x41,0x41,0x41,0x5F,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0xE4,0x04,0x04,0x04,0xF4,0x04,0x14,0x08, + /* 0xC8F3 [?] [3749]*/ + 0x02,0x21,0x15,0x14,0x85,0x44,0x44,0x14,0x15,0x24,0xE4,0x24,0x25,0x24,0x24,0x04, + 0x00,0x7C,0x04,0x04,0xF4,0x44,0x44,0x44,0xF4,0x44,0x44,0x44,0xF4,0x04,0x14,0x08, + /* 0xC8F4 [?] [3750]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x02,0xFF,0x04,0x08,0x1F,0x28,0x48,0x88,0x08,0x0F,0x08, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xC8F5 [?] [3751]*/ + 0x00,0x7E,0x02,0x02,0x7E,0x40,0x40,0x7E,0x22,0x12,0x06,0x1A,0x62,0x02,0x14,0x08, + 0x00,0xFC,0x04,0x04,0xFC,0x80,0x80,0xFC,0x44,0x24,0x0C,0x34,0xC4,0x04,0x28,0x10, + /* 0xC8F6 [?] [3752]*/ + 0x22,0x22,0x27,0x22,0xFA,0x27,0x20,0x2F,0x34,0xE7,0x24,0x27,0x24,0x24,0xA4,0x44, + 0x88,0x88,0xC8,0x90,0x9E,0xD4,0x24,0xD4,0x54,0xD4,0x54,0xC8,0x48,0x54,0x64,0xC2, + /* 0xC8F7 [?] [3753]*/ + 0x00,0x2F,0x10,0x10,0x87,0x44,0x44,0x14,0x14,0x24,0xE5,0x26,0x24,0x24,0x27,0x04, + 0x00,0xFE,0xA0,0xA0,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0x1C,0x04,0x04,0x04,0xFC,0x04, + /* 0xC8F8 [?] [3754]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7D,0x44,0x48,0x51,0x49,0x45,0x45,0x55,0x49,0x42,0x44, + 0x40,0x40,0xFE,0x40,0x20,0xFC,0x88,0x50,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC8F9 [?] [3755]*/ + 0x00,0x79,0x49,0x49,0x49,0x79,0x49,0x49,0x48,0x78,0x48,0x4A,0x4A,0x4C,0x48,0x98, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x00,0x40,0x24,0xA2,0x8A,0x88,0x78,0x00, + /* 0xC8FA [?] [3756]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7C,0x54,0x54,0x7D,0x01,0x1D,0xE2,0x40, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x10,0x54,0x42,0x42,0x4A,0x38,0x00, + /* 0xC8FB [?] [3757]*/ + 0x02,0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x11,0x21,0xDF,0x01,0x01,0x7F, + 0x00,0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0x10,0x08,0xF6,0x00,0x00,0xFC, + /* 0xC8FC [?] [3758]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x1F,0x29,0xC9,0x09,0x0A,0x04,0x18, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0xF0,0x28,0x26,0x20,0xA0,0x40,0x20, + /* 0xC8FD [?] [3759]*/ + 0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00, + /* 0xC8FE [?] [3760]*/ + 0x02,0x04,0x08,0x1F,0x02,0x7F,0x08,0x10,0x27,0xC0,0x00,0x0F,0x00,0x00,0x3F,0x00, + 0x00,0x40,0x20,0xF0,0x00,0xFC,0x20,0x10,0xC8,0x06,0x00,0xE0,0x00,0x00,0xF8,0x00, + /* 0xC9A1 [?] [3761]*/ + 0x01,0x01,0x02,0x04,0x08,0x30,0xC1,0x11,0x09,0x09,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0x80,0x40,0x20,0x18,0x06,0x10,0x10,0x20,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xC9A2 [?] [3762]*/ + 0x24,0x24,0x7E,0x24,0x24,0xFF,0x00,0x7E,0x42,0x7E,0x42,0x7E,0x42,0x42,0x4A,0x44, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xC9A3 [?] [3763]*/ + 0x1F,0x06,0x01,0x0E,0x00,0x7C,0x24,0x18,0x66,0x01,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0xE0,0x40,0x80,0x40,0x00,0xF8,0x48,0x30,0xCC,0x00,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xC9A4 [?] [3764]*/ + 0x03,0x01,0xF0,0x93,0x90,0x97,0x94,0x93,0x94,0x90,0xF7,0x90,0x01,0x02,0x0C,0x00, + 0xF0,0x10,0xE0,0x18,0x00,0xBC,0xA4,0x18,0xA4,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xC9A5 [?] [3765]*/ + 0x01,0x01,0x7F,0x01,0x11,0x09,0x09,0x01,0xFF,0x12,0x11,0x10,0x10,0x14,0x18,0x10, + 0x00,0x00,0xFC,0x00,0x10,0x10,0x20,0x00,0xFE,0x00,0x10,0xA0,0x40,0x30,0x0E,0x00, + /* 0xC9A6 [?] [3766]*/ + 0x20,0x23,0x21,0x21,0xF8,0x20,0x21,0x2E,0x30,0xE3,0x22,0x22,0x23,0x20,0xA7,0x40, + 0x00,0xF8,0x48,0x10,0xA0,0x40,0xB0,0x4E,0x40,0xF8,0x48,0x48,0xF8,0x44,0xFC,0x04, + /* 0xC9A7 [?] [3767]*/ + 0x00,0xF9,0x08,0x48,0x48,0x48,0x48,0x7F,0x04,0x05,0x1D,0xE5,0x45,0x04,0x2B,0x10, + 0x00,0xFC,0xA4,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x24,0x24,0xFC,0x22,0xFE,0x02, + /* 0xC9A8 [?] [3768]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x15,0x18,0x30,0xD0,0x10,0x10,0x13,0x50,0x20, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xC9A9 [?] [3769]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x24,0x49,0x28,0x10,0x28,0x44,0x80,0x03, + 0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x20,0xFC,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xC9AA [?] [3770]*/ + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x01,0x08,0x48,0x49,0x8E,0x18,0xE7,0x00, + 0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x10,0xA0,0x44,0x82,0x12,0x10,0xF0,0x00, + /* 0xC9AB [?] [3771]*/ + 0x08,0x08,0x1F,0x20,0x40,0xBF,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xC9AC [?] [3772]*/ + 0x00,0x23,0x10,0x12,0x82,0x44,0x40,0x11,0x12,0x20,0xE1,0x21,0x21,0x21,0x27,0x00, + 0x00,0xFC,0x44,0x44,0x44,0x84,0x94,0x08,0x20,0x20,0x3C,0x20,0x20,0x20,0xFE,0x00, + /* 0xC9AD [?] [3773]*/ + 0x01,0x01,0x7F,0x05,0x09,0x31,0xC1,0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC9,0x08,0x08, + 0x00,0x00,0xFC,0x40,0x20,0x18,0x06,0x20,0x20,0xFC,0x30,0x68,0xA4,0x22,0x20,0x20, + /* 0xC9AE [?] [3774]*/ + 0x09,0x08,0x08,0x13,0x12,0x32,0x32,0x52,0x93,0x10,0x11,0x11,0x11,0x11,0x11,0x11, + 0x04,0x88,0x00,0xFE,0x22,0xAA,0x72,0x22,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xC9AF [?] [3775]*/ + 0x08,0x08,0xFF,0x08,0x00,0x10,0x08,0x40,0x24,0x05,0x09,0x72,0x10,0x10,0x11,0x06, + 0x20,0x20,0xFE,0x20,0x00,0x20,0x20,0xA8,0xA4,0x22,0x22,0x28,0x10,0x60,0x80,0x00, + /* 0xC9B0 [?] [3776]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3D,0x65,0x66,0xA4,0x24,0x24,0x3C,0x24,0x20,0x03, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xC9B1 [?] [3777]*/ + 0x00,0x18,0x06,0x01,0x06,0x18,0x61,0x01,0xFF,0x01,0x11,0x11,0x21,0x21,0x45,0x02, + 0x08,0x10,0x60,0x80,0x60,0x18,0x04,0x00,0xFE,0x00,0x20,0x10,0x08,0x04,0x04,0x00, + /* 0xC9B2 [?] [3778]*/ + 0x01,0x62,0x14,0x08,0x14,0x22,0x49,0x08,0xFF,0x08,0x2A,0x29,0x48,0x88,0x28,0x10, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0x84,0x84,0x14,0x08, + /* 0xC9B3 [?] [3779]*/ + 0x00,0x20,0x10,0x11,0x81,0x42,0x42,0x14,0x10,0x20,0xE0,0x20,0x20,0x20,0x21,0x06, + 0x40,0x40,0x40,0x48,0x44,0x42,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0x40,0x80,0x00, + /* 0xC9B4 [?] [3780]*/ + 0x10,0x10,0x20,0x21,0x49,0xFA,0x12,0x24,0x40,0xF8,0x40,0x00,0x18,0xE0,0x41,0x06, + 0x40,0x40,0x40,0x48,0x44,0x42,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0x40,0x80,0x00, + /* 0xC9B5 [?] [3781]*/ + 0x08,0x08,0x0B,0x12,0x12,0x32,0x33,0x50,0x91,0x12,0x14,0x11,0x12,0x10,0x11,0x16, + 0x40,0x80,0xFC,0x94,0x64,0x94,0xFC,0x90,0x08,0x84,0xFA,0x08,0x90,0x60,0x98,0x06, + /* 0xC9B6 [?] [3782]*/ + 0x00,0x00,0x78,0x49,0x4A,0x4D,0x48,0x48,0x4F,0x48,0x78,0x4B,0x02,0x02,0x03,0x02, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x40,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC9B7 [?] [3783]*/ + 0x20,0x20,0x3C,0x44,0x88,0x7F,0x02,0x02,0x7E,0x02,0x02,0xFE,0x00,0x48,0x44,0x84, + 0x20,0x20,0x40,0x7E,0x84,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82,0x88,0x44,0x44, + /* 0xC9B8 [?] [3784]*/ + 0x20,0x3F,0x48,0x85,0x08,0x4B,0x48,0x48,0x49,0x49,0x49,0x49,0x11,0x11,0x20,0x40, + 0x40,0x7E,0x90,0x08,0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xC9B9 [?] [3785]*/ + 0x00,0x07,0x78,0x48,0x48,0x4B,0x4A,0x7A,0x4A,0x4A,0x4A,0x4B,0x7A,0x4A,0x03,0x02, + 0x00,0xFE,0x90,0x90,0x90,0xFC,0x94,0x94,0x94,0x94,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xC9BA [?] [3786]*/ + 0x00,0xF7,0x24,0x24,0x24,0x24,0xF4,0x2F,0x24,0x24,0x24,0x34,0xE4,0x45,0x08,0x10, + 0x00,0xBC,0xA4,0xA4,0xA4,0xA4,0xA4,0xFE,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x54,0x88, + /* 0xC9BB [?] [3787]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x20,0x20,0x3F,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFE,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xC9BC [?] [3788]*/ + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08,0x08, + 0x04,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x22,0x42,0x04,0x08,0x10,0x20,0xC0, + /* 0xC9BD [?] [3789]*/ + 0x01,0x01,0x01,0x01,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x3F,0x00,0x00, + 0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00, + /* 0xC9BE [?] [3790]*/ + 0x00,0x7B,0x4A,0x4A,0x4A,0x4A,0x4A,0xFF,0x4A,0x4A,0x4A,0x4A,0x4A,0x5A,0x85,0x08, + 0x02,0xC2,0x42,0x4A,0x4A,0x4A,0x4A,0xEA,0x4A,0x4A,0x4A,0x4A,0x42,0x42,0x4A,0x84, + /* 0xC9BF [?] [3791]*/ + 0x10,0x10,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x42,0x42,0x84, + 0x20,0x10,0xFE,0x02,0x02,0xFE,0x00,0xEE,0x22,0xAA,0x66,0x22,0x66,0xAA,0x22,0x66, + /* 0xC9C0 [?] [3792]*/ + 0x10,0x08,0x00,0x7E,0x02,0x04,0x08,0x1A,0x2C,0x4A,0x0A,0x08,0x08,0x08,0x08,0x08, + 0x04,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x22,0x42,0x04,0x08,0x10,0x20,0xC0, + /* 0xC9C1 [?] [3793]*/ + 0x20,0x17,0x00,0x40,0x41,0x41,0x41,0x41,0x42,0x42,0x44,0x48,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x84,0x44,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xC9C2 [?] [3794]*/ + 0x00,0x78,0x48,0x57,0x50,0x62,0x51,0x48,0x4F,0x48,0x68,0x51,0x41,0x42,0x44,0x48, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x50,0x40,0xFE,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xC9C3 [?] [3795]*/ + 0x20,0x2F,0x20,0x27,0xFC,0x25,0x25,0x2F,0x30,0xE3,0x22,0x23,0x22,0x23,0xA0,0x4F, + 0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xC9C4 [?] [3796]*/ + 0x00,0x7C,0x45,0x47,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x29,0x26,0x42,0x84, + 0x80,0xF8,0x08,0xFE,0x44,0x92,0xFE,0x00,0x7C,0x00,0x7C,0x00,0x7C,0x44,0x7C,0x44, + /* 0xC9C5 [?] [3797]*/ + 0x00,0x78,0x4B,0x48,0x49,0x78,0x4B,0x49,0x48,0x7B,0x48,0x49,0x49,0x49,0x49,0x99, + 0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xC9C6 [?] [3798]*/ + 0x08,0x04,0x7F,0x01,0x3F,0x01,0xFF,0x11,0x09,0xFF,0x00,0x3F,0x20,0x20,0x3F,0x20, + 0x20,0x40,0xFC,0x00,0xF8,0x00,0xFE,0x10,0x20,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xC9C7 [?] [3799]*/ + 0x00,0x20,0x10,0x10,0x84,0x44,0x44,0x14,0x14,0x24,0xE4,0x24,0x24,0x27,0x20,0x00, + 0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFC,0x04,0x00, + /* 0xC9C8 [?] [3800]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x21,0x29,0x25,0x49,0x51,0x85,0x02, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x7C,0x04,0x24,0x14,0x24,0x44,0x14,0x08, + /* 0xC9C9 [?] [3801]*/ + 0x10,0x10,0x23,0x20,0x49,0xF8,0x13,0x21,0x40,0xFB,0x40,0x01,0x19,0xE1,0x41,0x01, + 0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xC9CA [?] [3802]*/ + 0x20,0x20,0x23,0x20,0x20,0xFB,0x22,0x22,0x23,0x22,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x40,0x20,0xFE,0x88,0x50,0xFE,0x52,0x8A,0x06,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xC9CB [?] [3803]*/ + 0x08,0x08,0x09,0x11,0x12,0x34,0x30,0x53,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x80,0x80,0x00,0xFE,0x00,0x40,0x40,0xFC,0x44,0x44,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xC9CC [?] [3804]*/ + 0x02,0x01,0x7F,0x08,0x04,0x3F,0x20,0x24,0x28,0x37,0x24,0x24,0x27,0x20,0x20,0x20, + 0x00,0x00,0xFC,0x20,0x40,0xF8,0x08,0x48,0x28,0xD8,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xC9CD [?] [3805]*/ + 0x11,0x09,0x3F,0x20,0x4F,0x08,0x0F,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x10,0x20,0xFC,0x04,0xE8,0x20,0xE0,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xC9CE [?] [3806]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02, + 0x40,0x40,0x80,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xC9CF [?] [3807]*/ + 0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFF,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC9D0 [?] [3808]*/ + 0x01,0x21,0x11,0x09,0x01,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x20, + 0x00,0x08,0x10,0x20,0x00,0xF8,0x08,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xC9D1 [?] [3809]*/ + 0x01,0x11,0x09,0x7F,0x40,0x9F,0x10,0x1F,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x10,0x20,0xFE,0x02,0xF4,0x10,0xF0,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xC9D2 [?] [3810]*/ + 0x10,0x11,0x10,0x10,0xFC,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC9D3 [?] [3811]*/ + 0x10,0x11,0x10,0x10,0xFC,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC9D4 [?] [3812]*/ + 0x08,0x1D,0xF0,0x10,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC9D5 [?] [3813]*/ + 0x20,0x20,0x20,0x23,0xA8,0xB0,0xA0,0xA3,0x20,0x27,0x20,0x20,0x51,0x49,0x42,0x84, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xC9D6 [?] [3814]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x1F,0x20,0x40,0x88,0x04,0x02,0x02,0x00,0x00,0x00, + 0x40,0x40,0xFE,0x40,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC9D7 [?] [3815]*/ + 0x08,0x08,0x10,0x1F,0x20,0x40,0x80,0x04,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xC9D8 [?] [3816]*/ + 0x20,0x11,0x7C,0x00,0x44,0x28,0xFE,0x00,0x7D,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x94,0x88,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xC9D9 [?] [3817]*/ + 0x01,0x01,0x01,0x09,0x09,0x11,0x11,0x21,0x41,0x01,0x00,0x00,0x01,0x02,0x0C,0x70, + 0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x14,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xC9DA [?] [3818]*/ + 0x00,0x01,0x78,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xC9DB [?] [3819]*/ + 0x00,0x7F,0x11,0x11,0x21,0x25,0x42,0x80,0x3F,0x21,0x21,0x21,0x21,0x3F,0x21,0x00, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xC9DC [?] [3820]*/ + 0x10,0x13,0x20,0x20,0x48,0xF9,0x11,0x22,0x44,0xF9,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xC9DD [?] [3821]*/ + 0x02,0x02,0x7F,0x04,0x08,0x32,0xDF,0x02,0xFF,0x03,0x0F,0x38,0xCF,0x08,0x0F,0x08, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xD6,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xC9DE [?] [3822]*/ + 0x00,0x7C,0x44,0x54,0x55,0x56,0x54,0x54,0x57,0x54,0x55,0x11,0x2A,0x24,0x44,0x80, + 0x20,0x20,0x50,0x88,0x04,0xFA,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xC9DF [?] [3823]*/ + 0x10,0x10,0x10,0x7D,0x55,0x56,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xC9E0 [?] [3824]*/ + 0x00,0x00,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x10,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xC9E1 [?] [3825]*/ + 0x01,0x02,0x04,0x08,0x30,0xCF,0x01,0x01,0x3F,0x01,0x01,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xF8,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xC9E2 [?] [3826]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFF,0x14,0x14,0x56,0x55,0x95,0x24,0x24,0x54,0x88, + 0x20,0x20,0x20,0x40,0x7E,0x84,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xC9E3 [?] [3827]*/ + 0x10,0x13,0x11,0x11,0xFD,0x11,0x11,0x17,0x18,0x37,0xD0,0x12,0x11,0x12,0x54,0x28, + 0x00,0xFC,0x08,0xF8,0x08,0xF8,0x0E,0xF8,0x08,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xC9E4 [?] [3828]*/ + 0x08,0x10,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x22,0xFE,0x06,0x0A,0x12,0x22,0x4A,0x04, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x28,0x10, + /* 0xC9E5 [?] [3829]*/ + 0x20,0x23,0x21,0x21,0x31,0xA9,0xA1,0xA7,0xA0,0x27,0x20,0x22,0x21,0x22,0x24,0x28, + 0x00,0xFC,0x08,0xF8,0x08,0xF8,0x0E,0xF8,0x08,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xC9E6 [?] [3830]*/ + 0x00,0x20,0x11,0x11,0x81,0x41,0x47,0x10,0x10,0x21,0xE1,0x22,0x24,0x20,0x20,0x07, + 0x20,0x20,0x20,0x3C,0x20,0x20,0xFE,0x00,0x20,0x24,0x24,0x28,0x10,0x20,0xC0,0x00, + /* 0xC9E7 [?] [3831]*/ + 0x20,0x10,0x10,0xF8,0x08,0x10,0x13,0x38,0x54,0x94,0x10,0x10,0x10,0x10,0x17,0x10, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xC9E8 [?] [3832]*/ + 0x00,0x21,0x11,0x11,0x01,0x02,0xF4,0x13,0x11,0x11,0x10,0x14,0x18,0x10,0x03,0x0C, + 0x00,0xF0,0x10,0x10,0x10,0x0E,0x00,0xF8,0x08,0x10,0x90,0xA0,0x40,0xA0,0x18,0x06, + /* 0xC9E9 [?] [3833]*/ + 0x00,0x00,0xFC,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x24,0x20,0x00, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xC9EA [?] [3834]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x01, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00, + /* 0xC9EB [?] [3835]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4A,0x4B,0x4A,0x4A,0x7A,0x4B,0x02,0x00,0x00,0x00, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0xF8,0x48,0x48,0x48,0xF8,0x48,0x40,0x40,0x40, + /* 0xC9EC [?] [3836]*/ + 0x08,0x08,0x08,0x17,0x14,0x34,0x34,0x57,0x94,0x14,0x14,0x17,0x14,0x10,0x10,0x10, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x44,0x40,0x40,0x40, + /* 0xC9ED [?] [3837]*/ + 0x02,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x7F,0x00,0x00,0x03,0x1C,0xE0,0x00, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF2,0x14,0x18,0xF0,0x50,0x90,0x10,0x10,0x50,0x20, + /* 0xC9EE [?] [3838]*/ + 0x00,0x27,0x14,0x14,0x81,0x42,0x40,0x10,0x17,0x20,0xE0,0x21,0x22,0x2C,0x20,0x00, + 0x00,0xFC,0x04,0xA4,0x10,0x08,0x40,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xC9EF [?] [3839]*/ + 0x20,0x23,0x22,0x22,0xFA,0x4A,0x4A,0x4B,0x8A,0x4A,0x32,0x12,0x2A,0x4C,0x84,0x08, + 0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFC,0xA0,0xA4,0xA8,0x90,0x90,0x88,0xA4,0xC2, + /* 0xC9F0 [?] [3840]*/ + 0x10,0x10,0x20,0x25,0x45,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE0,0x40,0x00, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xC9F1 [?] [3841]*/ + 0x20,0x10,0x10,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x11,0x10,0x10,0x10, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xC9F2 [?] [3842]*/ + 0x00,0x20,0x10,0x17,0x84,0x48,0x40,0x10,0x10,0x20,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x40,0x40,0x40,0xFE,0x44,0x48,0x40,0xA0,0xA0,0xA0,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xC9F3 [?] [3843]*/ + 0x02,0x01,0x7F,0x41,0x81,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21,0x01,0x01,0x01, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x00,0x00,0x00, + /* 0xC9F4 [?] [3844]*/ + 0x20,0x20,0x23,0x22,0xF8,0x49,0x49,0x49,0x49,0x91,0x51,0x21,0x31,0x48,0x48,0x80, + 0x40,0x20,0xFE,0x22,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xC9F5 [?] [3845]*/ + 0x08,0x08,0x7F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x08,0x08,0xFF,0x12,0x14,0x10,0x1F, + 0x20,0x20,0xFC,0x20,0x20,0xE0,0x20,0x20,0xE0,0x20,0x20,0xFE,0x20,0x10,0x00,0xF8, + /* 0xC9F6 [?] [3846]*/ + 0x04,0x25,0x24,0x24,0x24,0x24,0x27,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10, + 0x00,0xF8,0x88,0x50,0x20,0xD8,0x06,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x50,0x20, + /* 0xC9F7 [?] [3847]*/ + 0x20,0x20,0x27,0x20,0x33,0xAA,0xA3,0xA2,0xA3,0x22,0x23,0x22,0x2F,0x21,0x22,0x24, + 0x40,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFE,0x10,0x08,0x04, + /* 0xC9F8 [?] [3848]*/ + 0x00,0x20,0x11,0x13,0x80,0x47,0x41,0x12,0x1C,0x23,0xE0,0x20,0x23,0x20,0x20,0x07, + 0x80,0x90,0x08,0xFC,0x40,0xFE,0x10,0x48,0x86,0x10,0x20,0xC4,0x08,0x30,0xC0,0x00, + /* 0xC9F9 [?] [3849]*/ + 0x01,0x01,0xFF,0x01,0x7F,0x00,0x3F,0x21,0x21,0x3F,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0x00,0xFE,0x00,0xFC,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xC9FA [?] [3850]*/ + 0x01,0x11,0x11,0x11,0x3F,0x21,0x41,0x81,0x01,0x3F,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xC9FB [?] [3851]*/ + 0x11,0x11,0x51,0x51,0x7D,0x51,0x91,0x10,0x7C,0x13,0x10,0x10,0x1C,0xE1,0x42,0x04, + 0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x40,0x40,0xFE,0x42,0x82,0x82,0x02,0x14,0x08, + /* 0xC9FC [?] [3852]*/ + 0x10,0x10,0x51,0x51,0x7D,0x51,0x92,0x10,0x1C,0xF1,0x50,0x10,0x10,0x10,0x13,0x10, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xC9FD [?] [3853]*/ + 0x01,0x07,0x3C,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x20,0xA0,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xC9FE [?] [3854]*/ + 0x10,0x11,0x21,0x21,0x49,0xF8,0x13,0x22,0x42,0xFB,0x42,0x02,0x1B,0xE0,0x40,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x40,0xF8,0x48,0x48,0xF8,0x48,0x48,0xFA,0x42,0x42,0x3E, + /* 0xCAA1 [?] [3855]*/ + 0x01,0x11,0x11,0x21,0x40,0x03,0x0C,0x3F,0xD0,0x1F,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x10,0x08,0x24,0xC0,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCAA2 [?] [3856]*/ + 0x00,0x00,0x3F,0x20,0x20,0x3E,0x22,0x22,0x4A,0x44,0x81,0x3F,0x24,0x24,0xFF,0x00, + 0x90,0x88,0xFC,0x80,0x88,0x48,0x50,0x24,0x54,0x8C,0x04,0xF8,0x48,0x48,0xFE,0x00, + /* 0xCAA3 [?] [3857]*/ + 0x07,0x78,0x08,0xFF,0x2A,0x2A,0xEB,0x2A,0x6A,0xA9,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x02,0x02,0x02,0x82,0x12,0x92,0x12,0x92,0x92,0x92,0x12,0x12,0x02,0x82,0x0A,0x04, + /* 0xCAA4 [?] [3858]*/ + 0x00,0x78,0x49,0x49,0x49,0x79,0x4A,0x48,0x48,0x79,0x48,0x48,0x48,0x48,0x4B,0x98, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xCAA5 [?] [3859]*/ + 0x00,0x3F,0x08,0x04,0x02,0x01,0x06,0x18,0xE1,0x01,0x1F,0x01,0x01,0x01,0x7F,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x00,0xC0,0x30,0x0E,0x00,0xF0,0x00,0x00,0x00,0xFC,0x00, + /* 0xCAA6 [?] [3860]*/ + 0x08,0x0B,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x09,0x11,0x10,0x20,0x40, + 0x00,0xFE,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,0x20, + /* 0xCAA7 [?] [3861]*/ + 0x01,0x11,0x11,0x11,0x3F,0x21,0x41,0x01,0xFF,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xCAA8 [?] [3862]*/ + 0x01,0x89,0x51,0x25,0x55,0x95,0x15,0x15,0x35,0x55,0x95,0x11,0x12,0x12,0xA4,0x48, + 0x00,0xFE,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5C,0x10,0x10,0x10, + /* 0xCAA9 [?] [3863]*/ + 0x20,0x10,0x10,0x01,0xFE,0x21,0x21,0x3D,0x27,0x25,0x25,0x25,0x25,0x45,0x54,0x88, + 0x80,0x80,0xFE,0x20,0x20,0x20,0x2C,0x74,0xA4,0x24,0x34,0x2A,0x22,0x02,0xFE,0x00, + /* 0xCAAA [?] [3864]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x17,0x11,0x21,0xE9,0x25,0x23,0x21,0x2F,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x20,0x20,0x24,0x28,0x30,0x20,0xFE,0x00, + /* 0xCAAB [?] [3865]*/ + 0x00,0x20,0x10,0x13,0x00,0x00,0xF7,0x10,0x10,0x17,0x10,0x12,0x15,0x19,0x10,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x40,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xCAAC [?] [3866]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xCAAD [?] [3867]*/ + 0x00,0x7F,0x00,0x03,0x7C,0x04,0x3F,0x24,0x24,0x24,0x3F,0x04,0x04,0x07,0x78,0x20, + 0x00,0xF0,0x90,0xD0,0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x12,0x8A,0xCA,0x46,0x02, + /* 0xCAAE [?] [3868]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xCAAF [?] [3869]*/ + 0x00,0xFF,0x02,0x02,0x04,0x04,0x08,0x0F,0x18,0x28,0x48,0x88,0x08,0x08,0x0F,0x08, + 0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xCAB0 [?] [3870]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x11,0x14,0x18,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCAB1 [?] [3871]*/ + 0x00,0x00,0x7C,0x44,0x45,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x08,0x28,0x10, + /* 0xCAB2 [?] [3872]*/ + 0x08,0x08,0x08,0x10,0x10,0x30,0x37,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xCAB3 [?] [3873]*/ + 0x01,0x02,0x04,0x0A,0x31,0xDF,0x10,0x1F,0x10,0x1F,0x10,0x11,0x10,0x12,0x14,0x18, + 0x00,0x80,0x40,0x20,0x18,0xF6,0x10,0xF0,0x10,0xF0,0x08,0x90,0x60,0x10,0x08,0x04, + /* 0xCAB4 [?] [3874]*/ + 0x20,0x20,0x20,0x3D,0x45,0x49,0xA1,0x21,0x21,0x21,0x20,0x20,0x28,0x33,0x21,0x00, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x28,0x24,0xFE,0x02,0x00, + /* 0xCAB5 [?] [3875]*/ + 0x02,0x01,0x7F,0x40,0x88,0x04,0x04,0x10,0x08,0x08,0xFF,0x01,0x02,0x04,0x18,0x60, + 0x00,0x00,0xFE,0x02,0x84,0x80,0x80,0x80,0x80,0x80,0xFE,0x40,0x20,0x10,0x08,0x04, + /* 0xCAB6 [?] [3876]*/ + 0x00,0x20,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x10,0x14,0x18,0x11,0x02,0x04, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xCAB7 [?] [3877]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x11,0x09,0x06,0x05,0x18,0xE0, + 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x80,0x70,0x0E, + /* 0xCAB8 [?] [3878]*/ + 0x08,0x08,0x08,0x1F,0x11,0x21,0x41,0x01,0xFF,0x01,0x02,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x80,0x80,0x40,0x20,0x18,0x06, + /* 0xCAB9 [?] [3879]*/ + 0x10,0x10,0x1F,0x20,0x20,0x67,0x64,0xA4,0x27,0x20,0x22,0x21,0x20,0x21,0x22,0x2C, + 0x40,0x40,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x40,0x40,0x40,0x80,0x40,0x30,0x0E, + /* 0xCABA [?] [3880]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x24,0x22,0x20,0x3F,0x21,0x22,0x24,0x48,0x50,0x80, + 0x00,0xFC,0x04,0x04,0xFC,0x80,0x90,0xA0,0x80,0xFC,0xC0,0xA0,0x90,0x88,0x86,0x80, + /* 0xCABB [?] [3881]*/ + 0x00,0xF8,0x08,0x49,0x49,0x49,0x49,0x7D,0x05,0x04,0x1C,0xE4,0x44,0x04,0x29,0x12, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x20,0xA0,0x60,0x60,0x90,0x08,0x06, + /* 0xCABC [?] [3882]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x25,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x80,0x00, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xCABD [?] [3883]*/ + 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x0F,0x78,0x20,0x00, + 0x48,0x44,0x44,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x20,0x22,0x12,0x0A,0x06,0x02, + /* 0xCABE [?] [3884]*/ + 0x00,0x3F,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x11,0x11,0x21,0x41,0x81,0x05,0x02, + 0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x10,0x08,0x04,0x02,0x02,0x00,0x00, + /* 0xCABF [?] [3885]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, + /* 0xCAC0 [?] [3886]*/ + 0x02,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x13,0x10,0x10,0x10,0x1F,0x00, + 0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0xFC,0x00, + /* 0xCAC1 [?] [3887]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x10,0x10, + 0x40,0x20,0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCAC2 [?] [3888]*/ + 0x01,0x01,0xFF,0x01,0x3F,0x21,0x3F,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0x00,0x00, + /* 0xCAC3 [?] [3889]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x14,0x1B,0x31,0xD1,0x11,0x11,0x11,0x17,0x52,0x20, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0xA0,0x20,0x10,0x10,0x10,0xCA,0x0A,0x06,0x02, + /* 0xCAC4 [?] [3890]*/ + 0x08,0x7E,0x08,0x0E,0x78,0x0A,0x19,0x7F,0x00,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x3F, + 0x0C,0xF0,0x80,0xFE,0x88,0x88,0x08,0xFC,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x08,0xF8, + /* 0xCAC5 [?] [3891]*/ + 0x02,0x42,0x22,0x22,0x0F,0x02,0xE2,0x23,0x2E,0x22,0x22,0x2A,0x24,0x51,0x8F,0x00, + 0x08,0x1C,0x60,0x40,0xC0,0x7E,0xC8,0x48,0x48,0x48,0x48,0x48,0x88,0x00,0xFE,0x00, + /* 0xCAC6 [?] [3892]*/ + 0x08,0x08,0x7D,0x08,0x0C,0x19,0x68,0x08,0x28,0x13,0x02,0x7F,0x04,0x08,0x10,0x60, + 0x40,0x40,0xF8,0x48,0x48,0xC8,0x4A,0xAA,0x86,0x02,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xCAC7 [?] [3893]*/ + 0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0xFF,0x01,0x11,0x11,0x11,0x29,0x45,0x83, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE, + /* 0xCAC8 [?] [3894]*/ + 0x00,0x00,0x79,0x48,0x4B,0x48,0x48,0x49,0x4A,0x4C,0x79,0x49,0x01,0x01,0x01,0x01, + 0x40,0x44,0xF8,0x50,0xFE,0x40,0xF8,0x82,0x7E,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xCAC9 [?] [3895]*/ + 0x02,0x02,0xF3,0x95,0x98,0x90,0x97,0x90,0x92,0x92,0xF2,0x95,0x08,0x00,0x0F,0x00, + 0x10,0x10,0xDE,0x28,0x84,0x00,0xFC,0x40,0x48,0x48,0x48,0x54,0xE2,0x40,0xFE,0x00, + /* 0xCACA [?] [3896]*/ + 0x00,0x23,0x10,0x10,0x07,0x00,0xF0,0x13,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0x78,0xC0,0x40,0x40,0xFE,0x40,0x40,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xCACB [?] [3897]*/ + 0x08,0x08,0x08,0x10,0x10,0x3F,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x17,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFC,0x00,0x00, + /* 0xCACC [?] [3898]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x37,0x50,0x90,0x17,0x10,0x12,0x11,0x11,0x10,0x10, + 0x40,0x40,0x40,0xFC,0x40,0x40,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xCACD [?] [3899]*/ + 0x0C,0xF3,0x11,0x54,0x38,0x10,0xFC,0x13,0x30,0x39,0x54,0x50,0x93,0x10,0x10,0x10, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xCACE [?] [3900]*/ + 0x20,0x20,0x20,0x3C,0x45,0x4A,0x80,0x21,0x21,0x21,0x21,0x25,0x29,0x31,0x20,0x00, + 0x80,0x80,0x80,0xFE,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCACF [?] [3901]*/ + 0x00,0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x30,0x20, + 0x10,0xF8,0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x40,0x40,0x22,0x12,0x0A,0x06,0x02, + /* 0xCAD0 [?] [3902]*/ + 0x02,0x01,0x00,0x7F,0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xCAD1 [?] [3903]*/ + 0x10,0x10,0x10,0x1B,0x54,0x50,0x57,0x90,0x10,0x17,0x10,0x12,0x11,0x11,0x10,0x10, + 0x40,0x40,0x40,0xFC,0x40,0x40,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xCAD2 [?] [3904]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3F,0x04,0x08,0x1F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0x20,0xF0,0x10,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xCAD3 [?] [3905]*/ + 0x20,0x11,0x11,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x10,0x10,0x10,0x11,0x12,0x14, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xCAD4 [?] [3906]*/ + 0x00,0x20,0x10,0x10,0x07,0x00,0xF0,0x17,0x11,0x11,0x11,0x15,0x19,0x17,0x02,0x00, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0xE0,0x20,0x10,0x10,0x10,0xCA,0x0A,0x06,0x02, + /* 0xCAD5 [?] [3907]*/ + 0x08,0x08,0x48,0x48,0x48,0x49,0x4A,0x48,0x48,0x58,0x68,0x48,0x08,0x08,0x09,0x0A, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xCAD6 [?] [3908]*/ + 0x00,0x00,0x3F,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x05,0x02, + 0x10,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xCAD7 [?] [3909]*/ + 0x10,0x08,0xFF,0x02,0x04,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20, + 0x10,0x20,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCAD8 [?] [3910]*/ + 0x02,0x01,0x7F,0x40,0x80,0x00,0x00,0xFF,0x00,0x00,0x10,0x08,0x08,0x00,0x01,0x00, + 0x00,0x00,0xFE,0x02,0x44,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xCAD9 [?] [3911]*/ + 0x02,0x02,0x7F,0x02,0x3F,0x04,0xFF,0x08,0x08,0x1F,0x10,0x24,0x42,0x82,0x00,0x00, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xCADA [?] [3912]*/ + 0x10,0x13,0x10,0x12,0xFD,0x11,0x17,0x14,0x18,0x33,0xD1,0x11,0x10,0x10,0x51,0x26, + 0x1C,0xE0,0x84,0x44,0x48,0x10,0xFE,0x02,0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xCADB [?] [3913]*/ + 0x09,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x10,0x00,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCADC [?] [3914]*/ + 0x00,0x01,0x7E,0x22,0x11,0x7F,0x40,0x80,0x3F,0x10,0x08,0x04,0x03,0x0C,0x30,0xC0, + 0x08,0xFC,0x10,0x10,0x20,0xFE,0x02,0x04,0xF0,0x10,0x20,0x40,0x80,0x60,0x18,0x06, + /* 0xCADD [?] [3915]*/ + 0x00,0x00,0x1F,0x11,0x96,0x54,0x57,0x14,0x37,0x50,0x97,0x12,0x21,0x20,0x43,0x8C, + 0x80,0x40,0xFE,0x40,0x5C,0x44,0x5C,0x44,0xFC,0x40,0xFC,0x08,0x10,0xE0,0x18,0x06, + /* 0xCADE [?] [3916]*/ + 0x08,0x04,0x3F,0x21,0x3F,0x21,0x3F,0x00,0xFF,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x20,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xCADF [?] [3917]*/ + 0x08,0xFF,0x08,0x00,0x7D,0x04,0x18,0x51,0x50,0x5C,0x50,0x50,0x5D,0x71,0xC2,0x04, + 0x20,0xFE,0x20,0x10,0xFE,0x20,0x48,0xFE,0x02,0xA8,0xA8,0xA8,0x2A,0x2A,0x2A,0x06, + /* 0xCAE0 [?] [3918]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x32,0x3A,0x56,0x52,0x92,0x12,0x13,0x12,0x13,0x10, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xCAE1 [?] [3919]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x33,0x38,0x55,0x51,0x91,0x11,0x12,0x12,0x14,0x18, + 0x40,0x20,0xFC,0x40,0x90,0x08,0xFC,0x04,0x50,0x50,0x50,0x50,0x50,0x52,0x52,0x0E, + /* 0xCAE2 [?] [3920]*/ + 0x00,0x01,0xFD,0x21,0x21,0x3E,0x44,0x47,0x64,0x94,0x08,0x09,0x11,0x22,0x40,0x80, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xCAE3 [?] [3921]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x13,0x14,0x18,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x00,0xF8,0x08,0x50,0x20,0x10,0xFE,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xCAE4 [?] [3922]*/ + 0x20,0x20,0x21,0xFA,0x25,0x40,0x53,0x92,0xFA,0x13,0x1A,0xF2,0x53,0x12,0x12,0x12, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xCAE5 [?] [3923]*/ + 0x08,0x08,0x0E,0x08,0x08,0x08,0xFF,0x00,0x08,0x08,0x4A,0x49,0x89,0x08,0x28,0x11, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xCAE6 [?] [3924]*/ + 0x10,0x11,0x28,0x44,0x82,0x7C,0x13,0x10,0xFE,0x10,0x10,0x7C,0x44,0x44,0x7C,0x44, + 0x00,0xF8,0x08,0x50,0x20,0x10,0xFE,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xCAE7 [?] [3925]*/ + 0x01,0x21,0x11,0x11,0x81,0x41,0x47,0x10,0x11,0x21,0xE5,0x25,0x29,0x21,0x25,0x02, + 0x00,0x00,0xDC,0x14,0x14,0x14,0xD4,0x14,0x14,0x14,0x88,0x48,0x48,0x14,0x14,0x22, + /* 0xCAE8 [?] [3926]*/ + 0x00,0x00,0x7D,0x04,0x08,0x10,0x51,0x50,0x5C,0x50,0x50,0x50,0x5D,0x71,0xC2,0x04, + 0x20,0x10,0xFE,0x20,0x48,0x84,0xFE,0x02,0xA8,0xA8,0xA8,0xA8,0x2A,0x2A,0x2A,0x06, + /* 0xCAE9 [?] [3927]*/ + 0x02,0x02,0x02,0x3F,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x20,0x10,0x08,0xE0,0x20,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x28,0x10,0x00, + /* 0xCAEA [?] [3928]*/ + 0x00,0x7C,0x45,0x44,0x54,0x57,0x54,0x54,0x54,0x55,0x54,0x13,0x28,0x24,0x40,0x83, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x10,0x90,0xFE,0x28,0x44,0x82,0x02, + /* 0xCAEB [?] [3929]*/ + 0x10,0x08,0xFF,0x00,0x7E,0x42,0x7E,0x01,0x7E,0x04,0x08,0x0E,0xF8,0x08,0x29,0x12, + 0x40,0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0xC8,0x48,0x68,0x5A,0x8A,0x8A,0x06,0x02, + /* 0xCAEC [?] [3930]*/ + 0x10,0xFE,0x00,0x7D,0x44,0x7C,0x00,0x7C,0x08,0xFE,0x11,0x52,0x20,0x48,0x44,0x84, + 0x40,0x40,0x40,0xF8,0x48,0x48,0xC8,0x48,0xAA,0xAA,0x06,0x02,0x00,0x88,0x44,0x44, + /* 0xCAED [?] [3931]*/ + 0x08,0xFF,0x08,0x3F,0x24,0x3F,0x02,0x1F,0x02,0xFF,0x03,0x0F,0x38,0xCF,0x08,0x0F, + 0x20,0xFE,0x20,0xF8,0x48,0xF8,0x00,0xD0,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xCAEE [?] [3932]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x02,0x1F,0x02,0xFF,0x03,0x0F,0x38,0xCF,0x08,0x0F,0x08, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xD0,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xCAEF [?] [3933]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x48,0x49,0x78,0x4B,0x48,0x48,0x49,0x7A,0x48,0x00,0x00, + 0x00,0xFE,0x52,0x52,0xFE,0x24,0xFC,0x28,0xFE,0x20,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xCAF0 [?] [3934]*/ + 0x00,0x3F,0x24,0x24,0x3F,0x02,0x1F,0x02,0xFF,0x03,0x0F,0x38,0xCF,0x08,0x0F,0x08, + 0x00,0xF8,0x48,0x48,0xF8,0x00,0xD0,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xCAF1 [?] [3935]*/ + 0x00,0x3F,0x24,0x24,0x3F,0x10,0x1F,0x22,0x5F,0x92,0x12,0x1F,0x02,0x03,0x7C,0x20, + 0x00,0xF8,0x48,0x48,0xF8,0x00,0xFC,0x04,0xC4,0x44,0x44,0xC4,0x24,0xF4,0x14,0x08, + /* 0xCAF2 [?] [3936]*/ + 0x00,0x3F,0x01,0x7F,0x09,0x11,0x22,0xC4,0x09,0x31,0xCB,0x05,0x19,0x61,0x05,0x02, + 0xF8,0x00,0x00,0xFC,0x20,0x10,0x88,0x44,0x20,0x18,0x26,0xC0,0x30,0x08,0x00,0x00, + /* 0xCAF3 [?] [3937]*/ + 0x04,0x38,0x20,0x3C,0x20,0x20,0x3F,0x00,0x29,0x25,0x21,0x29,0x25,0x21,0x29,0x31, + 0x00,0x78,0x08,0x78,0x08,0x08,0xF8,0x00,0x48,0x28,0x08,0x48,0x2A,0x0A,0x46,0x82, + /* 0xCAF4 [?] [3938]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x2F,0x20,0x2F,0x28,0x2F,0x20,0x3F,0x50,0x57,0x90,0x10, + 0x00,0xFC,0x04,0xFC,0x00,0xF8,0x80,0xF8,0x88,0xF8,0x80,0xFC,0x94,0xF4,0x14,0x08, + /* 0xCAF5 [?] [3939]*/ + 0x01,0x01,0x01,0x01,0x7F,0x03,0x05,0x05,0x09,0x11,0x21,0x41,0x81,0x01,0x01,0x01, + 0x00,0x20,0x10,0x10,0xFC,0x80,0x40,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00, + /* 0xCAF6 [?] [3940]*/ + 0x00,0x20,0x10,0x10,0x07,0x00,0xF0,0x11,0x11,0x12,0x14,0x10,0x10,0x28,0x47,0x00, + 0x40,0x50,0x48,0x40,0xFC,0xC0,0xE0,0x50,0x48,0x44,0x44,0x40,0x40,0x00,0xFE,0x00, + /* 0xCAF7 [?] [3941]*/ + 0x20,0x20,0x27,0x20,0xF8,0x24,0x22,0x72,0x69,0xA1,0xA2,0x22,0x24,0x28,0x20,0x20, + 0x04,0x04,0x84,0x84,0xBE,0x84,0x84,0xA4,0x14,0x14,0x84,0x84,0x84,0x04,0x14,0x08, + /* 0xCAF8 [?] [3942]*/ + 0x01,0x01,0xFF,0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x23,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x88,0x40,0x20,0x18,0x06,0x00, + /* 0xCAF9 [?] [3943]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x30,0x28,0x24,0x24,0x20,0x20,0x40,0x40,0x81, + 0x50,0x48,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xCAFA [?] [3944]*/ + 0x08,0x4B,0x4A,0x49,0x48,0x48,0x48,0x4B,0x0A,0x01,0x3F,0x00,0x08,0x04,0xFF,0x00, + 0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x0C,0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00, + /* 0xCAFB [?] [3945]*/ + 0x7F,0x49,0x7F,0x49,0x7F,0x08,0x7F,0x08,0x0F,0xF0,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x7C,0x04,0x28,0x10,0x7E,0x12,0x14,0x10,0x50,0x20,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xCAFC [?] [3946]*/ + 0x01,0x00,0x3F,0x20,0x22,0x22,0x3F,0x22,0x22,0x22,0x23,0x20,0x4A,0x49,0x91,0x00, + 0x00,0x80,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xE0,0x00,0x48,0x24,0x24,0x00, + /* 0xCAFD [?] [3947]*/ + 0x08,0x49,0x2A,0x08,0xFF,0x2A,0x49,0x88,0x10,0xFE,0x22,0x42,0x64,0x18,0x34,0xC2, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xCAFE [?] [3948]*/ + 0x01,0x21,0x17,0x11,0x81,0x47,0x45,0x15,0x17,0x21,0xE3,0x25,0x29,0x21,0x21,0x01, + 0x08,0x08,0xC8,0x08,0x1E,0xD2,0x64,0x40,0xC8,0x08,0x88,0x48,0x54,0x14,0x24,0x42, + /* 0xCBA1 [?] [3949]*/ + 0x10,0x10,0xFE,0x22,0x44,0x34,0x08,0x14,0x22,0xC0,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCBA2 [?] [3950]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x22,0x22,0x22,0x3F,0x52,0x52,0x52,0x93,0x12,0x02,0x02, + 0x02,0xC2,0x42,0x42,0xD2,0x12,0x12,0x12,0xD2,0x52,0x52,0x52,0x42,0x82,0x0A,0x04, + /* 0xCBA3 [?] [3951]*/ + 0x00,0xFF,0x02,0x04,0x3F,0x24,0x24,0x24,0x22,0x02,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0xFE,0x00,0x00,0xF8,0x88,0x88,0xA8,0x10,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xCBA4 [?] [3952]*/ + 0x10,0x10,0x13,0x10,0xFC,0x12,0x11,0x16,0x18,0x30,0xD0,0x13,0x10,0x10,0x50,0x20, + 0x40,0x20,0xFE,0x20,0x48,0xF2,0x24,0x52,0xF8,0x08,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xCBA5 [?] [3953]*/ + 0x02,0x01,0xFF,0x00,0x1F,0x10,0xFF,0x10,0x1F,0x02,0x04,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0xFE,0x00,0xF0,0x10,0xFE,0x10,0xF0,0x80,0x44,0x28,0x10,0x08,0x06,0x00, + /* 0xCBA6 [?] [3954]*/ + 0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x41,0x41,0x80, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x28,0x12,0x02,0xFE, + /* 0xCBA7 [?] [3955]*/ + 0x08,0x08,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x09,0x11,0x10,0x20,0x40, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,0x20, + /* 0xCBA8 [?] [3956]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x31,0x38,0x54,0x50,0x91,0x10,0x10,0x10,0x13,0x10, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xCBA9 [?] [3957]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x11,0x14,0x18,0x30,0xD1,0x10,0x10,0x10,0x53,0x20, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xCBAA [?] [3958]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x08,0x7E,0x18,0x2C,0x4A,0x88,0x08,0x08, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xCBAB [?] [3959]*/ + 0x00,0x00,0xFD,0x04,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x44,0x81,0x02, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xCBAC [?] [3960]*/ + 0x01,0x01,0x7F,0x01,0x29,0x11,0x29,0x01,0x29,0x11,0x2A,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFC,0x00,0x28,0x10,0x28,0x00,0x28,0x10,0xA8,0x80,0x40,0x20,0x18,0x06, + /* 0xCBAD [?] [3961]*/ + 0x01,0x41,0x21,0x23,0x02,0x06,0xEB,0x22,0x22,0x23,0x22,0x22,0x2A,0x33,0x22,0x02, + 0x40,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00, + /* 0xCBAE [?] [3962]*/ + 0x01,0x01,0x01,0x01,0x01,0x7D,0x05,0x09,0x09,0x11,0x11,0x21,0x41,0x81,0x05,0x02, + 0x00,0x00,0x00,0x08,0x08,0x90,0xA0,0x40,0x40,0x20,0x10,0x08,0x06,0x00,0x00,0x00, + /* 0xCBAF [?] [3963]*/ + 0x00,0x00,0xF3,0x90,0x90,0xF7,0x92,0x92,0xF7,0x92,0x92,0x97,0xF0,0x90,0x07,0x00, + 0x10,0x78,0xC0,0x40,0x40,0xFC,0x48,0x48,0xFE,0x48,0x48,0xFC,0x40,0x40,0xFC,0x00, + /* 0xCBB0 [?] [3964]*/ + 0x09,0x1C,0xF0,0x10,0x11,0xFD,0x11,0x31,0x39,0x54,0x54,0x90,0x10,0x11,0x12,0x14, + 0x04,0x84,0x88,0x10,0xFC,0x04,0x04,0x04,0xFC,0x50,0x50,0x90,0x92,0x12,0x0E,0x00, + /* 0xCBB1 [?] [3965]*/ + 0x00,0x00,0x79,0x49,0x4A,0x4F,0x48,0x49,0x49,0x49,0x79,0x49,0x02,0x02,0x04,0x08, + 0x80,0x80,0x00,0x10,0x08,0xFC,0x04,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xCBB2 [?] [3966]*/ + 0x00,0x07,0xF0,0x92,0x91,0xF7,0x94,0x9A,0xF2,0x93,0x94,0x9A,0xF1,0x92,0x04,0x08, + 0x3C,0xC0,0x44,0x24,0x08,0xFE,0x02,0x08,0x08,0xBE,0x88,0xA8,0x3E,0x08,0x08,0x08, + /* 0xCBB3 [?] [3967]*/ + 0x04,0x45,0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x54,0x85,0x06, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xCBB4 [?] [3968]*/ + 0x00,0x3F,0x01,0x10,0x08,0x7F,0x48,0x08,0x1E,0x22,0x52,0x0C,0x08,0x10,0x20,0x40, + 0x7C,0x80,0x08,0x88,0x90,0xFE,0x12,0x10,0xFC,0x10,0x90,0x90,0xFE,0x10,0x10,0x10, + /* 0xCBB5 [?] [3969]*/ + 0x02,0x21,0x11,0x10,0x03,0x02,0xF2,0x12,0x13,0x10,0x10,0x15,0x19,0x12,0x04,0x08, + 0x08,0x08,0x10,0x20,0xF8,0x08,0x08,0x08,0xF8,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xCBB6 [?] [3970]*/ + 0x00,0x03,0xFC,0x10,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3C,0x24,0x21,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x04, + /* 0xCBB7 [?] [3971]*/ + 0x42,0x22,0x24,0xFF,0x08,0x08,0x49,0x49,0x49,0x7F,0x09,0x10,0x10,0x20,0x41,0x82, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x84,0x84,0x14,0x08, + /* 0xCBB8 [?] [3972]*/ + 0x10,0x10,0x11,0x11,0x55,0x59,0x51,0x91,0x10,0x10,0x10,0x28,0x25,0x46,0x40,0x80, + 0x08,0x1C,0xE0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xCBB9 [?] [3973]*/ + 0x22,0x22,0x7F,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0xFF,0x04,0x22,0x41,0x81, + 0x00,0x04,0x78,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xCBBA [?] [3974]*/ + 0x24,0x24,0x24,0x2F,0xF4,0x27,0x24,0x27,0x34,0xE4,0x2F,0x20,0x25,0x28,0xB0,0x40, + 0x80,0x82,0x9C,0xD0,0x90,0x90,0x9E,0x94,0x94,0x94,0xD4,0x14,0x14,0xA4,0x24,0x44, + /* 0xCBBB [?] [3975]*/ + 0x04,0x04,0xE4,0xAF,0xA4,0xA7,0xA4,0xA7,0xA4,0xA4,0xEF,0xA0,0x05,0x08,0x10,0x00, + 0x80,0x82,0x9C,0xD0,0x90,0x90,0x9E,0x94,0x94,0x94,0xD4,0x14,0x14,0xA4,0x24,0x44, + /* 0xCBBC [?] [3976]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x20,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xCBBD [?] [3977]*/ + 0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x89,0x08,0x08,0x08, + 0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x40,0x48,0x84,0x84,0xFE,0x82,0x02,0x00, + /* 0xCBBE [?] [3978]*/ + 0x00,0x3F,0x00,0x00,0x7F,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0x00, + 0x00,0xF8,0x08,0x08,0xE8,0x08,0x08,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x28,0x10, + /* 0xCBBF [?] [3979]*/ + 0x08,0x08,0x10,0x10,0x22,0x42,0x7C,0x04,0x08,0x10,0x20,0x7E,0x00,0x00,0xFF,0x00, + 0x10,0x10,0x20,0x20,0x44,0x84,0xF8,0x08,0x10,0x20,0x40,0xFC,0x00,0x00,0xFE,0x00, + /* 0xCBC0 [?] [3980]*/ + 0x00,0xFF,0x10,0x10,0x10,0x1E,0x22,0x22,0x52,0x8C,0x04,0x08,0x08,0x10,0x20,0x40, + 0x00,0xFC,0x80,0x80,0x84,0x88,0x90,0xA0,0xC0,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xCBC1 [?] [3981]*/ + 0x00,0x3E,0x20,0x20,0x3D,0x20,0x20,0x3C,0x20,0x21,0xFE,0x20,0x25,0x42,0xFE,0x42, + 0x20,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xCBC2 [?] [3982]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00,0x00,0x7F,0x08,0x04,0x04,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xCBC3 [?] [3983]*/ + 0x00,0x3E,0x22,0x22,0x3E,0x00,0x7F,0x55,0x55,0x55,0x7F,0x55,0x55,0x55,0x51,0x43, + 0x00,0x7C,0x04,0x04,0xF4,0x04,0x04,0x74,0x54,0x54,0x54,0x54,0x74,0x04,0x14,0x08, + /* 0xCBC4 [?] [3984]*/ + 0x00,0x00,0x7F,0x44,0x44,0x44,0x44,0x44,0x48,0x48,0x50,0x60,0x40,0x7F,0x40,0x00, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xCBC5 [?] [3985]*/ + 0x08,0x0B,0x08,0x10,0x17,0x30,0x30,0x53,0x92,0x12,0x12,0x13,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x14,0x08, + /* 0xCBC6 [?] [3986]*/ + 0x10,0x11,0x10,0x24,0x24,0x64,0x64,0xA4,0x24,0x24,0x24,0x25,0x26,0x24,0x20,0x21, + 0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x08,0x10,0x10,0x10,0x28,0x24,0x44,0x82,0x02, + /* 0xCBC7 [?] [3987]*/ + 0x20,0x23,0x20,0x3C,0x47,0x48,0xA0,0x23,0x22,0x22,0x22,0x23,0x28,0x30,0x20,0x00, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x14,0x08, + /* 0xCBC8 [?] [3988]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xCBC9 [?] [3989]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x31,0x3A,0x54,0x54,0x90,0x10,0x11,0x13,0x11,0x10, + 0x10,0x90,0x90,0x88,0x88,0x24,0x24,0x22,0x40,0x40,0x88,0x84,0x04,0xFE,0x02,0x00, + /* 0xCBCA [?] [3990]*/ + 0x08,0x08,0x14,0x22,0x41,0x00,0x7F,0x10,0x1F,0x10,0x1F,0x10,0x10,0xFF,0x00,0x00, + 0x20,0x20,0x50,0x88,0x04,0x00,0xFC,0x10,0xF0,0x10,0xF0,0x10,0x3E,0xD0,0x10,0x10, + /* 0xCBCB [?] [3991]*/ + 0x08,0x08,0x08,0x08,0x14,0x12,0x22,0x20,0x41,0x82,0x01,0x08,0x48,0x48,0x87,0x00, + 0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x88,0x04,0x02,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCBCC [?] [3992]*/ + 0x00,0x28,0x24,0x24,0x42,0x52,0x90,0x10,0x20,0x20,0x48,0x44,0xFC,0x44,0x00,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xCBCD [?] [3993]*/ + 0x02,0x21,0x11,0x17,0x00,0x00,0xF0,0x17,0x10,0x10,0x10,0x11,0x12,0x28,0x47,0x00, + 0x08,0x08,0x10,0xFC,0x40,0x40,0x40,0xFE,0x40,0xA0,0x90,0x08,0x08,0x00,0xFE,0x00, + /* 0xCBCE [?] [3994]*/ + 0x02,0x01,0x7F,0x40,0x81,0x01,0x01,0x7F,0x03,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x00,0x00,0xFE,0x02,0x04,0x00,0x00,0xFC,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xCBCF [?] [3995]*/ + 0x00,0x21,0x11,0x11,0x01,0x02,0xF2,0x14,0x18,0x10,0x11,0x15,0x1A,0x17,0x02,0x00, + 0x20,0x20,0x20,0x10,0x10,0x48,0x48,0x44,0x82,0x80,0x10,0x08,0x08,0xFC,0x04,0x00, + /* 0xCBD0 [?] [3996]*/ + 0x00,0x47,0x20,0x21,0x00,0x07,0xE4,0x24,0x27,0x24,0x24,0x27,0x2C,0x34,0x24,0x04, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xCBD1 [?] [3997]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x18,0x31,0xD0,0x10,0x10,0x10,0x50,0x23, + 0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x20,0xFC,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xCBD2 [?] [3998]*/ + 0x10,0x21,0x7D,0x45,0x65,0x55,0x55,0xFD,0x44,0x65,0x54,0x54,0x44,0x44,0x54,0x8B, + 0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x20,0xFC,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xCBD3 [?] [3999]*/ + 0x22,0x2A,0x27,0x22,0xFF,0x22,0x27,0x2A,0x32,0xEF,0x24,0x28,0x25,0x22,0xA5,0x48, + 0x10,0x90,0x10,0x20,0xBE,0x44,0xA4,0xA4,0x28,0xA8,0x90,0x90,0x28,0x28,0x44,0x82, + /* 0xCBD4 [?] [4000]*/ + 0x01,0x01,0xF7,0x91,0x91,0x97,0x95,0x95,0x97,0x91,0xF3,0x95,0x09,0x01,0x01,0x01, + 0x08,0x08,0xC8,0x08,0x1E,0xD2,0x64,0x40,0xC8,0x08,0x88,0x48,0x54,0x14,0x24,0x42, + /* 0xCBD5 [?] [4001]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x02,0x7F,0x02,0x02,0x22,0x22,0x24,0x44,0x08,0x10,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF0,0x10,0x14,0x12,0x12,0x12,0x10,0x10,0xA0,0x40, + /* 0xCBD6 [?] [4002]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x04,0x1E,0xF0,0x10,0x10,0x10,0xFE,0x10,0x38,0x34,0x54,0x52,0x90,0x10,0x10,0x10, + /* 0xCBD7 [?] [4003]*/ + 0x09,0x09,0x0A,0x14,0x10,0x30,0x31,0x52,0x9C,0x13,0x12,0x12,0x12,0x12,0x13,0x12, + 0x10,0x08,0x04,0x44,0x40,0xA0,0x10,0x08,0x06,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xCBD8 [?] [4004]*/ + 0x01,0x3F,0x01,0x1F,0x01,0xFF,0x02,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0xF8,0x00,0xF0,0x00,0xFE,0x00,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xCBD9 [?] [4005]*/ + 0x00,0x20,0x17,0x10,0x03,0x02,0xF2,0x13,0x10,0x11,0x12,0x14,0x10,0x28,0x47,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x48,0x48,0xF8,0xE0,0x50,0x48,0x44,0x40,0x00,0xFE,0x00, + /* 0xCBDA [?] [4006]*/ + 0x7F,0x04,0x04,0x3F,0x24,0x24,0x3F,0x00,0x11,0x09,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0xFC,0x40,0x40,0xF8,0x48,0x48,0xF8,0x00,0x10,0x20,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xCBDB [?] [4007]*/ + 0x10,0x17,0x10,0x20,0x27,0x64,0x64,0xA7,0x22,0x21,0x27,0x20,0x21,0x22,0x2C,0x20, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xFC,0x48,0x50,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xCBDC [?] [4008]*/ + 0x22,0x14,0xFF,0x08,0x49,0x49,0x7F,0x08,0x10,0x21,0x41,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x94,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xCBDD [?] [4009]*/ + 0x04,0x42,0x22,0x20,0x07,0x81,0x45,0x55,0x15,0x27,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x40,0x5E,0x92,0x12,0xD2,0x1E,0x52,0x52,0x52,0xDE,0x52,0x12,0x12,0x22,0x2A,0x44, + /* 0xCBDE [?] [4010]*/ + 0x02,0x01,0x7F,0x40,0x88,0x0F,0x10,0x30,0x53,0x92,0x12,0x13,0x12,0x12,0x13,0x12, + 0x00,0x00,0xFE,0x02,0x04,0xFC,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCBDF [?] [4011]*/ + 0x00,0x20,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x12,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x30,0x18,0x14,0x12,0x10,0x10,0x10, + /* 0xCBE0 [?] [4012]*/ + 0x01,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x21,0x25,0x25,0x25,0x29,0x41,0x41,0x81, + 0x00,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0x08,0x48,0x28,0x28,0x28,0x08,0x08,0x08, + /* 0xCBE1 [?] [4013]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x10,0x10,0x20,0x44,0xFE,0x28,0x44,0xA2,0x3C,0x44,0x44,0xA8,0x10,0x28,0x44,0x82, + /* 0xCBE2 [?] [4014]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7C,0x00,0x00,0xFE,0x10,0x10,0x54,0x52,0x92,0x50,0x20, + 0x20,0x20,0xFE,0x20,0x00,0x7C,0x00,0x00,0xFE,0x10,0x10,0x54,0x52,0x92,0x50,0x20, + /* 0xCBE3 [?] [4015]*/ + 0x20,0x3E,0x48,0x80,0x3F,0x20,0x3F,0x20,0x3F,0x20,0x3F,0x08,0xFF,0x08,0x10,0x20, + 0x40,0x7E,0x90,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x20,0xFE,0x20,0x20,0x20, + /* 0xCBE4 [?] [4016]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x01,0x01,0x3F,0x21,0x21,0x3F,0x01,0x01,0x01,0x7F,0x20, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0xF8,0x20,0x10,0xF8,0x04,0x04, + /* 0xCBE5 [?] [4017]*/ + 0x00,0x78,0x4B,0x50,0x51,0x62,0x55,0x48,0x49,0x49,0x69,0x51,0x41,0x41,0x41,0x41, + 0x40,0x40,0xFE,0x80,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xCBE6 [?] [4018]*/ + 0x00,0x78,0x49,0x54,0x52,0x60,0x51,0x48,0x4E,0x4A,0x6A,0x52,0x42,0x42,0x45,0x48, + 0x10,0x10,0xFE,0x20,0x40,0xFC,0x44,0x44,0x7C,0x44,0x7C,0x44,0x54,0x48,0x00,0xFE, + /* 0xCBE7 [?] [4019]*/ + 0x10,0x10,0x23,0x20,0x4A,0xF9,0x11,0x20,0x43,0xF8,0x41,0x03,0x18,0xE0,0x41,0x06, + 0x08,0x3C,0xC0,0x44,0x24,0x28,0x00,0x40,0xFE,0x88,0x08,0x90,0x60,0x50,0x88,0x04, + /* 0xCBE8 [?] [4020]*/ + 0x00,0x7C,0x45,0x74,0x54,0xFE,0x82,0x7D,0x44,0x7C,0x44,0x7C,0x44,0x44,0x55,0x4A, + 0x10,0x7E,0x20,0xBC,0xC8,0xBE,0x00,0xBC,0xA4,0xBC,0xA4,0xBC,0xA4,0xAC,0x40,0x3E, + /* 0xCBE9 [?] [4021]*/ + 0x00,0x00,0xFD,0x10,0x10,0x20,0x3D,0x66,0x64,0xA4,0x27,0x24,0x3C,0x24,0x20,0x00, + 0x40,0x20,0xFE,0x00,0x88,0x88,0x54,0x22,0x00,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xCBEA [?] [4022]*/ + 0x01,0x21,0x21,0x21,0x3F,0x02,0x02,0x07,0x08,0x14,0x22,0x01,0x00,0x03,0x1C,0xE0, + 0x00,0x08,0x08,0x08,0xF8,0x00,0x00,0xF0,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xCBEB [?] [4023]*/ + 0x08,0x1C,0xF3,0x10,0x11,0xFD,0x11,0x39,0x35,0x50,0x53,0x90,0x10,0x12,0x12,0x14, + 0x20,0x20,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x22,0xFE,0x42,0x24,0xA2,0x8A,0x78, + /* 0xCBEC [?] [4024]*/ + 0x01,0x20,0x10,0x17,0x00,0x01,0xF6,0x10,0x11,0x16,0x10,0x11,0x16,0x28,0x47,0x00, + 0x10,0x90,0xA0,0xFC,0x80,0x44,0x68,0xB0,0x28,0x68,0xA4,0x24,0xA0,0x40,0xFE,0x00, + /* 0xCBED [?] [4025]*/ + 0x00,0x7C,0x4A,0x50,0x50,0x60,0x56,0x4A,0x4A,0x4A,0x6A,0x52,0x42,0x42,0x45,0x48, + 0x88,0x48,0x50,0xFC,0x20,0x50,0x94,0x38,0x50,0x98,0x34,0x54,0x90,0x20,0xFE,0x00, + /* 0xCBEE [?] [4026]*/ + 0x01,0x11,0x11,0x1F,0x41,0x41,0x7F,0x00,0x3F,0x00,0xFF,0x01,0x11,0x21,0x45,0x02, + 0x00,0x10,0x10,0xF0,0x04,0x04,0xFC,0x00,0xF8,0x00,0xFE,0x00,0x10,0x08,0x04,0x00, + /* 0xCBEF [?] [4027]*/ + 0x00,0x7E,0x02,0x04,0x08,0x08,0x0A,0x0C,0x39,0xC9,0x0A,0x08,0x08,0x08,0x28,0x10, + 0x20,0x20,0x20,0x20,0x20,0xA8,0xA4,0xA4,0x22,0x22,0x22,0x20,0x20,0x20,0xA0,0x40, + /* 0xCBF0 [?] [4028]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x11,0x15,0x19,0x31,0xD1,0x11,0x10,0x10,0x50,0x23, + 0x00,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xCBF1 [?] [4029]*/ + 0x10,0x10,0x3F,0x48,0x85,0x3F,0x02,0x02,0xFF,0x02,0x04,0x3F,0x08,0x10,0x20,0xC0, + 0x40,0x40,0x7E,0x90,0x08,0xF0,0x10,0x10,0xFE,0x10,0x10,0xF0,0x10,0x00,0x00,0x00, + /* 0xCBF2 [?] [4030]*/ + 0x08,0xFF,0x08,0x01,0x7F,0x00,0x1F,0x10,0xFF,0x10,0x1F,0x04,0x08,0x38,0xCB,0x0C, + 0x20,0xFE,0x20,0x00,0xFC,0x00,0xF0,0x10,0xFE,0x10,0xF0,0x88,0x50,0x20,0x18,0x06, + /* 0xCBF3 [?] [4031]*/ + 0x10,0x10,0x10,0x11,0xFB,0x10,0x30,0x39,0x56,0x50,0x91,0x12,0x10,0x10,0x11,0x16, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xCBF4 [?] [4032]*/ + 0x00,0x00,0x78,0x49,0x4B,0x48,0x48,0x49,0x4A,0x48,0x79,0x4A,0x00,0x00,0x01,0x06, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xCBF5 [?] [4033]*/ + 0x20,0x20,0x27,0x44,0x51,0xF1,0x22,0x26,0x4A,0xF2,0x42,0x02,0x32,0xC2,0x02,0x02, + 0x40,0x20,0xFE,0x02,0x00,0xFE,0x10,0x20,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xCBF6 [?] [4034]*/ + 0x00,0x01,0xFC,0x10,0x10,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1C,0xE0,0x41,0x02, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x88,0x04,0x02, + /* 0xCBF7 [?] [4035]*/ + 0x01,0x01,0x3F,0x01,0x01,0x7F,0x42,0x84,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0x00,0xF8,0x00,0x00,0xFE,0x02,0x24,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xCBF8 [?] [4036]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x14,0x18,0x11,0x02, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x88,0x04,0x02, + /* 0xCBF9 [?] [4037]*/ + 0x02,0x07,0x38,0x20,0x20,0x3E,0x22,0x22,0x22,0x3E,0x20,0x20,0x41,0x41,0x82,0x04, + 0x08,0x1C,0xE0,0x80,0x80,0x80,0xFE,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xCBFA [?] [4038]*/ + 0x20,0x23,0x22,0x23,0x22,0xFB,0x20,0x20,0x27,0x20,0x24,0x3A,0xE4,0x40,0x02,0x01, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x00,0xBC,0x84,0xA4,0x94,0xA4,0x84,0x94,0x08, + /* 0xCBFB [?] [4039]*/ + 0x08,0x08,0x0A,0x12,0x12,0x32,0x33,0x5E,0x92,0x12,0x12,0x12,0x12,0x12,0x11,0x10, + 0x40,0x40,0x40,0x58,0x68,0xC8,0x48,0x48,0x48,0x48,0x58,0x42,0x02,0x02,0xFE,0x00, + /* 0xCBFC [?] [4040]*/ + 0x02,0x01,0x7F,0x40,0x80,0x08,0x08,0x08,0x09,0x0E,0x08,0x08,0x08,0x08,0x07,0x00, + 0x00,0x00,0xFE,0x02,0x04,0x00,0x08,0x30,0xC0,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xCBFD [?] [4041]*/ + 0x10,0x10,0x10,0x11,0xFD,0x25,0x25,0x27,0x25,0x49,0x29,0x11,0x29,0x45,0x84,0x00, + 0x20,0x20,0x20,0x20,0x2C,0x34,0x64,0xA4,0x24,0x34,0x28,0x22,0x22,0x02,0xFE,0x00, + /* 0xCBFE [?] [4042]*/ + 0x21,0x21,0x27,0x21,0x20,0xF8,0x21,0x22,0x25,0x20,0x20,0x3B,0xE2,0x42,0x03,0x02, + 0x10,0x10,0xFC,0x10,0x40,0xA0,0x10,0x08,0xF6,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCCA1 [?] [4043]*/ + 0x02,0x92,0x5F,0x22,0x62,0xAF,0x2A,0x2A,0x6F,0xA2,0x27,0x2A,0x32,0x22,0xA2,0x42, + 0x10,0x10,0x9C,0x24,0x48,0xBE,0xA2,0xAA,0xAA,0x2A,0x2A,0xAA,0x88,0x14,0x22,0x42, + /* 0xCCA2 [?] [4044]*/ + 0x10,0x12,0x11,0x11,0xFC,0x10,0x13,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x54,0x20, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x28,0x24,0x44,0x42,0x82,0x00,0x80,0x7E,0x00, + /* 0xCCA3 [?] [4045]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x10,0x10,0x13,0x5C,0x52,0x51,0x52,0x5C,0xE1,0x00, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0x00,0xDE,0x42,0x52,0x4A,0x52,0x42,0x4A,0x84, + /* 0xCCA4 [?] [4046]*/ + 0x00,0x78,0x4B,0x48,0x48,0x79,0x12,0x10,0x51,0x5D,0x51,0x51,0x59,0xE1,0x01,0x01, + 0x20,0x22,0xB4,0xA8,0xA8,0x24,0xA2,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xCCA5 [?] [4047]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x25,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xCCA6 [?] [4048]*/ + 0x08,0x08,0xFF,0x08,0x04,0x08,0x10,0x3F,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x00,0x20,0x10,0xF8,0x08,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xCCA7 [?] [4049]*/ + 0x10,0x10,0x10,0x10,0xFD,0x13,0x10,0x14,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCA8 [?] [4050]*/ + 0x02,0x02,0x04,0x08,0x10,0x20,0x7F,0x20,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0x20,0x10,0x08,0xFC,0x04,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xCCA9 [?] [4051]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x09,0x31,0xCB,0x05,0x19,0x61,0x05,0x02, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x40,0x20,0x18,0x26,0xC0,0x30,0x08,0x00,0x00, + /* 0xCCAA [?] [4052]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAB,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFF,0x82, + 0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0xC8,0x24,0x02, + /* 0xCCAB [?] [4053]*/ + 0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x02,0x02,0x04,0x04,0x0A,0x11,0x21,0xC0, + 0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xCCAC [?] [4054]*/ + 0x01,0x01,0x7F,0x01,0x02,0x04,0x0A,0x31,0xC0,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0xFC,0x00,0x80,0x40,0x20,0x18,0x06,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xCCAD [?] [4055]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x48,0x08,0x10,0x10,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x88,0x48,0x44,0x02, + /* 0xCCAE [?] [4056]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x17,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x00,0xF8,0x08,0x08,0x48,0x28,0x28,0x08,0xFE,0x08,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xCCAF [?] [4057]*/ + 0x20,0x20,0x27,0x21,0xF1,0x29,0x25,0x25,0x32,0xE2,0x25,0x25,0x29,0x20,0xA0,0x40, + 0x28,0x24,0x40,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x48,0x7E,0x40,0x40, + /* 0xCCB0 [?] [4058]*/ + 0x01,0x02,0x04,0x09,0x30,0xCF,0x00,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0x80,0x40,0x20,0x98,0xE6,0x40,0x80,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xCCB1 [?] [4059]*/ + 0x01,0x00,0x3F,0x20,0x20,0xBE,0x72,0x2A,0x2B,0x64,0xA4,0x2A,0x2A,0x52,0x40,0x80, + 0x00,0x80,0xFE,0x50,0x48,0xFE,0x90,0x90,0xFE,0x90,0x90,0xFE,0x90,0x90,0xFE,0x80, + /* 0xCCB2 [?] [4060]*/ + 0x00,0x40,0x2E,0x22,0x03,0x92,0x4A,0x5A,0x14,0x24,0xEA,0x2A,0x32,0x20,0x20,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xCCB3 [?] [4061]*/ + 0x10,0x10,0x11,0x10,0x10,0xFC,0x13,0x10,0x10,0x10,0x10,0x1C,0xE1,0x43,0x01,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0x88,0x04,0xFE,0x02,0x00, + /* 0xCCB4 [?] [4062]*/ + 0x20,0x2F,0x20,0x27,0xFC,0x25,0x25,0x77,0x68,0xA3,0xA2,0x23,0x22,0x23,0x20,0x2F, + 0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xCCB5 [?] [4063]*/ + 0x00,0x00,0x1F,0x10,0x92,0x52,0x54,0x11,0x32,0x5C,0x92,0x12,0x24,0x21,0x42,0x8C, + 0x80,0x40,0xFE,0x40,0x48,0x50,0xA0,0x10,0x08,0x44,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xCCB6 [?] [4064]*/ + 0x00,0x27,0x10,0x17,0x84,0x47,0x40,0x13,0x12,0x23,0xE2,0x23,0x20,0x27,0x20,0x00, + 0x00,0xFC,0xA0,0xFC,0xA4,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0x40,0x40, + /* 0xCCB7 [?] [4065]*/ + 0x00,0x23,0x10,0x13,0x02,0x03,0xF0,0x11,0x11,0x11,0x11,0x15,0x18,0x13,0x00,0x00, + 0x00,0xFE,0x50,0xFE,0x52,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20, + /* 0xCCB8 [?] [4066]*/ + 0x00,0x22,0x12,0x14,0x00,0x01,0xF6,0x10,0x10,0x12,0x12,0x14,0x18,0x11,0x02,0x0C, + 0x40,0x44,0x44,0x48,0xA0,0x10,0x08,0x44,0x40,0x48,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xCCB9 [?] [4067]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE0,0x40,0x03,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xCCBA [?] [4068]*/ + 0x10,0x3A,0xE2,0x24,0x20,0x39,0xE6,0x20,0x20,0x3A,0xE2,0x24,0x20,0x21,0x22,0x1F, + 0x40,0x44,0x44,0x48,0xA0,0x10,0x08,0x44,0x40,0x48,0x48,0x50,0xA2,0x12,0x0A,0xFE, + /* 0xCCBB [?] [4069]*/ + 0x20,0x10,0x01,0xFD,0x09,0x11,0x11,0x35,0x59,0x95,0x15,0x11,0x10,0x10,0x13,0x10, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xCCBC [?] [4070]*/ + 0x00,0x01,0xF9,0x21,0x21,0x40,0x78,0x4B,0xC8,0x49,0x49,0x4A,0x7A,0x4C,0x08,0x00, + 0x20,0x24,0x24,0x24,0xFC,0x80,0x80,0xFE,0x90,0x10,0x52,0x54,0xA8,0x28,0x44,0x82, + /* 0xCCBD [?] [4071]*/ + 0x20,0x27,0x24,0x24,0xF9,0x22,0x20,0x28,0x37,0xE0,0x20,0x21,0x22,0x2C,0xA0,0x40, + 0x00,0xFC,0x04,0xA4,0x10,0x08,0x40,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xCCBE [?] [4072]*/ + 0x00,0x07,0x7A,0x4A,0x4A,0x49,0x49,0x49,0x48,0x48,0x78,0x48,0x00,0x01,0x02,0x0C, + 0x00,0xF8,0x08,0x08,0x08,0x10,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0x10,0x08,0x06, + /* 0xCCBF [?] [4073]*/ + 0x01,0x21,0x21,0x3F,0x08,0x08,0xFF,0x10,0x10,0x14,0x24,0x29,0x41,0x82,0x0C,0x30, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xFE,0x80,0x88,0x88,0x90,0x40,0x40,0x20,0x18,0x06, + /* 0xCCC0 [?] [4074]*/ + 0x00,0x23,0x10,0x10,0x80,0x41,0x43,0x11,0x11,0x21,0xE2,0x22,0x24,0x28,0x21,0x02, + 0x00,0xF0,0x20,0x40,0x80,0x00,0xFC,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xCCC1 [?] [4075]*/ + 0x20,0x20,0x27,0x24,0x25,0xFC,0x27,0x24,0x25,0x24,0x25,0x3D,0xE5,0x49,0x09,0x11, + 0x40,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCC2 [?] [4076]*/ + 0x20,0x20,0x27,0x24,0xFD,0x24,0x27,0x2C,0x35,0xE4,0x25,0x25,0x25,0x29,0xA9,0x51, + 0x40,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCC3 [?] [4077]*/ + 0x01,0x11,0x09,0x7F,0x40,0x9F,0x10,0x10,0x1F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x10,0x20,0xFE,0x02,0xF4,0x10,0x10,0xF0,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xCCC4 [?] [4078]*/ + 0x01,0x11,0x09,0x7F,0x40,0x9F,0x10,0x10,0x1F,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x10,0x20,0xFE,0x02,0xF4,0x10,0x10,0xF0,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xCCC5 [?] [4079]*/ + 0x00,0x79,0x48,0x4B,0x4A,0x78,0x48,0x48,0x48,0x78,0x48,0x49,0x48,0x48,0x4B,0x98, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xCCC6 [?] [4080]*/ + 0x01,0x00,0x3F,0x20,0x2F,0x20,0x3F,0x20,0x2F,0x20,0x2F,0x28,0x48,0x48,0x8F,0x08, + 0x00,0x80,0xFE,0x80,0xF8,0x88,0xFE,0x88,0xF8,0x80,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xCCC7 [?] [4081]*/ + 0x10,0x10,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x12,0x12,0x14, + 0x20,0x10,0xFE,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xCCC8 [?] [4082]*/ + 0x10,0x12,0x11,0x21,0x20,0x67,0x64,0xA4,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24, + 0x40,0x48,0x48,0x50,0x40,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xCCC9 [?] [4083]*/ + 0x10,0x21,0x7C,0x44,0x7C,0x45,0x7D,0x45,0x45,0xFD,0x0D,0x15,0x25,0x45,0x95,0x09, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0x74,0x54,0x54,0x54,0x74,0x04,0x14,0x08, + /* 0xCCCA [?] [4084]*/ + 0x00,0x22,0x11,0x11,0x80,0x47,0x44,0x14,0x15,0x25,0xE5,0x25,0x25,0x24,0x24,0x04, + 0x40,0x48,0x48,0x50,0x40,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xCCCB [?] [4085]*/ + 0x10,0x11,0x10,0x7C,0x11,0x11,0xFD,0x11,0x11,0x51,0x5D,0x51,0x71,0x50,0x4F,0x80, + 0x20,0x24,0xA4,0xA8,0xFC,0x04,0x04,0x74,0x54,0x54,0x74,0x04,0x0C,0x00,0xFE,0x00, + /* 0xCCCC [?] [4086]*/ + 0x23,0x10,0x80,0x43,0x11,0x21,0xE2,0x24,0x29,0x20,0x01,0x11,0x22,0x04,0x18,0xE0, + 0xF0,0x20,0xC0,0xFC,0x24,0x24,0x44,0x84,0x28,0x10,0x00,0x10,0xA0,0x40,0x30,0x0E, + /* 0xCCCD [?] [4087]*/ + 0x10,0x10,0x10,0x11,0xFE,0x10,0x11,0x14,0x1B,0x30,0xD1,0x11,0x11,0x10,0x50,0x20, + 0x80,0x80,0xFE,0x02,0x82,0xF2,0x42,0x42,0xFA,0x42,0x52,0x52,0xF2,0x02,0x14,0x08, + /* 0xCCCE [?] [4088]*/ + 0x00,0x20,0x17,0x10,0x83,0x40,0x47,0x10,0x11,0x21,0xE2,0x22,0x24,0x28,0x20,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFE,0x90,0x10,0xFE,0x10,0x90,0x50,0x10,0x50,0x20, + /* 0xCCCF [?] [4089]*/ + 0x00,0x4F,0x20,0x24,0x02,0x82,0x41,0x56,0x14,0x24,0xE7,0x24,0x24,0x24,0x27,0x04, + 0x3E,0xC0,0x84,0x44,0x48,0x10,0x00,0x1C,0x04,0x04,0x1C,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCD0 [?] [4090]*/ + 0x10,0x10,0x21,0x23,0x4C,0xF0,0x11,0x26,0x40,0xFB,0x40,0x02,0x1A,0xE4,0x41,0x00, + 0x80,0x80,0xF8,0x08,0x90,0x60,0x98,0x46,0x40,0xFC,0x40,0x48,0x44,0x44,0x40,0x80, + /* 0xCCD1 [?] [4091]*/ + 0x08,0xFF,0x08,0x20,0x3F,0x48,0x9F,0x22,0x02,0xFF,0x02,0x22,0x22,0x3F,0x00,0x00, + 0x20,0xFE,0x20,0x00,0xFC,0x04,0xE4,0x04,0x04,0xFC,0x04,0x24,0x24,0xE4,0x28,0x10, + /* 0xCCD2 [?] [4092]*/ + 0x10,0x10,0x10,0x12,0xFD,0x10,0x30,0x39,0x56,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xCCD3 [?] [4093]*/ + 0x00,0x20,0x14,0x12,0x01,0x00,0xF1,0x12,0x14,0x11,0x11,0x12,0x14,0x28,0x47,0x00, + 0xA0,0xA0,0xA4,0xA8,0xB0,0xA0,0xB0,0xA8,0xA4,0x20,0x24,0x24,0x1C,0x00,0xFE,0x00, + /* 0xCCD4 [?] [4094]*/ + 0x01,0x21,0x11,0x12,0x85,0x41,0x42,0x10,0x17,0x20,0xE2,0x22,0x23,0x20,0x20,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x84,0x84,0xF4,0x84,0xA4,0xA4,0xE4,0x04,0x28,0x10, + /* 0xCCD5 [?] [4095]*/ + 0x01,0x79,0x49,0x52,0x55,0x61,0x52,0x48,0x4F,0x48,0x6A,0x52,0x43,0x40,0x40,0x40, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x84,0x84,0xF4,0x84,0xA4,0xA4,0xE4,0x04,0x28,0x10, + /* 0xCCD6 [?] [4096]*/ + 0x00,0x20,0x10,0x10,0x03,0x00,0xF0,0x10,0x11,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xCCD7 [?] [4097]*/ + 0x01,0x01,0x7F,0x02,0x04,0x0F,0x34,0xC7,0x04,0x07,0x04,0xFF,0x04,0x08,0x1F,0x00, + 0x00,0x00,0xFC,0x80,0x40,0xF0,0x18,0xE6,0x00,0xE0,0x00,0xFE,0x00,0x10,0xF8,0x08, + /* 0xCCD8 [?] [4098]*/ + 0x10,0x10,0x50,0x51,0x7C,0x50,0x93,0x10,0x1C,0xF1,0x50,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0xFC,0x20,0x20,0xFE,0x08,0x08,0xFE,0x08,0x88,0x48,0x08,0x28,0x10, + /* 0xCCD9 [?] [4099]*/ + 0x04,0xFF,0x04,0x00,0x3D,0x24,0x25,0x3C,0x27,0x24,0x3D,0x26,0x24,0x44,0x55,0x8A, + 0x40,0xFE,0x40,0x20,0x24,0xA8,0xFC,0x40,0xFE,0x88,0x24,0xAA,0x70,0xA8,0x24,0x62, + /* 0xCCDA [?] [4100]*/ + 0x02,0x79,0x49,0x4F,0x48,0x7F,0x49,0x4A,0x4D,0x78,0x49,0x49,0x48,0x4B,0x48,0x98, + 0x48,0x48,0x50,0xFC,0x40,0xFE,0x10,0x08,0xF6,0x10,0x10,0xFC,0x04,0xE4,0x14,0x08, + /* 0xCCDB [?] [4101]*/ + 0x00,0x00,0x1F,0x11,0x91,0x53,0x56,0x19,0x30,0x53,0x9C,0x10,0x20,0x23,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xF8,0x10,0x20,0xC0,0x30,0x0E,0xC0,0x20,0x00,0xC0,0x20, + /* 0xCCDC [?] [4102]*/ + 0x11,0x09,0x09,0x7F,0x02,0xFF,0x09,0x3F,0xC0,0x1F,0x00,0x1F,0x00,0x1F,0x10,0x1F, + 0x10,0x10,0x20,0xFC,0x00,0xFE,0x20,0xF8,0x06,0xF0,0x00,0xF0,0x00,0xF0,0x10,0xF0, + /* 0xCCDD [?] [4103]*/ + 0x11,0x10,0x10,0x11,0xFC,0x10,0x31,0x39,0x55,0x51,0x90,0x10,0x11,0x12,0x14,0x10, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xCCDE [?] [4104]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x10,0x3F,0x4A,0x92,0x24,0x48,0x12,0x21, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0xA4,0xA4,0xA4,0x84,0x84,0x94,0x08, + /* 0xCCDF [?] [4105]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x10,0x10,0x5C,0x50,0x51,0x52,0x5C,0xE1,0x00,0x00, + 0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x40,0xFE,0x2A,0x4A,0x92,0x22,0x4A,0x84, + /* 0xCCE0 [?] [4106]*/ + 0x21,0x20,0x38,0x23,0x40,0x78,0xA3,0x22,0xFA,0x23,0x20,0x20,0x29,0x32,0x24,0x00, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xCCE1 [?] [4107]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x18,0x33,0xD0,0x11,0x11,0x11,0x52,0x24, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x20,0x20,0x3C,0x20,0xA0,0x7E, + /* 0xCCE2 [?] [4108]*/ + 0x00,0x3E,0x22,0x3E,0x22,0x3E,0x00,0xFF,0x08,0x08,0x2F,0x28,0x28,0x58,0x4F,0x80, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x28,0x44,0x82,0x00,0xFE,0x00, + /* 0xCCE3 [?] [4109]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7C,0x13,0x12,0x5C,0x51,0x51,0x51,0x5D,0xE1,0x00,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCCE4 [?] [4110]*/ + 0x00,0x00,0x79,0x48,0x48,0x48,0x4B,0x4A,0x4C,0x49,0x49,0x79,0x49,0x01,0x00,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCCE5 [?] [4111]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x50,0x91,0x11,0x12,0x15,0x18,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0xFC,0x40,0xE0,0xE0,0x50,0x50,0x48,0xF4,0x42,0x40,0x40,0x40, + /* 0xCCE6 [?] [4112]*/ + 0x08,0x08,0x7E,0x08,0xFE,0x14,0x22,0x41,0x9F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFC,0x20,0xFE,0x50,0x88,0x06,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xCCE7 [?] [4113]*/ + 0x00,0x07,0xF0,0x97,0x94,0x9B,0x92,0x93,0x92,0x93,0xF0,0x97,0x02,0x02,0x05,0x08, + 0x40,0xFC,0x40,0xFE,0x02,0xFC,0x48,0xF8,0x48,0xF8,0x00,0xFC,0x44,0x78,0x40,0xFE, + /* 0xCCE8 [?] [4114]*/ + 0x10,0x11,0x11,0x11,0x19,0x55,0x50,0x50,0x91,0x12,0x14,0x10,0x11,0x12,0x10,0x11, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0x80,0xFE,0x4A,0x4A,0x92,0x22,0x42,0x94,0x08, + /* 0xCCE9 [?] [4115]*/ + 0x02,0x21,0x11,0x17,0x80,0x40,0x47,0x14,0x14,0x27,0xE0,0x21,0x22,0x24,0x28,0x00, + 0x10,0x10,0x20,0xF8,0x48,0x48,0xF8,0x40,0x40,0xFC,0xC4,0x44,0x54,0x48,0x40,0x40, + /* 0xCCEA [?] [4116]*/ + 0x42,0x22,0x24,0xFF,0x09,0x09,0xFF,0x88,0x88,0xFF,0x18,0x28,0x4A,0x89,0x08,0x08, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0xA4,0xA4,0xA4,0x84,0x04,0x14,0x08, + /* 0xCCEB [?] [4117]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x24,0x24,0x24,0x3F,0x24,0x24,0x44,0x44,0x84,0x07, + 0x00,0xF8,0x08,0x08,0xF8,0x90,0x90,0x90,0x90,0xFC,0x90,0x90,0xF0,0x00,0x00,0xFE, + /* 0xCCEC [?] [4118]*/ + 0x00,0x3F,0x01,0x01,0x01,0x01,0xFF,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xCCED [?] [4119]*/ + 0x00,0x23,0x10,0x10,0x87,0x40,0x41,0x12,0x14,0x20,0xE0,0x22,0x22,0x24,0x21,0x00, + 0x00,0xFC,0x40,0x40,0xFE,0xA0,0x10,0x08,0x46,0x40,0x48,0x64,0x52,0x52,0x40,0x80, + /* 0xCCEE [?] [4120]*/ + 0x20,0x20,0x27,0x20,0x23,0xFA,0x23,0x22,0x23,0x22,0x23,0x3A,0xEF,0x41,0x02,0x04, + 0x40,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFE,0x10,0x08,0x04, + /* 0xCCEF [?] [4121]*/ + 0x00,0x3F,0x21,0x21,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x21,0x21,0x3F,0x20,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00, + /* 0xCCF0 [?] [4122]*/ + 0x08,0x1C,0x70,0x10,0x11,0xFC,0x10,0x10,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x00, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xCCF1 [?] [4123]*/ + 0x10,0x10,0x11,0x10,0x18,0x55,0x50,0x50,0x90,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCF2 [?] [4124]*/ + 0x08,0x1D,0x70,0x10,0x11,0xFC,0x10,0x10,0x7D,0x46,0x44,0x44,0x44,0x7D,0x44,0x00, + 0x00,0xFC,0x20,0x20,0xFE,0x50,0x50,0x88,0x24,0x22,0x24,0xB2,0xAA,0x2A,0xA0,0x40, + /* 0xCCF3 [?] [4125]*/ + 0x00,0x78,0x48,0x49,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x4B,0x48,0x48,0x49,0x9A, + 0x50,0x50,0x50,0xFC,0x54,0x54,0x54,0xFC,0x54,0x54,0x54,0xFE,0x00,0x88,0x04,0x02, + /* 0xCCF4 [?] [4126]*/ + 0x10,0x10,0x10,0x12,0xFD,0x10,0x10,0x15,0x1A,0x34,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xCCF5 [?] [4127]*/ + 0x04,0x04,0x0F,0x18,0x64,0x03,0x1D,0xE1,0x01,0x7F,0x01,0x09,0x11,0x21,0x45,0x02, + 0x00,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E,0x00,0xFC,0x00,0x20,0x10,0x08,0x04,0x00, + /* 0xCCF6 [?] [4128]*/ + 0x00,0x23,0x10,0x10,0x00,0x01,0xF2,0x11,0x11,0x11,0x11,0x11,0x10,0x28,0x47,0x00, + 0x00,0xFC,0x84,0x84,0x84,0x14,0x08,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0xFE,0x00, + /* 0xCCF7 [?] [4129]*/ + 0x00,0x00,0x78,0x4A,0x49,0x78,0x48,0x49,0x7A,0x4C,0x48,0x48,0x79,0x49,0x02,0x04, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xCCF8 [?] [4130]*/ + 0x00,0x7C,0x44,0x45,0x44,0x7C,0x10,0x10,0x10,0x5D,0x50,0x50,0x50,0x5C,0xE1,0x02, + 0x50,0x50,0x50,0x52,0xD4,0x58,0x50,0x58,0xD4,0x52,0x50,0x50,0x92,0x92,0x12,0x0E, + /* 0xCCF9 [?] [4131]*/ + 0x00,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x11,0x29,0x25,0x45,0x81, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCFA [?] [4132]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x12,0x10,0xFD,0x10,0x10,0x10,0x14,0x18,0x11,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xCCFB [?] [4133]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x5D,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCCFC [?] [4134]*/ + 0x00,0x3F,0x20,0x20,0x20,0x2F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x41,0x80, + 0x00,0xFE,0x00,0x00,0x00,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xCCFD [?] [4135]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x02,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xCCFE [?] [4136]*/ + 0x10,0x11,0x10,0x10,0x54,0x58,0x50,0x93,0x10,0x11,0x10,0x28,0x24,0x44,0x43,0x80, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xCDA1 [?] [4137]*/ + 0x00,0x20,0x13,0x10,0x80,0x40,0x48,0x08,0x10,0x10,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xCDA2 [?] [4138]*/ + 0x00,0x00,0xF9,0x08,0x10,0x10,0x21,0x78,0x08,0x08,0x48,0x33,0x10,0x2C,0x43,0x80, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00,0x00,0xFE,0x00, + /* 0xCDA3 [?] [4139]*/ + 0x10,0x10,0x17,0x20,0x23,0x62,0x63,0xA0,0x2F,0x28,0x23,0x20,0x20,0x20,0x21,0x20, + 0x80,0x40,0xFC,0x00,0xF8,0x08,0xF8,0x00,0xFE,0x02,0xF8,0x40,0x40,0x40,0x40,0x80, + /* 0xCDA4 [?] [4140]*/ + 0x02,0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x9F,0x01,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0x00,0x00,0x00,0x00, + /* 0xCDA5 [?] [4141]*/ + 0x01,0x00,0x3F,0x20,0x2E,0x22,0x24,0x24,0x2E,0x22,0x22,0x2A,0x44,0x46,0x89,0x10, + 0x00,0x80,0xFE,0x00,0x0E,0xF0,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0x00,0xFE,0x00, + /* 0xCDA6 [?] [4142]*/ + 0x20,0x20,0x27,0x21,0xF9,0x22,0x22,0x2F,0x31,0xE5,0x25,0x22,0x22,0x25,0xA8,0x50, + 0x00,0x0C,0x70,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,0xFE,0x00, + /* 0xCDA7 [?] [4143]*/ + 0x10,0x20,0x7B,0x48,0x68,0x59,0x49,0xFB,0x48,0x4A,0x6A,0x59,0x49,0x4A,0x4C,0x98, + 0x00,0x06,0xB8,0x88,0x88,0x08,0x3E,0x88,0x88,0x88,0x88,0x3E,0x00,0x80,0x7E,0x00, + /* 0xCDA8 [?] [4144]*/ + 0x00,0x47,0x20,0x21,0x00,0x07,0xE4,0x24,0x27,0x24,0x24,0x27,0x24,0x24,0x54,0x8F, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x54,0x08,0xFE, + /* 0xCDA9 [?] [4145]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x32,0x3A,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xCDAA [?] [4146]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0xFE,0x82,0x82,0xBA,0x82,0x82,0xBA,0xAA,0xAA,0xAA,0xBA,0x82,0x82,0x8A,0x84, + /* 0xCDAB [?] [4147]*/ + 0x00,0x01,0x78,0x48,0x4B,0x78,0x49,0x49,0x79,0x49,0x49,0x48,0x79,0x48,0x03,0x00, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xCDAC [?] [4148]*/ + 0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x24,0x20,0x20,0x20, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x14,0x08, + /* 0xCDAD [?] [4149]*/ + 0x20,0x23,0x3A,0x22,0x42,0x7A,0xA2,0x22,0xFA,0x22,0x22,0x22,0x2A,0x32,0x22,0x02, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xCDAE [?] [4150]*/ + 0x00,0x3F,0x21,0x21,0x29,0x25,0x25,0x21,0xFF,0x21,0x21,0x21,0x21,0x41,0x45,0x82, + 0x00,0x04,0x04,0x08,0x10,0x22,0x02,0x04,0xC8,0x10,0x22,0x02,0x04,0x08,0x10,0x60, + /* 0xCDAF [?] [4151]*/ + 0x02,0x01,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x3F,0x01,0xFF, + 0x00,0x00,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x00,0xFE, + /* 0xCDB0 [?] [4152]*/ + 0x20,0x27,0x20,0x21,0xF8,0x27,0x24,0x74,0x6F,0xA4,0xA4,0x27,0x24,0x24,0x24,0x24, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xCDB1 [?] [4153]*/ + 0x20,0x27,0x20,0x21,0xF8,0x27,0x24,0x2C,0x37,0xE4,0x24,0x27,0x24,0x24,0xA4,0x44, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xCDB2 [?] [4154]*/ + 0x10,0x10,0x3F,0x28,0x45,0xBF,0x20,0x2F,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x20, + 0x40,0x40,0x7E,0x90,0x08,0xF8,0x08,0xE8,0x08,0xC8,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xCDB3 [?] [4155]*/ + 0x10,0x10,0x20,0x23,0x48,0xF8,0x11,0x23,0x40,0xF8,0x40,0x00,0x19,0xE1,0x42,0x04, + 0x40,0x20,0x20,0xFE,0x40,0x88,0x04,0xFE,0x92,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xCDB4 [?] [4156]*/ + 0x00,0x00,0x1F,0x10,0x97,0x51,0x50,0x17,0x34,0x57,0x94,0x17,0x24,0x24,0x44,0x84, + 0x80,0x40,0xFE,0x00,0xF8,0x10,0xA0,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xCDB5 [?] [4157]*/ + 0x08,0x08,0x09,0x12,0x15,0x30,0x33,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x12,0x12, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xCDB6 [?] [4158]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x12,0x15,0x18,0x30,0xD0,0x10,0x10,0x10,0x50,0x23, + 0x00,0xF8,0x88,0x88,0x88,0x06,0x00,0xFC,0x84,0x84,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xCDB7 [?] [4159]*/ + 0x00,0x00,0x08,0x04,0x24,0x10,0x10,0x00,0xFF,0x01,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE,0x00,0x40,0x20,0x10,0x08,0x04,0x04, + /* 0xCDB8 [?] [4160]*/ + 0x00,0x23,0x10,0x17,0x01,0x02,0xF4,0x13,0x11,0x11,0x11,0x12,0x14,0x28,0x47,0x00, + 0x38,0xC0,0x40,0xFC,0x50,0x48,0x46,0xF0,0x10,0x3C,0x04,0x14,0x08,0x00,0xFE,0x00, + /* 0xCDB9 [?] [4161]*/ + 0x00,0x0F,0x08,0x08,0x08,0x08,0x08,0x78,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xCDBA [?] [4162]*/ + 0x00,0x1F,0x01,0x01,0x7F,0x05,0x09,0x31,0xC0,0x0F,0x08,0x08,0x08,0x10,0x20,0x40, + 0x70,0x80,0x00,0x00,0xFC,0x40,0x20,0x18,0x06,0xC0,0x40,0x40,0x44,0x44,0x3C,0x00, + /* 0xCDBB [?] [4163]*/ + 0x02,0x01,0x7F,0x40,0x88,0x11,0x21,0x01,0x01,0x7F,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x48,0x20,0x00,0xFC,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xCDBC [?] [4164]*/ + 0x00,0x7F,0x42,0x42,0x47,0x4C,0x52,0x41,0x46,0x78,0x43,0x40,0x46,0x41,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x44,0x84,0x04,0xC4,0x3C,0x04,0x84,0x04,0x84,0xFC,0x04, + /* 0xCDBD [?] [4165]*/ + 0x08,0x08,0x11,0x20,0x48,0x08,0x13,0x30,0x50,0x91,0x11,0x11,0x12,0x12,0x14,0x18, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xCDBE [?] [4166]*/ + 0x00,0x20,0x11,0x12,0x05,0x00,0xF0,0x17,0x10,0x12,0x12,0x14,0x11,0x28,0x47,0x00, + 0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x48,0x44,0x44,0x40,0x80,0xFE,0x00, + /* 0xCDBF [?] [4167]*/ + 0x00,0x20,0x10,0x11,0x82,0x45,0x40,0x10,0x17,0x20,0xE2,0x22,0x24,0x28,0x21,0x00, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xCDC0 [?] [4168]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x20,0x27,0x20,0x3F,0x20,0x23,0x26,0x5B,0x42,0x83,0x02, + 0x00,0xFC,0x04,0xFC,0x80,0x88,0xF0,0xA0,0xFE,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xCDC1 [?] [4169]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xCDC2 [?] [4170]*/ + 0x00,0x00,0x78,0x48,0x48,0x48,0x4F,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x0F,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xCDC3 [?] [4171]*/ + 0x08,0x08,0x0F,0x10,0x20,0x7F,0xA1,0x21,0x21,0x3F,0x22,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0x08,0xF8,0x88,0xA0,0x90,0x92,0x82,0x7E, + /* 0xCDC4 [?] [4172]*/ + 0x00,0x24,0x14,0x14,0x87,0x40,0x4F,0x10,0x10,0x27,0xE4,0x24,0x24,0x24,0x24,0x04, + 0x40,0x44,0x44,0x44,0xFC,0x00,0xFE,0x40,0x80,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0x0C, + /* 0xCDC5 [?] [4173]*/ + 0x00,0x7F,0x40,0x40,0x40,0x5F,0x40,0x41,0x42,0x44,0x48,0x50,0x42,0x41,0x7F,0x40, + 0x00,0xFC,0x04,0x84,0x84,0xF4,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0xFC,0x04, + /* 0xCDC6 [?] [4174]*/ + 0x10,0x10,0x10,0x11,0xFD,0x13,0x15,0x11,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xCDC7 [?] [4175]*/ + 0x0C,0x71,0x10,0xFE,0x11,0x39,0x55,0x93,0x01,0x39,0x29,0x29,0x2A,0x4C,0x49,0x82, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xCDC8 [?] [4176]*/ + 0x00,0x7A,0x49,0x49,0x48,0x78,0x4F,0x49,0x49,0x79,0x49,0x49,0x49,0x49,0x4A,0x9C, + 0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x50,0x4A,0x44,0x54,0x62,0x42,0x80,0x7E, + /* 0xCDC9 [?] [4177]*/ + 0x11,0x10,0x10,0x7C,0x55,0x55,0x55,0x55,0x7D,0x50,0x10,0x14,0x1C,0xE5,0x42,0x04, + 0x04,0x84,0x88,0x10,0xFC,0x04,0x04,0x04,0xFC,0x50,0x50,0x90,0x92,0x12,0x0E,0x00, + /* 0xCDCA [?] [4178]*/ + 0x20,0x12,0x01,0xF9,0x08,0x10,0x17,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x12,0x14, + 0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x50,0x4A,0x44,0x54,0x62,0x42,0x80,0x7E, + /* 0xCDCB [?] [4179]*/ + 0x03,0x22,0x12,0x13,0x02,0x02,0xF3,0x12,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x28,0x10,0x88,0x04,0x04,0x00,0xFE,0x00, + /* 0xCDCC [?] [4180]*/ + 0x00,0x3F,0x01,0x01,0xFF,0x02,0x04,0x08,0x30,0xDF,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0xF6,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xCDCD [?] [4181]*/ + 0x01,0x01,0x01,0xFF,0x01,0x21,0x21,0x21,0x21,0x3F,0x01,0x01,0x01,0x01,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x00,0x08,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xCDCE [?] [4182]*/ + 0x7E,0x42,0x7E,0x54,0x7E,0x54,0x7E,0x94,0x62,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10, + 0x78,0x48,0x48,0x86,0x78,0x48,0x30,0xCE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x30, + /* 0xCDCF [?] [4183]*/ + 0x10,0x10,0x10,0x11,0xFE,0x11,0x11,0x15,0x1B,0x31,0xD1,0x11,0x11,0x11,0x50,0x20, + 0x80,0x80,0xFE,0x00,0x20,0x20,0x2C,0x74,0xA4,0x24,0x34,0x28,0x22,0x02,0xFE,0x00, + /* 0xCDD0 [?] [4184]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x14,0x1B,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x08,0x3C,0xC0,0x40,0x40,0x40,0x40,0x7E,0xC0,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xCDD1 [?] [4185]*/ + 0x01,0x78,0x48,0x48,0x49,0x79,0x49,0x49,0x49,0x78,0x48,0x48,0x48,0x49,0x4A,0x9C, + 0x04,0x84,0x88,0x10,0xFC,0x04,0x04,0x04,0xFC,0x50,0x50,0x90,0x92,0x12,0x0E,0x00, + /* 0xCDD2 [?] [4186]*/ + 0x10,0x20,0x7C,0x44,0x54,0x45,0x54,0x48,0x40,0x7E,0x02,0x02,0xFA,0x02,0x14,0x08, + 0x20,0x10,0x10,0xFE,0x82,0x04,0x40,0x48,0x50,0x60,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xCDD3 [?] [4187]*/ + 0x00,0x7C,0x44,0x49,0x49,0x52,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x40,0x40, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x08,0x10,0x20,0xC0,0x04,0x04,0x04,0xFC,0x00, + /* 0xCDD4 [?] [4188]*/ + 0x00,0x7C,0x04,0x24,0x24,0x25,0x24,0x3E,0x02,0x02,0x1A,0xE2,0x42,0x02,0x15,0x0A, + 0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xCDD5 [?] [4189]*/ + 0x00,0xF8,0x08,0x49,0x49,0x4A,0x48,0x7C,0x04,0x04,0x1C,0xE4,0x44,0x04,0x28,0x10, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xCDD6 [?] [4190]*/ + 0x20,0x27,0x24,0x25,0xFD,0x26,0x25,0x74,0x6C,0xA4,0xA6,0x25,0x24,0x24,0x24,0x24, + 0x10,0x90,0x90,0x7E,0x20,0x20,0x7C,0xA4,0xA4,0xBC,0xA4,0x3C,0x24,0x24,0x24,0x2C, + /* 0xCDD7 [?] [4191]*/ + 0x00,0x7F,0x02,0x21,0x11,0x10,0x02,0x02,0xFF,0x04,0x08,0x1E,0x01,0x06,0x18,0x60, + 0xFC,0x00,0x08,0x08,0x10,0x20,0x00,0x00,0xFE,0x20,0x20,0x40,0x80,0x60,0x18,0x04, + /* 0xCDD8 [?] [4192]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x10,0x14,0x19,0x32,0xD4,0x10,0x10,0x10,0x50,0x20, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xCDD9 [?] [4193]*/ + 0x00,0x00,0xF3,0x90,0x90,0x97,0x92,0x92,0x97,0x92,0xF2,0x97,0x00,0x00,0x07,0x00, + 0x10,0x78,0xC0,0x40,0x40,0xFC,0x48,0x48,0xFE,0x48,0x48,0xFC,0x40,0x40,0xFC,0x00, + /* 0xCDDA [?] [4194]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x12,0x14,0x18,0x30,0xD0,0x10,0x11,0x11,0x50,0x20, + 0x40,0x20,0xFE,0x02,0x88,0x04,0x02,0xF8,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xCDDB [?] [4195]*/ + 0x00,0x00,0x79,0x48,0x48,0x48,0x4B,0x48,0x48,0x48,0x79,0x48,0x00,0x00,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xCDDC [?] [4196]*/ + 0x10,0x10,0x11,0x7C,0x54,0x54,0x57,0x54,0x7C,0x50,0x11,0x14,0x1C,0xE4,0x43,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xCDDD [?] [4197]*/ + 0x00,0x20,0x13,0x10,0x80,0x40,0x47,0x10,0x10,0x20,0xE3,0x20,0x20,0x20,0x27,0x00, + 0x40,0x40,0xF8,0x40,0x40,0x40,0xFC,0x00,0x40,0x40,0xF8,0x40,0x40,0x40,0xFC,0x00, + /* 0xCDDE [?] [4198]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x27,0x24,0x24,0x48,0x29,0x10,0x28,0x44,0x83,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xCDDF [?] [4199]*/ + 0x00,0xFF,0x04,0x04,0x04,0x07,0x08,0x0A,0x09,0x09,0x08,0x10,0x13,0x1C,0x10,0x00, + 0x00,0xFE,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xCDE0 [?] [4200]*/ + 0x20,0x10,0x00,0xFD,0x08,0x10,0x10,0x35,0x58,0x94,0x14,0x11,0x11,0x12,0x10,0x10, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xCDE1 [?] [4201]*/ + 0x00,0x7F,0x01,0x03,0x05,0x19,0x61,0x00,0x7F,0x01,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x60,0x18,0x04,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xCDE2 [?] [4202]*/ + 0x10,0x10,0x10,0x10,0x3E,0x22,0x42,0x42,0xA4,0x14,0x08,0x08,0x10,0x20,0x40,0x80, + 0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xCDE3 [?] [4203]*/ + 0x00,0xFC,0x03,0x02,0x7D,0x49,0x49,0x4A,0x7A,0x03,0x8C,0x48,0x51,0x19,0xE2,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xCDE4 [?] [4204]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x44,0x00,0x3F,0x00,0x3F,0x20,0x3F,0x00,0x00,0x00, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x50,0x20, + /* 0xCDE5 [?] [4205]*/ + 0x01,0x20,0x1F,0x11,0x85,0x49,0x40,0x17,0x10,0x27,0xE4,0x27,0x20,0x20,0x20,0x00, + 0x00,0x80,0xFC,0x20,0x28,0x24,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xCDE6 [?] [4206]*/ + 0x00,0x00,0xFD,0x10,0x10,0x10,0x13,0x7C,0x10,0x10,0x10,0x10,0x1D,0xE1,0x42,0x04, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xCDE7 [?] [4207]*/ + 0x00,0x7C,0x00,0x00,0x00,0xFE,0x28,0x28,0x28,0x28,0x28,0x2A,0x4C,0x48,0x80,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xCDE8 [?] [4208]*/ + 0x02,0x02,0x02,0x02,0x7F,0x02,0x12,0x0A,0x04,0x04,0x0A,0x09,0x11,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xCDE9 [?] [4209]*/ + 0x10,0x10,0x13,0x16,0x5C,0x51,0x50,0x90,0x13,0x10,0x10,0x28,0x25,0x41,0x42,0x84, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xCDEA [?] [4210]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x00,0x00,0x7F,0x04,0x04,0x04,0x08,0x08,0x10,0x60, + 0x00,0x00,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x40,0x40,0x40,0x44,0x44,0x44,0x3C, + /* 0xCDEB [?] [4211]*/ + 0x00,0x00,0xFB,0x22,0x25,0x41,0x79,0x4A,0xCA,0x4B,0x4C,0x48,0x79,0x49,0x02,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xCDEC [?] [4212]*/ + 0x10,0x10,0x11,0x12,0xFC,0x13,0x12,0x16,0x1A,0x33,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x44,0x44,0x44,0xFC,0xA0,0xA0,0x22,0x22,0x1E,0x00, + /* 0xCDED [?] [4213]*/ + 0x00,0x00,0x79,0x4A,0x4C,0x4B,0x4A,0x7A,0x4A,0x4B,0x48,0x48,0x79,0x49,0x02,0x04, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x44,0x44,0x44,0xFC,0xA0,0xA0,0x22,0x22,0x1E,0x00, + /* 0xCDEE [?] [4214]*/ + 0x10,0x10,0x23,0x7A,0x4C,0x49,0x48,0x48,0x7B,0x48,0x48,0x48,0x49,0x79,0x4A,0x04, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xCDEF [?] [4215]*/ + 0x10,0x10,0x13,0x12,0x1D,0x55,0x51,0x52,0x92,0x13,0x14,0x10,0x11,0x11,0x12,0x14, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xCDF0 [?] [4216]*/ + 0x02,0x01,0x7F,0x40,0x90,0x1E,0x12,0x22,0x22,0x52,0x8C,0x04,0x08,0x10,0x20,0x40, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x88,0x88,0x88,0xA8,0x90,0x82,0x82,0x82,0x7E,0x00, + /* 0xCDF1 [?] [4217]*/ + 0x20,0x20,0x23,0x22,0xFD,0x49,0x49,0x4A,0x8A,0x4B,0x34,0x10,0x29,0x49,0x82,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xCDF2 [?] [4218]*/ + 0x00,0x00,0xFF,0x04,0x04,0x04,0x07,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xCDF3 [?] [4219]*/ + 0x00,0x78,0x4B,0x4A,0x4D,0x79,0x49,0x4A,0x4A,0x7B,0x4C,0x48,0x49,0x49,0x4A,0x9C, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xCDF4 [?] [4220]*/ + 0x00,0x27,0x10,0x10,0x80,0x40,0x40,0x13,0x10,0x20,0xE0,0x20,0x20,0x20,0x2F,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xCDF5 [?] [4221]*/ + 0x00,0x7F,0x01,0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xCDF6 [?] [4222]*/ + 0x02,0x01,0x01,0x00,0xFF,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x00, + 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xCDF7 [?] [4223]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x30,0x38,0x55,0x50,0x90,0x10,0x10,0x10,0x17,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xCDF8 [?] [4224]*/ + 0x00,0x7F,0x40,0x40,0x42,0x52,0x4A,0x44,0x44,0x4A,0x4A,0x52,0x61,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x14,0x94,0x54,0x24,0x24,0x54,0x54,0x94,0x04,0x04,0x14,0x08, + /* 0xCDF9 [?] [4225]*/ + 0x08,0x08,0x10,0x27,0x48,0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x80,0x40,0x00,0xFC,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xCDFA [?] [4226]*/ + 0x00,0x07,0x78,0x48,0x48,0x48,0x78,0x4B,0x48,0x48,0x48,0x78,0x48,0x00,0x0F,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xCDFB [?] [4227]*/ + 0x10,0x08,0xFF,0x20,0x20,0x26,0x38,0x20,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x94,0x08,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE, + /* 0xCDFC [?] [4228]*/ + 0x02,0x01,0xFF,0x10,0x10,0x10,0x10,0x1F,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xCDFD [?] [4229]*/ + 0x02,0x01,0xFF,0x10,0x10,0x1F,0x02,0x02,0xFF,0x04,0x08,0x1E,0x01,0x06,0x18,0x60, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0xFE,0x20,0x20,0x40,0x80,0x60,0x18,0x04, + /* 0xCDFE [?] [4230]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x3F,0x22,0x22,0x3F,0x24,0x28,0x25,0x42,0x45,0x98, + 0x28,0x24,0x20,0xFE,0x20,0x20,0xE4,0x24,0x24,0xA8,0xA8,0x90,0x12,0x2A,0x46,0x82, + /* 0xCEA1 [?] [4231]*/ + 0x01,0x41,0x7F,0x00,0x7C,0x11,0xFF,0x39,0x55,0x93,0xFC,0x24,0x68,0x10,0x29,0xC6, + 0x00,0x04,0xFC,0x20,0x40,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x5A,0x5E,0x90,0x12,0x0E, + /* 0xCEA2 [?] [4232]*/ + 0x11,0x15,0x25,0x45,0x97,0x10,0x20,0x6F,0xA0,0x27,0x24,0x24,0x24,0x24,0x28,0x30, + 0x08,0x48,0x48,0x50,0xDE,0x24,0x14,0xD4,0x14,0x94,0x94,0xA8,0xC8,0x94,0x14,0x22, + /* 0xCEA3 [?] [4233]*/ + 0x04,0x04,0x0F,0x10,0x20,0x5F,0x10,0x13,0x12,0x12,0x12,0x12,0x22,0x22,0x41,0x80, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x00,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xCEA4 [?] [4234]*/ + 0x01,0x01,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0x7F,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0xFC,0x04,0x04,0x04,0x28,0x10,0x00, + /* 0xCEA5 [?] [4235]*/ + 0x00,0x40,0x2F,0x20,0x00,0x07,0xE0,0x20,0x2F,0x20,0x20,0x20,0x20,0x50,0x8F,0x00, + 0x80,0x80,0xFC,0x80,0x80,0xF8,0x80,0x80,0xFC,0x84,0x84,0x94,0x88,0x80,0xFE,0x00, + /* 0xCEA6 [?] [4236]*/ + 0x10,0x10,0x10,0x11,0xFE,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14, + 0x40,0x40,0xFC,0x04,0x08,0xFE,0x00,0x7C,0x44,0x44,0x54,0x48,0x42,0x42,0x3E,0x00, + /* 0xCEA7 [?] [4237]*/ + 0x00,0x7F,0x41,0x41,0x5F,0x41,0x4F,0x41,0x5F,0x41,0x41,0x41,0x41,0x41,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0xE4,0x04,0xF4,0x14,0x14,0x54,0x24,0x04,0xFC,0x04, + /* 0xCEA8 [?] [4238]*/ + 0x00,0x00,0x78,0x49,0x49,0x4B,0x4D,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xCEA9 [?] [4239]*/ + 0x10,0x10,0x10,0x11,0x19,0x57,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xCEAA [?] [4240]*/ + 0x01,0x21,0x11,0x11,0x01,0x7F,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x08,0x50,0x20, + /* 0xCEAB [?] [4241]*/ + 0x04,0x84,0x44,0x08,0x8B,0x5E,0x44,0x04,0x28,0x5E,0xC8,0x40,0x46,0x58,0x40,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xCEAC [?] [4242]*/ + 0x10,0x10,0x20,0x25,0x45,0xFB,0x15,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xCEAD [?] [4243]*/ + 0x08,0x08,0xFF,0x09,0x01,0x7F,0x01,0x01,0x1F,0x01,0x01,0x7F,0x01,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0x00,0xF0,0x00,0x00,0xFC,0x04,0x04,0x14,0x08, + /* 0xCEAE [?] [4244]*/ + 0x08,0xFF,0x08,0x00,0x1F,0x01,0x7F,0x05,0x19,0xE1,0x04,0x7F,0x08,0x1C,0x03,0x7C, + 0x20,0xFE,0x20,0x70,0x80,0x00,0xFC,0x40,0x30,0x0E,0x00,0xFC,0x20,0x40,0x80,0x78, + /* 0xCEAF [?] [4245]*/ + 0x00,0x1F,0x01,0x01,0xFF,0x05,0x09,0x31,0xC2,0x02,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x70,0x80,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xCEB0 [?] [4246]*/ + 0x08,0x08,0x08,0x17,0x10,0x30,0x33,0x50,0x90,0x17,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x40,0x40,0xFE,0x42,0x42,0x4A,0x44,0x40,0x40, + /* 0xCEB1 [?] [4247]*/ + 0x08,0x0A,0x09,0x11,0x10,0x37,0x30,0x50,0x90,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x40,0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x84,0xA4,0x94,0x14,0x04,0x04,0x28,0x10, + /* 0xCEB2 [?] [4248]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x21,0x21,0x2F,0x21,0x21,0x5F,0x41,0x80, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF8,0x02,0x02,0xFE, + /* 0xCEB3 [?] [4249]*/ + 0x10,0x10,0x20,0x25,0x44,0xF8,0x10,0x20,0x40,0xFD,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xCEB4 [?] [4250]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x03,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xCEB5 [?] [4251]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x21,0x3F,0x20,0x2E,0x20,0x3F,0x44,0x55,0xA4,0x0C, + 0x20,0x20,0xFE,0x20,0x00,0x08,0x08,0x08,0xFE,0x08,0x48,0x28,0x28,0x08,0xA8,0x10, + /* 0xCEB6 [?] [4252]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x4F,0x48,0x49,0x79,0x4A,0x04,0x08,0x00,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40, + /* 0xCEB7 [?] [4253]*/ + 0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00,0xFF,0x11,0x10,0x10,0x14,0x18,0x10, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0xFE,0x10,0xA0,0x40,0x30,0x0E,0x00, + /* 0xCEB8 [?] [4254]*/ + 0x00,0x3F,0x21,0x3F,0x21,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xCEB9 [?] [4255]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x4A,0x4A,0x4B,0x48,0x4F,0x7A,0x4A,0x02,0x02,0x03,0x02, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x00,0xFE,0x40,0x44,0x28,0x90,0x08,0x06, + /* 0xCEBA [?] [4256]*/ + 0x0C,0x70,0x11,0xFF,0x39,0x55,0x93,0x01,0x11,0xFC,0x24,0x44,0x28,0x11,0x29,0xC6, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x40,0x68,0xB2,0xBE,0x20,0x22,0x1E, + /* 0xCEBB [?] [4257]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x52,0x92,0x11,0x11,0x11,0x11,0x10,0x1F,0x10, + 0x80,0x40,0x40,0x00,0xFC,0x00,0x08,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0xFE,0x00, + /* 0xCEBC [?] [4258]*/ + 0x00,0x27,0x14,0x17,0x84,0x47,0x40,0x13,0x12,0x23,0xE2,0x23,0x22,0x22,0x22,0x02, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xCEBD [?] [4259]*/ + 0x00,0x47,0x24,0x27,0x04,0x07,0xE0,0x23,0x22,0x23,0x22,0x23,0x2A,0x32,0x22,0x02, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xCEBE [?] [4260]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x2F,0x20,0x20,0x3F,0x22,0x2A,0x4A,0x52,0x8A,0x04, + 0x04,0x84,0x84,0x84,0xBE,0x04,0x84,0x24,0x14,0xD4,0x04,0x84,0x44,0x44,0x14,0x08, + /* 0xCEBF [?] [4261]*/ + 0x3F,0x21,0x3F,0x20,0x2F,0x20,0x5F,0x44,0x95,0x2C,0x01,0x08,0x48,0x48,0x87,0x00, + 0x08,0x08,0x7E,0x08,0x48,0x28,0xA8,0x08,0x28,0x90,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCEC0 [?] [4262]*/ + 0x00,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFF,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xCEC1 [?] [4263]*/ + 0x01,0x00,0x3F,0x20,0x27,0xA4,0x67,0x24,0x27,0x60,0xAF,0x29,0x29,0x49,0x7F,0x80, + 0x00,0x80,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x24,0x24,0x24,0xFE,0x00, + /* 0xCEC2 [?] [4264]*/ + 0x00,0x23,0x12,0x12,0x83,0x42,0x42,0x13,0x10,0x27,0xE4,0x24,0x24,0x24,0x2F,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xA4,0xA4,0xFE,0x00, + /* 0xCEC3 [?] [4265]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x01, + 0x40,0x20,0x20,0xFE,0x88,0x88,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x06, + /* 0xCEC4 [?] [4266]*/ + 0x02,0x01,0x01,0xFF,0x10,0x10,0x08,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xCEC5 [?] [4267]*/ + 0x20,0x17,0x00,0x40,0x5F,0x44,0x47,0x44,0x47,0x44,0x44,0x5F,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x44,0xC4,0x44,0xC4,0x44,0x74,0xC4,0x44,0x44,0x54,0x08, + /* 0xCEC6 [?] [4268]*/ + 0x10,0x10,0x20,0x27,0x49,0xF1,0x11,0x21,0x41,0xF8,0x40,0x00,0x18,0xE1,0x42,0x0C, + 0x80,0x40,0x40,0xFC,0x10,0x10,0x10,0x10,0x10,0xA0,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xCEC7 [?] [4269]*/ + 0x01,0x01,0x79,0x49,0x4A,0x4C,0x48,0x49,0x49,0x4A,0x7C,0x48,0x01,0x02,0x04,0x00, + 0x00,0x00,0x00,0xFC,0xA4,0xA4,0xA4,0x24,0x24,0x44,0x44,0x84,0x04,0x04,0x28,0x10, + /* 0xCEC8 [?] [4270]*/ + 0x08,0x1C,0xF1,0x12,0x11,0xFC,0x10,0x39,0x34,0x54,0x51,0x90,0x10,0x12,0x12,0x14, + 0x40,0xF8,0x08,0x10,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x40,0x24,0xA2,0x8A,0x78, + /* 0xCEC9 [?] [4271]*/ + 0x02,0x01,0x7F,0x08,0x07,0x18,0xE2,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0x00,0xFC,0x20,0xC0,0x30,0x0E,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xCECA [?] [4272]*/ + 0x20,0x17,0x00,0x40,0x40,0x47,0x44,0x44,0x44,0x44,0x44,0x47,0x44,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xC4,0x44,0x44,0x44,0x44,0x44,0xC4,0x44,0x04,0x14,0x08, + /* 0xCECB [?] [4273]*/ + 0x00,0x00,0x79,0x4A,0x4C,0x49,0x48,0x48,0x4B,0x48,0x7A,0x49,0x02,0x00,0x01,0x00, + 0x90,0x88,0x04,0x42,0x88,0xFC,0x04,0x00,0xDE,0x42,0x52,0x4A,0x52,0x42,0x4A,0x84, + /* 0xCECC [?] [4274]*/ + 0x04,0x08,0x12,0x24,0xC8,0x1F,0x00,0x00,0x7E,0x22,0x12,0x0A,0x12,0x22,0x4A,0x04, + 0x40,0x20,0x10,0x08,0x26,0xF0,0x10,0x00,0xFC,0x44,0x24,0x14,0x24,0x44,0x94,0x08, + /* 0xCECD [?] [4275]*/ + 0x04,0x08,0x10,0x22,0xC4,0x08,0x1F,0x00,0x00,0x7F,0x08,0x0F,0x09,0x10,0x16,0x18, + 0x40,0x20,0x10,0x08,0x46,0x20,0xF0,0x00,0x00,0xFC,0x00,0xE0,0x20,0xA4,0x24,0x1C, + /* 0xCECE [?] [4276]*/ + 0x24,0x22,0x22,0x20,0xF8,0x2E,0x22,0x2A,0x32,0xE2,0x22,0x22,0x22,0x25,0xA8,0x40, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x48,0x28,0x28,0x08,0x08,0x28,0x10,0x00,0xFE,0x00, + /* 0xCECF [?] [4277]*/ + 0x20,0x21,0x21,0xF9,0xA9,0xA9,0xA8,0xA8,0xFB,0xA2,0x22,0x2A,0x3B,0xEA,0x42,0x02, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xCED0 [?] [4278]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x40,0x10,0x17,0x24,0xE4,0x25,0x26,0x24,0x24,0x04, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x40,0x40,0xFC,0x44,0xA4,0x14,0x14,0x04,0x14,0x08, + /* 0xCED1 [?] [4279]*/ + 0x02,0x01,0x7F,0x48,0x90,0x2F,0x08,0x08,0x0F,0x01,0x3F,0x21,0x22,0x24,0x20,0x20, + 0x00,0x00,0xFE,0x22,0x14,0xE8,0x20,0x20,0xE0,0x00,0xF8,0x08,0x88,0x48,0x08,0x18, + /* 0xCED2 [?] [4280]*/ + 0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x08,0x0A,0x0C,0x18,0x68,0x08,0x08,0x2B,0x10, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x40,0x44,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xCED3 [?] [4281]*/ + 0x10,0x10,0x10,0xFE,0x11,0x7C,0x44,0x7C,0x45,0x7C,0x10,0xFE,0x10,0x10,0x10,0x10, + 0x20,0x20,0x50,0x88,0x04,0x12,0x90,0x50,0x10,0x90,0x1E,0xF0,0x10,0x10,0x10,0x10, + /* 0xCED4 [?] [4282]*/ + 0x00,0x7F,0x48,0x48,0x48,0x7F,0x41,0x41,0x41,0x7F,0x48,0x48,0x48,0x7F,0x00,0x00, + 0x20,0xA0,0x20,0x20,0x20,0x30,0x28,0x24,0x22,0x22,0x20,0x20,0x20,0xA0,0x20,0x20, + /* 0xCED5 [?] [4283]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x23,0x2A,0x32,0xE3,0x22,0x22,0x25,0x24,0xA8,0x53, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x40,0x88,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE, + /* 0xCED6 [?] [4284]*/ + 0x00,0x20,0x17,0x10,0x80,0x40,0x40,0x17,0x10,0x20,0xE0,0x21,0x21,0x22,0x24,0x08, + 0x10,0x78,0xC0,0x40,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xCED7 [?] [4285]*/ + 0x00,0x00,0x7F,0x01,0x01,0x11,0x11,0x11,0x29,0x29,0x45,0x85,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x10,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0x00,0xFE,0x00, + /* 0xCED8 [?] [4286]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x78,0x48,0x03,0x00,0x00,0x00, + 0x20,0x40,0xFC,0x04,0x04,0x04,0x14,0x08,0x00,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xCED9 [?] [4287]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x15,0x18,0x10,0x00, + 0x20,0x40,0xFC,0x84,0x84,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xCEDA [?] [4288]*/ + 0x01,0x02,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x7F,0x00,0x00,0x00, + 0x00,0x00,0xF0,0x10,0x10,0x10,0x50,0x20,0x00,0xFC,0x04,0x04,0xE4,0x04,0x28,0x10, + /* 0xCEDB [?] [4289]*/ + 0x00,0x23,0x10,0x10,0x80,0x47,0x40,0x10,0x11,0x21,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0xF8,0x00,0x00,0x00,0xFE,0x80,0x80,0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xCEDC [?] [4290]*/ + 0x00,0x47,0x20,0x20,0x02,0x02,0xE2,0x25,0x24,0x28,0x20,0x28,0x30,0x20,0x0F,0x00, + 0x00,0xFC,0x40,0x40,0x48,0x48,0x48,0x54,0xD2,0x62,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xCEDD [?] [4291]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x2F,0x21,0x22,0x27,0x20,0x20,0x2F,0x40,0x40,0xBF, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x00,0x10,0xF8,0x88,0x80,0xFC,0x80,0x80,0xFE, + /* 0xCEDE [?] [4292]*/ + 0x00,0x3F,0x02,0x02,0x02,0x02,0x7F,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x00,0xF0,0x00,0x00,0x00,0x00,0xFC,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x7C,0x00, + /* 0xCEDF [?] [4293]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x02,0x02,0x7F,0x02,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x00,0x00,0xFC,0x80,0x80,0x80,0x84,0x84,0x7C,0x00, + /* 0xCEE0 [?] [4294]*/ + 0x10,0x13,0x10,0x10,0xFD,0x10,0x30,0x3B,0x54,0x50,0x91,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCEE1 [?] [4295]*/ + 0x00,0x7F,0x02,0x02,0x3F,0x04,0x04,0x08,0xFF,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0xFE,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xCEE2 [?] [4296]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x00,0x00,0x3F,0x01,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xCEE3 [?] [4297]*/ + 0x00,0x1F,0x11,0x11,0x11,0x11,0xFF,0x21,0x22,0x22,0x22,0x3F,0x04,0x08,0x10,0x20, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0xA0,0x40, + /* 0xCEE4 [?] [4298]*/ + 0x00,0x00,0x3F,0x00,0x00,0xFF,0x00,0x04,0x04,0x27,0x24,0x24,0x24,0x27,0xF8,0x40, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x40,0x40,0x40,0x40,0x20,0x22,0x12,0x8A,0x06,0x02, + /* 0xCEE5 [?] [4299]*/ + 0x00,0x7F,0x02,0x02,0x02,0x02,0x3F,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xCEE6 [?] [4300]*/ + 0x10,0x13,0x10,0x10,0xFD,0x10,0x10,0x17,0x18,0x30,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCEE7 [?] [4301]*/ + 0x08,0x08,0x08,0x1F,0x11,0x21,0x41,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xCEE8 [?] [4302]*/ + 0x10,0x3F,0x4A,0x0A,0x7F,0x0A,0x0A,0x7F,0x10,0x10,0x3E,0x42,0x14,0x08,0x30,0xC0, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA0,0xA0,0xFC,0x10,0x10,0xFC,0x10,0x90,0xFE,0x10,0x10, + /* 0xCEE9 [?] [4303]*/ + 0x08,0x0B,0x08,0x10,0x10,0x30,0x33,0x50,0x90,0x10,0x10,0x11,0x11,0x11,0x17,0x10, + 0x00,0xFC,0x40,0x40,0x40,0x40,0xF8,0x88,0x88,0x88,0x88,0x08,0x08,0x08,0xFE,0x00, + /* 0xCEEA [?] [4304]*/ + 0x09,0x09,0x09,0x12,0x15,0x31,0x31,0x51,0x97,0x11,0x12,0x12,0x13,0x10,0x10,0x10, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0x48,0x28,0xFE,0x08,0x48,0x28,0xFC,0x08,0x50,0x20, + /* 0xCEEB [?] [4305]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x10,0x1C,0xE3,0x40,0x00,0x00, + 0x20,0x40,0xFC,0x04,0x04,0x04,0x14,0x08,0x00,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xCEEC [?] [4306]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x43,0x8C, + 0x90,0x88,0x80,0xFE,0x80,0x80,0x84,0x44,0x48,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xCEED [?] [4307]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x04,0x0F,0x14,0x03,0x1C,0xE2,0x0F,0x04,0x18, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xE0,0x40,0x80,0x70,0x0E,0xE0,0x20,0x60, + /* 0xCEEE [?] [4308]*/ + 0x00,0x03,0x78,0x48,0x49,0x48,0x48,0x7B,0x48,0x48,0x49,0x49,0x79,0x49,0x01,0x01, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCEEF [?] [4309]*/ + 0x10,0x10,0x50,0x50,0x7D,0x52,0x90,0x10,0x1C,0xF1,0x52,0x10,0x10,0x10,0x11,0x10, + 0x80,0x80,0x80,0xFC,0x54,0x54,0x54,0x94,0x94,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xCEF0 [?] [4310]*/ + 0x08,0x08,0x08,0x1F,0x12,0x22,0x42,0x84,0x04,0x08,0x10,0x21,0x42,0x04,0x08,0x10, + 0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x04,0x04,0x04,0x28,0x10, + /* 0xCEF1 [?] [4311]*/ + 0x04,0x04,0x0F,0x18,0x24,0x03,0x0C,0x32,0xC2,0x1F,0x02,0x04,0x04,0x08,0x10,0x20, + 0x00,0x00,0xF0,0x20,0xC0,0x00,0xC0,0x30,0x0E,0xF0,0x10,0x10,0x10,0x10,0xA0,0x40, + /* 0xCEF2 [?] [4312]*/ + 0x10,0x13,0x10,0x10,0x19,0x54,0x50,0x53,0x90,0x10,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xCEF3 [?] [4313]*/ + 0x00,0x43,0x22,0x22,0x03,0x00,0xE0,0x27,0x20,0x20,0x2F,0x20,0x28,0x31,0x22,0x0C, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xCEF4 [?] [4314]*/ + 0x04,0x04,0x3F,0x04,0x04,0xFF,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x40,0x40,0xF8,0x40,0x40,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xCEF5 [?] [4315]*/ + 0x00,0x7F,0x44,0x44,0x5F,0x51,0x51,0x5F,0x44,0x44,0x7F,0x00,0x24,0x22,0x42,0x80, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x40,0x40,0x42,0x42,0xBE,0x00,0x88,0x44,0x44,0x04, + /* 0xCEF6 [?] [4316]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xCEF7 [?] [4317]*/ + 0x00,0xFF,0x04,0x04,0x04,0x3F,0x24,0x24,0x24,0x24,0x28,0x30,0x20,0x20,0x3F,0x20, + 0x00,0xFE,0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0x38,0x08,0x08,0x08,0xF8,0x08, + /* 0xCEF8 [?] [4318]*/ + 0x00,0x03,0xFC,0x10,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x00,0xFE,0x50,0x50,0xFC,0x54,0x54,0x54,0x54,0x54,0x8C,0x04,0x04,0x04,0xFC,0x04, + /* 0xCEF9 [?] [4319]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3D,0x66,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x03, + 0x40,0x40,0x40,0x7E,0x82,0x82,0x42,0x24,0x14,0x08,0x08,0x10,0x20,0x40,0x80,0x00, + /* 0xCEFA [?] [4320]*/ + 0x02,0x02,0xF2,0x92,0x9F,0x92,0x92,0xF6,0x97,0x9A,0x9A,0x92,0xF2,0x92,0x02,0x02, + 0x00,0x0C,0x70,0x40,0x40,0x40,0x7E,0x48,0x48,0xC8,0x48,0x48,0x48,0x48,0x48,0x88, + /* 0xCEFB [?] [4321]*/ + 0x00,0x07,0xF0,0x93,0x90,0x93,0x92,0x93,0x91,0x9F,0xF0,0x93,0x02,0x02,0x03,0x02, + 0x40,0xFC,0x40,0xF8,0x00,0xF8,0x08,0xF8,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCEFC [?] [4322]*/ + 0x00,0x07,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x4A,0x7A,0x4A,0x04,0x04,0x08,0x03, + 0x00,0xF8,0x08,0x10,0x10,0x20,0x3C,0x04,0x04,0x88,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xCEFD [?] [4323]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFC,0x11,0x12,0x10,0x15,0x1A,0x10,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x80,0xFC,0x54,0x94,0x24,0x44,0x94,0x08, + /* 0xCEFE [?] [4324]*/ + 0x10,0x17,0x50,0x50,0x7C,0x53,0x92,0x12,0x1E,0xF2,0x52,0x13,0x12,0x12,0x13,0x12, + 0x00,0xFE,0x90,0x90,0x90,0xFC,0x94,0x94,0x94,0x94,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xCFA1 [?] [4325]*/ + 0x09,0x1C,0xF0,0x10,0x13,0xFC,0x13,0x38,0x35,0x53,0x55,0x91,0x11,0x11,0x10,0x10, + 0x84,0x68,0x30,0xC8,0x04,0x40,0xFE,0xA0,0x20,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCFA2 [?] [4326]*/ + 0x01,0x02,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCFA3 [?] [4327]*/ + 0x18,0x06,0x01,0x06,0x3A,0x02,0xFF,0x04,0x08,0x1F,0x28,0x48,0x88,0x08,0x00,0x00, + 0x18,0x60,0x80,0x60,0x18,0x00,0xFE,0x80,0x80,0xF8,0x88,0x88,0xA8,0x90,0x80,0x80, + /* 0xCFA4 [?] [4328]*/ + 0x00,0x3F,0x11,0x09,0x01,0xFF,0x09,0x11,0x21,0xC0,0x01,0x08,0x48,0x48,0x87,0x00, + 0xF8,0x00,0x10,0x20,0x00,0xFE,0x20,0x10,0x08,0x06,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCFA5 [?] [4329]*/ + 0x00,0x78,0x4B,0x48,0x48,0x7B,0x48,0x48,0x49,0x7A,0x49,0x48,0x49,0x4A,0x48,0x98, + 0x20,0x20,0xFE,0x70,0xAC,0x22,0x50,0x88,0x24,0x22,0x24,0xA8,0x24,0x22,0xA0,0x40, + /* 0xCFA6 [?] [4330]*/ + 0x02,0x02,0x02,0x02,0x07,0x04,0x08,0x10,0x24,0x42,0x01,0x00,0x01,0x02,0x0C,0x70, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x10,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xCFA7 [?] [4331]*/ + 0x10,0x10,0x10,0x13,0x18,0x54,0x57,0x50,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x88,0x88,0x88,0xFE,0x88,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xCFA8 [?] [4332]*/ + 0x10,0x10,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x10,0x10,0x28,0x26,0x42,0x44,0x80, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xA4,0x8A,0x8A,0x78,0x00, + /* 0xCFA9 [?] [4333]*/ + 0x11,0x10,0x10,0x14,0x5B,0x50,0x53,0x90,0x11,0x13,0x15,0x29,0x25,0x41,0x40,0x80, + 0x84,0x68,0x30,0xC8,0x04,0x40,0xFE,0xA0,0x20,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xCFAA [?] [4334]*/ + 0x00,0x27,0x12,0x11,0x80,0x41,0x43,0x10,0x11,0x23,0xE0,0x20,0x27,0x20,0x21,0x06, + 0x3C,0xC0,0x44,0x28,0x80,0x10,0xE0,0x40,0x88,0xFC,0x44,0x40,0xFC,0xA0,0x10,0x0E, + /* 0xCFAB [?] [4335]*/ + 0x00,0x20,0x10,0x10,0x81,0x41,0x42,0x14,0x10,0x20,0xE0,0x20,0x20,0x20,0x21,0x06, + 0x80,0x80,0x80,0xFC,0x04,0x04,0x84,0x48,0x28,0x10,0x10,0x20,0x40,0x80,0x00,0x00, + /* 0xCFAC [?] [4336]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x28,0x26,0x28,0x24,0x27,0x28,0x20,0x5F,0x40,0x80,0x00, + 0x00,0xFC,0x04,0xFC,0x00,0x88,0xB0,0x8C,0x80,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80, + /* 0xCFAD [?] [4337]*/ + 0x21,0x22,0x27,0x24,0xFF,0x24,0x27,0x72,0x69,0xA7,0xA2,0x23,0x22,0x24,0x25,0x28, + 0x08,0x08,0xC8,0x50,0xDE,0x64,0xD4,0x14,0x14,0xD4,0x14,0xC8,0x48,0x54,0x54,0xA2, + /* 0xCFAE [?] [4338]*/ + 0x04,0x04,0xFF,0x09,0x11,0x21,0x4F,0x82,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x40,0x20,0xFE,0x10,0x60,0x84,0x04,0xFC,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xCFAF [?] [4339]*/ + 0x01,0x00,0x3F,0x22,0x22,0x3F,0x22,0x22,0x23,0x20,0x2F,0x28,0x48,0x48,0x88,0x00, + 0x00,0x80,0xFE,0x20,0x20,0xFC,0x20,0x20,0xE0,0x80,0xF8,0x88,0x88,0xA8,0x90,0x80, + /* 0xCFB0 [?] [4340]*/ + 0x00,0x7F,0x00,0x00,0x08,0x04,0x02,0x02,0x00,0x01,0x0E,0x70,0x20,0x00,0x00,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x68,0x88,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xCFB1 [?] [4341]*/ + 0x20,0x20,0x21,0x21,0xF9,0x49,0x49,0x49,0x89,0x48,0x30,0x10,0x2A,0x4A,0x84,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xA4,0x8A,0x8A,0x78,0x00, + /* 0xCFB2 [?] [4342]*/ + 0x01,0x7F,0x01,0x3F,0x00,0x3F,0x20,0x3F,0x08,0xFF,0x00,0x3F,0x20,0x20,0x3F,0x20, + 0x00,0xFC,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x20,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xCFB3 [?] [4343]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBE,0x10,0x13,0xFC,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x90,0x90,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xCFB4 [?] [4344]*/ + 0x00,0x22,0x12,0x13,0x84,0x48,0x40,0x17,0x11,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xCFB5 [?] [4345]*/ + 0x00,0x3F,0x04,0x08,0x10,0x3F,0x01,0x06,0x18,0x7F,0x01,0x09,0x11,0x21,0x45,0x02, + 0xF8,0x00,0x00,0x20,0x40,0x80,0x00,0x10,0x08,0xFC,0x04,0x20,0x10,0x08,0x04,0x00, + /* 0xCFB6 [?] [4346]*/ + 0x00,0x7C,0x45,0x4A,0x48,0x51,0x49,0x49,0x45,0x45,0x44,0x68,0x51,0x42,0x40,0x40, + 0x20,0xA8,0x24,0x22,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xCFB7 [?] [4347]*/ + 0x00,0x00,0x00,0x7E,0x02,0x02,0x25,0x14,0x08,0x08,0x14,0x12,0x22,0x40,0x00,0x01, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xCFB8 [?] [4348]*/ + 0x10,0x10,0x21,0x25,0x45,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x00,0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xCFB9 [?] [4349]*/ + 0x00,0x00,0x7B,0x4A,0x4C,0x79,0x48,0x49,0x78,0x4B,0x48,0x49,0x79,0x49,0x01,0x01, + 0x40,0x20,0xFE,0x02,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x20,0xFC,0x04,0x04,0xFC,0x04, + /* 0xCFBA [?] [4350]*/ + 0x10,0x13,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x00,0xFE,0x40,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xCFBB [?] [4351]*/ + 0x00,0x7F,0x40,0x40,0x4F,0x48,0x48,0x4F,0x48,0x48,0x4F,0x48,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x00,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0x88,0x80,0x80,0xFE,0x00, + /* 0xCFBC [?] [4352]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3E,0x22,0x3E,0x20,0x3E,0x20,0x3E,0x20, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x08,0xF8,0x00,0xF8,0x48,0x30,0xCC, + /* 0xCFBD [?] [4353]*/ + 0x20,0x20,0x23,0xFE,0x44,0x51,0x90,0xFD,0x10,0x13,0x1C,0xF1,0x51,0x11,0x11,0x11, + 0x40,0x20,0xFE,0x02,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x20,0xFC,0x04,0x04,0xFC,0x04, + /* 0xCFBE [?] [4354]*/ + 0x00,0x07,0xF4,0x94,0x94,0x97,0x94,0xF4,0x97,0x94,0x94,0x97,0xF4,0x94,0x04,0x04, + 0x00,0xBC,0x84,0x84,0x84,0xBC,0x00,0x00,0xBC,0x24,0x24,0xA8,0x10,0x28,0x44,0x82, + /* 0xCFBF [?] [4355]*/ + 0x10,0x10,0x10,0x11,0x54,0x55,0x54,0x54,0x54,0x57,0x54,0x5C,0x64,0x00,0x01,0x02, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xCFC0 [?] [4356]*/ + 0x08,0x08,0x08,0x17,0x10,0x32,0x31,0x50,0x9F,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x50,0x40,0xFE,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xCFC1 [?] [4357]*/ + 0x00,0x44,0x28,0x11,0x28,0x49,0x88,0x08,0x18,0x2B,0x48,0x88,0x08,0x08,0x51,0x22, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xCFC2 [?] [4358]*/ + 0x00,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0xFE,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x08,0x00,0x00,0x00,0x00,0x00, + /* 0xCFC3 [?] [4359]*/ + 0x3F,0x20,0x3F,0x21,0x27,0x24,0x27,0x24,0x27,0x24,0x27,0x22,0x47,0x4A,0x81,0x1E, + 0xFE,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xF8,0x08,0xF0,0x0E, + /* 0xCFC4 [?] [4360]*/ + 0x7F,0x02,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x08,0x1F,0x28,0x44,0x03,0x1C,0xE0, + 0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E, + /* 0xCFC5 [?] [4361]*/ + 0x00,0x07,0x78,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x00,0xFE,0x40,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xCFC6 [?] [4362]*/ + 0x20,0x20,0x27,0x24,0xF4,0x24,0x27,0x25,0x35,0xE5,0x25,0x25,0x25,0x29,0xA9,0x50, + 0x10,0x90,0x10,0x3E,0x22,0x44,0x90,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82, + /* 0xCFC7 [?] [4363]*/ + 0x20,0x20,0x3B,0x22,0x42,0x7A,0xA3,0x22,0xFA,0x22,0x22,0x22,0x2A,0x34,0x24,0x08, + 0x10,0x50,0x90,0x1E,0x12,0x24,0xC8,0x88,0x88,0x88,0x88,0x94,0x94,0x94,0x94,0x22, + /* 0xCFC8 [?] [4364]*/ + 0x01,0x11,0x11,0x1F,0x21,0x41,0x01,0xFF,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x40,0x40,0x40,0x40,0x42,0x42,0x3E,0x00, + /* 0xCFC9 [?] [4365]*/ + 0x10,0x10,0x10,0x20,0x24,0x64,0x64,0xA4,0x24,0x24,0x24,0x24,0x24,0x27,0x20,0x20, + 0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFC,0x04,0x00, + /* 0xCFCA [?] [4366]*/ + 0x10,0x10,0x1E,0x22,0x24,0x7E,0xAA,0x2A,0x3E,0x2A,0x2A,0x3E,0x00,0x0E,0x70,0x20, + 0x82,0x44,0x28,0xFE,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xCFCB [?] [4367]*/ + 0x10,0x10,0x21,0x24,0x44,0xF8,0x10,0x23,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xCFCC [?] [4368]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x2F,0x29,0x29,0x2F,0x49,0x40,0x81, + 0x50,0x48,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xCFCD [?] [4369]*/ + 0x04,0x25,0x24,0x24,0x24,0x24,0x27,0x04,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0xF8,0x88,0x50,0x20,0xD8,0x06,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xCFCE [?] [4370]*/ + 0x12,0x12,0x23,0x42,0x84,0x17,0x2A,0x62,0xAF,0x22,0x22,0x22,0x22,0x23,0x22,0x20, + 0x00,0x00,0x9C,0x00,0x00,0x80,0x3E,0x08,0x88,0x08,0x08,0x08,0x88,0x08,0x28,0x10, + /* 0xCFCF [?] [4371]*/ + 0x10,0x20,0x7C,0x45,0x64,0x54,0x54,0xFC,0x45,0x64,0x54,0x54,0x44,0x45,0x54,0x88, + 0x20,0x10,0x10,0xFE,0x20,0x20,0x44,0x84,0xF8,0x10,0x20,0x44,0x82,0xFE,0x82,0x00, + /* 0xCFD0 [?] [4372]*/ + 0x20,0x17,0x00,0x41,0x41,0x41,0x5F,0x41,0x43,0x45,0x49,0x51,0x41,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0xF4,0x04,0x84,0x44,0x24,0x14,0x04,0x04,0x14,0x08, + /* 0xCFD1 [?] [4373]*/ + 0x00,0x20,0x17,0x11,0x81,0x42,0x42,0x17,0x11,0x25,0xE5,0x22,0x22,0x25,0x28,0x10, + 0x08,0x1C,0x70,0x10,0x10,0x50,0x5C,0x50,0x50,0x50,0x50,0x7C,0x00,0x00,0xFE,0x00, + /* 0xCFD2 [?] [4374]*/ + 0x00,0xF8,0x08,0x0B,0x08,0x78,0x40,0x41,0x43,0x78,0x08,0x08,0x09,0x0B,0x51,0x20, + 0x40,0x20,0x20,0xFE,0x40,0x40,0x88,0x08,0xF0,0x20,0x40,0x88,0x04,0xFC,0x04,0x00, + /* 0xCFD3 [?] [4375]*/ + 0x10,0x10,0x10,0x13,0xFC,0x25,0x24,0x27,0x24,0x49,0x28,0x10,0x29,0x46,0x84,0x00, + 0x88,0x50,0x00,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50,0x50, + /* 0xCFD4 [?] [4376]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x04,0x44,0x24,0x14,0x14,0x04,0xFF,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x40,0x44,0x44,0x48,0x50,0x40,0xFE,0x00, + /* 0xCFD5 [?] [4377]*/ + 0x00,0x78,0x48,0x50,0x51,0x62,0x55,0x48,0x48,0x48,0x6A,0x51,0x41,0x40,0x47,0x40, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xCFD6 [?] [4378]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7D,0x11,0x11,0x10,0x10,0x1C,0xE1,0x42,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xCFD7 [?] [4379]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7F,0x41,0x55,0x49,0x5D,0x49,0x7F,0x49,0x49,0x45,0x42, + 0x10,0x14,0x92,0x12,0x10,0x7E,0x10,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82, + /* 0xCFD8 [?] [4380]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0xFF,0x04,0x08,0x10,0x3F,0x10, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0xFE,0x00,0x20,0x10,0xF8,0x08, + /* 0xCFD9 [?] [4381]*/ + 0x00,0x78,0x49,0x49,0x49,0x79,0x49,0x48,0x48,0x7B,0x48,0x49,0x49,0x4A,0x4C,0x98, + 0x40,0x80,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x32,0xB4,0xA8,0x28,0x24,0x24,0xA2,0x40, + /* 0xCFDA [?] [4382]*/ + 0x20,0x20,0x20,0x39,0x4A,0x54,0x80,0x23,0x22,0x22,0x23,0x22,0x2A,0x32,0x23,0x02, + 0x80,0x80,0xF8,0x08,0x10,0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xCFDB [?] [4383]*/ + 0x08,0x04,0x7F,0x01,0x3F,0x01,0xFF,0x40,0x20,0x09,0x12,0x24,0xE0,0x20,0x23,0x2C, + 0x20,0x40,0xFC,0x00,0xF8,0x00,0xFE,0x80,0x80,0xFC,0x04,0x48,0x40,0xA0,0x18,0x06, + /* 0xCFDC [?] [4384]*/ + 0x02,0x01,0x7F,0x40,0x81,0x11,0x1F,0x21,0x01,0xFF,0x04,0x04,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0xFE,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xCFDD [?] [4385]*/ + 0x00,0x78,0x48,0x51,0x52,0x64,0x50,0x4B,0x4A,0x4A,0x6B,0x52,0x42,0x42,0x43,0x42, + 0x80,0x80,0xF8,0x08,0x10,0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xCFDE [?] [4386]*/ + 0x00,0x7B,0x4A,0x52,0x53,0x62,0x52,0x4B,0x4A,0x4A,0x6A,0x52,0x42,0x42,0x43,0x42, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xCFDF [?] [4387]*/ + 0x10,0x10,0x20,0x24,0x45,0xF8,0x10,0x23,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x43,0x00, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xCFE0 [?] [4388]*/ + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08,0x08, + 0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xCFE1 [?] [4389]*/ + 0x00,0x3F,0x22,0x22,0x22,0x2F,0x22,0x26,0x27,0x2A,0x2A,0x32,0x22,0x42,0x42,0x82, + 0x00,0xFE,0x00,0x00,0x7C,0x44,0x44,0x7C,0x44,0xC4,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xCFE2 [?] [4390]*/ + 0x20,0x27,0x38,0x23,0x42,0x7B,0xA1,0x27,0xF9,0x27,0x21,0x27,0x29,0x33,0x25,0x01, + 0x40,0xFC,0x00,0xB8,0xA8,0xB8,0x10,0xFC,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xCFE3 [?] [4391]*/ + 0x00,0x1F,0x01,0x01,0xFF,0x05,0x09,0x31,0xDF,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x70,0x80,0x00,0x00,0xFE,0x40,0x20,0x18,0xF6,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xCFE4 [?] [4392]*/ + 0x10,0x10,0x3F,0x28,0x45,0x88,0x08,0x7E,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC, + /* 0xCFE5 [?] [4393]*/ + 0x01,0xFF,0x00,0x3E,0x22,0x3E,0x04,0x7F,0x04,0x3F,0x04,0xFF,0x04,0x1C,0xE5,0x06, + 0x00,0xFE,0x00,0xF8,0x88,0xF8,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x44,0x28,0x18,0x06, + /* 0xCFE6 [?] [4394]*/ + 0x02,0x42,0x22,0x22,0x0F,0x82,0x42,0x57,0x16,0x2A,0xF2,0x22,0x22,0x22,0x22,0x02, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0xC4,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xCFE7 [?] [4395]*/ + 0x02,0x02,0x04,0x08,0x10,0x3F,0x01,0x02,0x04,0x1F,0x00,0x00,0x01,0x06,0x18,0xE0, + 0x00,0x00,0x20,0x20,0x40,0x80,0x08,0x08,0x10,0xE0,0x40,0x80,0x00,0x00,0x00,0x00, + /* 0xCFE8 [?] [4396]*/ + 0x44,0x25,0x28,0xFE,0x11,0x10,0x7C,0x10,0x10,0xFE,0x11,0x10,0x20,0x20,0x41,0x80, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0x44,0x4C,0xD4,0x64,0x44,0x44,0x44,0x54,0x88, + /* 0xCFE9 [?] [4397]*/ + 0x21,0x10,0x10,0xF8,0x0B,0x10,0x10,0x39,0x54,0x90,0x13,0x10,0x10,0x10,0x10,0x10, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xCFEA [?] [4398]*/ + 0x02,0x21,0x11,0x10,0x07,0x00,0xF0,0x13,0x10,0x10,0x17,0x10,0x14,0x18,0x10,0x00, + 0x08,0x08,0x10,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xCFEB [?] [4399]*/ + 0x08,0x08,0x08,0x7E,0x08,0x18,0x1C,0x2A,0x48,0x08,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xF8,0x88,0x88,0xF8,0x88,0xF8,0x88,0x88,0xF8,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xCFEC [?] [4400]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x02,0x02, + 0x40,0x40,0x80,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xCFED [?] [4401]*/ + 0x02,0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x1F,0x00,0x01,0xFF,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00, + /* 0xCFEE [?] [4402]*/ + 0x00,0x01,0x00,0xFC,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x1D,0xE0,0x40,0x01,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xCFEF [?] [4403]*/ + 0x04,0x04,0x3F,0x04,0x04,0xFF,0x04,0x08,0x1F,0x28,0xC8,0x0F,0x08,0x08,0x08,0x07, + 0x40,0x40,0xF8,0x40,0x40,0xFE,0x40,0x20,0xF0,0x28,0x26,0xE0,0x20,0x08,0x08,0xF8, + /* 0xCFF0 [?] [4404]*/ + 0x10,0x10,0x11,0x13,0xFD,0x11,0x39,0x34,0x50,0x53,0x90,0x13,0x10,0x10,0x13,0x10, + 0x80,0xF8,0x08,0xFE,0x12,0x22,0xFE,0x40,0xA2,0x54,0x98,0x34,0x54,0x92,0x50,0x20, + /* 0xCFF1 [?] [4405]*/ + 0x09,0x09,0x0A,0x17,0x1A,0x32,0x33,0x50,0x91,0x16,0x11,0x16,0x10,0x11,0x16,0x10, + 0x00,0xF0,0x10,0xFC,0x24,0x44,0xFC,0x80,0x44,0xA8,0x30,0x68,0xA8,0x24,0xA2,0x40, + /* 0xCFF2 [?] [4406]*/ + 0x02,0x04,0x08,0x7F,0x40,0x40,0x47,0x44,0x44,0x44,0x44,0x47,0x44,0x40,0x40,0x40, + 0x00,0x00,0x00,0xFC,0x04,0x04,0xC4,0x44,0x44,0x44,0x44,0xC4,0x44,0x04,0x14,0x08, + /* 0xCFF3 [?] [4407]*/ + 0x08,0x1F,0x20,0x7F,0xA1,0x22,0x3F,0x06,0x19,0x62,0x0C,0x71,0x06,0x18,0xE2,0x01, + 0x00,0xE0,0x20,0xF8,0x08,0x08,0xF8,0x00,0x10,0xA0,0xC0,0xA0,0x90,0x88,0x86,0x00, + /* 0xCFF4 [?] [4408]*/ + 0x08,0x08,0xFF,0x08,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x25,0x25,0x29,0x41,0x81, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0x48,0x28,0x28,0x08,0x08, + /* 0xCFF5 [?] [4409]*/ + 0x00,0x01,0xFC,0x10,0x10,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xCFF6 [?] [4410]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x11,0x09,0x3F,0x20,0x3F,0x20,0x3F,0x20,0x20, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x10,0x20,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x18, + /* 0xCFF7 [?] [4411]*/ + 0x08,0x49,0x29,0x2A,0x08,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x41,0x41,0x45,0x42, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xCFF8 [?] [4412]*/ + 0x00,0x00,0x7B,0x48,0x48,0x4F,0x48,0x48,0x4B,0x49,0x7A,0x4D,0x08,0x00,0x00,0x00, + 0x40,0x44,0xF4,0x48,0x48,0xFE,0x20,0x40,0xF8,0x10,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xCFF9 [?] [4413]*/ + 0x3E,0x22,0x3E,0x00,0xFF,0x01,0x1F,0x10,0x11,0x02,0x0C,0x70,0x00,0x3E,0x22,0x3E, + 0xF8,0x88,0xF8,0x00,0xFE,0x00,0xF0,0x10,0x10,0xC0,0x30,0x08,0x00,0xF8,0x88,0xF8, + /* 0xCFFA [?] [4414]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xCFFB [?] [4415]*/ + 0x00,0x22,0x11,0x11,0x80,0x43,0x4A,0x0A,0x13,0x12,0xE2,0x23,0x22,0x22,0x22,0x02, + 0x40,0x48,0x48,0x50,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xCFFC [?] [4416]*/ + 0x02,0x01,0x7F,0x40,0x91,0x09,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x02,0x14,0x20,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xCFFD [?] [4417]*/ + 0x02,0x21,0x10,0x13,0x8C,0x40,0x4F,0x11,0x13,0x26,0xEB,0x22,0x23,0x22,0x22,0x02, + 0x10,0x20,0xC0,0x30,0x88,0x80,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xCFFE [?] [4418]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x7B,0x48,0x4B,0x48,0x48,0x79,0x49,0x02,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xD0A1 [?] [4419]*/ + 0x01,0x01,0x01,0x01,0x01,0x11,0x11,0x11,0x21,0x21,0x41,0x81,0x01,0x01,0x05,0x02, + 0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x00,0x00,0x00,0x00, + /* 0xD0A2 [?] [4420]*/ + 0x02,0x02,0x3F,0x02,0x02,0xFF,0x01,0x02,0x3F,0x10,0x20,0x5F,0x80,0x00,0x02,0x01, + 0x00,0x08,0xD0,0x20,0x40,0xFE,0x00,0x00,0xE0,0x40,0x80,0xFC,0x80,0x80,0x80,0x00, + /* 0xD0A3 [?] [4421]*/ + 0x10,0x10,0x10,0x11,0xFC,0x10,0x31,0x3A,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x13, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xD0A4 [?] [4422]*/ + 0x01,0x21,0x11,0x09,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x20, + 0x00,0x08,0x10,0x20,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xD0A5 [?] [4423]*/ + 0x00,0x00,0x7B,0x48,0x4F,0x48,0x4B,0x48,0x4A,0x4A,0x7A,0x4B,0x02,0x02,0x04,0x08, + 0x40,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x40,0x48,0x48,0xE8,0x58,0x48,0x48,0x48,0x48, + /* 0xD0A6 [?] [4424]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x01,0x01,0xFF,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x40,0x40,0x7E,0x90,0x08,0xF0,0x00,0x00,0x00,0xFE,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xD0A7 [?] [4425]*/ + 0x10,0x08,0x00,0xFF,0x00,0x24,0x42,0x81,0x24,0x14,0x08,0x14,0x22,0x42,0x80,0x01, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xD0A8 [?] [4426]*/ + 0x21,0x21,0x27,0x21,0xFB,0x21,0x27,0x71,0x69,0xA0,0xA7,0x20,0x20,0x21,0x22,0x2C, + 0x00,0x3C,0xD4,0x14,0x94,0x14,0xD4,0x24,0x4C,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xD0A9 [?] [4427]*/ + 0x04,0x04,0x24,0x27,0x24,0x24,0x24,0x2F,0xF0,0x40,0x00,0x1F,0x00,0x00,0x7F,0x00, + 0x40,0x40,0x44,0x48,0x70,0x42,0x42,0x42,0x3E,0x00,0x00,0xF0,0x00,0x00,0xFC,0x00, + /* 0xD0AA [?] [4428]*/ + 0x00,0x7E,0x42,0x7E,0x42,0x7E,0x20,0x7F,0x89,0x49,0x55,0x41,0x7D,0x01,0x0A,0x04, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82, + /* 0xD0AB [?] [4429]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x54,0x55,0x7E,0x51,0x11,0x15,0x1D,0xE4,0x40,0x00, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFE,0x22,0x22,0x52,0x02,0xFA,0x02,0x14,0x08, + /* 0xD0AC [?] [4430]*/ + 0x28,0x28,0xFE,0x28,0x38,0x10,0x7D,0x54,0x54,0x7C,0x10,0xFE,0x10,0x10,0x11,0x10, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xD0AD [?] [4431]*/ + 0x20,0x20,0x20,0x20,0xFB,0x20,0x20,0x22,0x22,0x24,0x28,0x20,0x21,0x21,0x22,0x24, + 0x80,0x80,0x80,0x80,0xF0,0x90,0x90,0x98,0x94,0x92,0x92,0x90,0x10,0x10,0x50,0x20, + /* 0xD0AE [?] [4432]*/ + 0x10,0x10,0x10,0x11,0xFC,0x11,0x10,0x14,0x18,0x33,0xD0,0x10,0x10,0x10,0x51,0x22, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xD0AF [?] [4433]*/ + 0x10,0x10,0x11,0x13,0xFD,0x11,0x11,0x15,0x19,0x31,0xD3,0x10,0x10,0x11,0x52,0x24, + 0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x9E,0x02,0x0A,0x04, + /* 0xD0B0 [?] [4434]*/ + 0x00,0x7F,0x02,0x22,0x22,0x22,0x42,0x7F,0x06,0x0A,0x12,0x22,0x42,0x82,0x0A,0x04, + 0x00,0xBE,0x22,0x24,0x24,0x28,0x24,0xE4,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xD0B1 [?] [4435]*/ + 0x08,0x08,0x14,0x22,0x41,0xBE,0x08,0x08,0x7F,0x08,0x2A,0x29,0x49,0x88,0x28,0x10, + 0x08,0x48,0x28,0x28,0x08,0x48,0x28,0x28,0x0E,0x78,0x08,0x08,0x08,0x08,0x08,0x08, + /* 0xD0B2 [?] [4436]*/ + 0x00,0x78,0x48,0x48,0x4B,0x78,0x48,0x4A,0x4A,0x7C,0x48,0x48,0x49,0x49,0x4A,0x9C, + 0x80,0x80,0x80,0x80,0xF0,0x90,0x90,0x98,0x94,0x92,0x92,0x90,0x10,0x10,0x50,0x20, + /* 0xD0B3 [?] [4437]*/ + 0x02,0x22,0x13,0x12,0x02,0x03,0xF2,0x10,0x13,0x12,0x12,0x13,0x16,0x1A,0x13,0x02, + 0x20,0x24,0xA8,0x30,0xA2,0x22,0x5E,0x80,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD0B4 [?] [4438]*/ + 0x00,0x7F,0x40,0x90,0x10,0x1F,0x10,0x20,0x3F,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, + 0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0xF8,0x08,0x08,0xC8,0x08,0x08,0x50,0x20, + /* 0xD0B5 [?] [4439]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x31,0x39,0x57,0x51,0x91,0x11,0x12,0x12,0x14,0x10, + 0x10,0x14,0x12,0x10,0xFE,0x10,0x50,0x54,0xF4,0x54,0x54,0x48,0x4A,0x5A,0x26,0x42, + /* 0xD0B6 [?] [4440]*/ + 0x20,0x20,0x3F,0x48,0x88,0x08,0x7F,0x08,0x08,0x2E,0x28,0x28,0x2F,0xF0,0x40,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40, + /* 0xD0B7 [?] [4441]*/ + 0x20,0x3E,0x44,0xBE,0x2A,0x3E,0x2A,0x3E,0x2A,0x2A,0x45,0x3F,0x21,0x3F,0x01,0x7F, + 0x00,0xFC,0x24,0x54,0x98,0x50,0xFC,0x10,0xFE,0x10,0x10,0xF8,0x08,0xF8,0x04,0xFE, + /* 0xD0B8 [?] [4442]*/ + 0x22,0x23,0x24,0x29,0x37,0xAD,0xA5,0xA7,0xA5,0x25,0x27,0x25,0x25,0x25,0x24,0x28, + 0x00,0x9E,0x8A,0x0A,0xD2,0x66,0x40,0xD4,0x5E,0x64,0xC4,0x44,0x5E,0x44,0x44,0xC4, + /* 0xD0B9 [?] [4443]*/ + 0x00,0x22,0x12,0x12,0x82,0x4F,0x42,0x12,0x12,0x22,0xE2,0x22,0x22,0x22,0x23,0x00, + 0x48,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x78,0x00,0x00,0x00,0xFE,0x00, + /* 0xD0BA [?] [4444]*/ + 0x00,0x27,0x14,0x19,0x81,0x41,0x49,0x0A,0x13,0x10,0xE0,0x27,0x20,0x20,0x20,0x00, + 0x00,0xFE,0x02,0x04,0x00,0xFC,0x00,0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xD0BB [?] [4445]*/ + 0x01,0x42,0x27,0x24,0x07,0x04,0xE7,0x24,0x24,0x2F,0x21,0x2A,0x34,0x28,0x02,0x01, + 0x08,0x08,0x88,0x88,0xBE,0x88,0x88,0xC8,0xA8,0xA8,0x88,0x88,0x88,0x88,0xA8,0x10, + /* 0xD0BC [?] [4446]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x24,0x22,0x2F,0x28,0x2F,0x28,0x4F,0x48,0x88,0x08, + 0x00,0xF8,0x08,0x08,0xF8,0x80,0x90,0xA0,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xD0BD [?] [4447]*/ + 0x08,0xFF,0x08,0x10,0x08,0x7F,0x22,0x14,0xFF,0x08,0x7F,0x08,0x2A,0x49,0xA8,0x11, + 0x20,0xFE,0x20,0x00,0x04,0x78,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xD0BE [?] [4448]*/ + 0x08,0x08,0xFF,0x08,0x08,0x02,0x01,0x00,0x04,0x24,0x24,0x44,0x84,0x04,0x03,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0x80,0x08,0x04,0x02,0x02,0x10,0x10,0xF0,0x00, + /* 0xD0BF [?] [4449]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x13,0x10,0xFC,0x10,0x11,0x10,0x14,0x18,0x10,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xD0C0 [?] [4450]*/ + 0x02,0x07,0x38,0x20,0x20,0x20,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x81, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xD0C1 [?] [4451]*/ + 0x02,0x01,0x3F,0x00,0x08,0x04,0xFF,0x01,0x01,0x01,0x7F,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00, + /* 0xD0C2 [?] [4452]*/ + 0x10,0x08,0x7F,0x00,0x22,0x14,0xFF,0x08,0x08,0x7F,0x08,0x2A,0x49,0x88,0x28,0x11, + 0x00,0x04,0x78,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xD0C3 [?] [4453]*/ + 0x10,0x10,0x11,0x11,0x19,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD0C4 [?] [4454]*/ + 0x00,0x02,0x01,0x00,0x00,0x04,0x04,0x24,0x24,0x24,0x44,0x44,0x84,0x04,0x03,0x00, + 0x00,0x00,0x00,0x80,0x80,0x00,0x08,0x04,0x04,0x02,0x02,0x12,0x10,0x10,0xF0,0x00, + /* 0xD0C5 [?] [4455]*/ + 0x08,0x08,0x0B,0x10,0x10,0x31,0x30,0x50,0x91,0x10,0x10,0x11,0x11,0x11,0x11,0x11, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD0C6 [?] [4456]*/ + 0x08,0x08,0x10,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x57,0xFC,0x00,0x00, + 0x10,0x10,0x94,0x54,0x58,0x10,0xFC,0x10,0x10,0x10,0xFE,0x10,0x90,0x10,0x10,0x10, + /* 0xD0C7 [?] [4457]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x11,0x1F,0x21,0x41,0x1F,0x01,0x01,0x7F,0x00, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xF8,0x00,0x00,0xF0,0x00,0x00,0xFC,0x00, + /* 0xD0C8 [?] [4458]*/ + 0x00,0x7B,0x4A,0x4B,0x4A,0x7B,0x48,0x4A,0x4B,0x7C,0x48,0x4B,0x48,0x48,0x4F,0x98, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0x40,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x00, + /* 0xD0C9 [?] [4459]*/ + 0x00,0x8B,0x52,0x23,0x52,0x93,0x10,0x12,0x33,0x54,0x90,0x13,0x10,0x10,0xA7,0x40, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0x40,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x00, + /* 0xD0CA [?] [4460]*/ + 0x10,0x11,0x11,0x11,0x19,0x55,0x50,0x51,0x91,0x12,0x10,0x11,0x10,0x10,0x13,0x10, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xD0CB [?] [4461]*/ + 0x04,0x02,0x21,0x11,0x08,0x08,0x00,0xFF,0x00,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x08,0x08,0x08,0x10,0x10,0x20,0x40,0xFE,0x00,0x40,0x20,0x10,0x08,0x08,0x04,0x04, + /* 0xD0CC [?] [4462]*/ + 0x00,0x7F,0x12,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x82, + 0x04,0x84,0x04,0x24,0x24,0x24,0x24,0xE4,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD0CD [?] [4463]*/ + 0x00,0x7F,0x12,0x12,0x12,0xFF,0x12,0x22,0x22,0x41,0x81,0x3F,0x01,0x01,0xFF,0x00, + 0x04,0x84,0x24,0x24,0x24,0xA4,0x24,0x04,0x14,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xD0CE [?] [4464]*/ + 0x00,0x7F,0x12,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x82, + 0x00,0x84,0x04,0x08,0x10,0x22,0x02,0xC4,0x08,0x10,0x22,0x02,0x04,0x08,0x10,0x60, + /* 0xD0CF [?] [4465]*/ + 0x00,0x7F,0x12,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x82, + 0x00,0xBE,0x22,0x24,0x24,0x28,0x24,0xE4,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xD0D0 [?] [4466]*/ + 0x08,0x09,0x10,0x20,0x48,0x08,0x13,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x00,0x00,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xD0D1 [?] [4467]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x10,0x50,0x7C,0x90,0x10,0x7C,0x10,0x10,0xFE,0x00, + /* 0xD0D2 [?] [4468]*/ + 0x01,0x01,0x3F,0x01,0x01,0xFF,0x08,0x04,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x00,0x00,0xFE,0x20,0x40,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xD0D3 [?] [4469]*/ + 0x01,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xD0D4 [?] [4470]*/ + 0x10,0x10,0x11,0x11,0x19,0x55,0x52,0x50,0x90,0x11,0x10,0x10,0x10,0x10,0x13,0x10, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD0D5 [?] [4471]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x26,0x24,0x24,0x49,0x28,0x10,0x28,0x44,0x83,0x00, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD0D6 [?] [4472]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x3F,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0xC0, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xD0D7 [?] [4473]*/ + 0x00,0x00,0x10,0x08,0x44,0x42,0x41,0x42,0x44,0x48,0x50,0x60,0x40,0x40,0x7F,0x00, + 0x00,0x10,0x10,0x20,0x44,0x84,0x04,0x84,0x44,0x24,0x14,0x14,0x04,0x04,0xFC,0x04, + /* 0xD0D8 [?] [4474]*/ + 0x01,0x79,0x49,0x49,0x4A,0x7A,0x4D,0x48,0x4A,0x7A,0x4B,0x4A,0x4B,0x48,0x48,0x98, + 0x00,0x00,0x00,0xFE,0x02,0x02,0x12,0xA2,0x4A,0xAA,0x1A,0x0A,0xFA,0x02,0x14,0x08, + /* 0xD0D9 [?] [4475]*/ + 0x08,0x08,0x10,0x1F,0x20,0x40,0x88,0x25,0x22,0x25,0x28,0x20,0x3F,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x08,0x88,0x88,0x28,0x28,0x28,0xA8,0x28,0xE8,0x08,0x50,0x20, + /* 0xD0DA [?] [4476]*/ + 0x00,0x20,0x11,0x10,0x82,0x42,0x4A,0x0A,0x12,0x12,0xE3,0x22,0x22,0x23,0x20,0x00, + 0x00,0x08,0x08,0x88,0x52,0x52,0x22,0x22,0x52,0x92,0x0A,0x0A,0x02,0xFE,0x02,0x00, + /* 0xD0DB [?] [4477]*/ + 0x08,0x08,0x08,0x7E,0x11,0x12,0x20,0x28,0x48,0x48,0x90,0x14,0x22,0x7E,0x22,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xD0DC [?] [4478]*/ + 0x10,0x24,0x42,0x7E,0x00,0x7E,0x42,0x7E,0x42,0x7E,0x42,0x46,0x00,0x48,0x44,0x84, + 0x80,0x98,0xE0,0x84,0x84,0x7C,0x80,0x98,0xE0,0x84,0x84,0x7C,0x00,0x88,0x44,0x44, + /* 0xD0DD [?] [4479]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x50,0x91,0x11,0x12,0x14,0x18,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0xFE,0x40,0xE0,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40,0x40, + /* 0xD0DE [?] [4480]*/ + 0x10,0x10,0x11,0x21,0x2A,0x6C,0xA9,0x2E,0x28,0x2B,0x28,0x28,0x2B,0x20,0x21,0x26, + 0x80,0x80,0xF8,0x08,0x90,0x60,0x98,0x26,0xC0,0x10,0x20,0xC8,0x10,0x60,0x80,0x00, + /* 0xD0DF [?] [4481]*/ + 0x08,0x04,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x0F,0x11,0x21,0xCF,0x02,0x02,0x3F,0x00, + 0x20,0x40,0xFC,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xFE,0x00, + /* 0xD0E0 [?] [4482]*/ + 0x10,0x13,0x10,0x10,0xFC,0x10,0x31,0x39,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFE,0x40,0x40,0x80,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xD0E1 [?] [4483]*/ + 0x00,0x00,0x7B,0x4A,0x4B,0x4A,0x4B,0x4A,0x4B,0x48,0x78,0x4F,0x00,0x01,0x02,0x0C, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x50,0x48,0xFE,0xA0,0x10,0x08,0x06, + /* 0xD0E2 [?] [4484]*/ + 0x10,0x11,0x3C,0x20,0x43,0xBC,0x11,0x12,0xFD,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x1C,0xE0,0x20,0x20,0xFE,0xA8,0x24,0x22,0xF8,0x88,0x90,0xBE,0x02,0x02,0x14,0x08, + /* 0xD0E3 [?] [4485]*/ + 0x00,0x1F,0x01,0x01,0x7F,0x05,0x09,0x31,0xCF,0x04,0x04,0x04,0x08,0x08,0x10,0x60, + 0x70,0x80,0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x20,0x40,0x78,0x08,0x08,0x50,0x20, + /* 0xD0E4 [?] [4486]*/ + 0x20,0x10,0x00,0xFC,0x09,0x11,0x11,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xD0E5 [?] [4487]*/ + 0x10,0x13,0x20,0x20,0x4F,0xF9,0x12,0x24,0x43,0xF9,0x41,0x01,0x1A,0xE2,0x44,0x08, + 0x38,0xC0,0x40,0x40,0xFC,0x50,0x48,0x46,0xF0,0x10,0x20,0x7C,0x04,0x04,0x28,0x10, + /* 0xD0E6 [?] [4488]*/ + 0x20,0x20,0x20,0x23,0x22,0xFA,0x23,0x22,0x22,0x22,0x22,0x3B,0xE4,0x44,0x09,0x00, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x00,0x50,0x54,0x54,0xD8,0x50,0xFE,0x00, + /* 0xD0E7 [?] [4489]*/ + 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0x20,0x40,0x40,0x81, + 0x50,0x48,0x40,0xFE,0x40,0x40,0x44,0x44,0x44,0x28,0x28,0x12,0x32,0x4A,0x86,0x02, + /* 0xD0E8 [?] [4490]*/ + 0x00,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0xFF,0x02,0x3F,0x24,0x24,0x24,0x20, + 0x00,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFE,0x00,0xF8,0x88,0x88,0xA8,0x10, + /* 0xD0E9 [?] [4491]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x21,0x20,0x22,0x32,0x2A,0x2A,0x42,0x5F,0x80, + 0x00,0xF8,0x00,0xFC,0x04,0x60,0x88,0x08,0xF8,0x40,0x48,0x48,0x50,0x40,0xFC,0x00, + /* 0xD0EA [?] [4492]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4B,0x4A,0x4A,0x4A,0x7A,0x4B,0x04,0x04,0x09,0x00, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x00,0x50,0x54,0x54,0xD8,0x50,0xFE,0x00, + /* 0xD0EB [?] [4493]*/ + 0x08,0x09,0x10,0x20,0x41,0x89,0x09,0x11,0x21,0x45,0x85,0x09,0x10,0x20,0x41,0x82, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xD0EC [?] [4494]*/ + 0x10,0x10,0x20,0x41,0x92,0x15,0x20,0x60,0xA7,0x20,0x22,0x22,0x24,0x28,0x21,0x20, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xD0ED [?] [4495]*/ + 0x00,0x20,0x10,0x11,0x01,0x02,0xF0,0x10,0x13,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x80,0x80,0x80,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD0EE [?] [4496]*/ + 0x08,0xFF,0x08,0x01,0xFF,0x08,0x1F,0x03,0x0C,0x3F,0x00,0x3F,0x21,0x3F,0x21,0x3F, + 0x20,0xFE,0x20,0x00,0xFE,0x20,0xC0,0x10,0x08,0xFC,0x04,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xD0EF [?] [4497]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x44,0x44,0x28,0xAA,0xAA,0x92,0x92,0xAA,0xAA,0xA6,0xC6,0x82,0x82,0xFE,0x02, + /* 0xD0F0 [?] [4498]*/ + 0x08,0x08,0x14,0x22,0x41,0xBE,0x08,0x08,0x7F,0x08,0x2A,0x29,0x49,0x88,0x28,0x11, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xD0F1 [?] [4499]*/ + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x43,0x80, + 0x00,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xF8,0x8A,0x02,0x02,0xFE,0x00, + /* 0xD0F2 [?] [4500]*/ + 0x01,0x00,0x3F,0x20,0x23,0x20,0x20,0x20,0x2F,0x20,0x20,0x20,0x40,0x40,0x81,0x00, + 0x00,0x80,0xFE,0x00,0xF8,0x10,0xA0,0x40,0xFE,0x42,0x44,0x40,0x40,0x40,0x40,0x80, + /* 0xD0F3 [?] [4501]*/ + 0x02,0x01,0x7F,0x04,0x08,0x1F,0x03,0x0C,0x3F,0x00,0x3F,0x21,0x3F,0x21,0x3F,0x20, + 0x00,0x00,0xFC,0x00,0x20,0xC0,0x10,0x08,0xFC,0x04,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xD0F4 [?] [4502]*/ + 0x10,0x10,0x10,0x11,0x1B,0x56,0x52,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x17,0x10, + 0x40,0x40,0x80,0x00,0xFC,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0xFE,0x00, + /* 0xD0F5 [?] [4503]*/ + 0x08,0x7F,0x11,0x32,0x0C,0x32,0xC2,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xD0F6 [?] [4504]*/ + 0x10,0x13,0x10,0x11,0xFD,0x25,0x26,0x24,0x25,0x49,0x29,0x11,0x29,0x45,0x81,0x01, + 0x00,0xFE,0x22,0x20,0x3C,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xD0F7 [?] [4505]*/ + 0x10,0x10,0x23,0x20,0x48,0xF7,0x10,0x20,0x41,0xFB,0x45,0x01,0x19,0xE1,0x41,0x01, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD0F8 [?] [4506]*/ + 0x10,0x10,0x21,0x24,0x44,0xFB,0x10,0x20,0x40,0xFD,0x40,0x03,0x1C,0xE0,0x40,0x03, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x10,0x90,0xFE,0x28,0x44,0x82,0x02, + /* 0xD0F9 [?] [4507]*/ + 0x10,0x10,0x10,0xFE,0x20,0x28,0x48,0x7E,0x09,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08, + 0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD0FA [?] [4508]*/ + 0x00,0x00,0x7B,0x4A,0x4C,0x49,0x48,0x49,0x49,0x49,0x79,0x49,0x01,0x00,0x03,0x00, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xD0FB [?] [4509]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x00,0xFF,0x00, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x00,0xFE,0x00, + /* 0xD0FC [?] [4510]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x10,0xFF,0x08,0x10,0x3F,0x10,0x01,0x28,0x28,0x48,0x07, + 0xF0,0x10,0xF0,0x10,0xF0,0x10,0xFE,0x20,0x10,0xF8,0x08,0x00,0x88,0xA4,0x24,0xE0, + /* 0xD0FD [?] [4511]*/ + 0x20,0x10,0x10,0x01,0xFE,0x21,0x20,0x3C,0x24,0x24,0x24,0x24,0x24,0x45,0x55,0x8A, + 0x80,0x80,0xFE,0x00,0x00,0xFC,0x24,0x24,0xA0,0xA0,0xBC,0xA0,0xA0,0x60,0x3E,0x00, + /* 0xD0FE [?] [4512]*/ + 0x02,0x01,0x01,0xFF,0x02,0x04,0x08,0x10,0x3F,0x11,0x02,0x04,0x08,0x3F,0x10,0x00, + 0x00,0x00,0x00,0xFE,0x00,0x20,0x20,0x40,0x80,0x00,0x00,0x20,0x10,0xF8,0x08,0x08, + /* 0xD1A1 [?] [4513]*/ + 0x00,0x22,0x12,0x13,0x04,0x00,0xF7,0x11,0x11,0x11,0x12,0x12,0x14,0x28,0x47,0x00, + 0x40,0x40,0x40,0xF8,0x40,0x40,0xFC,0x20,0x20,0x20,0x24,0x24,0x1C,0x00,0xFE,0x00, + /* 0xD1A2 [?] [4514]*/ + 0x01,0x00,0x3F,0x24,0x27,0xA9,0x72,0x2F,0x2A,0x6F,0xAA,0x2F,0x20,0x43,0x5C,0x80, + 0x00,0x80,0xFE,0x00,0x44,0x28,0x7E,0x90,0x90,0xBC,0x90,0x90,0x7E,0x90,0x10,0x10, + /* 0xD1A3 [?] [4515]*/ + 0x00,0x00,0x78,0x4B,0x48,0x78,0x48,0x49,0x7B,0x48,0x48,0x48,0x79,0x4B,0x01,0x00, + 0x40,0x20,0x20,0xFE,0x40,0x40,0x88,0x08,0xF0,0x20,0x40,0x88,0x04,0xFC,0x04,0x00, + /* 0xD1A4 [?] [4516]*/ + 0x10,0x10,0x21,0x21,0x4A,0xF4,0x13,0x22,0x42,0xFB,0x42,0x02,0x1B,0xE0,0x40,0x00, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xD1A5 [?] [4517]*/ + 0x28,0x28,0xFE,0x28,0x38,0x11,0x7E,0x54,0x54,0x7C,0x10,0xFE,0x10,0x10,0x10,0x10, + 0x50,0x50,0x50,0x92,0x92,0x94,0x98,0x90,0xB0,0xD0,0x90,0x90,0x92,0x92,0x8E,0x80, + /* 0xD1A6 [?] [4518]*/ + 0x08,0x08,0xFF,0x08,0x10,0x7C,0x45,0x44,0x7C,0x43,0x40,0x7C,0x45,0x44,0x7C,0x44, + 0x20,0x20,0xFE,0x20,0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20, + /* 0xD1A7 [?] [4519]*/ + 0x22,0x11,0x11,0x00,0x7F,0x40,0x80,0x1F,0x00,0x01,0xFF,0x01,0x01,0x01,0x05,0x02, + 0x08,0x08,0x10,0x20,0xFE,0x02,0x04,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xD1A8 [?] [4520]*/ + 0x02,0x01,0x01,0x7F,0x40,0x80,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0xFE,0x02,0x44,0x40,0x40,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x02, + /* 0xD1A9 [?] [4521]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x00,0x00,0x1F,0x00,0x00,0x3F,0x00, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD1AA [?] [4522]*/ + 0x01,0x01,0x02,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0x00,0xF8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xD1AB [?] [4523]*/ + 0x00,0x3E,0x22,0x22,0x3E,0x00,0x7F,0x41,0x49,0x49,0x49,0x49,0x14,0x12,0x21,0xC2, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xD1AC [?] [4524]*/ + 0x00,0x3F,0x01,0xFF,0x01,0x3F,0x29,0x25,0x3F,0x01,0x3F,0x01,0xFF,0x48,0x44,0x84, + 0xF8,0x00,0x00,0xFE,0x00,0xF8,0x28,0x48,0xF8,0x00,0xF8,0x00,0xFE,0x88,0x44,0x44, + /* 0xD1AD [?] [4525]*/ + 0x10,0x17,0x24,0x44,0x97,0x14,0x25,0x65,0xA5,0x25,0x25,0x25,0x29,0x29,0x31,0x21, + 0x3C,0xE0,0x20,0x20,0xFE,0x20,0xFC,0x04,0x04,0xFC,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD1AE [?] [4526]*/ + 0x08,0x08,0x0F,0x10,0x10,0x2F,0x48,0x88,0x0F,0x08,0x08,0x0F,0x08,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xC4,0x44,0x44,0xC4,0x44,0x44,0xC4,0x44,0x04,0x28,0x10, + /* 0xD1AF [?] [4527]*/ + 0x00,0x20,0x11,0x11,0x02,0x04,0xF3,0x12,0x12,0x13,0x12,0x12,0x17,0x18,0x10,0x00, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xD1B0 [?] [4528]*/ + 0x00,0x3F,0x00,0x00,0x1F,0x00,0x00,0x3F,0x00,0x00,0xFF,0x08,0x04,0x04,0x00,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x20,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xD1B1 [?] [4529]*/ + 0x01,0xF9,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1D,0xE5,0x45,0x06,0x2A,0x14, + 0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04, + /* 0xD1B2 [?] [4530]*/ + 0x00,0x21,0x11,0x11,0x02,0x02,0xF4,0x12,0x12,0x11,0x11,0x11,0x10,0x28,0x47,0x00, + 0x00,0x24,0x24,0x24,0x48,0x48,0x90,0x48,0x48,0x24,0x24,0x24,0x00,0x00,0xFE,0x00, + /* 0xD1B3 [?] [4531]*/ + 0x00,0x00,0xFD,0x21,0x22,0x3D,0x45,0x45,0x65,0x95,0x09,0x09,0x11,0x20,0x40,0x80, + 0x80,0x80,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x04,0x28,0x10, + /* 0xD1B4 [?] [4532]*/ + 0x00,0x27,0x11,0x11,0x81,0x41,0x41,0x17,0x11,0x21,0xE1,0x21,0x21,0x21,0x21,0x01, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xD0,0x10,0x10,0x10,0x12,0x0A,0x0A,0x06,0x02, + /* 0xD1B5 [?] [4533]*/ + 0x01,0x21,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x12,0x02,0x04, + 0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04, + /* 0xD1B6 [?] [4534]*/ + 0x00,0x27,0x11,0x11,0x01,0x01,0xF1,0x17,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xD0,0x10,0x10,0x10,0x12,0x0A,0x0A,0x06,0x02, + /* 0xD1B7 [?] [4535]*/ + 0x00,0x4F,0x20,0x21,0x02,0x02,0xE3,0x22,0x26,0x2A,0x23,0x22,0x2A,0x24,0x50,0x8F, + 0x10,0x90,0x90,0x10,0x10,0xD8,0x54,0x54,0x92,0x92,0x12,0x10,0x50,0x20,0x00,0xFE, + /* 0xD1B8 [?] [4536]*/ + 0x00,0x4F,0x22,0x22,0x02,0x02,0xEF,0x22,0x22,0x22,0x22,0x22,0x22,0x50,0x8F,0x00, + 0x00,0xE0,0x20,0x20,0x20,0x20,0xA0,0x20,0x24,0x14,0x14,0x0C,0x04,0x00,0xFE,0x00, + /* 0xD1B9 [?] [4537]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x2F,0x20,0x20,0x20,0x20,0x20,0x40,0x5F,0x80, + 0x00,0xFE,0x00,0x80,0x80,0x80,0x80,0xFC,0x80,0x80,0x90,0x88,0x88,0x80,0xFE,0x00, + /* 0xD1BA [?] [4538]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x10,0x10,0x10,0x50,0x20, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xD1BB [?] [4539]*/ + 0x00,0x7E,0x04,0x24,0x24,0x24,0x44,0x7F,0x0C,0x14,0x14,0x24,0x45,0x84,0x14,0x08, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xD1BC [?] [4540]*/ + 0x00,0xFE,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0xFE,0x92,0x10,0x11,0x10,0x10,0x10, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xD1BD [?] [4541]*/ + 0x00,0x03,0x78,0x49,0x49,0x49,0x4A,0x4B,0x48,0x48,0x78,0x49,0x02,0x04,0x00,0x00, + 0x00,0xFC,0x10,0x10,0x10,0x10,0x10,0xFE,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xD1BE [?] [4542]*/ + 0x00,0x20,0x10,0x08,0x04,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD1BF [?] [4543]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x00,0x10,0x20,0x3F,0x01,0x02,0x0C,0x30,0xC0,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xD1C0 [?] [4544]*/ + 0x00,0x3F,0x00,0x00,0x10,0x10,0x20,0x3F,0x01,0x02,0x04,0x08,0x10,0x60,0x01,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xD1C1 [?] [4545]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x55,0x55,0x7C,0x50,0x10,0x14,0x1D,0xE6,0x40,0x00, + 0x00,0xFE,0x08,0x88,0x88,0x88,0x08,0xFE,0x18,0x28,0x48,0x88,0x08,0x08,0x28,0x10, + /* 0xD1C2 [?] [4546]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x20,0x2F,0x20,0x3F,0x20,0x20,0x4F,0x40,0x9F,0x00, + 0x00,0x08,0x08,0xF8,0x00,0xFC,0x80,0xF8,0x80,0xFC,0x00,0x80,0xF8,0x80,0xFE,0x00, + /* 0xD1C3 [?] [4547]*/ + 0x10,0x1F,0x22,0x42,0x8F,0x14,0x24,0x6F,0xA0,0x20,0x27,0x24,0x24,0x24,0x27,0x24, + 0x00,0xC0,0x1C,0x00,0x80,0x80,0xBE,0xC8,0x08,0x08,0x88,0x88,0x88,0x88,0xA8,0x90, + /* 0xD1C4 [?] [4548]*/ + 0x00,0x27,0x14,0x14,0x85,0x44,0x44,0x17,0x14,0x24,0xE4,0x25,0x24,0x28,0x2B,0x10, + 0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xD1C5 [?] [4549]*/ + 0x00,0x7E,0x04,0x24,0x25,0x26,0x44,0x7F,0x0C,0x14,0x14,0x24,0x44,0x84,0x14,0x08, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xD1C6 [?] [4550]*/ + 0x00,0x03,0x78,0x48,0x48,0x48,0x4C,0x4A,0x4A,0x4A,0x78,0x48,0x00,0x00,0x07,0x00, + 0x00,0xFC,0x90,0x90,0x90,0x92,0x92,0x94,0x94,0x98,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xD1C7 [?] [4551]*/ + 0x00,0x7F,0x04,0x04,0x04,0x04,0x44,0x24,0x24,0x14,0x14,0x04,0x04,0x04,0xFF,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x48,0x50,0x40,0x40,0x40,0xFE,0x00, + /* 0xD1C8 [?] [4552]*/ + 0x00,0x23,0x10,0x11,0x01,0x01,0xF2,0x13,0x10,0x10,0x10,0x15,0x1A,0x14,0x00,0x00, + 0x00,0xFC,0x10,0x10,0x10,0x10,0x10,0xFE,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xD1C9 [?] [4553]*/ + 0x00,0x7F,0x01,0x11,0x11,0x11,0xFF,0x08,0x0F,0x10,0x1F,0x00,0x29,0x24,0x40,0x00, + 0x00,0xFC,0x00,0xF8,0x00,0x00,0xFE,0x00,0xF8,0x00,0xFC,0x04,0x24,0x94,0x28,0x10, + /* 0xD1CA [?] [4554]*/ + 0x00,0x07,0xF4,0x94,0x94,0x94,0x97,0x94,0x94,0x94,0xF4,0x95,0x06,0x04,0x07,0x04, + 0x00,0xFC,0x04,0x44,0x44,0x44,0xFC,0x44,0x44,0xA4,0x94,0x14,0x04,0x04,0xFC,0x04, + /* 0xD1CB [?] [4555]*/ + 0x20,0x17,0x00,0x42,0x5F,0x44,0x49,0x71,0x4F,0x49,0x4F,0x49,0x4F,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x44,0x24,0x1C,0xE4,0x24,0xE4,0x24,0xE4,0x14,0xF4,0x08, + /* 0xD1CC [?] [4556]*/ + 0x10,0x13,0x12,0x16,0x5A,0x52,0x53,0x92,0x12,0x12,0x12,0x2A,0x27,0x42,0x43,0x82, + 0x00,0xFE,0x02,0x22,0x22,0x22,0xFE,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0xFE,0x02, + /* 0xD1CD [?] [4557]*/ + 0x00,0x20,0x17,0x11,0x82,0x44,0x43,0x12,0x12,0x23,0xE2,0x22,0x23,0x20,0x20,0x00, + 0x40,0x80,0xFE,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xD1CE [?] [4558]*/ + 0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40,0x00,0x3F,0x24,0x24,0x24,0x24,0xFF,0x00, + 0x20,0x20,0x20,0x28,0x24,0x22,0x20,0x20,0x00,0xF8,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xD1CF [?] [4559]*/ + 0x00,0x7F,0x02,0x12,0x0A,0x02,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0xFC,0x40,0x48,0x50,0x40,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD1D0 [?] [4560]*/ + 0x00,0x01,0xFC,0x10,0x10,0x20,0x3C,0x67,0x64,0xA4,0x24,0x24,0x3C,0x25,0x21,0x02, + 0x00,0xFC,0x88,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xD1D1 [?] [4561]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xA9,0xA9,0xAB,0xF8,0xA2,0x22,0x29,0x39,0xEA,0x44,0x08, + 0x04,0x0E,0xB8,0x88,0x88,0x28,0x2E,0xA8,0xA8,0xA8,0xA8,0x3E,0x00,0x80,0x7E,0x00, + /* 0xD1D2 [?] [4562]*/ + 0x01,0x21,0x21,0x21,0x3F,0x00,0x00,0x7F,0x04,0x04,0x0F,0x18,0x28,0xC8,0x0F,0x08, + 0x00,0x08,0x08,0x08,0xF8,0x00,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xD1D3 [?] [4563]*/ + 0x00,0x00,0xF9,0x08,0x10,0x11,0x21,0x79,0x09,0x09,0x49,0x31,0x10,0x2C,0x43,0x80, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0xFC,0x00,0x00,0xFE,0x00, + /* 0xD1D4 [?] [4564]*/ + 0x02,0x01,0xFF,0x00,0x00,0x3F,0x00,0x00,0x3F,0x00,0x00,0x3F,0x20,0x20,0x3F,0x20, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD1D5 [?] [4565]*/ + 0x10,0x08,0x7F,0x22,0x14,0x7F,0x44,0x48,0x52,0x44,0x48,0x51,0x42,0x44,0x88,0x30, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xD1D6 [?] [4566]*/ + 0x20,0x17,0x02,0x42,0x47,0x48,0x52,0x4C,0x48,0x48,0x4E,0x48,0x48,0x4F,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x24,0x44,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x14,0x08, + /* 0xD1D7 [?] [4567]*/ + 0x01,0x11,0x11,0x21,0x02,0x04,0x18,0x60,0x01,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x00,0x08,0x10,0x20,0xC0,0x30,0x08,0x04,0x00,0x10,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xD1D8 [?] [4568]*/ + 0x00,0x21,0x11,0x11,0x81,0x41,0x42,0x14,0x10,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x0E,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD1D9 [?] [4569]*/ + 0x02,0x02,0x7F,0x04,0x09,0x31,0xDF,0x11,0x11,0x1F,0x11,0x11,0x1F,0x01,0x01,0x00, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xF6,0x10,0x10,0xF0,0x10,0x10,0xF4,0x04,0x04,0xFC, + /* 0xD1DA [?] [4570]*/ + 0x10,0x10,0x17,0x11,0xFE,0x14,0x13,0x16,0x1A,0x33,0xD2,0x12,0x13,0x10,0x50,0x20, + 0x40,0x80,0xFE,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xD1DB [?] [4571]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x7A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x03,0x02, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xD1DC [?] [4572]*/ + 0x10,0x12,0x21,0x41,0x80,0x14,0x22,0x62,0xA0,0x21,0x27,0x21,0x21,0x21,0x21,0x20, + 0x00,0x00,0x1C,0x00,0x00,0x00,0x3E,0x88,0x88,0x08,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xD1DD [?] [4573]*/ + 0x00,0x20,0x17,0x14,0x80,0x43,0x40,0x13,0x12,0x23,0xE2,0x23,0x20,0x21,0x22,0x04, + 0x80,0x40,0xFC,0x04,0x00,0xF8,0x40,0xF8,0x48,0xF8,0x48,0xF8,0x00,0x10,0x08,0x04, + /* 0xD1DE [?] [4574]*/ + 0x10,0x10,0x10,0xFD,0x12,0x15,0x11,0x7D,0x11,0x11,0x11,0xFD,0x11,0x11,0x10,0x10, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xD1DF [?] [4575]*/ + 0x20,0x23,0x22,0x22,0x22,0xFA,0x22,0x22,0x22,0x23,0x22,0x3A,0xE2,0x42,0x02,0x03, + 0x00,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x20,0xFE,0x48,0xC8,0x30,0x48,0x84,0xFE, + /* 0xD1E0 [?] [4576]*/ + 0x04,0xFF,0x04,0x04,0x17,0x10,0xF0,0x17,0x14,0x34,0xD7,0x10,0x00,0x48,0x44,0x84, + 0x40,0xFE,0x40,0x40,0xD0,0x12,0x1C,0xD0,0x50,0x52,0xD2,0x0E,0x00,0x88,0x44,0x44, + /* 0xD1E1 [?] [4577]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x2F,0x20,0x21,0x21,0x22,0x22,0x44,0x48,0x90, + 0x00,0xFE,0x00,0x80,0x90,0x88,0x80,0xFC,0x80,0x40,0x40,0x20,0x20,0x10,0x08,0x06, + /* 0xD1E2 [?] [4578]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x24,0x24,0x3C,0x25,0x22,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xD1E3 [?] [4579]*/ + 0x00,0x3F,0x20,0x22,0x22,0x24,0x24,0x2D,0x36,0x24,0x24,0x24,0x24,0x44,0x44,0x84, + 0x00,0xFE,0x00,0x50,0x48,0xFE,0x90,0x90,0xFE,0x90,0x90,0xFE,0x90,0x90,0xFE,0x80, + /* 0xD1E4 [?] [4580]*/ + 0x00,0x00,0x7B,0x48,0x48,0x49,0x48,0x48,0x49,0x48,0x78,0x49,0x01,0x01,0x01,0x01, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD1E5 [?] [4581]*/ + 0x02,0x01,0x3F,0x08,0x04,0x3F,0x20,0x20,0x21,0x2E,0x20,0x21,0x2E,0x40,0x43,0x9C, + 0x00,0x00,0xF8,0x20,0x40,0xFC,0x00,0x20,0xC0,0x10,0x60,0x88,0x10,0x60,0x80,0x00, + /* 0xD1E6 [?] [4582]*/ + 0x10,0x10,0x10,0x14,0x59,0x52,0x50,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x81, + 0x40,0x40,0x7C,0x84,0x08,0x00,0x20,0xCE,0x02,0x02,0xCE,0x02,0x02,0x02,0xFE,0x02, + /* 0xD1E7 [?] [4583]*/ + 0x02,0x01,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x04,0xFF,0x08,0x1C,0x03,0x0C,0x30, + 0x00,0x00,0xFE,0x02,0xF4,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xD1E8 [?] [4584]*/ + 0x00,0x20,0x13,0x10,0x01,0x00,0xF3,0x12,0x12,0x12,0x12,0x16,0x1A,0x14,0x04,0x09, + 0x40,0x20,0xFC,0x00,0x08,0x90,0xFE,0x10,0x20,0xC8,0x10,0x24,0xC8,0x10,0x60,0x80, + /* 0xD1E9 [?] [4585]*/ + 0x00,0xF8,0x08,0x48,0x48,0x49,0x4A,0x7C,0x04,0x04,0x1D,0xE4,0x44,0x04,0x2B,0x10, + 0x20,0x20,0x50,0x50,0x88,0x04,0xFA,0x00,0x44,0x24,0x24,0xA8,0x88,0x10,0xFE,0x00, + /* 0xD1EA [?] [4586]*/ + 0x00,0x00,0xFC,0x21,0x21,0x3D,0x45,0x45,0x65,0x97,0x08,0x08,0x10,0x20,0x41,0x82, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xD1EB [?] [4587]*/ + 0x01,0x01,0x01,0x1F,0x11,0x11,0x11,0x11,0x11,0xFF,0x02,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFE,0x80,0x80,0x40,0x20,0x18,0x06, + /* 0xD1EC [?] [4588]*/ + 0x01,0x1F,0x11,0x11,0xFF,0x02,0x1C,0xE2,0x04,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x00,0xF0,0x10,0x10,0xFE,0x80,0x70,0x0E,0x00,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xD1ED [?] [4589]*/ + 0x08,0x1C,0xF0,0x11,0x11,0xFD,0x11,0x31,0x39,0x57,0x54,0x90,0x10,0x10,0x11,0x12, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xD1EE [?] [4590]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x31,0x38,0x54,0x54,0x91,0x11,0x12,0x14,0x10,0x11, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xD1EF [?] [4591]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x11,0x14,0x18,0x30,0xD1,0x11,0x12,0x14,0x50,0x21, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xD1F0 [?] [4592]*/ + 0x0A,0x09,0x09,0x10,0x17,0x30,0x30,0x53,0x90,0x10,0x17,0x10,0x10,0x10,0x10,0x10, + 0x08,0x08,0x10,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xD1F1 [?] [4593]*/ + 0x00,0x00,0x1F,0x10,0x93,0x50,0x50,0x11,0x33,0x51,0x91,0x12,0x22,0x24,0x48,0x81, + 0x80,0x40,0xFE,0x00,0xF0,0x20,0xC0,0x00,0xFC,0x24,0x24,0x24,0x44,0x44,0xA8,0x10, + /* 0xD1F2 [?] [4594]*/ + 0x08,0x04,0x04,0x7F,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x20,0x20,0x40,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xD1F3 [?] [4595]*/ + 0x02,0x21,0x11,0x10,0x87,0x40,0x40,0x13,0x10,0x20,0xE7,0x20,0x20,0x20,0x20,0x00, + 0x08,0x08,0x10,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xD1F4 [?] [4596]*/ + 0x00,0x7C,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD1F5 [?] [4597]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x11,0x0A,0x7F,0x04,0x3F,0x04,0xFF,0x04,0x04,0x04, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0xD0,0x10,0x90,0x12,0xEA,0x0A,0x06,0x02, + /* 0xD1F6 [?] [4598]*/ + 0x08,0x08,0x0B,0x12,0x12,0x32,0x32,0x52,0x92,0x12,0x12,0x13,0x12,0x10,0x10,0x10, + 0x00,0x80,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xB4,0x28,0x20,0x20,0x20,0x20, + /* 0xD1F7 [?] [4599]*/ + 0x00,0x00,0x1F,0x11,0x90,0x57,0x50,0x10,0x33,0x50,0x90,0x17,0x20,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x10,0xA0,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40,0x40, + /* 0xD1F8 [?] [4600]*/ + 0x08,0x04,0x00,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x08,0x34,0xC4,0x04,0x08,0x10,0x20, + 0x20,0x40,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x40,0x20,0x58,0x46,0x40,0x40,0x40,0x40, + /* 0xD1F9 [?] [4601]*/ + 0x11,0x10,0x10,0x10,0xFB,0x10,0x30,0x39,0x54,0x50,0x93,0x10,0x10,0x10,0x10,0x10, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xD1FA [?] [4602]*/ + 0x02,0x21,0x17,0x10,0x83,0x40,0x47,0x10,0x10,0x21,0xE0,0x27,0x21,0x22,0x2D,0x00, + 0x08,0x10,0xFC,0x40,0xF8,0x40,0xFC,0x40,0x20,0xC0,0x44,0x68,0x50,0x48,0x46,0x80, + /* 0xD1FB [?] [4603]*/ + 0x02,0x44,0x2F,0x28,0x0F,0x08,0xEF,0x22,0x3F,0x24,0x27,0x28,0x32,0x21,0x50,0x8F, + 0x00,0x10,0x90,0x90,0x9E,0xA4,0xC4,0x14,0xD4,0x08,0x88,0x94,0xA2,0x42,0x00,0xFE, + /* 0xD1FC [?] [4604]*/ + 0x00,0x7B,0x48,0x48,0x4B,0x7A,0x4A,0x4B,0x48,0x78,0x4F,0x48,0x49,0x48,0x48,0x9B, + 0x00,0xFE,0x50,0x50,0xFE,0x52,0x52,0xFE,0x00,0x40,0xFE,0x88,0x90,0x60,0xD8,0x04, + /* 0xD1FD [?] [4605]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x25,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x81,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFE,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xD1FE [?] [4606]*/ + 0x00,0x00,0xFB,0x20,0x22,0x21,0xF9,0x22,0x20,0x23,0x20,0x39,0xE1,0x41,0x01,0x00, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0xFC,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xD2A1 [?] [4607]*/ + 0x10,0x10,0x13,0x10,0xFA,0x11,0x11,0x1A,0x30,0xD3,0x10,0x11,0x11,0x11,0x51,0x20, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0xFC,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xD2A2 [?] [4608]*/ + 0x02,0x02,0x02,0x7F,0x01,0x00,0x07,0x38,0x00,0xFF,0x04,0x04,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFC,0x20,0x40,0x84,0x64,0x1C,0x00,0xFE,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xD2A3 [?] [4609]*/ + 0x00,0x23,0x10,0x12,0x01,0x01,0xF2,0x10,0x13,0x10,0x11,0x11,0x11,0x11,0x28,0x47, + 0x3C,0xC0,0x04,0x44,0x28,0xFC,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x00,0xFE, + /* 0xD2A4 [?] [4610]*/ + 0x02,0x01,0x7F,0x48,0x90,0x20,0x08,0x1F,0x21,0x01,0xFF,0x01,0x21,0x21,0x3F,0x00, + 0x00,0x00,0xFE,0x22,0x14,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00,0x08,0x08,0xF8,0x08, + /* 0xD2A5 [?] [4611]*/ + 0x00,0x20,0x13,0x10,0x02,0x01,0xF1,0x12,0x10,0x13,0x10,0x11,0x15,0x19,0x11,0x00, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0xFC,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xD2A6 [?] [4612]*/ + 0x20,0x20,0x20,0x22,0xF9,0x48,0x48,0x49,0x8A,0x4C,0x30,0x10,0x29,0x49,0x82,0x04, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xD2A7 [?] [4613]*/ + 0x00,0x00,0xF0,0x97,0x90,0x91,0x92,0x94,0x91,0x91,0xF0,0x90,0x00,0x01,0x02,0x0C, + 0x80,0x40,0x40,0xFC,0x00,0x10,0x08,0x04,0x10,0x10,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xD2A8 [?] [4614]*/ + 0x00,0x7F,0x02,0x21,0x11,0x10,0x0C,0x30,0x20,0x20,0x3C,0x20,0x20,0x20,0x3F,0x20, + 0xFC,0x00,0x08,0x08,0x10,0x20,0x00,0x78,0x08,0x08,0x78,0x08,0x08,0x08,0xF8,0x08, + /* 0xD2A9 [?] [4615]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x20,0x45,0xFA,0x10,0x20,0xFC,0x00,0x1C,0xE0,0x40, + 0x40,0x40,0xFE,0x40,0x80,0x80,0xFC,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x28,0x10, + /* 0xD2AA [?] [4616]*/ + 0x00,0x7F,0x04,0x04,0x3F,0x24,0x24,0x3F,0x02,0x7F,0x04,0x08,0x1C,0x03,0x06,0x38, + 0x00,0xFC,0x40,0x40,0xF8,0x48,0x48,0xF8,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xD2AB [?] [4617]*/ + 0x10,0x11,0x90,0x55,0x58,0x11,0xFC,0x28,0x28,0x29,0x2A,0x28,0x2A,0x4C,0x48,0x80, + 0x00,0xDC,0x44,0x54,0xCC,0x54,0x00,0x48,0xFE,0x90,0xFC,0x90,0xFC,0x90,0xFE,0x80, + /* 0xD2AC [?] [4618]*/ + 0x20,0x2F,0x24,0x24,0xF4,0x27,0x24,0x74,0x6F,0xA4,0xA4,0x25,0x2E,0x20,0x20,0x20, + 0x00,0xDE,0x92,0x92,0x94,0x94,0x98,0x94,0x92,0x92,0x92,0xDA,0x94,0x90,0x90,0x90, + /* 0xD2AD [?] [4619]*/ + 0x00,0x03,0x78,0x49,0x48,0x4B,0x4A,0x49,0x48,0x49,0x79,0x49,0x01,0x00,0x03,0x00, + 0x20,0xFE,0x20,0xFC,0x00,0xFE,0x02,0xFC,0x00,0xFC,0x04,0xFC,0x04,0x88,0xFE,0x00, + /* 0xD2AE [?] [4620]*/ + 0x00,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x27,0xFA,0x42,0x02,0x02,0x02, + 0x00,0xBE,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0xA2,0x34,0x28,0x20,0x20,0x20, + /* 0xD2AF [?] [4621]*/ + 0x04,0x08,0x18,0x24,0x03,0x0C,0x30,0xC0,0x1F,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x40,0x20,0x50,0x88,0x00,0xC0,0x30,0x0E,0xF0,0x10,0x10,0x10,0x50,0x20,0x00,0x00, + /* 0xD2B0 [?] [4622]*/ + 0x00,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40, + 0x00,0x7C,0x04,0x28,0x10,0x08,0x7E,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xD2B1 [?] [4623]*/ + 0x00,0x40,0x20,0x21,0x02,0x07,0x10,0x10,0x23,0xE2,0x22,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD2B2 [?] [4624]*/ + 0x01,0x01,0x11,0x11,0x11,0x17,0x39,0xD1,0x11,0x11,0x11,0x11,0x10,0x10,0x0F,0x00, + 0x00,0x00,0x00,0x30,0xD0,0x10,0x10,0x10,0x10,0x50,0x20,0x02,0x02,0x02,0xFE,0x00, + /* 0xD2B3 [?] [4625]*/ + 0x00,0x7F,0x02,0x04,0x1F,0x10,0x11,0x11,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x40,0x20,0x10,0x08, + /* 0xD2B4 [?] [4626]*/ + 0x10,0x10,0x17,0x11,0xFD,0x12,0x12,0x16,0x1A,0x33,0xD2,0x12,0x12,0x12,0x52,0x23, + 0x80,0x40,0xFE,0x20,0x20,0x3C,0x44,0x64,0x94,0x48,0x48,0x30,0x20,0x50,0x88,0x06, + /* 0xD2B5 [?] [4627]*/ + 0x04,0x04,0x04,0x04,0x44,0x24,0x24,0x14,0x14,0x14,0x04,0x04,0x04,0x04,0xFF,0x00, + 0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x48,0x50,0x60,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xD2B6 [?] [4628]*/ + 0x00,0x00,0x78,0x48,0x48,0x48,0x4B,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD2B7 [?] [4629]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x00,0x00,0x00,0x01,0x0E,0xF0, + 0x00,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x90,0xA0,0x42,0xA2,0x1A,0x06, + /* 0xD2B8 [?] [4630]*/ + 0x00,0x78,0x4F,0x49,0x49,0x7A,0x4A,0x4E,0x4A,0x7B,0x4A,0x4A,0x4A,0x4A,0x4A,0x9B, + 0x80,0x40,0xFE,0x20,0x20,0x3C,0x44,0x64,0x94,0x48,0x48,0x30,0x20,0x50,0x88,0x06, + /* 0xD2B9 [?] [4631]*/ + 0x02,0x01,0xFF,0x08,0x08,0x10,0x11,0x31,0x52,0x95,0x11,0x10,0x10,0x10,0x11,0x16, + 0x00,0x00,0xFE,0x80,0x80,0xF8,0x08,0x48,0x28,0x10,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xD2BA [?] [4632]*/ + 0x00,0x20,0x17,0x11,0x81,0x42,0x42,0x16,0x12,0x23,0xE2,0x22,0x22,0x22,0x22,0x03, + 0x80,0x40,0xFE,0x20,0x20,0x3C,0x44,0x64,0x94,0x48,0x48,0x30,0x20,0x50,0x88,0x06, + /* 0xD2BB [?] [4633]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD2BC [?] [4634]*/ + 0x01,0x01,0x7F,0x01,0x1F,0x00,0x7F,0x40,0x9F,0x00,0x1F,0x10,0x1F,0x08,0x04,0xFF, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xFE,0x02,0xF4,0x00,0xF0,0x10,0xF0,0x20,0x40,0xFE, + /* 0xD2BD [?] [4635]*/ + 0x00,0x7F,0x44,0x44,0x4F,0x50,0x40,0x5F,0x40,0x41,0x42,0x44,0x58,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x00,0xF8,0x80,0x80,0xFC,0x80,0x40,0x20,0x10,0x08,0x00,0xFE,0x00, + /* 0xD2BE [?] [4636]*/ + 0x10,0x11,0x11,0x11,0xFD,0x10,0x17,0x15,0x19,0x31,0xD1,0x11,0x11,0x17,0x50,0x20, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x3E,0xC8,0x08,0x08, + /* 0xD2BF [?] [4637]*/ + 0x10,0x10,0x3C,0x23,0x40,0xBC,0x10,0x10,0xFD,0x12,0x14,0x10,0x14,0x18,0x10,0x00, + 0x40,0x20,0x20,0xFE,0x40,0x40,0xA0,0xA2,0xA4,0x98,0x90,0x88,0x84,0xA2,0xC0,0x80, + /* 0xD2C0 [?] [4638]*/ + 0x08,0x08,0x08,0x17,0x10,0x30,0x31,0x51,0x93,0x15,0x19,0x11,0x11,0x11,0x11,0x11, + 0x80,0x40,0x40,0xFE,0x80,0x80,0x40,0x44,0x48,0x30,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xD2C1 [?] [4639]*/ + 0x08,0x0B,0x08,0x10,0x10,0x37,0x30,0x50,0x90,0x13,0x10,0x10,0x11,0x11,0x12,0x14, + 0x00,0xF8,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0xF8,0x88,0x80,0x00,0x00,0x00,0x00, + /* 0xD2C2 [?] [4640]*/ + 0x02,0x01,0x01,0xFF,0x02,0x02,0x05,0x05,0x08,0x18,0x28,0x48,0x88,0x0A,0x0C,0x08, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x08,0x90,0xA0,0x40,0x20,0x10,0x08,0x06,0x00, + /* 0xD2C3 [?] [4641]*/ + 0x00,0x7D,0x48,0x48,0x49,0x5D,0x55,0x55,0x55,0x5D,0x49,0x49,0x48,0x7E,0x01,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xD2C4 [?] [4642]*/ + 0x01,0x01,0xFF,0x01,0x3F,0x01,0x01,0x3F,0x21,0x21,0x3F,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x84,0x4C,0x20,0x18,0x06, + /* 0xD2C5 [?] [4643]*/ + 0x00,0x23,0x12,0x13,0x00,0x0F,0xF0,0x13,0x12,0x12,0x12,0x10,0x11,0x2A,0x47,0x00, + 0x40,0xF8,0x48,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0xA0,0x10,0x08,0xFE,0x00, + /* 0xD2C6 [?] [4644]*/ + 0x08,0x1C,0xF0,0x10,0x11,0xFC,0x10,0x30,0x39,0x54,0x54,0x91,0x10,0x10,0x10,0x11, + 0x20,0x20,0x7C,0x84,0x48,0x30,0x20,0x48,0x90,0x3E,0x42,0xA4,0x18,0x10,0x60,0x80, + /* 0xD2C7 [?] [4645]*/ + 0x08,0x08,0x0A,0x12,0x12,0x31,0x31,0x51,0x90,0x10,0x10,0x10,0x10,0x11,0x12,0x14, + 0x80,0x48,0x48,0x08,0x08,0x10,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0x10,0x08,0x06, + /* 0xD2C8 [?] [4646]*/ + 0x00,0x78,0x4F,0x48,0x4B,0x78,0x4B,0x4A,0x4B,0x78,0x48,0x48,0x48,0x49,0x4A,0x9C, + 0x40,0x40,0xFC,0x40,0xF8,0x48,0xF8,0x40,0xFC,0x44,0x54,0xA8,0xA0,0x10,0x08,0x06, + /* 0xD2C9 [?] [4647]*/ + 0x40,0x4D,0x70,0x44,0x44,0x3D,0x40,0x7C,0x90,0x10,0xFE,0x10,0x28,0x25,0x45,0x82, + 0x00,0xFC,0x08,0x50,0x20,0xFE,0x24,0x28,0xA0,0xB8,0xA0,0xA0,0xE0,0x20,0x1E,0x00, + /* 0xD2CA [?] [4648]*/ + 0x00,0x20,0x13,0x12,0x82,0x42,0x43,0x12,0x12,0x22,0xE2,0x22,0x22,0x24,0x24,0x08, + 0x08,0x3C,0xC0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD2CB [?] [4649]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0xFF,0x00, + 0x00,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0xFE,0x00, + /* 0xD2CC [?] [4650]*/ + 0x20,0x20,0x27,0x20,0xFB,0x48,0x4B,0x4A,0x8B,0x48,0x30,0x10,0x28,0x49,0x82,0x04, + 0x40,0x40,0xFC,0x40,0xF8,0x48,0xF8,0x40,0xFC,0x44,0x54,0xA8,0xA0,0x10,0x08,0x06, + /* 0xD2CD [?] [4651]*/ + 0x08,0x0F,0x10,0x1F,0x00,0xFF,0x92,0x54,0xFE,0x38,0x54,0x92,0x08,0xFF,0x08,0x10, + 0x00,0xE0,0x20,0xC0,0x40,0xFE,0x24,0x78,0x12,0xFE,0x54,0x92,0x20,0xFE,0x20,0x20, + /* 0xD2CE [?] [4652]*/ + 0x20,0x20,0x23,0x20,0xF9,0x22,0x27,0x70,0x6B,0xA2,0xA2,0x22,0x23,0x20,0x20,0x20, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xFE,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xD2CF [?] [4653]*/ + 0x10,0x10,0x11,0x7D,0x55,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1C,0xE4,0x41,0x06, + 0x40,0x24,0x24,0x04,0x04,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xD2D0 [?] [4654]*/ + 0x08,0x08,0x0B,0x10,0x11,0x32,0x37,0x50,0x93,0x12,0x12,0x12,0x13,0x10,0x10,0x10, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xFE,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xD2D1 [?] [4655]*/ + 0x00,0x3F,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xD2D2 [?] [4656]*/ + 0x00,0x7F,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xD2D3 [?] [4657]*/ + 0x02,0x04,0x08,0x10,0x3F,0x08,0x08,0x1F,0x21,0x01,0x7F,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x20,0x10,0xF8,0x08,0x00,0xF0,0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06, + /* 0xD2D4 [?] [4658]*/ + 0x00,0x04,0x22,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x24,0x28,0x30,0x21,0x02,0x04, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x50,0x88,0x04,0x02,0x02, + /* 0xD2D5 [?] [4659]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x3F,0x00,0x03,0x04,0x08,0x10,0x20,0x20,0x1F,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xE0,0xC0,0x00,0x00,0x00,0x00,0x04,0x04,0xFC,0x00, + /* 0xD2D6 [?] [4660]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x12,0x16,0x1A,0x32,0xD2,0x13,0x12,0x10,0x50,0x20, + 0x00,0x80,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xB4,0x28,0x20,0x20,0x20,0x20, + /* 0xD2D7 [?] [4661]*/ + 0x0F,0x08,0x08,0x0F,0x08,0x08,0x0F,0x04,0x08,0x1F,0x22,0x42,0x04,0x08,0x11,0x02, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xFC,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xD2D8 [?] [4662]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x1F,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x02,0x02,0xFE,0x00, + /* 0xD2D9 [?] [4663]*/ + 0x10,0x10,0x10,0x10,0x55,0x56,0x54,0x54,0x54,0x54,0x54,0x5C,0x65,0x01,0x00,0x00, + 0x40,0x40,0x80,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xD2DA [?] [4664]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x50,0x90,0x11,0x11,0x12,0x12,0x12,0x11,0x10, + 0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x80,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xD2DB [?] [4665]*/ + 0x08,0x09,0x11,0x21,0x49,0x0A,0x14,0x33,0x51,0x91,0x10,0x10,0x10,0x10,0x13,0x1C, + 0x00,0xF0,0x10,0x10,0x10,0x0E,0x00,0xF8,0x08,0x10,0x90,0xA0,0x40,0xA0,0x18,0x06, + /* 0xD2DC [?] [4666]*/ + 0x00,0x78,0x49,0x48,0x48,0x7B,0x48,0x49,0x49,0x79,0x49,0x49,0x48,0x4A,0x4A,0x9C, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x94,0x8A,0x7A, + /* 0xD2DD [?] [4667]*/ + 0x01,0x41,0x21,0x22,0x04,0x0F,0xE4,0x24,0x27,0x20,0x21,0x21,0x22,0x24,0x50,0x8F, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFC,0xA0,0x30,0x2A,0x22,0x1E,0x00,0xFE, + /* 0xD2DE [?] [4668]*/ + 0x40,0x4C,0x70,0x44,0x45,0x3C,0x40,0x7C,0x90,0x11,0xFE,0x10,0x29,0x24,0x44,0x80, + 0x20,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xD2DF [?] [4669]*/ + 0x00,0x00,0x1F,0x10,0x93,0x52,0x52,0x14,0x38,0x57,0x92,0x11,0x20,0x20,0x41,0x8E, + 0x80,0x40,0xFE,0x00,0xF0,0x10,0x10,0x0E,0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xD2E0 [?] [4670]*/ + 0x02,0x01,0x01,0xFF,0x04,0x04,0x24,0x24,0x24,0x44,0x44,0x88,0x08,0x10,0x21,0x40, + 0x00,0x00,0x00,0xFE,0x40,0x40,0x50,0x48,0x48,0x44,0x44,0x44,0x40,0x40,0x40,0x80, + /* 0xD2E1 [?] [4671]*/ + 0x02,0x01,0xFF,0x04,0x08,0x3A,0xCC,0x08,0x3F,0x24,0x28,0x37,0x24,0x27,0x20,0x20, + 0x00,0x00,0xFE,0x88,0x50,0x20,0x18,0x06,0xF8,0x48,0x28,0xD8,0x48,0xC8,0x28,0x10, + /* 0xD2E2 [?] [4672]*/ + 0x01,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x02,0x51,0x51,0x90,0x0F, + 0x00,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x04,0x12,0x12,0xF0, + /* 0xD2E3 [?] [4673]*/ + 0x10,0x08,0x7F,0x22,0x14,0xFF,0x10,0x29,0xCE,0x14,0x26,0xCD,0x15,0x24,0xD4,0x09, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xD2E4 [?] [4674]*/ + 0x10,0x10,0x13,0x10,0x18,0x54,0x50,0x50,0x90,0x11,0x11,0x12,0x12,0x12,0x11,0x10, + 0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x80,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xD2E5 [?] [4675]*/ + 0x02,0x01,0x21,0x20,0x10,0x10,0x08,0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xD2E6 [?] [4676]*/ + 0x10,0x08,0x00,0xFF,0x00,0x08,0x10,0x20,0x40,0x3F,0x24,0x24,0x24,0x24,0xFF,0x00, + 0x10,0x20,0x00,0xFE,0x00,0x20,0x10,0x08,0x04,0xF8,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xD2E7 [?] [4677]*/ + 0x02,0x21,0x11,0x10,0x87,0x40,0x41,0x12,0x14,0x23,0xE2,0x22,0x22,0x22,0x2F,0x00, + 0x08,0x08,0x10,0x00,0xFC,0x00,0x10,0x08,0x04,0xF8,0xA8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xD2E8 [?] [4678]*/ + 0x01,0x21,0x11,0x11,0x01,0x01,0xF0,0x10,0x11,0x11,0x11,0x15,0x19,0x11,0x01,0x01, + 0x00,0x04,0x38,0xC0,0x02,0x02,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD2E9 [?] [4679]*/ + 0x00,0x20,0x12,0x12,0x02,0x01,0xF1,0x11,0x10,0x10,0x10,0x14,0x18,0x11,0x02,0x0C, + 0x80,0x48,0x48,0x08,0x08,0x10,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0x10,0x08,0x06, + /* 0xD2EA [?] [4680]*/ + 0x00,0x20,0x13,0x12,0x04,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x07,0x00, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00, + /* 0xD2EB [?] [4681]*/ + 0x00,0x23,0x11,0x10,0x00,0x00,0xF0,0x13,0x10,0x11,0x10,0x14,0x1B,0x10,0x00,0x00, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xD2EC [?] [4682]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x1F,0x00,0x08,0x08,0xFF,0x08,0x10,0x20,0x40, + 0x00,0xF0,0x10,0x10,0xF0,0x04,0x04,0xFC,0x00,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xD2ED [?] [4683]*/ + 0x7E,0x22,0x1A,0x62,0x02,0x3F,0x21,0x3F,0x21,0x3F,0x04,0x3F,0x04,0xFF,0x08,0x10, + 0xFC,0x44,0x34,0xC4,0x04,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xF8,0x40,0xFE,0x20,0x10, + /* 0xD2EE [?] [4684]*/ + 0x00,0x7E,0x22,0x12,0x06,0x1A,0x62,0x01,0x00,0x7F,0x00,0x10,0x08,0x04,0xFF,0x00, + 0x00,0xFC,0x44,0x24,0x0C,0x34,0xC4,0x00,0x80,0xFC,0x00,0x10,0x20,0x40,0xFE,0x00, + /* 0xD2EF [?] [4685]*/ + 0x10,0x13,0x21,0x20,0x48,0xF8,0x10,0x23,0x40,0xF9,0x40,0x00,0x1B,0xE0,0x40,0x00, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xD2F0 [?] [4686]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x21,0x21,0x2F,0x21,0x22,0x24,0x28,0x20,0x3F,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xE8,0x08,0x88,0x48,0x28,0x08,0xF8,0x08, + /* 0xD2F1 [?] [4687]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7C,0x44,0x48,0x50,0x48,0x44,0x44,0x54,0x48,0x41,0x42, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0x14,0x08, + /* 0xD2F2 [?] [4688]*/ + 0x00,0x7F,0x40,0x41,0x41,0x41,0x5F,0x41,0x42,0x42,0x44,0x48,0x50,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0xF4,0x04,0x84,0x44,0x24,0x14,0x14,0x04,0xFC,0x04, + /* 0xD2F3 [?] [4689]*/ + 0x06,0x38,0x20,0x3E,0x22,0x3E,0x22,0x3E,0x20,0x3E,0x22,0x22,0x42,0x4A,0x84,0x01, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xD2F4 [?] [4690]*/ + 0x02,0x01,0x3F,0x00,0x08,0x04,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xD2F5 [?] [4691]*/ + 0x00,0x7D,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x52,0x42,0x44,0x48, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xD2F6 [?] [4692]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x81,0x01, + 0x00,0xFC,0x04,0x24,0x24,0x24,0xFC,0x24,0x24,0x54,0x4C,0x8C,0x04,0x04,0xFC,0x04, + /* 0xD2F7 [?] [4693]*/ + 0x00,0x00,0x78,0x48,0x49,0x4A,0x4C,0x48,0x48,0x4B,0x78,0x48,0x00,0x00,0x00,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x88,0x46,0x40,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x40, + /* 0xD2F8 [?] [4694]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xD2F9 [?] [4695]*/ + 0x00,0x20,0x17,0x10,0x84,0x42,0x42,0x10,0x17,0x20,0xE0,0x2F,0x20,0x20,0x27,0x00, + 0x08,0x3C,0xC0,0x84,0x44,0x48,0x10,0x3C,0xC0,0x40,0x40,0xFE,0x40,0x40,0xFC,0x00, + /* 0xD2FA [?] [4696]*/ + 0x02,0x01,0x7F,0x40,0x9F,0x01,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x04,0x08,0x10, + 0x00,0x00,0xFE,0x02,0xF4,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x40,0x20,0x10, + /* 0xD2FB [?] [4697]*/ + 0x20,0x20,0x20,0x3E,0x44,0x48,0x81,0x10,0x10,0x10,0x10,0x12,0x14,0x18,0x11,0x02, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xD2FC [?] [4698]*/ + 0x00,0x00,0x3F,0x04,0x04,0xFF,0x04,0x04,0x3F,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x00,0x00,0xF0,0x10,0x10,0xFE,0x10,0x10,0xF0,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD2FD [?] [4699]*/ + 0x00,0x7F,0x01,0x01,0x01,0x3F,0x20,0x20,0x40,0x7F,0x01,0x01,0x01,0x01,0x0A,0x04, + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + /* 0xD2FE [?] [4700]*/ + 0x00,0x78,0x49,0x4A,0x54,0x53,0x60,0x51,0x48,0x4B,0x48,0x68,0x51,0x45,0x45,0x48, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x40,0x24,0x2A,0x0A,0xF8, + /* 0xD3A1 [?] [4701]*/ + 0x00,0x06,0x78,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0x4E,0x70,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xA8,0x90,0x80,0x80,0x80, + /* 0xD3A2 [?] [4702]*/ + 0x08,0x08,0xFF,0x08,0x01,0x01,0x1F,0x11,0x11,0x11,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xF0,0x10,0x10,0x10,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xD3A3 [?] [4703]*/ + 0x20,0x2F,0x28,0x2A,0xFA,0x2A,0x25,0x78,0x68,0xAF,0xA1,0x22,0x23,0x20,0x21,0x2E, + 0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0x80,0xFE,0x10,0x10,0xA0,0x60,0x98,0x04, + /* 0xD3A4 [?] [4704]*/ + 0x00,0x3E,0x22,0x2A,0x2A,0x2A,0x14,0x62,0x02,0x7F,0x04,0x08,0x1C,0x03,0x06,0x38, + 0x00,0xF8,0x88,0xA8,0xA8,0xA8,0x50,0x88,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xD3A5 [?] [4705]*/ + 0x00,0x3F,0x22,0x24,0x2D,0x36,0x24,0x24,0x21,0x27,0x24,0x24,0x47,0x40,0x9F,0x00, + 0x80,0xFE,0x50,0xFC,0x90,0xFC,0x90,0xFC,0x00,0xF0,0x90,0x20,0xFC,0x04,0xD4,0x08, + /* 0xD3A6 [?] [4706]*/ + 0x01,0x00,0x3F,0x20,0x20,0x21,0x28,0x24,0x24,0x22,0x22,0x22,0x40,0x40,0x9F,0x00, + 0x00,0x80,0xFE,0x00,0x00,0x04,0x84,0x84,0x48,0x48,0x10,0x10,0x20,0x40,0xFE,0x00, + /* 0xD3A7 [?] [4707]*/ + 0x20,0x2F,0x28,0x4A,0x5A,0xFA,0x25,0x28,0x40,0xF7,0x41,0x02,0x33,0xC0,0x01,0x0E, + 0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0x80,0xFE,0x10,0x10,0xA0,0x60,0x98,0x04, + /* 0xD3A8 [?] [4708]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x80,0x3F,0x01,0x01,0x1F,0x01,0x01,0x01,0x7F, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF8,0x00,0x00,0xF0,0x00,0x40,0x20,0xFC, + /* 0xD3A9 [?] [4709]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x41,0x81,0x1F,0x11,0x11,0x1F,0x01,0x01,0x7F,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xD3AA [?] [4710]*/ + 0x08,0x08,0xFF,0x08,0x7F,0x40,0x9F,0x10,0x10,0x1F,0x00,0x3F,0x20,0x20,0x3F,0x20, + 0x20,0x20,0xFE,0x20,0xFE,0x02,0xF4,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD3AB [?] [4711]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x81,0x11,0x11,0x22,0x02,0x04,0x08,0x30,0xC0, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0x10,0x10,0xA0,0x80,0x40,0x20,0x18,0x06, + /* 0xD3AC [?] [4712]*/ + 0x20,0x21,0x21,0xF9,0xA9,0xA8,0xAB,0xAA,0xFA,0xA3,0x22,0x2A,0x3B,0xE8,0x40,0x00, + 0x00,0xF0,0x10,0x10,0xF0,0x40,0xF8,0x48,0x48,0xF8,0x48,0x48,0xFA,0x42,0x42,0x3E, + /* 0xD3AD [?] [4713]*/ + 0x00,0x20,0x13,0x12,0x02,0x02,0xF2,0x12,0x12,0x12,0x13,0x12,0x10,0x28,0x47,0x00, + 0x00,0x80,0x3C,0x24,0x24,0x24,0x24,0x24,0x24,0xB4,0x28,0x20,0x20,0x20,0xFE,0x00, + /* 0xD3AE [?] [4714]*/ + 0x01,0xFF,0x20,0x3F,0x00,0x3F,0x20,0x3F,0x00,0x77,0x54,0x75,0x55,0x75,0x52,0xB4, + 0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x00,0xDC,0x54,0x54,0x5C,0x56,0x96,0x62, + /* 0xD3AF [?] [4715]*/ + 0x00,0x3F,0x08,0x0F,0x08,0x12,0x11,0x22,0x44,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0xF0,0x10,0xA0,0xBC,0x84,0x04,0x94,0x48,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xD3B0 [?] [4716]*/ + 0x00,0x7F,0x41,0x7F,0x41,0x7F,0x08,0xFF,0x00,0x7F,0x41,0x7F,0x08,0x49,0x88,0x18, + 0x00,0x04,0x04,0x08,0x10,0x22,0x02,0xC4,0x08,0x10,0x22,0x02,0x04,0x08,0x90,0x60, + /* 0xD3B1 [?] [4717]*/ + 0x40,0x4D,0x70,0x44,0x45,0x3D,0x01,0x0D,0x71,0x11,0xFF,0x11,0x38,0x54,0x91,0x12, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xD3B2 [?] [4718]*/ + 0x00,0x01,0xFC,0x10,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3C,0x24,0x20,0x03, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xD3B3 [?] [4719]*/ + 0x00,0x00,0x78,0x49,0x49,0x49,0x79,0x49,0x49,0x4B,0x48,0x78,0x48,0x00,0x01,0x02, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xD3B4 [?] [4720]*/ + 0x02,0x02,0xF2,0x94,0x95,0x9F,0x92,0x92,0x94,0x9F,0xF4,0x90,0x01,0x0E,0x04,0x00, + 0x20,0x20,0x20,0x3C,0x44,0x44,0x84,0x24,0x14,0x94,0x04,0x04,0x84,0x04,0x28,0x10, + /* 0xD3B5 [?] [4721]*/ + 0x20,0x27,0x24,0x24,0xFC,0x27,0x24,0x2C,0x34,0xE7,0x24,0x24,0x24,0x28,0xA8,0x50, + 0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x54,0x08, + /* 0xD3B6 [?] [4722]*/ + 0x10,0x17,0x14,0x24,0x24,0x67,0x64,0xA4,0x24,0x27,0x24,0x24,0x24,0x28,0x28,0x30, + 0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x54,0x08, + /* 0xD3B7 [?] [4723]*/ + 0x00,0x78,0x4F,0x48,0x4A,0x7A,0x4C,0x4F,0x49,0x7A,0x4C,0x4F,0x49,0x4A,0x4C,0x98, + 0x40,0x20,0xFE,0x28,0x24,0x7E,0xC8,0x48,0x7E,0x48,0xC8,0x7E,0x48,0x48,0x7E,0x40, + /* 0xD3B8 [?] [4724]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x54,0x14,0x37,0x54,0x94,0x17,0x24,0x28,0x48,0x90, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xD3B9 [?] [4725]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x3F,0x20,0x2F,0x20,0x2F,0x28,0x2F,0x48,0x4F,0x88,0x08, + 0x80,0xFE,0x80,0xF8,0x88,0xFE,0x88,0xF8,0x80,0xF8,0x88,0xF8,0x88,0xF8,0x88,0x98, + /* 0xD3BA [?] [4726]*/ + 0x02,0x01,0xFF,0x10,0x10,0x24,0x45,0x7A,0x10,0x24,0x44,0x78,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xFE,0x50,0x48,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0xFE,0x80, + /* 0xD3BB [?] [4727]*/ + 0x00,0x7D,0x44,0x44,0x44,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01,0x01, + 0x00,0xF8,0x08,0xD0,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0x0C, + /* 0xD3BC [?] [4728]*/ + 0x10,0x11,0x10,0x7C,0x54,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x00,0xF8,0x08,0xD0,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0x0C, + /* 0xD3BD [?] [4729]*/ + 0x00,0x00,0x78,0x49,0x48,0x48,0x4B,0x48,0x48,0x48,0x79,0x49,0x02,0x04,0x00,0x00, + 0x40,0x20,0x10,0xE0,0x22,0x34,0xB8,0xB0,0xA8,0xA8,0x28,0x24,0x24,0x22,0xA0,0x40, + /* 0xD3BE [?] [4730]*/ + 0x00,0x20,0x10,0x13,0x80,0x40,0x4F,0x11,0x11,0x21,0xE2,0x24,0x28,0x30,0x21,0x00, + 0x80,0x40,0x20,0xC0,0x44,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x42,0x40,0x80, + /* 0xD3BF [?] [4731]*/ + 0x00,0x27,0x10,0x11,0x80,0x47,0x44,0x14,0x17,0x24,0xE4,0x27,0x24,0x24,0x24,0x04, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xD3C0 [?] [4732]*/ + 0x02,0x01,0x00,0x1F,0x01,0x01,0x7D,0x05,0x05,0x09,0x09,0x11,0x21,0xC1,0x05,0x02, + 0x00,0x00,0x80,0x00,0x04,0x08,0x90,0xA0,0x40,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xD3C1 [?] [4733]*/ + 0x3F,0x06,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x20,0x01,0x08,0x48,0x48,0x87,0x00, + 0xF0,0x60,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x18,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xD3C2 [?] [4734]*/ + 0x3F,0x06,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x22,0x02,0x7F,0x04,0x08,0x10,0x60, + 0xF0,0x60,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xD3C3 [?] [4735]*/ + 0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x41,0x41,0x80, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xD3C4 [?] [4736]*/ + 0x01,0x01,0x09,0x09,0x51,0x55,0x7D,0x49,0x49,0x55,0x7D,0x45,0x41,0x41,0x7F,0x00, + 0x00,0x00,0x20,0x20,0x44,0x54,0xF4,0x24,0x24,0x54,0xF4,0x14,0x04,0x04,0xFC,0x04, + /* 0xD3C5 [?] [4737]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x50,0x90,0x10,0x11,0x11,0x11,0x12,0x12,0x14, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xD3C6 [?] [4738]*/ + 0x10,0x10,0x24,0x64,0xA5,0x24,0x24,0x20,0x20,0x23,0x01,0x08,0x48,0x48,0x87,0x00, + 0x40,0x40,0x7E,0x88,0x48,0x50,0x20,0x58,0x86,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xD3C7 [?] [4739]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x90,0x10,0x11,0x11,0x11,0x12,0x12,0x14, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xD3C8 [?] [4740]*/ + 0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x20,0x10,0x10,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x82,0x7E,0x00, + /* 0xD3C9 [?] [4741]*/ + 0x01,0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x21,0x3F,0x20, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD3CA [?] [4742]*/ + 0x08,0x08,0x08,0x7F,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x7F,0x41,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xD3CB [?] [4743]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xD3CC [?] [4744]*/ + 0x00,0x44,0x28,0x10,0x2B,0x48,0x88,0x08,0x18,0x28,0x49,0x89,0x09,0x0A,0x52,0x24, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xD3CD [?] [4745]*/ + 0x00,0x20,0x10,0x10,0x87,0x44,0x44,0x14,0x14,0x27,0xE4,0x24,0x24,0x24,0x27,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0xFC,0x04, + /* 0xD3CE [?] [4746]*/ + 0x02,0x21,0x11,0x17,0x82,0x42,0x43,0x12,0x12,0x22,0xE2,0x22,0x24,0x24,0x29,0x10, + 0x10,0x10,0x10,0xBE,0x20,0x40,0xBC,0x84,0x88,0x88,0xBE,0x88,0x88,0x88,0xA8,0x10, + /* 0xD3CF [?] [4747]*/ + 0x00,0xFF,0x04,0x04,0x7F,0x44,0x44,0x48,0x50,0x60,0x40,0x7F,0x40,0x40,0x7F,0x40, + 0x00,0xFE,0x40,0x40,0xFC,0x44,0x44,0x44,0x3C,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD3D0 [?] [4748]*/ + 0x02,0x02,0xFF,0x04,0x04,0x0F,0x08,0x18,0x2F,0x48,0x88,0x0F,0x08,0x08,0x08,0x08, + 0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xD3D1 [?] [4749]*/ + 0x02,0x02,0x02,0xFF,0x04,0x04,0x0F,0x0A,0x12,0x11,0x21,0x40,0x81,0x06,0x18,0x60, + 0x00,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x20,0x40,0x80,0x40,0x20,0x18,0x06, + /* 0xD3D2 [?] [4750]*/ + 0x02,0x02,0x02,0xFF,0x04,0x04,0x08,0x08,0x1F,0x28,0x48,0x88,0x08,0x08,0x0F,0x08, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD3D3 [?] [4751]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x30,0x51,0x93,0x15,0x19,0x11,0x11,0x11,0x11,0x11, + 0x40,0x40,0x40,0x40,0xFE,0x80,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD3D4 [?] [4752]*/ + 0x0C,0xF0,0x10,0x54,0x39,0x11,0xFD,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xD3D5 [?] [4753]*/ + 0x00,0x47,0x20,0x20,0x0F,0x01,0xE2,0x2C,0x23,0x21,0x21,0x21,0x2A,0x32,0x24,0x08, + 0x1C,0xE0,0x40,0x40,0xFE,0x50,0x48,0x46,0xF0,0x10,0x20,0x7C,0x04,0x04,0x28,0x10, + /* 0xD3D6 [?] [4754]*/ + 0x00,0x3F,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0xF0,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xD3D7 [?] [4755]*/ + 0x10,0x10,0x20,0x20,0x45,0x44,0xF8,0x08,0x10,0x10,0x28,0x44,0xFD,0x45,0x02,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xD3D8 [?] [4756]*/ + 0x00,0x23,0x10,0x10,0x00,0x00,0xF7,0x10,0x10,0x10,0x10,0x10,0x11,0x28,0x47,0x00, + 0x00,0xF8,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0xFE,0x00, + /* 0xD3D9 [?] [4757]*/ + 0x02,0x41,0x20,0x2F,0x04,0x84,0x44,0x57,0x14,0x24,0xE4,0x24,0x24,0x28,0x2A,0x11, + 0x10,0x10,0x10,0xA8,0x28,0x44,0x02,0x90,0x88,0x88,0x80,0xA0,0x90,0x88,0x88,0x00, + /* 0xD3DA [?] [4758]*/ + 0x00,0x3F,0x01,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD3DB [?] [4759]*/ + 0x00,0x3F,0x01,0x01,0xFF,0x01,0x01,0x05,0x02,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xD3DC [?] [4760]*/ + 0x10,0x10,0x11,0x12,0xFD,0x10,0x33,0x3A,0x56,0x53,0x92,0x12,0x13,0x12,0x12,0x12, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xD3DD [?] [4761]*/ + 0x01,0x01,0x01,0x3F,0x21,0x2F,0x21,0x27,0x24,0x27,0x20,0x2F,0x20,0x5F,0x42,0x9C, + 0x00,0xF8,0x00,0xFC,0x04,0xE0,0x08,0xF8,0x10,0xF0,0x00,0xF8,0x80,0xFC,0x20,0x1C, + /* 0xD3DE [?] [4762]*/ + 0x1F,0x11,0x1F,0x11,0x1F,0x01,0x3F,0x21,0x21,0x2F,0x24,0x20,0x01,0x48,0x48,0x87, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x48,0xE8,0x28,0x10,0x00,0x84,0x12,0xF2, + /* 0xD3DF [?] [4763]*/ + 0x11,0x61,0x47,0x42,0x75,0x47,0x41,0x77,0x41,0x41,0xFF,0x00,0x08,0x10,0x20,0x40, + 0x00,0x1C,0xC4,0x04,0x1C,0xC4,0x04,0xDC,0x04,0x04,0xFE,0x00,0x20,0x10,0x08,0x04, + /* 0xD3E0 [?] [4764]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x2F,0xC1,0x01,0x3F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0x80,0x40,0x20,0x10,0xE8,0x06,0x00,0xF8,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xD3E1 [?] [4765]*/ + 0x01,0x02,0x04,0x08,0x30,0xCF,0x00,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x22,0x2A,0x24, + 0x00,0x80,0x40,0x20,0x18,0xE6,0x00,0x08,0x48,0x48,0x48,0x48,0x48,0x08,0x28,0x10, + /* 0xD3E2 [?] [4766]*/ + 0x00,0x40,0x21,0x22,0x0D,0x00,0xE7,0x24,0x27,0x24,0x27,0x24,0x24,0x25,0x50,0x8F, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0x84,0xA4,0xA4,0xA4,0xA4,0x84,0x94,0x88,0x00,0xFE, + /* 0xD3E3 [?] [4767]*/ + 0x04,0x04,0x0F,0x10,0x20,0x7F,0xA1,0x21,0x3F,0x21,0x21,0x3F,0x00,0x00,0xFF,0x00, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFE,0x00, + /* 0xD3E4 [?] [4768]*/ + 0x10,0x10,0x11,0x12,0x1D,0x54,0x53,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x12,0x12, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xD3E5 [?] [4769]*/ + 0x00,0x20,0x11,0x12,0x85,0x48,0x47,0x14,0x14,0x27,0xE4,0x24,0x27,0x24,0x25,0x04, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0x88, + /* 0xD3E6 [?] [4770]*/ + 0x01,0x41,0x23,0x22,0x04,0x8F,0x54,0x54,0x17,0x24,0xE4,0x27,0x20,0x20,0x2F,0x00, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x00,0x00,0xFE,0x00, + /* 0xD3E7 [?] [4771]*/ + 0x01,0x79,0x49,0x49,0x51,0x51,0x61,0x50,0x48,0x4B,0x4A,0x6A,0x52,0x42,0x42,0x42, + 0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x22,0x2A,0xFA,0x0A,0x02,0x06, + /* 0xD3E8 [?] [4772]*/ + 0x00,0x1F,0x00,0x02,0x01,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01, + 0x00,0xF0,0x10,0x20,0x40,0x80,0xFE,0x82,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + /* 0xD3E9 [?] [4773]*/ + 0x20,0x23,0x22,0x22,0xFB,0x48,0x48,0x4B,0x88,0x48,0x37,0x10,0x28,0x49,0x82,0x04, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xD3EA [?] [4774]*/ + 0x00,0xFF,0x01,0x01,0x01,0x7F,0x41,0x41,0x49,0x45,0x41,0x49,0x45,0x41,0x41,0x40, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x44,0x24,0x04,0x44,0x24,0x04,0x14,0x08, + /* 0xD3EB [?] [4775]*/ + 0x10,0x10,0x10,0x1F,0x10,0x20,0x20,0x3F,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xC8,0x08,0x08,0x50,0x20, + /* 0xD3EC [?] [4776]*/ + 0x10,0x10,0x10,0x10,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5D,0x64,0x00,0x00,0x00, + 0x40,0x40,0x40,0x7E,0x40,0x80,0x80,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xD3ED [?] [4777]*/ + 0x00,0x00,0x3F,0x01,0x1F,0x11,0x11,0x1F,0x01,0x7F,0x41,0x41,0x5F,0x48,0x40,0x40, + 0x10,0xF8,0x00,0x00,0xF0,0x10,0x10,0xF0,0x00,0xFC,0x04,0x24,0xF4,0x14,0x04,0x0C, + /* 0xD3EE [?] [4778]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD3EF [?] [4779]*/ + 0x00,0x47,0x20,0x20,0x03,0x00,0xE0,0x27,0x20,0x20,0x23,0x22,0x2A,0x32,0x23,0x02, + 0x00,0xFC,0x40,0x40,0xF8,0x88,0x88,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xD3F0 [?] [4780]*/ + 0x00,0x7E,0x02,0x02,0x22,0x12,0x12,0x02,0x0A,0x12,0x62,0x22,0x02,0x02,0x14,0x08, + 0x00,0xFC,0x04,0x04,0x44,0x24,0x24,0x04,0x14,0x24,0xC4,0x44,0x04,0x04,0x28,0x10, + /* 0xD3F1 [?] [4781]*/ + 0x00,0x7F,0x01,0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x20,0x10,0x10,0x00,0xFE,0x00, + /* 0xD3F2 [?] [4782]*/ + 0x20,0x20,0x20,0x27,0x20,0xF8,0x23,0x22,0x22,0x22,0x23,0x38,0xE0,0x47,0x02,0x00, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD2,0x52,0x52,0x54,0xD4,0x08,0xEA,0x1A,0x26,0x42, + /* 0xD3F3 [?] [4783]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x05,0x02, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD3F4 [?] [4784]*/ + 0x08,0x08,0xFF,0x10,0x10,0x3F,0x21,0x61,0xBF,0x21,0x21,0x3F,0x21,0x21,0x25,0x22, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xD3F5 [?] [4785]*/ + 0x00,0x01,0x78,0x48,0x48,0x48,0x48,0x4B,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xD3F6 [?] [4786]*/ + 0x00,0x23,0x12,0x13,0x02,0x03,0xF0,0x17,0x14,0x14,0x14,0x15,0x14,0x14,0x28,0x47, + 0x00,0xF8,0x48,0xF8,0x48,0xF8,0x40,0xFC,0x44,0x54,0x74,0x94,0x04,0x0C,0x00,0xFE, + /* 0xD3F7 [?] [4787]*/ + 0x00,0x00,0x79,0x4A,0x4D,0x48,0x4B,0x4A,0x4A,0x4B,0x7A,0x4A,0x03,0x02,0x02,0x02, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xD3F8 [?] [4788]*/ + 0x10,0x10,0x10,0x10,0x55,0x54,0x54,0x54,0x55,0x56,0x54,0x5C,0x64,0x00,0x00,0x00, + 0x00,0x50,0x48,0x84,0x24,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xD3F9 [?] [4789]*/ + 0x14,0x14,0x27,0x49,0x91,0x11,0x2F,0x61,0xA1,0x25,0x25,0x25,0x25,0x3E,0x28,0x20, + 0x00,0x00,0xDE,0x12,0x12,0x12,0xD2,0x12,0x12,0xD2,0x12,0x1A,0xD4,0x10,0x10,0x10, + /* 0xD3FA [?] [4790]*/ + 0x01,0x02,0x0C,0x37,0xC0,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x26,0x01,0x48,0x48,0x87, + 0x00,0x80,0x60,0xD8,0x06,0x08,0x48,0x48,0x48,0x48,0x08,0x18,0x00,0x84,0x12,0xF2, + /* 0xD3FB [?] [4791]*/ + 0x14,0x12,0x21,0x49,0x08,0x14,0x22,0x41,0xBE,0x22,0x22,0x22,0x22,0x3E,0x22,0x01, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xD3FC [?] [4792]*/ + 0x00,0x94,0x52,0x22,0x50,0x9E,0x12,0x12,0x32,0x52,0x92,0x13,0x12,0x10,0xA1,0x42, + 0x20,0x28,0x24,0x24,0x20,0x20,0xFC,0x20,0x20,0x50,0xD0,0x50,0x88,0x88,0x04,0x02, + /* 0xD3FD [?] [4793]*/ + 0x02,0x01,0xFF,0x08,0x10,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x00,0x10,0xF8,0x08,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xD3FE [?] [4794]*/ + 0x22,0x11,0x11,0x00,0xFF,0x08,0x11,0x2F,0xC0,0x1F,0x00,0x1F,0x00,0x1F,0x10,0x1F, + 0x08,0x08,0x10,0x20,0xFE,0x20,0x10,0xE8,0x06,0xF0,0x00,0xF0,0x00,0xF0,0x10,0xF0, + /* 0xD4A1 [?] [4795]*/ + 0x01,0x21,0x12,0x14,0x80,0x40,0x41,0x12,0x14,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x10,0x08,0x04,0x44,0x40,0xA0,0x10,0x08,0x06,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD4A2 [?] [4796]*/ + 0x02,0x01,0x7F,0x40,0x9F,0x11,0x1F,0x11,0x1F,0x01,0x3F,0x21,0x21,0x2F,0x24,0x20, + 0x00,0x00,0xFE,0x02,0xF4,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x48,0xE8,0x28,0x10, + /* 0xD4A3 [?] [4797]*/ + 0x20,0x10,0x00,0xFC,0x09,0x10,0x10,0x34,0x59,0x94,0x14,0x10,0x10,0x10,0x10,0x10, + 0x00,0x50,0x48,0x84,0x24,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xD4A4 [?] [4798]*/ + 0x00,0xF9,0x08,0x50,0x21,0x11,0xFD,0x25,0x29,0x21,0x21,0x21,0x20,0x20,0xA1,0x42, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xD4A5 [?] [4799]*/ + 0x00,0xF8,0x09,0x53,0x25,0x11,0xFD,0x24,0x28,0x23,0x20,0x23,0x20,0x20,0xA3,0x40, + 0x80,0xF8,0x08,0xFE,0x12,0x22,0xFE,0x40,0xA2,0x54,0x98,0x34,0x54,0x92,0x50,0x20, + /* 0xD4A6 [?] [4800]*/ + 0x00,0x7C,0x05,0x24,0x24,0x24,0x24,0x3E,0x02,0x02,0x1A,0xE2,0x42,0x02,0x15,0x0A, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xD4A7 [?] [4801]*/ + 0x10,0x3E,0x42,0xA2,0x14,0x18,0xE2,0x1F,0x14,0x12,0x10,0x1F,0x00,0x7F,0x00,0x00, + 0x00,0xF8,0x88,0xAA,0x92,0x7E,0x00,0xE0,0x20,0x60,0x00,0xF8,0x08,0x88,0x28,0x10, + /* 0xD4A8 [?] [4802]*/ + 0x04,0x24,0x16,0x15,0x85,0x44,0x47,0x14,0x14,0x24,0xE5,0x25,0x26,0x28,0x28,0x10, + 0x44,0x44,0x54,0x54,0x64,0x44,0xFC,0x44,0xC4,0xE4,0x54,0x54,0x44,0x44,0x44,0x44, + /* 0xD4A9 [?] [4803]*/ + 0x00,0x7F,0x40,0x88,0x0F,0x10,0x20,0x5F,0x11,0x11,0x1F,0x02,0x04,0x08,0x10,0x60, + 0x00,0xFE,0x02,0x04,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x80,0xA0,0x92,0x82,0x7E, + /* 0xD4AA [?] [4804]*/ + 0x00,0x3F,0x00,0x00,0x00,0xFF,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x00,0xF8,0x00,0x00,0x00,0xFE,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xD4AB [?] [4805]*/ + 0x10,0x13,0x10,0x10,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE0,0x40,0x03,0x00, + 0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xD4AC [?] [4806]*/ + 0x01,0x01,0x3F,0x01,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x05,0x08,0x38,0xCA,0x0C,0x08, + 0x00,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x04,0x88,0x50,0x20,0x18,0x06, + /* 0xD4AD [?] [4807]*/ + 0x00,0x3F,0x20,0x21,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x20,0x24,0x48,0x52,0x81, + 0x00,0xFE,0x80,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x80,0x90,0x88,0x84,0x00, + /* 0xD4AE [?] [4808]*/ + 0x20,0x27,0x22,0x21,0xF8,0x23,0x20,0x28,0x37,0xE1,0x21,0x22,0x22,0x24,0xA8,0x43, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xD4AF [?] [4809]*/ + 0x20,0x20,0x21,0xFC,0x43,0x50,0x91,0xFD,0x11,0x11,0x1C,0xF0,0x51,0x16,0x10,0x10, + 0x20,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x52,0x94,0x88,0xA4,0xC2,0x80, + /* 0xD4B0 [?] [4810]*/ + 0x00,0x7F,0x40,0x4F,0x40,0x40,0x5F,0x44,0x44,0x44,0x48,0x48,0x50,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0xE4,0x04,0x04,0xF4,0x84,0x84,0x84,0x94,0x94,0x74,0x04,0xFC,0x04, + /* 0xD4B1 [?] [4811]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x20,0x20,0x21,0x21,0x21,0x02,0x04,0x18,0xE0, + 0x00,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xC0,0x30,0x08,0x04, + /* 0xD4B2 [?] [4812]*/ + 0x00,0x7F,0x40,0x4F,0x48,0x4F,0x40,0x5F,0x50,0x51,0x51,0x52,0x44,0x48,0x7F,0x40, + 0x00,0xFC,0x04,0xE4,0x24,0xE4,0x04,0xF4,0x14,0x14,0x14,0x94,0x44,0x24,0xFC,0x04, + /* 0xD4B3 [?] [4813]*/ + 0x00,0x90,0x53,0x20,0x57,0x90,0x13,0x12,0x32,0x53,0x90,0x11,0x13,0x1D,0xA1,0x41, + 0x40,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x08,0xF8,0xA4,0x28,0x10,0x48,0x86,0x00, + /* 0xD4B4 [?] [4814]*/ + 0x00,0x27,0x14,0x14,0x85,0x45,0x45,0x15,0x15,0x25,0xE4,0x24,0x29,0x2A,0x30,0x00, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xD4B5 [?] [4815]*/ + 0x10,0x10,0x21,0x21,0x48,0xFB,0x10,0x20,0x43,0xF8,0x40,0x03,0x18,0xE0,0x43,0x00, + 0x80,0xFC,0x04,0xF8,0x08,0xFE,0x40,0xA2,0x34,0x58,0x94,0x34,0x52,0x90,0x50,0x20, + /* 0xD4B6 [?] [4816]*/ + 0x00,0x23,0x10,0x10,0x00,0x07,0xF1,0x11,0x11,0x11,0x11,0x12,0x12,0x14,0x28,0x47, + 0x00,0xF8,0x00,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x1C,0x00,0xFE, + /* 0xD4B7 [?] [4817]*/ + 0x04,0x04,0xFF,0x04,0x10,0x1E,0x12,0x22,0x22,0x52,0x8C,0x04,0x08,0x10,0x20,0x40, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x88,0x88,0x88,0xA8,0x90,0x82,0x82,0x82,0x7E,0x00, + /* 0xD4B8 [?] [4818]*/ + 0x00,0x3F,0x20,0x27,0x24,0x27,0x24,0x27,0x22,0x24,0x29,0x20,0x20,0x4A,0x4A,0x91, + 0x00,0xFE,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x50,0x48,0x44,0x80,0x44,0x42,0x12,0xF0, + /* 0xD4B9 [?] [4819]*/ + 0x10,0x10,0x3E,0x42,0xA2,0x14,0x08,0x10,0x20,0xC0,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xF8,0x88,0x88,0xA8,0x90,0x84,0x84,0x7C,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xD4BA [?] [4820]*/ + 0x00,0x78,0x4B,0x52,0x54,0x61,0x50,0x48,0x4B,0x48,0x68,0x50,0x41,0x41,0x42,0x44, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xD4BB [?] [4821]*/ + 0x00,0x00,0x7F,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x7F,0x40,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xE4,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x00, + /* 0xD4BC [?] [4822]*/ + 0x10,0x10,0x20,0x24,0x45,0xFA,0x10,0x21,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xD4BD [?] [4823]*/ + 0x10,0x10,0x10,0x7D,0x11,0x11,0xFD,0x11,0x11,0x51,0x5D,0x51,0x70,0x50,0x4F,0x80, + 0x28,0x24,0x20,0xFC,0x20,0x24,0x24,0x28,0x28,0x10,0x94,0x2C,0x44,0x00,0xFE,0x00, + /* 0xD4BE [?] [4824]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7C,0x13,0x10,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x01,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFE,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xD4BF [?] [4825]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x04,0x04,0x14,0x08, + /* 0xD4C0 [?] [4826]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0xFF,0x01,0x01,0x21,0x21,0x21,0x3F,0x00, + 0x70,0x80,0x00,0x00,0xF8,0x80,0x80,0x80,0xFE,0x00,0x00,0x08,0x08,0x08,0xF8,0x08, + /* 0xD4C1 [?] [4827]*/ + 0x02,0x3F,0x29,0x25,0x2F,0x23,0x25,0x29,0x3F,0x00,0xFF,0x10,0x1F,0x00,0x00,0x00, + 0x00,0xF8,0x28,0x48,0xE8,0x88,0x48,0x28,0xF8,0x00,0xFE,0x00,0xF8,0x08,0x50,0x20, + /* 0xD4C2 [?] [4828]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x20,0x20,0x40,0x80, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xD4C3 [?] [4829]*/ + 0x12,0x11,0x11,0x10,0x1B,0x56,0x52,0x52,0x93,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x08,0x08,0x10,0x20,0xF8,0x08,0x08,0x08,0xF8,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xD4C4 [?] [4830]*/ + 0x20,0x17,0x00,0x44,0x42,0x40,0x4F,0x48,0x48,0x4F,0x42,0x42,0x44,0x48,0x50,0x40, + 0x00,0xFC,0x04,0x44,0x84,0x04,0xE4,0x24,0x24,0xE4,0x84,0x84,0x84,0x94,0x74,0x08, + /* 0xD4C5 [?] [4831]*/ + 0x10,0x10,0x10,0xFE,0x10,0x7C,0x11,0xFE,0x10,0x38,0x34,0x54,0x50,0x91,0x10,0x10, + 0x00,0xFC,0x00,0x00,0x00,0x00,0xFE,0x20,0x20,0x40,0x48,0x84,0x84,0xFE,0x82,0x02, + /* 0xD4C6 [?] [4832]*/ + 0x00,0x3F,0x00,0x00,0x00,0x00,0xFF,0x02,0x04,0x04,0x08,0x10,0x20,0x7F,0x20,0x00, + 0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x40,0x20,0x10,0xF8,0x08,0x08, + /* 0xD4C7 [?] [4833]*/ + 0x00,0x3E,0x22,0x22,0x3E,0x00,0x7F,0x41,0x49,0x49,0x49,0x49,0x14,0x12,0x21,0xC1, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xD4C8 [?] [4834]*/ + 0x08,0x08,0x0F,0x10,0x20,0x48,0x84,0x02,0x00,0x00,0x03,0x1C,0x08,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x24,0xC4,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xD4C9 [?] [4835]*/ + 0x00,0x7C,0x44,0x48,0x48,0x50,0x49,0x49,0x45,0x45,0x45,0x69,0x50,0x40,0x40,0x43, + 0x00,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xD4CA [?] [4836]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x3F,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x00,0x00,0x40,0x20,0x10,0xF8,0x48,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E, + /* 0xD4CB [?] [4837]*/ + 0x00,0x23,0x10,0x10,0x00,0x07,0xF0,0x10,0x11,0x12,0x17,0x12,0x10,0x28,0x47,0x00, + 0x00,0xF8,0x00,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xD4CC [?] [4838]*/ + 0x04,0x04,0xFF,0x04,0x21,0x21,0x45,0x89,0xF1,0x20,0x43,0xFA,0x02,0x1A,0xE7,0x40, + 0x40,0x40,0xFE,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0x94,0x94,0xFE,0x00, + /* 0xD4CD [?] [4839]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x00,0x7C,0x00,0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x44,0x42,0xFE,0x42,0x00, + /* 0xD4CE [?] [4840]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x00,0x7F,0x42,0x9F,0x04,0x09,0x1F,0x01,0x7F,0x01,0x01, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0x00,0xF0,0x00,0xFC,0x00,0x00, + /* 0xD4CF [?] [4841]*/ + 0x20,0x10,0x7C,0x00,0x45,0x2A,0xFE,0x00,0x7C,0x44,0x44,0x7C,0x45,0x44,0x7C,0x44, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x84,0x44,0x44,0x14,0x24,0x44,0x84,0x04,0x28,0x10, + /* 0xD4D0 [?] [4842]*/ + 0x00,0x3F,0x08,0x08,0x08,0x10,0x17,0x20,0x40,0x01,0xFF,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF0,0x10,0x20,0x3C,0x04,0xC4,0x54,0x88,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xD4D1 [?] [4843]*/ + 0x00,0x7F,0x40,0x40,0x40,0x4F,0x48,0x48,0x48,0x48,0x48,0x48,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x80,0x80,0x80,0xF8,0x88,0x88,0x88,0x88,0xA8,0x90,0x80,0x80,0xFE,0x00, + /* 0xD4D2 [?] [4844]*/ + 0x00,0x03,0xFA,0x22,0x22,0x42,0x7A,0x4A,0xCA,0x4A,0x4A,0x4A,0x7A,0x4A,0x03,0x00, + 0x00,0xFE,0x10,0x10,0x10,0xFE,0x92,0x92,0x92,0x92,0x9A,0x94,0x10,0x10,0xFE,0x00, + /* 0xD4D3 [?] [4845]*/ + 0x02,0x02,0x3F,0x04,0x04,0x08,0x11,0x61,0x01,0xFF,0x01,0x09,0x11,0x21,0x45,0x02, + 0x00,0x00,0xE0,0x20,0x22,0x22,0x1E,0x00,0x00,0xFE,0x00,0x20,0x10,0x08,0x04,0x00, + /* 0xD4D4 [?] [4846]*/ + 0x08,0x08,0x7F,0x08,0x08,0xFF,0x00,0x08,0x08,0xFF,0x18,0x2C,0x2A,0x49,0x88,0x08, + 0x40,0x48,0x44,0x44,0x40,0xFE,0x40,0x44,0x44,0x44,0x28,0x2A,0x12,0x2A,0x46,0x82, + /* 0xD4D5 [?] [4847]*/ + 0x08,0x08,0x08,0x7F,0x08,0x08,0xFF,0x00,0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x00, + 0x40,0x48,0x44,0x44,0x40,0x40,0xFE,0x40,0x44,0x44,0x28,0x2A,0x12,0x2A,0x46,0x82, + /* 0xD4D6 [?] [4848]*/ + 0x02,0x01,0x7F,0x40,0x81,0x01,0x11,0x11,0x11,0x21,0x02,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFE,0x02,0x04,0x00,0x08,0x08,0x10,0x20,0x80,0x80,0x40,0x20,0x18,0x06, + /* 0xD4D7 [?] [4849]*/ + 0x02,0x01,0x7F,0x42,0x81,0x3F,0x00,0x08,0x04,0xFF,0x01,0x01,0x7F,0x01,0x01,0x01, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0x20,0x40,0xFE,0x00,0x00,0xFC,0x00,0x00,0x00, + /* 0xD4D8 [?] [4850]*/ + 0x08,0x08,0x7F,0x08,0xFF,0x10,0x10,0xFF,0x20,0x48,0x7F,0x08,0x0F,0xF8,0x08,0x08, + 0x20,0x28,0x24,0x20,0xFE,0x20,0x24,0x24,0x24,0x28,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xD4D9 [?] [4851]*/ + 0x00,0xFF,0x01,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0xFF,0x20,0x20,0x20,0x20,0x20, + 0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x08,0x08,0x08,0x28,0x10, + /* 0xD4DA [?] [4852]*/ + 0x02,0x02,0x04,0xFF,0x08,0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0xFE,0x00,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xD4DB [?] [4853]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01, + 0x20,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xD4DC [?] [4854]*/ + 0x21,0x25,0x27,0x29,0xF7,0x23,0x25,0x29,0x30,0xE3,0x22,0x22,0x22,0x20,0xA1,0x46, + 0x08,0x28,0xBE,0x48,0xBE,0x18,0xAA,0x46,0x00,0xF8,0x08,0x48,0x48,0xB0,0x08,0x04, + /* 0xD4DD [?] [4855]*/ + 0x10,0xFE,0x20,0x48,0x7E,0x08,0x0E,0xF9,0x4A,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0xF8,0x10,0x10,0xF0,0x10,0x10,0xF0, + /* 0xD4DE [?] [4856]*/ + 0x08,0x28,0x3E,0x48,0x7E,0x14,0x25,0x46,0x81,0x1F,0x10,0x11,0x11,0x02,0x0C,0x30, + 0x10,0x50,0x7C,0x90,0xFE,0x28,0x48,0x8A,0x06,0xF0,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xD4DF [?] [4857]*/ + 0x00,0x7C,0x44,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x29,0x26,0x42,0x84, + 0x20,0x10,0x10,0xFE,0x00,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xD4E0 [?] [4858]*/ + 0x00,0x78,0x48,0x49,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x4A,0x4A,0x9C, + 0x20,0x10,0x10,0xFE,0x00,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xD4E1 [?] [4859]*/ + 0x08,0xFF,0x08,0xFF,0x10,0x3E,0x42,0x24,0x18,0xE0,0x08,0x08,0xFF,0x08,0x10,0x20, + 0x20,0xFE,0x20,0xFE,0x80,0x98,0xE0,0x84,0x84,0x7C,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xD4E2 [?] [4860]*/ + 0x00,0x2F,0x10,0x17,0x04,0x07,0xF4,0x17,0x10,0x13,0x12,0x13,0x12,0x13,0x28,0x47, + 0xA0,0xFE,0xA0,0xFC,0xA4,0xFC,0xA4,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xD4E3 [?] [4861]*/ + 0x20,0x20,0x27,0xA8,0x73,0x22,0xFB,0x22,0x73,0x68,0xA9,0x21,0x21,0x21,0x21,0x21, + 0x90,0x90,0xFE,0x90,0xFC,0x94,0xFC,0x94,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xD4E4 [?] [4862]*/ + 0x04,0x24,0x14,0x04,0xFF,0x00,0x04,0x22,0x2F,0x21,0x21,0x2F,0x21,0x21,0x3F,0x00, + 0x40,0x48,0x50,0x40,0xFE,0x00,0x40,0x88,0xE8,0x08,0x08,0xE8,0x08,0x08,0xF8,0x08, + /* 0xD4E5 [?] [4863]*/ + 0x08,0xFF,0x08,0x23,0x12,0x13,0x80,0x47,0x54,0x17,0x20,0xEF,0x21,0x22,0x2C,0x20, + 0x20,0xFE,0x20,0xF8,0x08,0xF8,0x00,0xBC,0xA4,0xBC,0x40,0xFE,0x50,0x48,0x46,0x40, + /* 0xD4E6 [?] [4864]*/ + 0x01,0x01,0xFF,0x01,0x3F,0x21,0x23,0x25,0x09,0x30,0xC6,0x01,0x00,0x0E,0x01,0x00, + 0x00,0x00,0xFE,0x00,0xF8,0x08,0x88,0x48,0x20,0x18,0x06,0x80,0x40,0x00,0x80,0x40, + /* 0xD4E7 [?] [4865]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xD4E8 [?] [4866]*/ + 0x03,0x42,0x22,0x23,0x00,0x87,0x44,0x54,0x17,0x20,0xEF,0x21,0x22,0x24,0x38,0x00, + 0xF8,0x08,0x08,0xF8,0x00,0xBC,0xA4,0xA4,0xBC,0x40,0xFE,0x60,0x50,0x48,0x46,0x40, + /* 0xD4E9 [?] [4867]*/ + 0x00,0x3F,0x12,0x09,0x04,0x03,0x1C,0xE1,0x1F,0x11,0x11,0x1F,0x11,0x01,0x7F,0x20, + 0x00,0xF0,0x10,0x20,0x40,0x80,0x70,0x0E,0xF0,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xD4EA [?] [4868]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7D,0x11,0x11,0x5D,0x50,0x53,0x50,0x5C,0xE1,0x02,0x00, + 0xF8,0x88,0x88,0xF8,0x00,0xDC,0x54,0x54,0xDC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xD4EB [?] [4869]*/ + 0x03,0x02,0xF2,0x93,0x90,0x97,0x94,0x94,0x97,0x90,0xFF,0x91,0x02,0x04,0x18,0x00, + 0xF8,0x08,0x08,0xF8,0x00,0xBC,0xA4,0xA4,0xBC,0x40,0xFE,0x60,0x50,0x48,0x46,0x40, + /* 0xD4EC [?] [4870]*/ + 0x00,0x22,0x13,0x14,0x00,0x07,0xF0,0x10,0x13,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0x40,0x40,0xF8,0x40,0x40,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xD4ED [?] [4871]*/ + 0x01,0x02,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x02,0x02,0x03,0xFE,0x02,0x02,0x01, + 0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xFC,0x00,0x04,0x04,0xFC, + /* 0xD4EE [?] [4872]*/ + 0x10,0x10,0x10,0x10,0x54,0x58,0x51,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x43,0x80, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD4EF [?] [4873]*/ + 0x10,0x10,0x10,0x14,0x58,0x51,0x51,0x91,0x11,0x10,0x13,0x28,0x24,0x41,0x42,0x80, + 0xF8,0x88,0x88,0xF8,0x00,0xDC,0x54,0x54,0xDC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xD4F0 [?] [4874]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x01,0xFF,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xD4F1 [?] [4875]*/ + 0x20,0x27,0x22,0x21,0xF0,0x20,0x21,0x26,0x30,0xE3,0x20,0x20,0x27,0x20,0xA0,0x40, + 0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x4E,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40, + /* 0xD4F2 [?] [4876]*/ + 0x00,0x7F,0x41,0x41,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x14,0x12,0x21,0x40,0x80, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x94,0x88, + /* 0xD4F3 [?] [4877]*/ + 0x00,0x27,0x12,0x11,0x80,0x40,0x41,0x16,0x10,0x23,0xE0,0x20,0x27,0x20,0x20,0x00, + 0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x4E,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40, + /* 0xD4F4 [?] [4878]*/ + 0x00,0x7C,0x44,0x45,0x54,0x54,0x54,0x54,0x57,0x54,0x54,0x10,0x28,0x25,0x41,0x82, + 0x14,0x12,0x10,0xFE,0x10,0x90,0x92,0x92,0xF2,0x94,0x94,0x88,0x8A,0x1A,0x26,0x42, + /* 0xD4F5 [?] [4879]*/ + 0x08,0x08,0x0F,0x14,0x24,0x47,0x04,0x04,0x07,0x04,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0x00,0xFC,0x00,0x00,0xF0,0x00,0x00,0xF8,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xD4F6 [?] [4880]*/ + 0x22,0x21,0x20,0x27,0x24,0xFD,0x24,0x24,0x27,0x20,0x23,0x3A,0xE3,0x42,0x03,0x02, + 0x08,0x10,0x00,0xFC,0x44,0x54,0xE4,0x44,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xD4F7 [?] [4881]*/ + 0x11,0x10,0x10,0x13,0x1A,0x56,0x52,0x52,0x93,0x10,0x11,0x11,0x11,0x11,0x11,0x11, + 0x04,0x88,0x00,0xFE,0x22,0xAA,0x72,0x22,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xD4F8 [?] [4882]*/ + 0x08,0x04,0x3F,0x21,0x29,0x25,0x3F,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x40,0xF8,0x08,0x28,0x48,0xF8,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xD4F9 [?] [4883]*/ + 0x00,0x7C,0x44,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x54,0x10,0x28,0x24,0x44,0x80, + 0x88,0x48,0x50,0xFC,0x24,0xAC,0x74,0x24,0xFC,0x00,0xF8,0x88,0xF8,0x88,0xF8,0x88, + /* 0xD4FA [?] [4884]*/ + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x12,0x1C,0x30,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xD4FB [?] [4885]*/ + 0x00,0x00,0xF7,0x90,0x91,0x92,0x94,0x93,0x92,0x93,0xF2,0x93,0x02,0x00,0x0F,0x00, + 0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xD4FC [?] [4886]*/ + 0x00,0x20,0x17,0x10,0x81,0x42,0x44,0x13,0x12,0x23,0xE2,0x23,0x22,0x20,0x2F,0x00, + 0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xD4FD [?] [4887]*/ + 0x08,0x08,0x08,0x08,0xFE,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08,0x08,0x08, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xD4FE [?] [4888]*/ + 0x10,0x10,0x10,0xFE,0x20,0x28,0x48,0x7E,0x08,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xD5A1 [?] [4889]*/ + 0x20,0x23,0x3A,0x22,0x42,0x7A,0xA2,0x22,0xFA,0x22,0x22,0x20,0x29,0x31,0x22,0x04, + 0x02,0xE2,0x22,0x2A,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x82,0x42,0x22,0x0A,0x04, + /* 0xD5A2 [?] [4890]*/ + 0x20,0x17,0x00,0x40,0x4F,0x49,0x49,0x4F,0x49,0x49,0x4F,0x49,0x41,0x41,0x41,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x24,0x04,0x04,0x14,0x08, + /* 0xD5A3 [?] [4891]*/ + 0x00,0x00,0x7B,0x48,0x48,0x78,0x4B,0x48,0x78,0x48,0x48,0x48,0x79,0x4A,0x04,0x00, + 0x08,0x3C,0xC0,0x00,0x40,0x20,0xFC,0x08,0x10,0x20,0x40,0x80,0x00,0x80,0x7E,0x00, + /* 0xD5A4 [?] [4892]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x3B,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14, + 0x00,0xDC,0x54,0x54,0x54,0x54,0x54,0xFE,0x54,0x54,0x54,0x54,0x54,0xD4,0x24,0x4C, + /* 0xD5A5 [?] [4893]*/ + 0x10,0x10,0x13,0x12,0xFD,0x10,0x30,0x39,0x56,0x50,0x90,0x10,0x10,0x10,0x10,0x10, + 0x40,0x20,0xFE,0x8A,0x04,0x80,0xFE,0x40,0x40,0x7C,0x40,0x40,0x7E,0x40,0x40,0x40, + /* 0xD5A6 [?] [4894]*/ + 0x01,0x01,0x79,0x49,0x4A,0x4A,0x4C,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80, + /* 0xD5A7 [?] [4895]*/ + 0x08,0x08,0x0F,0x12,0x12,0x22,0x43,0x82,0x02,0x02,0x03,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00, + /* 0xD5A8 [?] [4896]*/ + 0x11,0x11,0x11,0x15,0x5A,0x52,0x54,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x40,0x80, + 0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80, + /* 0xD5A9 [?] [4897]*/ + 0x01,0x21,0x11,0x11,0x02,0x02,0xF4,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80, + /* 0xD5AA [?] [4898]*/ + 0x20,0x20,0x27,0x21,0xF8,0x27,0x24,0x2D,0x34,0xE5,0x25,0x25,0x25,0x24,0xA4,0x44, + 0x80,0x40,0xFC,0x10,0xA0,0xFC,0x44,0xF4,0x44,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xD5AB [?] [4899]*/ + 0x02,0x01,0x7F,0x08,0x04,0x03,0x1C,0xE0,0x1F,0x02,0x04,0x3F,0x24,0x24,0x24,0x20, + 0x00,0x00,0xFC,0x20,0x40,0x80,0x70,0x0E,0xF0,0x00,0x00,0xF8,0x88,0x88,0xA8,0x10, + /* 0xD5AC [?] [4900]*/ + 0x02,0x01,0x7F,0x40,0x80,0x00,0x03,0x3E,0x02,0x03,0xFE,0x02,0x02,0x02,0x01,0x00, + 0x00,0x00,0xFE,0x02,0x04,0x20,0xF0,0x00,0x00,0xFC,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xD5AD [?] [4901]*/ + 0x02,0x01,0x7F,0x48,0x90,0x28,0x0F,0x14,0x24,0x47,0x04,0x04,0x07,0x04,0x04,0x04, + 0x00,0x00,0xFE,0x22,0x14,0x08,0xF8,0x00,0x00,0xF0,0x00,0x00,0xF8,0x00,0x00,0x00, + /* 0xD5AE [?] [4902]*/ + 0x08,0x08,0x0F,0x10,0x13,0x30,0x37,0x50,0x93,0x12,0x12,0x12,0x12,0x10,0x11,0x16, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0x48,0xA0,0x10,0x08, + /* 0xD5AF [?] [4903]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x11,0x2F,0xC1,0x09,0x11,0x25,0x02, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0x10,0xE8,0x06,0x20,0x10,0x08,0x00, + /* 0xD5B0 [?] [4904]*/ + 0x01,0x01,0x7A,0x4F,0x4A,0x7B,0x4B,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x4C,0x04,0x08, + 0x00,0xF8,0x08,0xFE,0x88,0x24,0xFE,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x84,0xFC,0x84, + /* 0xD5B1 [?] [4905]*/ + 0x08,0x1C,0x70,0x10,0x10,0x1C,0x70,0x11,0x11,0x1D,0xF1,0x11,0x11,0x10,0x0F,0x00, + 0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xF8,0x08,0x08,0x08,0xFA,0x0A,0x02,0xFE,0x00, + /* 0xD5B2 [?] [4906]*/ + 0x08,0x0F,0x10,0x3F,0x65,0xA8,0x3F,0x20,0x27,0x20,0x27,0x20,0x27,0x44,0x47,0x84, + 0x00,0xF0,0x20,0xFE,0x08,0x84,0xFE,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x08, + /* 0xD5B3 [?] [4907]*/ + 0x10,0x10,0x94,0x54,0x58,0x10,0xFC,0x30,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5B4 [?] [4908]*/ + 0x00,0x20,0x10,0x10,0x80,0x40,0x48,0x08,0x13,0x12,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5B5 [?] [4909]*/ + 0x02,0x02,0x03,0x7E,0x03,0xFE,0x01,0x03,0x1C,0xE0,0x00,0x3F,0x24,0x24,0x24,0xFF, + 0x40,0x20,0xF8,0x00,0xFC,0x10,0x60,0x82,0x62,0x1E,0x00,0xF8,0x48,0x48,0x48,0xFE, + /* 0xD5B6 [?] [4910]*/ + 0x20,0x20,0x21,0xFD,0x41,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD5B7 [?] [4911]*/ + 0x20,0x23,0x22,0xFA,0x43,0x52,0x92,0xFE,0x12,0x12,0x1F,0xF2,0x52,0x14,0x14,0x18, + 0x00,0xFC,0x04,0x04,0xFC,0x48,0x48,0xFC,0x48,0x48,0xFE,0xA4,0xA8,0x90,0xC8,0x86, + /* 0xD5B8 [?] [4912]*/ + 0x01,0x21,0x21,0x3F,0x10,0x10,0xFE,0x20,0x48,0x7E,0x08,0x0E,0xF8,0x49,0x09,0x0A, + 0x00,0x08,0x08,0xF8,0x00,0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xD5B9 [?] [4913]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x22,0x22,0x2F,0x22,0x22,0x3F,0x24,0x24,0x45,0x46,0x84, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xF8,0x20,0x20,0xFE,0x88,0x50,0x30,0x0E,0x00, + /* 0xD5BA [?] [4914]*/ + 0x08,0xFF,0x08,0x00,0xFE,0x10,0x11,0x7C,0x54,0x54,0x6C,0x44,0x7C,0x45,0x7D,0x46, + 0x20,0xFE,0x20,0x50,0x48,0xFE,0x90,0xFC,0x90,0xFC,0x90,0xFE,0x80,0x54,0x2A,0x2A, + /* 0xD5BB [?] [4915]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x39,0x54,0x50,0x90,0x10,0x10,0x10,0x13,0x10, + 0x50,0x48,0x40,0x5C,0xE0,0x40,0x5E,0xE0,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02, + /* 0xD5BC [?] [4916]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x20,0x20,0x20,0x20,0x3F,0x20, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD5BD [?] [4917]*/ + 0x10,0x10,0x10,0x1E,0x10,0x10,0x11,0x10,0x7E,0x42,0x42,0x42,0x42,0x7E,0x42,0x01, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xD5BE [?] [4918]*/ + 0x10,0x08,0x08,0x7E,0x00,0x04,0x44,0x44,0x25,0x29,0x29,0x0F,0xF1,0x41,0x01,0x01, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5BF [?] [4919]*/ + 0x01,0x21,0x17,0x11,0x81,0x41,0x49,0x09,0x11,0x17,0xE2,0x22,0x23,0x22,0x23,0x00, + 0x08,0x08,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x50,0x88,0x04,0x00,0xFC,0x00, + /* 0xD5C0 [?] [4920]*/ + 0x10,0x10,0x23,0x22,0x4C,0xF8,0x13,0x20,0x40,0xF9,0x41,0x01,0x1A,0xE2,0x44,0x08, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xD5C1 [?] [4921]*/ + 0x10,0x11,0x10,0x10,0xFB,0x10,0x31,0x39,0x55,0x51,0x91,0x10,0x13,0x10,0x10,0x10, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xD5C2 [?] [4922]*/ + 0x02,0x01,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x01,0x01, + 0x00,0x00,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0x00, + /* 0xD5C3 [?] [4923]*/ + 0x10,0x08,0x7F,0x22,0x14,0xFF,0x00,0x7F,0x41,0x7F,0x41,0x7F,0x08,0xFF,0x08,0x08, + 0x00,0x04,0x04,0x08,0x10,0xA2,0x02,0x04,0x08,0x10,0x22,0x02,0x04,0x88,0x10,0x60, + /* 0xD5C4 [?] [4924]*/ + 0x00,0x27,0x11,0x10,0x8F,0x40,0x43,0x12,0x13,0x22,0xE3,0x20,0x2F,0x20,0x20,0x00, + 0x40,0xFC,0x10,0xA0,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFE,0x40,0x40,0x40, + /* 0xD5C5 [?] [4925]*/ + 0x01,0xF9,0x09,0x09,0x09,0x79,0x41,0x47,0x41,0x79,0x09,0x09,0x09,0x09,0x51,0x21, + 0x00,0x08,0x08,0x10,0x20,0x40,0x00,0xFE,0x40,0x20,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xD5C6 [?] [4926]*/ + 0x11,0x09,0x3F,0x20,0x4F,0x08,0x0F,0x00,0x3F,0x01,0x3F,0x01,0x7F,0x01,0x05,0x02, + 0x10,0x20,0xFC,0x04,0xE8,0x20,0xE0,0xF0,0x00,0x00,0xF8,0x00,0xFC,0x00,0x00,0x00, + /* 0xD5C7 [?] [4927]*/ + 0x00,0x4F,0x21,0x21,0x01,0x8F,0x48,0x58,0x18,0x2F,0xE1,0x21,0x21,0x21,0x2A,0x04, + 0x40,0x44,0x44,0x48,0x48,0x50,0x40,0xFE,0x50,0x50,0x48,0x48,0x44,0x44,0x62,0x40, + /* 0xD5C8 [?] [4928]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x30,0x39,0x55,0x54,0x90,0x10,0x10,0x10,0x11,0x16, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x50,0x20,0x50,0x88,0x06, + /* 0xD5C9 [?] [4929]*/ + 0x00,0x00,0x00,0x00,0x7F,0x00,0x10,0x10,0x08,0x04,0x02,0x01,0x02,0x04,0x18,0xE0, + 0x80,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x80,0x40,0x30,0x0E, + /* 0xD5CA [?] [4930]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x5C,0x10,0x10,0x10,0x10, + 0x80,0x84,0x84,0x88,0x90,0xA0,0x80,0xFE,0xA0,0x90,0x90,0x88,0x84,0xA2,0xC0,0x80, + /* 0xD5CB [?] [4931]*/ + 0x00,0x7C,0x44,0x54,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x10,0x28,0x24,0x44,0x80, + 0x80,0x84,0x84,0x88,0x90,0xA0,0x80,0xFE,0xA0,0xA0,0x90,0x90,0x88,0xA4,0xC2,0x80, + /* 0xD5CC [?] [4932]*/ + 0x08,0x08,0x08,0x10,0x13,0x30,0x30,0x51,0x91,0x10,0x10,0x10,0x10,0x10,0x11,0x16, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x50,0x20,0x50,0x88,0x06, + /* 0xD5CD [?] [4933]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x27,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x80,0x84,0x84,0x88,0x90,0xA0,0x80,0xFE,0xA0,0x90,0x90,0x88,0x84,0xA2,0xC0,0x80, + /* 0xD5CE [?] [4934]*/ + 0x00,0x3F,0x20,0x27,0xA1,0x6F,0x20,0x23,0x62,0xA3,0x22,0x23,0x20,0x4F,0x40,0x80, + 0x80,0xFE,0x40,0xFC,0x10,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFE,0x40,0x40, + /* 0xD5CF [?] [4935]*/ + 0x00,0x7D,0x44,0x48,0x4B,0x50,0x49,0x49,0x45,0x45,0x45,0x68,0x53,0x40,0x40,0x40, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xD5D0 [?] [4936]*/ + 0x10,0x13,0x10,0x10,0xFC,0x11,0x11,0x12,0x1C,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5D1 [?] [4937]*/ + 0x00,0x03,0x78,0x48,0x48,0x49,0x49,0x7A,0x4C,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5D2 [?] [4938]*/ + 0x10,0x10,0x10,0x10,0xFC,0x13,0x10,0x14,0x18,0x30,0xD0,0x10,0x10,0x11,0x52,0x20, + 0x90,0x88,0x88,0x80,0xBC,0xC0,0x80,0x88,0x88,0x90,0x60,0x44,0xA4,0x14,0x0C,0x04, + /* 0xD5D3 [?] [4939]*/ + 0x00,0x27,0x10,0x10,0x80,0x41,0x41,0x12,0x14,0x23,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5D4 [?] [4940]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFE,0x08,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x00,0x04,0x84,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0x00,0xFE,0x00, + /* 0xD5D5 [?] [4941]*/ + 0x00,0x7D,0x44,0x44,0x44,0x44,0x7D,0x44,0x44,0x44,0x44,0x7C,0x00,0x48,0x44,0x84, + 0x00,0xFC,0x44,0x44,0x44,0x94,0x08,0xFC,0x84,0x84,0x84,0xFC,0x00,0x88,0x44,0x44, + /* 0xD5D6 [?] [4942]*/ + 0x00,0x7F,0x44,0x7F,0x01,0x01,0x01,0x3F,0x20,0x3F,0x20,0x3F,0x01,0xFF,0x01,0x01, + 0x00,0xFC,0x44,0xFC,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x00,0x00, + /* 0xD5D7 [?] [4943]*/ + 0x04,0x04,0x44,0x24,0x14,0x14,0x04,0x0C,0x14,0x24,0x44,0x08,0x08,0x10,0x20,0x40, + 0x40,0x40,0x44,0x48,0x50,0x40,0x60,0x50,0x48,0x44,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xD5D8 [?] [4944]*/ + 0x08,0x3E,0x22,0x3E,0x20,0x41,0x9F,0x01,0xFF,0x01,0x1F,0x01,0x3F,0x01,0xFF,0x01, + 0x40,0x7E,0xA8,0x10,0x6E,0x00,0xF0,0x10,0xFE,0x10,0xF0,0x00,0xF8,0x00,0xFE,0x00, + /* 0xD5D9 [?] [4945]*/ + 0x00,0x7F,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x9F,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x50,0x20,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD5DA [?] [4946]*/ + 0x00,0x40,0x27,0x24,0x04,0x04,0xE7,0x24,0x24,0x24,0x28,0x2A,0x32,0x24,0x50,0x8F, + 0x40,0x20,0xFE,0x00,0x88,0x88,0xFE,0x88,0x88,0xF8,0x00,0xA4,0x52,0x52,0x00,0xFE, + /* 0xD5DB [?] [4947]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD5DC [?] [4948]*/ + 0x08,0x08,0x7E,0x08,0x0E,0x78,0x08,0x29,0x12,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xD5DD [?] [4949]*/ + 0x10,0x10,0xFB,0x10,0x19,0xF0,0x11,0x52,0x25,0x1F,0x11,0x11,0x1F,0x01,0x7F,0x20, + 0x80,0x80,0xF0,0x90,0x90,0x94,0x54,0x0C,0x04,0xF0,0x10,0x10,0xF0,0x08,0xFC,0x04, + /* 0xD5DE [?] [4950]*/ + 0x22,0x21,0x27,0xFA,0x24,0x4F,0x50,0x97,0xFC,0x17,0x1C,0xF7,0x54,0x14,0x14,0x15, + 0x08,0x08,0xC8,0x10,0x9E,0xD4,0x64,0x94,0x94,0x94,0x94,0x88,0x88,0x94,0xA4,0xC2, + /* 0xD5DF [?] [4951]*/ + 0x02,0x02,0x3F,0x02,0x02,0xFF,0x01,0x02,0x0F,0x18,0x28,0x4F,0x88,0x08,0x0F,0x08, + 0x00,0x08,0xD0,0x20,0x40,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xD5E0 [?] [4952]*/ + 0x20,0x20,0x39,0x20,0x40,0x7B,0xA0,0x20,0xF8,0x21,0x22,0x20,0x28,0x30,0x20,0x00, + 0x20,0x22,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xD5E1 [?] [4953]*/ + 0x08,0x08,0xFF,0x09,0x00,0x3F,0x22,0x22,0x3F,0x22,0x22,0x23,0x20,0x4A,0x49,0x91, + 0x20,0x20,0xFE,0x20,0x80,0xFC,0x20,0x20,0xFC,0x20,0x20,0xE0,0x00,0x48,0x24,0x24, + /* 0xD5E2 [?] [4954]*/ + 0x00,0x20,0x10,0x17,0x00,0x02,0xF1,0x10,0x10,0x10,0x11,0x12,0x14,0x28,0x47,0x00, + 0x80,0x40,0x40,0xFC,0x10,0x10,0x20,0xA0,0x40,0xA0,0x10,0x08,0x08,0x00,0xFE,0x00, + /* 0xD5E3 [?] [4955]*/ + 0x02,0x42,0x22,0x22,0x0F,0x82,0x42,0x52,0x13,0x2E,0xE2,0x22,0x22,0x22,0x2A,0x05, + 0x08,0x1C,0x60,0x40,0xC0,0x40,0x7E,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x08, + /* 0xD5E4 [?] [4956]*/ + 0x00,0x00,0xFC,0x10,0x11,0x12,0x7C,0x10,0x11,0x10,0x10,0x1C,0xE1,0x40,0x00,0x03, + 0x20,0x20,0x50,0x88,0x04,0x12,0x20,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80, + /* 0xD5E5 [?] [4957]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x22,0x3E,0x22,0x22,0xFF,0x40,0x54,0x62,0x40,0x7E,0x00, + 0x08,0x48,0x28,0x28,0x08,0x48,0x28,0x28,0x0E,0x78,0x08,0x08,0x08,0x08,0x08,0x08, + /* 0xD5E6 [?] [4958]*/ + 0x01,0x01,0x7F,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10,0xFF,0x08,0x10,0x20, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xFE,0x20,0x10,0x08, + /* 0xD5E7 [?] [4959]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xFE,0x10,0x10,0xFE,0x10,0x10,0x1E,0xF0,0x40, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xD5E8 [?] [4960]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3C,0x64,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD5E9 [?] [4961]*/ + 0x00,0xF8,0x23,0x40,0x51,0x88,0xFB,0x28,0x21,0xFA,0x20,0x21,0x38,0xE0,0x43,0x00, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x34,0xE2,0x20,0xFC,0x70,0xAC,0x22,0x20, + /* 0xD5EA [?] [4962]*/ + 0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x21,0x21,0x21,0x22,0x22,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0xC0,0x30,0x08,0x04, + /* 0xD5EB [?] [4963]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x93,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD5EC [?] [4964]*/ + 0x08,0x08,0x08,0x10,0x10,0x33,0x32,0x52,0x92,0x12,0x12,0x12,0x10,0x11,0x12,0x14, + 0x40,0x40,0x7E,0x40,0x40,0xF8,0x08,0x48,0x48,0x48,0x48,0x48,0xA0,0x10,0x08,0x04, + /* 0xD5ED [?] [4965]*/ + 0x10,0x10,0x10,0x13,0xFA,0x14,0x30,0x38,0x54,0x50,0x90,0x11,0x11,0x12,0x14,0x18, + 0x40,0x40,0x40,0xFC,0x44,0x48,0x40,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xD5EE [?] [4966]*/ + 0x00,0x00,0x1F,0x10,0x90,0x51,0x52,0x14,0x30,0x53,0x90,0x10,0x23,0x20,0x40,0x87, + 0x80,0x40,0xFE,0x40,0xA0,0x10,0x08,0x26,0xC0,0x10,0x20,0xC0,0x08,0x10,0xE0,0x00, + /* 0xD5EF [?] [4967]*/ + 0x00,0x40,0x20,0x21,0x02,0x04,0xE0,0x20,0x23,0x20,0x20,0x28,0x33,0x20,0x00,0x07, + 0x40,0x40,0xA0,0x10,0x08,0x26,0x40,0x80,0x10,0x20,0x40,0x88,0x10,0x20,0xC0,0x00, + /* 0xD5F0 [?] [4968]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x20,0x2F,0x20,0x3F,0x24,0x44,0x86, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFC,0x00,0xF8,0x00,0xFC,0x48,0x30,0x0E, + /* 0xD5F1 [?] [4969]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x12,0x17,0x1A,0x32,0xD2,0x12,0x12,0x14,0x54,0x28, + 0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFC,0xA0,0xA4,0xA8,0x90,0x90,0x88,0xA4,0xC2, + /* 0xD5F2 [?] [4970]*/ + 0x20,0x20,0x3B,0x40,0x41,0x79,0xA1,0x21,0xF9,0x21,0x21,0x29,0x37,0x20,0x01,0x02, + 0x20,0x20,0xFE,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFE,0x88,0x04,0x02, + /* 0xD5F3 [?] [4971]*/ + 0x00,0x7C,0x44,0x4B,0x48,0x50,0x49,0x49,0x44,0x44,0x44,0x6B,0x50,0x40,0x40,0x40, + 0x40,0x40,0x40,0xFE,0x80,0xA0,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xD5F4 [?] [4972]*/ + 0x08,0x08,0xFF,0x08,0x1F,0x00,0x7D,0x05,0x09,0x31,0xC5,0x02,0x3F,0x00,0x24,0x42, + 0x20,0x20,0xFE,0x20,0xC0,0x44,0x88,0x50,0x20,0x18,0x06,0x00,0xF8,0x00,0x88,0x44, + /* 0xD5F5 [?] [4973]*/ + 0x10,0x10,0x11,0x12,0xF8,0x13,0x10,0x18,0x37,0xD0,0x10,0x13,0x10,0x10,0x51,0x20, + 0x80,0x80,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x44,0x40,0x40,0x80, + /* 0xD5F6 [?] [4974]*/ + 0x01,0x01,0x79,0x4A,0x4C,0x7B,0x48,0x48,0x7B,0x48,0x48,0x4B,0x78,0x48,0x01,0x00, + 0x00,0x00,0xF0,0x10,0x20,0xF8,0x48,0x48,0xFE,0x48,0x48,0xF8,0x48,0x40,0x40,0x80, + /* 0xD5F7 [?] [4975]*/ + 0x08,0x08,0x13,0x20,0x48,0x08,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x17,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD5F8 [?] [4976]*/ + 0x00,0x44,0x29,0x12,0x28,0x4B,0x88,0x08,0x1F,0x28,0x48,0x8B,0x08,0x08,0x51,0x20, + 0x80,0x80,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x44,0x40,0x40,0x80, + /* 0xD5F9 [?] [4977]*/ + 0x08,0x08,0x1F,0x20,0x40,0xBF,0x01,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0x05,0x02, + 0x00,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xFE,0x08,0x08,0xF8,0x08,0x00,0x00,0x00, + /* 0xD5FA [?] [4978]*/ + 0x10,0x10,0x13,0x10,0x18,0x54,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x17,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD5FB [?] [4979]*/ + 0x08,0x08,0xFF,0x08,0x7F,0x49,0x7F,0x2A,0x49,0x88,0x00,0x7F,0x01,0x11,0x11,0xFF, + 0x20,0x20,0xBE,0x44,0xA4,0x24,0x28,0x10,0x28,0x46,0x00,0xFC,0x00,0xF8,0x00,0xFE, + /* 0xD5FC [?] [4980]*/ + 0x10,0x11,0x10,0x10,0xFC,0x13,0x10,0x14,0x19,0x31,0xD2,0x14,0x10,0x10,0x57,0x20, + 0x00,0xFC,0x08,0x10,0x22,0xB2,0xB4,0xA8,0x28,0x24,0x22,0xA0,0x40,0x00,0xFE,0x00, + /* 0xD5FD [?] [4981]*/ + 0x00,0x7F,0x01,0x01,0x01,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD5FE [?] [4982]*/ + 0x00,0x00,0xFF,0x08,0x08,0x08,0x48,0x4E,0x48,0x48,0x48,0x48,0x4F,0xF0,0x00,0x01, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xD6A1 [?] [4983]*/ + 0x10,0x10,0x10,0x7C,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x10,0x10,0x10,0x11, + 0x20,0x20,0x3E,0x20,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xD6A2 [?] [4984]*/ + 0x00,0x00,0x1F,0x10,0x90,0x5F,0x50,0x10,0x32,0x52,0x92,0x12,0x22,0x22,0x5F,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xD6A3 [?] [4985]*/ + 0x22,0x12,0x14,0x7F,0x08,0x08,0x08,0xFF,0x08,0x08,0x14,0x12,0x21,0x41,0x80,0x00, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0xA4,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xD6A4 [?] [4986]*/ + 0x00,0x20,0x13,0x10,0x00,0x00,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x07,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6A5 [?] [4987]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x01,0x01,0x7F,0x00,0x00,0x03,0x0C,0x30,0x48,0x87,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xF8,0x30,0xC0,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD6A6 [?] [4988]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x30,0x39,0x54,0x54,0x90,0x10,0x10,0x10,0x11,0x16, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xD6A7 [?] [4989]*/ + 0x01,0x01,0x01,0x7F,0x01,0x01,0x01,0x3F,0x10,0x08,0x04,0x02,0x01,0x06,0x18,0xE0, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0xC0,0x30,0x0E, + /* 0xD6A8 [?] [4990]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x49,0x48,0x48,0x78,0x48,0x00,0x00,0x01,0x06, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xD6A9 [?] [4991]*/ + 0x21,0x21,0x21,0xFB,0xAA,0xAC,0xA8,0xA8,0xFB,0xA0,0x20,0x29,0x39,0xEA,0x44,0x08, + 0x00,0x00,0x00,0xDE,0x92,0x92,0x92,0x92,0xF2,0x92,0x92,0x52,0x5E,0x20,0x20,0x00, + /* 0xD6AA [?] [4992]*/ + 0x20,0x20,0x20,0x7E,0x48,0x88,0x08,0x08,0xFF,0x08,0x14,0x14,0x22,0x22,0x42,0x80, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + /* 0xD6AB [?] [4993]*/ + 0x00,0x3C,0x24,0x25,0x24,0x3C,0x24,0x25,0x24,0x3C,0x24,0x24,0x24,0x44,0x55,0x8E, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xD6AC [?] [4994]*/ + 0x01,0x3D,0x25,0x25,0x25,0x3D,0x24,0x24,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x89, + 0x00,0x04,0x38,0xC0,0x02,0x02,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD6AD [?] [4995]*/ + 0x00,0x20,0x10,0x10,0x80,0x40,0x47,0x10,0x10,0x20,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xD6AE [?] [4996]*/ + 0x02,0x01,0x01,0x00,0x7F,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x18,0x24,0x43,0x00, + 0x00,0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD6AF [?] [4997]*/ + 0x10,0x10,0x21,0x25,0x45,0xF9,0x11,0x21,0x41,0xFD,0x40,0x00,0x1C,0xE1,0x42,0x04, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xD6B0 [?] [4998]*/ + 0x00,0xFF,0x24,0x24,0x3C,0x24,0x24,0x3C,0x24,0x24,0x2E,0xF4,0x44,0x04,0x04,0x05, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84,0x00,0x48,0x44,0x84,0x82,0x02, + /* 0xD6B1 [?] [4999]*/ + 0x01,0x01,0x7F,0x01,0x1F,0x10,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0xFF,0x00, + 0x00,0x00,0xFC,0x00,0xF0,0x10,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0xFE,0x00, + /* 0xD6B2 [?] [5000]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x17,0x10, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0xFE,0x00, + /* 0xD6B3 [?] [5001]*/ + 0x00,0xFC,0x23,0x20,0x20,0x3D,0x45,0x45,0x65,0x95,0x09,0x09,0x11,0x21,0x47,0x80, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0xFE,0x00, + /* 0xD6B4 [?] [5002]*/ + 0x10,0x10,0x10,0x10,0xFD,0x10,0x10,0x14,0x19,0x30,0xD0,0x10,0x10,0x11,0x52,0x24, + 0x40,0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0xC8,0x48,0xA8,0xAA,0x0A,0x06,0x02, + /* 0xD6B5 [?] [5003]*/ + 0x08,0x08,0x0F,0x10,0x10,0x33,0x32,0x53,0x92,0x13,0x12,0x13,0x12,0x12,0x1F,0x10, + 0x40,0x40,0xFC,0x40,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x00, + /* 0xD6B6 [?] [5004]*/ + 0x10,0x17,0x10,0x20,0x21,0x62,0x67,0xA0,0x20,0x20,0x27,0x20,0x20,0x20,0x2F,0x20, + 0x00,0xFE,0x40,0x80,0x10,0x08,0xFC,0x44,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xD6B7 [?] [5005]*/ + 0x10,0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x07,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6B8 [?] [5006]*/ + 0x11,0x11,0x11,0x11,0xFD,0x11,0x10,0x14,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x00,0x04,0x38,0xC0,0x02,0x02,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD6B9 [?] [5007]*/ + 0x01,0x01,0x01,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD6BA [?] [5008]*/ + 0x00,0x7C,0x44,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x07,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6BB [?] [5009]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0x08,0x08,0x10,0x20,0x40, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x00,0x20,0x10,0x08,0x04,0x04, + /* 0xD6BC [?] [5010]*/ + 0x20,0x20,0x23,0x3C,0x20,0x20,0x1F,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x70,0x80,0x08,0x08,0x08,0xF8,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xD6BD [?] [5011]*/ + 0x10,0x10,0x23,0x22,0x4A,0xFA,0x12,0x23,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x43,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x06,0x02, + /* 0xD6BE [?] [5012]*/ + 0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x3F,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xD6BF [?] [5013]*/ + 0x10,0xFB,0x10,0x19,0xF0,0x11,0x52,0x24,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x05,0x02, + 0x80,0xF0,0x90,0x90,0x94,0x54,0x0C,0xE4,0x00,0x00,0xF8,0x00,0xFC,0x00,0x00,0x00, + /* 0xD6C0 [?] [5014]*/ + 0x24,0x22,0x22,0x20,0xFF,0x21,0x21,0x29,0x37,0xE1,0x21,0x21,0x22,0x22,0xA4,0x48, + 0x40,0x5E,0x92,0x12,0xD4,0x14,0x18,0x14,0xF2,0x12,0x12,0x1A,0x94,0x50,0x50,0x10, + /* 0xD6C1 [?] [5015]*/ + 0x00,0x7F,0x02,0x04,0x08,0x10,0x3F,0x00,0x01,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0x20,0x10,0xF8,0x08,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xD6C2 [?] [5016]*/ + 0x00,0xFE,0x10,0x20,0x28,0x45,0xFE,0x12,0x10,0x10,0x7C,0x10,0x10,0x1E,0xF1,0x42, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xD6C3 [?] [5017]*/ + 0x7F,0x44,0x7F,0x01,0x7F,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10,0xFF,0x00, + 0xFC,0x44,0xFC,0x00,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xFE,0x00, + /* 0xD6C4 [?] [5018]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x5C,0x10,0x11,0x12,0x14, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xD6C5 [?] [5019]*/ + 0x10,0x10,0x10,0x11,0x54,0x54,0x57,0x54,0x54,0x55,0x54,0x5C,0x64,0x00,0x00,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0xFE,0x08,0x08,0xFE,0x08,0x88,0x48,0x08,0x28,0x10, + /* 0xD6C6 [?] [5020]*/ + 0x04,0x24,0x24,0x3F,0x44,0x04,0xFF,0x04,0x04,0x3F,0x24,0x24,0x26,0x25,0x04,0x04, + 0x04,0x04,0x04,0xA4,0x24,0x24,0xE4,0x24,0x24,0xA4,0xA4,0xA4,0x84,0x04,0x14,0x08, + /* 0xD6C7 [?] [5021]*/ + 0x20,0x3E,0x48,0x08,0xFF,0x14,0x22,0x40,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xD6C8 [?] [5022]*/ + 0x08,0x1C,0xF1,0x11,0x11,0xFD,0x12,0x30,0x39,0x54,0x54,0x90,0x10,0x10,0x11,0x12, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xD6C9 [?] [5023]*/ + 0x08,0x1C,0xF0,0x11,0x11,0xFF,0x15,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0xA0,0x90,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xD6CA [?] [5024]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x41,0x46,0x98, + 0x7C,0xC0,0x40,0x40,0xFE,0x40,0x40,0xFC,0x04,0x44,0x44,0x44,0xB4,0x08,0x04,0x02, + /* 0xD6CB [?] [5025]*/ + 0x02,0x04,0x0F,0x12,0x69,0x04,0x03,0x0C,0x71,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xF8,0x10,0x20,0xC0,0x00,0x00,0x00,0x10,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xD6CC [?] [5026]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x3F,0x50,0x90,0x1F,0x22,0x21,0x41,0x80, + 0x80,0x40,0xFE,0x40,0x40,0xFC,0x40,0x40,0xFE,0x10,0x10,0xFE,0x10,0x10,0x50,0x20, + /* 0xD6CD [?] [5027]*/ + 0x01,0x21,0x17,0x11,0x81,0x40,0x47,0x14,0x18,0x23,0xE2,0x22,0x22,0x22,0x20,0x00, + 0x50,0x50,0xFC,0x50,0x50,0x00,0xFE,0x42,0x44,0xF8,0x48,0x48,0x48,0x58,0x40,0x40, + /* 0xD6CE [?] [5028]*/ + 0x00,0x20,0x10,0x11,0x82,0x47,0x40,0x10,0x13,0x22,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x40,0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD6CF [?] [5029]*/ + 0x02,0x01,0x7F,0x48,0x90,0x00,0x7F,0x04,0x08,0x1F,0x01,0x01,0x3F,0x01,0x01,0xFF, + 0x00,0x00,0xFE,0x22,0x14,0x00,0xFC,0x00,0x20,0xF0,0x10,0x00,0xF8,0x00,0x00,0xFE, + /* 0xD6D0 [?] [5030]*/ + 0x01,0x01,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00, + /* 0xD6D1 [?] [5031]*/ + 0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xD6D2 [?] [5032]*/ + 0x01,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x01,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xD6D3 [?] [5033]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x10,0x14,0x18,0x10,0x00, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xD6D4 [?] [5034]*/ + 0x02,0x01,0xFF,0x01,0x3F,0x21,0x21,0x3F,0x01,0x02,0x04,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x00,0x80,0x44,0x28,0x10,0x08,0x06,0x00, + /* 0xD6D5 [?] [5035]*/ + 0x10,0x10,0x20,0x21,0x4B,0xFC,0x10,0x20,0x43,0xFC,0x40,0x00,0x18,0xE1,0x40,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xC0,0x20,0x10,0x80,0x60,0x10, + /* 0xD6D6 [?] [5036]*/ + 0x08,0x1C,0xF0,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xD6D7 [?] [5037]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x24,0x24,0x44,0x54,0x88, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xD6D8 [?] [5038]*/ + 0x00,0x00,0x3F,0x01,0xFF,0x01,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x3F,0x01,0xFF,0x00, + 0x10,0xF8,0x00,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x00,0xFE,0x00, + /* 0xD6D9 [?] [5039]*/ + 0x08,0x08,0x08,0x10,0x17,0x34,0x34,0x54,0x94,0x14,0x17,0x14,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x44,0x40,0x40,0x40,0x40, + /* 0xD6DA [?] [5040]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x28,0xC8,0x08,0x08,0x08,0x14,0x12,0x22,0x41,0x82, + 0x00,0x00,0x80,0x40,0x20,0x10,0x28,0x26,0x20,0x20,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xD6DB [?] [5041]*/ + 0x02,0x04,0x1F,0x10,0x12,0x11,0x11,0xFF,0x10,0x12,0x11,0x11,0x20,0x20,0x40,0x80, + 0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xD6DC [?] [5042]*/ + 0x00,0x3F,0x21,0x21,0x2F,0x21,0x21,0x3F,0x20,0x27,0x24,0x24,0x27,0x40,0x40,0x80, + 0x00,0xF8,0x08,0x08,0xE8,0x08,0x08,0xF8,0x08,0xC8,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xD6DD [?] [5043]*/ + 0x10,0x10,0x10,0x10,0x10,0x54,0x52,0x52,0x90,0x10,0x10,0x10,0x20,0x20,0x40,0x80, + 0x04,0x84,0x84,0x84,0x84,0xA4,0x94,0x94,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x04, + /* 0xD6DE [?] [5044]*/ + 0x01,0x21,0x11,0x11,0x81,0x41,0x45,0x15,0x19,0x21,0xE1,0x21,0x21,0x22,0x22,0x04, + 0x04,0x24,0x24,0x24,0x24,0x24,0xB4,0x6C,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04, + /* 0xD6DF [?] [5045]*/ + 0x00,0x20,0x10,0x11,0x02,0x04,0xF3,0x10,0x10,0x10,0x11,0x10,0x14,0x18,0x13,0x00, + 0x80,0x80,0xF8,0x08,0x10,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xD6E0 [?] [5046]*/ + 0x01,0xF9,0x09,0x0D,0x0B,0x79,0x41,0x47,0x41,0x79,0x0B,0x0D,0x09,0x09,0x51,0x21, + 0x00,0x3C,0x04,0x44,0x84,0x3C,0x20,0xE0,0x20,0x3C,0x84,0x44,0x04,0x04,0x28,0x10, + /* 0xD6E1 [?] [5047]*/ + 0x20,0x20,0x20,0xFC,0x41,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xD6E2 [?] [5048]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x08,0x28,0x10, + /* 0xD6E3 [?] [5049]*/ + 0x00,0x1F,0x00,0x0F,0x00,0x1F,0x00,0x7F,0x41,0x81,0x1F,0x11,0x11,0x11,0x11,0x01, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x02,0x04,0xF0,0x10,0x10,0x50,0x20,0x00, + /* 0xD6E4 [?] [5050]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x00,0x0F,0x08,0x08,0x08,0x10,0x10,0x20,0xC0, + 0x00,0xF8,0x88,0x88,0x88,0xF8,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xD6E5 [?] [5051]*/ + 0x20,0x20,0x3E,0x42,0x84,0x08,0xFE,0x02,0x02,0x7E,0x02,0x02,0x02,0xFF,0x02,0x00, + 0x10,0x10,0x10,0xFE,0x92,0x94,0x90,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0x28,0x44,0x82, + /* 0xD6E6 [?] [5052]*/ + 0x02,0x01,0x7F,0x40,0x81,0x01,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x20, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xD6E7 [?] [5053]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x20,0x2F,0x48,0x8F,0x08,0x0F,0x00,0x7F,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x40,0x20,0x10,0xE8,0x26,0xE0,0x20,0xE0,0x00,0xFC,0x00, + /* 0xD6E8 [?] [5054]*/ + 0x07,0xF2,0x13,0x52,0x53,0x52,0x57,0x78,0x08,0x0F,0x39,0xCA,0x08,0x09,0x2E,0x10, + 0xE0,0x5C,0xC4,0x54,0xC8,0x68,0xD4,0x64,0x3C,0xC0,0x44,0x68,0xD0,0x48,0x46,0x40, + /* 0xD6E9 [?] [5055]*/ + 0x00,0x01,0xFD,0x11,0x11,0x12,0x7C,0x13,0x10,0x10,0x10,0x1D,0xE1,0x42,0x00,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xD6EA [?] [5056]*/ + 0x10,0x11,0x11,0x11,0xFD,0x12,0x30,0x3B,0x54,0x54,0x90,0x11,0x11,0x12,0x10,0x10, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xD6EB [?] [5057]*/ + 0x10,0x11,0x11,0x7D,0x55,0x56,0x54,0x57,0x7C,0x50,0x10,0x15,0x1D,0xE6,0x40,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xD6EC [?] [5058]*/ + 0x01,0x11,0x11,0x1F,0x21,0x41,0x01,0xFF,0x03,0x05,0x09,0x11,0x21,0xC1,0x01,0x01, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x80,0x40,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xD6ED [?] [5059]*/ + 0x00,0x88,0x53,0x20,0x50,0x97,0x10,0x10,0x31,0x53,0x95,0x11,0x11,0x11,0xA1,0x41, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD6EE [?] [5060]*/ + 0x00,0x40,0x23,0x20,0x00,0x07,0xE0,0x20,0x21,0x23,0x25,0x21,0x29,0x31,0x21,0x01, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD6EF [?] [5061]*/ + 0x00,0x21,0x11,0x11,0x01,0x02,0xF0,0x13,0x10,0x10,0x10,0x15,0x19,0x12,0x00,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xD6F0 [?] [5062]*/ + 0x00,0x23,0x10,0x10,0x01,0x06,0xF0,0x11,0x16,0x10,0x11,0x16,0x10,0x28,0x47,0x00, + 0x00,0xFC,0x40,0x80,0x44,0x68,0xB0,0x28,0x68,0xA4,0x24,0x20,0xA0,0x40,0xFE,0x00, + /* 0xD6F1 [?] [5063]*/ + 0x10,0x10,0x10,0x10,0x3E,0x28,0x49,0x8A,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x40,0x40,0x40,0x40,0xFE,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xD6F2 [?] [5064]*/ + 0x10,0x10,0x10,0x11,0x55,0x59,0x51,0x91,0x11,0x11,0x10,0x28,0x24,0x45,0x40,0x80, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x28,0x24,0xFE,0x82,0x00, + /* 0xD6F3 [?] [5065]*/ + 0x02,0x02,0x3F,0x02,0xFF,0x01,0x0F,0x38,0xCF,0x08,0x08,0x0F,0x00,0x48,0x44,0x84, + 0x00,0x08,0xD0,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0x10,0xF0,0x00,0x88,0x44,0x44, + /* 0xD6F4 [?] [5066]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x10,0x14,0x19,0x30,0xD0,0x10,0x10,0x10,0x53,0x20, + 0x40,0x20,0x00,0xFE,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6F5 [?] [5067]*/ + 0x00,0x07,0xF4,0x97,0x94,0xF5,0x94,0x95,0xF5,0x95,0x94,0x97,0xF6,0x96,0x0A,0x12, + 0x00,0xFC,0x04,0xFC,0x00,0xFC,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x2A,0xFA,0x0A,0x06, + /* 0xD6F6 [?] [5068]*/ + 0x00,0x07,0xF4,0x97,0x94,0x95,0x94,0x95,0x95,0x95,0xF4,0x97,0x06,0x06,0x0A,0x12, + 0x00,0xFC,0x04,0xFC,0x00,0xFC,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x2A,0xFA,0x0A,0x06, + /* 0xD6F7 [?] [5069]*/ + 0x02,0x01,0x00,0x7F,0x01,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD6F8 [?] [5070]*/ + 0x08,0xFF,0x08,0x02,0x3F,0x02,0x02,0xFF,0x03,0x0C,0x3F,0xC8,0x0F,0x08,0x0F,0x08, + 0x20,0xFE,0x20,0x08,0xD0,0x20,0x40,0xFE,0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xD6F9 [?] [5071]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x30,0x38,0x55,0x54,0x90,0x10,0x10,0x10,0x13,0x10, + 0x40,0x20,0x00,0xFE,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6FA [?] [5072]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x44,0x44,0x4E,0xF0,0x01,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xD6FB [?] [5073]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x54,0x54,0x7D,0x50,0x10,0x14,0x1C,0xE4,0x43,0x00, + 0x40,0x20,0x00,0xFE,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD6FC [?] [5074]*/ + 0x00,0x7C,0x44,0x54,0x55,0x55,0x56,0x54,0x54,0x54,0x54,0x10,0x28,0x25,0x44,0x80, + 0x40,0x20,0x20,0x00,0xFE,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00, + /* 0xD6FD [?] [5075]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x11,0x10,0xFC,0x10,0x10,0x11,0x15,0x1A,0x10,0x00, + 0x20,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x48,0x48,0xFE,0x88,0x48,0x28,0x08,0x28,0x10, + /* 0xD6FE [?] [5076]*/ + 0x10,0x10,0x3F,0x48,0x85,0x00,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE2,0x42,0x04,0x08, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF0,0x10,0x10,0x90,0x50,0x12,0x12,0x12,0x0E,0x00, + /* 0xD7A1 [?] [5077]*/ + 0x08,0x08,0x08,0x17,0x10,0x30,0x30,0x50,0x97,0x10,0x10,0x10,0x10,0x10,0x1F,0x10, + 0x80,0x40,0x00,0xFC,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xD7A2 [?] [5078]*/ + 0x00,0x20,0x10,0x17,0x80,0x40,0x40,0x10,0x13,0x20,0xE0,0x20,0x20,0x20,0x2F,0x00, + 0x80,0x40,0x00,0xFC,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xD7A3 [?] [5079]*/ + 0x20,0x13,0x12,0xFA,0x0A,0x12,0x13,0x38,0x54,0x94,0x10,0x11,0x11,0x12,0x14,0x18, + 0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x90,0x90,0x90,0x90,0x12,0x12,0x12,0x0E,0x00, + /* 0xD7A4 [?] [5080]*/ + 0x00,0xF8,0x08,0x4B,0x48,0x48,0x48,0x7C,0x05,0x04,0x1C,0xE4,0x44,0x04,0x2B,0x10, + 0x40,0x20,0x00,0xFE,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD7A5 [?] [5081]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x31,0xD1,0x11,0x11,0x12,0x52,0x24, + 0x08,0x1C,0xF0,0x50,0x50,0x50,0x50,0x50,0x50,0x48,0x48,0x48,0x44,0x44,0x42,0x00, + /* 0xD7A6 [?] [5082]*/ + 0x00,0x00,0x1F,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x42,0x80, + 0x10,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x02, + /* 0xD7A7 [?] [5083]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x11,0x15,0x19,0x30,0xD0,0x10,0x10,0x10,0x53,0x20, + 0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x24,0x18,0x32,0xCA,0x06,0x02, + /* 0xD7A8 [?] [5084]*/ + 0x01,0x01,0x01,0x3F,0x02,0x02,0xFF,0x04,0x08,0x0F,0x00,0x00,0x06,0x01,0x00,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x40,0x20, + /* 0xD7A9 [?] [5085]*/ + 0x00,0x00,0xFC,0x11,0x10,0x20,0x3D,0x64,0x64,0xA5,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x40,0xFE,0x40,0x80,0xFC,0x04,0x88,0x50,0x20,0x10,0x10, + /* 0xD7AA [?] [5086]*/ + 0x20,0x20,0x20,0xFD,0x40,0x50,0x93,0xFC,0x10,0x11,0x1C,0xF0,0x50,0x10,0x10,0x10, + 0x20,0x20,0x20,0xFC,0x20,0x40,0xFE,0x40,0x80,0xFC,0x04,0x88,0x50,0x20,0x10,0x10, + /* 0xD7AB [?] [5087]*/ + 0x20,0x27,0x24,0x27,0xFC,0x24,0x23,0x28,0x31,0xE7,0x21,0x21,0x2F,0x21,0xA2,0x44, + 0x00,0xBC,0xA4,0xBC,0x20,0xA4,0x9C,0x00,0x10,0xFC,0x10,0x10,0xFE,0x10,0x08,0x04, + /* 0xD7AC [?] [5088]*/ + 0x00,0x7C,0x44,0x55,0x54,0x55,0x54,0x57,0x54,0x55,0x54,0x10,0x29,0x26,0x44,0x80, + 0x88,0x50,0x00,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50,0x50, + /* 0xD7AD [?] [5089]*/ + 0x20,0x3E,0x48,0x88,0x0F,0x10,0x1F,0x00,0xFF,0x06,0x3B,0x04,0x19,0x62,0x0C,0x73, + 0x40,0x7E,0x90,0x00,0xE0,0x20,0xC0,0x40,0xFE,0x00,0x08,0xB0,0xC0,0xA0,0x98,0x06, + /* 0xD7AE [?] [5090]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x20,0x10,0x10,0xFE,0x00,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xD7AF [?] [5091]*/ + 0x01,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x2F,0x20,0x20,0x20,0x20,0x40,0x5F,0x80, + 0x00,0x80,0x80,0xFC,0x00,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80,0x80,0xFE,0x00, + /* 0xD7B0 [?] [5092]*/ + 0x08,0x48,0x2B,0x08,0x18,0x28,0xC9,0x0A,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x00,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xD7B1 [?] [5093]*/ + 0x08,0x08,0x08,0x48,0x2B,0x28,0x08,0x08,0x18,0x29,0xC8,0x08,0x08,0x08,0x08,0x0B, + 0x40,0x40,0x40,0x40,0xFE,0x88,0x88,0x88,0x88,0x08,0x90,0x50,0x20,0x50,0x88,0x04, + /* 0xD7B2 [?] [5094]*/ + 0x10,0x11,0x10,0x10,0xFD,0x10,0x11,0x15,0x19,0x31,0xD1,0x10,0x11,0x10,0x53,0x20, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xD7B3 [?] [5095]*/ + 0x08,0x08,0x08,0x48,0x28,0x28,0x0B,0x18,0x28,0x48,0x88,0x08,0x08,0x08,0x09,0x08, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00, + /* 0xD7B4 [?] [5096]*/ + 0x08,0x08,0x08,0x48,0x28,0x2F,0x08,0x08,0x18,0x28,0xC8,0x08,0x09,0x09,0x0A,0x0C, + 0x40,0x48,0x44,0x44,0x40,0xFE,0x40,0x40,0x40,0xA0,0xA0,0x90,0x10,0x08,0x04,0x02, + /* 0xD7B5 [?] [5097]*/ + 0x10,0x10,0x10,0x11,0xFD,0x13,0x35,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0xA0,0x90,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xD7B6 [?] [5098]*/ + 0x10,0x10,0x3C,0x20,0x41,0xBE,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xD7B7 [?] [5099]*/ + 0x00,0x20,0x13,0x12,0x02,0x03,0xF2,0x12,0x13,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0x20,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFE,0x02,0x02,0xFE,0x02,0x00,0xFE,0x00, + /* 0xD7B8 [?] [5100]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x10,0x1E,0x22,0x46,0x9F,0x10,0x11,0x02,0x0C,0x70, + 0x20,0x20,0x7E,0x44,0xA4,0x28,0x10,0x28,0x44,0x82,0xF0,0x10,0x10,0xC0,0x30,0x08, + /* 0xD7B9 [?] [5101]*/ + 0x00,0x7C,0x44,0x48,0x44,0x44,0x55,0x49,0x42,0x45,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x40,0x40,0x40,0x40,0xA0,0xA0,0x10,0x08,0x04,0x02,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xD7BA [?] [5102]*/ + 0x20,0x27,0x20,0x42,0x51,0xF2,0x24,0x28,0x40,0xF7,0x40,0x02,0x31,0xC2,0x04,0x08, + 0x00,0xBC,0x84,0x94,0x08,0x94,0xA4,0x40,0x00,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xD7BB [?] [5103]*/ + 0x00,0x20,0x17,0x10,0x03,0x02,0xF3,0x10,0x13,0x10,0x10,0x17,0x18,0x10,0x01,0x00, + 0x80,0x40,0xFC,0x00,0xF8,0x08,0xF8,0x00,0xF8,0x10,0x20,0xFC,0x40,0x40,0x40,0x80, + /* 0xD7BC [?] [5104]*/ + 0x01,0x41,0x21,0x23,0x02,0x16,0x1B,0x12,0x22,0x23,0xE2,0x22,0x22,0x23,0x22,0x02, + 0x40,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00, + /* 0xD7BD [?] [5105]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x10,0x14,0x19,0x31,0xD1,0x11,0x12,0x12,0x54,0x28, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0x20,0x3C,0x20,0x20,0xA0,0x60,0x3E,0x00, + /* 0xD7BE [?] [5106]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x15,0x18,0x30,0xD0,0x12,0x12,0x12,0x12,0x53,0x20, + 0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x22,0x22,0x22,0x22,0xFE,0x02, + /* 0xD7BF [?] [5107]*/ + 0x01,0x01,0x01,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x11,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xD7C0 [?] [5108]*/ + 0x01,0x01,0x01,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xD7C1 [?] [5109]*/ + 0x00,0x03,0xF8,0x20,0x21,0x22,0x20,0xFA,0x21,0x22,0x20,0x38,0xE1,0x42,0x00,0x00, + 0x00,0xFE,0x40,0x80,0x44,0x24,0x68,0xB0,0x30,0xA8,0x68,0xA4,0x22,0x20,0xA0,0x40, + /* 0xD7C2 [?] [5110]*/ + 0x08,0x08,0xFF,0x08,0x09,0x21,0x21,0x21,0x3F,0x01,0x01,0x41,0x41,0x41,0x7F,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x08,0x08,0x08,0xF8,0x08,0x00,0x04,0x04,0x04,0xFC,0x04, + /* 0xD7C3 [?] [5111]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x20,0x20,0x7C,0x44,0x84,0x04,0x44,0x24,0x14,0x14,0x04,0x04,0x04,0x28,0x10, + /* 0xD7C4 [?] [5112]*/ + 0x00,0x03,0x78,0x48,0x49,0x4A,0x48,0x4A,0x49,0x4A,0x78,0x48,0x01,0x02,0x00,0x00, + 0x00,0xFE,0x40,0x80,0x44,0x24,0x68,0xB0,0x30,0xA8,0x68,0xA4,0x22,0x20,0xA0,0x40, + /* 0xD7C5 [?] [5113]*/ + 0x08,0x04,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x0F,0x18,0x2F,0xC8,0x0F,0x08,0x0F,0x08, + 0x20,0x40,0xFC,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xD7C6 [?] [5114]*/ + 0x10,0x10,0x10,0x10,0x55,0x5A,0x50,0x91,0x10,0x10,0x10,0x28,0x24,0x44,0x40,0x80, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xD7C7 [?] [5115]*/ + 0x00,0x20,0x10,0x17,0x84,0x44,0x44,0x14,0x17,0x24,0xE0,0x20,0x20,0x2F,0x24,0x00, + 0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0xFC,0x44,0x40,0x48,0x44,0xFE,0x02,0x00, + /* 0xD7C8 [?] [5116]*/ + 0x08,0x04,0x04,0xFF,0x10,0x10,0x20,0x24,0x44,0x78,0x08,0x10,0x14,0x22,0x7E,0x02, + 0x20,0x20,0x40,0xFE,0x20,0x20,0x40,0x48,0x88,0xF0,0x10,0x20,0x28,0x44,0xFC,0x04, + /* 0xD7C9 [?] [5117]*/ + 0x40,0x20,0x09,0x12,0x24,0xE0,0x20,0x23,0x2C,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x80,0x80,0xFC,0x04,0x48,0x40,0xA0,0x18,0x06,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xD7CA [?] [5118]*/ + 0x01,0x41,0x21,0x0A,0x14,0xE0,0x21,0x26,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0x00,0xFC,0x44,0x48,0xA0,0x10,0x0C,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xD7CB [?] [5119]*/ + 0x40,0x20,0x09,0x12,0x24,0xE0,0x20,0x23,0x2C,0x04,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x80,0x80,0xFC,0x04,0x48,0x40,0xA0,0x18,0x06,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xD7CC [?] [5120]*/ + 0x01,0x20,0x10,0x17,0x81,0x41,0x42,0x12,0x14,0x27,0xE1,0x22,0x22,0x24,0x27,0x00, + 0x08,0x88,0x90,0xFE,0x08,0x08,0x10,0x94,0xA4,0x38,0x08,0x10,0x10,0xA4,0xBC,0x84, + /* 0xD7CD [?] [5121]*/ + 0x01,0x21,0x12,0x14,0x82,0x41,0x41,0x10,0x17,0x24,0xE4,0x27,0x24,0x24,0x27,0x04, + 0x24,0x24,0x48,0x90,0x48,0x24,0x24,0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x04, + /* 0xD7CE [?] [5122]*/ + 0x00,0xFC,0x04,0x08,0x10,0x11,0x16,0x18,0x30,0xD0,0x10,0x10,0x10,0x10,0x51,0x22, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xD7CF [?] [5123]*/ + 0x08,0x28,0x2E,0x28,0x2E,0xF0,0x02,0x04,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x80,0x88,0xF0,0x84,0x84,0x7C,0x00,0x20,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xD7D0 [?] [5124]*/ + 0x08,0x0B,0x08,0x10,0x10,0x30,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x10,0x11,0x10, + 0x00,0xF8,0x08,0x10,0x20,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xD7D1 [?] [5125]*/ + 0x10,0x11,0x94,0x54,0x58,0x10,0xFC,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x04,0x08,0x10,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xD7D2 [?] [5126]*/ + 0x00,0x20,0x17,0x14,0x80,0x43,0x41,0x10,0x17,0x20,0xE0,0x23,0x20,0x20,0x20,0x00, + 0x80,0x40,0xFC,0x84,0x40,0xF8,0x10,0xA0,0xFC,0x40,0x40,0xF8,0x40,0x40,0x40,0x40, + /* 0xD7D3 [?] [5127]*/ + 0x00,0x7F,0x00,0x00,0x00,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x10,0x20,0x40,0x80,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7D4 [?] [5128]*/ + 0x01,0x02,0x04,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xD7D5 [?] [5129]*/ + 0x00,0x20,0x17,0x10,0x83,0x40,0x47,0x10,0x13,0x22,0xE2,0x22,0x22,0x20,0x21,0x06, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0x48,0xA0,0x10,0x08, + /* 0xD7D6 [?] [5130]*/ + 0x02,0x01,0x7F,0x40,0x80,0x1F,0x00,0x00,0x01,0xFF,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0x00,0xFE,0x02,0x04,0xE0,0x40,0x80,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7D7 [?] [5131]*/ + 0x3F,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x01,0x7F,0x40,0x1F,0x00,0x7F,0x11,0x25,0x42, + 0x08,0x30,0xC4,0x18,0x62,0x0C,0x70,0x00,0xFC,0x04,0xF0,0x00,0xFC,0x10,0x08,0x04, + /* 0xD7D8 [?] [5132]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x30,0x38,0x57,0x54,0x91,0x11,0x12,0x14,0x10,0x10, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xD7D9 [?] [5133]*/ + 0x00,0x78,0x4B,0x4A,0x4C,0x79,0x10,0x10,0x53,0x5C,0x51,0x51,0x5A,0xE4,0x00,0x00, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xD7DA [?] [5134]*/ + 0x02,0x01,0x01,0x7F,0x40,0x80,0x1F,0x00,0x00,0x7F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0x00,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xD7DB [?] [5135]*/ + 0x10,0x10,0x23,0x22,0x48,0xF9,0x10,0x20,0x43,0xF8,0x41,0x01,0x1A,0xE4,0x40,0x00, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xD7DC [?] [5136]*/ + 0x10,0x08,0x04,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10,0x01,0x08,0x48,0x48,0x87,0x00, + 0x10,0x20,0x40,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xD7DD [?] [5137]*/ + 0x11,0x11,0x21,0x21,0x49,0xF9,0x11,0x21,0x41,0xFA,0x42,0x02,0x1C,0xE4,0x48,0x11, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xA8,0x68,0x28,0x44,0x44,0x84,0x02, + /* 0xD7DE [?] [5138]*/ + 0x20,0x20,0x3E,0x42,0x84,0x08,0xFE,0x02,0x02,0x7E,0x02,0x02,0x02,0xFE,0x02,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xD7DF [?] [5139]*/ + 0x01,0x01,0x01,0x3F,0x01,0x01,0xFF,0x01,0x01,0x11,0x11,0x11,0x11,0x29,0x47,0x80, + 0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xD7E0 [?] [5140]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x08,0x37,0xC1,0x1F,0x01,0x02,0x0C,0x30, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x40,0x20,0xD8,0x06,0xF0,0x00,0xC0,0x30,0x08, + /* 0xD7E1 [?] [5141]*/ + 0x20,0x20,0x27,0x20,0xFB,0x20,0x27,0x29,0x32,0xE5,0x20,0x23,0x20,0x20,0xA1,0x46, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x08,0xF6,0x40,0xF8,0x40,0xA0,0x10,0x08, + /* 0xD7E2 [?] [5142]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x17,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD7E3 [?] [5143]*/ + 0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x01,0x01,0x11,0x11,0x11,0x29,0x25,0x43,0x80, + 0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xD7E4 [?] [5144]*/ + 0x02,0x01,0x7F,0x08,0x08,0x08,0x14,0x22,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x50,0x88,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xD7E5 [?] [5145]*/ + 0x20,0x10,0x10,0x01,0xFE,0x20,0x20,0x3C,0x25,0x24,0x27,0x24,0x24,0x44,0x54,0x89, + 0x80,0x80,0xFE,0x00,0x80,0x80,0xFC,0xA0,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x06, + /* 0xD7E6 [?] [5146]*/ + 0x20,0x11,0x11,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x11,0x11,0x17,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD7E7 [?] [5147]*/ + 0x00,0x21,0x11,0x11,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x07,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD7E8 [?] [5148]*/ + 0x00,0x7D,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x47,0x40, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD7E9 [?] [5149]*/ + 0x10,0x11,0x21,0x21,0x49,0xF9,0x11,0x21,0x41,0xF9,0x41,0x01,0x19,0xE1,0x47,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD7EA [?] [5150]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x10,0x10,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD7EB [?] [5151]*/ + 0x20,0x3E,0x48,0xBF,0x24,0x22,0x3F,0x02,0xFF,0x09,0x12,0x2F,0xC2,0x1F,0x09,0x13, + 0x40,0x7E,0x90,0xF8,0x88,0x48,0xF8,0x00,0xFE,0x20,0x50,0x88,0x26,0xF0,0x48,0x20, + /* 0xD7EC [?] [5152]*/ + 0x00,0x02,0xF2,0x92,0x92,0x97,0x91,0x92,0x97,0x9A,0xF3,0x92,0x03,0x04,0x04,0x08, + 0x90,0x94,0xD8,0x92,0xD2,0x0E,0xF0,0x10,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x54,0x08, + /* 0xD7ED [?] [5153]*/ + 0x00,0xFE,0x29,0x28,0xFE,0xAA,0xAB,0xAA,0xAE,0xC2,0x83,0xFE,0x82,0x82,0xFE,0x82, + 0x40,0x20,0xFE,0x00,0x88,0x88,0x54,0x22,0x00,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xD7EE [?] [5154]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x00,0xFF,0x22,0x3E,0x22,0x3E,0x22,0x2F,0xF2,0x42,0x03, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0xF8,0x88,0x90,0x50,0x20,0x50,0x88,0x06, + /* 0xD7EF [?] [5155]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x00,0x04,0x7C,0x04,0x04,0x7C,0x04,0x04,0xFC,0x04,0x04, + 0x00,0xFC,0x44,0x44,0xFC,0x00,0x40,0x7C,0x40,0x40,0x7C,0x40,0x40,0x7E,0x40,0x40, + /* 0xD7F0 [?] [5156]*/ + 0x08,0x04,0xFF,0x04,0x3F,0x28,0x30,0x27,0x20,0x3F,0x00,0xFF,0x08,0x04,0x04,0x00, + 0x20,0x40,0xFE,0x40,0xF8,0x48,0x38,0xC8,0x08,0xF8,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xD7F1 [?] [5157]*/ + 0x01,0x4F,0x20,0x27,0x04,0x05,0xE6,0x27,0x24,0x27,0x20,0x2F,0x21,0x20,0x50,0x8F, + 0x10,0xFE,0xA0,0xFC,0xA4,0x1C,0x04,0xFC,0x04,0xFC,0x10,0xFE,0x10,0xB0,0x00,0xFE, + /* 0xD7F2 [?] [5158]*/ + 0x01,0x01,0x79,0x49,0x4A,0x4A,0x4C,0x78,0x48,0x48,0x48,0x48,0x78,0x48,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80, + /* 0xD7F3 [?] [5159]*/ + 0x02,0x02,0x02,0xFF,0x04,0x04,0x04,0x08,0x0F,0x10,0x10,0x20,0x40,0x80,0x3F,0x00, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0xFE,0x00, + /* 0xD7F4 [?] [5160]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x31,0x51,0x91,0x12,0x12,0x14,0x14,0x18,0x13,0x10, + 0x80,0x80,0x80,0x80,0xFE,0x80,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD7F5 [?] [5161]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x32,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xD7F6 [?] [5162]*/ + 0x12,0x12,0x12,0x2F,0x22,0x62,0x62,0xAF,0x28,0x28,0x28,0x28,0x2F,0x28,0x20,0x20, + 0x10,0x10,0x10,0xA0,0x3E,0x44,0x24,0xA4,0xA4,0xA8,0xA8,0x90,0xA8,0x28,0x44,0x82, + /* 0xD7F7 [?] [5163]*/ + 0x09,0x09,0x09,0x11,0x12,0x32,0x34,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x80,0x80,0x80,0x80, + /* 0xD7F8 [?] [5164]*/ + 0x01,0x11,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x00,0x10,0x10,0x10,0x10,0x28,0x24,0x44,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xD7F9 [?] [5165]*/ + 0x01,0x00,0x3F,0x20,0x24,0x24,0x24,0x2A,0x31,0x20,0x2F,0x20,0x40,0x40,0xBF,0x00, + 0x00,0x80,0xFE,0x80,0x90,0x90,0x90,0xA8,0xC4,0x80,0xF8,0x80,0x80,0x80,0xFE,0x00, + /* 0xD7FA [?] [5166]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7FB [?] [5167]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7FC [?] [5168]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7FD [?] [5169]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD7FE [?] [5170]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD8A1 [?] [5171]*/ + 0x00,0x3F,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD8A2 [?] [5172]*/ + 0x00,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD8A3 [?] [5173]*/ + 0x00,0x00,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x3C,0x00, + /* 0xD8A4 [?] [5174]*/ + 0x00,0xFF,0x01,0x01,0x21,0x21,0x21,0x21,0x21,0x3F,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xD8A5 [?] [5175]*/ + 0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0F,0x08, + 0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10, + /* 0xD8A6 [?] [5176]*/ + 0x10,0x11,0x11,0x11,0x11,0x11,0xFF,0x11,0x11,0x11,0x11,0x11,0x11,0x21,0x20,0x40, + 0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD8A7 [?] [5177]*/ + 0x00,0x7F,0x00,0x01,0x01,0x03,0x05,0x09,0x31,0xC1,0x01,0x01,0x01,0x00,0xFF,0x00, + 0x00,0xFC,0x80,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD8A8 [?] [5178]*/ + 0x00,0x7F,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x00,0x00,0xFF,0x00, + 0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x00,0x00,0xFE,0x00, + /* 0xD8A9 [?] [5179]*/ + 0x00,0x3F,0x00,0x00,0x00,0x7D,0x05,0x09,0x09,0x11,0x21,0x41,0x85,0x02,0xFF,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x04,0x88,0x50,0x20,0x10,0x08,0x06,0x00,0x00,0xFE,0x00, + /* 0xD8AA [?] [5180]*/ + 0x00,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x00,0x7F,0x48,0x44,0x5F,0x41,0x41,0x41,0x40, + 0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x00,0xFC,0x24,0x44,0xF4,0x04,0x04,0x14,0x08, + /* 0xD8AB [?] [5181]*/ + 0x7F,0x00,0x03,0x0D,0x71,0x01,0x10,0x10,0xFE,0x22,0x22,0x64,0x14,0x08,0x34,0xC2, + 0xFC,0x80,0x60,0x18,0x04,0x00,0x00,0xFC,0x04,0x08,0x10,0xFE,0x10,0x10,0x50,0x20, + /* 0xD8AC [?] [5182]*/ + 0x00,0x7F,0x01,0x3D,0x25,0x25,0x3D,0x01,0x7F,0x01,0x3D,0x25,0x25,0x3D,0x01,0xFF, + 0x00,0xFC,0x00,0x78,0x48,0x48,0x78,0x00,0xFC,0x00,0x78,0x48,0x48,0x78,0x00,0xFE, + /* 0xD8AD [?] [5183]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD8AE [?] [5184]*/ + 0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x01,0x7F,0x41,0x41,0x5F,0x48,0x40,0x40, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x24,0xE4,0x24,0x14,0x08, + /* 0xD8AF [?] [5185]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x10,0x20, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD8B0 [?] [5186]*/ + 0x10,0x10,0x10,0x10,0x10,0x10,0x13,0x1C,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x00, + 0x00,0x00,0x00,0x08,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xD8B1 [?] [5187]*/ + 0x00,0x03,0x3E,0x02,0x02,0x02,0x02,0x03,0xFE,0x02,0x02,0x02,0x02,0x02,0x01,0x00, + 0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xD8B2 [?] [5188]*/ + 0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0xFF,0x01,0x02,0x02,0x04,0x08,0x10,0x20,0xC0, + 0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x06, + /* 0xD8B3 [?] [5189]*/ + 0x00,0x18,0x06,0x01,0x06,0x18,0x60,0x00,0x08,0x04,0x02,0x01,0x02,0x0C,0x30,0xC0, + 0x08,0x10,0x60,0x80,0x60,0x18,0x04,0x20,0x20,0x40,0x80,0x00,0x80,0x40,0x30,0x0E, + /* 0xD8B4 [?] [5190]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x44,0x43,0x80, + 0x7C,0x80,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x50,0x24,0x04,0x04,0xFC,0x00, + /* 0xD8B5 [?] [5191]*/ + 0x00,0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x21,0x28,0x30,0x20, + 0x10,0xF8,0x80,0x80,0x80,0x80,0xFE,0x80,0x80,0x40,0x40,0x22,0x12,0x8A,0x46,0x42, + /* 0xD8B6 [?] [5192]*/ + 0x02,0x02,0x04,0x7F,0x40,0x48,0x44,0x42,0x41,0x42,0x44,0x48,0x40,0x40,0x7F,0x40, + 0x00,0x00,0x00,0xFC,0x04,0x24,0x44,0x84,0x04,0x84,0x44,0x24,0x04,0x04,0xFC,0x04, + /* 0xD8B7 [?] [5193]*/ + 0x01,0x22,0x24,0x27,0x21,0x22,0x27,0x20,0x27,0x24,0x27,0x24,0x27,0x44,0x44,0x84, + 0x00,0x08,0x48,0x88,0x08,0x48,0xC8,0x08,0xC8,0x48,0xC8,0x48,0xCA,0x4A,0x4A,0xC6, + /* 0xD8B8 [?] [5194]*/ + 0x21,0x20,0x20,0x23,0xFC,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x44,0x43,0x80, + 0x10,0xA0,0x00,0xFC,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFA,0x0A,0x02,0xFE,0x00, + /* 0xD8B9 [?] [5195]*/ + 0x40,0x40,0x7D,0x80,0x7C,0x44,0x65,0x54,0xFE,0x44,0xA4,0x94,0xFE,0x05,0x29,0x12, + 0x20,0x10,0xFE,0x20,0x48,0x84,0xFE,0x02,0xA8,0xA8,0xA8,0xA8,0xAA,0x2A,0x26,0x00, + /* 0xD8BA [?] [5196]*/ + 0x04,0x08,0x7F,0x44,0x7F,0x01,0x3F,0x01,0xFF,0x08,0x04,0x3F,0x01,0xFF,0x01,0x01, + 0x00,0x00,0xFC,0x44,0xFC,0x00,0xF8,0x00,0xFE,0x20,0x40,0xF8,0x00,0xFE,0x00,0x00, + /* 0xD8BB [?] [5197]*/ + 0x24,0x14,0x24,0x08,0x70,0x08,0xFF,0x08,0x7E,0x00,0x7E,0x42,0x7E,0x24,0x1E,0xE0, + 0x90,0xA0,0x94,0x84,0x7C,0x10,0x10,0xFE,0x10,0xFC,0x44,0x48,0x28,0x10,0x28,0xC6, + /* 0xD8BC [?] [5198]*/ + 0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00, + /* 0xD8BD [?] [5199]*/ + 0x00,0x3F,0x00,0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x79,0x01,0x05,0x02,0xFF,0x00, + 0x00,0xF0,0x20,0x40,0x80,0x3C,0x04,0x44,0x28,0x10,0x28,0x44,0x00,0x00,0xFE,0x00, + /* 0xD8BE [?] [5200]*/ + 0x7F,0x10,0x10,0x2F,0x48,0x8F,0x08,0x4F,0x48,0x4F,0x40,0x7C,0x04,0xFC,0x24,0x44, + 0xF8,0x08,0x1E,0xE2,0x2A,0xE4,0x20,0xE4,0x24,0xE4,0x04,0x7C,0x40,0x7C,0x44,0x44, + /* 0xD8BF [?] [5201]*/ + 0x00,0x00,0x10,0x10,0x10,0x17,0x38,0xD0,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x00, + 0x00,0x00,0x00,0x30,0xD0,0x10,0x10,0x10,0x10,0x50,0x20,0x02,0x02,0x02,0xFE,0x00, + /* 0xD8C0 [?] [5202]*/ + 0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x7F,0x41,0x41,0x41,0x41,0x41,0x7F,0x41, + 0x20,0x20,0x20,0x20,0xA0,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1E,0x00, + /* 0xD8C1 [?] [5203]*/ + 0x00,0x3F,0x00,0x00,0x00,0xFF,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0xF8,0x00,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD8C2 [?] [5204]*/ + 0x09,0x09,0xF9,0x09,0x09,0x01,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x20,0x20,0x3E,0x20,0x20,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xD8C3 [?] [5205]*/ + 0x01,0x01,0x3F,0x01,0x01,0x7F,0x40,0x80,0x0F,0x00,0x00,0xFF,0x01,0x01,0x05,0x02, + 0x00,0x00,0xF8,0x00,0x00,0xFE,0x02,0x04,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00, + /* 0xD8C4 [?] [5206]*/ + 0x01,0x01,0x7F,0x01,0x11,0x09,0xFF,0x00,0x3F,0x20,0x27,0x24,0x27,0x20,0x3F,0x20, + 0x00,0x00,0xFC,0x00,0x10,0x20,0xFE,0x00,0xF8,0x08,0xC8,0x48,0xC8,0x08,0xF8,0x08, + /* 0xD8C5 [?] [5207]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x7D,0x45,0x45,0x45,0x45,0x7D,0x45,0x01, + 0x00,0xDC,0x44,0x44,0x44,0xDC,0x00,0x00,0xDC,0x14,0x14,0xD4,0x08,0x08,0x14,0x22, + /* 0xD8C6 [?] [5208]*/ + 0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x21,0x22,0x42,0x44,0x88,0x10, + 0x00,0xFE,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x08,0x06, + /* 0xD8C7 [?] [5209]*/ + 0x00,0x3F,0x20,0x20,0x20,0x2F,0x21,0x22,0x24,0x27,0x20,0x20,0x4F,0x40,0x80,0x00, + 0x00,0xFE,0x00,0x80,0x80,0xFC,0x00,0x40,0x40,0xFC,0x40,0x40,0xFE,0x40,0x40,0x40, + /* 0xD8C8 [?] [5210]*/ + 0x00,0x3F,0x22,0x22,0x2F,0x22,0x22,0x3F,0x20,0x27,0x24,0x24,0x47,0x44,0x84,0x07, + 0x00,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8, + /* 0xD8C9 [?] [5211]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x21,0x26,0x38,0x2F,0x28,0x2F,0x28,0x4F,0x48,0x80,0x00, + 0x00,0xFE,0xA0,0x90,0xFE,0x40,0x30,0x0E,0xF8,0x88,0xF8,0x88,0xF8,0x88,0x80,0x80, + /* 0xD8CA [?] [5212]*/ + 0x00,0x3F,0x20,0x28,0x25,0x2F,0x22,0x22,0x2A,0x2A,0x2F,0x22,0x42,0x44,0x84,0x08, + 0x00,0xFE,0x00,0x90,0x10,0xBE,0x22,0x44,0x90,0x90,0x90,0x10,0x28,0x28,0x44,0x82, + /* 0xD8CB [?] [5213]*/ + 0x00,0x3F,0x29,0x29,0x3F,0x29,0x29,0x2F,0x29,0x2F,0x29,0x29,0x5F,0x40,0x8A,0x11, + 0x00,0xFE,0x00,0x0C,0xB0,0x20,0x20,0x3E,0x28,0x28,0x28,0x28,0xA8,0x48,0x88,0x08, + /* 0xD8CC [?] [5214]*/ + 0x3F,0x20,0x3F,0x21,0x26,0x38,0x27,0x20,0x2F,0x2A,0x2B,0x2A,0x4B,0x4A,0x8F,0x08, + 0xFC,0x90,0xFC,0x40,0x30,0x0C,0xF0,0x80,0xF8,0x28,0xE8,0x28,0xE8,0x28,0xF8,0x08, + /* 0xD8CD [?] [5215]*/ + 0x3F,0x22,0x24,0x2D,0x36,0x24,0x24,0x24,0x24,0x20,0x27,0x24,0x44,0x40,0x83,0x1C, + 0xFE,0x50,0xFE,0x90,0xFC,0x90,0xFC,0x90,0xFE,0x00,0xFC,0x44,0x44,0xB0,0x0C,0x02, + /* 0xD8CE [?] [5216]*/ + 0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xD8CF [?] [5217]*/ + 0x00,0x7F,0x40,0x40,0x40,0x47,0x44,0x44,0x44,0x44,0x47,0x44,0x40,0x40,0x7F,0x00, + 0x00,0xFC,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10,0x00,0x00,0xFE,0x00, + /* 0xD8D0 [?] [5218]*/ + 0x00,0x7F,0x44,0x44,0x5F,0x48,0x52,0x5F,0x42,0x43,0x5E,0x4A,0x42,0x42,0x7F,0x00, + 0x00,0xFC,0x20,0x20,0xA0,0x78,0x28,0xA8,0x28,0xA8,0x2A,0x2A,0x46,0x80,0xFE,0x00, + /* 0xD8D1 [?] [5219]*/ + 0x00,0x7F,0x40,0x4F,0x48,0x4F,0x40,0x7F,0x40,0x4F,0x48,0x49,0x42,0x4C,0x7F,0x00, + 0x00,0xFC,0x80,0xF8,0x88,0xF8,0x80,0xFE,0x00,0xF8,0x88,0x68,0x10,0x08,0xFE,0x00, + /* 0xD8D2 [?] [5220]*/ + 0x00,0x7F,0x40,0x4F,0x48,0x4F,0x48,0x4F,0x59,0x69,0x4F,0x49,0x49,0x40,0x7F,0x00, + 0x00,0xFC,0x80,0xF8,0x08,0xF8,0x00,0xFC,0x24,0x24,0xFC,0x24,0x2C,0x00,0xFE,0x00, + /* 0xD8D3 [?] [5221]*/ + 0x00,0x7D,0x48,0x48,0x48,0x5D,0x54,0x55,0x55,0x5D,0x49,0x49,0x49,0x7E,0x00,0x03, + 0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xD8D4 [?] [5222]*/ + 0x08,0x08,0x7F,0x08,0x08,0x08,0xFF,0x00,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40, + 0x20,0x20,0x20,0x20,0x20,0x30,0xA8,0x24,0x22,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xD8D5 [?] [5223]*/ + 0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0x88,0x08,0x08,0xF8,0x08, + /* 0xD8D6 [?] [5224]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x04,0x04,0x04,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x04,0x04,0x04,0x14,0x08, + /* 0xD8D7 [?] [5225]*/ + 0x00,0x01,0x01,0x21,0x11,0x0A,0x0A,0x04,0x04,0x0A,0x0A,0x11,0x21,0x40,0x80,0x00, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8D8 [?] [5226]*/ + 0x20,0x20,0x20,0x3F,0x54,0x94,0x14,0x24,0x24,0x48,0x88,0x10,0x20,0x40,0x85,0x02, + 0x04,0x04,0x04,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x84,0x84,0x14,0x08, + /* 0xD8D9 [?] [5227]*/ + 0x00,0x7F,0x02,0x04,0x0C,0x12,0x21,0xC0,0x00,0x7F,0x08,0x08,0x08,0x0F,0xF0,0x40, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0xA4,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DA [?] [5228]*/ + 0x08,0x08,0xFF,0x14,0x22,0x41,0xBE,0x00,0xFF,0x10,0x20,0x7F,0x01,0x01,0x0A,0x04, + 0x04,0x04,0x84,0x24,0x24,0x24,0xA4,0x24,0xA4,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DB [?] [5229]*/ + 0x08,0x49,0x49,0x49,0x7F,0x10,0x10,0x3F,0x41,0xA1,0x12,0x14,0x08,0x10,0x20,0xC0, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DC [?] [5230]*/ + 0x08,0x49,0x49,0x49,0x7F,0x00,0x7F,0x01,0x01,0x3F,0x20,0x20,0x23,0x2C,0x30,0x00, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DD [?] [5231]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7F,0x49,0x49,0x7F,0x08,0x1C,0x2A,0x49,0x88,0x08,0x08, + 0x04,0x04,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DE [?] [5232]*/ + 0x08,0x08,0x7F,0x14,0x22,0x41,0xFF,0x01,0x79,0x49,0x49,0x49,0x79,0x01,0x05,0x02, + 0x04,0x04,0x84,0x24,0x24,0x24,0xE4,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD8DF [?] [5233]*/ + 0x08,0x09,0x49,0x4A,0x88,0x14,0x22,0x49,0x88,0x49,0x49,0x8A,0x14,0x22,0x41,0x80, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x88, + /* 0xD8E0 [?] [5234]*/ + 0x08,0x04,0x7F,0x40,0x20,0x3B,0x2A,0x2A,0x2A,0x5A,0x4B,0x8A,0x12,0x12,0x23,0x42, + 0x04,0x04,0x84,0xA4,0x24,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x24,0x04,0x84,0x14,0x08, + /* 0xD8E1 [?] [5235]*/ + 0x11,0x11,0xFF,0x11,0x00,0x7B,0x4A,0x4A,0x7B,0x4A,0x4A,0x7B,0x4A,0x4A,0xAB,0x14, + 0x02,0x02,0xE2,0x0A,0x0A,0xCA,0x4A,0x4A,0xCA,0x4A,0x4A,0xCA,0x42,0x42,0x4A,0x84, + /* 0xD8E2 [?] [5236]*/ + 0x00,0xFF,0x0A,0x7F,0x4A,0x4A,0x7F,0x00,0x7F,0x00,0xFF,0x04,0x24,0x44,0x94,0x08, + 0x02,0xE2,0x02,0xC2,0x52,0x52,0xD2,0x12,0xD2,0x12,0xF2,0x12,0x82,0x42,0x2A,0x04, + /* 0xD8E3 [?] [5237]*/ + 0x00,0x7F,0x40,0x51,0x4A,0x5F,0x44,0x44,0x55,0x55,0x5F,0x44,0x44,0x48,0x49,0x92, + 0x02,0xF2,0x02,0x4A,0x4A,0x7A,0x9A,0x2A,0x0A,0x4A,0x4A,0x4A,0xA2,0xA2,0x2A,0x04, + /* 0xD8E4 [?] [5238]*/ + 0x12,0x11,0x3F,0x22,0x62,0xBF,0x22,0x22,0x3F,0x22,0x22,0x3F,0x20,0x54,0x4A,0x8A, + 0x02,0x02,0xC2,0x02,0x12,0xD2,0x12,0x12,0xD2,0x12,0x12,0xD2,0x02,0x82,0x4A,0x44, + /* 0xD8E5 [?] [5239]*/ + 0x11,0x7F,0x15,0x12,0x3F,0x64,0xBF,0x24,0x3F,0x24,0x3F,0x20,0x7F,0x11,0x0E,0x71, + 0x02,0xC2,0x02,0x02,0xD2,0x12,0x92,0x12,0x92,0x12,0xD2,0x12,0x82,0x02,0x0A,0x84, + /* 0xD8E6 [?] [5240]*/ + 0x08,0x3F,0x20,0x3F,0x20,0x3F,0x00,0x7F,0x44,0x7F,0x44,0x7F,0x00,0xFF,0x11,0x21, + 0x02,0x82,0x82,0x82,0x92,0x92,0x12,0xD2,0x52,0xD2,0x52,0xD2,0x02,0xE2,0x0A,0x04, + /* 0xD8E7 [?] [5241]*/ + 0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xD8E8 [?] [5242]*/ + 0x00,0x7F,0x40,0x48,0x44,0x5F,0x41,0x40,0x5F,0x44,0x44,0x44,0x47,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x24,0x44,0xF4,0x04,0x84,0xF4,0x04,0x04,0x04,0xE4,0x04,0x14,0x08, + /* 0xD8E9 [?] [5243]*/ + 0x08,0x08,0x08,0x10,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD8EA [?] [5244]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xD8EB [?] [5245]*/ + 0x08,0x09,0x09,0x11,0x11,0x31,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xD8EC [?] [5246]*/ + 0x08,0x08,0x08,0x10,0x13,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xD8ED [?] [5247]*/ + 0x08,0x08,0x0B,0x10,0x10,0x30,0x30,0x51,0x90,0x10,0x10,0x10,0x10,0x17,0x10,0x10, + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00, + /* 0xD8EE [?] [5248]*/ + 0x08,0x08,0x09,0x11,0x12,0x34,0x31,0x50,0x90,0x10,0x10,0x11,0x12,0x12,0x11,0x10, + 0x80,0x80,0x00,0xFE,0x00,0x00,0xF8,0x08,0x10,0x60,0x80,0x00,0x02,0x02,0xFE,0x00, + /* 0xD8EF [?] [5249]*/ + 0x08,0x08,0x08,0x10,0x11,0x31,0x32,0x54,0x90,0x10,0x10,0x11,0x12,0x17,0x12,0x10, + 0x40,0x40,0x80,0x80,0x00,0x10,0x10,0x20,0x20,0x40,0x80,0x08,0x04,0xFE,0x02,0x00, + /* 0xD8F0 [?] [5250]*/ + 0x08,0x08,0x0B,0x10,0x10,0x32,0x32,0x52,0x94,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x04,0x28,0x10, + /* 0xD8F1 [?] [5251]*/ + 0x08,0x0B,0x0A,0x12,0x12,0x32,0x32,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x13,0x10, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xD8F2 [?] [5252]*/ + 0x08,0x0A,0x0A,0x12,0x12,0x32,0x33,0x52,0x92,0x12,0x12,0x12,0x12,0x13,0x12,0x10, + 0x20,0x20,0x20,0x22,0x22,0x24,0xA8,0x30,0x20,0x20,0x20,0x22,0xA2,0x22,0x1E,0x00, + /* 0xD8F3 [?] [5253]*/ + 0x08,0x0B,0x08,0x11,0x11,0x31,0x32,0x53,0x90,0x10,0x10,0x11,0x12,0x14,0x10,0x10, + 0x00,0xFC,0x10,0x10,0x10,0x10,0x10,0xFE,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xD8F4 [?] [5254]*/ + 0x08,0x08,0x0F,0x11,0x11,0x31,0x31,0x51,0x91,0x12,0x12,0x12,0x12,0x12,0x13,0x12, + 0x00,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0x90,0x50,0x50,0x10,0x12,0x92,0x12,0x0E, + /* 0xD8F5 [?] [5255]*/ + 0x11,0x11,0x11,0x23,0x22,0x62,0x64,0xA0,0x20,0x2F,0x20,0x20,0x20,0x20,0x20,0x20, + 0x00,0x00,0x00,0xF8,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xD8F6 [?] [5256]*/ + 0x09,0x09,0x09,0x11,0x11,0x31,0x31,0x57,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0x08,0x08,0x10,0x20,0x40,0x00,0xFE,0x40,0x20,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xD8F7 [?] [5257]*/ + 0x08,0x08,0x08,0x11,0x12,0x34,0x3B,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x11,0x10, + 0x40,0x40,0xA0,0x10,0x08,0x04,0xF2,0x10,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xD8F8 [?] [5258]*/ + 0x08,0x08,0x08,0x13,0x10,0x30,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xD8F9 [?] [5259]*/ + 0x08,0x08,0x08,0x10,0x13,0x32,0x34,0x50,0x90,0x10,0x10,0x10,0x10,0x13,0x10,0x10, + 0x40,0x20,0x20,0x00,0xFE,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00, + /* 0xD8FA [?] [5260]*/ + 0x10,0x13,0x10,0x20,0x2F,0x60,0x60,0xAF,0x21,0x22,0x26,0x21,0x20,0x20,0x23,0x2C, + 0x00,0xF8,0x00,0x00,0xFE,0x80,0x80,0xFE,0x08,0x10,0x10,0xA0,0x60,0x90,0x08,0x04, + /* 0xD8FB [?] [5261]*/ + 0x08,0x08,0x08,0x10,0x10,0x30,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x40,0x40,0x50,0x48,0x44,0x40,0x40,0x40, + /* 0xD8FC [?] [5262]*/ + 0x08,0x08,0x08,0x10,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x10,0x10,0x11, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xD8FD [?] [5263]*/ + 0x10,0x10,0x12,0x22,0x23,0x62,0x64,0xA0,0x2F,0x20,0x20,0x20,0x21,0x22,0x24,0x28, + 0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x04,0x02, + /* 0xD8FE [?] [5264]*/ + 0x11,0x11,0x12,0x23,0x24,0x68,0x63,0xA2,0x22,0x22,0x22,0x23,0x22,0x20,0x20,0x20, + 0x00,0x00,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0x24,0xE4,0x24,0x04,0x28,0x10, + /* 0xD9A1 [?] [5265]*/ + 0x08,0x08,0x08,0x11,0x13,0x34,0x30,0x50,0x93,0x1C,0x10,0x10,0x10,0x11,0x10,0x10, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xC0,0x20,0x10,0x80,0x60,0x10, + /* 0xD9A2 [?] [5266]*/ + 0x08,0x08,0x08,0x13,0x12,0x34,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x10,0x10, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x08,0x10,0x20,0xC0,0x02,0x02,0x02,0xFE,0x00, + /* 0xD9A3 [?] [5267]*/ + 0x08,0x0B,0x0A,0x12,0x12,0x33,0x32,0x52,0x92,0x12,0x12,0x12,0x14,0x14,0x18,0x10, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xD9A4 [?] [5268]*/ + 0x14,0x14,0x14,0x24,0x2F,0x64,0x64,0xA4,0x24,0x24,0x24,0x24,0x28,0x28,0x32,0x21, + 0x00,0x00,0x00,0x3C,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xBC,0xA4,0x00, + /* 0xD9A5 [?] [5269]*/ + 0x08,0x08,0x08,0x1F,0x10,0x30,0x37,0x50,0x90,0x13,0x12,0x12,0x12,0x12,0x13,0x12, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xD9A6 [?] [5270]*/ + 0x08,0x0B,0x09,0x11,0x11,0x31,0x31,0x51,0x91,0x11,0x11,0x11,0x17,0x10,0x10,0x10, + 0x00,0xFE,0x08,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x1E,0xE8,0x08,0x08,0x08, + /* 0xD9A7 [?] [5271]*/ + 0x08,0x08,0x0F,0x10,0x11,0x31,0x33,0x55,0x99,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x40,0x40,0xFE,0x80,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xD9A8 [?] [5272]*/ + 0x10,0x10,0x17,0x20,0x21,0x62,0x6D,0xA0,0x27,0x20,0x21,0x23,0x20,0x20,0x20,0x20, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xF6,0x00,0xFC,0x80,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xD9A9 [?] [5273]*/ + 0x10,0x17,0x14,0x24,0x24,0x67,0x60,0xA2,0x22,0x22,0x22,0x22,0x22,0x24,0x24,0x28, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x48,0x48,0x48,0x48,0x48,0x4A,0x4A,0x4A,0x06, + /* 0xD9AA [?] [5274]*/ + 0x08,0x0A,0x0A,0x13,0x14,0x30,0x30,0x57,0x90,0x11,0x11,0x12,0x14,0x18,0x10,0x10, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40, + /* 0xD9AB [?] [5275]*/ + 0x08,0x09,0x09,0x12,0x14,0x3B,0x32,0x52,0x93,0x12,0x12,0x13,0x12,0x12,0x12,0x12, + 0x10,0x10,0x08,0x08,0x04,0xFA,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xD9AC [?] [5276]*/ + 0x08,0x08,0x08,0x14,0x12,0x30,0x30,0x51,0x92,0x14,0x10,0x10,0x11,0x11,0x12,0x14, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xD9AD [?] [5277]*/ + 0x08,0x08,0x0F,0x12,0x11,0x30,0x30,0x51,0x96,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x80,0x40,0xFE,0x08,0x10,0xA0,0x40,0xB0,0x0E,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xD9AE [?] [5278]*/ + 0x10,0x10,0x10,0x27,0x20,0x61,0x62,0xA4,0x21,0x21,0x20,0x20,0x20,0x21,0x22,0x2C, + 0x80,0x40,0x40,0xFC,0x00,0x10,0x08,0x04,0x10,0x10,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xD9AF [?] [5279]*/ + 0x10,0x10,0x10,0x27,0x24,0x68,0x61,0xA1,0x23,0x25,0x29,0x21,0x21,0x21,0x21,0x21, + 0x40,0x40,0x40,0xFC,0x84,0x88,0x40,0x44,0x48,0x30,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xD9B0 [?] [5280]*/ + 0x08,0x08,0x08,0x11,0x13,0x30,0x31,0x51,0x91,0x12,0x10,0x17,0x10,0x10,0x10,0x10, + 0x40,0x40,0x90,0x08,0xFC,0x24,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xD9B1 [?] [5281]*/ + 0x10,0x10,0x17,0x20,0x23,0x60,0x67,0xA0,0x21,0x21,0x22,0x22,0x24,0x28,0x20,0x20, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFE,0x90,0x10,0xFE,0x10,0x90,0x50,0x10,0x50,0x20, + /* 0xD9B2 [?] [5282]*/ + 0x08,0x0B,0x08,0x12,0x11,0x30,0x33,0x52,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18, + 0x00,0xFC,0x90,0x94,0x98,0x90,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD9B3 [?] [5283]*/ + 0x10,0x1F,0x10,0x20,0x27,0x64,0x64,0xA4,0x26,0x25,0x24,0x24,0x24,0x24,0x24,0x25, + 0x00,0xFE,0x00,0x00,0xBC,0xA4,0xA4,0xA4,0xB4,0xAC,0xA4,0xA4,0xA4,0xA4,0xA4,0xAC, + /* 0xD9B4 [?] [5284]*/ + 0x08,0x08,0x08,0x10,0x17,0x30,0x32,0x51,0x91,0x10,0x11,0x12,0x14,0x10,0x11,0x10, + 0x50,0x48,0x48,0x40,0xFE,0x40,0x44,0x64,0x68,0xD0,0x50,0x48,0x44,0x42,0x40,0x80, + /* 0xD9B5 [?] [5285]*/ + 0x10,0x17,0x14,0x24,0x27,0x64,0x64,0xA7,0x20,0x20,0x27,0x20,0x20,0x20,0x2F,0x20, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xD9B6 [?] [5286]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x30,0x30,0x57,0x90,0x10,0x1F,0x10,0x10,0x11,0x12,0x14, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xD9B7 [?] [5287]*/ + 0x10,0x10,0x17,0x24,0x27,0x64,0x67,0xA0,0x3F,0x21,0x22,0x23,0x20,0x20,0x20,0x20, + 0x40,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xD9B8 [?] [5288]*/ + 0x10,0x17,0x10,0x21,0x20,0x67,0x64,0xA4,0x27,0x24,0x24,0x27,0x24,0x24,0x24,0x24, + 0x00,0xF8,0x10,0xA0,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xD9B9 [?] [5289]*/ + 0x10,0x10,0x11,0x22,0x27,0x61,0x61,0xA3,0x24,0x20,0x2F,0x20,0x20,0x21,0x22,0x2C, + 0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xD9BA [?] [5290]*/ + 0x08,0x08,0x0F,0x10,0x13,0x30,0x37,0x51,0x92,0x14,0x11,0x10,0x17,0x10,0x10,0x10, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x48,0x46,0xF0,0x40,0xFC,0x40,0x40,0x40, + /* 0xD9BB [?] [5291]*/ + 0x08,0x08,0x0F,0x10,0x13,0x30,0x37,0x50,0x93,0x12,0x13,0x12,0x13,0x12,0x12,0x12, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xD9BC [?] [5292]*/ + 0x11,0x11,0x17,0x21,0x21,0x60,0x67,0xA0,0x21,0x23,0x25,0x29,0x21,0x21,0x21,0x21, + 0x08,0x08,0xFE,0x08,0x48,0x40,0xFE,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xD9BD [?] [5293]*/ + 0x08,0x08,0x08,0x17,0x10,0x30,0x30,0x53,0x90,0x10,0x10,0x17,0x10,0x10,0x10,0x10, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xD9BE [?] [5294]*/ + 0x08,0x08,0x08,0x10,0x13,0x32,0x33,0x52,0x93,0x12,0x10,0x17,0x10,0x10,0x10,0x10, + 0x40,0x40,0x7E,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x44,0x40,0xFE,0x40,0x40,0x40,0x40, + /* 0xD9BF [?] [5295]*/ + 0x10,0x10,0x11,0x21,0x2A,0x6C,0xA9,0x2E,0x28,0x28,0x2B,0x28,0x28,0x21,0x22,0x24, + 0x80,0x80,0xF8,0x08,0x90,0x60,0x98,0x46,0x50,0x48,0xFC,0x40,0xA0,0x10,0x08,0x04, + /* 0xD9C0 [?] [5296]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x32,0x32,0x53,0x90,0x17,0x10,0x11,0x12,0x14,0x10,0x10, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xD9C1 [?] [5297]*/ + 0x08,0x0B,0x08,0x10,0x17,0x31,0x32,0x54,0x90,0x17,0x11,0x12,0x11,0x10,0x10,0x13, + 0x38,0xC0,0x40,0x40,0xFC,0x50,0x48,0x86,0x80,0xFC,0x10,0x10,0xA0,0x60,0x90,0x08, + /* 0xD9C2 [?] [5298]*/ + 0x08,0x08,0x0B,0x12,0x12,0x33,0x32,0x52,0x93,0x10,0x11,0x17,0x10,0x10,0x10,0x10, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xD9C3 [?] [5299]*/ + 0x10,0x17,0x14,0x24,0x25,0x64,0x64,0xA7,0x24,0x25,0x25,0x25,0x25,0x24,0x24,0x28, + 0x00,0xFC,0x44,0x44,0xF4,0x44,0x44,0xFC,0x04,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xD9C4 [?] [5300]*/ + 0x08,0x08,0x0B,0x12,0x14,0x31,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD9C5 [?] [5301]*/ + 0x08,0x08,0x08,0x13,0x12,0x34,0x31,0x52,0x90,0x11,0x10,0x10,0x10,0x10,0x17,0x10, + 0x40,0x20,0x20,0xFE,0x02,0x94,0x08,0x04,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xD9C6 [?] [5302]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x32,0x32,0x53,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xD9C7 [?] [5303]*/ + 0x10,0x10,0x17,0x20,0x22,0x6F,0x62,0xA0,0x27,0x24,0x24,0x24,0x24,0x20,0x23,0x2C, + 0x40,0x40,0xFC,0x40,0x48,0xFE,0x08,0x00,0xFC,0x04,0x44,0x44,0x44,0xB0,0x0C,0x02, + /* 0xD9C8 [?] [5304]*/ + 0x08,0x0B,0x0A,0x12,0x12,0x32,0x32,0x52,0x92,0x13,0x12,0x12,0x12,0x12,0x12,0x13, + 0x00,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x20,0xFE,0x48,0xC8,0x30,0x48,0x84,0xFE, + /* 0xD9C9 [?] [5305]*/ + 0x0A,0x0A,0x0B,0x12,0x12,0x33,0x32,0x50,0x93,0x12,0x12,0x13,0x12,0x12,0x13,0x12, + 0x20,0x24,0xA8,0x30,0xA2,0x22,0x5E,0x80,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xD9CA [?] [5306]*/ + 0x08,0x0B,0x0A,0x13,0x12,0x33,0x31,0x53,0x94,0x12,0x12,0x12,0x13,0x10,0x10,0x10, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xD9CB [?] [5307]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x32,0x32,0x53,0x90,0x17,0x12,0x12,0x12,0x12,0x13,0x12, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x00,0xFE,0x40,0x44,0x28,0x90,0x08,0x06, + /* 0xD9CC [?] [5308]*/ + 0x11,0x11,0x13,0x24,0x2B,0x61,0x62,0xA4,0x21,0x22,0x20,0x21,0x25,0x25,0x28,0x20, + 0x00,0x00,0xFC,0x94,0x94,0x64,0x54,0x84,0x28,0x10,0x40,0x24,0x2A,0x0A,0xF8,0x00, + /* 0xD9CD [?] [5309]*/ + 0x08,0x09,0x08,0x10,0x13,0x30,0x31,0x52,0x90,0x17,0x10,0x11,0x11,0x10,0x11,0x16, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xD9CE [?] [5310]*/ + 0x08,0x0A,0x09,0x10,0x17,0x34,0x38,0x53,0x92,0x12,0x13,0x10,0x11,0x11,0x12,0x14, + 0x40,0x48,0x50,0x40,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0xA0,0x20,0x24,0x24,0x1C, + /* 0xD9CF [?] [5311]*/ + 0x10,0x10,0x17,0x24,0x28,0x63,0x62,0xA2,0x23,0x22,0x22,0x2F,0x20,0x21,0x22,0x24, + 0x80,0x40,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x10,0x08,0x04, + /* 0xD9D0 [?] [5312]*/ + 0x10,0x10,0x17,0x21,0x21,0x69,0x65,0xA5,0x22,0x22,0x25,0x25,0x29,0x20,0x20,0x20, + 0x28,0x24,0x40,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x48,0x7E,0x40,0x40, + /* 0xD9D1 [?] [5313]*/ + 0x09,0x09,0x0B,0x12,0x15,0x32,0x31,0x52,0x94,0x10,0x13,0x10,0x11,0x12,0x15,0x10, + 0x00,0x10,0xDC,0x54,0x54,0x88,0x08,0xF4,0x02,0x00,0xFC,0x40,0x50,0x48,0x44,0x80, + /* 0xD9D2 [?] [5314]*/ + 0x10,0x17,0x10,0x23,0x20,0x63,0x62,0xA3,0x21,0x2F,0x20,0x23,0x22,0x22,0x23,0x22, + 0x40,0xFC,0x40,0xF8,0x00,0xF8,0x08,0xF8,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xD9D3 [?] [5315]*/ + 0x12,0x12,0x17,0x22,0x24,0x67,0x64,0xA8,0x27,0x25,0x25,0x27,0x25,0x20,0x22,0x21, + 0x88,0x88,0xE8,0x90,0x1E,0xE4,0x54,0x54,0x54,0x54,0x54,0x48,0x48,0x54,0x94,0x22, + /* 0xD9D4 [?] [5316]*/ + 0x10,0x17,0x11,0x25,0x27,0x63,0x65,0xA9,0x20,0x23,0x22,0x22,0x23,0x22,0x22,0x23, + 0x00,0xBC,0x08,0x28,0xBC,0x18,0xAA,0x46,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8, + /* 0xD9D5 [?] [5317]*/ + 0x11,0x11,0x13,0x22,0x26,0x6B,0x62,0xA2,0x23,0x22,0x22,0x23,0x22,0x25,0x24,0x28, + 0x40,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x24,0x92,0x92, + /* 0xD9D6 [?] [5318]*/ + 0x14,0x12,0x1F,0x20,0x20,0x6F,0x68,0xA8,0x2F,0x22,0x2B,0x2A,0x32,0x22,0x2A,0x24, + 0x14,0x12,0x92,0x10,0x7E,0x90,0x90,0x90,0x90,0x28,0x28,0xA8,0x28,0x4A,0x4A,0x86, + /* 0xD9D7 [?] [5319]*/ + 0x08,0x0B,0x09,0x10,0x17,0x30,0x33,0x52,0x93,0x12,0x13,0x10,0x13,0x10,0x17,0x10, + 0x40,0xF8,0x10,0xA0,0xFC,0x00,0xF8,0x48,0xF8,0x48,0xF8,0x40,0xF8,0x40,0xFE,0x00, + /* 0xD9D8 [?] [5320]*/ + 0x08,0x0B,0x0A,0x12,0x13,0x30,0x37,0x50,0x93,0x12,0x13,0x10,0x11,0x13,0x1D,0x11, + 0x00,0xFC,0x94,0x94,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0xA2,0x14,0x08,0x44,0x82, + /* 0xD9D9 [?] [5321]*/ + 0x12,0x13,0x14,0x27,0x2D,0x76,0x67,0xA4,0x25,0x24,0x25,0x24,0x25,0x29,0x29,0x31, + 0x00,0xF8,0x10,0xFE,0x48,0x24,0xFE,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x04,0xFC,0x04, + /* 0xD9DA [?] [5322]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x20,0xC0,0x1F,0x01,0x01,0x01,0x01,0x01,0x7F,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0xF0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00, + /* 0xD9DB [?] [5323]*/ + 0x01,0x02,0x04,0x08,0x31,0xC1,0x01,0x3D,0x05,0x09,0x09,0x11,0x21,0xC1,0x05,0x02, + 0x00,0x80,0x40,0x20,0x18,0x06,0x00,0x84,0x88,0x50,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xD9DC [?] [5324]*/ + 0x01,0x01,0x02,0x04,0x08,0x30,0xCF,0x00,0x00,0x7F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xFC,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xD9DD [?] [5325]*/ + 0x01,0x01,0x02,0x04,0x08,0x10,0x2F,0xC0,0x02,0x11,0x09,0x09,0x08,0x00,0x7F,0x00, + 0x00,0x00,0x80,0x40,0x20,0x10,0xE8,0x06,0x10,0x10,0x10,0x20,0x20,0x40,0xFC,0x00, + /* 0xD9DE [?] [5326]*/ + 0x10,0x11,0x11,0x29,0x25,0x45,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x07,0x00, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xD9DF [?] [5327]*/ + 0x01,0x02,0x0C,0x30,0xDF,0x00,0x3B,0x2A,0x3B,0x00,0x3F,0x24,0x3F,0x24,0x24,0x20, + 0x00,0x80,0x60,0x18,0xF6,0x00,0xB8,0xA8,0xB8,0x00,0xF8,0x88,0xF8,0x88,0xA8,0x10, + /* 0xD9E0 [?] [5328]*/ + 0x06,0x01,0x02,0x0C,0x31,0xC1,0x01,0x3D,0x05,0x09,0x09,0x11,0x21,0xC1,0x05,0x02, + 0x00,0x00,0x80,0x60,0x18,0x06,0x00,0x84,0x88,0x50,0x20,0x10,0x08,0x06,0x00,0x00, + /* 0xD9E1 [?] [5329]*/ + 0x06,0x01,0x02,0x04,0x18,0xE1,0x11,0x09,0x05,0x7F,0x05,0x09,0x11,0x21,0xC1,0x01, + 0x00,0x00,0x80,0x40,0x30,0x0E,0x10,0x20,0x40,0xFC,0x40,0x20,0x10,0x08,0x06,0x00, + /* 0xD9E2 [?] [5330]*/ + 0x04,0x04,0x08,0x08,0x10,0x20,0xDF,0x04,0x08,0x0F,0x00,0x00,0x00,0x00,0x01,0x00, + 0x40,0x40,0x20,0x20,0x10,0x08,0xF6,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x40,0x80, + /* 0xD9E3 [?] [5331]*/ + 0x00,0x7C,0x44,0x7C,0x40,0x42,0x3E,0x04,0x04,0x3F,0x04,0x04,0xFF,0x08,0x10,0x20, + 0x00,0xF8,0x88,0xF8,0x80,0x84,0x7C,0x40,0x40,0xF8,0x40,0x40,0xFE,0x20,0x10,0x08, + /* 0xD9E4 [?] [5332]*/ + 0x11,0x08,0x7F,0x44,0x9F,0x04,0x7F,0x01,0x1F,0x11,0x1F,0x11,0x1F,0x04,0x08,0x10, + 0x08,0x90,0xFE,0x42,0xF4,0x40,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x40,0x20,0x10, + /* 0xD9E5 [?] [5333]*/ + 0x44,0x24,0x28,0xFD,0x10,0x20,0x7D,0x45,0x45,0x7D,0x45,0x7C,0x44,0x47,0x7C,0x44, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD2,0x52,0x52,0x54,0xD4,0x08,0xCA,0x1A,0x26,0x42, + /* 0xD9E6 [?] [5334]*/ + 0x44,0x25,0x29,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x11,0x11,0xFD,0x12,0x12,0x14, + 0x00,0xFE,0x02,0x02,0xFE,0x24,0x24,0x7E,0x24,0x24,0xFE,0x52,0x54,0x48,0x64,0x42, + /* 0xD9E7 [?] [5335]*/ + 0x04,0xFF,0x11,0x13,0x52,0x5B,0x52,0x53,0x5A,0xE3,0x24,0x4F,0x94,0x03,0x1C,0xE0, + 0x40,0xFE,0x00,0xDC,0x54,0xD4,0x5C,0xD0,0x52,0xCE,0x08,0xE4,0x42,0x80,0x70,0x0E, + /* 0xD9E8 [?] [5336]*/ + 0x10,0x10,0x3F,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xD9E9 [?] [5337]*/ + 0x10,0x10,0x1F,0x22,0x42,0xBF,0x02,0x3F,0x22,0x3F,0x22,0x3F,0x22,0x22,0x22,0x20, + 0x00,0x00,0xFC,0x44,0x24,0xF4,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0x24,0xB4,0x48, + /* 0xD9EA [?] [5338]*/ + 0x10,0x10,0x1F,0x20,0x42,0xBF,0x00,0x1F,0x00,0x1F,0x00,0x1F,0x10,0x1F,0x10,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x04,0xC4,0x04,0xC4,0x04,0xC4,0x44,0xC4,0x54,0x08, + /* 0xD9EB [?] [5339]*/ + 0x10,0x10,0x1F,0x20,0x7F,0x80,0x1F,0x10,0x1F,0x00,0x3F,0x22,0x3F,0x22,0x3F,0x20, + 0x00,0x00,0xFC,0x04,0xE4,0x04,0xC4,0x44,0xC4,0x04,0xE4,0x24,0xE4,0x24,0xF4,0x28, + /* 0xD9EC [?] [5340]*/ + 0x02,0x04,0x3F,0x20,0x24,0x22,0x20,0x3F,0x00,0x1F,0x10,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0xE0,0x20,0x20,0xA0,0x40,0xF8,0x08,0x88,0xA8,0x90,0x82,0x82,0x7E,0x00, + /* 0xD9ED [?] [5341]*/ + 0x00,0x3F,0x20,0x20,0x2F,0x22,0x22,0x27,0x24,0x28,0x34,0x22,0x21,0x42,0x44,0x88, + 0x00,0xF8,0x08,0x08,0xE8,0x08,0x08,0xC8,0x48,0x48,0x88,0x8A,0x0A,0x0A,0x06,0x02, + /* 0xD9EE [?] [5342]*/ + 0x00,0x3C,0x24,0x24,0x24,0x27,0x20,0x20,0x3F,0x24,0x04,0x04,0x08,0x10,0x20,0xC0, + 0x00,0x78,0x48,0x48,0x48,0xC8,0x08,0x08,0xF8,0x48,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xD9EF [?] [5343]*/ + 0x02,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD9F0 [?] [5344]*/ + 0x02,0x01,0xFF,0x08,0x11,0x22,0x44,0x08,0x1F,0x04,0x04,0x08,0x08,0x10,0x20,0xC0, + 0x00,0x00,0xFE,0x20,0x10,0x08,0x44,0x20,0xF0,0x50,0x40,0x40,0x40,0x42,0x42,0x3E, + /* 0xD9F1 [?] [5345]*/ + 0x01,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x80,0x3F,0x02,0x03,0x7E,0x02,0x01, + 0x00,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0x00,0xF8,0x02,0x02,0xFE, + /* 0xD9F2 [?] [5346]*/ + 0x02,0x01,0xFF,0x00,0x08,0x12,0x24,0x48,0x1F,0x02,0x04,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0xFE,0x00,0x20,0x10,0x48,0x24,0xF0,0x90,0x44,0x28,0x10,0x08,0x06,0x00, + /* 0xD9F3 [?] [5347]*/ + 0x01,0xFF,0x00,0x1F,0x02,0x01,0x7F,0x04,0x18,0x62,0x03,0x04,0x0C,0x35,0xC6,0x04, + 0x00,0xFE,0x00,0xF0,0x20,0x40,0xFC,0x84,0x88,0x80,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xD9F4 [?] [5348]*/ + 0x01,0xFF,0x00,0x08,0x7D,0x08,0x0C,0x78,0x08,0x29,0x13,0x04,0x0C,0x35,0xC6,0x04, + 0x00,0xFE,0x00,0x40,0xF8,0x48,0xC8,0x4A,0xAA,0x06,0x02,0x88,0x50,0x30,0x0E,0x00, + /* 0xD9F5 [?] [5349]*/ + 0x02,0x01,0xFF,0x04,0x14,0x25,0x41,0x3F,0x22,0x24,0x29,0x21,0x22,0x24,0x20,0x20, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x04,0xF8,0x88,0x48,0x28,0x08,0x88,0x48,0x08,0x18, + /* 0xD9F6 [?] [5350]*/ + 0x02,0x01,0xFF,0x04,0x38,0x20,0x3C,0x20,0x3F,0x02,0x04,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0xFE,0x00,0x78,0x08,0x78,0x08,0xF8,0x80,0x44,0x28,0x10,0x08,0x06,0x00, + /* 0xD9F7 [?] [5351]*/ + 0x01,0xFF,0x00,0x3F,0x20,0x27,0x24,0x27,0x20,0x3F,0x00,0x3F,0x00,0xFF,0x11,0x23, + 0x00,0xFE,0x00,0xF8,0x08,0xC8,0x48,0xC8,0x08,0xF8,0x00,0xF8,0x00,0xFE,0x10,0x08, + /* 0xD9F8 [?] [5352]*/ + 0x01,0xFF,0x20,0x3F,0x00,0x3F,0x20,0x3F,0x01,0x79,0x4F,0x7A,0x4A,0x79,0x4A,0x9C, + 0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x00,0x38,0xA8,0xA8,0xB8,0x2A,0xAA,0x46, + /* 0xD9F9 [?] [5353]*/ + 0x01,0xFF,0x20,0x3F,0x00,0x3F,0x20,0x3F,0x00,0x71,0x57,0x75,0x57,0x71,0x57,0xB0, + 0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x00,0x1C,0xD4,0x54,0xDC,0x56,0xD6,0x62, + /* 0xD9FA [?] [5354]*/ + 0x01,0xFF,0x20,0x3F,0x00,0x3F,0x20,0x3F,0x04,0x72,0x57,0x71,0x53,0x71,0x57,0xB1, + 0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x40,0x9C,0xD4,0x14,0x9C,0x16,0xD6,0x22, + /* 0xD9FB [?] [5355]*/ + 0x00,0x40,0x20,0x20,0x00,0x08,0x08,0x10,0x10,0xE0,0x20,0x20,0x20,0x20,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xD9FC [?] [5356]*/ + 0x00,0x47,0x20,0x20,0x00,0x08,0x09,0x11,0x11,0x22,0xE3,0x20,0x20,0x20,0x27,0x00, + 0x00,0xFE,0x80,0x80,0x80,0xF8,0x08,0x08,0x08,0x08,0xF8,0x10,0x10,0x10,0xFE,0x00, + /* 0xD9FD [?] [5357]*/ + 0x00,0x40,0x2F,0x22,0x02,0x03,0x12,0x14,0x26,0xE5,0x29,0x21,0x22,0x22,0x24,0x08, + 0x04,0x04,0xC4,0x24,0x24,0xA4,0xA4,0xA4,0xA4,0xA4,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xD9FE [?] [5358]*/ + 0x00,0x42,0x22,0x23,0x04,0x00,0x10,0x17,0x21,0xE1,0x21,0x21,0x22,0x22,0x24,0x08, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xDAA1 [?] [5359]*/ + 0x02,0x42,0x22,0x22,0x0F,0x02,0x12,0x16,0x27,0xEA,0x2A,0x32,0x22,0x22,0x22,0x02, + 0x08,0x28,0x28,0x28,0xA4,0x44,0x54,0x92,0x10,0xA0,0x20,0x28,0x44,0xFC,0x44,0x00, + /* 0xDAA2 [?] [5360]*/ + 0x00,0x7F,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xFE,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDAA3 [?] [5361]*/ + 0x00,0x7F,0x40,0x80,0x7F,0x02,0x06,0x19,0x6A,0x04,0x1B,0x62,0x0C,0x30,0xC2,0x01, + 0x00,0xFE,0x02,0x04,0xFC,0x00,0x08,0x10,0xA0,0xC0,0xA0,0x98,0x86,0x80,0x80,0x00, + /* 0xDAA4 [?] [5362]*/ + 0x00,0x7F,0x40,0x80,0x1F,0x10,0x1F,0x10,0x1F,0x12,0x01,0xFF,0x00,0x08,0x10,0x20, + 0x00,0xFE,0x02,0x04,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x00,0xFE,0x00,0x20,0x10,0x08, + /* 0xDAA5 [?] [5363]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDAA6 [?] [5364]*/ + 0x00,0x20,0x13,0x10,0x00,0x00,0xF0,0x10,0x17,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xDAA7 [?] [5365]*/ + 0x00,0x20,0x13,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x07,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xDAA8 [?] [5366]*/ + 0x00,0x20,0x10,0x10,0x01,0x01,0xF1,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00, + /* 0xDAA9 [?] [5367]*/ + 0x00,0x23,0x12,0x12,0x02,0x02,0xF2,0x12,0x12,0x12,0x12,0x12,0x17,0x1A,0x13,0x00, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xDAAA [?] [5368]*/ + 0x00,0x23,0x12,0x12,0x02,0x03,0xF2,0x12,0x12,0x12,0x13,0x12,0x16,0x1A,0x13,0x00, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xDAAB [?] [5369]*/ + 0x00,0x20,0x10,0x10,0x03,0x02,0xF2,0x12,0x12,0x12,0x12,0x13,0x16,0x1A,0x12,0x02, + 0x20,0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xDAAC [?] [5370]*/ + 0x00,0x20,0x10,0x10,0x03,0x00,0xF0,0x10,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAAD [?] [5371]*/ + 0x00,0x20,0x17,0x10,0x00,0x03,0xF2,0x12,0x12,0x12,0x13,0x12,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0x48,0x48,0xC8,0x48,0x08,0x08,0x28,0x10, + /* 0xDAAE [?] [5372]*/ + 0x00,0x20,0x13,0x12,0x02,0x02,0xF2,0x13,0x12,0x12,0x12,0x12,0x16,0x1A,0x13,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xDAAF [?] [5373]*/ + 0x00,0x23,0x10,0x10,0x00,0x01,0xF1,0x12,0x14,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAB0 [?] [5374]*/ + 0x00,0x20,0x11,0x11,0x01,0x01,0xF1,0x10,0x10,0x11,0x11,0x11,0x15,0x19,0x11,0x00, + 0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xDAB1 [?] [5375]*/ + 0x00,0x20,0x10,0x10,0x01,0x03,0xF0,0x10,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAB2 [?] [5376]*/ + 0x00,0x23,0x12,0x12,0x03,0x02,0xF2,0x12,0x12,0x12,0x12,0x13,0x16,0x1A,0x13,0x00, + 0x00,0xFE,0x00,0x00,0xFC,0x20,0x20,0xF8,0x20,0x20,0x20,0xFC,0x00,0x00,0xFE,0x00, + /* 0xDAB3 [?] [5377]*/ + 0x00,0x40,0x27,0x20,0x00,0x03,0xE0,0x20,0x27,0x20,0x21,0x29,0x32,0x24,0x08,0x00, + 0x40,0x40,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40, + /* 0xDAB4 [?] [5378]*/ + 0x00,0x20,0x11,0x10,0x00,0x00,0xF3,0x10,0x10,0x10,0x11,0x10,0x14,0x18,0x13,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xDAB5 [?] [5379]*/ + 0x00,0x20,0x10,0x17,0x00,0x00,0xF3,0x10,0x10,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAB6 [?] [5380]*/ + 0x00,0x20,0x10,0x17,0x01,0x01,0xF2,0x12,0x14,0x15,0x1A,0x10,0x14,0x19,0x12,0x04, + 0x80,0x80,0x80,0xFE,0x00,0x20,0x20,0xA4,0xA4,0x28,0x50,0x50,0x88,0x08,0x04,0x02, + /* 0xDAB7 [?] [5381]*/ + 0x00,0x21,0x11,0x11,0x01,0x02,0xF0,0x13,0x10,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x90,0x90,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xDAB8 [?] [5382]*/ + 0x00,0x40,0x23,0x22,0x02,0x03,0xE2,0x22,0x22,0x22,0x22,0x2A,0x34,0x24,0x08,0x00, + 0x08,0x3C,0xC0,0x00,0x00,0xFE,0x00,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xDAB9 [?] [5383]*/ + 0x00,0x20,0x10,0x11,0x02,0x04,0xF3,0x10,0x10,0x10,0x13,0x10,0x14,0x18,0x17,0x00, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x40,0x40,0x40,0xF8,0x40,0x40,0x40,0xFE,0x00, + /* 0xDABA [?] [5384]*/ + 0x00,0x20,0x11,0x12,0x00,0x03,0xF0,0x10,0x17,0x10,0x10,0x13,0x14,0x18,0x11,0x00, + 0x80,0x80,0xF0,0x10,0x20,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x44,0x40,0x40,0x80, + /* 0xDABB [?] [5385]*/ + 0x00,0x23,0x12,0x14,0x00,0x03,0xF0,0x10,0x11,0x11,0x10,0x14,0x1B,0x10,0x00,0x00, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xDABC [?] [5386]*/ + 0x00,0x47,0x20,0x20,0x04,0x02,0xE2,0x20,0x21,0x22,0x24,0x20,0x28,0x30,0x22,0x01, + 0x00,0xBC,0x84,0x84,0xA4,0x94,0x94,0x84,0x8C,0x94,0xA4,0x84,0x84,0x84,0x94,0x08, + /* 0xDABD [?] [5387]*/ + 0x00,0x21,0x10,0x10,0x00,0x01,0xF1,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xDABE [?] [5388]*/ + 0x00,0x21,0x11,0x11,0x02,0x04,0xF0,0x13,0x10,0x10,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xDABF [?] [5389]*/ + 0x00,0x44,0x22,0x21,0x02,0x04,0xE0,0x20,0x21,0x22,0x24,0x20,0x28,0x30,0x25,0x02, + 0x00,0x40,0xBE,0x08,0x88,0x88,0x88,0xBE,0x88,0x88,0x88,0x88,0x88,0x88,0x3E,0x00, + /* 0xDAC0 [?] [5390]*/ + 0x00,0x40,0x21,0x22,0x07,0x01,0xE1,0x23,0x24,0x20,0x2F,0x20,0x28,0x31,0x22,0x0C, + 0x40,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xDAC1 [?] [5391]*/ + 0x00,0x4F,0x24,0x24,0x04,0x07,0xE4,0x24,0x27,0x24,0x24,0x25,0x2E,0x30,0x20,0x00, + 0x00,0xC0,0xBC,0xA4,0xA4,0xA4,0xA4,0xA8,0xA8,0xA8,0x90,0xD0,0xA8,0xA8,0xC4,0x82, + /* 0xDAC2 [?] [5392]*/ + 0x00,0x4F,0x20,0x21,0x02,0x04,0xEA,0x21,0x22,0x24,0x28,0x21,0x2A,0x34,0x20,0x00, + 0x00,0xFE,0x80,0x84,0x44,0x68,0xB0,0x30,0xA8,0x68,0xA4,0x24,0x22,0x20,0xA0,0x40, + /* 0xDAC3 [?] [5393]*/ + 0x00,0x43,0x20,0x20,0x07,0x01,0xE2,0x24,0x20,0x27,0x21,0x2A,0x31,0x20,0x00,0x03, + 0x38,0xC0,0x40,0x40,0xFC,0x50,0x48,0x86,0x80,0xFC,0x10,0x10,0xA0,0x60,0x90,0x08, + /* 0xDAC4 [?] [5394]*/ + 0x00,0x41,0x26,0x24,0x04,0x07,0xE4,0x24,0x27,0x24,0x20,0x20,0x29,0x32,0x24,0x08, + 0x40,0x40,0x5C,0x44,0x44,0x5C,0x44,0x44,0xFC,0x44,0xA0,0xA0,0x10,0x08,0x04,0x02, + /* 0xDAC5 [?] [5395]*/ + 0x00,0x40,0x20,0x21,0x02,0x04,0xE8,0x23,0x20,0x20,0x20,0x29,0x35,0x25,0x09,0x00, + 0x40,0x40,0xA0,0x10,0x88,0x46,0x00,0xF0,0x10,0x20,0x40,0x24,0x22,0x0A,0x08,0xF8, + /* 0xDAC6 [?] [5396]*/ + 0x00,0x40,0x20,0x21,0x02,0x04,0xE0,0x23,0x22,0x22,0x23,0x22,0x2A,0x32,0x23,0x02, + 0x80,0x80,0xF8,0x08,0x10,0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAC7 [?] [5397]*/ + 0x00,0x40,0x27,0x20,0x01,0x01,0xE2,0x24,0x20,0x20,0x27,0x20,0x28,0x30,0x20,0x00, + 0x80,0x40,0xFC,0x00,0x10,0x10,0xA8,0x44,0x00,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xDAC8 [?] [5398]*/ + 0x01,0x41,0x27,0x21,0x01,0x01,0xE1,0x21,0x21,0x27,0x22,0x22,0x2B,0x32,0x23,0x00, + 0x10,0x10,0xFC,0x10,0xF0,0x10,0xF0,0x10,0x10,0xFE,0x00,0x90,0x08,0x00,0xFC,0x00, + /* 0xDAC9 [?] [5399]*/ + 0x00,0x40,0x2F,0x20,0x07,0x04,0xE5,0x24,0x24,0x27,0x20,0x29,0x32,0x24,0x00,0x00, + 0x40,0x40,0xFE,0x40,0xFC,0x44,0x54,0xE4,0x44,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xDACA [?] [5400]*/ + 0x00,0x20,0x10,0x13,0x02,0x02,0xF3,0x12,0x12,0x12,0x12,0x16,0x1B,0x14,0x04,0x08, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC0,0x44,0x3C,0x00,0xFC,0x80,0xFE,0x80,0x80,0xFC, + /* 0xDACB [?] [5401]*/ + 0x00,0x43,0x22,0x23,0x02,0x03,0xE1,0x23,0x24,0x22,0x22,0x22,0x2B,0x30,0x20,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0x44,0xA4,0x04,0xF4,0x04,0x28,0x10, + /* 0xDACC [?] [5402]*/ + 0x00,0x47,0x24,0x24,0x07,0x00,0xE3,0x20,0x2F,0x21,0x22,0x23,0x28,0x30,0x20,0x00, + 0x00,0xBC,0xA4,0xA4,0xBC,0x00,0xF8,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xDACD [?] [5403]*/ + 0x00,0x20,0x11,0x12,0x05,0x00,0xF3,0x12,0x12,0x13,0x12,0x12,0x17,0x1A,0x12,0x02, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xDACE [?] [5404]*/ + 0x00,0x47,0x22,0x21,0x00,0x03,0xE0,0x20,0x27,0x21,0x21,0x2A,0x32,0x24,0x08,0x03, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xDACF [?] [5405]*/ + 0x00,0x40,0x27,0x20,0x02,0x01,0xEF,0x20,0x23,0x22,0x22,0x23,0x2A,0x32,0x23,0x02, + 0x80,0x40,0xFC,0x00,0x08,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xDAD0 [?] [5406]*/ + 0x00,0x20,0x11,0x10,0x00,0x00,0xF3,0x12,0x14,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xDAD1 [?] [5407]*/ + 0x00,0x22,0x11,0x10,0x01,0x06,0xF2,0x12,0x12,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x40,0x40,0x7C,0x84,0x08,0x20,0x20,0x50,0x88,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDAD2 [?] [5408]*/ + 0x00,0x40,0x27,0x24,0x04,0x07,0xE4,0x24,0x27,0x26,0x2A,0x2B,0x3A,0x2A,0x12,0x02, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0xA4,0xA4,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xDAD3 [?] [5409]*/ + 0x01,0x41,0x27,0x21,0x00,0x03,0xE2,0x23,0x22,0x23,0x20,0x27,0x28,0x31,0x22,0x0C, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xDAD4 [?] [5410]*/ + 0x00,0x42,0x21,0x20,0x07,0x04,0xE8,0x23,0x22,0x22,0x23,0x20,0x29,0x31,0x22,0x04, + 0x40,0x48,0x50,0x40,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0xA0,0x20,0x24,0x24,0x1C, + /* 0xDAD5 [?] [5411]*/ + 0x00,0x47,0x24,0x27,0x04,0x07,0xE1,0x22,0x24,0x21,0x22,0x25,0x30,0x20,0x01,0x0E, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x10,0x08,0x84,0xF8,0x08,0x08,0x90,0x60,0x98,0x06, + /* 0xDAD6 [?] [5412]*/ + 0x02,0x41,0x21,0x20,0x07,0x00,0xE1,0x22,0x24,0x23,0x22,0x22,0x2A,0x32,0x2F,0x00, + 0x08,0x08,0x10,0x00,0xFC,0x00,0x10,0x08,0x04,0xF8,0xA8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xDAD7 [?] [5413]*/ + 0x00,0x40,0x20,0x22,0x02,0x04,0xE1,0x26,0x20,0x23,0x22,0x22,0x2A,0x32,0x27,0x00, + 0x40,0x28,0x90,0xA4,0xC2,0x8A,0x88,0x78,0x00,0xFC,0x94,0x94,0x94,0x94,0xFE,0x00, + /* 0xDAD8 [?] [5414]*/ + 0x00,0x40,0x27,0x21,0x00,0x07,0xE4,0x25,0x24,0x25,0x25,0x25,0x2D,0x34,0x24,0x04, + 0x80,0x40,0xFC,0x10,0xA0,0xFC,0x44,0xF4,0x44,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xDAD9 [?] [5415]*/ + 0x01,0x20,0x17,0x10,0x03,0x02,0xF3,0x12,0x13,0x12,0x12,0x14,0x1B,0x10,0x01,0x06, + 0x08,0x90,0xFE,0x00,0xC4,0x54,0xD4,0x54,0xD4,0x44,0xCC,0x00,0xFC,0x84,0x14,0x08, + /* 0xDADA [?] [5416]*/ + 0x00,0x47,0x21,0x25,0x07,0x03,0xE5,0x29,0x20,0x23,0x22,0x22,0x2B,0x32,0x22,0x03, + 0x00,0xBC,0x08,0x28,0xBC,0x18,0xAA,0x46,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8, + /* 0xDADB [?] [5417]*/ + 0x01,0x41,0x23,0x22,0x06,0x0B,0xE2,0x22,0x23,0x22,0x22,0x2B,0x32,0x25,0x04,0x08, + 0x40,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x24,0x92,0x92, + /* 0xDADC [?] [5418]*/ + 0x00,0x47,0x20,0x20,0x07,0x00,0xE1,0x26,0x20,0x27,0x24,0x25,0x2E,0x34,0x24,0x04, + 0x00,0xF8,0x90,0x60,0xFC,0xA4,0x28,0xA0,0x40,0xFC,0xA4,0x14,0xEC,0xA4,0xE4,0x0C, + /* 0xDADD [?] [5419]*/ + 0x01,0x41,0x27,0x21,0x01,0x07,0xE4,0x26,0x25,0x27,0x25,0x27,0x2D,0x35,0x24,0x04, + 0x08,0x08,0xCC,0x0A,0x08,0xDE,0x48,0xC8,0x48,0xC8,0x54,0xD4,0x54,0x54,0x54,0xE2, + /* 0xDADE [?] [5420]*/ + 0x02,0x43,0x24,0x27,0x0D,0x16,0xE7,0x24,0x25,0x24,0x25,0x2C,0x35,0x29,0x09,0x11, + 0x00,0xF8,0x10,0xFE,0x48,0x24,0xFE,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x04,0xFC,0x04, + /* 0xDADF [?] [5421]*/ + 0x04,0x44,0x2A,0x20,0x0F,0x02,0xEE,0x22,0x2E,0x22,0x2E,0x2A,0x32,0x2F,0x04,0x00, + 0x48,0x4C,0xAA,0x08,0xFE,0x88,0xE8,0x8A,0xEA,0x8C,0xEC,0x88,0xEA,0x1A,0x26,0x42, + /* 0xDAE0 [?] [5422]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40, + /* 0xDAE1 [?] [5423]*/ + 0x1F,0x00,0x7D,0x05,0x09,0x31,0xC5,0x02,0x3F,0x00,0x1F,0x10,0x10,0x10,0x10,0x0F, + 0xC0,0x44,0x88,0x50,0x20,0x18,0x06,0x00,0xF8,0x00,0xF0,0x10,0x50,0x24,0x04,0xFC, + /* 0xDAE2 [?] [5424]*/ + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDAE3 [?] [5425]*/ + 0x00,0x7C,0x47,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44, + 0x00,0x00,0xFC,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xDAE4 [?] [5426]*/ + 0x00,0x7C,0x45,0x48,0x48,0x50,0x48,0x4B,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xDAE5 [?] [5427]*/ + 0x00,0x7C,0x44,0x48,0x4B,0x50,0x48,0x48,0x44,0x47,0x44,0x68,0x50,0x41,0x41,0x42, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xDAE6 [?] [5428]*/ + 0x00,0x7C,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x42,0x42,0x44, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xDAE7 [?] [5429]*/ + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDAE8 [?] [5430]*/ + 0x00,0x7C,0x44,0x48,0x49,0x51,0x4A,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xDAE9 [?] [5431]*/ + 0x00,0x78,0x48,0x53,0x52,0x62,0x52,0x4B,0x4A,0x4A,0x6A,0x52,0x42,0x44,0x44,0x49, + 0x20,0x20,0x20,0xFE,0x22,0x24,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xDAEA [?] [5432]*/ + 0x00,0x7D,0x44,0x48,0x48,0x50,0x48,0x4B,0x44,0x45,0x44,0x68,0x50,0x40,0x43,0x40, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xDAEB [?] [5433]*/ + 0x00,0x78,0x48,0x57,0x50,0x60,0x51,0x4B,0x48,0x48,0x69,0x56,0x40,0x40,0x41,0x46, + 0x40,0x20,0x20,0xFE,0x40,0x84,0x08,0xF0,0x22,0x44,0x88,0x10,0x20,0x50,0x88,0x04, + /* 0xDAEC [?] [5434]*/ + 0x00,0x78,0x49,0x51,0x51,0x61,0x57,0x48,0x48,0x49,0x69,0x52,0x44,0x40,0x40,0x47, + 0x20,0x20,0x20,0x3C,0x20,0x20,0xFE,0x00,0x20,0x24,0x24,0x28,0x10,0x20,0xC0,0x00, + /* 0xDAED [?] [5435]*/ + 0x00,0x7D,0x45,0x49,0x49,0x51,0x49,0x49,0x44,0x44,0x45,0x68,0x50,0x40,0x43,0x40, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xDAEE [?] [5436]*/ + 0x00,0x7F,0x4A,0x52,0x52,0x63,0x52,0x4A,0x4B,0x4A,0x6A,0x52,0x47,0x40,0x40,0x40, + 0x00,0xE0,0x5E,0x52,0x52,0xD2,0x52,0x54,0xD4,0x54,0x48,0xE8,0x54,0x54,0x62,0x40, + /* 0xDAEF [?] [5437]*/ + 0x00,0x78,0x49,0x50,0x50,0x63,0x51,0x49,0x4F,0x49,0x69,0x53,0x40,0x40,0x43,0x40, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x24,0x24,0xFE,0x24,0x24,0xFE,0x20,0x20,0xFE,0x00, + /* 0xDAF0 [?] [5438]*/ + 0x00,0x78,0x4B,0x52,0x52,0x63,0x52,0x4A,0x4B,0x48,0x69,0x57,0x40,0x40,0x40,0x40, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xDAF1 [?] [5439]*/ + 0x00,0x7B,0x4A,0x4A,0x53,0x52,0x62,0x53,0x48,0x4F,0x4A,0x6A,0x52,0x42,0x43,0x42, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x00,0xFE,0x40,0x44,0x28,0x90,0x08,0x06, + /* 0xDAF2 [?] [5440]*/ + 0x00,0x7C,0x45,0x49,0x49,0x51,0x49,0x48,0x47,0x44,0x44,0x69,0x50,0x40,0x43,0x40, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xDAF3 [?] [5441]*/ + 0x00,0x78,0x4B,0x4A,0x52,0x53,0x62,0x52,0x4B,0x48,0x48,0x68,0x51,0x41,0x42,0x44, + 0x20,0x40,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x40,0xA8,0xB4,0x3C,0x22,0x22,0x1E, + /* 0xDAF4 [?] [5442]*/ + 0x00,0x7B,0x4A,0x4B,0x52,0x53,0x61,0x52,0x4B,0x49,0x4A,0x6B,0x50,0x42,0x42,0x44, + 0x00,0xFE,0x02,0xFE,0x02,0xFE,0x08,0x52,0x9C,0x08,0x52,0xDE,0x00,0xA4,0x52,0x52, + /* 0xDAF5 [?] [5443]*/ + 0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0xC8,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDAF6 [?] [5444]*/ + 0x00,0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0F,0xF0,0x40,0x00,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDAF7 [?] [5445]*/ + 0x08,0x04,0x04,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + 0x00,0x3E,0x22,0xA4,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDAF8 [?] [5446]*/ + 0x10,0x08,0x08,0x00,0xFF,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x00,0x00, + 0x00,0x3E,0x22,0x24,0xA4,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDAF9 [?] [5447]*/ + 0x10,0x20,0x7E,0x42,0x42,0x4A,0x44,0x40,0x7F,0x01,0x01,0x1D,0xE1,0x41,0x0A,0x04, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDAFA [?] [5448]*/ + 0x10,0x08,0x08,0xFF,0x10,0x10,0x1F,0x11,0x11,0x11,0x11,0x11,0x21,0x25,0x42,0x80, + 0x00,0x3E,0x22,0xA4,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDAFB [?] [5449]*/ + 0x00,0x7F,0x08,0x08,0x08,0x7F,0x48,0x48,0x54,0x52,0x62,0x40,0x40,0x40,0x42,0x41, + 0x00,0xBE,0x22,0x24,0x24,0xA8,0xA4,0xA4,0xA2,0xA2,0xA2,0xB4,0xA8,0xA0,0xA0,0x20, + /* 0xDAFC [?] [5450]*/ + 0x00,0xFF,0x08,0x08,0x10,0x14,0x32,0x51,0x90,0x10,0x10,0x00,0x0E,0xF0,0x40,0x00, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDAFD [?] [5451]*/ + 0x12,0x12,0x12,0x12,0x12,0xF3,0x12,0x12,0x12,0x12,0x12,0x32,0x52,0x93,0x12,0x00, + 0x00,0x3E,0x22,0x24,0x24,0xA8,0x24,0x24,0x22,0x22,0x22,0x34,0xA8,0x20,0x20,0x20, + /* 0xDAFE [?] [5452]*/ + 0x14,0x14,0x14,0x14,0x94,0x55,0x55,0x56,0x14,0x14,0x14,0x17,0xF8,0x40,0x00,0x00, + 0x00,0x3E,0x22,0xA4,0xA4,0x28,0x24,0x24,0x22,0x22,0x22,0xB4,0x28,0x20,0x20,0x20, + /* 0xDBA1 [?] [5453]*/ + 0x01,0x07,0x7C,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x42,0x42,0x52,0x69,0x44, + 0x00,0xBE,0x22,0x24,0x24,0x28,0x24,0xA4,0x22,0x22,0x22,0x34,0xA8,0xA0,0xA0,0xA0, + /* 0xDBA2 [?] [5454]*/ + 0x08,0x08,0x10,0x22,0x41,0xFF,0x00,0x00,0x7F,0x41,0x41,0x41,0x41,0x41,0x7F,0x41, + 0x00,0x3E,0x22,0x24,0x24,0xA8,0xA4,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBA3 [?] [5455]*/ + 0x08,0x08,0x08,0xFF,0x08,0x49,0x29,0x2A,0xFF,0x08,0x08,0x14,0x12,0x21,0x41,0x80, + 0x00,0x3E,0x22,0xA4,0x24,0x28,0x24,0x24,0xA2,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBA4 [?] [5456]*/ + 0x00,0xFF,0x08,0x10,0x22,0x41,0xFF,0x08,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF8,0x40, + 0x00,0xBE,0x22,0x24,0x24,0x28,0xA4,0xA4,0x22,0x22,0x22,0x34,0x28,0xA0,0x20,0x20, + /* 0xDBA5 [?] [5457]*/ + 0x08,0x48,0x48,0x7F,0x48,0x88,0x08,0xFF,0x18,0x1C,0x2A,0x29,0x49,0x88,0x08,0x08, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0xC8,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDBA6 [?] [5458]*/ + 0x08,0x08,0x14,0x22,0x41,0xBE,0x00,0x00,0xFF,0x10,0x10,0x22,0x41,0xFF,0x41,0x00, + 0x00,0x3E,0x22,0x24,0x24,0xA8,0x24,0x24,0xA2,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBA7 [?] [5459]*/ + 0x01,0x32,0x0C,0x12,0x69,0x08,0xFF,0x10,0x24,0x24,0x48,0x8A,0x11,0x3F,0x11,0x00, + 0x00,0x3E,0x22,0x24,0x24,0x28,0xA4,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBA8 [?] [5460]*/ + 0x20,0x20,0x7F,0x41,0x81,0x79,0x49,0x49,0x79,0x49,0x49,0x79,0x41,0x01,0x0A,0x04, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBA9 [?] [5461]*/ + 0x00,0x7F,0x48,0x08,0x7F,0x10,0x14,0x24,0x7F,0x04,0x04,0x07,0xFC,0x44,0x04,0x04, + 0x00,0xBE,0xA2,0x24,0xA4,0x28,0x24,0x24,0xA2,0x22,0x22,0xB4,0x28,0x20,0x20,0x20, + /* 0xDBAA [?] [5462]*/ + 0x00,0x7F,0x00,0x00,0x7B,0x4A,0x4A,0x4A,0x6B,0x5A,0x4A,0x4A,0x4A,0x4A,0x4A,0x5A, + 0x00,0xDE,0x12,0x12,0xD4,0x54,0x58,0x54,0x52,0xD2,0x52,0x5A,0x54,0x50,0x50,0xD0, + /* 0xDBAB [?] [5463]*/ + 0x00,0x7F,0x41,0x41,0x41,0x7F,0x00,0x7F,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDBAC [?] [5464]*/ + 0x08,0x48,0x48,0x7F,0x48,0x88,0x08,0xFF,0x00,0x00,0x7F,0x41,0x41,0x41,0x7F,0x41, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0xA4,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBAD [?] [5465]*/ + 0x30,0x0D,0x06,0x19,0x60,0x08,0x7F,0x14,0x24,0x7F,0xA4,0x24,0x26,0x25,0x04,0x04, + 0x80,0x3E,0x22,0x24,0xA4,0x28,0xE4,0x24,0x22,0xA2,0xA2,0xB4,0xA8,0x20,0x20,0x20, + /* 0xDBAE [?] [5466]*/ + 0x02,0x0F,0xF0,0x01,0x91,0x4A,0x00,0xFE,0x04,0x08,0x0F,0xF8,0x48,0x08,0x28,0x10, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBAF [?] [5467]*/ + 0x10,0x20,0x7F,0x49,0x49,0x7F,0x49,0x51,0x7F,0x24,0x44,0xFF,0x04,0x04,0x04,0x04, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0xB4,0x28,0x20,0x20,0x20, + /* 0xDBB0 [?] [5468]*/ + 0x08,0x09,0x49,0x4A,0x88,0x14,0x22,0x49,0x88,0x49,0x49,0x8A,0x14,0x22,0x41,0x80, + 0x00,0x3E,0x22,0x24,0x24,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0xA0, + /* 0xDBB1 [?] [5469]*/ + 0x00,0x7F,0x40,0x5F,0x50,0x5F,0x50,0x5F,0x44,0x7F,0x49,0x59,0x46,0x49,0x50,0x7F, + 0x00,0xDE,0x12,0x92,0x94,0x94,0x98,0x94,0x12,0xD2,0x12,0x1A,0x14,0x10,0x90,0xD0, + /* 0xDBB2 [?] [5470]*/ + 0x00,0xFF,0x14,0x14,0x7F,0x55,0x55,0x7F,0x08,0x08,0x7F,0x08,0x08,0x0F,0xF0,0x40, + 0x00,0x7C,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDBB3 [?] [5471]*/ + 0x00,0x7F,0x04,0x27,0x24,0xFF,0x20,0x3F,0x40,0x7F,0x00,0xAA,0xAA,0x00,0x05,0x02, + 0x00,0xBE,0x22,0x24,0x24,0xA8,0x24,0xA4,0x22,0xA2,0xA2,0xB4,0xA8,0xA0,0x20,0x20, + /* 0xDBB4 [?] [5472]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x08,0x7F,0x49,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x0F,0xF0, + 0x00,0x7C,0xC4,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40, + /* 0xDBB5 [?] [5473]*/ + 0x08,0x7F,0x22,0x14,0xFF,0x00,0x7F,0x41,0x7F,0x41,0x7F,0x08,0xFF,0x08,0x08,0x08, + 0x00,0x3E,0x22,0x24,0xA4,0x28,0x24,0x24,0x22,0x22,0x22,0x34,0xA8,0x20,0x20,0x20, + /* 0xDBB6 [?] [5474]*/ + 0x0F,0xF8,0x49,0x2A,0xFF,0x2A,0x49,0x80,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x41, + 0x00,0x3E,0x22,0x24,0xA4,0x28,0x24,0xA4,0x22,0x22,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBB7 [?] [5475]*/ + 0x22,0x14,0xFF,0x08,0x7F,0x08,0xFF,0x49,0x2A,0xFF,0x00,0x7F,0x41,0x41,0x7F,0x41, + 0x00,0x3E,0xA2,0x24,0x24,0x28,0xA4,0x24,0x22,0xA2,0x22,0x34,0x28,0x20,0x20,0x20, + /* 0xDBB8 [?] [5476]*/ + 0xFC,0x4B,0x78,0x4A,0x79,0x4D,0xFA,0x0C,0x07,0xF8,0x28,0x4D,0x1A,0x29,0xC8,0x08, + 0x00,0xBE,0xA2,0xA4,0x24,0x28,0xA4,0xA4,0xA2,0x22,0xA2,0x34,0x28,0x20,0xA0,0x20, + /* 0xDBB9 [?] [5477]*/ + 0x00,0x7F,0x04,0xFF,0x84,0x35,0x04,0x35,0x00,0x00,0xEE,0xAA,0xAA,0xAA,0xEE,0xAA, + 0x00,0xCE,0x0A,0xEA,0x2A,0x8A,0x0C,0x8A,0x0A,0x0A,0xEA,0xAA,0xAC,0xA8,0xE8,0xA8, + /* 0xDBBA [?] [5478]*/ + 0x2A,0x7F,0xAA,0xFF,0xAA,0xFF,0xAA,0xFF,0x00,0xFF,0x00,0x7F,0x41,0x7F,0x22,0xFF, + 0x00,0x3E,0xA2,0xA4,0xA4,0xA8,0xA4,0xA4,0x22,0xA2,0x22,0x34,0x28,0x20,0x20,0xA0, + /* 0xDBBB [?] [5479]*/ + 0x04,0x04,0x0F,0x10,0x20,0x40,0xBF,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00, + 0x00,0x00,0xF0,0x10,0x20,0x40,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDBBC [?] [5480]*/ + 0x08,0x08,0x0F,0x10,0x20,0x5F,0x91,0x11,0x11,0x11,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xE0,0x20,0x40,0xF0,0x10,0x10,0x10,0x10,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xDBBD [?] [5481]*/ + 0x00,0x00,0xFF,0x20,0x20,0x20,0x3E,0x22,0x22,0x22,0x22,0x22,0x42,0x42,0x94,0x09, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0xA8,0x10, + /* 0xDBBE [?] [5482]*/ + 0x20,0x20,0x20,0x7E,0x42,0x82,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x15,0x0A, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xDBBF [?] [5483]*/ + 0x00,0x7E,0x12,0x12,0x22,0x2A,0x44,0x80,0x3E,0x22,0x22,0x22,0x22,0x3E,0x22,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0xA8,0x10, + /* 0xDBC0 [?] [5484]*/ + 0x10,0x08,0x08,0xFF,0x08,0x10,0x22,0x7C,0x09,0x12,0x24,0xC8,0x14,0x22,0xC0,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0xA8,0x10, + /* 0xDBC1 [?] [5485]*/ + 0x08,0x08,0x7F,0x11,0x11,0x25,0x42,0x00,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x00,0x00, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0xFE,0x10,0x90,0x90,0x90,0x90,0x50,0x20, + /* 0xDBC2 [?] [5486]*/ + 0x00,0x3E,0x04,0x08,0x7E,0x08,0x08,0x28,0x10,0x7F,0x55,0x55,0x55,0x57,0xFD,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xDBC3 [?] [5487]*/ + 0x00,0xFF,0x81,0xBD,0x81,0xBD,0x81,0x00,0x7E,0x42,0x7E,0x42,0x7E,0x42,0x7E,0x43, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0xA8,0x10, + /* 0xDBC4 [?] [5488]*/ + 0x10,0x10,0x7E,0x12,0x22,0x2A,0x44,0x80,0x44,0xFF,0x55,0x55,0x55,0x55,0x59,0xB3, + 0x00,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x10,0x08,0x28,0x20,0x64,0xAA,0x28,0x18, + /* 0xDBC5 [?] [5489]*/ + 0x01,0x05,0x39,0x21,0x21,0x3D,0x21,0x21,0x3F,0x01,0x3F,0x08,0x04,0x03,0x1C,0xE0, + 0x00,0x00,0x78,0x08,0x08,0x78,0x08,0x08,0xF8,0x00,0xF0,0x20,0x40,0x80,0x70,0x0E, + /* 0xDBC6 [?] [5490]*/ + 0x21,0x27,0x20,0x6B,0xB0,0x23,0x20,0x53,0x4A,0x8B,0x00,0x3F,0x08,0x04,0x07,0xF8, + 0x08,0xC8,0x08,0x9A,0x2C,0x88,0x08,0x94,0x92,0xA2,0x00,0xF0,0x20,0xC0,0x80,0x7E, + /* 0xDBC7 [?] [5491]*/ + 0x7C,0x44,0x7C,0x44,0x7C,0x09,0x1F,0x31,0x5F,0x91,0x1F,0x10,0x3F,0x08,0x07,0xF8, + 0xF8,0x88,0xF8,0x88,0xF8,0x00,0xF8,0x00,0xF0,0x00,0xFC,0x00,0xF0,0x20,0xC0,0x3E, + /* 0xDBC8 [?] [5492]*/ + 0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x78,0x08,0x08,0x48,0x30,0x10,0x2C,0x43,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xDBC9 [?] [5493]*/ + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00, + 0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDBCA [?] [5494]*/ + 0x01,0x01,0x01,0x01,0x5D,0x45,0x45,0x49,0x49,0x51,0x61,0x45,0x42,0x40,0x7F,0x00, + 0x00,0x00,0x00,0x10,0x24,0x44,0x84,0x44,0x24,0x14,0x14,0x04,0x04,0x04,0xFC,0x04, + /* 0xDBCB [?] [5495]*/ + 0x09,0x24,0x22,0x29,0x22,0x24,0x29,0x3F,0x10,0x10,0x11,0x1E,0x10,0x10,0x0F,0x00, + 0x20,0x48,0x88,0x28,0x88,0x48,0x28,0xF8,0x00,0x38,0xC0,0x04,0x04,0x04,0xFC,0x00, + /* 0xDBCC [?] [5496]*/ + 0x02,0x02,0x02,0x02,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x7F,0x20,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x10,0xF8,0x08,0x08,0x00, + /* 0xDBCD [?] [5497]*/ + 0x02,0x04,0x08,0x10,0x3F,0x00,0x08,0x08,0x08,0xFF,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0x00,0x20,0x10,0xF8,0x08,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xDBCE [?] [5498]*/ + 0x02,0x04,0x08,0x1F,0x02,0x7F,0x08,0x10,0x3F,0xD1,0x11,0x1F,0x11,0x11,0x1F,0x10, + 0x00,0x40,0x20,0xF0,0x00,0xFC,0x20,0x10,0xF8,0x16,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xDBCF [?] [5499]*/ + 0x00,0x7C,0x05,0x08,0x10,0x28,0x45,0x82,0x00,0x7C,0x10,0x10,0x10,0x1D,0xE1,0x42, + 0x20,0x10,0xFE,0x20,0x48,0x84,0xFE,0x02,0xA8,0xA8,0xA8,0xA8,0xAA,0x2A,0x26,0x00, + /* 0xDBD0 [?] [5500]*/ + 0x04,0x08,0x10,0x2F,0xC4,0x04,0x08,0x10,0x61,0x01,0x3F,0x01,0x01,0x01,0xFF,0x00, + 0x40,0x20,0x10,0xE8,0x26,0x20,0x20,0xA0,0x40,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xDBD1 [?] [5501]*/ + 0x00,0x7F,0x04,0x24,0x14,0x14,0x04,0xFF,0x00,0x01,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0xFC,0x40,0x48,0x48,0x50,0x40,0xFE,0x00,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00, + /* 0xDBD2 [?] [5502]*/ + 0x08,0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x10,0x11,0x16,0x01,0x3F,0x01,0x01,0xFF, + 0xA0,0x90,0x80,0xFC,0x80,0x48,0x50,0x24,0x54,0x8C,0x04,0x00,0xF8,0x00,0x00,0xFE, + /* 0xDBD3 [?] [5503]*/ + 0x10,0xFE,0x00,0x7D,0x44,0x7C,0x00,0x7C,0x08,0xFE,0x11,0x52,0x21,0x3F,0x01,0xFF, + 0x40,0x40,0x40,0xF8,0x48,0x48,0xC8,0x48,0xAA,0xAA,0x06,0x02,0x00,0xF8,0x00,0xFE, + /* 0xDBD4 [?] [5504]*/ + 0x08,0xFF,0x08,0x7F,0x49,0x7F,0x49,0x7F,0x08,0xFF,0x49,0x7F,0x01,0x3F,0x01,0xFF, + 0x00,0x78,0x48,0x48,0x86,0x00,0x78,0x48,0x28,0x90,0x28,0x44,0x00,0xF8,0x00,0xFE, + /* 0xDBD5 [?] [5505]*/ + 0x02,0x01,0xFF,0x10,0x24,0x79,0x10,0x22,0x7C,0x08,0x30,0xC0,0x01,0x3F,0x01,0xFF, + 0x00,0x00,0xFE,0x48,0xFE,0x90,0xFC,0x90,0xFC,0x90,0xFE,0x80,0x00,0xF8,0x00,0xFE, + /* 0xDBD6 [?] [5506]*/ + 0x08,0x0F,0x08,0xFF,0x80,0x7F,0x49,0x94,0x22,0x7F,0xA2,0x3E,0x01,0x3F,0x01,0xFF, + 0x00,0x00,0x7C,0xA4,0xA4,0x24,0x24,0xA8,0x10,0x28,0x44,0x02,0x00,0xF8,0x00,0xFE, + /* 0xDBD7 [?] [5507]*/ + 0x10,0x11,0x10,0x10,0x10,0xFC,0x10,0x13,0x10,0x10,0x10,0x1C,0xE0,0x40,0x00,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xDBD8 [?] [5508]*/ + 0x20,0x21,0x20,0x20,0x20,0xFB,0x20,0x20,0x21,0x21,0x20,0x38,0xE0,0x40,0x00,0x00, + 0x00,0xFC,0x00,0x00,0x00,0xFE,0x80,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xDBD9 [?] [5509]*/ + 0x10,0x10,0x10,0x10,0x11,0xFE,0x10,0x10,0x10,0x10,0x10,0x1C,0xE1,0x41,0x00,0x00, + 0x40,0x40,0x80,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xDBDA [?] [5510]*/ + 0x11,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04, + /* 0xDBDB [?] [5511]*/ + 0x10,0x10,0x10,0x13,0x12,0xFE,0x12,0x12,0x12,0x12,0x1E,0xE2,0x42,0x04,0x04,0x08, + 0x40,0x20,0x20,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDBDC [?] [5512]*/ + 0x10,0x10,0x11,0x10,0x10,0xFC,0x10,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x00,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xDBDD [?] [5513]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x00,0x00, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xDBDE [?] [5514]*/ + 0x20,0x23,0x22,0x22,0x22,0xFA,0x22,0x22,0x22,0x22,0x22,0x3A,0xE4,0x44,0x09,0x12, + 0x00,0xFE,0x00,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xDBDF [?] [5515]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xDBE0 [?] [5516]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xDBE1 [?] [5517]*/ + 0x11,0x11,0x11,0x11,0x17,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01,0x01, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xDBE2 [?] [5518]*/ + 0x10,0x10,0x10,0x10,0x13,0xFC,0x10,0x10,0x10,0x10,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0xA8,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xDBE3 [?] [5519]*/ + 0x10,0x10,0x10,0x10,0x10,0xFC,0x10,0x10,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01,0x01, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDBE4 [?] [5520]*/ + 0x20,0x20,0x20,0x20,0x20,0xFB,0x22,0x22,0x22,0x23,0x22,0x3A,0xE2,0x44,0x04,0x08, + 0x40,0x40,0x7E,0x40,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00, + /* 0xDBE5 [?] [5521]*/ + 0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x30,0x18,0x14,0x12,0x10,0x10,0x10, + /* 0xDBE6 [?] [5522]*/ + 0x10,0x10,0x13,0x12,0x12,0xFE,0x12,0x13,0x12,0x12,0x12,0x1E,0xE2,0x42,0x03,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xDBE7 [?] [5523]*/ + 0x10,0x10,0x10,0x13,0x12,0xFC,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x00,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x08,0x10,0x20,0xC0,0x02,0x02,0x02,0xFE,0x00, + /* 0xDBE8 [?] [5524]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x42,0x02,0x04, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xDBE9 [?] [5525]*/ + 0x20,0x21,0x21,0x21,0x21,0xF9,0x21,0x27,0x22,0x22,0x22,0x3A,0xE3,0x40,0x00,0x00, + 0x00,0xF8,0x08,0x48,0x28,0x08,0x08,0xFE,0x08,0x88,0x48,0x08,0xFE,0x08,0x50,0x20, + /* 0xDBEA [?] [5526]*/ + 0x20,0x21,0x21,0x22,0x22,0xF4,0x27,0x21,0x22,0x22,0x24,0x37,0xE0,0x40,0x00,0x01, + 0x20,0x20,0x20,0x20,0xFC,0xA4,0x24,0x24,0x24,0x24,0xA4,0xA4,0xC4,0x44,0x94,0x08, + /* 0xDBEB [?] [5527]*/ + 0x20,0x23,0x20,0x20,0x20,0xF8,0x24,0x22,0x22,0x22,0x20,0x38,0xE0,0x40,0x07,0x00, + 0x00,0xFC,0x90,0x90,0x90,0x92,0x92,0x94,0x94,0x98,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xDBEC [?] [5528]*/ + 0x20,0x27,0x20,0x20,0x21,0xFA,0x27,0x20,0x20,0x20,0x27,0x38,0xE0,0x40,0x0F,0x00, + 0x00,0xFE,0x40,0x80,0x10,0x08,0xFC,0x44,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xDBED [?] [5529]*/ + 0x20,0x23,0x22,0x22,0x22,0xFA,0x22,0x22,0x22,0x22,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x00,0xFE,0x02,0x02,0xFA,0x02,0x02,0xFA,0x8A,0x8A,0x8A,0xFA,0x02,0x02,0x0A,0x04, + /* 0xDBEE [?] [5530]*/ + 0x10,0x11,0x11,0x11,0x11,0xFC,0x11,0x10,0x10,0x11,0x11,0x1D,0xE1,0x41,0x00,0x00, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xDBEF [?] [5531]*/ + 0x20,0x20,0x27,0x21,0x21,0xFA,0x22,0x27,0x21,0x25,0x25,0x3A,0xE2,0x45,0x08,0x10, + 0x08,0x1C,0x70,0x10,0x10,0x50,0x5C,0x50,0x50,0x50,0x50,0x7C,0x00,0x00,0xFE,0x00, + /* 0xDBF0 [?] [5532]*/ + 0x20,0x20,0x20,0x23,0x22,0xFA,0x22,0x22,0x22,0x22,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x40,0x40,0x80,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xDBF1 [?] [5533]*/ + 0x20,0x20,0x20,0x27,0x20,0xF8,0x20,0x22,0x22,0x22,0x22,0x3A,0xE2,0x42,0x03,0x00, + 0x40,0x20,0x20,0xFE,0x00,0x00,0x90,0x54,0x24,0x24,0x54,0x94,0x04,0x04,0xFC,0x04, + /* 0xDBF2 [?] [5534]*/ + 0x20,0x20,0x20,0x27,0x20,0xF8,0x21,0x23,0x20,0x20,0x39,0xE6,0x40,0x00,0x01,0x06, + 0x40,0x20,0x20,0xFE,0x40,0x84,0x08,0xF0,0x22,0x44,0x88,0x10,0x20,0x50,0x88,0x04, + /* 0xDBF3 [?] [5535]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01,0x01, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xDBF4 [?] [5536]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x10,0x10,0x13,0x10,0x10,0x1D,0xE0,0x40,0x03,0x00, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xDBF5 [?] [5537]*/ + 0x20,0x20,0x27,0x24,0x24,0xFC,0x24,0x27,0x24,0x24,0x24,0x3C,0xE7,0x44,0x00,0x00, + 0x08,0x08,0x88,0x88,0xFE,0x88,0x88,0xC8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x28,0x10, + /* 0xDBF6 [?] [5538]*/ + 0x20,0x23,0x22,0x22,0x22,0xFB,0x20,0x20,0x27,0x24,0x24,0x3D,0xE6,0x44,0x04,0x04, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x40,0x40,0xFC,0x44,0xA4,0x14,0x14,0x04,0x14,0x08, + /* 0xDBF7 [?] [5539]*/ + 0x20,0x23,0x22,0x22,0x23,0xF8,0x20,0x27,0x24,0x24,0x24,0x3C,0xE4,0x41,0x06,0x18, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x44,0x44,0x44,0xB4,0x08,0x04,0x02, + /* 0xDBF8 [?] [5540]*/ + 0x10,0x10,0x13,0x10,0x12,0xFD,0x11,0x10,0x13,0x10,0x11,0x1C,0xE0,0x40,0x00,0x00, + 0x08,0x3C,0xC0,0x44,0x24,0x28,0x00,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x50,0x20, + /* 0xDBF9 [?] [5541]*/ + 0x10,0x10,0x13,0x12,0x14,0xFD,0x10,0x10,0x13,0x10,0x10,0x1C,0xE1,0x41,0x02,0x04, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xDBFA [?] [5542]*/ + 0x20,0x20,0x27,0x20,0x20,0xFB,0x22,0x23,0x22,0x23,0x22,0x3B,0xE2,0x42,0x0F,0x00, + 0x40,0x40,0xFC,0x40,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x00, + /* 0xDBFB [?] [5543]*/ + 0x20,0x20,0x27,0x21,0x22,0xFC,0x23,0x22,0x22,0x23,0x22,0x3A,0xE3,0x40,0x00,0x00, + 0x40,0x80,0xFE,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xDBFC [?] [5544]*/ + 0x10,0x11,0x11,0x11,0x11,0xFD,0x10,0x10,0x11,0x12,0x14,0x1C,0xE1,0x42,0x00,0x01, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0x80,0xFE,0x4A,0x4A,0x92,0x22,0x42,0x94,0x08, + /* 0xDBFD [?] [5545]*/ + 0x20,0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x23,0x20,0x39,0xE7,0x40,0x00,0x00,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xDBFE [?] [5546]*/ + 0x20,0x20,0x20,0x20,0x21,0xFA,0x21,0x20,0x20,0x20,0x20,0x3A,0xE2,0x42,0x04,0x00, + 0x20,0x20,0x50,0x88,0x44,0x22,0xF8,0x08,0x50,0x20,0xA4,0x82,0x8A,0x8A,0x78,0x00, + /* 0xDCA1 [?] [5547]*/ + 0x20,0x23,0x22,0x22,0x22,0xFB,0x22,0x22,0x22,0x23,0x22,0x3A,0xE2,0x42,0x05,0x08, + 0x00,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0xDE,0x52,0x52,0x52,0x52,0x52,0xA6, + /* 0xDCA2 [?] [5548]*/ + 0x21,0x21,0x21,0x22,0xFA,0x27,0x2A,0x22,0x22,0x23,0x22,0x38,0xE1,0x42,0x04,0x08, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0x44,0xFC,0xA4,0xB0,0x28,0x2A,0x22,0x1E, + /* 0xDCA3 [?] [5549]*/ + 0x20,0x23,0x20,0x21,0x20,0xFB,0x20,0x27,0x24,0x28,0x23,0x3A,0xE2,0x42,0x02,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x42,0x44,0xF8,0x48,0x48,0x48,0x58,0x40, + /* 0xDCA4 [?] [5550]*/ + 0x20,0x20,0x23,0x20,0xF8,0x27,0x20,0x20,0x23,0x24,0x22,0x39,0xE2,0x44,0x01,0x00, + 0x40,0x40,0xF8,0x48,0x48,0xFE,0x48,0x48,0xF8,0x44,0xE8,0x50,0x48,0x46,0x40,0x80, + /* 0xDCA5 [?] [5551]*/ + 0x10,0x13,0x12,0x12,0x13,0xFE,0x12,0x12,0x12,0x12,0x12,0x1E,0xE2,0x44,0x04,0x08, + 0x00,0xFE,0x02,0x02,0xFE,0x10,0x92,0x92,0x92,0xFE,0x10,0x92,0x92,0x92,0xFE,0x02, + /* 0xDCA6 [?] [5552]*/ + 0x20,0x22,0x22,0x27,0x22,0xFA,0x22,0x22,0x23,0x20,0x27,0x38,0xE1,0x42,0x0C,0x00, + 0x90,0x90,0x90,0xFE,0x90,0x90,0xF0,0x00,0xFC,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xDCA7 [?] [5553]*/ + 0x20,0x27,0x20,0x20,0x27,0xFC,0x24,0x24,0x27,0x20,0x38,0xE7,0x40,0x00,0x0F,0x00, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xA4,0xFC,0x40,0x40,0xFC,0x40,0x40,0xFE,0x00, + /* 0xDCA8 [?] [5554]*/ + 0x20,0x23,0x22,0x22,0x22,0xFB,0x20,0x20,0x27,0x20,0x20,0x38,0xE1,0x41,0x02,0x04, + 0x00,0xFC,0x94,0x94,0x94,0xFC,0x80,0x40,0xFE,0x80,0xF8,0x88,0x08,0x08,0x28,0x10, + /* 0xDCA9 [?] [5555]*/ + 0x21,0x21,0x21,0x22,0xFA,0x26,0x2A,0x22,0x22,0x22,0x22,0x3A,0xE2,0x42,0x02,0x02, + 0x00,0x78,0x08,0x08,0xFE,0x40,0x40,0x7C,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xDCAA [?] [5556]*/ + 0x20,0x23,0x20,0x21,0x21,0xF9,0x21,0x20,0x23,0x22,0x22,0x3B,0xE2,0x42,0x02,0x02, + 0x00,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x8A,0x52,0xFE,0x22,0x22,0x2A,0x04, + /* 0xDCAB [?] [5557]*/ + 0x20,0x27,0x24,0x24,0x25,0xFD,0x25,0x25,0x25,0x25,0x3C,0xE4,0x49,0x0A,0x10,0x00, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xDCAC [?] [5558]*/ + 0x23,0x22,0x23,0x22,0x23,0xF8,0x27,0x24,0x24,0x27,0x20,0x3B,0xE1,0x40,0x03,0x0C, + 0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0xA4,0xA4,0xFC,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xDCAD [?] [5559]*/ + 0x20,0x27,0x24,0x25,0xF4,0x27,0x24,0x25,0x24,0x25,0x35,0xE5,0x45,0x09,0x09,0x11, + 0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x2C, + /* 0xDCAE [?] [5560]*/ + 0x22,0x21,0x24,0x22,0x20,0xF9,0x22,0x20,0x20,0x27,0x20,0x39,0xE2,0x4C,0x00,0x00, + 0x78,0x28,0x6C,0xAA,0x2A,0x48,0x98,0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xDCAF [?] [5561]*/ + 0x20,0x27,0x24,0x27,0x24,0xFC,0x24,0x24,0x25,0x24,0x3C,0xE5,0x44,0x0B,0x08,0x10, + 0x00,0xFC,0x04,0xFC,0x20,0xA8,0x70,0xA8,0x04,0xA0,0xFC,0x20,0x20,0xFE,0x20,0x20, + /* 0xDCB0 [?] [5562]*/ + 0x08,0xFF,0x08,0x3E,0x2A,0x3E,0x40,0x9F,0x01,0x7F,0x09,0x3F,0xC8,0x0F,0x08,0x0F, + 0x78,0x48,0x86,0x78,0x48,0x30,0x48,0xE4,0x00,0xFC,0x20,0xF8,0x26,0xE0,0x20,0xE0, + /* 0xDCB1 [?] [5563]*/ + 0x08,0xFF,0x08,0x7F,0x41,0x7F,0x22,0x1F,0xFF,0x11,0x1F,0x12,0x1F,0x04,0x7F,0x00, + 0x10,0x7E,0x10,0x7C,0x44,0x28,0x10,0x28,0xF6,0x10,0xF0,0x10,0xF0,0x40,0xFC,0x40, + /* 0xDCB2 [?] [5564]*/ + 0x10,0xFF,0x10,0x7C,0x00,0xFE,0x83,0x7C,0x00,0x7C,0x44,0x7C,0x45,0x2F,0xF1,0x42, + 0x20,0x20,0xBE,0x44,0x50,0x90,0x90,0xA8,0xA4,0xC2,0x20,0x10,0x54,0x42,0x4A,0x38, + /* 0xDCB3 [?] [5565]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDCB4 [?] [5566]*/ + 0x08,0x08,0xFF,0x08,0x08,0x04,0x04,0x7F,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xDCB5 [?] [5567]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x80, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x10,0x20,0x7C,0x04,0x04,0x04,0x44,0x28,0x10, + /* 0xDCB6 [?] [5568]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x01,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xDCB7 [?] [5569]*/ + 0x04,0x04,0xFF,0x04,0x00,0x00,0x3F,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xDCB8 [?] [5570]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x08,0x08,0x0C,0x0A,0x11,0x10,0x20,0x20,0x43,0x8C, + 0x40,0x40,0xFE,0x40,0x00,0xF0,0x20,0x40,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xDCB9 [?] [5571]*/ + 0x08,0x08,0xFF,0x08,0x08,0x02,0x02,0x7F,0x02,0x0A,0x04,0x06,0x09,0x10,0x20,0x40, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xDCBA [?] [5572]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x00,0x00,0x3F,0x20,0x20,0x3F,0x00,0x00,0x00,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xDCBB [?] [5573]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xDCBC [?] [5574]*/ + 0x08,0x08,0xFF,0x0A,0x04,0x08,0x1F,0x00,0x03,0x0C,0x3F,0x10,0x00,0x01,0x0E,0x70, + 0x20,0x20,0xFE,0x20,0x00,0x10,0xE0,0xC0,0x04,0x08,0xF0,0x20,0x40,0x80,0x00,0x00, + /* 0xDCBD [?] [5575]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x3F,0x01,0x01,0xFF,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x00,0x00,0xFE,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xDCBE [?] [5576]*/ + 0x08,0x08,0xFF,0x08,0x00,0x1F,0x00,0x00,0x7F,0x04,0x04,0x04,0x08,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x00,0x00,0xFC,0x40,0x40,0x40,0x44,0x44,0x44,0x3C, + /* 0xDCBF [?] [5577]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x3F,0x00,0x00,0xFF,0x02,0x04,0x08,0x10,0x3F,0x10, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x20,0x10,0xF8,0x08, + /* 0xDCC0 [?] [5578]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0xFF,0x01,0x01,0x3F,0x21,0x21,0x21,0x21,0x21,0x01, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0x28,0x10,0x00, + /* 0xDCC1 [?] [5579]*/ + 0x08,0x08,0xFF,0x09,0x01,0x7F,0x01,0x01,0x3F,0x08,0x04,0x02,0x01,0x06,0x18,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0x00,0xF0,0x20,0x40,0x80,0x00,0xC0,0x30,0x0E, + /* 0xDCC2 [?] [5580]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x21,0x21,0x2F,0x21,0x21,0x22,0x22,0x44,0x48,0x90, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xDCC3 [?] [5581]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x44,0x44,0x83, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x00,0x00,0xE0,0x20,0x20,0xA0,0x44,0x04,0x04,0xFC, + /* 0xDCC4 [?] [5582]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x3F, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0x00,0xF0,0x10,0x10,0xF0,0x00,0x00,0x00,0xFC, + /* 0xDCC5 [?] [5583]*/ + 0x08,0x08,0xFF,0x08,0x08,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x24,0x28,0x30,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x80,0x88,0x90,0xA0,0xC0,0x84,0x84,0x84,0x7C,0x00, + /* 0xDCC6 [?] [5584]*/ + 0x08,0x08,0xFF,0x08,0x08,0x01,0x01,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xDCC7 [?] [5585]*/ + 0x08,0x08,0xFF,0x08,0x09,0x01,0x3F,0x21,0x21,0x22,0x24,0x28,0x20,0x20,0x20,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x08,0x08,0x88,0x48,0x28,0x08,0x08,0x28,0x10, + /* 0xDCC8 [?] [5586]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x1F,0x10,0x11,0x11,0x11,0x12,0x02,0x04,0x18,0x60, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x80,0x82,0x82,0x7E, + /* 0xDCC9 [?] [5587]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x09,0x0E,0x08,0xFF,0x09,0x08,0x08,0x0A,0x0C,0x08, + 0x40,0x40,0xFE,0x40,0x00,0x30,0xC0,0x00,0x00,0xFE,0x00,0x80,0x40,0x30,0x0E,0x00, + /* 0xDCCA [?] [5588]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x14,0x12,0x22,0x41,0x82, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xDCCB [?] [5589]*/ + 0x08,0x08,0xFF,0x08,0x09,0x02,0x04,0x0A,0x31,0xC1,0x1F,0x00,0x00,0x00,0x00,0x01, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x40,0x20,0x18,0x06,0xE0,0x20,0x40,0x40,0x80,0x00, + /* 0xDCCC [?] [5590]*/ + 0x08,0x08,0xFF,0x08,0x10,0x10,0x1F,0x22,0x42,0x84,0x08,0x11,0x22,0x44,0x08,0x10, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xF8,0x48,0x48,0x88,0x88,0x08,0x08,0x08,0x50,0x20, + /* 0xDCCD [?] [5591]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x0F,0x10,0x21,0x41,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x40,0x40,0xFE,0x40,0x00,0x00,0xFC,0x04,0x08,0x00,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xDCCE [?] [5592]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x28,0x30,0x20, + 0x20,0x20,0xFE,0x20,0x78,0x80,0x80,0x80,0x80,0xFE,0x40,0x40,0x24,0x14,0x0C,0x04, + /* 0xDCCF [?] [5593]*/ + 0x08,0x08,0xFF,0x08,0x00,0x0F,0x08,0x10,0x60,0x00,0x1F,0x08,0x04,0x03,0x1C,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0xE0,0x20,0x20,0x1C,0x00,0xE0,0x20,0x40,0x80,0x70,0x0E, + /* 0xDCD0 [?] [5594]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x01,0x01,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x20,0x20,0xFE,0x20,0x20,0x00,0x00,0xFE,0x00,0x00,0x40,0x20,0x10,0x00,0x00,0x00, + /* 0xDCD1 [?] [5595]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x01,0x7F,0x40,0x80,0x00,0x00,0x00,0x00,0x7F,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFE,0x02,0x04,0x00,0x00,0x00,0x00,0xFC,0x00,0x00, + /* 0xDCD2 [?] [5596]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7F,0x02,0x04,0x08,0x0F,0xF8,0x48,0x08,0x08,0x28,0x10, + 0x40,0x40,0xFE,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xDCD3 [?] [5597]*/ + 0x08,0x08,0xFF,0x08,0x00,0x24,0x22,0x21,0x21,0x20,0x20,0x24,0x28,0x30,0x21,0x06, + 0x20,0x20,0xFE,0x20,0x00,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xDCD4 [?] [5598]*/ + 0x08,0x08,0xFF,0x09,0x01,0x01,0xFF,0x01,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xFE,0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xDCD5 [?] [5599]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0xFF,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x40,0xFE,0x40,0x10,0x10,0xFE,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xDCD6 [?] [5600]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x00,0x01,0x03,0x05,0x19,0x61,0x01,0x01,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x80,0x00,0x60,0x10,0x08,0x04,0x00,0x00,0xFE,0x00, + /* 0xDCD7 [?] [5601]*/ + 0x08,0x08,0xFF,0x08,0x08,0x00,0x04,0x7F,0x04,0x04,0x08,0x08,0x10,0x23,0x4C,0x80, + 0x20,0x20,0xFE,0x20,0x20,0x40,0x20,0xFC,0x80,0x88,0x90,0xA0,0xC2,0x82,0x82,0x7E, + /* 0xDCD8 [?] [5602]*/ + 0x04,0x04,0xFF,0x04,0x02,0x02,0xFF,0x04,0x04,0x0F,0x08,0x14,0x22,0x41,0x86,0x38, + 0x40,0x40,0xFE,0x40,0x10,0x08,0xFE,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x70,0x0E, + /* 0xDCD9 [?] [5603]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xDCDA [?] [5604]*/ + 0x08,0x08,0xFF,0x08,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10,0x10,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10,0x10,0xFE,0x00, + /* 0xDCDB [?] [5605]*/ + 0x08,0x08,0xFF,0x08,0x08,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0xFF,0x20,0x20,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x08,0x28,0x10, + /* 0xDCDC [?] [5606]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xDCDD [?] [5607]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x10,0x10,0x37,0x50,0x90,0x10,0x10,0x10,0x13,0x10, + 0x40,0x40,0xFE,0x40,0x00,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0xFC,0x00, + /* 0xDCDE [?] [5608]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x10,0x13,0x30,0x51,0x90,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0xFE,0x40,0x10,0x10,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20, + /* 0xDCDF [?] [5609]*/ + 0x08,0x08,0xFF,0x09,0x02,0x04,0x0A,0x31,0xC1,0x1F,0x00,0x00,0x0C,0x03,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x80,0x40,0x20,0x18,0x06,0xE0,0x20,0x40,0x80,0x00,0x80,0x40, + /* 0xDCE0 [?] [5610]*/ + 0x08,0x08,0xFF,0x09,0x02,0x1F,0x12,0x11,0x11,0x10,0x1F,0x00,0x7F,0x00,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0x10,0x50,0x20,0xFC,0x04,0xE4,0x04,0x28,0x10, + /* 0xDCE1 [?] [5611]*/ + 0x08,0x08,0xFF,0x08,0x06,0x78,0x40,0x40,0x7E,0x40,0x40,0x40,0x4E,0x70,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80,0x80, + /* 0xDCE2 [?] [5612]*/ + 0x08,0x08,0xFF,0x08,0x00,0x0C,0x70,0x40,0x44,0x44,0x5C,0x64,0x48,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80,0x80, + /* 0xDCE3 [?] [5613]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x81,0x01,0x3F,0x01,0x01,0x01,0x01,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xDCE4 [?] [5614]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x80,0x1F,0x04,0x04,0x3F,0x04,0x04,0x04,0x04, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xE0,0x20,0x20,0xA0,0x20,0x14,0x0C,0x04, + /* 0xDCE5 [?] [5615]*/ + 0x08,0x08,0xFF,0x08,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x20,0x20,0x24,0x28,0x30, + 0x20,0x20,0xFE,0x20,0xF8,0x08,0x08,0xF8,0x80,0x80,0xFC,0x40,0x24,0x14,0x0C,0x04, + /* 0xDCE6 [?] [5616]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x04,0x08,0x10,0x20,0xDF,0x10,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0x08,0x50,0x20,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDCE7 [?] [5617]*/ + 0x04,0x04,0xFF,0x04,0x00,0xFF,0x04,0x04,0x3F,0x24,0x24,0x28,0x30,0x20,0x3F,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xFE,0x40,0x40,0xF8,0x48,0x48,0x48,0x38,0x08,0xF8,0x08, + /* 0xDCE8 [?] [5618]*/ + 0x08,0x08,0xFF,0x08,0x01,0xFF,0x01,0x7F,0x01,0x3F,0x21,0x3F,0x02,0x04,0x18,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xFC,0x84,0x4C,0x30,0x0E, + /* 0xDCE9 [?] [5619]*/ + 0x08,0x08,0xFF,0x0A,0x02,0x7F,0x01,0x00,0x07,0x38,0x00,0x7F,0x04,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0x40,0x84,0x64,0x1C,0x00,0xFC,0x40,0x42,0x42,0x3E, + /* 0xDCEA [?] [5620]*/ + 0x08,0x08,0xFF,0x08,0x20,0x20,0x3E,0x20,0x20,0x26,0x39,0x01,0xFF,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x80,0x88,0xB0,0xC4,0x84,0x7C,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xDCEB [?] [5621]*/ + 0x08,0x08,0xFF,0x08,0x04,0x04,0x24,0x24,0x27,0x24,0x24,0x24,0x24,0x2F,0xF0,0x40, + 0x20,0x20,0xFE,0x20,0x40,0x40,0x44,0x48,0x50,0x60,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xDCEC [?] [5622]*/ + 0x08,0x08,0xFF,0x08,0x00,0x1F,0x10,0x10,0x1F,0x00,0x3F,0x20,0x20,0x20,0x3F,0x20, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDCED [?] [5623]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x20,0x2F,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x20, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0xE8,0x08,0xC8,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xDCEE [?] [5624]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x3F,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xC8,0x48,0x48,0xC8,0x08,0x08,0xF8,0x08, + /* 0xDCEF [?] [5625]*/ + 0x04,0x04,0xFF,0x05,0x11,0x11,0x3F,0x41,0x01,0xFF,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x40,0x40,0xFE,0x40,0x00,0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xDCF0 [?] [5626]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7B,0x08,0x10,0x23,0x78,0x08,0x2B,0x10,0x28,0x47,0x80, + 0x40,0x40,0xFE,0x40,0x38,0xC0,0x40,0x40,0xF8,0x40,0x40,0xFC,0x00,0x00,0xFE,0x00, + /* 0xDCF1 [?] [5627]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3F,0x02,0xFF,0x04,0x08,0x34,0xC4,0x04,0x04,0x08,0x10, + 0x20,0x20,0xFE,0x20,0xF0,0x00,0x00,0xFE,0x40,0x20,0x58,0x46,0x40,0x40,0x40,0x40, + /* 0xDCF2 [?] [5628]*/ + 0x08,0x08,0xFF,0x08,0x00,0x08,0x08,0x10,0x37,0x50,0x90,0x10,0x11,0x11,0x12,0x14, + 0x20,0x20,0xFE,0x20,0x00,0x50,0x48,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x06, + /* 0xDCF3 [?] [5629]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x13,0x30,0x50,0x9F,0x10,0x10,0x10,0x10,0x17,0x10, + 0x40,0x40,0xFE,0x40,0x10,0x78,0xC0,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0xFC,0x00, + /* 0xDCF4 [?] [5630]*/ + 0x04,0x04,0xFF,0x04,0x10,0x21,0x40,0x88,0x13,0x30,0x50,0x90,0x10,0x10,0x10,0x10, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xDCF5 [?] [5631]*/ + 0x08,0x08,0xFF,0x09,0x02,0x04,0x08,0x30,0xCF,0x01,0x01,0x1F,0x01,0x01,0x7F,0x00, + 0x20,0x20,0xFE,0x20,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xF0,0x00,0x00,0xFC,0x00, + /* 0xDCF6 [?] [5632]*/ + 0x08,0x08,0xFF,0x09,0x02,0x04,0x08,0x37,0xC0,0x00,0x3F,0x02,0x04,0x08,0x1F,0x08, + 0x20,0x20,0xFE,0x20,0x80,0x40,0x20,0xD8,0x06,0x00,0xF8,0x00,0x40,0x20,0xF0,0x10, + /* 0xDCF7 [?] [5633]*/ + 0x04,0x04,0xFF,0x14,0x10,0x1F,0x20,0x5F,0x90,0x1F,0x10,0x1F,0x10,0x00,0x00,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0xC8,0x48,0xC8,0x48,0xC8,0x48,0x08,0x50,0x20, + /* 0xDCF8 [?] [5634]*/ + 0x08,0x08,0xFF,0x08,0x02,0x07,0x08,0x34,0x02,0x01,0x0F,0x18,0xE8,0x08,0x0F,0x08, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x10,0x20,0x40,0x80,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDCF9 [?] [5635]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x7F,0x08,0x04,0x03,0x0C,0x30,0xC4,0x04,0x04,0x08,0x10, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x20,0x40,0x80,0x60,0x18,0x46,0x40,0x40,0x40,0x40, + /* 0xDCFA [?] [5636]*/ + 0x08,0x08,0xFF,0x08,0x0A,0x01,0x7F,0x08,0x10,0x24,0x44,0x02,0x01,0x06,0x18,0xE0, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFC,0x20,0x10,0x48,0x44,0x80,0x00,0xC0,0x30,0x0E, + /* 0xDCFB [?] [5637]*/ + 0x08,0x08,0xFF,0x0A,0x01,0xFF,0x04,0x08,0x10,0x3F,0x04,0x04,0x04,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x00,0x20,0x10,0xF8,0x48,0x40,0x40,0x44,0x44,0x3C, + /* 0xDCFC [?] [5638]*/ + 0x08,0x08,0xFF,0x08,0x08,0x20,0x17,0x90,0x40,0x48,0x08,0x10,0xE0,0x20,0x2F,0x20, + 0x20,0x20,0xFE,0x20,0x20,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xDCFD [?] [5639]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x81,0x11,0x1F,0x21,0x01,0xFF,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xDCFE [?] [5640]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x40,0x81,0x01,0x7D,0x05,0x09,0x11,0x21,0xC5,0x02, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0x04,0x88,0x50,0x20,0x10,0x08,0x06,0x00, + /* 0xDDA1 [?] [5641]*/ + 0x08,0x08,0xFF,0x08,0x3F,0x00,0x1F,0x00,0x3F,0x00,0xFF,0x08,0x04,0x04,0x00,0x00, + 0x20,0x20,0xFE,0x20,0xF0,0x10,0xF0,0x10,0xF0,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xDDA2 [?] [5642]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x20,0x3F,0x20,0x3F,0x22,0x21,0x20,0x24,0x28,0x30, + 0x40,0x40,0xFE,0x40,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x08,0x10,0xA0,0x40,0x30,0x0E, + /* 0xDDA3 [?] [5643]*/ + 0x04,0x04,0xFF,0x04,0x1F,0x10,0x10,0x1F,0x10,0x10,0x16,0x21,0x20,0x46,0x81,0x00, + 0x40,0x40,0xFE,0x40,0xF0,0x10,0x10,0xF0,0x80,0x40,0x20,0x10,0x88,0x06,0x80,0x40, + /* 0xDDA4 [?] [5644]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7F,0x04,0x02,0x12,0x08,0x09,0xFF,0x02,0x04,0x18,0x60, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x04,0x88,0x80,0x80,0x00,0xFE,0x40,0x20,0x10,0x08, + /* 0xDDA5 [?] [5645]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7C,0x04,0x08,0x10,0x10,0x1D,0xF1,0x12,0x10,0x50,0x20, + 0x40,0x40,0xFE,0x40,0x00,0x20,0x20,0x20,0xA8,0xA4,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xDDA6 [?] [5646]*/ + 0x08,0x08,0xFF,0x08,0x10,0x10,0x21,0x44,0xF8,0x10,0x20,0xFC,0x40,0x1C,0xE3,0x40, + 0x20,0x20,0xFE,0x20,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xDDA7 [?] [5647]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x20,0x45,0xF8,0x10,0x20,0xFC,0x40,0x1C,0xE0,0x40, + 0x40,0x40,0xFE,0x40,0x08,0x08,0x08,0xFE,0x08,0x88,0x48,0x48,0x08,0x08,0x28,0x10, + /* 0xDDA8 [?] [5648]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x10,0x7D,0x12,0x10,0x10,0x1C,0xE0,0x41,0x02,0x0C, + 0x40,0x40,0xFE,0x40,0x80,0x80,0xFC,0x04,0x48,0x40,0x40,0xA0,0xA0,0x10,0x08,0x06, + /* 0xDDA9 [?] [5649]*/ + 0x08,0x08,0xFF,0x09,0x01,0x3F,0x01,0x7F,0x40,0x9F,0x00,0x01,0xFF,0x01,0x05,0x02, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0xFE,0x02,0xE4,0x40,0x80,0xFE,0x00,0x00,0x00, + /* 0xDDAA [?] [5650]*/ + 0x04,0x04,0xFF,0x04,0x00,0x7C,0x44,0x45,0x44,0x7D,0x44,0x44,0x44,0x7C,0x44,0x00, + 0x40,0x40,0xFE,0x40,0x10,0x10,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20, + /* 0xDDAB [?] [5651]*/ + 0x04,0x04,0xFF,0x04,0x1F,0x10,0x10,0x1F,0x01,0x7F,0x41,0x42,0x44,0x48,0x40,0x40, + 0x40,0x40,0xFE,0x40,0xF0,0x10,0x10,0xF0,0x00,0xFC,0x04,0x84,0x44,0x44,0x14,0x08, + /* 0xDDAC [?] [5652]*/ + 0x04,0x04,0xFF,0x04,0x1F,0x01,0x7F,0x05,0x09,0x31,0xCF,0x04,0x04,0x08,0x10,0x60, + 0x40,0x40,0xFE,0x70,0x80,0x00,0xFC,0x40,0x20,0x18,0xC6,0x40,0xF0,0x10,0x50,0x20, + /* 0xDDAD [?] [5653]*/ + 0x08,0x08,0xFF,0x08,0x06,0x38,0x08,0xFF,0x08,0x08,0x0E,0x78,0x08,0x08,0x28,0x13, + 0x20,0x20,0xFE,0x20,0x40,0x50,0x48,0xFE,0x40,0x40,0x24,0x28,0x12,0x2A,0xC6,0x02, + /* 0xDDAE [?] [5654]*/ + 0x04,0x04,0xFF,0x14,0x10,0x3F,0x40,0x9F,0x12,0x11,0xFF,0x22,0x21,0x3F,0x00,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x00,0xF0,0x10,0x10,0xFE,0x10,0x10,0xFC,0x10,0x60, + /* 0xDDAF [?] [5655]*/ + 0x08,0x08,0xFF,0x08,0x00,0x10,0x10,0x24,0x24,0x64,0xA5,0x24,0x24,0x20,0x20,0x23, + 0x20,0x20,0xFE,0x20,0x00,0x40,0x40,0x7E,0x88,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xDDB0 [?] [5656]*/ + 0x08,0x08,0xFF,0x08,0x08,0x08,0x10,0x33,0x50,0x90,0x12,0x11,0x11,0x10,0x17,0x10, + 0x20,0x20,0xFE,0x20,0x80,0x40,0x40,0xFC,0x00,0x08,0x08,0x10,0x10,0x20,0xFE,0x00, + /* 0xDDB1 [?] [5657]*/ + 0x08,0x08,0xFF,0x09,0x02,0x04,0x08,0x37,0xC1,0x01,0x3F,0x01,0x11,0x21,0x45,0x02, + 0x20,0x20,0xFE,0x20,0x80,0x40,0x20,0xD8,0x06,0x00,0xF8,0x00,0x10,0x08,0x04,0x00, + /* 0xDDB2 [?] [5658]*/ + 0x08,0x08,0xFF,0x08,0x09,0x02,0x04,0x08,0x37,0xC0,0x02,0x11,0x09,0x08,0x7F,0x00, + 0x20,0x20,0xFE,0x20,0x20,0x80,0x40,0x20,0xD8,0x06,0x10,0x10,0x20,0x40,0xFC,0x00, + /* 0xDDB3 [?] [5659]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x22,0x11,0x3F,0x00,0x00,0xFF,0x01,0x01,0x05,0x02, + 0x20,0x20,0xFE,0x20,0xF8,0x00,0x10,0x20,0xE0,0x40,0x80,0xFE,0x00,0x00,0x00,0x00, + /* 0xDDB4 [?] [5660]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x22,0x11,0x02,0xFF,0x04,0x08,0x1C,0x03,0x0C,0x70, + 0x20,0x20,0xFE,0x20,0xF8,0x00,0x10,0x20,0x00,0xFE,0x20,0x20,0x40,0x80,0x70,0x08, + /* 0xDDB5 [?] [5661]*/ + 0x04,0x04,0xFF,0x04,0x44,0x28,0x10,0x2B,0x48,0x98,0x28,0x49,0x89,0x0A,0x52,0x24, + 0x40,0x40,0xFE,0x40,0x90,0x88,0x88,0xFE,0xA0,0xA0,0xA0,0x20,0x20,0x22,0x22,0x1E, + /* 0xDDB6 [?] [5662]*/ + 0x04,0x04,0xFF,0x04,0x44,0x28,0x10,0x28,0x48,0x99,0x28,0x48,0x88,0x08,0x51,0x22, + 0x40,0x40,0xFE,0x40,0x20,0x20,0xA4,0xA4,0xA8,0x20,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xDDB7 [?] [5663]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x3F,0x00,0x08,0x04,0xFF,0x01,0x01,0x7F,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00,0x00,0xFC,0x00,0x00,0x00, + /* 0xDDB8 [?] [5664]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x3F,0x20,0x40,0x1F,0x00,0x7F,0x04,0x04,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x04,0x08,0xE0,0x00,0xFC,0x40,0x40,0x44,0x44,0x3C, + /* 0xDDB9 [?] [5665]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x1F,0x10,0x1F,0x10,0x1F,0x11,0x10,0x10,0x12,0x14,0x18, + 0x20,0x20,0xFE,0x20,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x04,0x88,0x50,0x20,0x18,0x06, + /* 0xDDBA [?] [5666]*/ + 0x08,0x08,0xFF,0x08,0x7F,0x42,0x9F,0x10,0x12,0x11,0x10,0x1F,0x00,0x00,0x7F,0x00, + 0x20,0x20,0xFE,0x20,0xFE,0x02,0xF4,0x10,0x10,0x50,0x20,0xFC,0x04,0x04,0xD4,0x08, + /* 0xDDBB [?] [5667]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x23,0x44,0x79,0x11,0x21,0x7D,0x00,0x1C,0xE0,0x40, + 0x40,0x40,0xFE,0x40,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x1E, + /* 0xDDBC [?] [5668]*/ + 0x08,0xFF,0x09,0x3F,0x01,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10, + 0x20,0xFE,0x20,0xF8,0x00,0xF0,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x30, + /* 0xDDBD [?] [5669]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x08,0x10,0x20, + 0x40,0x40,0xFE,0x40,0x20,0x20,0xFC,0x20,0xE0,0x20,0xE0,0x20,0xFE,0x20,0x10,0x08, + /* 0xDDBE [?] [5670]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x51,0x92,0x12,0x14, + 0x40,0x40,0xFE,0x40,0x00,0x0C,0xF0,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xDDBF [?] [5671]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0x10,0xFD,0x31,0x3A,0x54,0x50,0x90,0x11,0x13,0x11, + 0x40,0x40,0xFE,0x40,0x10,0x90,0x90,0x08,0x48,0x44,0x42,0x90,0x88,0x08,0xFC,0x04, + /* 0xDDC0 [?] [5672]*/ + 0x08,0x08,0xFF,0x08,0x0F,0x01,0x3F,0x21,0x3F,0x01,0x7F,0x01,0x3F,0x01,0xFF,0x00, + 0x20,0x20,0xFE,0x20,0xE0,0x00,0xF8,0x08,0xF8,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x00, + /* 0xDDC1 [?] [5673]*/ + 0x08,0x08,0xFF,0x0A,0x02,0x7F,0x04,0x08,0x37,0xC0,0x3F,0x01,0x09,0x11,0x25,0x02, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x40,0x20,0xD8,0x06,0xF8,0x00,0x20,0x10,0x08,0x00, + /* 0xDDC2 [?] [5674]*/ + 0x08,0xFF,0x09,0x7F,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x02,0xFF,0x08,0x1C,0x03,0x7C, + 0x20,0xFE,0x20,0xFC,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0xFE,0x20,0x40,0xC0,0x38, + /* 0xDDC3 [?] [5675]*/ + 0x08,0x08,0xFF,0x08,0x10,0x10,0xFD,0x10,0x14,0x18,0x30,0xD1,0x11,0x12,0x54,0x20, + 0x20,0x20,0xFE,0x20,0x48,0x44,0xFE,0x40,0x40,0xFC,0xA4,0x28,0x28,0x10,0x28,0xC6, + /* 0xDDC4 [?] [5676]*/ + 0x04,0x04,0xFF,0x04,0x08,0x0F,0x08,0x08,0xFF,0x00,0x08,0x2A,0x49,0x89,0x28,0x10, + 0x40,0x40,0xFE,0x40,0x00,0x7C,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xDDC5 [?] [5677]*/ + 0x04,0x04,0xFF,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x20,0x3F,0x20,0x3F,0x20, + 0x40,0x40,0xFE,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xDDC6 [?] [5678]*/ + 0x04,0x04,0xFF,0x04,0x10,0x10,0xFE,0x92,0x92,0x92,0x92,0x9A,0x94,0x10,0x10,0x10, + 0x40,0x40,0xFE,0x40,0x20,0x20,0x3E,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xDDC7 [?] [5679]*/ + 0x08,0x08,0xFF,0x08,0x05,0x39,0x21,0x21,0x3D,0x21,0x21,0x3F,0x02,0x04,0x18,0xE0, + 0x20,0x20,0xFE,0x20,0x00,0x78,0x08,0x08,0x78,0x08,0x08,0xF8,0x80,0x40,0x30,0x0E, + /* 0xDDC8 [?] [5680]*/ + 0x08,0x08,0xFF,0x09,0x08,0x1F,0x10,0x30,0x5F,0x90,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x80,0xFC,0x80,0x80,0xF8,0x80,0x80,0xF8,0x80,0x80,0xFC,0x00, + /* 0xDDC9 [?] [5681]*/ + 0x08,0x08,0xFF,0x0A,0x04,0x3F,0x21,0x3F,0x22,0x3F,0x08,0x10,0xFF,0x00,0x00,0x00, + 0x20,0x20,0xFE,0x20,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80, + /* 0xDDCA [?] [5682]*/ + 0x08,0x08,0xFF,0x08,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x22,0x4A,0x84, + 0x20,0x20,0xFE,0x20,0xFC,0x84,0x94,0x88,0x80,0xFC,0xA4,0xA4,0xA8,0x90,0xA8,0xC6, + /* 0xDDCB [?] [5683]*/ + 0x04,0xFF,0x04,0x08,0x0F,0x10,0x20,0x5F,0x11,0x11,0x1F,0x02,0x04,0x08,0x10,0x60, + 0x40,0xFE,0x40,0x00,0xE0,0x20,0x40,0xF8,0x08,0x08,0xF8,0x80,0xA0,0x92,0x82,0x7E, + /* 0xDDCC [?] [5684]*/ + 0x04,0x04,0xFF,0x04,0x08,0x1F,0x20,0x44,0xB8,0x20,0x20,0x3C,0x20,0x20,0x3F,0x20, + 0x40,0x40,0xFE,0x40,0x00,0xE0,0x20,0x40,0x78,0x08,0x08,0x78,0x08,0x08,0xF8,0x08, + /* 0xDDCD [?] [5685]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x7F,0x08,0x08,0x14,0x22,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x20,0x20,0xFE,0x20,0x00,0xFC,0x20,0x20,0x50,0x88,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xDDCE [?] [5686]*/ + 0x04,0x04,0xFF,0x04,0x10,0x08,0x7E,0x10,0x10,0x1F,0x12,0x12,0x22,0x22,0x4A,0x84, + 0x40,0x40,0xFE,0x40,0x20,0x20,0x50,0x50,0x88,0x06,0x60,0x10,0x00,0xC0,0x30,0x08, + /* 0xDDCF [?] [5687]*/ + 0x04,0x04,0xFF,0x04,0x10,0x09,0x09,0x41,0x21,0x29,0x09,0x11,0x71,0x11,0x17,0x10, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00, + /* 0xDDD0 [?] [5688]*/ + 0x08,0xFF,0x0A,0x01,0x7F,0x40,0x80,0x3F,0x04,0x08,0x1F,0x28,0x48,0x08,0x0F,0x08, + 0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF0,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xDDD1 [?] [5689]*/ + 0x08,0x08,0xFF,0x08,0x01,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0xE4,0x20,0xE0,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xDDD2 [?] [5690]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x7F,0x40,0x90,0x1E,0x22,0x24,0x54,0x08,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x04,0xF8,0x88,0x88,0xA8,0x90,0x84,0x84,0x7C, + /* 0xDDD3 [?] [5691]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x44,0x88,0x1F,0x03,0x0C,0x3F,0x01,0x11,0x25,0x42, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x44,0x80,0x20,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xDDD4 [?] [5692]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7D,0x09,0x11,0x11,0x1D,0x31,0xD1,0x11,0x12,0x52,0x24, + 0x20,0x20,0xFE,0x20,0x1C,0xF0,0x50,0x50,0x50,0x50,0x48,0x48,0x44,0x54,0x5A,0x68, + /* 0xDDD5 [?] [5693]*/ + 0x04,0x04,0xFF,0x04,0x00,0x1F,0x40,0x51,0x49,0x43,0x45,0x49,0x55,0x42,0x7F,0x00, + 0x40,0x40,0xFE,0x40,0x00,0xE0,0x44,0x94,0x24,0xC4,0x44,0x24,0x14,0x04,0xFC,0x04, + /* 0xDDD6 [?] [5694]*/ + 0x04,0xFF,0x04,0x08,0x7F,0x08,0x3E,0x08,0x7F,0x08,0x01,0xFF,0x02,0x0C,0x30,0xC0, + 0x40,0xFE,0x40,0x00,0x7C,0x24,0x24,0x44,0x54,0x88,0x00,0xFE,0x80,0x60,0x18,0x06, + /* 0xDDD7 [?] [5695]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x7F,0x08,0xFF,0x08,0x08,0x7F,0x08,0x0F,0xF0,0x40, + 0x40,0x40,0xFE,0x40,0x00,0x08,0x08,0xFE,0x08,0x48,0x28,0x28,0x08,0x08,0x28,0x10, + /* 0xDDD8 [?] [5696]*/ + 0x04,0x04,0xFF,0x04,0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x12,0x14,0x10,0x1F, + 0x40,0x40,0xFE,0x40,0x20,0xFC,0x20,0xE0,0x20,0xE0,0x20,0xFE,0x40,0x20,0x00,0xF8, + /* 0xDDD9 [?] [5697]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x7E,0x08,0x18,0x1C,0x2A,0x2A,0x48,0x88,0x08,0x08, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xDDDA [?] [5698]*/ + 0x04,0x04,0xFF,0x04,0x00,0x00,0x3F,0x20,0x2F,0x22,0x2F,0x24,0x2D,0x42,0x45,0x88, + 0x40,0x40,0xFE,0x40,0x28,0x24,0xFE,0x20,0xA4,0x24,0xA8,0x98,0x12,0x2A,0x46,0x82, + /* 0xDDDB [?] [5699]*/ + 0x04,0x04,0xFF,0x04,0x00,0x3F,0x20,0x2F,0x28,0x2A,0x2A,0x2A,0x2A,0x45,0x49,0x90, + 0x40,0x40,0xFE,0x48,0x24,0xFE,0x20,0xA4,0xA4,0xA8,0xA8,0x90,0x92,0x2A,0x46,0x82, + /* 0xDDDC [?] [5700]*/ + 0x04,0x04,0xFF,0x04,0x20,0x3C,0x20,0x2C,0x30,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x40,0x40,0xFE,0x40,0x88,0x90,0xE4,0x84,0x7C,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xDDDD [?] [5701]*/ + 0x08,0xFF,0x08,0x1F,0x10,0x1F,0x00,0x7F,0x10,0x1F,0x10,0x1F,0x10,0xFF,0x00,0x00, + 0x20,0xFE,0x20,0xF0,0x10,0xF0,0x00,0xFC,0x10,0xF0,0x10,0xF0,0x3E,0xD0,0x10,0x10, + /* 0xDDDE [?] [5702]*/ + 0x08,0xFF,0x08,0x01,0x1F,0x11,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x11,0x02,0x0C,0x70, + 0x20,0xFE,0x20,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x00,0xF0,0x10,0x10,0xC0,0x30,0x08, + /* 0xDDDF [?] [5703]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x02,0x51,0x51,0x90,0x0F, + 0x20,0xFE,0x20,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x04,0x12,0x12,0xF0, + /* 0xDDE0 [?] [5704]*/ + 0x08,0xFF,0x08,0x00,0x3E,0x22,0x3E,0x00,0x3F,0x00,0xFF,0x08,0x0F,0x00,0x00,0x00, + 0x20,0xFE,0x20,0x00,0xF8,0x88,0xF8,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xA0,0x40, + /* 0xDDE1 [?] [5705]*/ + 0x04,0x04,0xFF,0x04,0x08,0x0B,0x12,0x32,0x53,0x90,0x17,0x10,0x11,0x12,0x1C,0x10, + 0x40,0x40,0xFE,0x40,0x00,0xF8,0x08,0x08,0xF8,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xDDE2 [?] [5706]*/ + 0x04,0x04,0xFF,0x04,0x10,0x21,0x7D,0x45,0x45,0x45,0x7D,0x45,0x45,0x45,0x7D,0x44, + 0x40,0x40,0xFE,0x40,0x00,0xFC,0x24,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE, + /* 0xDDE3 [?] [5707]*/ + 0x08,0xFF,0x09,0x7F,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x9F,0x01,0x01,0x05,0x02, + 0x20,0xFE,0x20,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x02,0xF4,0x00,0x00,0x00,0x00, + /* 0xDDE4 [?] [5708]*/ + 0x04,0x04,0xFF,0x04,0x11,0x09,0x7F,0x05,0x19,0x61,0x04,0xFF,0x08,0x1E,0x03,0x3C, + 0x40,0x40,0xFE,0x40,0x10,0x20,0xFC,0x40,0x30,0x0C,0x00,0xFE,0x20,0x40,0xC0,0x38, + /* 0xDDE5 [?] [5709]*/ + 0x04,0x04,0xFF,0x04,0x20,0x13,0x92,0x42,0x4A,0x0A,0x12,0xE2,0x22,0x24,0x24,0x28, + 0x40,0x40,0xFE,0x40,0x1C,0xE0,0x0E,0xF0,0x90,0x90,0x92,0x94,0x88,0x88,0xA4,0xC2, + /* 0xDDE6 [?] [5710]*/ + 0x08,0x08,0xFF,0x0A,0x01,0x7F,0x40,0x9F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0xFF, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0xF4,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xDDE7 [?] [5711]*/ + 0x08,0xFF,0x08,0x00,0x7C,0x44,0x44,0x7C,0x40,0x41,0x7C,0x40,0x40,0x7C,0x40,0x43, + 0x20,0xFE,0x20,0x00,0xF8,0x08,0x08,0xF8,0x00,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xDDE8 [?] [5712]*/ + 0x08,0xFF,0x08,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x08,0x17,0x21,0xDF,0x05,0x09,0x11, + 0x20,0xFE,0x20,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0xD0,0x08,0xF6,0x40,0x20,0x10, + /* 0xDDE9 [?] [5713]*/ + 0x08,0xFF,0x0A,0x3F,0x02,0xFF,0x02,0x0F,0x34,0xC3,0x00,0x1F,0x10,0x1F,0x10,0x1F, + 0x20,0xFE,0x20,0xC0,0x80,0xFE,0x20,0xC0,0x08,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xDDEA [?] [5714]*/ + 0x08,0xFF,0x08,0x3F,0x20,0x2F,0x20,0x3F,0x24,0x24,0x26,0x20,0x5F,0x44,0x82,0x00, + 0x20,0xFE,0x20,0xFC,0x00,0xF8,0x00,0xFC,0x48,0x30,0x0E,0x20,0xFC,0x20,0xA0,0x40, + /* 0xDDEB [?] [5715]*/ + 0x04,0xFF,0x04,0x1F,0x10,0x1F,0x10,0xFF,0x10,0x2F,0xC0,0x08,0x0F,0x00,0x7F,0x00, + 0x40,0xFE,0x40,0xF0,0x10,0xF0,0x10,0xFE,0x10,0xC8,0x46,0x40,0xF8,0x08,0xA8,0x10, + /* 0xDDEC [?] [5716]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x21,0x2F,0x22,0x24,0x28,0x3F,0x01,0x08,0x48,0x48,0x87, + 0x20,0xFE,0x20,0x00,0xF8,0x08,0xE8,0x88,0x48,0x28,0xF8,0x00,0x84,0x92,0x12,0xF0, + /* 0xDDED [?] [5717]*/ + 0x08,0x08,0xFF,0x08,0x10,0x17,0x20,0x62,0xA1,0x2F,0x20,0x23,0x22,0x22,0x23,0x22, + 0x20,0x20,0xFE,0xA0,0x40,0xFC,0x00,0x08,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xDDEE [?] [5718]*/ + 0x08,0xFF,0x08,0x04,0x08,0x32,0xC4,0x0F,0x00,0x7E,0x22,0x12,0x0A,0x12,0x2A,0x44, + 0x20,0xFE,0x20,0x40,0x20,0x18,0x46,0xE0,0x20,0xFC,0x44,0x24,0x14,0x24,0x54,0x88, + /* 0xDDEF [?] [5719]*/ + 0x08,0xFF,0x08,0x02,0xFF,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x4F,0x48,0x4F,0x40, + 0x20,0xFE,0x20,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x00,0xFC,0x04,0xE4,0x24,0xE4,0x0C, + /* 0xDDF0 [?] [5720]*/ + 0x08,0xFF,0x09,0x00,0x1F,0x10,0x92,0x53,0x54,0x10,0x3F,0x50,0x90,0x21,0x22,0x4C, + 0x20,0xFE,0x20,0x80,0xFC,0x00,0x00,0xF8,0x40,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xDDF1 [?] [5721]*/ + 0x08,0x08,0xFF,0x09,0x00,0xFF,0x04,0x13,0x14,0x1F,0x01,0x7F,0x44,0x4F,0x44,0x40, + 0x20,0x20,0xFE,0x20,0x80,0xFE,0x40,0x90,0x50,0xF0,0x00,0xFC,0x44,0xE4,0x24,0x0C, + /* 0xDDF2 [?] [5722]*/ + 0x08,0xFF,0x08,0x01,0x3F,0x08,0x04,0x7F,0x42,0x81,0x3F,0x04,0x07,0x08,0x10,0x20, + 0x20,0xFE,0x20,0x00,0xF8,0x20,0x40,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x10,0x50,0x20, + /* 0xDDF3 [?] [5723]*/ + 0x08,0xFF,0x08,0x10,0x08,0xFF,0x04,0x3F,0x04,0xFF,0x04,0x3F,0x0C,0x34,0xC4,0x04, + 0x20,0xFE,0x20,0x10,0x20,0xFE,0x40,0xF8,0x48,0xFE,0x48,0xF8,0x60,0x58,0x46,0x40, + /* 0xDDF4 [?] [5724]*/ + 0x08,0x08,0xFF,0x08,0x41,0x22,0xFF,0x08,0x49,0x49,0x49,0x7F,0x11,0x20,0x40,0x81, + 0x20,0x20,0xFE,0x20,0x00,0x7C,0xC4,0x44,0x7C,0x44,0x44,0x7C,0x44,0x44,0x94,0x08, + /* 0xDDF5 [?] [5725]*/ + 0x08,0x08,0xFF,0x08,0x20,0x13,0x92,0x43,0x4A,0x0B,0x12,0xE2,0x22,0x22,0x23,0x22, + 0x20,0x20,0xFE,0xA0,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x42,0x44,0x28,0x90,0x08,0x06, + /* 0xDDF6 [?] [5726]*/ + 0x08,0x08,0xFF,0x08,0x00,0x7F,0x41,0x82,0x0C,0x30,0xDF,0x01,0x3F,0x11,0x09,0x7F, + 0x20,0x20,0xFE,0x20,0x00,0xFE,0x02,0x84,0x60,0x18,0xF6,0x00,0xF8,0x10,0x20,0xFC, + /* 0xDDF7 [?] [5727]*/ + 0x08,0xFF,0x08,0x00,0x7D,0x04,0x28,0x11,0xFD,0x15,0x11,0x11,0x11,0x10,0x50,0x23, + 0x20,0xFE,0x20,0x00,0xFC,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xDDF8 [?] [5728]*/ + 0x08,0xFF,0x08,0x00,0x08,0xFF,0x08,0x7F,0x49,0x49,0x7F,0x1C,0x2A,0x49,0x88,0x08, + 0x20,0xFE,0x20,0x00,0x20,0xA0,0x3E,0x42,0x94,0x10,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xDDF9 [?] [5729]*/ + 0x08,0xFF,0x08,0x3F,0x24,0x3F,0x00,0x7F,0x40,0xBF,0x08,0x0F,0x09,0x10,0x16,0x18, + 0x20,0xFE,0x20,0xF8,0x48,0xF8,0x00,0xFE,0x02,0xF4,0x00,0xE0,0x20,0xA4,0x24,0x1C, + /* 0xDDFA [?] [5730]*/ + 0x08,0x08,0xFF,0x09,0x12,0x67,0x44,0x47,0x44,0x57,0x60,0x04,0x04,0x08,0x10,0x60, + 0x20,0x20,0xFE,0x20,0x00,0xDC,0x44,0xC4,0x44,0xDC,0x00,0x40,0x40,0x42,0x42,0x3E, + /* 0xDDFB [?] [5731]*/ + 0x04,0x04,0xFF,0x04,0x10,0x21,0x41,0x89,0x17,0x30,0x50,0x91,0x11,0x11,0x12,0x14, + 0x40,0x40,0xFE,0x40,0x20,0x3C,0x20,0x20,0xFE,0x00,0x20,0x20,0x3E,0x20,0xA0,0x7E, + /* 0xDDFC [?] [5732]*/ + 0x04,0x04,0xFF,0x04,0x08,0x08,0x14,0x22,0x5D,0x80,0x11,0x09,0x4A,0x27,0xF8,0x40, + 0x40,0x40,0xFE,0x40,0x20,0x20,0x3E,0x44,0xA4,0x24,0x28,0x28,0x10,0xA8,0x44,0x82, + /* 0xDDFD [?] [5733]*/ + 0x08,0x08,0xFF,0x08,0x20,0x10,0xFE,0x21,0x20,0x3C,0x25,0x24,0x25,0x44,0x54,0x89, + 0x20,0x20,0xFE,0x20,0x40,0x40,0xFE,0x20,0x40,0xFC,0x20,0x20,0xFE,0x50,0x88,0x06, + /* 0xDDFE [?] [5734]*/ + 0x08,0xFF,0x08,0x20,0x17,0x05,0x44,0x4F,0x59,0x6F,0x49,0x4F,0x49,0x4F,0x48,0x40, + 0x20,0xFE,0x20,0x00,0xFC,0x04,0x84,0xF4,0x04,0xE4,0x04,0xE4,0x04,0xF4,0x14,0x08, + /* 0xDEA1 [?] [5735]*/ + 0x08,0xFF,0x08,0x23,0x12,0x43,0x2A,0x0B,0x72,0x13,0x11,0xFF,0x05,0x19,0xE1,0x01, + 0x20,0xFE,0x20,0xFC,0x00,0xF8,0x08,0xF8,0x00,0xFC,0x00,0xFE,0x40,0x30,0x0E,0x00, + /* 0xDEA2 [?] [5736]*/ + 0x08,0xFF,0x0A,0x01,0x7F,0x40,0x80,0x3E,0x00,0x7E,0x14,0x14,0x14,0x24,0x24,0x43, + 0x20,0xFE,0x20,0x00,0xFE,0x02,0x24,0x38,0x20,0xF8,0x08,0x50,0x24,0x54,0x84,0xFC, + /* 0xDEA3 [?] [5737]*/ + 0x08,0xFF,0x08,0x01,0x7F,0x48,0x8B,0x10,0x33,0x52,0x92,0x13,0x12,0x12,0x13,0x12, + 0x20,0xFE,0x20,0x00,0xFE,0x02,0xF4,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xDEA4 [?] [5738]*/ + 0x08,0xFF,0x08,0x3C,0x24,0x14,0x25,0x06,0x18,0xE3,0x0C,0x31,0x06,0x38,0x07,0x38, + 0x20,0xFE,0x20,0xF8,0x48,0x28,0x48,0xC0,0x30,0x0E,0x40,0x80,0x30,0xC0,0x00,0x00, + /* 0xDEA5 [?] [5739]*/ + 0x08,0xFF,0x09,0x3F,0x01,0x1F,0x11,0x1F,0x11,0x1F,0x01,0x7F,0x02,0x49,0x48,0x87, + 0x20,0xFE,0x20,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x08,0xFC,0x04,0x08,0x24,0xE4, + /* 0xDEA6 [?] [5740]*/ + 0x08,0xFF,0x08,0x7F,0x04,0x3F,0x24,0x3F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x01,0x01, + 0x20,0xFE,0x20,0xFC,0x40,0xF8,0x48,0xF8,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0x00, + /* 0xDEA7 [?] [5741]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x28,0x25,0x2F,0x22,0x2A,0x2A,0x2F,0x22,0x44,0x44,0x88, + 0x20,0xFE,0x20,0x00,0xFE,0x90,0x10,0xBE,0x22,0xD4,0x90,0x90,0x28,0x28,0x44,0x82, + /* 0xDEA8 [?] [5742]*/ + 0x08,0xFF,0x08,0x00,0xFF,0x10,0x29,0x4E,0x96,0x25,0xCD,0x14,0x24,0xC4,0x14,0x08, + 0x20,0xFE,0x20,0x10,0x50,0x7C,0x90,0x10,0x7C,0x10,0x10,0xFE,0x40,0x30,0x0E,0x00, + /* 0xDEA9 [?] [5743]*/ + 0x08,0xFF,0x08,0x1F,0x10,0x1F,0x10,0xFF,0x22,0x3E,0x22,0x3E,0x22,0x2F,0xF2,0x42, + 0x20,0xFE,0x20,0xF0,0x10,0xF0,0x10,0xFE,0x00,0xFC,0x44,0x44,0x28,0x10,0x28,0xC6, + /* 0xDEAA [?] [5744]*/ + 0x04,0xFF,0x04,0x3E,0x22,0x3E,0x00,0xFF,0x22,0x3E,0x22,0x3E,0x22,0x2F,0xF2,0x42, + 0x40,0xFE,0x40,0x28,0x24,0x24,0x20,0xFE,0x20,0x28,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xDEAB [?] [5745]*/ + 0x08,0xFF,0x08,0x3F,0x24,0x3F,0x00,0x7F,0x40,0x9F,0x10,0x1F,0x10,0x1F,0x10,0x1F, + 0x20,0xFE,0x20,0xF8,0x48,0xF8,0x00,0xFE,0x02,0xF4,0x10,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xDEAC [?] [5746]*/ + 0x08,0xFF,0x08,0x00,0x3F,0x11,0x09,0xFF,0x09,0x30,0xDF,0x11,0x1F,0x11,0x1F,0x10, + 0x20,0xFE,0x20,0xF8,0x00,0x10,0x20,0xFE,0x20,0x18,0xF6,0x10,0xF0,0x10,0xF0,0x10, + /* 0xDEAD [?] [5747]*/ + 0x08,0xFF,0x08,0x22,0x14,0x7F,0x49,0x7F,0x49,0x7F,0x08,0xFF,0x08,0x08,0x08,0x09, + 0x20,0xFE,0x20,0x0C,0x70,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xDEAE [?] [5748]*/ + 0x08,0x08,0xFF,0x08,0x00,0x3E,0x20,0x3C,0x20,0x3C,0x20,0xFE,0x20,0x44,0xFE,0x43, + 0x20,0x20,0xFE,0x20,0x48,0x48,0x48,0xFC,0x48,0x48,0x48,0xFE,0x00,0x48,0x84,0x02, + /* 0xDEAF [?] [5749]*/ + 0x08,0xFF,0x08,0x00,0x7E,0x11,0x10,0x3C,0x25,0x64,0x94,0x09,0x08,0x10,0x23,0x40, + 0x20,0xFE,0x20,0x50,0x50,0xDC,0x50,0x50,0xDC,0x50,0x50,0xDC,0x50,0x50,0xFE,0x00, + /* 0xDEB0 [?] [5750]*/ + 0x08,0xFF,0x08,0x7F,0x44,0x7F,0x00,0x7F,0x40,0xBF,0x08,0x1F,0x62,0x14,0x18,0xE0, + 0x20,0xFE,0x20,0xFC,0x44,0xFC,0x00,0xFE,0x02,0xF4,0x40,0x48,0x50,0x62,0x42,0x3E, + /* 0xDEB1 [?] [5751]*/ + 0x04,0x04,0xFF,0x04,0x22,0x4A,0x8A,0x1F,0x20,0x6F,0xA0,0x2F,0x29,0x29,0x29,0x30, + 0x40,0x40,0xFE,0x40,0x20,0xA0,0xBE,0xC4,0xA4,0x24,0x28,0x28,0x10,0xA8,0x44,0x82, + /* 0xDEB2 [?] [5752]*/ + 0x08,0xFF,0x08,0x01,0x3F,0x08,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x49,0x48,0x87, + 0x20,0xFE,0x20,0x00,0xF8,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x04,0x92,0xF2, + /* 0xDEB3 [?] [5753]*/ + 0x08,0xFF,0x0A,0x01,0xFF,0x10,0x20,0x45,0x7B,0x11,0x25,0x7D,0x09,0x11,0x21,0xC1, + 0x20,0xFE,0x20,0x00,0xFE,0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xDEB4 [?] [5754]*/ + 0x04,0xFF,0x04,0x00,0x49,0x2A,0xFF,0x2A,0x49,0x10,0xFE,0x22,0x64,0x18,0x24,0xC2, + 0x40,0xFE,0x40,0x00,0x20,0x20,0x3E,0x44,0xA4,0x24,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xDEB5 [?] [5755]*/ + 0x08,0xFF,0x08,0x00,0x3E,0x22,0x22,0x3E,0x21,0x20,0x3E,0x52,0x52,0x9E,0x12,0x00, + 0x20,0xFE,0x20,0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0x20,0xFC,0x20,0x20,0x20,0x20, + /* 0xDEB6 [?] [5756]*/ + 0x08,0xFF,0x08,0x23,0x22,0xFA,0x4A,0x4B,0x4A,0x92,0x52,0x22,0x53,0x4A,0x84,0x08, + 0x20,0xFE,0x20,0xFE,0x00,0xFC,0x00,0xFE,0xA4,0x98,0xC6,0x08,0xFE,0x88,0x48,0x18, + /* 0xDEB7 [?] [5757]*/ + 0x08,0xFF,0x09,0xFF,0x01,0x3F,0x00,0x1F,0x10,0x7F,0x48,0x9F,0x01,0x3F,0x01,0xFF, + 0x20,0xFE,0x20,0xFE,0x00,0xF8,0x00,0xF0,0x10,0xFE,0x22,0xF4,0x00,0xF8,0x00,0xFE, + /* 0xDEB8 [?] [5758]*/ + 0x08,0xFF,0x08,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x7F,0x02,0x3F,0x24,0x24, + 0x20,0xFE,0x20,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFC,0x00,0xF8,0x48,0x58, + /* 0xDEB9 [?] [5759]*/ + 0x08,0xFF,0x08,0x3F,0x01,0xFF,0x01,0x3F,0x29,0x3F,0x01,0x3F,0x01,0xFF,0x24,0x42, + 0x20,0xFE,0x20,0xF8,0x00,0xFE,0x00,0xF8,0x28,0xF8,0x00,0xF8,0x00,0xFE,0x48,0x24, + /* 0xDEBA [?] [5760]*/ + 0x08,0x08,0xFF,0x08,0x20,0x3E,0x44,0xFF,0x49,0x7F,0x49,0x7F,0x00,0x0F,0xF0,0x40, + 0x20,0x20,0xFE,0x20,0x44,0x28,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x10,0x10,0x10, + /* 0xDEBB [?] [5761]*/ + 0x08,0xFF,0x08,0x01,0x7F,0x08,0x0F,0x00,0x7F,0x48,0x4F,0x01,0x7F,0x05,0x19,0xE1, + 0x20,0xFE,0x20,0x00,0xFC,0x20,0xE0,0x00,0xFC,0x24,0xEC,0x00,0xFC,0x40,0x30,0x0E, + /* 0xDEBC [?] [5762]*/ + 0x08,0xFF,0x08,0x06,0x38,0x08,0x7E,0x1C,0x2A,0x49,0x02,0x1D,0xE9,0x05,0x09,0x13, + 0x20,0xFE,0x20,0x40,0x7C,0x94,0x24,0x44,0x94,0x08,0xC0,0x30,0x2E,0x40,0x20,0x10, + /* 0xDEBD [?] [5763]*/ + 0x08,0xFF,0x08,0x3F,0x01,0x7F,0x41,0x9D,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F, + 0x20,0xFE,0x20,0xF8,0x00,0xFE,0x02,0x74,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC, + /* 0xDEBE [?] [5764]*/ + 0x08,0xFF,0x08,0x00,0x40,0x2F,0x28,0x0B,0xE8,0x2B,0x29,0x2A,0x31,0x22,0x51,0x8F, + 0x20,0xFE,0xA0,0xF8,0x80,0xFC,0x84,0xF0,0x88,0xF8,0x40,0xA8,0x70,0xA8,0x60,0xFE, + /* 0xDEBF [?] [5765]*/ + 0x08,0xFF,0x08,0x22,0x47,0x88,0x17,0x25,0x67,0xA5,0x27,0x21,0x2F,0x21,0x22,0x24, + 0x20,0xFE,0x20,0x00,0xDC,0x80,0xC0,0x7E,0xC8,0x48,0xC8,0x08,0xE8,0x08,0xA8,0x50, + /* 0xDEC0 [?] [5766]*/ + 0x08,0xFF,0x28,0x3F,0x40,0xBE,0x2A,0xFF,0x4A,0x7F,0x08,0x1F,0x02,0x3F,0x11,0x23, + 0x20,0xFE,0x20,0x20,0x3E,0x48,0xA8,0x28,0x10,0x28,0x46,0x80,0x10,0xF8,0x10,0x08, + /* 0xDEC1 [?] [5767]*/ + 0x04,0xFF,0x04,0x20,0x7D,0x44,0x7C,0x41,0x7C,0x45,0x7C,0x01,0x7F,0x05,0x19,0xE1, + 0x40,0xFE,0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x00,0xFC,0x40,0x30,0x0E, + /* 0xDEC2 [?] [5768]*/ + 0x08,0xFF,0x08,0x3F,0x24,0x3F,0x26,0x2D,0x34,0x21,0x3F,0x21,0x2F,0x41,0x5F,0x81, + 0x20,0xFE,0xA0,0xFE,0x10,0x7C,0x38,0x54,0x12,0x20,0x3E,0x20,0x3C,0x20,0x3E,0x20, + /* 0xDEC3 [?] [5769]*/ + 0x00,0x00,0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xDEC4 [?] [5770]*/ + 0x02,0x01,0x7F,0x04,0x24,0x44,0x89,0x10,0x00,0x08,0x08,0xFF,0x08,0x10,0x20,0x40, + 0x00,0x00,0xFC,0x40,0x50,0x48,0x44,0x80,0x00,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xDEC5 [?] [5771]*/ + 0x01,0x01,0x7F,0x02,0x04,0x08,0x30,0xC9,0x09,0x09,0x09,0x09,0x11,0x11,0x21,0x40, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x26,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xDEC6 [?] [5772]*/ + 0x02,0x02,0x7F,0x04,0x08,0x30,0xDF,0x10,0x12,0x11,0x10,0x11,0x12,0x10,0x1F,0x00, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xF6,0x00,0x20,0x40,0x80,0x40,0x20,0x00,0xF8,0x00, + /* 0xDEC7 [?] [5773]*/ + 0x01,0x01,0x7F,0x02,0x04,0x08,0x3F,0xC8,0x0F,0x08,0x0F,0x08,0x09,0x7E,0x00,0x00, + 0x00,0x00,0xFC,0x80,0x40,0x20,0xF8,0x26,0xE0,0x20,0xE0,0x20,0xF8,0x20,0x20,0x20, + /* 0xDEC8 [?] [5774]*/ + 0x02,0x01,0x7F,0x04,0x24,0x44,0x89,0x10,0x01,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0xFC,0x40,0x50,0x48,0x44,0x80,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xDEC9 [?] [5775]*/ + 0x00,0x7F,0x22,0x15,0x08,0x1F,0x03,0x0C,0x3F,0x01,0x01,0x7F,0x02,0x04,0x18,0xE0, + 0xFC,0x00,0x08,0x10,0x40,0x80,0x20,0x10,0xF8,0x08,0x00,0xFC,0x80,0x40,0x30,0x0E, + /* 0xDECA [?] [5776]*/ + 0x24,0x24,0x24,0x3D,0x04,0xFC,0x24,0x24,0x45,0x01,0xFF,0x02,0x04,0x08,0x30,0xC0, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06, + /* 0xDECB [?] [5777]*/ + 0x10,0x10,0xFE,0x28,0x45,0x82,0x7C,0x00,0xFE,0x20,0x40,0x7C,0x04,0x04,0x28,0x10, + 0x40,0x40,0xFC,0x84,0x04,0xF4,0x94,0x94,0xF4,0x84,0x94,0x88,0x82,0x82,0x7E,0x00, + /* 0xDECC [?] [5778]*/ + 0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x00,0x00,0x00,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x82,0x7E,0x00, + /* 0xDECD [?] [5779]*/ + 0x20,0x20,0x20,0x21,0xFD,0x2A,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x48,0x47,0x80, + 0x80,0x80,0x80,0xF8,0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x50,0x22,0x02,0xFE,0x00, + /* 0xDECE [?] [5780]*/ + 0x20,0x20,0x20,0x20,0xFD,0x2A,0x28,0x28,0x28,0x28,0x29,0x29,0x2A,0x48,0x47,0x80, + 0x20,0x20,0x50,0x88,0x04,0x02,0x88,0x88,0x88,0x88,0x08,0x08,0x0A,0x02,0xFE,0x00, + /* 0xDECF [?] [5781]*/ + 0x20,0x22,0x22,0x22,0xFE,0x2A,0x28,0x2B,0x2A,0x2A,0x2A,0x2F,0x28,0x48,0x47,0x80, + 0x90,0x90,0xBC,0xD0,0x88,0x88,0x00,0xF8,0xA8,0xA8,0xA8,0xFE,0x02,0x02,0xFE,0x00, + /* 0xDED0 [?] [5782]*/ + 0x10,0x10,0x10,0x10,0xF8,0x10,0x14,0x18,0x30,0xD0,0x10,0x10,0x10,0x10,0x50,0x20, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xDED1 [?] [5783]*/ + 0x11,0x10,0x10,0x12,0xFA,0x12,0x16,0x1A,0x32,0xD2,0x12,0x12,0x12,0x12,0x52,0x22, + 0x00,0x80,0xBC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xDED2 [?] [5784]*/ + 0x10,0x10,0x10,0x11,0xFC,0x10,0x11,0x14,0x18,0x31,0xD0,0x10,0x10,0x10,0x50,0x20, + 0x20,0x20,0x20,0xFC,0x20,0x40,0xFE,0x40,0x80,0xFC,0x04,0x88,0x50,0x20,0x10,0x10, + /* 0xDED3 [?] [5785]*/ + 0x10,0x10,0x10,0x13,0xFA,0x12,0x16,0x1B,0x32,0xD2,0x12,0x13,0x12,0x10,0x50,0x20, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0xFE,0x22,0x20,0x20,0x20, + /* 0xDED4 [?] [5786]*/ + 0x10,0x10,0x10,0x11,0xFD,0x13,0x15,0x11,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x88,0x88,0x88,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xDED5 [?] [5787]*/ + 0x10,0x10,0x10,0x10,0xFD,0x13,0x10,0x14,0x18,0x33,0xD0,0x10,0x11,0x11,0x52,0x24, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x88,0x88,0xFE,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xDED6 [?] [5788]*/ + 0x20,0x21,0x21,0x22,0xFA,0x24,0x27,0x29,0x32,0xE2,0x24,0x27,0x20,0x20,0xA0,0x41, + 0x20,0x20,0x20,0x20,0xFC,0xA4,0x24,0x24,0x24,0x24,0xA4,0xA4,0xC4,0x44,0x94,0x08, + /* 0xDED7 [?] [5789]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x11,0x14,0x18,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDED8 [?] [5790]*/ + 0x20,0x20,0x23,0x20,0xF8,0x27,0x20,0x29,0x32,0xE5,0x21,0x21,0x21,0x22,0xA2,0x44, + 0x10,0x78,0xC0,0x40,0x40,0xFE,0xA0,0x10,0x08,0x16,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xDED9 [?] [5791]*/ + 0x11,0x11,0x12,0x11,0xFD,0x10,0x10,0x14,0x19,0x31,0xD2,0x14,0x10,0x10,0x50,0x23, + 0x24,0x24,0x48,0x24,0x24,0x00,0x80,0xFC,0x04,0x84,0x48,0x28,0x10,0x20,0xC0,0x00, + /* 0xDEDA [?] [5792]*/ + 0x10,0x11,0x11,0x11,0xFD,0x10,0x13,0x12,0x1A,0x32,0xD3,0x12,0x12,0x12,0x51,0x20, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x44,0x44,0x44,0xFC,0x00,0x02,0x02,0xFE,0x00, + /* 0xDEDB [?] [5793]*/ + 0x10,0x10,0x13,0x10,0xFA,0x11,0x15,0x18,0x33,0xD0,0x11,0x10,0x10,0x10,0x50,0x20, + 0x08,0x3C,0xC0,0x44,0x24,0x28,0x00,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x50,0x20, + /* 0xDEDC [?] [5794]*/ + 0x10,0x11,0x10,0x10,0xFB,0x10,0x14,0x19,0x30,0xD0,0x11,0x12,0x14,0x10,0x50,0x20, + 0x00,0xFC,0x44,0x44,0xFE,0x44,0x44,0xFC,0x80,0x80,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xDEDD [?] [5795]*/ + 0x20,0x23,0x20,0x20,0xFB,0x20,0x21,0x2A,0x34,0xE0,0x20,0x22,0x22,0x24,0xA1,0x40, + 0x00,0xFC,0x40,0x40,0xFE,0xA0,0x10,0x08,0x46,0x40,0x48,0x64,0x52,0x52,0x40,0x80, + /* 0xDEDE [?] [5796]*/ + 0x20,0x2F,0x24,0x24,0xF4,0x27,0x24,0x24,0x37,0xE4,0x24,0x25,0x2E,0x20,0xA0,0x40, + 0x00,0xDE,0x92,0x92,0x94,0x94,0x98,0x94,0x92,0x92,0x92,0xDA,0x94,0x90,0x90,0x90, + /* 0xDEDF [?] [5797]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x12,0x17,0x1A,0x32,0xD2,0x12,0x12,0x14,0x55,0x28, + 0x00,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xDEE0 [?] [5798]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x12,0x10,0x18,0x33,0xD0,0x11,0x11,0x12,0x50,0x20, + 0x20,0x20,0xFE,0x50,0x88,0x04,0xFA,0x00,0x00,0xFE,0x20,0x24,0x22,0x22,0xA0,0x40, + /* 0xDEE1 [?] [5799]*/ + 0x10,0x10,0x13,0x10,0xFD,0x12,0x17,0x10,0x1B,0x32,0xD2,0x12,0x13,0x10,0x50,0x20, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xFE,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xDEE2 [?] [5800]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x2A,0x32,0xE2,0x22,0x23,0x22,0x22,0xA3,0x42, + 0x00,0xFE,0x02,0x02,0xFE,0x22,0x22,0xFA,0x22,0x32,0x2A,0xFE,0x02,0x02,0xFE,0x02, + /* 0xDEE3 [?] [5801]*/ + 0x10,0x10,0x13,0x12,0xFA,0x13,0x16,0x1A,0x33,0xD0,0x11,0x17,0x10,0x10,0x50,0x20, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xDEE4 [?] [5802]*/ + 0x11,0x11,0x11,0x12,0xFC,0x11,0x14,0x18,0x33,0xD0,0x10,0x11,0x12,0x10,0x50,0x20, + 0x00,0x00,0xFC,0x04,0x44,0x54,0xE4,0x44,0xFC,0x44,0xE4,0x54,0x44,0x44,0x14,0x08, + /* 0xDEE5 [?] [5803]*/ + 0x10,0x10,0x11,0x10,0xFD,0x10,0x10,0x13,0x18,0x30,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xDEE6 [?] [5804]*/ + 0x10,0x10,0x13,0x12,0xFA,0x13,0x16,0x1A,0x32,0xD3,0x12,0x12,0x12,0x14,0x55,0x2A, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x00,0x28,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xDEE7 [?] [5805]*/ + 0x10,0x10,0x13,0x12,0xFE,0x13,0x12,0x12,0x1A,0x32,0xD2,0x12,0x14,0x14,0x58,0x20, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x84,0x94,0x88, + /* 0xDEE8 [?] [5806]*/ + 0x11,0x11,0x11,0x13,0xFD,0x11,0x11,0x14,0x19,0x31,0xD1,0x11,0x11,0x10,0x50,0x23, + 0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x00,0xFC,0x04,0x24,0x24,0x24,0x58,0x84,0x02, + /* 0xDEE9 [?] [5807]*/ + 0x10,0x11,0x11,0x13,0xFD,0x11,0x11,0x15,0x19,0x30,0xD3,0x10,0x10,0x11,0x56,0x20, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xDEEA [?] [5808]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x12,0x11,0x19,0x31,0xD1,0x11,0x11,0x10,0x57,0x20, + 0x20,0x20,0xFE,0x70,0xA8,0x24,0x22,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xDEEB [?] [5809]*/ + 0x10,0x13,0x12,0x12,0xFA,0x12,0x16,0x1A,0x32,0xD3,0x12,0x12,0x12,0x12,0x52,0x23, + 0x00,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x20,0xFE,0x48,0xC8,0x30,0x48,0x84,0xFE, + /* 0xDEEC [?] [5810]*/ + 0x22,0x22,0x22,0x23,0xF4,0x24,0x27,0x2A,0x32,0xEF,0x22,0x22,0x22,0x23,0xA2,0x40, + 0x10,0x10,0x10,0xBE,0x22,0x44,0x90,0x10,0x10,0x90,0x28,0x28,0xA8,0x44,0x44,0x82, + /* 0xDEED [?] [5811]*/ + 0x20,0x20,0x21,0x22,0xFD,0x20,0x23,0x2A,0x32,0xE3,0x22,0x22,0x23,0x22,0xA2,0x42, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xDEEE [?] [5812]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x17,0x10,0x19,0x31,0xD1,0x11,0x11,0x11,0x51,0x21, + 0x40,0x20,0xFE,0x00,0x04,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xDEEF [?] [5813]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x14,0x19,0x31,0xD1,0x11,0x11,0x11,0x10,0x53,0x20, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xDEF0 [?] [5814]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x2A,0x32,0xE2,0x22,0x23,0x24,0x24,0xA8,0x51, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x84,0x48,0xFC,0x48,0x48,0xFE,0x48,0x48,0x88,0x08, + /* 0xDEF1 [?] [5815]*/ + 0x10,0x13,0x10,0x12,0xFD,0x10,0x11,0x12,0x18,0x30,0xD3,0x10,0x10,0x10,0x51,0x22, + 0x10,0xD4,0x58,0x52,0x8C,0x88,0x04,0xFA,0x20,0x20,0xFE,0x20,0x50,0x88,0x04,0x02, + /* 0xDEF2 [?] [5816]*/ + 0x21,0x21,0x22,0x23,0xF8,0x27,0x20,0x29,0x36,0xE0,0x21,0x26,0x20,0x21,0xA6,0x40, + 0x00,0xF8,0x08,0xF0,0x10,0xFE,0x80,0x44,0x68,0xB0,0x28,0x68,0xA4,0x22,0xA0,0x40, + /* 0xDEF3 [?] [5817]*/ + 0x20,0x20,0x20,0x27,0xF4,0x24,0x27,0x24,0x34,0xE4,0x24,0x24,0x25,0x29,0xA9,0x52, + 0x40,0x7C,0x40,0xFE,0x42,0x70,0xC4,0x44,0x3C,0x20,0x10,0x54,0x42,0x42,0x4A,0x38, + /* 0xDEF4 [?] [5818]*/ + 0x20,0x27,0x24,0x24,0xF7,0x24,0x24,0x25,0x34,0xE7,0x20,0x20,0x25,0x25,0xA9,0x40, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0xA4,0x14,0x04,0xFC,0x40,0x24,0x22,0x0A,0x08,0xF8, + /* 0xDEF5 [?] [5819]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x12,0x16,0x1A,0x32,0xD2,0x12,0x12,0x14,0x55,0x2A, + 0x04,0x1E,0xF0,0x1E,0x10,0xFE,0x92,0x98,0xF2,0x8E,0x80,0xB8,0xA8,0xAA,0x4A,0x86, + /* 0xDEF6 [?] [5820]*/ + 0x11,0x10,0x10,0x17,0xF8,0x13,0x10,0x1F,0x30,0xD3,0x10,0x11,0x12,0x14,0x50,0x20, + 0x10,0xA0,0x00,0xFE,0xA0,0xF8,0xA8,0xFE,0xA8,0xF8,0xA0,0xB0,0xA8,0xA6,0xA0,0xA0, + /* 0xDEF7 [?] [5821]*/ + 0x24,0x22,0x22,0x20,0xF7,0x21,0x25,0x25,0x35,0xE7,0x21,0x21,0x22,0x22,0xA4,0x48, + 0x40,0x5E,0x92,0x12,0xD2,0x1E,0x52,0x52,0x52,0xDE,0x52,0x12,0x12,0x22,0x2A,0x44, + /* 0xDEF8 [?] [5822]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x2A,0x32,0xE2,0x23,0x22,0x22,0x24,0xA4,0x48, + 0x00,0xFC,0x04,0x04,0xFC,0x48,0x48,0xFC,0x48,0x48,0xFE,0xA4,0xA8,0x90,0xC8,0x86, + /* 0xDEF9 [?] [5823]*/ + 0x20,0x27,0x20,0x20,0xF7,0x24,0x24,0x27,0x30,0xE4,0x22,0x22,0x24,0x20,0xA5,0x42, + 0x00,0xBC,0x84,0x84,0xBC,0x20,0x20,0xBC,0x84,0xA4,0x94,0x94,0xA4,0x84,0x28,0x10, + /* 0xDEFA [?] [5824]*/ + 0x23,0x21,0x20,0x23,0xF8,0x27,0x24,0x2B,0x34,0xE0,0x27,0x20,0x21,0x22,0xAC,0x40, + 0xF0,0x10,0xE0,0x18,0x00,0xBC,0xA4,0x18,0xA4,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xDEFB [?] [5825]*/ + 0x10,0x13,0x12,0x13,0xFE,0x13,0x10,0x15,0x1B,0x30,0xD1,0x13,0x10,0x11,0x52,0x24, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x80,0x10,0xE0,0x48,0x84,0xFE,0x22,0x28,0xA4,0x42, + /* 0xDEFC [?] [5826]*/ + 0x20,0x2F,0x28,0x2A,0xFA,0x2A,0x25,0x28,0x30,0xEF,0x21,0x22,0x23,0x20,0xA1,0x4E, + 0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0x80,0xFE,0x10,0x10,0xA0,0x60,0x98,0x04, + /* 0xDEFD [?] [5827]*/ + 0x20,0x20,0x23,0x22,0xFA,0x22,0x23,0x2A,0x32,0xE2,0x22,0x22,0x25,0x25,0xAA,0x50, + 0x40,0x20,0xFE,0x00,0x48,0x48,0xFE,0x48,0x48,0x48,0x78,0x00,0x54,0x2A,0x2A,0x00, + /* 0xDEFE [?] [5828]*/ + 0x20,0x27,0x20,0x21,0xFF,0x24,0x24,0x27,0x34,0xE7,0x24,0x24,0x27,0x2C,0xA0,0x40, + 0x08,0x88,0x88,0x10,0xDE,0x94,0xA4,0x94,0x94,0x94,0x94,0xC8,0x88,0x94,0xA4,0xC2, + /* 0xDFA1 [?] [5829]*/ + 0x20,0x27,0x20,0x24,0xFA,0x24,0x20,0x28,0x33,0xE2,0x22,0x23,0x22,0x22,0xA3,0x42, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x84,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xDFA2 [?] [5830]*/ + 0x22,0x22,0x22,0x2F,0xF2,0x22,0x27,0x20,0x30,0xE7,0x25,0x25,0x25,0x27,0xA5,0x40, + 0x00,0xFE,0x10,0xA0,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xDFA3 [?] [5831]*/ + 0x21,0x23,0x24,0x2F,0xF4,0x27,0x24,0x27,0x30,0xEF,0x20,0x23,0x22,0x23,0xA2,0x43, + 0x00,0xF0,0x10,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xDFA4 [?] [5832]*/ + 0x21,0x20,0x27,0x20,0xFB,0x22,0x23,0x2A,0x33,0xE2,0x23,0x20,0x27,0x21,0xA0,0x40, + 0x08,0x90,0xFE,0x90,0xFC,0x94,0x1C,0x04,0xFC,0x04,0xFC,0x08,0xFE,0x08,0xA8,0x10, + /* 0xDFA5 [?] [5833]*/ + 0x20,0x20,0x27,0x25,0xFA,0x24,0x23,0x2A,0x33,0xE0,0x27,0x24,0x27,0x24,0xA0,0x40, + 0x80,0x40,0xFC,0x14,0x48,0x44,0xF8,0x48,0xF8,0x40,0xFC,0x44,0xFC,0x44,0x40,0x40, + /* 0xDFA6 [?] [5834]*/ + 0x21,0x21,0x21,0x2F,0xF1,0x27,0x24,0x27,0x34,0xE7,0x21,0x2F,0x21,0x21,0xA1,0x41, + 0x08,0x08,0x14,0xD4,0x22,0xC0,0x5C,0xC8,0x48,0xC8,0x3E,0xC8,0x08,0x08,0x08,0x08, + /* 0xDFA7 [?] [5835]*/ + 0x10,0x13,0x12,0x12,0xFB,0x10,0x17,0x18,0x33,0xD2,0x13,0x10,0x11,0x13,0x5D,0x21, + 0x00,0xFC,0x94,0x94,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0xA2,0x14,0x08,0x44,0x82, + /* 0xDFA8 [?] [5836]*/ + 0x20,0x20,0x27,0x24,0xF4,0x24,0x27,0x24,0x34,0xE7,0x26,0x2A,0x2A,0x2B,0xB2,0x40, + 0x10,0x08,0x88,0xBE,0x80,0x94,0x88,0x7E,0x08,0x88,0xBE,0x88,0x88,0x88,0x88,0x08, + /* 0xDFA9 [?] [5837]*/ + 0x20,0x23,0x22,0x23,0xFA,0x23,0x20,0x2F,0x34,0xE7,0x24,0x27,0x20,0x2F,0xA1,0x42, + 0x80,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x10,0x10, + /* 0xDFAA [?] [5838]*/ + 0x20,0x27,0x20,0x24,0xFA,0x24,0x21,0x2A,0x37,0xEA,0x23,0x22,0x23,0x22,0xA3,0x42, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x20,0x10,0xFC,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xDFAB [?] [5839]*/ + 0x27,0x20,0x27,0x24,0xFB,0x20,0x27,0x29,0x33,0xE6,0x2B,0x22,0x23,0x22,0xA3,0x42, + 0xFC,0x40,0xFE,0x42,0x5C,0x40,0x5C,0x20,0xFC,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xDFAC [?] [5840]*/ + 0x22,0x23,0x25,0x20,0xFB,0x22,0x22,0x2B,0x30,0xE7,0x22,0x25,0x28,0x23,0xA1,0x42, + 0x10,0xDE,0x28,0x84,0xFC,0xA4,0x54,0xFC,0x80,0xFE,0xA8,0xE4,0x52,0xF8,0x50,0xC8, + /* 0xDFAD [?] [5841]*/ + 0x20,0x27,0x22,0x23,0xF0,0x2F,0x2A,0x23,0x31,0xE7,0x21,0x2F,0x21,0x23,0xAD,0x41, + 0x40,0xFC,0x48,0xF8,0x40,0xFE,0xAA,0xB8,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xDFAE [?] [5842]*/ + 0x02,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x20,0x10,0x10,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x22,0x1A,0x06, + /* 0xDFAF [?] [5843]*/ + 0x00,0x00,0x00,0x00,0xFF,0x00,0x08,0x04,0x14,0x55,0x50,0x50,0x92,0x12,0x0E,0x00, + 0x48,0x44,0x44,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0xA0,0xA2,0x92,0x0A,0x06,0x02, + /* 0xDFB0 [?] [5844]*/ + 0x00,0x00,0x00,0xFF,0x00,0x22,0x22,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x00, + 0x50,0x48,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x12,0x12,0x0A,0x06,0x02, + /* 0xDFB1 [?] [5845]*/ + 0x00,0x44,0x28,0x13,0x28,0x44,0x10,0x11,0xFC,0x10,0x58,0x54,0x94,0x13,0x51,0x20, + 0x14,0x12,0x10,0xFE,0x10,0x10,0x10,0xF0,0x90,0x90,0x90,0x88,0xEA,0x8A,0x06,0x02, + /* 0xDFB2 [?] [5846]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xDFB3 [?] [5847]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7D,0x44,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0x42,0x44,0x48,0x50,0x60,0x40,0xC0,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xDFB4 [?] [5848]*/ + 0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x7A,0x4A,0x02,0x04,0x04,0x08, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xDFB5 [?] [5849]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,0x00,0x00, + 0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80,0x80,0x80, + /* 0xDFB6 [?] [5850]*/ + 0x00,0x00,0x7D,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x01,0x02,0x04, + 0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xDFB7 [?] [5851]*/ + 0x00,0x00,0x78,0x48,0x4B,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x01,0x01,0x02,0x04, + 0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xDFB8 [?] [5852]*/ + 0x00,0x00,0x7B,0x48,0x48,0x48,0x48,0x48,0x4B,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x08,0x3C,0xC0,0x40,0x40,0x40,0x40,0x7E,0xC0,0x40,0x40,0x42,0x42,0x42,0x3E,0x00, + /* 0xDFB9 [?] [5853]*/ + 0x00,0x02,0x79,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x00,0x02,0x04,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xDFBA [?] [5854]*/ + 0x00,0x00,0x78,0x48,0x48,0x48,0x49,0x4B,0x49,0x48,0x78,0x48,0x00,0x01,0x03,0x01, + 0x20,0x20,0x40,0x40,0x84,0x84,0x08,0xF8,0x10,0x10,0x20,0x40,0x88,0x04,0xFE,0x02, + /* 0xDFBB [?] [5855]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x4F,0x48,0x48,0x78,0x49,0x01,0x02,0x04,0x08, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xDFBC [?] [5856]*/ + 0x00,0x03,0x78,0x48,0x48,0x48,0x4F,0x48,0x48,0x48,0x78,0x49,0x01,0x02,0x04,0x08, + 0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xDFBD [?] [5857]*/ + 0x00,0x00,0x7B,0x48,0x48,0x48,0x4B,0x48,0x48,0x48,0x78,0x49,0x02,0x02,0x01,0x00, + 0x90,0x90,0xFE,0x90,0x90,0x00,0xF8,0x10,0x20,0x40,0x80,0x00,0x02,0x02,0xFE,0x00, + /* 0xDFBE [?] [5858]*/ + 0x00,0x00,0x78,0x48,0x4F,0x48,0x48,0x48,0x48,0x48,0x79,0x49,0x02,0x02,0x04,0x08, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0xA0,0xA0,0xA0,0x10,0x10,0x88,0x48,0x44,0x02, + /* 0xDFBF [?] [5859]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x04,0x04,0x09,0x12, + 0x00,0xFE,0x00,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xDFC0 [?] [5860]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x04,0x04,0x08,0x10, + 0x00,0xFE,0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xA8,0x90,0x82,0x82,0x82,0x7E,0x00, + /* 0xDFC1 [?] [5861]*/ + 0x00,0x02,0x7A,0x4A,0x4A,0x4A,0x4B,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x03,0x02,0x00, + 0x20,0x20,0x20,0x22,0x22,0x24,0xA8,0x30,0x20,0x20,0x20,0x22,0xA2,0x22,0x1E,0x00, + /* 0xDFC2 [?] [5862]*/ + 0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x48,0x00,0x00,0x01,0x06, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x02,0x02, + /* 0xDFC3 [?] [5863]*/ + 0x00,0x1F,0x10,0x10,0x10,0x1F,0x01,0x01,0x7F,0x41,0x42,0x44,0x48,0x40,0x40,0x40, + 0x00,0xF0,0x10,0x10,0x10,0xF0,0x00,0x00,0xFC,0x04,0x84,0x44,0x24,0x04,0x14,0x08, + /* 0xDFC4 [?] [5864]*/ + 0x00,0x00,0xF0,0x90,0x90,0x90,0x90,0x92,0x92,0x92,0xF2,0x94,0x00,0x00,0x00,0x00, + 0x00,0x40,0x20,0x10,0x90,0x80,0x80,0x84,0x82,0x82,0x82,0x88,0x88,0x88,0x78,0x00, + /* 0xDFC5 [?] [5865]*/ + 0x00,0x03,0x78,0x48,0x48,0x49,0x49,0x49,0x4A,0x4B,0x78,0x48,0x00,0x00,0x01,0x00, + 0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0xE4,0x24,0x24,0x24,0x24,0x44,0x84, + /* 0xDFC6 [?] [5866]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x03,0x00, + 0x00,0xFE,0x10,0x10,0x10,0xFE,0x92,0x92,0x92,0x92,0x9A,0x94,0x10,0x10,0xFE,0x00, + /* 0xDFC7 [?] [5867]*/ + 0x00,0x00,0x78,0x48,0x48,0x48,0x48,0x4F,0x48,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x40,0x40,0x50,0x48,0x44,0x40,0x40,0x40, + /* 0xDFC8 [?] [5868]*/ + 0x00,0x07,0xF4,0x94,0x94,0x97,0x94,0x94,0x94,0x97,0xF4,0x90,0x00,0x00,0x00,0x00, + 0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x44,0x40,0x40,0x40,0x40,0x40, + /* 0xDFC9 [?] [5869]*/ + 0x00,0x00,0x7B,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x02,0x04,0x04,0x08, + 0x08,0x3C,0xD0,0x90,0x90,0x90,0x90,0x90,0x90,0x88,0x88,0xC8,0xA4,0xD4,0x92,0x00, + /* 0xDFCA [?] [5870]*/ + 0x00,0x00,0x78,0x48,0x49,0x4A,0x4C,0x48,0x4B,0x48,0x78,0x49,0x00,0x00,0x00,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xDFCB [?] [5871]*/ + 0x00,0x00,0x78,0x49,0x4B,0x4C,0x48,0x48,0x4B,0x4C,0x78,0x48,0x00,0x01,0x00,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xC0,0x20,0x10,0x80,0x60,0x10, + /* 0xDFCC [?] [5872]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4C,0x48,0x48,0x4B,0x48,0x78,0x48,0x00,0x00,0x00,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xDFCD [?] [5873]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x48,0x48,0x48,0x7A,0x4A,0x02,0x02,0x03,0x00, + 0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x22,0x22,0x22,0x22,0xFE,0x02, + /* 0xDFCE [?] [5874]*/ + 0x02,0x02,0xE2,0xA2,0xAF,0xA4,0xA4,0xA4,0xA4,0xA9,0xE5,0xA2,0x05,0x09,0x10,0x01, + 0x00,0x00,0x7C,0x24,0xA4,0xA4,0xA4,0xA8,0xA8,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xDFCF [?] [5875]*/ + 0x00,0x01,0x71,0x52,0x52,0x54,0x57,0x51,0x52,0x52,0x74,0x47,0x00,0x00,0x00,0x01, + 0x20,0x20,0x20,0x20,0xFC,0xA4,0x24,0x24,0x24,0x24,0xA4,0xA4,0xC4,0x44,0x94,0x08, + /* 0xDFD0 [?] [5876]*/ + 0x01,0x01,0x71,0x52,0x52,0x54,0x57,0x51,0x51,0x52,0x74,0x57,0x00,0x00,0x0F,0x00, + 0x08,0x08,0x08,0x10,0x94,0xA4,0xBC,0x08,0x08,0x10,0x20,0xBC,0x00,0x00,0xFE,0x00, + /* 0xDFD1 [?] [5877]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4B,0x02,0x02,0x03,0x00, + 0x00,0xFE,0x00,0x00,0xFC,0x20,0x20,0xF8,0x20,0x20,0x20,0xFC,0x00,0x00,0xFE,0x00, + /* 0xDFD2 [?] [5878]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x49,0x48,0x48,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDFD3 [?] [5879]*/ + 0x00,0x07,0x78,0x48,0x48,0x4B,0x4A,0x4A,0x4A,0x4A,0x7A,0x4B,0x02,0x02,0x03,0x02, + 0x00,0xFE,0x90,0x90,0x90,0xFC,0x94,0x94,0x94,0x94,0x9C,0x04,0x04,0x04,0xFC,0x04, + /* 0xDFD4 [?] [5880]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x49,0x49,0x49,0x7A,0x4A,0x04,0x00,0x00,0x01, + 0x40,0x40,0x40,0xFE,0x80,0x90,0x90,0x12,0x52,0x54,0x90,0x28,0x28,0x44,0x84,0x02, + /* 0xDFD5 [?] [5881]*/ + 0x00,0x02,0x79,0x49,0x48,0x48,0x4B,0x49,0x49,0x49,0x79,0x49,0x01,0x02,0x04,0x00, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x28,0x24,0x44,0x42,0x82,0x00,0x80,0x7E,0x00, + /* 0xDFD6 [?] [5882]*/ + 0x00,0x00,0xEF,0xA2,0xA2,0xA3,0xA2,0xA4,0xA6,0xA5,0xE8,0xA0,0x01,0x02,0x04,0x08, + 0x04,0x04,0xC4,0x14,0x14,0xD4,0x54,0x54,0x54,0x54,0x94,0x94,0x04,0x04,0x14,0x08, + /* 0xDFD7 [?] [5883]*/ + 0x00,0x00,0xF7,0x90,0x97,0x90,0x93,0x92,0x94,0x97,0xF0,0x90,0x00,0x01,0x02,0x0C, + 0x40,0x40,0xFE,0x40,0xFC,0x44,0xFC,0x40,0x40,0xFE,0x42,0xAA,0xA4,0x10,0x08,0x06, + /* 0xDFD8 [?] [5884]*/ + 0x00,0x00,0x78,0x4B,0x48,0x48,0x48,0x4B,0x48,0x4B,0x78,0x48,0x01,0x01,0x02,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xDFD9 [?] [5885]*/ + 0x01,0x01,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x48,0x7B,0x48,0x00,0x00,0x00,0x00, + 0x10,0x12,0x14,0xD8,0x10,0x12,0x52,0x8E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xDFDA [?] [5886]*/ + 0x00,0x00,0x78,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x4A,0x03,0x0E,0x04,0x00, + 0x90,0x90,0x90,0x90,0x92,0xD4,0x98,0x90,0x90,0x90,0x90,0x92,0xD2,0x12,0x0E,0x00, + /* 0xDFDB [?] [5887]*/ + 0x00,0x00,0x7A,0x49,0x49,0x48,0x4F,0x48,0x48,0x48,0x78,0x48,0x01,0x01,0x02,0x04, + 0x40,0x44,0x44,0x48,0x50,0x40,0xFE,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xDFDC [?] [5888]*/ + 0x00,0x01,0x79,0x49,0x49,0x48,0x48,0x48,0x49,0x4A,0x78,0x48,0x00,0x00,0x00,0x03, + 0x20,0x24,0x24,0x24,0xFC,0x40,0x40,0xFC,0x04,0x84,0x48,0x50,0x20,0x40,0x80,0x00, + /* 0xDFDD [?] [5889]*/ + 0x00,0x00,0x78,0x49,0x49,0x4B,0x4D,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x90,0x90,0x90,0x10,0xFE,0x10,0x10,0x38,0x38,0x54,0x54,0x92,0x10,0x10,0x10,0x10, + /* 0xDFDE [?] [5890]*/ + 0x01,0x01,0xF1,0x92,0x92,0x96,0x9A,0x92,0x92,0x92,0xF2,0x92,0x02,0x02,0x02,0x02, + 0x00,0x7C,0x24,0x24,0x24,0xFE,0x24,0x24,0x24,0x7C,0x24,0x20,0x20,0x20,0x40,0x80, + /* 0xDFDF [?] [5891]*/ + 0x00,0x00,0xF7,0x94,0x94,0x95,0x95,0x95,0x95,0x95,0xF5,0x95,0x05,0x09,0x09,0x11, + 0x08,0x3C,0xC0,0x00,0x1C,0xE0,0x20,0x22,0x24,0x28,0x10,0x10,0x08,0x44,0x82,0x00, + /* 0xDFE0 [?] [5892]*/ + 0x00,0x00,0x78,0x49,0x4A,0x4C,0x49,0x48,0x48,0x4F,0x78,0x48,0x01,0x02,0x07,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xDFE1 [?] [5893]*/ + 0x00,0x01,0x79,0x49,0x49,0x49,0x4A,0x4C,0x4B,0x48,0x78,0x49,0x02,0x04,0x00,0x00, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x4E,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xDFE2 [?] [5894]*/ + 0x00,0x00,0x7B,0x49,0x48,0x48,0x48,0x48,0x4B,0x48,0x78,0x48,0x00,0x01,0x01,0x02, + 0x40,0x20,0xFE,0x04,0x88,0x50,0x20,0xD8,0x06,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xDFE3 [?] [5895]*/ + 0x01,0x00,0x78,0x48,0x4B,0x48,0x48,0x49,0x48,0x48,0x7B,0x48,0x00,0x00,0x00,0x00, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xDFE4 [?] [5896]*/ + 0x00,0x00,0x7A,0x49,0x49,0x48,0x4F,0x48,0x48,0x49,0x79,0x4A,0x04,0x08,0x00,0x00, + 0x40,0x40,0x48,0x48,0x50,0x40,0xFE,0x40,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40, + /* 0xDFE5 [?] [5897]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4C,0x48,0x4B,0x48,0x48,0x78,0x4F,0x00,0x00,0x00,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x38,0xC0,0x40,0x40,0x7E,0xC0,0x40,0x42,0x42,0x3E, + /* 0xDFE6 [?] [5898]*/ + 0x00,0x00,0xF0,0x97,0x94,0x98,0x91,0x91,0x93,0x95,0xF9,0x91,0x01,0x01,0x01,0x01, + 0x40,0x40,0x40,0xFC,0x84,0x88,0x40,0x44,0x48,0x30,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xDFE7 [?] [5899]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x4A,0x4A,0x4B,0x4A,0x4A,0x7A,0x4A,0x02,0x02,0x03,0x02, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x88,0x06,0x00, + /* 0xDFE8 [?] [5900]*/ + 0x00,0x00,0x78,0x49,0x4B,0x48,0x49,0x49,0x49,0x4A,0x78,0x4F,0x00,0x00,0x00,0x00, + 0x40,0x40,0x90,0x08,0xFC,0x24,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xDFE9 [?] [5901]*/ + 0x00,0x00,0xF7,0x90,0x93,0x90,0x97,0x90,0x90,0x91,0xF3,0x94,0x00,0x00,0x03,0x0C, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xDFEA [?] [5902]*/ + 0x00,0x00,0x79,0x48,0x48,0x48,0x4B,0x48,0x48,0x49,0x79,0x4A,0x00,0x00,0x01,0x02, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x48,0x48,0x4C,0x4A,0x4A,0x88,0x88,0x28,0x10, + /* 0xDFEB [?] [5903]*/ + 0x00,0x00,0x7B,0x48,0x48,0x4B,0x4A,0x4C,0x48,0x4B,0x78,0x48,0x00,0x01,0x02,0x04, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x44,0x40,0xFC,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xDFEC [?] [5904]*/ + 0x00,0x07,0xF0,0x97,0x94,0x94,0x97,0x94,0x94,0x97,0xF2,0x91,0x00,0x01,0x02,0x0C, + 0x00,0xFE,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0x80,0x40,0x30,0x0E, + /* 0xDFED [?] [5905]*/ + 0x00,0x07,0xF0,0x90,0x93,0x90,0x90,0x97,0x90,0x90,0xF3,0x92,0x02,0x02,0x03,0x02, + 0x00,0xFC,0x40,0x40,0xF8,0x88,0x88,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xDFEE [?] [5906]*/ + 0x02,0x02,0x72,0x52,0x5F,0x52,0x52,0x52,0x53,0x5E,0x72,0x52,0x02,0x02,0x0A,0x05, + 0x08,0x1C,0x60,0x40,0xC0,0x40,0x7E,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x08, + /* 0xDFEF [?] [5907]*/ + 0x00,0x01,0x78,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x00,0x00,0x01,0x02, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x88,0x04,0x02, + /* 0xDFF0 [?] [5908]*/ + 0x00,0x00,0x79,0x49,0x49,0x49,0x49,0x49,0x49,0x48,0x78,0x48,0x07,0x00,0x00,0x00, + 0x20,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x40,0x40,0x7E,0xC0,0x42,0x42,0x3E, + /* 0xDFF1 [?] [5909]*/ + 0x01,0x00,0x78,0x48,0x4B,0x48,0x4B,0x48,0x49,0x4B,0x7D,0x49,0x01,0x01,0x00,0x00, + 0x84,0x68,0x30,0xC8,0x04,0x40,0xFE,0xA0,0x20,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xDFF2 [?] [5910]*/ + 0x00,0x00,0xF2,0x92,0x92,0x95,0x98,0x90,0x90,0x97,0xF0,0x90,0x00,0x00,0x0F,0x00, + 0x40,0x40,0x48,0x48,0x48,0x54,0xE2,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xDFF3 [?] [5911]*/ + 0x00,0x07,0x74,0x54,0x54,0x57,0x54,0x54,0x54,0x57,0x74,0x55,0x04,0x05,0x06,0x00, + 0x00,0xBC,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x34,0x28,0xA0,0x60,0x20,0x20, + /* 0xDFF4 [?] [5912]*/ + 0x00,0x00,0xF7,0x90,0x93,0x90,0x97,0x91,0x92,0x94,0xF1,0x90,0x07,0x00,0x00,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x48,0x46,0xF0,0x40,0xFC,0x40,0x40,0x40, + /* 0xDFF5 [?] [5913]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4B,0x48,0x49,0x49,0x79,0x49,0x01,0x00,0x00,0x03, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xDFF6 [?] [5914]*/ + 0x01,0x01,0xF7,0x91,0x91,0x90,0x97,0x90,0x91,0x93,0xF5,0x99,0x01,0x01,0x01,0x01, + 0x08,0x08,0xFE,0x08,0x48,0x40,0xFE,0x80,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xDFF7 [?] [5915]*/ + 0x00,0x00,0x7B,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x04, + /* 0xDFF8 [?] [5916]*/ + 0x01,0x01,0x71,0x51,0x57,0x51,0x51,0x53,0x53,0x55,0x75,0x59,0x01,0x01,0x01,0x01, + 0x10,0x10,0x10,0x10,0xBC,0x10,0x10,0x38,0xB8,0x54,0x54,0x92,0x10,0x10,0x10,0x10, + /* 0xDFF9 [?] [5917]*/ + 0x02,0x02,0x72,0x5F,0x52,0x55,0x55,0x57,0x51,0x51,0x71,0x5F,0x05,0x01,0x01,0x01, + 0x10,0x10,0x10,0xBC,0x10,0x10,0x7E,0x90,0x20,0x3C,0xC4,0x08,0x28,0x10,0x08,0x04, + /* 0xDFFA [?] [5918]*/ + 0x00,0x07,0xF4,0x94,0x95,0x94,0x94,0x97,0x94,0x95,0xF5,0x95,0x05,0x04,0x04,0x08, + 0x00,0xFC,0x44,0x44,0xF4,0x44,0x44,0xFC,0x04,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xDFFB [?] [5919]*/ + 0x01,0x01,0x79,0x4A,0x4D,0x49,0x4A,0x48,0x4F,0x48,0x7A,0x4A,0x03,0x00,0x00,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x84,0x84,0xF4,0x84,0xA4,0xA4,0xE4,0x04,0x28,0x10, + /* 0xDFFC [?] [5920]*/ + 0x01,0x01,0xF3,0x94,0x98,0x91,0x92,0x94,0x91,0x92,0xF0,0x91,0x05,0x05,0x08,0x00, + 0x00,0x00,0xFC,0x94,0x94,0x24,0x44,0x84,0x28,0x10,0x40,0x24,0x2A,0x0A,0xF8,0x00, + /* 0xDFFD [?] [5921]*/ + 0x00,0x00,0xF7,0x90,0x91,0x91,0x92,0x94,0x90,0x90,0xF7,0x90,0x00,0x00,0x00,0x00, + 0x80,0x40,0xFC,0x00,0x10,0x10,0xA8,0x44,0x00,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xDFFE [?] [5922]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4F,0x48,0x48,0x4F,0x78,0x49,0x00,0x00,0x01,0x06, + 0x80,0x40,0xFC,0x00,0x08,0x90,0xFE,0x40,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xE0A1 [?] [5923]*/ + 0x00,0x00,0x7B,0x48,0x49,0x4B,0x48,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x40,0x20,0xFE,0x80,0x04,0xFE,0x02,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xE0A2 [?] [5924]*/ + 0x00,0x02,0xF2,0x94,0x90,0x91,0x96,0x90,0x90,0x92,0xF2,0x94,0x00,0x01,0x02,0x0C, + 0x40,0x44,0x44,0x48,0xA0,0x10,0x08,0x44,0x40,0x48,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xE0A3 [?] [5925]*/ + 0x00,0x04,0x72,0x52,0x58,0x54,0x54,0x52,0x52,0x54,0x7C,0x54,0x04,0x05,0x05,0x02, + 0x10,0x10,0x10,0xFE,0x92,0x94,0x90,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0x28,0x44,0x82, + /* 0xE0A4 [?] [5926]*/ + 0x00,0x00,0x7B,0x4A,0x4C,0x48,0x4B,0x48,0x48,0x49,0x79,0x49,0x02,0x02,0x04,0x08, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xE0A5 [?] [5927]*/ + 0x01,0x00,0x7B,0x4A,0x4A,0x4B,0x4A,0x4A,0x4B,0x4A,0x7A,0x4A,0x02,0x03,0x02,0x00, + 0x00,0x9E,0xD2,0x52,0x54,0xD4,0x58,0x54,0xD2,0x12,0x92,0x5A,0xD4,0x50,0x10,0x10, + /* 0xE0A6 [?] [5928]*/ + 0x00,0x00,0x7B,0x4A,0x4A,0x4B,0x4A,0x4A,0x4A,0x4B,0x7A,0x4A,0x02,0x04,0x05,0x0A, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x00,0x28,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xE0A7 [?] [5929]*/ + 0x00,0x07,0x74,0x54,0x57,0x54,0x54,0x54,0x57,0x56,0x76,0x5A,0x0A,0x12,0x00,0x00, + 0x02,0xE2,0x22,0x2A,0xEA,0x8A,0x8A,0x8A,0xEA,0xAA,0xAA,0xAA,0xA2,0xE2,0x8A,0x84, + /* 0xE0A8 [?] [5930]*/ + 0x00,0x07,0x70,0x52,0x51,0x52,0x54,0x58,0x50,0x57,0x70,0x52,0x01,0x02,0x04,0x08, + 0x00,0xBC,0x84,0x94,0x08,0x94,0xA4,0x40,0x00,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xE0A9 [?] [5931]*/ + 0x00,0x01,0x79,0x4B,0x49,0x49,0x49,0x49,0x49,0x48,0x7B,0x48,0x00,0x01,0x06,0x00, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xE0AA [?] [5932]*/ + 0x01,0x01,0xF7,0x91,0x90,0x90,0x91,0x92,0x95,0x90,0xF0,0x93,0x02,0x02,0x03,0x02, + 0x10,0x10,0xFC,0x10,0x40,0xA0,0x10,0x08,0xF6,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE0AB [?] [5933]*/ + 0x00,0x00,0xF7,0x90,0x90,0x97,0x95,0x94,0x95,0x94,0xF4,0x95,0x04,0x04,0x04,0x04, + 0x40,0x40,0xFC,0x40,0x40,0xFC,0x14,0xA4,0xF4,0x44,0x44,0xF4,0x44,0x44,0x54,0x08, + /* 0xE0AC [?] [5934]*/ + 0x00,0x07,0xF4,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0xF4,0x94,0x05,0x08,0x08,0x13, + 0x00,0xFE,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE, + /* 0xE0AD [?] [5935]*/ + 0x00,0x00,0xF7,0x90,0x91,0x92,0x9D,0x90,0x90,0x97,0xF0,0x90,0x03,0x00,0x00,0x0F, + 0x40,0x40,0xFC,0xA0,0x10,0x48,0xF6,0x40,0x40,0xFC,0x00,0x40,0xF8,0x40,0x40,0xFE, + /* 0xE0AE [?] [5936]*/ + 0x02,0x02,0x7B,0x4A,0x4A,0x4B,0x4A,0x48,0x4B,0x4A,0x7A,0x4B,0x02,0x02,0x03,0x02, + 0x20,0x24,0xA8,0x30,0xA2,0x22,0x5E,0x80,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xE0AF [?] [5937]*/ + 0x01,0x01,0x79,0x49,0x49,0x49,0x49,0x48,0x48,0x4B,0x7A,0x4A,0x02,0x02,0x02,0x02, + 0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x22,0x2A,0xFA,0x0A,0x02,0x06, + /* 0xE0B0 [?] [5938]*/ + 0x00,0x03,0x7A,0x4B,0x4A,0x4B,0x48,0x49,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x00,0xFE,0x22,0xFE,0x22,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xE0B1 [?] [5939]*/ + 0x00,0x01,0x77,0x51,0x51,0x51,0x57,0x51,0x53,0x53,0x75,0x55,0x09,0x01,0x01,0x01, + 0x88,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xE0B2 [?] [5940]*/ + 0x01,0x06,0xF4,0x94,0x97,0x94,0x94,0x97,0x90,0x97,0xF2,0x91,0x00,0x00,0x01,0x0E, + 0x40,0x5C,0x44,0x44,0x5C,0x44,0x44,0xFC,0x40,0xFC,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xE0B3 [?] [5941]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4F,0x48,0x49,0x49,0x79,0x49,0x01,0x01,0x01,0x01, + 0x80,0x40,0xFC,0x00,0x08,0x90,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE0B4 [?] [5942]*/ + 0x01,0x3F,0x08,0x04,0x7F,0x41,0x9F,0x11,0x11,0x11,0x01,0x3F,0x20,0x20,0x3F,0x20, + 0x00,0xF8,0x20,0x40,0xFE,0x02,0xF4,0x10,0x50,0x20,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE0B5 [?] [5943]*/ + 0x01,0x00,0x78,0x4B,0x48,0x49,0x48,0x4B,0x48,0x49,0x79,0x4A,0x04,0x08,0x03,0x00, + 0x08,0x88,0x90,0xFC,0x40,0xF8,0x40,0xFE,0x80,0x00,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE0B6 [?] [5944]*/ + 0x00,0x01,0x78,0x48,0x4B,0x48,0x49,0x4A,0x48,0x4F,0x78,0x49,0x01,0x00,0x01,0x06, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xE0B7 [?] [5945]*/ + 0x22,0x11,0x00,0x7F,0x41,0x91,0x1F,0x21,0x01,0xFF,0x00,0x1F,0x10,0x10,0x1F,0x10, + 0x08,0x10,0x20,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xE0B8 [?] [5946]*/ + 0x00,0x03,0x7A,0x4A,0x4B,0x4A,0x4B,0x4A,0x4A,0x4B,0x7A,0x4A,0x05,0x04,0x08,0x13, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x40,0x88,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE, + /* 0xE0B9 [?] [5947]*/ + 0x01,0x01,0xF2,0x93,0x90,0x97,0x90,0x91,0x96,0x90,0xF1,0x96,0x00,0x01,0x06,0x00, + 0x00,0xF8,0x08,0xF0,0x10,0xFE,0x80,0x44,0x68,0xB0,0x28,0x68,0xA4,0x22,0xA0,0x40, + /* 0xE0BA [?] [5948]*/ + 0x00,0x00,0xF7,0x90,0x93,0x90,0x97,0x91,0x92,0x95,0xF0,0x93,0x00,0x01,0x06,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x68,0xC6,0x40,0xF8,0xE0,0x58,0x44,0x40, + /* 0xE0BB [?] [5949]*/ + 0x01,0x01,0x71,0x57,0x51,0x57,0x51,0x5F,0x52,0x53,0x72,0x52,0x02,0x04,0x04,0x08, + 0x08,0x08,0x08,0xD0,0x1E,0x94,0x24,0xD4,0x14,0xD4,0x54,0x48,0x48,0xD4,0x24,0x42, + /* 0xE0BC [?] [5950]*/ + 0x00,0x00,0x7B,0x48,0x49,0x48,0x4B,0x48,0x48,0x49,0x78,0x4B,0x00,0x01,0x02,0x00, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x40,0x88,0xF0,0x24,0xFE,0x22,0x24,0xA2,0x40, + /* 0xE0BD [?] [5951]*/ + 0x02,0x02,0xEF,0xA2,0xA2,0xAF,0xA1,0xA2,0xA7,0xAC,0xF4,0xA7,0x04,0x04,0x07,0x04, + 0x00,0x3E,0x62,0x64,0xA4,0xE8,0x24,0x24,0xA2,0xA2,0xA2,0xB4,0xA8,0xA0,0xA0,0xA0, + /* 0xE0BE [?] [5952]*/ + 0x00,0x00,0x79,0x48,0x48,0x4B,0x48,0x49,0x4B,0x48,0x7B,0x4A,0x02,0x02,0x07,0x00, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x80,0x04,0xFE,0x02,0xFC,0x94,0x94,0x94,0xFE,0x00, + /* 0xE0BF [?] [5953]*/ + 0x00,0x03,0x79,0x49,0x49,0x49,0x49,0x4F,0x48,0x4F,0x78,0x4A,0x01,0x02,0x04,0x08, + 0x00,0xFC,0x08,0xF8,0x08,0xF8,0x0E,0xF8,0x08,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xE0C0 [?] [5954]*/ + 0x01,0x01,0xF7,0x91,0x91,0x92,0x92,0x96,0x9A,0x92,0xF2,0x92,0x02,0x02,0x02,0x02, + 0x10,0x10,0xFE,0x10,0x00,0xFE,0x08,0x08,0xE8,0xA8,0xA8,0xE8,0xA8,0x08,0x28,0x10, + /* 0xE0C1 [?] [5955]*/ + 0x00,0x00,0xF7,0x90,0x93,0x92,0x93,0x92,0x93,0x92,0xF3,0x92,0x0F,0x01,0x02,0x04, + 0x40,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFE,0x10,0x08,0x04, + /* 0xE0C2 [?] [5956]*/ + 0x00,0x00,0xF7,0x90,0x97,0x94,0x99,0x93,0x90,0x90,0xF7,0x90,0x02,0x04,0x09,0x00, + 0x40,0x40,0xFC,0x40,0xFC,0x84,0x18,0xE0,0x40,0x88,0xFC,0x44,0x50,0x48,0x48,0x80, + /* 0xE0C3 [?] [5957]*/ + 0x00,0x0F,0xF0,0x93,0x92,0x92,0x93,0x90,0x97,0x95,0xF4,0x97,0x04,0x04,0x04,0x04, + 0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x14,0xA4,0xFC,0x44,0x44,0x54,0x08, + /* 0xE0C4 [?] [5958]*/ + 0x07,0x00,0xF3,0x92,0x93,0x92,0x93,0x92,0x93,0x90,0xF1,0x93,0x04,0x00,0x01,0x0E, + 0xFC,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x80,0xF8,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xE0C5 [?] [5959]*/ + 0x00,0x07,0xF4,0x94,0x97,0x94,0x94,0x95,0x94,0x97,0xF0,0x90,0x05,0x05,0x09,0x00, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0xA4,0x14,0x04,0xFC,0x40,0x24,0x22,0x0A,0x08,0xF8, + /* 0xE0C6 [?] [5960]*/ + 0x00,0x00,0xF3,0x92,0x93,0x92,0x93,0x90,0x97,0x91,0xF2,0x94,0x0B,0x00,0x00,0x00, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x80,0xFC,0x10,0x48,0x44,0xFA,0x40,0x40,0x40, + /* 0xE0C7 [?] [5961]*/ + 0x00,0x01,0xF2,0x90,0x91,0x96,0x90,0x93,0x90,0x90,0xF7,0x90,0x03,0x00,0x00,0x07, + 0x90,0x08,0x94,0x60,0x98,0x46,0xFC,0x08,0xB0,0xD0,0x3E,0xC2,0x24,0x18,0x60,0x80, + /* 0xE0C8 [?] [5962]*/ + 0x00,0x03,0x78,0x4A,0x49,0x4B,0x4A,0x48,0x4B,0x48,0x78,0x49,0x01,0x02,0x04,0x01, + 0x0E,0xF0,0x44,0x24,0x08,0xFE,0x42,0x40,0xFE,0x80,0xFC,0x44,0x28,0x10,0x68,0x86, + /* 0xE0C9 [?] [5963]*/ + 0x02,0x01,0xF1,0x90,0x97,0x90,0x91,0x92,0x94,0x93,0xF2,0x92,0x02,0x02,0x0F,0x00, + 0x08,0x08,0x10,0x00,0xFC,0x00,0x10,0x08,0x04,0xF8,0xA8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xE0CA [?] [5964]*/ + 0x04,0x02,0x72,0x50,0x57,0x51,0x55,0x55,0x55,0x57,0x71,0x51,0x02,0x02,0x04,0x08, + 0x40,0x5E,0x92,0x12,0xD2,0x1E,0x52,0x52,0x52,0xDE,0x52,0x12,0x12,0x22,0x2A,0x44, + /* 0xE0CB [?] [5965]*/ + 0x00,0x08,0xE4,0xA1,0xAA,0xA4,0xA4,0xA0,0xA3,0xA4,0xED,0xA5,0x05,0x04,0x04,0x00, + 0x80,0x80,0xFE,0x00,0xFC,0x84,0xA4,0x94,0xFE,0x84,0x24,0x14,0xFE,0x04,0x28,0x10, + /* 0xE0CC [?] [5966]*/ + 0x01,0x08,0xE4,0xA4,0xA1,0xA1,0xBD,0xA5,0xA5,0xA5,0xE5,0xA5,0x05,0x0A,0x11,0x00, + 0xFC,0x08,0x50,0x20,0xFC,0x24,0x24,0xFC,0x24,0xFC,0x24,0x24,0x2C,0x00,0xFE,0x00, + /* 0xE0CD [?] [5967]*/ + 0x00,0x01,0x79,0x49,0x48,0x4B,0x48,0x48,0x49,0x49,0x79,0x49,0x00,0x00,0x03,0x01, + 0x20,0x24,0x24,0xFC,0x20,0xFE,0x00,0x20,0xFC,0x24,0x24,0xFC,0x20,0x24,0xFE,0x02, + /* 0xE0CE [?] [5968]*/ + 0x22,0x22,0x47,0x8A,0xF5,0x27,0x41,0xF9,0x07,0x19,0xE1,0x3F,0x20,0x20,0x3F,0x20, + 0x08,0x08,0xD0,0x22,0x3C,0xC8,0x10,0x3E,0xC0,0x3E,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE0CF [?] [5969]*/ + 0x02,0x02,0x77,0x52,0x53,0x51,0x57,0x55,0x55,0x57,0x71,0x57,0x01,0x01,0x01,0x01, + 0x90,0x90,0xD0,0x90,0xBC,0x14,0xD4,0x54,0x54,0xD4,0x14,0xD4,0x24,0x24,0x54,0x88, + /* 0xE0D0 [?] [5970]*/ + 0x00,0x00,0x77,0x50,0x57,0x54,0x57,0x54,0x57,0x50,0x73,0x52,0x03,0x02,0x03,0x02, + 0xA0,0xA0,0xFE,0xA0,0xFC,0xA4,0xFC,0xA4,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xE0D1 [?] [5971]*/ + 0x00,0x0F,0xE0,0xA7,0xA4,0xA4,0xA7,0xA0,0xA7,0xA0,0xEF,0xA0,0x02,0x04,0x09,0x00, + 0x00,0xFE,0xA0,0xFC,0xA4,0xA4,0xFC,0x00,0xFC,0x00,0xFE,0x40,0x48,0x44,0x42,0x80, + /* 0xE0D2 [?] [5972]*/ + 0x00,0x00,0x70,0x57,0x54,0x54,0x54,0x54,0x57,0x54,0x74,0x55,0x0A,0x08,0x11,0x00, + 0x14,0x12,0x10,0xFE,0x10,0x90,0xD2,0x92,0xF2,0x94,0x94,0xC8,0xAA,0x9A,0xA6,0x42, + /* 0xE0D3 [?] [5973]*/ + 0x00,0x0F,0xE8,0xAA,0xAA,0xAA,0xA5,0xA8,0xA0,0xAF,0xE1,0xA2,0x03,0x00,0x01,0x0E, + 0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0x80,0xFE,0x10,0x10,0xA0,0x60,0x98,0x04, + /* 0xE0D4 [?] [5974]*/ + 0x00,0x04,0x74,0x57,0x50,0x57,0x54,0x54,0x57,0x54,0x74,0x57,0x04,0x04,0x0A,0x11, + 0x40,0x44,0x44,0xFC,0x00,0xBC,0xA4,0xA4,0xBC,0xA4,0xA4,0xBC,0xA4,0xA4,0xB4,0x48, + /* 0xE0D5 [?] [5975]*/ + 0x04,0x02,0x72,0x5F,0x54,0x54,0x57,0x55,0x55,0x55,0x75,0x55,0x05,0x09,0x0B,0x10, + 0x20,0x20,0x3E,0x40,0xA0,0x20,0x3C,0x50,0x10,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xE0D6 [?] [5976]*/ + 0x00,0x00,0xF7,0x91,0x90,0x97,0x94,0x95,0x94,0x95,0xF5,0x95,0x05,0x04,0x04,0x04, + 0x80,0x40,0xFC,0x10,0xA0,0xFC,0x44,0xF4,0x44,0xF4,0x14,0x14,0xF4,0x04,0x14,0x08, + /* 0xE0D7 [?] [5977]*/ + 0x00,0x00,0xF7,0x94,0x98,0x90,0x95,0x95,0x98,0x93,0xF0,0x94,0x04,0x04,0x07,0x00, + 0x80,0x40,0xFE,0x02,0x94,0x50,0x24,0x4A,0xFA,0x00,0x40,0x44,0x44,0x44,0xFC,0x04, + /* 0xE0D8 [?] [5978]*/ + 0x01,0x01,0x77,0x51,0x51,0x57,0x50,0x57,0x54,0x54,0x77,0x54,0x02,0x00,0x0F,0x04, + 0x04,0x04,0xE8,0x10,0x00,0xC4,0x04,0xC8,0x50,0x42,0xC2,0x44,0x84,0xE8,0x10,0x20, + /* 0xE0D9 [?] [5979]*/ + 0x00,0x0F,0xE8,0xAA,0xA9,0xAB,0xA8,0xA8,0xAA,0xAA,0xEB,0xA8,0x08,0x09,0x09,0x12, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xE0DA [?] [5980]*/ + 0x00,0x00,0xF7,0x90,0x95,0x92,0x97,0x9A,0x93,0x92,0xF3,0x90,0x02,0x04,0x09,0x00, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xE0DB [?] [5981]*/ + 0x00,0x04,0xF2,0x90,0x97,0x91,0x90,0x97,0x90,0x93,0xF0,0x97,0x00,0x01,0x02,0x0C, + 0xA0,0xA4,0xA8,0xA0,0xFC,0x10,0xA0,0xFC,0x40,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xE0DC [?] [5982]*/ + 0x00,0x03,0xF2,0x93,0x92,0x93,0x90,0x9F,0x94,0x97,0xF4,0x97,0x04,0x0F,0x00,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x80,0xBC,0x94,0x94,0xD4,0x88,0x94,0xA2, + /* 0xE0DD [?] [5983]*/ + 0x01,0x01,0xF3,0x92,0x96,0x9B,0x92,0x92,0x93,0x92,0xF2,0x93,0x02,0x05,0x04,0x08, + 0x40,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x24,0x92,0x92, + /* 0xE0DE [?] [5984]*/ + 0x00,0x01,0xF7,0x94,0x95,0x94,0x97,0x94,0x95,0x94,0xF0,0x97,0x00,0x01,0x02,0x0C, + 0x80,0x00,0xFC,0x44,0x54,0x44,0xFC,0xE4,0x54,0x04,0x40,0xFE,0xA0,0x10,0x08,0x06, + /* 0xE0DF [?] [5985]*/ + 0x00,0x00,0xF1,0x92,0x9D,0x90,0x92,0x92,0x93,0x90,0xF7,0x94,0x05,0x05,0x04,0x04, + 0x40,0xA0,0x10,0x48,0xF6,0xA0,0x48,0xA8,0xF8,0x40,0xFC,0x84,0x24,0xF4,0x14,0x0C, + /* 0xE0E0 [?] [5986]*/ + 0x01,0x03,0xF4,0x9F,0x94,0x97,0x94,0x97,0x90,0x9F,0xF0,0x93,0x02,0x03,0x02,0x03, + 0x00,0xF0,0x10,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xE0E1 [?] [5987]*/ + 0x02,0x01,0xF0,0x97,0x94,0x95,0x94,0x94,0x97,0x90,0xF3,0x92,0x03,0x02,0x03,0x02, + 0x08,0x10,0x00,0xFC,0x44,0x54,0xE4,0x44,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xE0E2 [?] [5988]*/ + 0x00,0x07,0xF0,0x92,0x91,0x92,0x95,0x98,0x93,0x92,0xF2,0x93,0x02,0x01,0x0F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xE0E3 [?] [5989]*/ + 0x01,0x07,0xF1,0x90,0x97,0x90,0x91,0x91,0x91,0x90,0xF7,0x94,0x05,0x05,0x05,0x04, + 0x08,0xFE,0x08,0x20,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xFE,0x02,0xFA,0x0A,0xFA,0x06, + /* 0xE0E4 [?] [5990]*/ + 0x01,0x01,0xF7,0x91,0x93,0x95,0x99,0x90,0x93,0x90,0xF7,0x90,0x02,0x04,0x09,0x00, + 0x10,0x10,0xBC,0x10,0xB8,0x54,0x12,0x00,0xF8,0x00,0xFC,0x40,0x48,0x44,0x42,0x80, + /* 0xE0E5 [?] [5991]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x4A,0x4B,0x4A,0x4A,0x4B,0x7A,0x4B,0x02,0x05,0x04,0x09, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x00,0xFE,0x40,0xA4,0x58,0xB4,0x52,0xB0, + /* 0xE0E6 [?] [5992]*/ + 0x00,0x00,0x7B,0x49,0x48,0x4F,0x48,0x4B,0x4A,0x4B,0x7A,0x4B,0x00,0x05,0x05,0x08, + 0x80,0x40,0xFC,0x08,0x90,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x24,0x0A,0xFA, + /* 0xE0E7 [?] [5993]*/ + 0x00,0x00,0xF7,0x95,0x9B,0x91,0x97,0x91,0x97,0x91,0xF2,0x95,0x08,0x00,0x07,0x00, + 0x80,0x40,0xFE,0x12,0xFC,0x10,0xFC,0x10,0xFE,0x10,0x48,0xF4,0x42,0x40,0xFC,0x00, + /* 0xE0E8 [?] [5994]*/ + 0x00,0x00,0x77,0x54,0x54,0x54,0x57,0x54,0x54,0x57,0x76,0x5A,0x0A,0x0B,0x12,0x00, + 0x10,0x08,0x88,0xBE,0x80,0x94,0x88,0x7E,0x08,0x88,0xBE,0x88,0x88,0x88,0x88,0x08, + /* 0xE0E9 [?] [5995]*/ + 0x00,0x07,0xE0,0xAF,0xA8,0xA3,0xA0,0xA3,0xA0,0xAF,0xE0,0xA7,0x04,0x04,0x04,0x04, + 0x00,0xFC,0x40,0xFE,0x42,0x58,0x40,0x58,0x00,0xFE,0x40,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xE0EA [?] [5996]*/ + 0x00,0x00,0x77,0x54,0x5A,0x53,0x54,0x5A,0x55,0x52,0x74,0x5B,0x00,0x02,0x04,0x00, + 0x80,0x40,0xFE,0x02,0x24,0xBC,0xA4,0xA8,0x10,0xE8,0x04,0xFA,0x40,0x48,0x44,0xC0, + /* 0xE0EB [?] [5997]*/ + 0x07,0x00,0xF7,0x94,0x9B,0x90,0x97,0x91,0x93,0x96,0xFB,0x92,0x03,0x02,0x03,0x02, + 0xFC,0x40,0xFE,0x42,0x5C,0x40,0x5C,0x20,0xFC,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE0EC [?] [5998]*/ + 0x00,0x07,0x72,0x53,0x50,0x5F,0x5A,0x53,0x51,0x57,0x71,0x4F,0x01,0x03,0x0D,0x01, + 0x40,0xFC,0x48,0xF8,0x40,0xFE,0xAA,0xB8,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xE0ED [?] [5999]*/ + 0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE0EE [?] [6000]*/ + 0x00,0x7F,0x40,0x40,0x4F,0x40,0x40,0x41,0x5F,0x41,0x41,0x41,0x45,0x42,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x44,0x84,0x04,0xF4,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE0EF [?] [6001]*/ + 0x00,0x7F,0x42,0x42,0x42,0x7F,0x44,0x44,0x48,0x46,0x41,0x42,0x44,0x48,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x44,0x44,0x84,0x84,0x04,0x84,0x44,0x24,0xFC,0x04, + /* 0xE0F0 [?] [6002]*/ + 0x00,0x7F,0x41,0x41,0x42,0x44,0x48,0x54,0x65,0x46,0x44,0x44,0x43,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x84,0x44,0x24,0x9C,0x04,0x04,0x24,0x24,0xE4,0x04,0xFC,0x04, + /* 0xE0F1 [?] [6003]*/ + 0x00,0x7F,0x44,0x44,0x47,0x49,0x49,0x52,0x42,0x44,0x49,0x42,0x44,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x54,0x54,0x54,0x94,0x94,0x14,0xA4,0x44,0x04,0xFC,0x04, + /* 0xE0F2 [?] [6004]*/ + 0x00,0x7F,0x41,0x41,0x42,0x44,0x4A,0x51,0x6F,0x40,0x40,0x42,0x41,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0x84,0x44,0x24,0x1C,0xE4,0x24,0x44,0x84,0x04,0x84,0xFC,0x04, + /* 0xE0F3 [?] [6005]*/ + 0x00,0x7F,0x42,0x42,0x5F,0x44,0x4F,0x54,0x67,0x44,0x47,0x44,0x44,0x44,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0xA4,0x44,0xFC,0x04, + /* 0xE0F4 [?] [6006]*/ + 0x00,0x7F,0x40,0x5F,0x42,0x4F,0x44,0x7F,0x40,0x4F,0x48,0x48,0x4F,0x40,0x7F,0x40, + 0x00,0xFC,0x04,0xF4,0x04,0xE4,0x24,0xFC,0x04,0xE4,0x24,0x24,0xE4,0x04,0xFC,0x04, + /* 0xE0F5 [?] [6007]*/ + 0x7F,0x41,0x4F,0x41,0x4F,0x41,0x7F,0x40,0x4F,0x48,0x4F,0x48,0x4F,0x48,0x48,0x7F, + 0xFC,0x04,0xE4,0x04,0xE4,0x04,0xFC,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0x64,0xFC, + /* 0xE0F6 [?] [6008]*/ + 0x00,0x7F,0x41,0x41,0x4F,0x41,0x5F,0x44,0x42,0x4F,0x41,0x5F,0x41,0x41,0x7F,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x04,0xF4,0x44,0x84,0xE4,0x04,0xF4,0x04,0x04,0xFC,0x04, + /* 0xE0F7 [?] [6009]*/ + 0x7F,0x40,0x5F,0x52,0x5F,0x40,0x7F,0x40,0x4F,0x48,0x4F,0x45,0x4C,0x74,0x46,0x7F, + 0xFC,0x04,0xF4,0x94,0xF4,0x04,0xFC,0x04,0xE4,0x24,0xE4,0x14,0xA4,0x44,0x24,0xFC, + /* 0xE0F8 [?] [6010]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x54,0x54,0x54,0x55,0x54,0x5C,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xE0F9 [?] [6011]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x56,0x54,0x57,0x54,0x54,0x5C,0x10,0x10,0x11,0x12, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xE0FA [?] [6012]*/ + 0x10,0x10,0x10,0x7D,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x11,0x12,0x12,0x14, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xE0FB [?] [6013]*/ + 0x10,0x10,0xFE,0x22,0x64,0x18,0x24,0xC3,0x01,0x3F,0x21,0x21,0x21,0x21,0x01,0x01, + 0x00,0x00,0xFC,0x44,0x28,0x10,0x28,0x46,0x00,0xF8,0x08,0x08,0x28,0x10,0x00,0x00, + /* 0xE0FC [?] [6014]*/ + 0x20,0x20,0x27,0xF8,0xAB,0xA8,0xAF,0xA8,0xA9,0xA9,0xAA,0xBA,0x24,0x28,0x20,0x20, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFE,0x90,0x10,0xFE,0x10,0x90,0x50,0x10,0x50,0x20, + /* 0xE0FD [?] [6015]*/ + 0x20,0x20,0x27,0xF8,0xAB,0xA8,0xAF,0xA8,0xAB,0xAA,0xAA,0xBA,0x22,0x20,0x21,0x26, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x00,0xF8,0x08,0x48,0x48,0x48,0xA0,0x10,0x08, + /* 0xE0FE [?] [6016]*/ + 0x20,0x23,0x22,0xFA,0xAB,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xBB,0x22,0x22,0x23,0x22, + 0x00,0xFE,0x02,0x02,0xFE,0x22,0x22,0xFA,0x22,0x32,0x2A,0xFE,0x02,0x02,0xFE,0x02, + /* 0xE1A1 [?] [6017]*/ + 0x10,0x10,0x10,0x7C,0x55,0x56,0x54,0x54,0x54,0x54,0x54,0x5C,0x10,0x10,0x10,0x10, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xE1A2 [?] [6018]*/ + 0x20,0x23,0x22,0xFA,0xAB,0xAA,0xAB,0xAA,0xAA,0xAB,0xAA,0xBA,0x25,0x24,0x28,0x33, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x40,0x88,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE, + /* 0xE1A3 [?] [6019]*/ + 0x20,0x21,0x21,0xF9,0xA9,0xA9,0xA8,0xAB,0xAA,0xAB,0xA8,0xB9,0x20,0x20,0x21,0x26, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0xFC,0x00,0xF8,0x90,0x60,0x98,0x06, + /* 0xE1A4 [?] [6020]*/ + 0x10,0x11,0x10,0x7C,0x57,0x54,0x55,0x55,0x55,0x55,0x55,0x5C,0x13,0x10,0x10,0x10, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xE1A5 [?] [6021]*/ + 0x20,0x22,0x21,0xF8,0xAB,0xA8,0xA8,0xAB,0xA8,0xA9,0xA8,0xBB,0x20,0x20,0x21,0x26, + 0x50,0x52,0x54,0x50,0xFE,0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xE1A6 [?] [6022]*/ + 0x20,0x27,0x22,0xF9,0xAB,0xA9,0xAA,0xAC,0xAB,0xAA,0xAA,0xBB,0x22,0x22,0x23,0x22, + 0x78,0xC0,0x48,0x50,0xFC,0x50,0x48,0x06,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x08, + /* 0xE1A7 [?] [6023]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x08,0x08,0x0C,0x0A,0x11,0x10,0x20,0x20,0x43,0x8C, + 0x00,0x08,0x08,0xF8,0x00,0xF0,0x20,0x40,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xE1A8 [?] [6024]*/ + 0x10,0x10,0x11,0x10,0x54,0x54,0x54,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x00,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE1A9 [?] [6025]*/ + 0x10,0x11,0x10,0x10,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x5C,0x64,0x01,0x01,0x02, + 0x00,0xFC,0x88,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xE1AA [?] [6026]*/ + 0x10,0x10,0x10,0x13,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x5C,0x64,0x00,0x01,0x06, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xE1AB [?] [6027]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x00, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xE1AC [?] [6028]*/ + 0x10,0x11,0x10,0x10,0x54,0x54,0x55,0x55,0x54,0x54,0x54,0x5C,0x65,0x02,0x00,0x00, + 0x00,0xFE,0x08,0x88,0x88,0x88,0x08,0xFE,0x18,0x28,0x48,0x88,0x08,0x08,0x28,0x10, + /* 0xE1AD [?] [6029]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x5C,0x64,0x01,0x02,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xE1AE [?] [6030]*/ + 0x00,0x00,0x3F,0x01,0x02,0x7F,0x04,0x08,0x30,0xC1,0x01,0x21,0x21,0x21,0x3F,0x00, + 0x10,0xF8,0x00,0x00,0x00,0xFC,0x40,0x20,0x18,0x06,0x00,0x08,0x08,0x08,0xF8,0x08, + /* 0xE1AF [?] [6031]*/ + 0x01,0x21,0x21,0x3F,0x01,0x02,0x04,0x0A,0x31,0xC1,0x1F,0x00,0x00,0x00,0x00,0x01, + 0x00,0x08,0x08,0xF8,0x00,0x80,0x40,0x20,0x18,0x06,0xE0,0x20,0x40,0x40,0x80,0x00, + /* 0xE1B0 [?] [6032]*/ + 0x01,0x21,0x21,0x3F,0x00,0x1F,0x10,0x10,0x14,0x12,0x11,0x12,0x24,0x28,0x40,0x80, + 0x00,0x08,0x08,0xF8,0x00,0xF0,0x10,0x50,0x50,0x90,0x10,0x92,0x4A,0x4A,0x06,0x02, + /* 0xE1B1 [?] [6033]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x21,0x21,0x21,0x3F,0x20,0x20,0x20,0x20,0x1F,0x00, + 0x00,0x08,0x08,0xF8,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xE1B2 [?] [6034]*/ + 0x10,0x10,0x10,0x10,0x55,0x54,0x54,0x54,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE1B3 [?] [6035]*/ + 0x01,0x21,0x21,0x3F,0x00,0x00,0xFF,0x00,0x00,0x1F,0x10,0x10,0x1F,0x00,0x00,0x00, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xFE,0x10,0x10,0x90,0x90,0x90,0x90,0x10,0x50,0x20, + /* 0xE1B4 [?] [6036]*/ + 0x01,0x21,0x21,0x3F,0x02,0x02,0x7F,0x04,0x09,0x11,0x3F,0x01,0x11,0x21,0x45,0x02, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x10,0x08,0x04,0x00, + /* 0xE1B5 [?] [6037]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5C,0x64,0x00,0x00,0x00, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xE1B6 [?] [6038]*/ + 0x10,0x10,0x10,0x10,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xE1B7 [?] [6039]*/ + 0x08,0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x11,0x01,0x21,0x21,0x21,0x21,0x3F,0x00, + 0x90,0x88,0x80,0x9E,0xE0,0x80,0x44,0x34,0x0C,0x00,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xE1B8 [?] [6040]*/ + 0x10,0x10,0x11,0x11,0x56,0x54,0x55,0x55,0x55,0x55,0x55,0x5D,0x64,0x00,0x00,0x00, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x04,0x28,0x10, + /* 0xE1B9 [?] [6041]*/ + 0x01,0x21,0x21,0x3F,0x00,0x0C,0x70,0x40,0x44,0x44,0x5C,0x64,0x48,0x08,0x10,0x60, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80,0x80, + /* 0xE1BA [?] [6042]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x01, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x4A,0x86,0x02, + /* 0xE1BB [?] [6043]*/ + 0x10,0x13,0x11,0x10,0x54,0x54,0x54,0x57,0x54,0x55,0x54,0x5C,0x67,0x00,0x00,0x00, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE1BC [?] [6044]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x01,0x01,0x01, + 0x00,0xFE,0x02,0x02,0x7A,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x7A,0x02,0x02,0x0A,0x04, + /* 0xE1BD [?] [6045]*/ + 0x10,0x10,0x11,0x10,0x54,0x57,0x54,0x54,0x55,0x56,0x54,0x5C,0x64,0x01,0x01,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xE1BE [?] [6046]*/ + 0x10,0x10,0x11,0x11,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x65,0x00,0x00,0x00, + 0x80,0x80,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x04,0x28,0x10, + /* 0xE1BF [?] [6047]*/ + 0x10,0x10,0x10,0x11,0x56,0x55,0x54,0x54,0x55,0x54,0x54,0x5D,0x64,0x00,0x00,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x24,0x20,0xA0,0x40, + /* 0xE1C0 [?] [6048]*/ + 0x20,0x20,0x23,0x20,0xA8,0xAB,0xAA,0xAC,0xA8,0xAB,0xA8,0xB8,0xC8,0x01,0x02,0x04, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x44,0x40,0xFC,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xE1C1 [?] [6049]*/ + 0x20,0x20,0x20,0x27,0xA8,0xAA,0xA9,0xA9,0xAF,0xA8,0xA9,0xB9,0xCA,0x04,0x08,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x50,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40, + /* 0xE1C2 [?] [6050]*/ + 0x01,0x21,0x21,0x3F,0x10,0x10,0x10,0xFD,0x31,0x3A,0x54,0x50,0x90,0x11,0x13,0x11, + 0x00,0x08,0x08,0xF8,0x10,0x90,0x90,0x08,0x48,0x44,0x42,0x90,0x88,0x08,0xFC,0x04, + /* 0xE1C3 [?] [6051]*/ + 0x20,0x20,0x27,0x21,0xAA,0xAC,0xAB,0xAA,0xAA,0xAB,0xAA,0xBA,0xCB,0x00,0x00,0x00, + 0x40,0x80,0xFE,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xE1C4 [?] [6052]*/ + 0x01,0x21,0x21,0x3F,0x00,0x3F,0x21,0x21,0x2F,0x21,0x27,0x24,0x27,0x20,0x3F,0x20, + 0x00,0x08,0x08,0xF8,0x00,0xF8,0x08,0x08,0xE8,0x08,0xC8,0x48,0xC8,0x08,0xF8,0x08, + /* 0xE1C5 [?] [6053]*/ + 0x21,0x20,0x20,0x20,0xAB,0xA8,0xAB,0xA8,0xA8,0xA9,0xAA,0xB8,0xC8,0x00,0x00,0x00, + 0x84,0x68,0x30,0xC8,0x24,0x20,0xFE,0x40,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x94,0x88, + /* 0xE1C6 [?] [6054]*/ + 0x20,0x20,0x23,0x20,0xA9,0xA9,0xA9,0xA8,0xA9,0xA8,0xA8,0xBB,0xC8,0x00,0x00,0x00, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFC,0x08,0x10,0xFE,0x20,0x20,0xA0,0x40, + /* 0xE1C7 [?] [6055]*/ + 0x20,0x20,0x20,0x23,0xAA,0xAC,0xA9,0xAA,0xA8,0xA9,0xA8,0xB8,0xC8,0x00,0x07,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x94,0x08,0x04,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xE1C8 [?] [6056]*/ + 0x20,0x23,0x22,0x22,0xAB,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xBA,0xCA,0x04,0x04,0x08, + 0x00,0xFE,0x02,0x02,0xFE,0x10,0x92,0x92,0x92,0xFE,0x10,0x92,0x92,0x92,0xFE,0x02, + /* 0xE1C9 [?] [6057]*/ + 0x20,0x20,0x23,0x20,0xA8,0xAB,0xAA,0xAC,0xA8,0xAB,0xA8,0xB8,0xC8,0x01,0x02,0x00, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x24,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20, + /* 0xE1CA [?] [6058]*/ + 0x20,0x23,0x20,0x20,0xAB,0xAA,0xAA,0xAB,0xA8,0xA8,0xAF,0xB8,0xC9,0x00,0x00,0x03, + 0x00,0xFE,0x50,0x50,0xFE,0x52,0x52,0xFE,0x00,0x40,0xFE,0x88,0x90,0x60,0xD8,0x04, + /* 0xE1CB [?] [6059]*/ + 0x01,0x21,0x21,0x3F,0x00,0x00,0x3F,0x20,0x2F,0x22,0x2F,0x24,0x2D,0x42,0x45,0x88, + 0x00,0x08,0x08,0xF8,0x28,0x24,0xFE,0x20,0xA4,0x24,0xA8,0x98,0x12,0x2A,0x46,0x82, + /* 0xE1CC [?] [6060]*/ + 0x01,0x21,0x21,0x3F,0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x01,0x48,0x48,0x87, + 0x00,0x08,0x08,0xF8,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x84,0x12,0xF2, + /* 0xE1CD [?] [6061]*/ + 0x01,0x21,0x21,0x3F,0x02,0x04,0x3F,0x21,0x3F,0x21,0x3F,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x08,0x08,0xF8,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x90,0xA8,0xFA,0x8A,0x7E, + /* 0xE1CE [?] [6062]*/ + 0x01,0x21,0x21,0x3F,0x02,0x0C,0x37,0xC0,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x22,0x26, + 0x00,0x08,0x08,0xF8,0x80,0x60,0xD8,0x06,0x08,0x48,0x48,0x48,0x48,0x08,0x28,0x10, + /* 0xE1CF [?] [6063]*/ + 0x11,0x10,0x10,0x13,0x54,0x55,0x54,0x57,0x54,0x55,0x55,0x5E,0x64,0x08,0x03,0x00, + 0x08,0x88,0x90,0xFC,0x40,0xF8,0x40,0xFE,0x80,0x00,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE1D0 [?] [6064]*/ + 0x20,0x21,0x20,0x20,0xAB,0xA8,0xA9,0xAA,0xA8,0xAF,0xA8,0xB9,0xC9,0x00,0x01,0x06, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xE1D1 [?] [6065]*/ + 0x20,0x20,0x20,0x23,0xA8,0xA8,0xA9,0xA9,0xAA,0xAB,0xA8,0xB9,0xC9,0x02,0x03,0x00, + 0x84,0x44,0x48,0xFE,0x84,0x84,0x08,0x4A,0x52,0x9C,0x84,0x08,0x08,0x52,0xDE,0x42, + /* 0xE1D2 [?] [6066]*/ + 0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5D,0x62,0x02,0x04,0x08, + 0x00,0xFE,0x12,0x12,0xFE,0x00,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x42, + /* 0xE1D3 [?] [6067]*/ + 0x20,0x23,0x20,0x27,0xA9,0xA9,0xAF,0xA9,0xAB,0xAD,0xA8,0xB9,0xCA,0x04,0x08,0x00, + 0x38,0xC0,0x40,0xFC,0x50,0x54,0x58,0x54,0x54,0x4C,0xE0,0x50,0x48,0x44,0x42,0x40, + /* 0xE1D4 [?] [6068]*/ + 0x01,0x41,0x7F,0x02,0xFF,0x00,0x1F,0x10,0x1F,0x00,0x7F,0x40,0x4F,0x48,0x4F,0x40, + 0x00,0x04,0xFC,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x00,0xFC,0x04,0xE4,0x24,0xE4,0x0C, + /* 0xE1D5 [?] [6069]*/ + 0x20,0x22,0x21,0x22,0xAC,0xA9,0xAE,0xAB,0xAA,0xAB,0xAA,0xBB,0xCA,0x02,0x02,0x02, + 0x40,0x48,0x50,0x48,0xA4,0x18,0x06,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xE1D6 [?] [6070]*/ + 0x10,0x11,0x10,0x10,0x57,0x54,0x55,0x55,0x55,0x55,0x55,0x5C,0x67,0x00,0x00,0x00, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xE1D7 [?] [6071]*/ + 0x20,0x21,0x20,0x23,0xA8,0xA9,0xAA,0xA9,0xA9,0xA9,0xAA,0xBD,0xC8,0x01,0x02,0x04, + 0x20,0x24,0xA8,0xFE,0xA8,0x24,0x22,0x04,0x04,0xDE,0x44,0x54,0x9E,0x04,0x04,0x04, + /* 0xE1D8 [?] [6072]*/ + 0x20,0x27,0x20,0x22,0xA9,0xAA,0xAD,0xA8,0xAB,0xAA,0xAA,0xBB,0xCA,0x01,0x0F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xE1D9 [?] [6073]*/ + 0x01,0x41,0x7D,0x49,0x51,0x6B,0x4D,0x59,0x6D,0x4B,0x59,0x69,0x59,0x41,0x7F,0x00, + 0x00,0x04,0xF4,0x24,0x44,0xAC,0x34,0x64,0xB4,0x2C,0x64,0xA4,0x64,0x04,0xFC,0x04, + /* 0xE1DA [?] [6074]*/ + 0x01,0x41,0x7F,0x00,0x24,0x3A,0x22,0x1E,0x20,0x3E,0x48,0x08,0x7F,0x14,0x22,0x41, + 0x00,0x04,0xFC,0x00,0x7C,0x04,0x28,0x10,0xFE,0x12,0x50,0x5E,0x50,0xB0,0x9E,0x00, + /* 0xE1DB [?] [6075]*/ + 0x21,0x3F,0x08,0x7E,0x08,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x3E,0x22,0xFF,0x24,0x42, + 0x08,0xF8,0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x28,0x44,0x82, + /* 0xE1DC [?] [6076]*/ + 0x08,0x08,0x10,0x20,0x48,0x08,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE1DD [?] [6077]*/ + 0x08,0x08,0x10,0x23,0x48,0x08,0x10,0x30,0x50,0x90,0x10,0x10,0x11,0x11,0x12,0x14, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xE1DE [?] [6078]*/ + 0x08,0x09,0x11,0x21,0x49,0x09,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x17,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xE1DF [?] [6079]*/ + 0x08,0x08,0x11,0x21,0x4A,0x0C,0x13,0x32,0x52,0x93,0x12,0x12,0x13,0x10,0x10,0x10, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xE1E0 [?] [6080]*/ + 0x09,0x08,0x10,0x20,0x4B,0x08,0x10,0x31,0x50,0x90,0x13,0x10,0x10,0x10,0x10,0x10, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xE1E1 [?] [6081]*/ + 0x08,0x08,0x10,0x21,0x4B,0x08,0x10,0x33,0x50,0x90,0x11,0x13,0x14,0x10,0x11,0x16, + 0x20,0x40,0x88,0x10,0xE0,0x40,0x88,0xFC,0x84,0x80,0xF8,0x08,0x90,0x60,0x98,0x06, + /* 0xE1E2 [?] [6082]*/ + 0x10,0x10,0x20,0x47,0x90,0x12,0x21,0x61,0xAF,0x20,0x21,0x21,0x22,0x24,0x28,0x20, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x50,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40, + /* 0xE1E3 [?] [6083]*/ + 0x08,0x08,0x11,0x21,0x49,0x09,0x17,0x30,0x50,0x91,0x11,0x11,0x12,0x14,0x18,0x10, + 0x20,0x20,0x20,0x3C,0x20,0x20,0xFE,0x00,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xE1E4 [?] [6084]*/ + 0x08,0x09,0x10,0x20,0x48,0x0B,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x12, + 0x20,0x24,0xA4,0xA8,0x20,0xFE,0x02,0x02,0xFA,0x8A,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE1E5 [?] [6085]*/ + 0x08,0x08,0x13,0x22,0x4B,0x0A,0x13,0x30,0x57,0x90,0x10,0x13,0x10,0x10,0x17,0x10, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFC,0x00, + /* 0xE1E6 [?] [6086]*/ + 0x08,0x08,0x13,0x20,0x4A,0x09,0x11,0x32,0x50,0x93,0x10,0x11,0x11,0x11,0x11,0x10, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0xFC,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xE1E7 [?] [6087]*/ + 0x11,0x15,0x25,0x45,0x97,0x10,0x27,0x60,0xA7,0x21,0x27,0x21,0x21,0x2F,0x20,0x20, + 0x08,0x48,0x48,0x50,0xDE,0x14,0xE4,0x14,0xD4,0x14,0xD4,0x08,0x08,0xD4,0x24,0x42, + /* 0xE1E8 [?] [6088]*/ + 0x12,0x14,0x2F,0x48,0x9F,0x18,0x2F,0x64,0xA2,0x2F,0x24,0x27,0x24,0x28,0x2A,0x31, + 0x10,0x10,0x90,0x90,0xBE,0xA4,0xD4,0x14,0x14,0xD4,0x14,0x88,0x88,0x94,0x94,0x22, + /* 0xE1E9 [?] [6089]*/ + 0x2E,0x2A,0x4E,0x4A,0x8E,0x1A,0x2E,0x64,0xAF,0x34,0x27,0x24,0x27,0x24,0x27,0x24, + 0xE0,0xA0,0xEE,0xA0,0xE0,0xA0,0xFE,0x44,0xF4,0x84,0xE4,0x84,0xE4,0x84,0xF4,0x08, + /* 0xE1EA [?] [6090]*/ + 0x04,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x20,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE1EB [?] [6091]*/ + 0x00,0x44,0x28,0x10,0x28,0x48,0x88,0x08,0x18,0x28,0x48,0x88,0x08,0x08,0x50,0x20, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE1EC [?] [6092]*/ + 0x00,0x44,0x28,0x10,0x2B,0x48,0x88,0x08,0x18,0x28,0x48,0x88,0x09,0x09,0x52,0x24, + 0x80,0x80,0x80,0x80,0xF0,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xE1ED [?] [6093]*/ + 0x00,0x45,0x28,0x10,0x28,0x48,0x88,0x0B,0x18,0x28,0x48,0x88,0x08,0x08,0x50,0x20, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xE1EE [?] [6094]*/ + 0x00,0x44,0x28,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x0A,0x52,0x24, + 0x20,0x10,0x10,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE1EF [?] [6095]*/ + 0x00,0x47,0x28,0x10,0x29,0x49,0x89,0x09,0x18,0x28,0x48,0x8B,0x08,0x08,0x50,0x20, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xE1F0 [?] [6096]*/ + 0x00,0x45,0x28,0x10,0x28,0x48,0x88,0x0B,0x18,0x28,0x48,0x88,0x08,0x08,0x53,0x20, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFE,0x00, + /* 0xE1F1 [?] [6097]*/ + 0x00,0x44,0x28,0x10,0x29,0x4B,0x88,0x08,0x18,0x28,0x48,0x88,0x09,0x09,0x52,0x24, + 0x40,0x40,0x80,0x88,0x04,0xFE,0x02,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xE1F2 [?] [6098]*/ + 0x00,0x45,0x29,0x11,0x29,0x49,0x89,0x09,0x19,0x29,0x49,0x88,0x08,0x08,0x50,0x20, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xE1F3 [?] [6099]*/ + 0x00,0x44,0x29,0x11,0x2A,0x4D,0x89,0x09,0x19,0x29,0x49,0x89,0x09,0x09,0x50,0x20, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xE1F4 [?] [6100]*/ + 0x00,0x44,0x28,0x13,0x28,0x48,0x8B,0x0A,0x1A,0x2B,0x48,0x88,0x09,0x09,0x52,0x24, + 0x90,0x90,0x90,0xFC,0x94,0x94,0xFC,0x90,0x90,0xFE,0x92,0x92,0x1A,0x14,0x10,0x10, + /* 0xE1F5 [?] [6101]*/ + 0x00,0x44,0x28,0x10,0x2B,0x48,0x89,0x09,0x19,0x2B,0x49,0x89,0x0A,0x0A,0x54,0x20, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x24,0x24,0x24,0xA8,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xE1F6 [?] [6102]*/ + 0x00,0x88,0x50,0x21,0x52,0x94,0x11,0x10,0x30,0x57,0x90,0x10,0x11,0x12,0xA7,0x42, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xE1F7 [?] [6103]*/ + 0x00,0x88,0x53,0x22,0x54,0x90,0x10,0x13,0x30,0x51,0x90,0x10,0x10,0x10,0xA0,0x40, + 0x40,0x20,0xFE,0x02,0x14,0x10,0x10,0xFE,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20, + /* 0xE1F8 [?] [6104]*/ + 0x00,0x88,0x57,0x20,0x51,0x92,0x12,0x13,0x32,0x56,0x9A,0x13,0x12,0x12,0xA2,0x46, + 0x00,0x10,0x90,0x90,0x10,0x10,0xD8,0x54,0x54,0x92,0x92,0x12,0x10,0x10,0x50,0x20, + /* 0xE1F9 [?] [6105]*/ + 0x02,0x8A,0x52,0x23,0x52,0x92,0x12,0x13,0x30,0x50,0x93,0x10,0x10,0x10,0xA7,0x40, + 0x20,0x24,0x28,0xB0,0x20,0x22,0xA2,0x1E,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xE1FA [?] [6106]*/ + 0x00,0x45,0x29,0x11,0x29,0x48,0x8B,0x0A,0x1A,0x2B,0x4A,0x8A,0x0B,0x0A,0x52,0x22, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x14,0x08, + /* 0xE1FB [?] [6107]*/ + 0x00,0x89,0x57,0x21,0x51,0x91,0x1F,0x11,0x33,0x53,0x95,0x15,0x19,0x11,0xA1,0x41, + 0x84,0xC4,0x04,0x14,0x14,0x14,0xD4,0x14,0x14,0x94,0x54,0x04,0x04,0x04,0x14,0x08, + /* 0xE1FC [?] [6108]*/ + 0x00,0x88,0x50,0x21,0x52,0x95,0x10,0x10,0x37,0x50,0x92,0x12,0x14,0x18,0xA1,0x40, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xE1FD [?] [6109]*/ + 0x00,0x88,0x50,0x20,0x51,0x92,0x15,0x10,0x30,0x50,0x92,0x11,0x11,0x10,0xA7,0x40, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xE1FE [?] [6110]*/ + 0x00,0x44,0x2B,0x10,0x28,0x49,0x88,0x08,0x19,0x28,0x48,0x89,0x09,0x09,0x51,0x21, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xE2A1 [?] [6111]*/ + 0x00,0x44,0x28,0x11,0x2B,0x48,0x88,0x09,0x1A,0x28,0x49,0x8A,0x08,0x08,0x51,0x26, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xE2A2 [?] [6112]*/ + 0x00,0x88,0x53,0x20,0x51,0x92,0x17,0x10,0x33,0x52,0x92,0x12,0x13,0x10,0xA0,0x40, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xFE,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xE2A3 [?] [6113]*/ + 0x00,0x8B,0x52,0x22,0x53,0x92,0x12,0x13,0x30,0x57,0x90,0x11,0x12,0x14,0xA0,0x40, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xE2A4 [?] [6114]*/ + 0x00,0x8B,0x52,0x22,0x52,0x93,0x10,0x10,0x30,0x51,0x92,0x10,0x10,0x10,0xA1,0x46, + 0x00,0xFE,0x52,0x52,0x52,0xFE,0x20,0x40,0xFC,0x04,0x88,0x50,0x20,0x40,0x80,0x00, + /* 0xE2A5 [?] [6115]*/ + 0x00,0x90,0x53,0x22,0x52,0x93,0x12,0x12,0x33,0x50,0x90,0x10,0x10,0x11,0xA2,0x44, + 0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0xFC,0x90,0x90,0x90,0x90,0x12,0x12,0x0E, + /* 0xE2A6 [?] [6116]*/ + 0x00,0x88,0x50,0x21,0x52,0x95,0x10,0x10,0x37,0x50,0x90,0x13,0x12,0x12,0xA3,0x42, + 0x40,0x40,0xA0,0x10,0x08,0xF6,0x40,0x40,0xFC,0x40,0x40,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE2A7 [?] [6117]*/ + 0x00,0x88,0x57,0x20,0x51,0x91,0x12,0x14,0x30,0x50,0x97,0x10,0x10,0x10,0xA0,0x40, + 0x80,0x40,0xFC,0x00,0x10,0x10,0xA8,0x44,0x00,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xE2A8 [?] [6118]*/ + 0x00,0x97,0x51,0x21,0x51,0x97,0x14,0x14,0x34,0x57,0x91,0x11,0x11,0x11,0xA5,0x42, + 0x20,0x20,0x20,0x3E,0x42,0x44,0x90,0x10,0x10,0x54,0x52,0x52,0x92,0x10,0x50,0x20, + /* 0xE2A9 [?] [6119]*/ + 0x01,0x89,0x51,0x27,0x51,0x91,0x11,0x17,0x34,0x54,0x94,0x17,0x14,0x10,0xA0,0x40, + 0x00,0x1E,0x12,0xD2,0x12,0x1E,0x12,0xD2,0x52,0x5E,0x52,0xD2,0x52,0x22,0x2A,0x44, + /* 0xE2AA [?] [6120]*/ + 0x00,0x90,0x57,0x20,0x51,0x92,0x14,0x13,0x32,0x53,0x92,0x13,0x12,0x10,0xA7,0x40, + 0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xE2AB [?] [6121]*/ + 0x00,0x8B,0x52,0x22,0x53,0x92,0x12,0x13,0x30,0x57,0x92,0x12,0x12,0x12,0xA3,0x42, + 0x00,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x00,0xFE,0x40,0x44,0x28,0x90,0x08,0x06, + /* 0xE2AC [?] [6122]*/ + 0x00,0x97,0x54,0x27,0x54,0x97,0x10,0x13,0x32,0x53,0x92,0x13,0x12,0x12,0xA2,0x42, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xE2AD [?] [6123]*/ + 0x00,0x8B,0x52,0x22,0x53,0x92,0x12,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0xA4,0x48, + 0x00,0xFC,0x24,0x24,0xFC,0x00,0xFC,0x84,0x84,0xFC,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xE2AE [?] [6124]*/ + 0x00,0x8B,0x50,0x20,0x57,0x90,0x11,0x12,0x34,0x50,0x97,0x10,0x11,0x12,0xAC,0x40, + 0x00,0xF8,0x90,0x60,0xFC,0xA4,0x28,0x20,0x60,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xE2AF [?] [6125]*/ + 0x00,0x45,0x28,0x10,0x2B,0x48,0x89,0x09,0x19,0x29,0x49,0x88,0x0B,0x08,0x50,0x20, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xE2B0 [?] [6126]*/ + 0x00,0x88,0x53,0x21,0x50,0x97,0x10,0x13,0x32,0x53,0x92,0x13,0x11,0x11,0xA2,0x4C, + 0x80,0x40,0xF8,0x10,0xA0,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x20,0x22,0x22,0x1E, + /* 0xE2B1 [?] [6127]*/ + 0x00,0x9F,0x58,0x2A,0x69,0xAB,0x28,0x28,0x6A,0xAA,0x2B,0x28,0x28,0x29,0xA9,0x52, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xE2B2 [?] [6128]*/ + 0x00,0x90,0x57,0x20,0x55,0x92,0x17,0x1A,0x33,0x52,0x93,0x10,0x12,0x14,0xA9,0x40, + 0x40,0x40,0xFC,0xA0,0x14,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x40,0x48,0x44,0x44,0x80, + /* 0xE2B3 [?] [6129]*/ + 0x02,0x93,0x54,0x29,0x67,0xA5,0x25,0x27,0x65,0xA5,0x27,0x25,0x25,0x25,0xA4,0x48, + 0x00,0x9E,0x8A,0x0A,0xD2,0x66,0x40,0xD4,0x5E,0x64,0xC4,0x44,0x5E,0x44,0x44,0xC4, + /* 0xE2B4 [?] [6130]*/ + 0x00,0x97,0x50,0x2F,0x50,0x97,0x15,0x14,0x37,0x50,0x97,0x10,0x1F,0x10,0xA5,0x48, + 0x3C,0xC0,0x40,0xFE,0x40,0xFC,0x54,0xE4,0xFC,0x40,0xFC,0x40,0xFE,0x00,0x24,0x92, + /* 0xE2B5 [?] [6131]*/ + 0x01,0x8F,0x51,0x27,0x54,0x97,0x11,0x11,0x33,0x52,0x97,0x1A,0x13,0x12,0xA3,0x42, + 0x10,0xFE,0x10,0xBC,0xA4,0xBC,0x40,0x20,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE2B6 [?] [6132]*/ + 0x10,0x10,0x10,0x1E,0x12,0x22,0x22,0x52,0x8A,0x04,0x04,0x08,0x08,0x10,0x20,0x40, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x90,0x90,0x90,0x90,0xFE,0x10,0x10,0x10,0x10,0x10, + /* 0xE2B7 [?] [6133]*/ + 0x00,0x7E,0x4A,0x4A,0x7E,0x4A,0x4A,0x7E,0x08,0xFF,0x18,0x2C,0x2A,0x4A,0x88,0x08, + 0x20,0x20,0x7C,0x44,0xA8,0x10,0x20,0xD0,0x1E,0x22,0x64,0x94,0x08,0x10,0x20,0xC0, + /* 0xE2B8 [?] [6134]*/ + 0x20,0x20,0x20,0x3C,0x24,0x45,0x46,0xA4,0x14,0x08,0x08,0x10,0x10,0x20,0x40,0x80, + 0x20,0x20,0x50,0x48,0xA4,0xFA,0x88,0xF8,0x88,0xF8,0xA2,0x94,0x88,0xA4,0xC4,0x80, + /* 0xE2B9 [?] [6135]*/ + 0x02,0x0F,0x34,0x03,0x1D,0x7F,0x40,0xBF,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x10,0x20, + 0x00,0xF0,0x60,0x80,0x00,0xFE,0x02,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x10,0x08, + /* 0xE2BA [?] [6136]*/ + 0x04,0x04,0x04,0x0F,0x08,0x10,0x30,0x48,0x84,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xE2BB [?] [6137]*/ + 0x20,0x20,0x20,0x3E,0x44,0x48,0x80,0x10,0x10,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE2BC [?] [6138]*/ + 0x20,0x21,0x20,0x3C,0x44,0x48,0xA1,0x20,0x20,0x20,0x21,0x21,0x2A,0x34,0x20,0x01, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xE2BD [?] [6139]*/ + 0x20,0x20,0x20,0x3B,0x48,0x52,0x82,0x22,0x22,0x23,0x20,0x20,0x28,0x30,0x20,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xE2BE [?] [6140]*/ + 0x20,0x20,0x20,0x3D,0x46,0x48,0x80,0x20,0x21,0x20,0x20,0x24,0x28,0x30,0x20,0x00, + 0x80,0x80,0xFC,0x00,0x00,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x0A,0x0A,0x06,0x02, + /* 0xE2BF [?] [6141]*/ + 0x20,0x20,0x21,0x3C,0x44,0x48,0x80,0x23,0x20,0x20,0x20,0x24,0x28,0x30,0x21,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00, + /* 0xE2C0 [?] [6142]*/ + 0x20,0x20,0x21,0x3C,0x44,0x48,0x83,0x20,0x20,0x20,0x20,0x24,0x28,0x30,0x21,0x02, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFE,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xE2C1 [?] [6143]*/ + 0x20,0x20,0x21,0x39,0x4A,0x54,0x80,0x23,0x20,0x20,0x20,0x20,0x29,0x31,0x22,0x04, + 0x80,0x80,0x00,0xFE,0x00,0x40,0x40,0xFC,0x44,0x44,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xE2C2 [?] [6144]*/ + 0x20,0x20,0x20,0x3C,0x45,0x4B,0x80,0x20,0x21,0x21,0x21,0x25,0x29,0x31,0x21,0x01, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE2C3 [?] [6145]*/ + 0x20,0x20,0x20,0x3B,0x4A,0x52,0x82,0x22,0x22,0x22,0x22,0x22,0x2A,0x32,0x22,0x02, + 0x40,0x40,0x80,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xE2C4 [?] [6146]*/ + 0x20,0x20,0x23,0x3C,0x44,0x4B,0xA2,0x24,0x21,0x20,0x20,0x23,0x28,0x30,0x20,0x00, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x02,0x04,0xF8,0x10,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xE2C5 [?] [6147]*/ + 0x20,0x20,0x20,0x3C,0x45,0x4A,0xA0,0x20,0x23,0x20,0x21,0x21,0x2A,0x34,0x20,0x00, + 0x20,0x20,0x50,0x88,0x04,0xFA,0x20,0x20,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xE2C6 [?] [6148]*/ + 0x20,0x21,0x21,0x3D,0x45,0x49,0xA1,0x21,0x20,0x21,0x21,0x21,0x29,0x31,0x21,0x01, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xE2C7 [?] [6149]*/ + 0x20,0x20,0x27,0x38,0x49,0x52,0x84,0x23,0x22,0x23,0x22,0x23,0x2A,0x30,0x27,0x00, + 0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xE2C8 [?] [6150]*/ + 0x20,0x23,0x22,0x3E,0x47,0x4A,0xA2,0x23,0x20,0x23,0x21,0x20,0x28,0x30,0x20,0x07, + 0xA0,0x2E,0x22,0x22,0xAE,0x22,0x22,0xFE,0x20,0xFE,0x04,0x88,0x50,0x20,0xD8,0x06, + /* 0xE2C9 [?] [6151]*/ + 0x21,0x21,0x27,0x39,0x48,0x53,0x82,0x23,0x22,0x23,0x20,0x23,0x28,0x31,0x22,0x04, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xE2CA [?] [6152]*/ + 0x22,0x21,0x27,0x38,0x4B,0x50,0x87,0x21,0x23,0x24,0x28,0x23,0x29,0x31,0x27,0x00, + 0x08,0x10,0xFC,0x40,0xF8,0x80,0xFC,0x00,0xF8,0x88,0x88,0xF8,0x08,0x08,0xFE,0x00, + /* 0xE2CB [?] [6153]*/ + 0x20,0x20,0x23,0x3C,0x44,0x48,0xA1,0x21,0x21,0x20,0x23,0x20,0x29,0x30,0x23,0x00, + 0x88,0x88,0xFE,0x88,0xF8,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE2CC [?] [6154]*/ + 0x22,0x22,0x27,0x3A,0x4A,0x57,0x80,0x27,0x24,0x27,0x24,0x27,0x2C,0x34,0x24,0x04, + 0x88,0x88,0xC8,0x90,0x9E,0xD4,0x24,0xD4,0x54,0xD4,0x54,0xC8,0x48,0x54,0x64,0xC2, + /* 0xE2CD [?] [6155]*/ + 0x20,0x23,0x22,0x3B,0x4A,0x52,0x81,0x20,0x20,0x23,0x20,0x20,0x2B,0x30,0x21,0x02, + 0x00,0xDE,0x52,0xDE,0x10,0x52,0xCE,0x00,0x88,0xFE,0x88,0x88,0xFE,0x88,0x04,0x02, + /* 0xE2CE [?] [6156]*/ + 0x20,0x27,0x22,0x3B,0x48,0x5F,0x8A,0x23,0x21,0x27,0x21,0x2F,0x29,0x33,0x2D,0x01, + 0x40,0xFC,0x48,0xF8,0x40,0xFE,0xAA,0xB8,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xE2CF [?] [6157]*/ + 0x01,0x00,0x3F,0x20,0x20,0x22,0x22,0x22,0x22,0x23,0x22,0x22,0x22,0x42,0x41,0x80, + 0x00,0x80,0xFE,0x00,0x00,0x00,0x04,0x18,0x60,0x80,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xE2D0 [?] [6158]*/ + 0x01,0x00,0x3F,0x20,0x20,0x2F,0x20,0x20,0x3F,0x21,0x21,0x22,0x42,0x44,0x88,0x10, + 0x00,0x80,0xFE,0x00,0x00,0xFC,0x80,0x80,0xFE,0x40,0x40,0x40,0x42,0x42,0x3E,0x00, + /* 0xE2D1 [?] [6159]*/ + 0x01,0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x24,0x22,0x21,0x40,0x41,0x86,0x38, + 0x00,0x80,0xFE,0x80,0x80,0xFC,0x80,0x80,0xF0,0x10,0x20,0x40,0x80,0x60,0x18,0x06, + /* 0xE2D2 [?] [6160]*/ + 0x01,0x00,0x3F,0x22,0x22,0x27,0x28,0x37,0x24,0x24,0x27,0x24,0x24,0x44,0x43,0x80, + 0x00,0x80,0xFE,0x00,0x00,0xF8,0x08,0xC8,0x48,0x48,0xC8,0x28,0x12,0x02,0xFE,0x00, + /* 0xE2D3 [?] [6161]*/ + 0x01,0x00,0x3F,0x20,0x22,0x22,0x24,0x2D,0x34,0x24,0x24,0x25,0x26,0x44,0x44,0x84, + 0x00,0x80,0xFE,0x00,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20,0x20, + /* 0xE2D4 [?] [6162]*/ + 0x01,0x00,0x3F,0x24,0x22,0x3F,0x20,0x20,0x2F,0x20,0x20,0x3F,0x20,0x40,0x40,0x80, + 0x00,0x80,0xFE,0x10,0x20,0xFC,0x80,0x80,0xF8,0x80,0x80,0xFE,0x80,0x80,0x80,0x80, + /* 0xE2D5 [?] [6163]*/ + 0x01,0x00,0x3F,0x22,0x22,0x3F,0x22,0x23,0x20,0x27,0x24,0x27,0x44,0x44,0x88,0x10, + 0x00,0x80,0xFE,0x10,0x10,0xFE,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x20,0x10,0x08,0x06, + /* 0xE2D6 [?] [6164]*/ + 0x01,0x00,0x3F,0x20,0x20,0x2F,0x21,0x22,0x24,0x2F,0x34,0x27,0x24,0x47,0x40,0x80, + 0x00,0x80,0xFE,0x00,0x80,0xFC,0x20,0x10,0x88,0xF6,0x90,0xF0,0x90,0xF2,0x82,0x7E, + /* 0xE2D7 [?] [6165]*/ + 0x01,0x00,0x3F,0x20,0x22,0x2C,0x28,0x28,0x2E,0x28,0x28,0x2F,0x41,0x42,0x8C,0x30, + 0x00,0x80,0xFE,0x00,0x80,0xB8,0x88,0x88,0xB8,0x88,0x88,0xF8,0x40,0x20,0x18,0x06, + /* 0xE2D8 [?] [6166]*/ + 0x01,0x00,0x3F,0x20,0x21,0x27,0x24,0x27,0x24,0x27,0x21,0x22,0x3F,0x40,0x40,0x80, + 0x00,0x80,0xFE,0x80,0x00,0xFC,0x44,0xFC,0x84,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE2D9 [?] [6167]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x3F,0x21,0x2F,0x24,0x2F,0x34,0x24,0x44,0x41,0x82,0x0C, + 0x80,0xFE,0x80,0xF8,0x88,0xFE,0x08,0xF8,0x10,0xF8,0x16,0x90,0x90,0x60,0x10,0x08, + /* 0xE2DA [?] [6168]*/ + 0x01,0x00,0x3F,0x22,0x2F,0x22,0x2F,0x22,0x3F,0x24,0x27,0x24,0x44,0x48,0x8A,0x11, + 0x00,0x80,0xFE,0x10,0x90,0x1E,0xA4,0x24,0xD4,0x14,0x94,0x88,0x88,0x94,0xA4,0x42, + /* 0xE2DB [?] [6169]*/ + 0x00,0x3F,0x24,0x3F,0x24,0x27,0x20,0x2F,0x28,0x2F,0x20,0x3F,0x40,0x4F,0x80,0x3F, + 0x80,0xFE,0x10,0xFE,0x10,0xF0,0x80,0xF8,0x88,0xF8,0x80,0xFC,0x80,0xF8,0x80,0xFE, + /* 0xE2DC [?] [6170]*/ + 0x00,0x3F,0x20,0x2F,0x28,0x2F,0x28,0x2F,0x20,0x2F,0x20,0x3F,0x48,0x53,0x80,0x3F, + 0x80,0xFE,0x00,0xF8,0x88,0xF8,0x88,0xF8,0x80,0xF8,0x80,0xFE,0x88,0xE4,0x80,0xFE, + /* 0xE2DD [?] [6171]*/ + 0x00,0x3F,0x24,0x2F,0x31,0x22,0x2F,0x2A,0x2F,0x2A,0x2F,0x2A,0x4A,0x4A,0x88,0x11, + 0x80,0xFE,0x00,0x3C,0x14,0x24,0xCC,0x80,0xA8,0xBE,0xC8,0x88,0xBE,0x88,0x88,0x88, + /* 0xE2DE [?] [6172]*/ + 0x00,0x3F,0x20,0x2F,0x20,0x27,0x24,0x25,0x25,0x27,0x20,0x27,0x40,0x4F,0x82,0x04, + 0x80,0xFE,0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xFC,0x00,0xFC,0x00,0xFE,0x48,0xC4, + /* 0xE2DF [?] [6173]*/ + 0x00,0x3F,0x22,0x24,0x2D,0x36,0x24,0x24,0x20,0x27,0x24,0x27,0x44,0x47,0x84,0x04, + 0x80,0xFE,0x50,0xFC,0x90,0xFC,0x90,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x18, + /* 0xE2E0 [?] [6174]*/ + 0x10,0x10,0x10,0x10,0x18,0x54,0x50,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE2E1 [?] [6175]*/ + 0x10,0x10,0x17,0x10,0x18,0x54,0x50,0x50,0x90,0x10,0x11,0x11,0x12,0x12,0x14,0x18, + 0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xE2E2 [?] [6176]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xE2E3 [?] [6177]*/ + 0x10,0x10,0x13,0x10,0x18,0x54,0x50,0x57,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x78,0xC0,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xE2E4 [?] [6178]*/ + 0x10,0x13,0x10,0x18,0x54,0x50,0x57,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x18, + 0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xE2E5 [?] [6179]*/ + 0x10,0x10,0x10,0x17,0x18,0x54,0x50,0x57,0x92,0x12,0x11,0x10,0x10,0x10,0x11,0x16, + 0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0xF8,0x08,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06, + /* 0xE2E6 [?] [6180]*/ + 0x10,0x13,0x12,0x12,0x1A,0x56,0x52,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x13,0x10, + 0x00,0xFC,0x00,0x08,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x08,0x00,0xFE,0x00, + /* 0xE2E7 [?] [6181]*/ + 0x10,0x10,0x10,0x10,0x1B,0x56,0x52,0x52,0x92,0x12,0x13,0x12,0x10,0x10,0x10,0x10, + 0x20,0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x22,0xFE,0x22,0x20,0x20,0x20,0x20, + /* 0xE2E8 [?] [6182]*/ + 0x10,0x10,0x10,0x11,0x19,0x56,0x50,0x50,0x93,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xE2E9 [?] [6183]*/ + 0x11,0x11,0x11,0x1A,0x54,0x51,0x50,0x90,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x0A,0x0A,0x06,0x02, + /* 0xE2EA [?] [6184]*/ + 0x11,0x11,0x11,0x11,0x19,0x55,0x51,0x57,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0x08,0x08,0x10,0x20,0x40,0x00,0xFE,0x40,0x20,0x20,0x10,0x08,0x44,0x82,0x00, + /* 0xE2EB [?] [6185]*/ + 0x10,0x10,0x10,0x18,0x55,0x52,0x54,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xE2EC [?] [6186]*/ + 0x10,0x11,0x11,0x19,0x55,0x52,0x52,0x94,0x18,0x10,0x11,0x11,0x12,0x17,0x12,0x10, + 0x20,0x20,0x20,0x10,0x10,0x48,0x48,0x44,0x82,0x80,0x10,0x08,0x08,0xFC,0x04,0x00, + /* 0xE2ED [?] [6187]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x20,0x20,0x00,0xFE,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40, + /* 0xE2EE [?] [6188]*/ + 0x10,0x13,0x10,0x10,0x18,0x54,0x50,0x57,0x91,0x11,0x11,0x11,0x11,0x11,0x17,0x10, + 0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xE2EF [?] [6189]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE2F0 [?] [6190]*/ + 0x10,0x10,0x10,0x10,0x1B,0x54,0x50,0x50,0x90,0x10,0x11,0x12,0x14,0x10,0x10,0x10, + 0x20,0x28,0x24,0x20,0xFE,0x20,0x70,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20,0x20,0x20, + /* 0xE2F1 [?] [6191]*/ + 0x10,0x13,0x10,0x10,0x1A,0x55,0x51,0x50,0x97,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0xF8,0x40,0x40,0x48,0x48,0x50,0x40,0xFE,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xE2F2 [?] [6192]*/ + 0x10,0x10,0x11,0x11,0x19,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x10,0x10,0x13,0x10, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xE2F3 [?] [6193]*/ + 0x10,0x10,0x10,0x13,0x1A,0x56,0x52,0x52,0x92,0x17,0x10,0x10,0x10,0x11,0x12,0x14, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0x48,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x06, + /* 0xE2F4 [?] [6194]*/ + 0x10,0x10,0x10,0x18,0x55,0x51,0x52,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xE2F5 [?] [6195]*/ + 0x10,0x11,0x11,0x11,0x19,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xE2F6 [?] [6196]*/ + 0x10,0x10,0x10,0x13,0x18,0x54,0x53,0x52,0x92,0x13,0x10,0x10,0x11,0x11,0x12,0x14, + 0x90,0x90,0x90,0xFC,0x94,0x94,0xFC,0x90,0x90,0xFE,0x92,0x92,0x1A,0x14,0x10,0x10, + /* 0xE2F7 [?] [6197]*/ + 0x10,0x13,0x10,0x10,0x18,0x55,0x51,0x52,0x94,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x84,0x84,0x84,0x04,0x14,0x08,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE2F8 [?] [6198]*/ + 0x10,0x17,0x12,0x11,0x18,0x54,0x51,0x56,0x90,0x13,0x10,0x10,0x17,0x10,0x10,0x10, + 0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x4E,0x40,0xF8,0x40,0x40,0xFC,0x40,0x40,0x40, + /* 0xE2F9 [?] [6199]*/ + 0x10,0x10,0x10,0x18,0x54,0x51,0x53,0x90,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x40,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE2FA [?] [6200]*/ + 0x20,0x20,0x27,0x30,0xA8,0xA0,0xAF,0xA2,0x22,0x24,0x25,0x28,0x2F,0x20,0x20,0x21, + 0x10,0x10,0x90,0x10,0x7E,0x12,0xD2,0x12,0x12,0x22,0x22,0xA2,0xC2,0x42,0x94,0x08, + /* 0xE2FB [?] [6201]*/ + 0x10,0x13,0x12,0x12,0x1A,0x56,0x53,0x52,0x92,0x12,0x12,0x12,0x14,0x14,0x19,0x12, + 0x00,0xFE,0x20,0x28,0x24,0x20,0xFE,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xE2FC [?] [6202]*/ + 0x20,0x27,0x24,0x24,0x35,0xAD,0xA5,0xA5,0xA5,0x25,0x25,0x21,0x22,0x22,0x24,0x28, + 0x04,0xC4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x04,0x84,0x44,0x14,0x08, + /* 0xE2FD [?] [6203]*/ + 0x10,0x11,0x11,0x11,0x19,0x54,0x51,0x50,0x90,0x11,0x11,0x11,0x11,0x11,0x10,0x10, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE2FE [?] [6204]*/ + 0x10,0x10,0x11,0x11,0x1A,0x54,0x53,0x52,0x92,0x13,0x12,0x12,0x13,0x10,0x10,0x10, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xE3A1 [?] [6205]*/ + 0x10,0x10,0x10,0x11,0x1B,0x54,0x50,0x50,0x91,0x12,0x15,0x11,0x11,0x11,0x11,0x11, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xE3A2 [?] [6206]*/ + 0x10,0x13,0x12,0x1C,0x54,0x53,0x50,0x90,0x11,0x11,0x10,0x10,0x17,0x10,0x10,0x10, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE3A3 [?] [6207]*/ + 0x10,0x10,0x13,0x18,0x54,0x53,0x52,0x94,0x11,0x10,0x10,0x13,0x10,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x02,0x04,0xF8,0x10,0x20,0xFE,0x20,0x20,0xA0,0x40, + /* 0xE3A4 [?] [6208]*/ + 0x10,0x10,0x13,0x10,0x18,0x55,0x51,0x51,0x91,0x10,0x10,0x10,0x11,0x12,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xE3A5 [?] [6209]*/ + 0x10,0x12,0x12,0x12,0x1A,0x56,0x52,0x50,0x90,0x10,0x11,0x10,0x10,0x10,0x13,0x10, + 0x80,0xFC,0xA4,0xA4,0xA8,0x90,0xA8,0xC6,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE3A6 [?] [6210]*/ + 0x20,0x27,0x24,0x24,0x37,0xAC,0xA4,0xA7,0xA0,0x20,0x27,0x20,0x20,0x20,0x2F,0x20, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0x00, + /* 0xE3A7 [?] [6211]*/ + 0x20,0x27,0x24,0x24,0x34,0xAF,0xA4,0xA4,0xA4,0x25,0x26,0x24,0x24,0x24,0x27,0x24, + 0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0xC4,0xE4,0x54,0x44,0x44,0x44,0x04,0xFC,0x04, + /* 0xE3A8 [?] [6212]*/ + 0x10,0x11,0x11,0x11,0x19,0x54,0x53,0x52,0x92,0x12,0x13,0x12,0x12,0x12,0x11,0x10, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x44,0x44,0x44,0xFC,0x00,0x02,0x02,0xFE,0x00, + /* 0xE3A9 [?] [6213]*/ + 0x11,0x10,0x10,0x13,0x18,0x54,0x53,0x52,0x92,0x13,0x10,0x10,0x11,0x12,0x14,0x10, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xE3AA [?] [6214]*/ + 0x10,0x10,0x10,0x11,0x1B,0x54,0x50,0x51,0x92,0x10,0x11,0x12,0x10,0x10,0x11,0x16, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xE3AB [?] [6215]*/ + 0x20,0x27,0x24,0x24,0x35,0xAC,0xA5,0xA4,0xA7,0x24,0x24,0x24,0x24,0x25,0x27,0x20, + 0x00,0xFE,0x20,0x20,0xFC,0x20,0x24,0xA8,0xFE,0x20,0x50,0x48,0x84,0x04,0xFE,0x00, + /* 0xE3AC [?] [6216]*/ + 0x10,0x10,0x13,0x10,0x18,0x57,0x50,0x50,0x93,0x10,0x10,0x17,0x10,0x10,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x88,0x50,0xFE,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE3AD [?] [6217]*/ + 0x10,0x10,0x10,0x17,0x18,0x54,0x50,0x53,0x90,0x10,0x10,0x17,0x10,0x10,0x10,0x10, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xE3AE [?] [6218]*/ + 0x10,0x11,0x10,0x10,0x18,0x57,0x52,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12, + 0x20,0x24,0xA4,0xA8,0x20,0xFE,0x02,0x02,0xFA,0x8A,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE3AF [?] [6219]*/ + 0x10,0x13,0x12,0x12,0x1A,0x57,0x52,0x52,0x93,0x12,0x12,0x12,0x12,0x12,0x12,0x12, + 0x00,0xFE,0x02,0x8A,0x52,0xFE,0x42,0x22,0xFE,0x82,0x82,0x82,0xFA,0x02,0x0A,0x04, + /* 0xE3B0 [?] [6220]*/ + 0x10,0x13,0x12,0x12,0x1A,0x56,0x52,0x53,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x14, + 0x00,0xFE,0x22,0x22,0xFA,0x22,0x22,0xFE,0x02,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE3B1 [?] [6221]*/ + 0x10,0x10,0x10,0x11,0x1A,0x54,0x51,0x52,0x90,0x11,0x10,0x10,0x12,0x12,0x14,0x10, + 0x80,0x80,0xFC,0x54,0x54,0xA4,0x24,0x44,0x94,0x08,0x40,0xA4,0xAA,0x8A,0x78,0x00, + /* 0xE3B2 [?] [6222]*/ + 0x10,0x10,0x13,0x18,0x55,0x51,0x52,0x94,0x10,0x10,0x17,0x10,0x10,0x10,0x10,0x10, + 0x80,0x40,0xFC,0x00,0x10,0x10,0xA8,0x44,0x00,0x40,0xFE,0x40,0x40,0x40,0x40,0x40, + /* 0xE3B3 [?] [6223]*/ + 0x10,0x11,0x11,0x11,0x19,0x55,0x51,0x51,0x90,0x13,0x12,0x12,0x12,0x12,0x17,0x10, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x94,0x94,0x94,0x94,0xFE,0x00, + /* 0xE3B4 [?] [6224]*/ + 0x10,0x10,0x11,0x19,0x55,0x50,0x53,0x90,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x13, + 0x20,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xE3B5 [?] [6225]*/ + 0x20,0x27,0x24,0x24,0x37,0xA8,0xA3,0xA0,0xA7,0x21,0x22,0x23,0x20,0x20,0x20,0x20, + 0x00,0xBC,0xA4,0xA4,0xBC,0x00,0xF8,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xE3B6 [?] [6226]*/ + 0x10,0x13,0x12,0x1A,0x56,0x53,0x50,0x90,0x17,0x10,0x10,0x10,0x11,0x11,0x12,0x14, + 0x00,0xFC,0x94,0x94,0x94,0xFC,0x80,0x40,0xFE,0x80,0xF8,0x88,0x08,0x08,0x28,0x10, + /* 0xE3B7 [?] [6227]*/ + 0x20,0x24,0x24,0x34,0xAF,0xA0,0xAF,0xA0,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x24, + 0x40,0x44,0x44,0x44,0xFC,0x00,0xFE,0x40,0x80,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0x0C, + /* 0xE3B8 [?] [6228]*/ + 0x20,0x21,0x27,0x31,0xA9,0xA1,0xA7,0xA1,0x23,0x23,0x25,0x25,0x29,0x21,0x21,0x21, + 0x88,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xE3B9 [?] [6229]*/ + 0x11,0x11,0x11,0x1A,0x55,0x51,0x51,0x91,0x11,0x10,0x10,0x11,0x12,0x10,0x11,0x16, + 0x00,0x00,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFC,0x08,0x90,0x60,0x98,0x06, + /* 0xE3BA [?] [6230]*/ + 0x10,0x10,0x17,0x10,0x1B,0x54,0x57,0x50,0x91,0x13,0x10,0x17,0x10,0x12,0x15,0x10, + 0x40,0x40,0xFC,0x40,0xF8,0x40,0xFE,0x80,0x10,0xE0,0x48,0xFC,0x44,0x48,0x44,0x80, + /* 0xE3BB [?] [6231]*/ + 0x21,0x20,0x20,0x27,0x30,0xAB,0xA0,0xA7,0xA0,0x23,0x20,0x21,0x22,0x2C,0x20,0x20, + 0x10,0xA0,0x00,0xFE,0xA0,0xF8,0xA8,0xFE,0xA8,0xF8,0xA0,0xB0,0xA8,0xA6,0xA0,0xA0, + /* 0xE3BC [?] [6232]*/ + 0x20,0x27,0x24,0x25,0x34,0xAF,0xA4,0xA5,0xA4,0x25,0x25,0x25,0x25,0x29,0x29,0x31, + 0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x2C, + /* 0xE3BD [?] [6233]*/ + 0x10,0x13,0x12,0x1B,0x56,0x53,0x50,0x97,0x10,0x13,0x12,0x13,0x10,0x12,0x14,0x10, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFE,0x00,0xF8,0x08,0xF8,0x40,0x48,0x44,0xC0, + /* 0xE3BE [?] [6234]*/ + 0x21,0x21,0x23,0x22,0x36,0xAB,0xA2,0xA2,0xA3,0x22,0x22,0x23,0x22,0x25,0x24,0x28, + 0x40,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0x24,0x92,0x92, + /* 0xE3BF [?] [6235]*/ + 0x10,0x11,0x10,0x10,0x1B,0x54,0x51,0x51,0x91,0x11,0x11,0x10,0x11,0x10,0x13,0x10, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE3C0 [?] [6236]*/ + 0x21,0x21,0x27,0x31,0xAB,0xA5,0xA9,0xA0,0x27,0x20,0x22,0x22,0x22,0x25,0x28,0x30, + 0x10,0x10,0xBC,0x10,0xB8,0x54,0x12,0x00,0xFC,0x44,0x40,0x78,0x40,0x40,0xFE,0x00, + /* 0xE3C1 [?] [6237]*/ + 0x20,0x2F,0x20,0x37,0xAC,0xA5,0xA5,0xA5,0x24,0x27,0x20,0x23,0x20,0x2F,0x22,0x24, + 0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xF4,0x04,0xFC,0x00,0xF8,0x00,0xFE,0x48,0xC4, + /* 0xE3C2 [?] [6238]*/ + 0x11,0x17,0x11,0x13,0x1A,0x57,0x50,0x57,0x94,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x08,0xFE,0x08,0xFC,0x94,0xFC,0x00,0xFE,0x02,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xE3C3 [?] [6239]*/ + 0x00,0x3F,0x01,0x01,0xFF,0x02,0x04,0x09,0x31,0xC1,0x11,0x11,0x21,0x41,0x05,0x02, + 0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06,0x90,0x48,0x24,0x24,0x00,0x00, + /* 0xE3C4 [?] [6240]*/ + 0x00,0x7B,0x48,0x51,0x4A,0x4D,0x68,0x50,0x41,0x46,0x19,0xE1,0x11,0x21,0x45,0x02, + 0x40,0xFC,0x80,0xF8,0x20,0xFC,0x88,0xF8,0x88,0xC0,0x30,0x0E,0x90,0x48,0x24,0x00, + /* 0xE3C5 [?] [6241]*/ + 0x20,0x17,0x00,0x40,0x40,0x40,0x40,0x5F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xF4,0x04,0x04,0x04,0x04,0x04,0x04,0x14,0x08, + /* 0xE3C6 [?] [6242]*/ + 0x20,0x17,0x00,0x40,0x5F,0x40,0x40,0x40,0x4F,0x40,0x40,0x40,0x5F,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0x04,0xE4,0x04,0x04,0x04,0xF4,0x04,0x14,0x08, + /* 0xE3C7 [?] [6243]*/ + 0x20,0x17,0x01,0x41,0x5F,0x41,0x41,0x4F,0x41,0x41,0x5F,0x41,0x41,0x41,0x41,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x04,0x04,0xF4,0x14,0x14,0x54,0x24,0x0C, + /* 0xE3C8 [?] [6244]*/ + 0x20,0x17,0x02,0x42,0x42,0x5F,0x44,0x44,0x48,0x49,0x51,0x52,0x67,0x42,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x84,0x84,0x04,0x44,0x24,0xF4,0x14,0x14,0x08, + /* 0xE3C9 [?] [6245]*/ + 0x20,0x17,0x00,0x42,0x41,0x5F,0x40,0x44,0x42,0x41,0x42,0x44,0x48,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x44,0x44,0x84,0x04,0x84,0x44,0x44,0x04,0x14,0x08, + /* 0xE3CA [?] [6246]*/ + 0x20,0x17,0x00,0x42,0x41,0x5F,0x40,0x40,0x47,0x44,0x44,0x44,0x48,0x50,0x40,0x40, + 0x00,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0xC4,0x44,0x44,0x54,0x34,0x04,0x14,0x08, + /* 0xE3CB [?] [6247]*/ + 0x20,0x17,0x00,0x48,0x44,0x45,0x40,0x5C,0x44,0x44,0x45,0x4A,0x51,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x44,0x44,0xF4,0x44,0x44,0xA4,0x94,0x14,0x04,0xF4,0x04,0x14,0x08, + /* 0xE3CC [?] [6248]*/ + 0x20,0x17,0x00,0x40,0x47,0x44,0x44,0x47,0x40,0x4F,0x48,0x48,0x4F,0x40,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xC4,0x44,0x44,0xC4,0x04,0xE4,0x24,0x24,0xE4,0x04,0x14,0x08, + /* 0xE3CD [?] [6249]*/ + 0x20,0x17,0x00,0x40,0x5F,0x51,0x51,0x5F,0x51,0x53,0x55,0x59,0x51,0x5F,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xF4,0x14,0x14,0xF4,0x14,0x94,0x54,0x34,0x14,0xF4,0x04,0x0C, + /* 0xE3CE [?] [6250]*/ + 0x20,0x17,0x00,0x44,0x47,0x48,0x51,0x6F,0x49,0x4F,0x49,0x4F,0x41,0x41,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xC4,0x84,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x14,0x14,0xF4,0x0C, + /* 0xE3CF [?] [6251]*/ + 0x20,0x17,0x02,0x41,0x4F,0x48,0x4F,0x48,0x4F,0x49,0x48,0x4A,0x4C,0x48,0x40,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x14,0xA4,0x44,0x24,0x14,0x04,0x0C, + /* 0xE3D0 [?] [6252]*/ + 0x20,0x17,0x00,0x40,0x40,0x5F,0x40,0x4E,0x4A,0x4E,0x40,0x46,0x58,0x41,0x42,0x40, + 0x00,0xFC,0x84,0xA4,0x94,0xF4,0x84,0xA4,0xA4,0xA4,0xC4,0x54,0xB4,0x14,0x04,0x0C, + /* 0xE3D1 [?] [6253]*/ + 0x20,0x17,0x00,0x4F,0x48,0x4F,0x48,0x4F,0x40,0x5F,0x50,0x5F,0x50,0x5F,0x40,0x40, + 0x00,0xFC,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x04,0xF4,0x14,0xF4,0x14,0xF4,0x04,0x0C, + /* 0xE3D2 [?] [6254]*/ + 0x20,0x17,0x00,0x42,0x4C,0x48,0x4E,0x48,0x4F,0x42,0x42,0x44,0x44,0x48,0x50,0x40, + 0x00,0xFC,0x04,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x84,0x84,0x94,0x94,0x74,0x04,0x0C, + /* 0xE3D3 [?] [6255]*/ + 0x20,0x17,0x00,0x40,0x5F,0x4A,0x45,0x5F,0x50,0x47,0x40,0x46,0x41,0x42,0x44,0x48, + 0x00,0xFC,0x04,0xE4,0x04,0x24,0x44,0xF4,0x14,0xC4,0x44,0x84,0x04,0x84,0x44,0x2C, + /* 0xE3D4 [?] [6256]*/ + 0x20,0x17,0x00,0x40,0x5F,0x51,0x5F,0x50,0x5C,0x50,0x4F,0x48,0x4F,0x48,0x4F,0x48, + 0x00,0xFC,0x04,0x64,0x84,0x04,0xF4,0x84,0x54,0x34,0xE4,0x24,0xE4,0x24,0xE4,0x2C, + /* 0xE3D5 [?] [6257]*/ + 0x20,0x17,0x00,0x48,0x44,0x5E,0x48,0x49,0x4E,0x4A,0x4A,0x4A,0x4A,0x52,0x56,0x60, + 0x00,0xFC,0x04,0x44,0x44,0xA4,0xA4,0x14,0x0C,0x44,0x24,0x04,0x84,0x44,0x24,0x0C, + /* 0xE3D6 [?] [6258]*/ + 0x20,0x17,0x00,0x4F,0x48,0x4F,0x48,0x4F,0x48,0x4F,0x41,0x5F,0x41,0x42,0x44,0x48, + 0x00,0xFC,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0xE4,0x44,0xF4,0x04,0x84,0x44,0x2C, + /* 0xE3D7 [?] [6259]*/ + 0x20,0x17,0x00,0x40,0x5E,0x42,0x4A,0x44,0x48,0x57,0x61,0x4F,0x41,0x42,0x44,0x58, + 0x00,0xFC,0x04,0x84,0x94,0xA4,0x4C,0x54,0x24,0xD4,0x0C,0xE4,0x04,0x84,0x44,0x2C, + /* 0xE3D8 [?] [6260]*/ + 0x20,0x13,0x11,0x4F,0x41,0x5F,0x42,0x44,0x4F,0x40,0x4F,0x4A,0x4A,0x5F,0x40,0x40, + 0x00,0xFC,0x04,0xE4,0x04,0xF4,0x04,0x44,0xE4,0x04,0xE4,0xA4,0xA4,0xF4,0x14,0x08, + /* 0xE3D9 [?] [6261]*/ + 0x20,0x17,0x01,0x5F,0x41,0x4F,0x48,0x4F,0x48,0x4F,0x48,0x4F,0x48,0x7F,0x44,0x48, + 0x00,0xFC,0x04,0xF4,0x04,0xE4,0x24,0xE4,0x24,0xE4,0x24,0xE4,0x24,0xFC,0x44,0x2C, + /* 0xE3DA [?] [6262]*/ + 0x20,0x17,0x00,0x51,0x4A,0x5F,0x44,0x55,0x55,0x5F,0x44,0x48,0x49,0x52,0x40,0x40, + 0x00,0xFC,0x04,0x44,0x44,0x74,0x94,0x24,0x44,0x44,0x44,0xA4,0x14,0x04,0x14,0x08, + /* 0xE3DB [?] [6263]*/ + 0x20,0x17,0x00,0x5C,0x44,0x7F,0x52,0x5E,0x52,0x5E,0x53,0x7E,0x42,0x43,0x40,0x40, + 0x00,0xFC,0x04,0x44,0x7C,0x54,0x94,0x14,0x54,0x24,0xA4,0x54,0x94,0x04,0x14,0x08, + /* 0xE3DC [?] [6264]*/ + 0x01,0x01,0x01,0x11,0x09,0x09,0x01,0x03,0x05,0x09,0x31,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE3DD [?] [6265]*/ + 0x00,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,0x7F,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + 0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xE3DE [?] [6266]*/ + 0x04,0x24,0x24,0x24,0x24,0x3C,0x05,0x04,0xFC,0x24,0x24,0x24,0x24,0x44,0x84,0x05, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xE3DF [?] [6267]*/ + 0x00,0x20,0x10,0x10,0x80,0x40,0x48,0x08,0x10,0x10,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE3E0 [?] [6268]*/ + 0x00,0x20,0x11,0x11,0x82,0x44,0x41,0x10,0x10,0x20,0xE0,0x21,0x22,0x22,0x21,0x00, + 0x80,0x80,0x00,0xFE,0x00,0x00,0xF8,0x08,0x10,0x60,0x80,0x00,0x02,0x02,0xFE,0x00, + /* 0xE3E1 [?] [6269]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x4A,0x0B,0x12,0x12,0xE2,0x22,0x22,0x22,0x21,0x00, + 0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xE3E2 [?] [6270]*/ + 0x00,0x27,0x12,0x12,0x82,0x41,0x49,0x09,0x10,0x10,0xE0,0x20,0x20,0x21,0x22,0x0C, + 0x00,0xF8,0x08,0x88,0x48,0x50,0x10,0x10,0xA0,0xA0,0x40,0x40,0xA0,0x10,0x08,0x06, + /* 0xE3E3 [?] [6271]*/ + 0x00,0x20,0x10,0x13,0x80,0x40,0x48,0x09,0x10,0x10,0xE0,0x27,0x20,0x20,0x20,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE3E4 [?] [6272]*/ + 0x00,0x20,0x13,0x10,0x80,0x40,0x47,0x11,0x11,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x00,0x00,0xF8,0x00,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xE3E5 [?] [6273]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x48,0x08,0x11,0x11,0xE2,0x24,0x28,0x20,0x20,0x00, + 0x40,0x40,0x40,0x40,0xFE,0x40,0xE0,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40,0x40, + /* 0xE3E6 [?] [6274]*/ + 0x00,0x27,0x10,0x10,0x82,0x42,0x4A,0x0A,0x12,0x13,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x00,0xFE,0x40,0x40,0x40,0x7C,0x44,0x44,0x44,0xFC,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xE3E7 [?] [6275]*/ + 0x00,0x20,0x10,0x17,0x80,0x42,0x4A,0x0A,0x12,0x13,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xE3E8 [?] [6276]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x4A,0x0B,0x12,0x12,0xE2,0x22,0x22,0x23,0x22,0x00, + 0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xE3E9 [?] [6277]*/ + 0x00,0x20,0x17,0x14,0x84,0x44,0x44,0x17,0x14,0x24,0xE4,0x24,0x24,0x27,0x24,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xF4,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xE3EA [?] [6278]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x48,0x08,0x10,0x10,0xE0,0x20,0x20,0x20,0x20,0x00, + 0x80,0x40,0x40,0x00,0xFE,0x80,0x80,0xC0,0xA0,0x90,0x88,0x88,0x80,0x80,0x80,0x80, + /* 0xE3EB [?] [6279]*/ + 0x00,0x20,0x10,0x17,0x81,0x41,0x49,0x09,0x11,0x10,0xE0,0x20,0x20,0x21,0x22,0x0C, + 0x80,0x40,0x40,0xFC,0x10,0x10,0x10,0x10,0x10,0xA0,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xE3EC [?] [6280]*/ + 0x00,0x20,0x10,0x17,0x80,0x40,0x49,0x09,0x11,0x11,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x80,0x40,0x40,0xFC,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xE3ED [?] [6281]*/ + 0x00,0x22,0x11,0x11,0x80,0x47,0x40,0x10,0x10,0x20,0xE0,0x21,0x21,0x22,0x24,0x08, + 0x40,0x40,0x40,0x40,0x40,0xFC,0x44,0x44,0x84,0xA4,0x94,0x14,0x04,0x04,0x28,0x10, + /* 0xE3EE [?] [6282]*/ + 0x00,0x47,0x24,0x25,0x05,0x86,0x45,0x54,0x14,0x24,0xE6,0x25,0x24,0x24,0x24,0x04, + 0x10,0x90,0x90,0x10,0x7E,0x12,0x12,0x92,0x92,0x92,0x92,0x12,0x22,0x22,0x4A,0x84, + /* 0xE3EF [?] [6283]*/ + 0x01,0x21,0x11,0x11,0x87,0x41,0x41,0x11,0x11,0x21,0xE1,0x21,0x21,0x21,0x21,0x01, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xE3F0 [?] [6284]*/ + 0x00,0x20,0x10,0x10,0x87,0x40,0x40,0x10,0x11,0x21,0xE2,0x24,0x28,0x20,0x20,0x00, + 0x40,0x50,0x48,0x40,0xFC,0x40,0xE0,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40,0x40, + /* 0xE3F1 [?] [6285]*/ + 0x01,0x21,0x11,0x11,0x87,0x41,0x49,0x09,0x11,0x12,0xE2,0x22,0x24,0x24,0x29,0x10, + 0x20,0x10,0x10,0x00,0xFE,0x40,0x40,0x48,0x48,0x50,0x50,0x62,0x42,0xC2,0x3E,0x00, + /* 0xE3F2 [?] [6286]*/ + 0x00,0x20,0x10,0x10,0x80,0x43,0x4A,0x0A,0x12,0x13,0xE2,0x22,0x22,0x24,0x24,0x08, + 0x40,0x40,0x7E,0x40,0x40,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00, + /* 0xE3F3 [?] [6287]*/ + 0x00,0x20,0x10,0x13,0x82,0x42,0x4A,0x0A,0x12,0x17,0xE0,0x20,0x20,0x21,0x22,0x04, + 0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0x48,0xFE,0x40,0xA0,0xA0,0x10,0x08,0x06, + /* 0xE3F4 [?] [6288]*/ + 0x00,0x20,0x17,0x14,0x84,0x44,0x44,0x14,0x14,0x25,0xE5,0x26,0x24,0x24,0x27,0x04, + 0x00,0x00,0xFC,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x24,0x1C,0x04,0x04,0x04,0xFC,0x04, + /* 0xE3F5 [?] [6289]*/ + 0x01,0x21,0x13,0x12,0x84,0x48,0x42,0x12,0x13,0x2E,0xE2,0x22,0x22,0x22,0x21,0x00, + 0x00,0x00,0xFC,0x00,0x40,0x40,0x78,0xC8,0x48,0x48,0x48,0x5A,0x42,0x02,0xFE,0x00, + /* 0xE3F6 [?] [6290]*/ + 0x00,0x20,0x10,0x10,0x81,0x42,0x44,0x10,0x13,0x20,0xE0,0x21,0x20,0x20,0x20,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x48,0x26,0x20,0xF8,0x08,0x10,0x10,0xA0,0x40,0x20,0x20, + /* 0xE3F7 [?] [6291]*/ + 0x00,0x21,0x16,0x14,0x84,0x44,0x44,0x14,0x14,0x25,0xE6,0x24,0x21,0x21,0x22,0x04, + 0x00,0x00,0x3C,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xB4,0xA8,0x20,0x20,0x20,0x20, + /* 0xE3F8 [?] [6292]*/ + 0x00,0x20,0x17,0x14,0x84,0x44,0x44,0x17,0x10,0x20,0xE2,0x22,0x24,0x28,0x21,0x00, + 0x08,0x3C,0xC0,0x00,0x40,0x40,0x40,0xFE,0x40,0x40,0x48,0x44,0x42,0x42,0x40,0x80, + /* 0xE3F9 [?] [6293]*/ + 0x00,0x20,0x10,0x17,0x80,0x40,0x41,0x12,0x17,0x20,0xE0,0x21,0x22,0x27,0x22,0x00, + 0x80,0x40,0x40,0xFE,0x40,0x80,0x08,0x10,0xE0,0x40,0x80,0x08,0x04,0xFE,0x02,0x00, + /* 0xE3FA [?] [6294]*/ + 0x00,0x20,0x12,0x11,0x81,0x40,0x4B,0x08,0x10,0x10,0xE7,0x20,0x20,0x20,0x20,0x00, + 0x40,0x40,0x48,0x48,0x50,0x40,0xF8,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x40, + /* 0xE3FB [?] [6295]*/ + 0x00,0x20,0x10,0x17,0x84,0x48,0x42,0x12,0x12,0x22,0xE3,0x22,0x22,0x22,0x21,0x00, + 0x80,0x40,0x40,0xFC,0x04,0x08,0x00,0x10,0x20,0x40,0x80,0x04,0x04,0x04,0xFC,0x00, + /* 0xE3FC [?] [6296]*/ + 0x00,0x27,0x10,0x10,0x80,0x47,0x44,0x14,0x14,0x27,0xE0,0x20,0x20,0x20,0x25,0x02, + 0x08,0x88,0x88,0x88,0x88,0x88,0x08,0x10,0x10,0x90,0x94,0xA4,0xA2,0xBE,0x02,0x00, + /* 0xE3FD [?] [6297]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x4A,0x0A,0x13,0x12,0xE2,0x22,0x22,0x22,0x23,0x02, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x8A,0x06,0x02, + /* 0xE3FE [?] [6298]*/ + 0x00,0x27,0x10,0x10,0x80,0x40,0x41,0x16,0x10,0x23,0xE0,0x20,0x20,0x20,0x27,0x00, + 0x00,0xF8,0x10,0x20,0x60,0x98,0x04,0x02,0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x00, + /* 0xE4A1 [?] [6299]*/ + 0x00,0x27,0x10,0x10,0x83,0x42,0x42,0x13,0x12,0x22,0xE3,0x22,0x20,0x20,0x2F,0x00, + 0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x00,0x00,0xFE,0x00, + /* 0xE4A2 [?] [6300]*/ + 0x00,0x20,0x17,0x10,0x81,0x41,0x43,0x15,0x19,0x21,0xE1,0x21,0x21,0x21,0x21,0x01, + 0x40,0x40,0xFE,0x80,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xE4A3 [?] [6301]*/ + 0x00,0x40,0x2F,0x22,0x02,0x83,0x42,0x54,0x16,0x25,0xE8,0x20,0x21,0x22,0x24,0x08, + 0x02,0x02,0xC2,0x12,0x12,0xD2,0x52,0x52,0x52,0x52,0x92,0x92,0x02,0x02,0x0A,0x04, + /* 0xE4A4 [?] [6302]*/ + 0x00,0x20,0x10,0x17,0x80,0x42,0x51,0x10,0x1F,0x20,0xE0,0x21,0x21,0x22,0x24,0x08, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x50,0x40,0xFE,0xA0,0xA0,0x10,0x10,0x08,0x04,0x02, + /* 0xE4A5 [?] [6303]*/ + 0x00,0x20,0x10,0x10,0x80,0x43,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x20,0x21,0x22,0x04, + 0x40,0x40,0x7E,0x40,0x40,0xF8,0x08,0x48,0x48,0x48,0x48,0x48,0xA0,0x10,0x08,0x04, + /* 0xE4A6 [?] [6304]*/ + 0x00,0x27,0x14,0x14,0x84,0x44,0x47,0x14,0x14,0x24,0xE4,0x25,0x26,0x24,0x27,0x04, + 0x00,0xFC,0x04,0x44,0x44,0x44,0xFC,0x44,0x44,0xA4,0x94,0x14,0x04,0x04,0xFC,0x04, + /* 0xE4A7 [?] [6305]*/ + 0x00,0x27,0x14,0x14,0x84,0x44,0x44,0x14,0x14,0x24,0xE4,0x24,0x24,0x24,0x27,0x04, + 0x00,0xFE,0x02,0x02,0xF2,0x92,0x92,0x92,0x92,0x92,0xF2,0x92,0x02,0x02,0xFE,0x02, + /* 0xE4A8 [?] [6306]*/ + 0x00,0x22,0x12,0x13,0x84,0x40,0x40,0x17,0x10,0x21,0xE1,0x22,0x24,0x28,0x20,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40, + /* 0xE4A9 [?] [6307]*/ + 0x00,0x20,0x13,0x12,0x82,0x42,0x4B,0x0A,0x12,0x12,0xE3,0x22,0x22,0x22,0x23,0x02, + 0x40,0x80,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE4AA [?] [6308]*/ + 0x00,0x20,0x10,0x11,0x83,0x42,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x22,0x22,0x2F,0x00, + 0x40,0x40,0x80,0x00,0xFC,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0xFE,0x00, + /* 0xE4AB [?] [6309]*/ + 0x00,0x20,0x10,0x11,0x82,0x44,0x41,0x10,0x10,0x27,0xE0,0x20,0x21,0x22,0x27,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x00,0x00,0xFC,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xE4AC [?] [6310]*/ + 0x00,0x20,0x10,0x14,0x82,0x40,0x40,0x11,0x12,0x24,0xE0,0x20,0x21,0x21,0x22,0x04, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xE4AD [?] [6311]*/ + 0x00,0x20,0x11,0x11,0x82,0x44,0x43,0x12,0x12,0x23,0xE2,0x22,0x23,0x20,0x20,0x00, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10, + /* 0xE4AE [?] [6312]*/ + 0x01,0x21,0x11,0x13,0x84,0x40,0x51,0x16,0x10,0x23,0xE0,0x24,0x27,0x20,0x20,0x00, + 0x00,0x00,0xF8,0x10,0xA0,0x40,0xB0,0x4E,0x40,0xFC,0x40,0x40,0xFE,0x40,0x40,0x40, + /* 0xE4AF [?] [6313]*/ + 0x02,0x41,0x21,0x2F,0x00,0x84,0x42,0x52,0x11,0x21,0xE2,0x22,0x24,0x28,0x30,0x00, + 0x04,0x04,0x04,0xE4,0x94,0x94,0x94,0x94,0x14,0x14,0x94,0x94,0x44,0x44,0x14,0x08, + /* 0xE4B0 [?] [6314]*/ + 0x00,0x44,0x22,0x22,0x00,0x80,0x4E,0x52,0x12,0x22,0xE2,0x22,0x23,0x22,0x20,0x00, + 0x40,0x40,0x40,0x7C,0x50,0x90,0x10,0x10,0xFE,0x10,0x10,0x90,0x10,0x10,0x10,0x10, + /* 0xE4B1 [?] [6315]*/ + 0x00,0x27,0x10,0x10,0x83,0x40,0x40,0x17,0x10,0x20,0xEF,0x22,0x21,0x21,0x20,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x10,0x10,0xFE,0x10,0x10,0x10,0x50,0x20, + /* 0xE4B2 [?] [6316]*/ + 0x01,0x21,0x11,0x11,0x87,0x42,0x42,0x12,0x12,0x24,0xE2,0x21,0x22,0x22,0x24,0x08, + 0x00,0x00,0x00,0x1E,0xD2,0x52,0x52,0x52,0x52,0x92,0x92,0x12,0x92,0x5E,0x52,0x00, + /* 0xE4B3 [?] [6317]*/ + 0x00,0x40,0x2F,0x20,0x00,0x87,0x44,0x54,0x17,0x20,0xE0,0x21,0x22,0x2C,0x20,0x00, + 0x40,0x40,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xE4B4 [?] [6318]*/ + 0x00,0x27,0x10,0x10,0x83,0x40,0x40,0x17,0x10,0x20,0xE3,0x22,0x22,0x22,0x23,0x02, + 0x00,0xFC,0x40,0x40,0xF8,0x88,0x88,0xFE,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xE4B5 [?] [6319]*/ + 0x00,0x20,0x10,0x17,0x80,0x42,0x41,0x11,0x17,0x20,0xE1,0x21,0x22,0x24,0x28,0x00, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x50,0xFE,0xE0,0x50,0x50,0x48,0x44,0x42,0x40, + /* 0xE4B6 [?] [6320]*/ + 0x00,0x27,0x14,0x14,0x85,0x44,0x44,0x14,0x15,0x24,0xE4,0x24,0x24,0x24,0x27,0x04, + 0x00,0xFC,0x44,0x44,0xF4,0x44,0xE4,0x44,0xF4,0x54,0x54,0x74,0x44,0x44,0xFC,0x04, + /* 0xE4B7 [?] [6321]*/ + 0x00,0x23,0x12,0x12,0x82,0x42,0x43,0x10,0x10,0x22,0xE2,0x22,0x22,0x25,0x28,0x10, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x00, + /* 0xE4B8 [?] [6322]*/ + 0x00,0x21,0x11,0x11,0x81,0x40,0x4B,0x0A,0x12,0x13,0xE2,0x22,0x23,0x22,0x22,0x02, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x14,0x08, + /* 0xE4B9 [?] [6323]*/ + 0x00,0x22,0x12,0x12,0x83,0x40,0x48,0x09,0x12,0x14,0xE0,0x23,0x20,0x20,0x20,0x00, + 0x40,0x48,0x48,0x48,0xF8,0x40,0xA0,0x10,0x88,0x46,0x40,0xF0,0x10,0x20,0x20,0x40, + /* 0xE4BA [?] [6324]*/ + 0x00,0x20,0x13,0x12,0x82,0x43,0x42,0x12,0x12,0x22,0xEF,0x20,0x21,0x22,0x24,0x08, + 0x10,0x38,0xC0,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00,0x20,0x10,0x08,0x04, + /* 0xE4BB [?] [6325]*/ + 0x02,0x21,0x10,0x11,0x82,0x40,0x4F,0x11,0x12,0x27,0xEA,0x22,0x22,0x22,0x20,0x00, + 0x08,0x10,0xE0,0x10,0x08,0x80,0xFE,0x40,0x40,0xFC,0x44,0x44,0x54,0x48,0x40,0x40, + /* 0xE4BC [?] [6326]*/ + 0x01,0x21,0x11,0x12,0x82,0x47,0x4A,0x12,0x12,0x23,0xE2,0x20,0x21,0x22,0x24,0x08, + 0x00,0x00,0xF0,0x10,0x20,0xFC,0x44,0x44,0x44,0xFC,0xA4,0xA0,0x20,0x22,0x22,0x1E, + /* 0xE4BD [?] [6327]*/ + 0x00,0x20,0x17,0x14,0x88,0x43,0x40,0x10,0x17,0x21,0xE1,0x21,0x22,0x22,0x24,0x08, + 0x80,0x40,0xFC,0x04,0x08,0xF0,0x00,0x00,0xFC,0x20,0x20,0x20,0x24,0x24,0x1C,0x00, + /* 0xE4BE [?] [6328]*/ + 0x00,0x20,0x17,0x10,0x80,0x4F,0x40,0x11,0x13,0x26,0xEA,0x23,0x22,0x22,0x23,0x02, + 0x80,0x88,0xE8,0x90,0xA0,0xFE,0x80,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE4BF [?] [6329]*/ + 0x01,0x21,0x17,0x11,0x81,0x41,0x49,0x09,0x11,0x11,0xE1,0x27,0x20,0x20,0x21,0x02, + 0x08,0x08,0xFE,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00,0x90,0x08,0x04, + /* 0xE4C0 [?] [6330]*/ + 0x02,0x42,0x22,0x22,0x0F,0x82,0x42,0x56,0x17,0x2A,0xEA,0x32,0x22,0x22,0x22,0x02, + 0x00,0x0C,0x70,0x40,0x40,0x40,0x7E,0x48,0x48,0xC8,0x48,0x48,0x48,0x48,0x48,0x88, + /* 0xE4C1 [?] [6331]*/ + 0x02,0x42,0x22,0x22,0x0F,0x82,0x42,0x56,0x17,0x2A,0xEA,0x32,0x22,0x22,0x22,0x02, + 0x08,0x28,0x28,0x28,0xA4,0x44,0x54,0x92,0x10,0xA0,0x20,0x28,0x44,0xFC,0x44,0x00, + /* 0xE4C2 [?] [6332]*/ + 0x00,0x20,0x13,0x10,0x80,0x47,0x40,0x11,0x10,0x22,0xE1,0x27,0x20,0x20,0x21,0x06, + 0x40,0x40,0xF8,0x40,0x40,0xFC,0x04,0x28,0xA0,0x20,0x20,0xFC,0x50,0x88,0x04,0x04, + /* 0xE4C3 [?] [6333]*/ + 0x00,0x4F,0x20,0x21,0x02,0x84,0x4A,0x41,0x12,0x24,0xE8,0x21,0x22,0x24,0x20,0x00, + 0x00,0xFE,0x80,0x84,0x44,0x68,0xB0,0x30,0xA8,0x68,0xA4,0x24,0x22,0x20,0xA0,0x40, + /* 0xE4C4 [?] [6334]*/ + 0x00,0x27,0x14,0x14,0x87,0x44,0x44,0x17,0x10,0x20,0xEF,0x22,0x22,0x22,0x24,0x08, + 0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x00,0x00,0xFE,0x08,0x08,0x08,0x08,0x08, + /* 0xE4C5 [?] [6335]*/ + 0x00,0x23,0x12,0x12,0x83,0x40,0x47,0x14,0x14,0x27,0xE4,0x24,0x27,0x20,0x20,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x42,0x42,0x3E, + /* 0xE4C6 [?] [6336]*/ + 0x00,0x20,0x10,0x11,0x82,0x44,0x41,0x10,0x10,0x23,0xE0,0x22,0x21,0x21,0x2F,0x00, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF0,0x40,0x40,0xF8,0x40,0x48,0x48,0x50,0xFE,0x00, + /* 0xE4C7 [?] [6337]*/ + 0x00,0x27,0x14,0x14,0x84,0x47,0x44,0x14,0x14,0x27,0xE4,0x24,0x24,0x28,0x2A,0x11, + 0x00,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xBE,0xA0,0xA0,0xA0,0xA2,0xA2,0xA2,0x1E, + /* 0xE4C8 [?] [6338]*/ + 0x00,0x40,0x27,0x24,0x08,0x83,0x40,0x50,0x17,0x20,0xE2,0x22,0x24,0x28,0x21,0x00, + 0x80,0x40,0xFE,0x02,0x04,0xF0,0x00,0x00,0xFC,0x40,0x50,0x48,0x44,0x44,0x40,0x80, + /* 0xE4C9 [?] [6339]*/ + 0x00,0x20,0x17,0x14,0x80,0x43,0x42,0x12,0x13,0x22,0xE2,0x23,0x22,0x20,0x20,0x00, + 0x80,0x40,0xFC,0x44,0x40,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x48,0x40,0x40,0x40, + /* 0xE4CA [?] [6340]*/ + 0x00,0x40,0x27,0x24,0x08,0x83,0x42,0x52,0x13,0x22,0xE2,0x23,0x22,0x22,0x23,0x02, + 0x80,0x40,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xE4CB [?] [6341]*/ + 0x00,0x23,0x10,0x10,0x83,0x40,0x40,0x17,0x10,0x24,0xE2,0x21,0x22,0x24,0x21,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x40,0x44,0xE8,0x50,0x48,0x46,0x40,0x80, + /* 0xE4CC [?] [6342]*/ + 0x00,0x47,0x24,0x24,0x07,0x84,0x44,0x54,0x17,0x26,0xE6,0x2A,0x2A,0x32,0x20,0x00, + 0x02,0xE2,0x22,0x2A,0xEA,0x8A,0x8A,0x8A,0xEA,0xAA,0xAA,0xAA,0xA2,0xE2,0x8A,0x84, + /* 0xE4CD [?] [6343]*/ + 0x00,0x22,0x12,0x17,0x82,0x42,0x42,0x12,0x13,0x20,0xE7,0x20,0x21,0x22,0x2C,0x00, + 0x90,0x90,0x90,0xFE,0x90,0x90,0xF0,0x00,0xFC,0x40,0xFE,0xE0,0x50,0x48,0x46,0x40, + /* 0xE4CE [?] [6344]*/ + 0x00,0x27,0x10,0x10,0x87,0x44,0x44,0x14,0x17,0x20,0xE0,0x27,0x20,0x20,0x2F,0x00, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xA4,0xFC,0x40,0x40,0xFC,0x40,0x40,0xFE,0x00, + /* 0xE4CF [?] [6345]*/ + 0x00,0x27,0x10,0x10,0x87,0x44,0x44,0x14,0x14,0x24,0xE4,0x24,0x24,0x24,0x27,0x04, + 0x00,0xFE,0x40,0x80,0xFE,0x92,0x92,0xF2,0x92,0x92,0xF2,0x92,0x92,0x92,0xFE,0x02, + /* 0xE4D0 [?] [6346]*/ + 0x43,0x2E,0x22,0x82,0x42,0x4F,0x02,0x26,0x27,0x4A,0xCA,0x52,0x42,0x42,0x42,0x03, + 0x90,0x10,0x10,0x12,0x52,0xD4,0x58,0x90,0x10,0xA8,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xE4D1 [?] [6347]*/ + 0x00,0x21,0x16,0x14,0x84,0x47,0x44,0x14,0x17,0x20,0xE7,0x21,0x20,0x20,0x23,0x1C, + 0x40,0x40,0x5C,0x44,0x44,0x5C,0x44,0x44,0xFC,0x40,0xF8,0x10,0xA0,0x60,0x98,0x06, + /* 0xE4D2 [?] [6348]*/ + 0x00,0x20,0x13,0x12,0x83,0x42,0x4B,0x08,0x17,0x10,0xE0,0x23,0x20,0x20,0x27,0x00, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x40,0x40,0xF8,0x40,0x40,0xFC,0x00, + /* 0xE4D3 [?] [6349]*/ + 0x42,0x22,0x25,0x84,0x48,0x57,0x02,0x22,0x2F,0x42,0xCB,0x4A,0x52,0x42,0x4A,0x04, + 0x00,0x00,0x7C,0xA4,0x24,0x24,0x24,0x28,0xA8,0x28,0x10,0x90,0xA8,0x28,0x44,0x82, + /* 0xE4D4 [?] [6350]*/ + 0x00,0x21,0x11,0x12,0x85,0x40,0x41,0x12,0x14,0x23,0xE2,0x22,0x22,0x22,0x2F,0x00, + 0x10,0x10,0x08,0x04,0xFA,0x88,0x08,0x28,0x10,0xF8,0xA8,0xA8,0xA8,0xA8,0xFE,0x00, + /* 0xE4D5 [?] [6351]*/ + 0x02,0x41,0x21,0x2F,0x00,0x87,0x44,0x54,0x17,0x24,0xE4,0x27,0x24,0x24,0x25,0x04, + 0x08,0x08,0x10,0xFE,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x54,0x44,0x54,0x88, + /* 0xE4D6 [?] [6352]*/ + 0x00,0x40,0x27,0x24,0x08,0x83,0x40,0x53,0x12,0x23,0xE2,0x23,0x22,0x20,0x27,0x00, + 0x80,0x40,0xFC,0x04,0x08,0xF8,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x00,0xFC,0x00, + /* 0xE4D7 [?] [6353]*/ + 0x00,0x23,0x12,0x12,0x83,0x42,0x4B,0x0A,0x12,0x13,0xE2,0x22,0x25,0x24,0x28,0x13, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0xFC,0x40,0x88,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE, + /* 0xE4D8 [?] [6354]*/ + 0x00,0x23,0x12,0x12,0x83,0x42,0x4A,0x0A,0x12,0x12,0xE2,0x22,0x24,0x24,0x28,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x00,0xFC,0x84,0x84,0xFC,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xE4D9 [?] [6355]*/ + 0x04,0x84,0x44,0x1F,0x84,0x44,0x44,0x1E,0x24,0x44,0xC4,0x5F,0x44,0x44,0x44,0x04, + 0x20,0x20,0x78,0x48,0x90,0x7C,0x54,0x54,0x54,0x7C,0x40,0x40,0x42,0x42,0x3E,0x00, + /* 0xE4DA [?] [6356]*/ + 0x00,0x20,0x17,0x10,0x83,0x40,0x47,0x11,0x12,0x25,0xE0,0x23,0x20,0x21,0x26,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x68,0xC6,0x40,0xF8,0xE0,0x58,0x44,0x40, + /* 0xE4DB [?] [6357]*/ + 0x00,0x20,0x13,0x10,0x80,0x4F,0x40,0x11,0x13,0x20,0xE7,0x24,0x24,0x24,0x2F,0x00, + 0x40,0x40,0xFC,0x40,0x40,0xFE,0x80,0x10,0xF8,0x08,0xFC,0xA4,0xA4,0xA4,0xFE,0x00, + /* 0xE4DC [?] [6358]*/ + 0x00,0x23,0x11,0x11,0x81,0x41,0x41,0x17,0x10,0x27,0xE0,0x22,0x21,0x22,0x24,0x08, + 0x00,0xFC,0x08,0xF8,0x08,0xF8,0x0E,0xF8,0x08,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xE4DD [?] [6359]*/ + 0x01,0x21,0x17,0x11,0x80,0x47,0x40,0x11,0x12,0x25,0xE1,0x27,0x21,0x21,0x22,0x04, + 0x10,0x10,0xFC,0x10,0x48,0xFC,0xA0,0x10,0x08,0x14,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xE4DE [?] [6360]*/ + 0x01,0x21,0x17,0x11,0x80,0x4F,0x48,0x10,0x17,0x20,0xE0,0x23,0x20,0x20,0x2F,0x00, + 0x10,0x10,0xFE,0x10,0x00,0xFE,0x02,0x00,0xFC,0x40,0x40,0xF8,0x50,0x48,0xFE,0x00, + /* 0xE4DF [?] [6361]*/ + 0x00,0x40,0x2F,0x20,0x07,0x84,0x47,0x54,0x17,0x24,0xE0,0x2F,0x22,0x21,0x21,0x00, + 0x50,0x48,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x08,0xFE,0x08,0x08,0x28,0x10, + /* 0xE4E0 [?] [6362]*/ + 0x00,0x27,0x10,0x10,0x87,0x44,0x44,0x17,0x10,0x20,0xE7,0x20,0x21,0x22,0x2C,0x00, + 0x00,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xFC,0x40,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xE4E1 [?] [6363]*/ + 0x00,0x23,0x12,0x12,0x82,0x43,0x4A,0x0A,0x12,0x12,0xE2,0x23,0x22,0x24,0x24,0x08, + 0x00,0xFE,0x00,0xFC,0x00,0xFE,0xA8,0x90,0xC8,0x86,0x08,0xFE,0x88,0x48,0x08,0x18, + /* 0xE4E2 [?] [6364]*/ + 0x00,0x23,0x12,0x13,0x82,0x43,0x40,0x17,0x10,0x24,0xE2,0x21,0x26,0x20,0x22,0x01, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xBC,0x84,0xA4,0x94,0x8C,0xB4,0x84,0x94,0x08, + /* 0xE4E3 [?] [6365]*/ + 0x00,0x27,0x14,0x15,0x84,0x44,0x45,0x14,0x14,0x25,0xE4,0x24,0x25,0x24,0x27,0x04, + 0x00,0xFE,0x02,0xFA,0x42,0xC2,0x2A,0x6A,0xB2,0x2A,0x6A,0xAA,0x22,0x42,0xFE,0x02, + /* 0xE4E4 [?] [6366]*/ + 0x02,0x22,0x13,0x15,0x88,0x40,0x47,0x10,0x10,0x27,0xE0,0x20,0x2F,0x20,0x20,0x00, + 0x10,0x10,0xDE,0x28,0x84,0x78,0x80,0x80,0xF8,0x80,0x80,0xF8,0x84,0x84,0x84,0x7C, + /* 0xE4E5 [?] [6367]*/ + 0x00,0x20,0x13,0x12,0x83,0x42,0x43,0x12,0x13,0x20,0xE0,0x27,0x20,0x21,0x22,0x0C, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x50,0x48,0xFE,0xA0,0x10,0x08,0x06, + /* 0xE4E6 [?] [6368]*/ + 0x01,0x42,0x25,0x20,0x00,0x83,0x4C,0x53,0x10,0x20,0xE7,0x20,0x22,0x21,0x2F,0x00, + 0x10,0x08,0x14,0xA0,0xE0,0x18,0x06,0xF8,0x40,0x40,0xFC,0x40,0x48,0x50,0xFE,0x00, + /* 0xE4E7 [?] [6369]*/ + 0x00,0x20,0x17,0x14,0x85,0x44,0x47,0x14,0x15,0x24,0xE5,0x25,0x25,0x29,0x29,0x11, + 0x40,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE4E8 [?] [6370]*/ + 0x00,0x40,0x27,0x22,0x01,0x8F,0x48,0x50,0x17,0x21,0xE1,0x21,0x21,0x22,0x22,0x04, + 0x80,0x40,0xFC,0x10,0x20,0xFE,0x82,0x44,0xFC,0x00,0x00,0xF8,0x08,0x08,0x28,0x10, + /* 0xE4E9 [?] [6371]*/ + 0x00,0x27,0x14,0x10,0x83,0x42,0x4B,0x0A,0x13,0x10,0xE0,0x27,0x20,0x21,0x22,0x04, + 0x00,0xFC,0x04,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x80,0x40,0xFC,0x00,0x10,0x08,0x04, + /* 0xE4EA [?] [6372]*/ + 0x01,0x21,0x17,0x11,0x81,0x4F,0x40,0x17,0x14,0x27,0xE4,0x27,0x20,0x21,0x22,0x04, + 0x10,0x10,0xFC,0x10,0x10,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x00,0x10,0x08,0x04, + /* 0xE4EB [?] [6373]*/ + 0x01,0x4F,0x21,0x20,0x0F,0x88,0x51,0x43,0x10,0x20,0xE7,0x20,0x22,0x24,0x29,0x00, + 0x10,0xFE,0x10,0x00,0xFE,0x82,0x14,0xE0,0x40,0x88,0xFC,0x44,0x50,0x48,0x44,0x80, + /* 0xE4EC [?] [6374]*/ + 0x01,0x41,0x2F,0x21,0x00,0x87,0x40,0x5F,0x10,0x27,0xE0,0x25,0x25,0x26,0x28,0x10, + 0x10,0x10,0xFE,0x10,0x40,0xFC,0x44,0xFE,0x44,0xFC,0x40,0x64,0x54,0x54,0x44,0x44, + /* 0xE4ED [?] [6375]*/ + 0x01,0x41,0x27,0x21,0x03,0x85,0x49,0x40,0x10,0x2F,0xE1,0x22,0x21,0x20,0x23,0x0C, + 0x10,0x10,0xBC,0x10,0xB8,0x54,0x12,0x80,0x80,0xFC,0x10,0x10,0x20,0xC0,0x30,0x08, + /* 0xE4EE [?] [6376]*/ + 0x00,0x20,0x17,0x10,0x87,0x44,0x47,0x14,0x17,0x20,0xE3,0x22,0x23,0x22,0x23,0x02, + 0xA0,0xA0,0xFE,0xA0,0xFC,0xA4,0xFC,0xA4,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xE4EF [?] [6377]*/ + 0x00,0x20,0x10,0x17,0x84,0x44,0x45,0x14,0x14,0x24,0xE5,0x24,0x27,0x28,0x28,0x10, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x08,0xF0,0x24,0xA8,0xFE,0x20,0xA0,0x40, + /* 0xE4F0 [?] [6378]*/ + 0x00,0x27,0x14,0x17,0x84,0x47,0x41,0x12,0x17,0x20,0xE3,0x2F,0x20,0x22,0x25,0x08, + 0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0x10,0xE0,0xC8,0x04,0xFE,0x42,0x48,0x44,0x82, + /* 0xE4F1 [?] [6379]*/ + 0x00,0x20,0x13,0x12,0x83,0x40,0x47,0x14,0x17,0x20,0xE0,0x20,0x25,0x25,0x28,0x00, + 0x40,0x40,0xF8,0x48,0xF8,0x40,0xFC,0x44,0xFC,0x40,0x80,0x48,0x44,0x14,0xF0,0x00, + /* 0xE4F2 [?] [6380]*/ + 0x42,0x22,0x25,0x84,0x48,0x57,0x00,0x24,0x32,0x4A,0xC8,0x41,0x43,0x5C,0x40,0x00, + 0x10,0x10,0x10,0xA0,0x3E,0x44,0x24,0xA4,0xA4,0xA8,0xA8,0x10,0xA8,0x28,0x44,0x82, + /* 0xE4F3 [?] [6381]*/ + 0x00,0x49,0x25,0x22,0x06,0x8B,0x42,0x52,0x16,0x2B,0xE2,0x22,0x22,0x22,0x2A,0x04, + 0x20,0x20,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xE4F4 [?] [6382]*/ + 0x00,0x49,0x25,0x22,0x06,0x8A,0x43,0x52,0x16,0x2A,0xE2,0x22,0x22,0x22,0x2A,0x04, + 0x20,0x20,0xFC,0x20,0x50,0x88,0xFE,0x08,0xE8,0xA8,0xA8,0xE8,0xA8,0x08,0x28,0x10, + /* 0xE4F5 [?] [6383]*/ + 0x00,0x20,0x17,0x14,0x84,0x47,0x44,0x14,0x17,0x24,0xE5,0x25,0x25,0x29,0x29,0x11, + 0x80,0x40,0xFC,0xA0,0xA0,0xFC,0xA4,0xA4,0xFC,0x00,0x24,0xA8,0x30,0x24,0xA4,0x1C, + /* 0xE4F6 [?] [6384]*/ + 0x04,0x42,0x22,0x2F,0x04,0x84,0x47,0x55,0x15,0x25,0xE5,0x25,0x29,0x2B,0x30,0x21, + 0x20,0x20,0x20,0x7E,0x80,0x00,0x7C,0x14,0x10,0x50,0x5C,0x50,0x50,0x50,0xBE,0x00, + /* 0xE4F7 [?] [6385]*/ + 0x00,0x47,0x20,0x21,0x0F,0x84,0x44,0x57,0x14,0x27,0xE4,0x24,0x27,0x2C,0x20,0x00, + 0x08,0x88,0x88,0x10,0xDE,0x94,0xA4,0x94,0x94,0x94,0x94,0xC8,0x88,0x94,0xA4,0xC2, + /* 0xE4F8 [?] [6386]*/ + 0x01,0x41,0x2F,0x21,0x01,0x87,0x40,0x57,0x14,0x24,0xE7,0x24,0x22,0x20,0x2F,0x04, + 0x04,0x04,0xE4,0x04,0x3E,0xC4,0x04,0xE4,0x54,0x54,0xC4,0x44,0x84,0xE4,0x14,0x08, + /* 0xE4F9 [?] [6387]*/ + 0x04,0x44,0x24,0x2F,0x04,0x87,0x44,0x57,0x14,0x24,0xEF,0x20,0x25,0x28,0x30,0x00, + 0x80,0x82,0x9C,0xD0,0x90,0x90,0x9E,0x94,0x94,0x94,0xD4,0x14,0x14,0xA4,0x24,0x44, + /* 0xE4FA [?] [6388]*/ + 0x04,0x84,0x5F,0x04,0x95,0x55,0x65,0x00,0x2F,0x48,0xCF,0x48,0x4F,0x48,0x48,0x08, + 0x20,0x20,0xFC,0x20,0x68,0xAA,0x26,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xE4FB [?] [6389]*/ + 0x01,0x4E,0x22,0x22,0x02,0x8F,0x42,0x53,0x16,0x26,0xEA,0x22,0x22,0x22,0x22,0x02, + 0x10,0x10,0x54,0x38,0x10,0x7C,0x44,0x44,0xFC,0x44,0x44,0x7C,0x44,0x44,0x54,0x48, + /* 0xE4FC [?] [6390]*/ + 0x00,0x23,0x11,0x10,0x87,0x40,0x4B,0x0A,0x13,0x12,0xE3,0x20,0x23,0x20,0x27,0x00, + 0x40,0xF8,0x10,0xA0,0xFC,0x00,0xF8,0x48,0xF8,0x48,0xF8,0x40,0xF8,0x40,0xFE,0x00, + /* 0xE4FD [?] [6391]*/ + 0x07,0x24,0x17,0x14,0x85,0x44,0x47,0x14,0x14,0x27,0xE4,0x25,0x29,0x2F,0x31,0x03, + 0xFC,0x04,0xFC,0x00,0xF8,0x10,0xFE,0x20,0x60,0x9C,0x84,0x08,0xDE,0x08,0x08,0x18, + /* 0xE4FE [?] [6392]*/ + 0x02,0x42,0x2F,0x22,0x02,0x8F,0x4A,0x5A,0x1F,0x22,0xE7,0x2A,0x32,0x22,0x22,0x02, + 0x10,0x10,0x9C,0x24,0x48,0xBE,0xA2,0xAA,0xAA,0x2A,0x2A,0xAA,0x88,0x14,0x22,0x42, + /* 0xE5A1 [?] [6393]*/ + 0x00,0x40,0x2F,0x29,0x09,0x8F,0x49,0x59,0x1F,0x29,0xE9,0x29,0x2F,0x29,0x20,0x00, + 0x28,0x24,0x40,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x48,0x7E,0x40,0x40, + /* 0xE5A2 [?] [6394]*/ + 0x00,0x20,0x17,0x14,0x87,0x44,0x47,0x10,0x17,0x20,0xE3,0x22,0x23,0x21,0x20,0x0F, + 0xA0,0xA0,0xFC,0xA4,0xFC,0xA4,0xFC,0x00,0xFC,0x00,0xF8,0x08,0xF8,0x10,0xA0,0xFE, + /* 0xE5A3 [?] [6395]*/ + 0x02,0x43,0x24,0x27,0x0D,0x96,0x47,0x54,0x15,0x24,0xE5,0x24,0x25,0x29,0x29,0x11, + 0x00,0xF8,0x10,0xFE,0x48,0x24,0xFE,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x04,0xFC,0x04, + /* 0xE5A4 [?] [6396]*/ + 0x00,0x4F,0x20,0x27,0x04,0x85,0x45,0x57,0x10,0x23,0xE2,0x23,0x22,0x23,0x20,0x0F, + 0x40,0xFE,0x00,0xFC,0x04,0xF4,0x14,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xE5A5 [?] [6397]*/ + 0x00,0x27,0x15,0x14,0x87,0x44,0x45,0x14,0x17,0x24,0xE5,0x24,0x24,0x29,0x2A,0x10, + 0x20,0xFE,0x08,0x90,0xFC,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50, + /* 0xE5A6 [?] [6398]*/ + 0x00,0x47,0x20,0x2F,0x08,0x83,0x40,0x53,0x10,0x2F,0xE0,0x27,0x24,0x24,0x24,0x04, + 0x00,0xFC,0x40,0xFE,0x42,0x58,0x40,0x58,0x00,0xFE,0x40,0xFC,0xA4,0xA4,0xA4,0x0C, + /* 0xE5A7 [?] [6399]*/ + 0x01,0x21,0x11,0x12,0x82,0x46,0x56,0x1A,0x12,0x22,0xE2,0x22,0x22,0x22,0x22,0x02, + 0x28,0xAA,0x6C,0x28,0xFE,0x44,0x28,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x28,0x44,0x82, + /* 0xE5A8 [?] [6400]*/ + 0x00,0x23,0x12,0x13,0x82,0x43,0x40,0x17,0x14,0x27,0xE4,0x27,0x20,0x2F,0x21,0x02, + 0x80,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x10,0x10, + /* 0xE5A9 [?] [6401]*/ + 0x00,0x27,0x10,0x11,0x81,0x41,0x40,0x17,0x14,0x23,0xE1,0x26,0x21,0x26,0x21,0x0E, + 0x40,0xFE,0x00,0xF8,0x08,0xF8,0x00,0xFE,0x02,0xF8,0x80,0x44,0xB8,0x68,0xA6,0x60, + /* 0xE5AA [?] [6402]*/ + 0x00,0x27,0x10,0x14,0x82,0x44,0x41,0x12,0x17,0x2A,0xE3,0x22,0x23,0x22,0x23,0x02, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x20,0x10,0xFC,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE5AB [?] [6403]*/ + 0x04,0x84,0x44,0x1F,0x84,0x5F,0x51,0x1F,0x31,0x5F,0xC4,0x5F,0x44,0x44,0x44,0x04, + 0x10,0x10,0x28,0x44,0x82,0x00,0xEE,0x22,0xAA,0x66,0x22,0x66,0xAA,0x22,0xAA,0x44, + /* 0xE5AC [?] [6404]*/ + 0x01,0x41,0x25,0x27,0x04,0x8A,0x41,0x52,0x17,0x20,0xE3,0x20,0x27,0x20,0x2F,0x00, + 0x00,0xBC,0x24,0xA8,0x90,0xA8,0x46,0xA0,0xBC,0xA0,0xB8,0xA0,0xBC,0xA0,0xFE,0x00, + /* 0xE5AD [?] [6405]*/ + 0x00,0xBF,0x48,0x0F,0x80,0x4F,0x48,0x0F,0x20,0x5C,0xD7,0x5D,0x55,0x5C,0x55,0x2E, + 0x80,0xFC,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x80,0x9C,0xD4,0x54,0x5C,0x96,0x56,0x22, + /* 0xE5AE [?] [6406]*/ + 0x40,0x20,0x21,0x82,0x4D,0x40,0x0E,0x2A,0x2E,0x40,0xCF,0x49,0x4F,0x49,0x49,0x08, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xEE,0xAA,0xEE,0x00,0xFE,0x22,0xFE,0x22,0x2A,0x04, + /* 0xE5AF [?] [6407]*/ + 0x02,0x21,0x17,0x11,0x86,0x43,0x42,0x13,0x12,0x23,0xE1,0x27,0x21,0x2F,0x22,0x04, + 0x48,0x50,0xFC,0x50,0x4C,0xF8,0x48,0xF8,0x48,0xF8,0x10,0xFC,0x10,0xFE,0x08,0x04, + /* 0xE5B0 [?] [6408]*/ + 0x40,0x2F,0x28,0x8F,0x48,0x4F,0x02,0x3F,0x20,0x4F,0xC8,0x4F,0x42,0x4A,0x52,0x06, + 0x00,0xBE,0x88,0x90,0xBE,0xA2,0x22,0xEA,0x2A,0xAA,0xAA,0xAA,0x08,0x94,0x52,0x22, + /* 0xE5B1 [?] [6409]*/ + 0x47,0x20,0x2F,0x88,0x43,0x45,0x0F,0x25,0x27,0x42,0xCF,0x4A,0x4F,0x42,0x5F,0x02, + 0xFC,0x40,0xFE,0x42,0x58,0x00,0xBC,0x24,0x24,0x3C,0xA4,0xA4,0xBC,0x24,0xA4,0x4C, + /* 0xE5B2 [?] [6410]*/ + 0x02,0x01,0x01,0x7F,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFE,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE5B3 [?] [6411]*/ + 0x02,0x01,0x01,0x7F,0x40,0x82,0x02,0x1F,0x02,0x02,0x04,0x04,0x08,0x10,0x20,0x40, + 0x00,0x00,0x00,0xFE,0x02,0x04,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xE5B4 [?] [6412]*/ + 0x02,0x01,0x7F,0x40,0x80,0x00,0x7F,0x04,0x04,0x08,0x1F,0x28,0xC8,0x08,0x0F,0x08, + 0x00,0x00,0xFE,0x02,0x04,0x00,0xFC,0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xE5B5 [?] [6413]*/ + 0x02,0x01,0x01,0x7F,0x40,0x81,0x00,0x08,0x48,0x48,0x48,0x89,0x0E,0x18,0xE7,0x00, + 0x00,0x00,0x00,0xFE,0x02,0x04,0x90,0x90,0x24,0x42,0x82,0x02,0x10,0x10,0xF0,0x00, + /* 0xE5B6 [?] [6414]*/ + 0x02,0x01,0x7F,0x42,0x82,0x7F,0x04,0x0F,0x18,0x2F,0x48,0x8F,0x08,0x08,0x08,0x08, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xE5B7 [?] [6415]*/ + 0x02,0x01,0x7F,0x40,0x80,0x3F,0x20,0x2F,0x20,0x3F,0x24,0x24,0x44,0x45,0x86,0x04, + 0x00,0x00,0xFE,0x02,0x04,0xF8,0x00,0xF0,0x00,0xFC,0x88,0x50,0x20,0x18,0x06,0x00, + /* 0xE5B8 [?] [6416]*/ + 0x02,0x01,0x7F,0x41,0x94,0x14,0x23,0x00,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x21,0x20, + 0x00,0x00,0xFE,0x02,0x94,0x28,0xE8,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xE5B9 [?] [6417]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x1F,0x20,0xC8,0x0F,0x00,0x7F,0x00, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0xD0,0x48,0x46,0xF8,0x08,0xA8,0x10, + /* 0xE5BA [?] [6418]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x17,0x21,0xDF,0x01,0x7F,0x01,0x03, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0xD0,0x08,0xF6,0x00,0xF8,0x00,0x00, + /* 0xE5BB [?] [6419]*/ + 0x02,0x01,0x7F,0x40,0x85,0x24,0x24,0x3C,0x04,0x05,0x7C,0x24,0x24,0x24,0x44,0x84, + 0x00,0x00,0xFE,0x02,0xFC,0x20,0xF8,0x48,0x48,0xFE,0x00,0xFC,0x84,0x84,0xFC,0x84, + /* 0xE5BC [?] [6420]*/ + 0x01,0x7F,0x40,0x81,0x7F,0x04,0x28,0x1F,0x28,0xCF,0x08,0x0F,0x01,0x11,0x25,0x02, + 0x00,0xFE,0x02,0x04,0xFC,0x40,0x28,0xF0,0x28,0xE6,0x20,0xE0,0x00,0x10,0x08,0x00, + /* 0xE5BD [?] [6421]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x0A,0x11,0x2F,0xC2,0x04,0x1C,0x65,0x06, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0x10,0xE8,0x8E,0x50,0x20,0x18,0x06, + /* 0xE5BE [?] [6422]*/ + 0x01,0x7F,0x40,0xBF,0x24,0x3F,0x00,0xFF,0x00,0x1F,0x10,0x1F,0x05,0x18,0xEA,0x0C, + 0x00,0xFE,0x02,0xFC,0x48,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x08,0x90,0x60,0x1C, + /* 0xE5BF [?] [6423]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x08,0x1F,0x28,0xCF,0x01,0x09,0x15,0x23, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0xF0,0x28,0xE6,0x00,0xF0,0x00,0xFC, + /* 0xE5C0 [?] [6424]*/ + 0x01,0x7F,0x44,0x9F,0x04,0x3F,0x04,0xFF,0x09,0x1F,0x20,0xDF,0x00,0x1F,0x10,0x1F, + 0x00,0xFE,0x42,0xF4,0x40,0xF8,0x40,0xFE,0x20,0xF0,0x08,0xF6,0x00,0xF0,0x10,0xF0, + /* 0xE5C1 [?] [6425]*/ + 0x00,0x20,0x10,0x10,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xE5C2 [?] [6426]*/ + 0x00,0x23,0x10,0x11,0x01,0x02,0xF3,0x10,0x10,0x10,0x11,0x16,0x10,0x28,0x47,0x00, + 0x00,0xFC,0x10,0x10,0x10,0x10,0xFE,0x30,0x50,0x90,0x10,0x50,0x20,0x00,0xFE,0x00, + /* 0xE5C3 [?] [6427]*/ + 0x00,0x20,0x10,0x11,0x01,0x02,0xF0,0x10,0x17,0x10,0x10,0x10,0x10,0x28,0x47,0x00, + 0x80,0x80,0x80,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xE5C4 [?] [6428]*/ + 0x00,0x23,0x12,0x12,0x02,0x02,0xF2,0x12,0x12,0x12,0x12,0x12,0x12,0x28,0x47,0x00, + 0x00,0xFC,0x04,0x04,0xF4,0x94,0x94,0x94,0xF4,0x94,0x04,0x14,0x08,0x00,0xFE,0x00, + /* 0xE5C5 [?] [6429]*/ + 0x01,0x21,0x11,0x13,0x02,0x04,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x00, + 0x00,0x00,0x00,0xFE,0x80,0x80,0xF8,0x80,0x80,0xFC,0x80,0x80,0x80,0x00,0xFE,0x00, + /* 0xE5C6 [?] [6430]*/ + 0x02,0x22,0x13,0x14,0x04,0x0A,0xF2,0x17,0x12,0x12,0x12,0x12,0x11,0x28,0x47,0x00, + 0x00,0x00,0xFC,0x40,0x40,0x58,0xE8,0x48,0x68,0x50,0x44,0x04,0xFC,0x00,0xFE,0x00, + /* 0xE5C7 [?] [6431]*/ + 0x00,0x20,0x11,0x11,0x02,0x04,0xF0,0x11,0x11,0x12,0x14,0x10,0x10,0x28,0x47,0x00, + 0x80,0x80,0x00,0xFE,0x02,0x24,0x20,0x28,0x24,0x22,0x22,0xA0,0x40,0x00,0xFE,0x00, + /* 0xE5C8 [?] [6432]*/ + 0x04,0x44,0x24,0x2F,0x04,0x04,0xE4,0x24,0x24,0x28,0x28,0x32,0x21,0x50,0x8F,0x00, + 0x00,0x00,0x3C,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xBC,0xA4,0x00,0x00,0xFE,0x00, + /* 0xE5C9 [?] [6433]*/ + 0x00,0x23,0x10,0x10,0x00,0x01,0xF6,0x13,0x10,0x10,0x10,0x17,0x10,0x28,0x47,0x00, + 0x00,0xF8,0x10,0x20,0x50,0x88,0x04,0xF8,0x40,0x40,0x40,0xFC,0x00,0x00,0xFE,0x00, + /* 0xE5CA [?] [6434]*/ + 0x00,0x20,0x11,0x12,0x07,0x02,0xF0,0x13,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x00, + 0x80,0x80,0x10,0x08,0xFC,0x04,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x00,0xFE,0x00, + /* 0xE5CB [?] [6435]*/ + 0x00,0x23,0x12,0x12,0x03,0x02,0xF2,0x12,0x12,0x14,0x14,0x18,0x10,0x28,0x47,0x00, + 0x3C,0xC0,0x00,0x00,0xFE,0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x00,0xFE,0x00, + /* 0xE5CC [?] [6436]*/ + 0x00,0x20,0x10,0x11,0x02,0x00,0xF1,0x16,0x10,0x11,0x10,0x12,0x13,0x10,0x28,0x47, + 0x80,0x80,0xFC,0x08,0x90,0x60,0x98,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFE, + /* 0xE5CD [?] [6437]*/ + 0x00,0x40,0x2F,0x20,0x07,0x04,0xE7,0x24,0x27,0x24,0x24,0x24,0x24,0x50,0x8F,0x00, + 0x48,0x44,0xFE,0x40,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x44,0x54,0x08,0x00,0xFE,0x00, + /* 0xE5CE [?] [6438]*/ + 0x00,0x4F,0x20,0x20,0x07,0x04,0xE4,0x26,0x25,0x24,0x24,0x24,0x25,0x50,0x8F,0x00, + 0x00,0xFE,0x00,0x00,0xBC,0xA4,0xA4,0xB4,0xAC,0xA4,0xA4,0xA4,0xAC,0x00,0xFE,0x00, + /* 0xE5CF [?] [6439]*/ + 0x00,0x20,0x10,0x17,0x00,0x02,0xF1,0x10,0x11,0x12,0x14,0x11,0x10,0x28,0x47,0x00, + 0x40,0x50,0x48,0xFC,0x40,0x48,0x50,0xE0,0x50,0x48,0x44,0x40,0x80,0x00,0xFE,0x00, + /* 0xE5D0 [?] [6440]*/ + 0x00,0x22,0x11,0x11,0x00,0x03,0xF2,0x12,0x13,0x12,0x12,0x13,0x12,0x12,0x2A,0x47, + 0x40,0x48,0x48,0x50,0x40,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x28,0x10,0xFE, + /* 0xE5D1 [?] [6441]*/ + 0x09,0x45,0x22,0x26,0x0A,0x02,0xE2,0x26,0x2A,0x32,0x22,0x2A,0x25,0x50,0x8F,0x00, + 0x10,0x10,0x10,0x52,0x52,0x54,0x90,0x28,0x24,0x44,0x42,0x82,0x00,0x00,0xFE,0x00, + /* 0xE5D2 [?] [6442]*/ + 0x00,0x21,0x12,0x17,0x00,0x01,0xF2,0x15,0x11,0x12,0x15,0x10,0x11,0x2E,0x47,0x00, + 0x80,0x10,0x08,0xFC,0x04,0x10,0x08,0x04,0xF8,0x08,0x90,0x60,0x90,0x08,0xFE,0x00, + /* 0xE5D3 [?] [6443]*/ + 0x00,0x20,0x13,0x10,0x00,0x07,0xF1,0x12,0x14,0x13,0x10,0x10,0x17,0x10,0x28,0x47, + 0x40,0x40,0xF8,0x40,0x40,0xFC,0x10,0x48,0x44,0xF8,0x40,0x40,0xFC,0x00,0x00,0xFE, + /* 0xE5D4 [?] [6444]*/ + 0x00,0x23,0x10,0x17,0x01,0x02,0xF4,0x10,0x1F,0x11,0x13,0x10,0x11,0x16,0x28,0x47, + 0x38,0xC0,0x40,0xFC,0x50,0x48,0x44,0x80,0xFE,0x08,0x90,0x60,0x98,0x04,0x00,0xFE, + /* 0xE5D5 [?] [6445]*/ + 0x00,0x20,0x17,0x14,0x03,0x02,0xF2,0x13,0x12,0x13,0x12,0x12,0x13,0x28,0x47,0x00, + 0x80,0x40,0xFC,0x04,0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x00, + /* 0xE5D6 [?] [6446]*/ + 0x00,0x47,0x20,0x23,0x00,0x0F,0xE0,0x24,0x22,0x21,0x22,0x24,0x21,0x50,0x8F,0x00, + 0x00,0xF8,0x08,0xF8,0x08,0xFE,0x40,0x44,0xE8,0x50,0x48,0x44,0x40,0x80,0xFE,0x00, + /* 0xE5D7 [?] [6447]*/ + 0x00,0x44,0x24,0x24,0x07,0x00,0xEF,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x50,0x8F, + 0x40,0x44,0x44,0x44,0xFC,0x00,0xFE,0x80,0xFC,0xA4,0xA4,0xA4,0xA4,0x0C,0x00,0xFE, + /* 0xE5D8 [?] [6448]*/ + 0x00,0x20,0x13,0x12,0x03,0x02,0xF3,0x10,0x17,0x10,0x13,0x10,0x17,0x28,0x47,0x00, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x40,0xF8,0x40,0xFC,0x00,0xFE,0x00, + /* 0xE5D9 [?] [6449]*/ + 0x02,0x41,0x2F,0x20,0x07,0x04,0xE4,0x25,0x26,0x24,0x27,0x24,0x27,0x50,0x8F,0x00, + 0x08,0x10,0xFE,0xA0,0xFC,0xA4,0xA4,0x24,0x1C,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x00, + /* 0xE5DA [?] [6450]*/ + 0x00,0x47,0x24,0x24,0x07,0x04,0xE4,0x27,0x24,0x24,0x27,0x24,0x24,0x54,0x8F,0x00, + 0x00,0xBC,0x84,0x84,0xBC,0x00,0x00,0xBC,0x04,0x04,0xA8,0x10,0x28,0x44,0xFE,0x00, + /* 0xE5DB [?] [6451]*/ + 0x02,0x42,0x2F,0x22,0x07,0x02,0xEF,0x24,0x27,0x24,0x24,0x2A,0x29,0x50,0x8F,0x00, + 0x10,0x10,0x90,0x1E,0xA4,0x44,0x94,0x14,0x88,0x88,0x94,0xA2,0x42,0x00,0xFE,0x00, + /* 0xE5DC [?] [6452]*/ + 0x01,0x27,0x11,0x13,0x01,0x07,0xF0,0x13,0x12,0x13,0x12,0x17,0x12,0x12,0x2A,0x47, + 0x10,0xFC,0x10,0xF8,0x10,0xFC,0x40,0xF8,0x48,0xF8,0x48,0xFE,0x08,0x28,0x10,0xFE, + /* 0xE5DD [?] [6453]*/ + 0x00,0x23,0x12,0x13,0x02,0x03,0xF0,0x17,0x10,0x14,0x12,0x14,0x12,0x11,0x28,0x47, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xBC,0x84,0xA4,0x94,0xA4,0x94,0x08,0x00,0xFE, + /* 0xE5DE [?] [6454]*/ + 0x00,0x47,0x24,0x25,0x04,0x05,0xE6,0x20,0x27,0x24,0x27,0x24,0x27,0x50,0x8F,0x00, + 0x80,0x7C,0x24,0x24,0xA4,0x54,0x48,0x80,0xFC,0x44,0xFC,0x44,0xFC,0x00,0xFE,0x00, + /* 0xE5DF [?] [6455]*/ + 0x07,0x44,0x27,0x24,0x07,0x02,0xE7,0x2C,0x37,0x24,0x27,0x24,0x27,0x54,0x8F,0x00, + 0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0x40,0xF8,0x40,0xF8,0x40,0xFC,0x00,0xFE,0x00, + /* 0xE5E0 [?] [6456]*/ + 0x00,0x22,0x11,0x17,0x01,0x02,0xF4,0x12,0x13,0x14,0x1A,0x11,0x11,0x12,0x2A,0x47, + 0x40,0x48,0x50,0xFC,0x50,0x48,0x44,0x10,0x90,0xBC,0x90,0x50,0x7E,0x10,0x10,0xFE, + /* 0xE5E1 [?] [6457]*/ + 0x00,0x40,0x20,0x27,0x04,0x05,0xE4,0x27,0x24,0x27,0x28,0x2B,0x30,0x23,0x50,0x8F, + 0x40,0x7C,0x40,0xFE,0x42,0xF8,0x44,0xFC,0xC0,0x22,0xD4,0x18,0x74,0x92,0x20,0xFE, + /* 0xE5E2 [?] [6458]*/ + 0x04,0x4F,0x29,0x32,0x0F,0x0A,0xEA,0x2F,0x2A,0x2A,0x2F,0x2A,0x2A,0x31,0x50,0x8F, + 0x00,0x3C,0x14,0x14,0x94,0xA8,0xA8,0xBC,0xC8,0x88,0xBE,0x88,0x88,0x88,0x08,0xFE, + /* 0xE5E3 [?] [6459]*/ + 0x01,0x42,0x2D,0x25,0x02,0x0D,0xE3,0x25,0x29,0x23,0x25,0x29,0x25,0x52,0x8F,0x00, + 0x10,0x20,0x7C,0xC4,0x44,0x7C,0x44,0x44,0x7C,0x28,0x28,0x2A,0x46,0x80,0xFE,0x00, + /* 0xE5E4 [?] [6460]*/ + 0x00,0x40,0x2F,0x2A,0x14,0x01,0xE7,0x20,0x21,0x26,0x21,0x26,0x21,0x26,0x50,0x8F, + 0x80,0x40,0xFE,0x12,0x0C,0x20,0xFC,0x80,0x44,0x68,0xB0,0x68,0xA4,0xA4,0x40,0xFE, + /* 0xE5E5 [?] [6461]*/ + 0x02,0x44,0x22,0x27,0x05,0x04,0xE5,0x27,0x24,0x26,0x24,0x26,0x24,0x26,0x50,0x8F, + 0x48,0x90,0x48,0xF8,0x28,0xC8,0x28,0xF8,0x90,0xD0,0x90,0xD4,0x8C,0xC4,0x00,0xFE, + /* 0xE5E6 [?] [6462]*/ + 0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00, + /* 0xE5E7 [?] [6463]*/ + 0x10,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x00,0x7F,0x00,0x00,0x3F,0x00,0x00,0x7F,0x00, + 0x10,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE5E8 [?] [6464]*/ + 0x08,0x0F,0x10,0x1F,0x00,0xFF,0x02,0x0D,0x71,0x02,0x0C,0x71,0x06,0x18,0xE2,0x01, + 0x00,0xF0,0x10,0xE0,0x20,0xFE,0x00,0x08,0x90,0xA0,0xC0,0xA0,0x98,0x86,0x80,0x00, + /* 0xE5E9 [?] [6465]*/ + 0x08,0x0F,0x10,0x1F,0x00,0xFF,0x02,0x42,0x43,0x75,0x41,0x4F,0x41,0x62,0x44,0x08, + 0x00,0xF0,0x10,0xE0,0x20,0xFE,0x00,0x10,0xD2,0x14,0x18,0xD0,0x12,0x92,0x4E,0x20, + /* 0xE5EA [?] [6466]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x21,0x21,0x2F,0x21,0x21,0x22,0x22,0x44,0x44,0x88,0x10, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x1E,0x00, + /* 0xE5EB [?] [6467]*/ + 0x00,0x3E,0x22,0x22,0x22,0x22,0x3E,0x2A,0x28,0x28,0x28,0x24,0x24,0x42,0x41,0x80, + 0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x00,0x28,0x24,0x44,0x42,0x82,0x00,0x80,0x7E, + /* 0xE5EC [?] [6468]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x24,0x29,0x30,0x22,0x25,0x2C,0x34,0x44,0x44,0x84,0x07, + 0x00,0xFC,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x88,0x50,0x20,0xD8,0x06, + /* 0xE5ED [?] [6469]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x2E,0x2A,0x2A,0x2C,0x2A,0x2A,0x2A,0x4A,0x4E,0x88,0x08, + 0x00,0xFC,0x04,0xFC,0x00,0xFC,0x08,0xE8,0xA8,0xA8,0xA8,0xE8,0xA8,0x08,0x28,0x10, + /* 0xE5EE [?] [6470]*/ + 0x3F,0x20,0x3F,0x20,0x23,0x20,0x3F,0x20,0x20,0x2F,0x21,0x23,0x5E,0x42,0x8A,0x04, + 0xFC,0x04,0xFC,0x00,0xF0,0x20,0xFE,0x40,0xC0,0xBE,0x04,0x88,0x7E,0x08,0x28,0x10, + /* 0xE5EF [?] [6471]*/ + 0x3F,0x20,0x3F,0x22,0x24,0x28,0x30,0x22,0x25,0x2C,0x34,0x24,0x44,0x45,0x86,0x04, + 0xFC,0x04,0xFC,0x10,0x10,0x9C,0x90,0x90,0xFE,0x10,0x90,0x9C,0x90,0x50,0x3E,0x00, + /* 0xE5F0 [?] [6472]*/ + 0x00,0x3F,0x20,0x3F,0x20,0x25,0x28,0x31,0x24,0x29,0x38,0x2B,0x48,0x49,0x88,0x0B, + 0x00,0xFC,0x04,0xFC,0x00,0x24,0xA8,0xFC,0xA8,0x24,0x40,0xFE,0x88,0x90,0x70,0x8C, + /* 0xE5F1 [?] [6473]*/ + 0x3F,0x20,0x3F,0x22,0x2F,0x20,0x27,0x20,0x3F,0x2A,0x3F,0x24,0x5F,0x44,0xBF,0x08, + 0xFC,0x04,0xFC,0x20,0xF8,0x80,0xF0,0x80,0xFC,0xA8,0x7C,0x10,0x7C,0x10,0x7E,0x10, + /* 0xE5F2 [?] [6474]*/ + 0x00,0x7D,0x04,0x04,0x04,0x7C,0x40,0x43,0x40,0x7D,0x04,0x04,0x04,0x04,0x2B,0x10, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xE5F3 [?] [6475]*/ + 0x08,0x7F,0x11,0x32,0x0C,0x12,0x61,0x00,0x3F,0x00,0x3F,0x20,0x3F,0x00,0x00,0x00, + 0x00,0x7C,0x44,0x28,0x10,0x28,0x46,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x50,0x20, + /* 0xE5F4 [?] [6476]*/ + 0x00,0xFB,0x09,0x09,0x09,0x79,0x41,0x41,0x41,0x79,0x09,0x09,0x0B,0x08,0x50,0x20, + 0x00,0xFE,0x08,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x1E,0xE8,0x08,0x08,0x08, + /* 0xE5F5 [?] [6477]*/ + 0x28,0x28,0x28,0xFE,0x2A,0x2A,0xFE,0xA8,0xA8,0xFF,0x29,0x29,0x2D,0x4A,0x48,0x88, + 0x20,0x20,0x7C,0x44,0x88,0x7C,0x54,0x54,0x54,0x7C,0x40,0x40,0x42,0x42,0x3E,0x00, + /* 0xE5F6 [?] [6478]*/ + 0x00,0xF0,0x17,0x11,0x12,0xF7,0x84,0x84,0x84,0xF7,0x14,0x14,0x14,0x17,0xA4,0x40, + 0x00,0x1E,0xC2,0x02,0x02,0xDE,0x50,0x50,0x50,0xDE,0x42,0x42,0x42,0xC2,0x54,0x08, + /* 0xE5F7 [?] [6479]*/ + 0x71,0x15,0x71,0x47,0x73,0x15,0x31,0x00,0xFF,0x10,0x1F,0x00,0x7F,0x44,0x4F,0x41, + 0x1C,0x44,0x1C,0xD0,0x9C,0x44,0x0C,0x00,0xFE,0x10,0xF0,0x00,0xFC,0x44,0xE4,0x0C, + /* 0xE5F8 [?] [6480]*/ + 0x01,0x01,0x21,0x21,0x21,0x21,0x21,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0x08,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE5F9 [?] [6481]*/ + 0x10,0x10,0x10,0x10,0xFD,0x26,0x24,0x25,0x24,0x48,0x28,0x10,0x28,0x44,0x84,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xE5FA [?] [6482]*/ + 0x10,0x10,0x11,0x10,0xFC,0x24,0x24,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x84,0x00, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE5FB [?] [6483]*/ + 0x10,0x13,0x10,0x10,0xFC,0x24,0x24,0x27,0x24,0x48,0x28,0x10,0x28,0x44,0x81,0x02, + 0x00,0xFE,0x88,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x08, + /* 0xE5FC [?] [6484]*/ + 0x20,0x23,0x20,0x20,0xF8,0x48,0x4F,0x48,0x88,0x48,0x30,0x11,0x29,0x4A,0x84,0x08, + 0x00,0xFC,0x40,0x40,0x40,0x40,0xFE,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xE5FD [?] [6485]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x00, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xE5FE [?] [6486]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x00, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xE6A1 [?] [6487]*/ + 0x10,0x10,0x10,0x10,0xFC,0x25,0x26,0x24,0x24,0x49,0x28,0x10,0x28,0x44,0x84,0x00, + 0x20,0x20,0x50,0x50,0x88,0x44,0x22,0x20,0x00,0xFC,0x04,0x08,0x08,0x10,0x10,0x20, + /* 0xE6A2 [?] [6488]*/ + 0x10,0x10,0x10,0x11,0xFD,0x25,0x25,0x25,0x24,0x48,0x28,0x11,0x2E,0x44,0x84,0x00, + 0x20,0x20,0x2E,0xF0,0x20,0x20,0x20,0xFE,0x22,0x62,0xA2,0x2A,0x24,0x20,0x20,0x20, + /* 0xE6A3 [?] [6489]*/ + 0x10,0x11,0x10,0x10,0xFC,0x27,0x24,0x24,0x24,0x48,0x28,0x10,0x28,0x45,0x82,0x04, + 0x20,0x20,0xA0,0xA0,0x20,0xFE,0x22,0x22,0x42,0x52,0x4A,0x8A,0x82,0x02,0x14,0x08, + /* 0xE6A4 [?] [6490]*/ + 0x10,0x11,0x10,0x10,0xFC,0x24,0x24,0x25,0x24,0x48,0x28,0x10,0x28,0x44,0x83,0x00, + 0x00,0xF8,0x48,0x48,0x48,0x48,0x48,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0xFE,0x00, + /* 0xE6A5 [?] [6491]*/ + 0x10,0x11,0x10,0x10,0xFC,0x24,0x27,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x84,0x00, + 0x00,0xF8,0x08,0x50,0x20,0x10,0xFE,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xE6A6 [?] [6492]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x44,0x84,0x00, + 0x08,0x48,0x28,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x48,0x94,0x14,0x22,0x42,0x82, + /* 0xE6A7 [?] [6493]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x24,0x24,0x24,0x48,0x28,0x10,0x28,0x44,0x85,0x00, + 0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x00,0x00,0xFE,0x00, + /* 0xE6A8 [?] [6494]*/ + 0x10,0x10,0x10,0x10,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xE6A9 [?] [6495]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x27,0x25,0x49,0x29,0x11,0x29,0x46,0x82,0x04, + 0x00,0xDC,0x54,0x54,0x54,0x54,0x54,0xFE,0x54,0x54,0x54,0x54,0x54,0xD4,0x24,0x4C, + /* 0xE6AA [?] [6496]*/ + 0x02,0x01,0x3F,0x00,0x08,0x04,0xFF,0x02,0x02,0x7F,0x04,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0x00,0xF8,0x00,0x20,0x40,0xFE,0x00,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xE6AB [?] [6497]*/ + 0x20,0x23,0x20,0x20,0xF8,0x48,0x4C,0x4A,0x8A,0x4A,0x30,0x10,0x28,0x48,0x87,0x00, + 0x00,0xFC,0x90,0x90,0x90,0x92,0x92,0x94,0x94,0x98,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xE6AC [?] [6498]*/ + 0x20,0x20,0x20,0x23,0xF8,0x48,0x48,0x4B,0x88,0x4B,0x30,0x10,0x29,0x49,0x82,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xE6AD [?] [6499]*/ + 0x20,0x21,0x21,0x21,0xF9,0x4A,0x48,0x4B,0x48,0x90,0x50,0x21,0x31,0x4A,0x48,0x80, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xE6AE [?] [6500]*/ + 0x02,0x01,0xFF,0x04,0x14,0x14,0x24,0x42,0x02,0x7F,0x04,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x04,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xE6AF [?] [6501]*/ + 0x10,0x10,0x10,0x11,0xFC,0x24,0x25,0x26,0x24,0x48,0x28,0x10,0x28,0x44,0x80,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xE6B0 [?] [6502]*/ + 0x11,0x10,0x10,0x10,0xFD,0x24,0x24,0x24,0x24,0x4B,0x28,0x10,0x29,0x45,0x82,0x04, + 0x04,0x84,0x88,0x00,0xFE,0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xE6B1 [?] [6503]*/ + 0x10,0x10,0x10,0x11,0xFD,0x26,0x24,0x25,0x24,0x48,0x28,0x13,0x28,0x44,0x84,0x00, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x18,0xE0,0x40,0x40,0x7E,0xC0,0x40,0x44,0x44,0x3C, + /* 0xE6B2 [?] [6504]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x25,0x25,0x24,0x48,0x29,0x10,0x28,0x44,0x87,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE6B3 [?] [6505]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x25,0x24,0x27,0x48,0x29,0x11,0x28,0x44,0x84,0x00, + 0x20,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE,0x80,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xE6B4 [?] [6506]*/ + 0x20,0x21,0x21,0x21,0xF9,0x49,0x48,0x48,0x4B,0x92,0x52,0x22,0x33,0x4A,0x4A,0x82, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xE6B5 [?] [6507]*/ + 0x11,0x10,0x10,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x00,0xBC,0x04,0x24,0x24,0x24,0xFC,0x24,0x74,0xAC,0x24,0x24,0x24,0x04,0x14,0x08, + /* 0xE6B6 [?] [6508]*/ + 0x10,0x08,0x40,0x24,0x09,0x72,0x10,0x17,0x02,0x7F,0x04,0x08,0x1C,0x03,0x0C,0x70, + 0x20,0x20,0xA8,0xA4,0x2A,0x30,0xC0,0x00,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xE6B7 [?] [6509]*/ + 0x11,0x10,0x10,0x11,0xFC,0x24,0x25,0x25,0x25,0x49,0x28,0x10,0x29,0x46,0x84,0x00, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xE6B8 [?] [6510]*/ + 0x20,0x23,0x22,0x22,0xFB,0x4A,0x4A,0x4A,0x8A,0x4A,0x32,0x13,0x2A,0x4C,0x84,0x08, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x18,0xE0,0x38,0xE0,0x3C,0xE0,0x22,0x22,0x1E,0x00, + /* 0xE6B9 [?] [6511]*/ + 0x20,0x27,0x25,0x25,0xF5,0x55,0x56,0x55,0x55,0x95,0x55,0x25,0x26,0x54,0x54,0x84, + 0x00,0x7E,0x04,0x04,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x54,0x04,0x04,0x14,0x08, + /* 0xE6BA [?] [6512]*/ + 0x10,0x10,0x13,0x10,0xFD,0x24,0x27,0x24,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xE6BB [?] [6513]*/ + 0x10,0x10,0x13,0x10,0xFC,0x25,0x24,0x24,0x27,0x48,0x28,0x11,0x2A,0x44,0x84,0x00, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x40,0xA4,0xA8,0x90,0x88,0xC6,0x80, + /* 0xE6BC [?] [6514]*/ + 0x20,0x20,0x23,0x20,0xF9,0x48,0x4B,0x48,0x89,0x48,0x31,0x11,0x29,0x4A,0x82,0x04, + 0x20,0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0x20,0x3E,0x20,0xA0,0x7E,0x00, + /* 0xE6BD [?] [6515]*/ + 0x10,0x10,0x10,0x10,0xFC,0x24,0x24,0x24,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x00,0xFE,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02, + /* 0xE6BE [?] [6516]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x25,0x25,0x25,0x48,0x29,0x13,0x28,0x44,0x84,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xE6BF [?] [6517]*/ + 0x11,0x10,0x10,0x11,0xFD,0x25,0x25,0x25,0x25,0x49,0x28,0x10,0x2B,0x44,0x84,0x00, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE6C0 [?] [6518]*/ + 0x10,0x10,0xFE,0x22,0x64,0x18,0x24,0xC2,0x01,0x3F,0x22,0x24,0x21,0x22,0x24,0x20, + 0x00,0x00,0xFC,0x44,0x28,0x10,0x28,0xC6,0x00,0xF8,0x88,0x48,0x08,0x88,0x48,0x18, + /* 0xE6C1 [?] [6519]*/ + 0x20,0x21,0x21,0x21,0xF9,0x49,0x49,0x49,0x88,0x4B,0x32,0x12,0x2A,0x4A,0x87,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x94,0x94,0x94,0x94,0xFE,0x00, + /* 0xE6C2 [?] [6520]*/ + 0x20,0x27,0x22,0x21,0xF8,0x4B,0x48,0x48,0x4F,0x91,0x51,0x22,0x32,0x4C,0x48,0x83, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xE6C3 [?] [6521]*/ + 0x10,0x10,0x13,0x10,0xFD,0x25,0x25,0x24,0x27,0x4A,0x29,0x10,0x28,0x44,0x84,0x00, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFC,0x20,0x20,0x20,0xA0,0x40, + /* 0xE6C4 [?] [6522]*/ + 0x00,0x7E,0x24,0x18,0xFF,0x29,0x4A,0x98,0x02,0x7F,0x04,0x08,0x1C,0x03,0x06,0x38, + 0x20,0x20,0x7E,0xA4,0x28,0x10,0x28,0xC6,0x00,0xFC,0x20,0x40,0x80,0x80,0x70,0x08, + /* 0xE6C5 [?] [6523]*/ + 0x10,0x10,0x13,0x10,0xFD,0x24,0x27,0x24,0x25,0x49,0x29,0x11,0x2B,0x45,0x85,0x01, + 0x88,0x88,0xFE,0x88,0xFC,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFE,0x04,0x14,0x08, + /* 0xE6C6 [?] [6524]*/ + 0x21,0x21,0x27,0x21,0xF8,0x4B,0x4A,0x4B,0x8A,0x4B,0x30,0x17,0x28,0x49,0x82,0x04, + 0x10,0x10,0xFC,0x10,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xE6C7 [?] [6525]*/ + 0x10,0x10,0x11,0x11,0xFD,0x25,0x25,0x25,0x24,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x20,0x40,0xFC,0x54,0x24,0x54,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xE6C8 [?] [6526]*/ + 0x20,0x23,0x20,0x22,0xF9,0x4B,0x4A,0x48,0x4B,0x90,0x50,0x21,0x31,0x4A,0x4C,0x81, + 0x0E,0xF0,0x44,0x24,0x08,0xFE,0x42,0x40,0xFE,0x80,0xFC,0x44,0x28,0x10,0x68,0x86, + /* 0xE6C9 [?] [6527]*/ + 0x20,0x20,0x23,0x22,0xFC,0x49,0x49,0x49,0x49,0x91,0x51,0x27,0x30,0x48,0x49,0x82, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xE6CA [?] [6528]*/ + 0x20,0x21,0x21,0x21,0xF8,0x4B,0x48,0x48,0x49,0x91,0x51,0x21,0x30,0x48,0x4B,0x81, + 0x20,0x24,0x24,0xFC,0x20,0xFE,0x00,0x20,0xFC,0x24,0x24,0xFC,0x20,0x24,0xFE,0x02, + /* 0xE6CB [?] [6529]*/ + 0x08,0x3E,0x08,0x7F,0x1C,0x2A,0x49,0x3F,0x21,0x21,0x3F,0x22,0x27,0x40,0x43,0x8C, + 0x20,0x7E,0xA4,0x28,0x10,0x28,0x44,0xFE,0x00,0x00,0xFE,0x10,0x20,0xC0,0x30,0x0C, + /* 0xE6CC [?] [6530]*/ + 0x20,0x27,0x20,0x22,0xFA,0x4F,0x49,0x49,0x4A,0x93,0x50,0x25,0x35,0x48,0x48,0x80, + 0x00,0xFC,0x40,0x78,0x40,0xFE,0x00,0xFC,0x00,0xFC,0x04,0x54,0x54,0x04,0x28,0x10, + /* 0xE6CD [?] [6531]*/ + 0x10,0x10,0x13,0x10,0xFD,0x24,0x27,0x24,0x25,0x49,0x29,0x11,0x29,0x45,0x85,0x01, + 0x20,0x20,0xFE,0x20,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x74,0x54,0x74,0x04,0xFC,0x04, + /* 0xE6CE [?] [6532]*/ + 0x10,0x13,0x10,0x11,0xFD,0x25,0x25,0x24,0x25,0x48,0x2B,0x10,0x28,0x45,0x82,0x00, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xE6CF [?] [6533]*/ + 0x20,0x21,0x20,0x23,0xFA,0x48,0x48,0x48,0x48,0x90,0x51,0x21,0x31,0x49,0x49,0x80, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0xFC,0x24,0x24,0x34,0x28,0x20, + /* 0xE6D0 [?] [6534]*/ + 0x10,0x11,0x11,0x11,0xFD,0x25,0x24,0x24,0x25,0x48,0x28,0x13,0x28,0x45,0x82,0x00, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x40,0x88,0xF0,0x20,0x44,0xFE,0x22,0x24,0x22,0x60, + /* 0xE6D1 [?] [6535]*/ + 0x20,0x21,0x20,0x20,0xFB,0x48,0x49,0x49,0x49,0x91,0x51,0x20,0x33,0x48,0x48,0x80, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xE6D2 [?] [6536]*/ + 0x10,0x13,0x10,0x11,0xFC,0x25,0x25,0x25,0x24,0x4B,0x28,0x11,0x29,0x45,0x85,0x01, + 0x20,0xFE,0x20,0xFC,0x00,0xFC,0x04,0xFC,0x88,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xE6D3 [?] [6537]*/ + 0x20,0x23,0x20,0x23,0xFA,0x4A,0x4A,0x4B,0x48,0x91,0x51,0x21,0x31,0x49,0x48,0x83, + 0x20,0xFE,0x00,0xFC,0x04,0xF4,0x94,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xE6D4 [?] [6538]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3C,0x02,0xFF,0x08,0x1C,0x03,0x3C, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xFE,0x20,0x40,0xC0,0x38, + /* 0xE6D5 [?] [6539]*/ + 0x00,0xF9,0xA9,0xA9,0xF9,0xAF,0xAA,0xFA,0x42,0x44,0xFA,0x49,0x49,0x4A,0xAC,0x10, + 0x00,0x3E,0x2A,0x2A,0x3E,0xAA,0xAA,0xBE,0x90,0x90,0xBE,0x12,0x12,0x92,0xAA,0x44, + /* 0xE6D6 [?] [6540]*/ + 0x20,0x20,0x27,0x24,0xF7,0x54,0x55,0x56,0x54,0x94,0x54,0x25,0x24,0x54,0x55,0x88, + 0x40,0x20,0xFE,0x88,0xDE,0x88,0xDC,0xAA,0x88,0x40,0x90,0x20,0x48,0x84,0xFC,0x84, + /* 0xE6D7 [?] [6541]*/ + 0x21,0x20,0x23,0x22,0xF9,0x48,0x49,0x48,0x48,0x93,0x50,0x21,0x32,0x4C,0x48,0x80, + 0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0x9E,0xF2,0x9E,0xD2,0xBE,0x92,0x9E,0x92, + /* 0xE6D8 [?] [6542]*/ + 0x00,0x3F,0x08,0x08,0x08,0x10,0x10,0x21,0x41,0x09,0x09,0x11,0x21,0x41,0x05,0x02, + 0x00,0xF0,0x10,0x20,0x3C,0x04,0x04,0x14,0x08,0x20,0x10,0x08,0x04,0x04,0x00,0x00, + /* 0xE6D9 [?] [6543]*/ + 0x01,0x09,0x11,0x21,0x00,0x01,0xFF,0x02,0x0C,0x30,0xC1,0x09,0x09,0x11,0x25,0x02, + 0x00,0x20,0x10,0x08,0x00,0x00,0xFE,0x80,0x60,0x18,0x06,0x20,0x10,0x08,0x08,0x00, + /* 0xE6DA [?] [6544]*/ + 0x00,0x7F,0x22,0x11,0x11,0x00,0x1F,0x00,0x00,0x01,0xFF,0x01,0x01,0x01,0x05,0x02, + 0xF8,0x00,0x10,0x10,0x20,0x00,0xE0,0x40,0x80,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, + /* 0xE6DB [?] [6545]*/ + 0x10,0x10,0xFE,0x22,0x64,0x18,0x24,0xC2,0x00,0x3F,0x00,0x01,0xFF,0x01,0x05,0x02, + 0x00,0x00,0xFC,0x44,0x28,0x10,0x28,0xC6,0x00,0xE0,0x80,0x00,0xFE,0x00,0x00,0x00, + /* 0xE6DC [?] [6546]*/ + 0x08,0x04,0x7F,0x12,0x3C,0x08,0x14,0x3E,0x00,0x3F,0x00,0x01,0xFF,0x01,0x05,0x02, + 0x20,0x40,0xFC,0x48,0xF0,0x20,0x50,0xF8,0x00,0xE0,0x80,0x00,0xFE,0x00,0x00,0x00, + /* 0xE6DD [?] [6547]*/ + 0x00,0x7F,0x00,0x00,0x00,0x01,0x01,0x01,0x03,0x1D,0xE1,0x41,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x10,0x20,0x40,0x84,0x18,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE6DE [?] [6548]*/ + 0x00,0x7F,0x00,0x00,0x20,0x11,0x09,0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x05,0x02, + 0x00,0xF8,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x0C,0x00,0x00, + /* 0xE6DF [?] [6549]*/ + 0x00,0xFC,0x05,0x09,0x12,0x15,0x15,0x19,0x31,0xD1,0x11,0x11,0x11,0x11,0x50,0x20, + 0x80,0x80,0xFC,0x04,0x04,0xF4,0x14,0x14,0x14,0xF4,0x04,0x28,0x12,0x02,0xFE,0x00, + /* 0xE6E0 [?] [6550]*/ + 0x00,0xF8,0x08,0x48,0x48,0x48,0x48,0x7C,0x04,0x04,0x1C,0xE4,0x44,0x04,0x2B,0x10, + 0x00,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xFE,0x00, + /* 0xE6E1 [?] [6551]*/ + 0x00,0xF9,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1D,0xE5,0x45,0x05,0x29,0x10, + 0x00,0xFC,0x54,0x54,0x54,0x54,0x54,0x54,0x94,0x8C,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xE6E2 [?] [6552]*/ + 0x00,0xF8,0x08,0x49,0x49,0x4B,0x4D,0x7D,0x05,0x05,0x1D,0xE5,0x45,0x05,0x29,0x11, + 0x88,0x88,0x88,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xE6E3 [?] [6553]*/ + 0x00,0xF8,0x08,0x49,0x4A,0x4C,0x4B,0x7C,0x04,0x04,0x1D,0xE4,0x44,0x04,0x2B,0x10, + 0x80,0x80,0xF8,0x08,0x10,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE6E4 [?] [6554]*/ + 0x00,0xFB,0x09,0x48,0x48,0x48,0x48,0x7F,0x04,0x05,0x1C,0xE4,0x47,0x04,0x28,0x10, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE6E5 [?] [6555]*/ + 0x08,0x7F,0x11,0x32,0x0C,0x12,0x61,0x1F,0x00,0x08,0x08,0x0F,0x00,0x7F,0x00,0x00, + 0x00,0x7C,0x44,0x28,0x10,0x28,0x46,0xE0,0x20,0x20,0x20,0xFC,0x04,0xC4,0x14,0x08, + /* 0xE6E6 [?] [6556]*/ + 0x00,0xF8,0x08,0x48,0x49,0x4B,0x48,0x7C,0x05,0x05,0x1D,0xE5,0x45,0x05,0x29,0x11, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE6E7 [?] [6557]*/ + 0x00,0xF8,0x08,0x4B,0x48,0x48,0x48,0x7F,0x04,0x07,0x1C,0xE4,0x45,0x05,0x2A,0x14, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xE6E8 [?] [6558]*/ + 0x00,0xF8,0x09,0x49,0x4B,0x4D,0x49,0x7D,0x05,0x04,0x1F,0xE4,0x44,0x04,0x28,0x10, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xE6E9 [?] [6559]*/ + 0x00,0xF8,0x08,0x48,0x49,0x48,0x48,0x7C,0x04,0x07,0x1C,0xE4,0x44,0x04,0x28,0x11, + 0x84,0x44,0x48,0x00,0xFE,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x88,0x08, + /* 0xE6EA [?] [6560]*/ + 0x00,0xF3,0x10,0x50,0x53,0x52,0x52,0x7A,0x0B,0x0A,0x3A,0xCA,0x0A,0x0A,0x2A,0x12, + 0x00,0xFE,0x00,0x00,0xDE,0x52,0x52,0x52,0x5A,0xD6,0x52,0x52,0x52,0x52,0x52,0xD6, + /* 0xE6EB [?] [6561]*/ + 0x00,0xF8,0x0B,0x48,0x48,0x48,0x48,0x7C,0x04,0x04,0x1C,0xE7,0x44,0x04,0x28,0x11, + 0x88,0x88,0xFE,0x88,0x88,0xF8,0x88,0x88,0xF8,0x88,0x88,0xFE,0x00,0x88,0x84,0x04, + /* 0xE6EC [?] [6562]*/ + 0x00,0xF9,0x09,0x49,0x49,0x49,0x49,0x7D,0x04,0x07,0x1C,0xE4,0x45,0x06,0x28,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xE6ED [?] [6563]*/ + 0x00,0xF8,0x08,0x48,0x49,0x4A,0x48,0x7C,0x04,0x04,0x1C,0xE4,0x44,0x04,0x28,0x10, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xE6EE [?] [6564]*/ + 0x00,0xF8,0x08,0x49,0x48,0x4B,0x48,0x7D,0x06,0x05,0x1C,0xE4,0x45,0x04,0x28,0x13, + 0x40,0x48,0x84,0xFE,0x20,0xFE,0x88,0x24,0x42,0x88,0x10,0x62,0x84,0x18,0x60,0x80, + /* 0xE6EF [?] [6565]*/ + 0x00,0x79,0x49,0x53,0x48,0x6B,0x50,0x43,0x1F,0x00,0x08,0x0F,0x00,0x7F,0x00,0x00, + 0x20,0x3C,0x20,0xFE,0xA4,0x28,0x70,0x80,0xE0,0x20,0x20,0xFC,0x04,0xC4,0x14,0x08, + /* 0xE6F0 [?] [6566]*/ + 0x7E,0x24,0x18,0xFF,0x29,0x4A,0x98,0x00,0x1F,0x00,0x08,0x0F,0x00,0x7F,0x00,0x00, + 0x20,0x3E,0x48,0xA8,0x10,0x28,0x46,0x00,0xE0,0x20,0x20,0xFC,0x04,0xC4,0x14,0x08, + /* 0xE6F1 [?] [6567]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x10,0x1E,0x22,0x5F,0x80,0x08,0x0F,0x00,0x7F,0x00, + 0x20,0x20,0x7E,0x44,0xA4,0x28,0x10,0x28,0x44,0xE2,0x20,0x20,0xFC,0x04,0xD4,0x08, + /* 0xE6F2 [?] [6568]*/ + 0x00,0xF9,0x09,0x49,0x49,0x49,0x49,0x7C,0x05,0x05,0x1D,0xE5,0x45,0x05,0x29,0x11, + 0x40,0xBC,0x14,0x94,0x54,0xA4,0x4C,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xE6F3 [?] [6569]*/ + 0x00,0xF8,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1D,0xE5,0x45,0x06,0x2A,0x14, + 0x20,0x10,0xFE,0x02,0x02,0xFE,0x00,0xEE,0x22,0xAA,0x66,0x22,0x66,0xAA,0x22,0x66, + /* 0xE6F4 [?] [6570]*/ + 0x00,0xFB,0x08,0x49,0x49,0x49,0x49,0x7C,0x05,0x04,0x1F,0xE4,0x44,0x05,0x2A,0x10, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xE6F5 [?] [6571]*/ + 0x00,0xF8,0x09,0x49,0x49,0x49,0x49,0x7D,0x05,0x05,0x1C,0xE4,0x45,0x05,0x29,0x12, + 0x20,0x40,0xFC,0x24,0x7C,0x8C,0x54,0x24,0x54,0xFC,0x20,0x10,0x54,0x42,0x4A,0x38, + /* 0xE6F6 [?] [6572]*/ + 0x03,0xF2,0x13,0x52,0x52,0x52,0x53,0x7A,0x0A,0x0B,0x3A,0xCA,0x0C,0x0F,0x28,0x11, + 0xFE,0x02,0xFE,0x00,0xFC,0x08,0xFE,0x10,0x30,0xCE,0x42,0x84,0xEE,0x84,0x84,0x8C, + /* 0xE6F7 [?] [6573]*/ + 0x00,0xFB,0x08,0x49,0x4A,0x49,0x49,0x7D,0x05,0x05,0x1C,0xE5,0x44,0x07,0x28,0x11, + 0x94,0x98,0x92,0x8E,0x80,0xFC,0x24,0xFC,0x24,0xFC,0x88,0xFC,0x88,0xFE,0x88,0x04, + /* 0xE6F8 [?] [6574]*/ + 0x00,0xF3,0x10,0x51,0x51,0x51,0x50,0x7B,0x08,0x0B,0x38,0xCB,0x08,0x09,0x2A,0x10, + 0x20,0xFE,0x00,0xDC,0x54,0xDC,0x88,0xFE,0x88,0xFE,0x88,0xFE,0x94,0x88,0xA4,0xC2, + /* 0xE6F9 [?] [6575]*/ + 0x10,0x10,0x20,0x24,0x44,0xF8,0x10,0x20,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE6FA [?] [6576]*/ + 0x10,0x11,0x20,0x24,0x44,0xF8,0x10,0x23,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xE6FB [?] [6577]*/ + 0x10,0x10,0x20,0x24,0x45,0xF8,0x10,0x20,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x88,0x48,0x48,0x08,0x08,0x08,0x28,0x10, + /* 0xE6FC [?] [6578]*/ + 0x10,0x10,0x20,0x24,0x45,0xFA,0x10,0x20,0x40,0xFC,0x40,0x00,0x1D,0xE1,0x40,0x00, + 0x40,0x40,0x80,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xE6FD [?] [6579]*/ + 0x10,0x10,0x20,0x24,0x45,0xF8,0x10,0x20,0x41,0xFC,0x40,0x00,0x1C,0xE1,0x42,0x04, + 0x40,0x40,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0xC8,0x48,0xA8,0xAA,0x0A,0x06,0x02, + /* 0xE6FE [?] [6580]*/ + 0x10,0x10,0x20,0x25,0x45,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE2,0x42,0x04, + 0x20,0x10,0x10,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xE7A1 [?] [6581]*/ + 0x10,0x10,0x21,0x24,0x44,0xF8,0x13,0x20,0x40,0xFC,0x40,0x00,0x1D,0xE3,0x41,0x00, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0x88,0x04,0xFE,0x02,0x00, + /* 0xE7A2 [?] [6582]*/ + 0x10,0x11,0x21,0x25,0x45,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x00, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xE7A3 [?] [6583]*/ + 0x10,0x11,0x20,0x24,0x44,0xF8,0x13,0x20,0x40,0xFC,0x40,0x00,0x1C,0xE0,0x40,0x00, + 0x00,0xF8,0x08,0x50,0x20,0x10,0xFE,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xE7A4 [?] [6584]*/ + 0x11,0x11,0x21,0x25,0x47,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xE7A5 [?] [6585]*/ + 0x10,0x12,0x22,0x22,0x4A,0xF7,0x12,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x43,0x00, + 0x48,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x78,0x00,0x00,0x00,0xFE,0x00, + /* 0xE7A6 [?] [6586]*/ + 0x10,0x10,0x20,0x20,0x4B,0xF8,0x10,0x20,0x41,0xF9,0x41,0x01,0x1A,0xE2,0x44,0x01, + 0x50,0x48,0x48,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xE7A7 [?] [6587]*/ + 0x10,0x10,0x20,0x21,0x4A,0xFC,0x13,0x20,0x40,0xF8,0x41,0x00,0x18,0xE0,0x43,0x00, + 0x80,0x80,0xF8,0x08,0x10,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE7A8 [?] [6588]*/ + 0x10,0x10,0x20,0x23,0x48,0xF8,0x13,0x22,0x42,0xFB,0x40,0x00,0x19,0xE1,0x42,0x04, + 0x90,0x90,0x90,0xFC,0x94,0x94,0xFC,0x90,0x90,0xFE,0x92,0x92,0x1A,0x14,0x10,0x10, + /* 0xE7A9 [?] [6589]*/ + 0x10,0x10,0x21,0x25,0x45,0xF9,0x11,0x20,0x40,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x00, + 0x20,0x20,0x24,0x24,0x24,0x24,0xFC,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xE7AA [?] [6590]*/ + 0x10,0x10,0x20,0x24,0x45,0xFB,0x10,0x20,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x20,0x20,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE7AB [?] [6591]*/ + 0x10,0x10,0x27,0x20,0x49,0xFA,0x1D,0x20,0x47,0xF8,0x41,0x03,0x18,0xE0,0x40,0x00, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xF6,0x00,0xFC,0x80,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xE7AC [?] [6592]*/ + 0x10,0x10,0x21,0x22,0x4C,0xF0,0x11,0x23,0x45,0xF9,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x80,0x80,0x3C,0x00,0x80,0x80,0x7E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xE7AD [?] [6593]*/ + 0x10,0x10,0x20,0x21,0x4A,0xF8,0x11,0x26,0x40,0xF9,0x40,0x02,0x1B,0xE0,0x40,0x00, + 0x80,0x80,0xFC,0x08,0x90,0x60,0x98,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE7AE [?] [6594]*/ + 0x10,0x13,0x20,0x24,0x45,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1C,0xE0,0x40,0x03, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xE7AF [?] [6595]*/ + 0x10,0x11,0x20,0x24,0x44,0xF9,0x11,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xE7B0 [?] [6596]*/ + 0x11,0x10,0x20,0x23,0x48,0xF8,0x13,0x22,0x42,0xFB,0x40,0x00,0x19,0xE2,0x44,0x00, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xE7B1 [?] [6597]*/ + 0x10,0x10,0x21,0x20,0x48,0xFB,0x10,0x21,0x42,0xF8,0x41,0x02,0x18,0xE0,0x41,0x06, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xE7B2 [?] [6598]*/ + 0x10,0x10,0x21,0x24,0x44,0xF9,0x13,0x20,0x41,0xFD,0x41,0x01,0x1D,0xE0,0x40,0x00, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFE,0x08,0xE8,0x28,0x28,0xE8,0x28,0x08,0x28,0x10, + /* 0xE7B3 [?] [6599]*/ + 0x10,0x10,0x20,0x27,0x48,0xF8,0x10,0x23,0x40,0xF8,0x40,0x07,0x18,0xE0,0x40,0x00, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xE7B4 [?] [6600]*/ + 0x10,0x11,0x20,0x20,0x48,0xFB,0x12,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x42,0x02, + 0x20,0x24,0xA4,0xA8,0x20,0xFE,0x02,0x02,0xFA,0x8A,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE7B5 [?] [6601]*/ + 0x10,0x11,0x21,0x25,0x45,0xF9,0x11,0x21,0x40,0xFD,0x41,0x01,0x1D,0xE1,0x41,0x01, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xE7B6 [?] [6602]*/ + 0x10,0x10,0x21,0x20,0x48,0xFB,0x11,0x21,0x47,0xF9,0x41,0x03,0x18,0xE0,0x43,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x24,0x24,0xFE,0x24,0x24,0xFE,0x20,0x20,0xFE,0x00, + /* 0xE7B7 [?] [6603]*/ + 0x10,0x13,0x20,0x22,0x49,0xF9,0x17,0x24,0x40,0xFB,0x41,0x01,0x18,0xE0,0x41,0x06, + 0x1C,0xE0,0x84,0x44,0x48,0x10,0xFE,0x02,0x00,0xF8,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xE7B8 [?] [6604]*/ + 0x10,0x10,0x21,0x21,0x4A,0xF5,0x10,0x21,0x46,0xF8,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x88,0x88,0xEC,0x2A,0x28,0x48,0x88,0x7E,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE7B9 [?] [6605]*/ + 0x10,0x12,0x21,0x20,0x4B,0xF8,0x17,0x21,0x42,0xFD,0x49,0x01,0x19,0xE1,0x41,0x00, + 0x40,0x48,0x50,0x40,0xF8,0x80,0xFC,0x10,0x08,0xF4,0x12,0x10,0x50,0x24,0x04,0xFC, + /* 0xE7BA [?] [6606]*/ + 0x10,0x10,0x23,0x22,0x4C,0xF9,0x11,0x21,0x41,0xF9,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xE7BB [?] [6607]*/ + 0x11,0x11,0x22,0x24,0x4A,0xF9,0x11,0x20,0x43,0xFA,0x42,0x03,0x1A,0xE2,0x43,0x02, + 0x24,0x24,0x48,0x90,0x48,0x24,0x24,0x00,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x04, + /* 0xE7BC [?] [6608]*/ + 0x10,0x10,0x23,0x24,0x44,0xF8,0x11,0x21,0x41,0xFD,0x40,0x03,0x1C,0xE0,0x40,0x00, + 0x88,0x88,0xFE,0x88,0xF8,0x20,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE7BD [?] [6609]*/ + 0x11,0x11,0x21,0x21,0x4F,0xF1,0x11,0x23,0x43,0xFD,0x49,0x01,0x19,0xE1,0x41,0x01, + 0x00,0x00,0x3E,0x22,0xA2,0x22,0x3E,0xA2,0x62,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22, + /* 0xE7BE [?] [6610]*/ + 0x10,0x11,0x21,0x21,0x49,0xF9,0x11,0x21,0x40,0xFB,0x40,0x01,0x19,0xE1,0x42,0x04, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x20,0x20,0x3C,0x20,0xA0,0x7E, + /* 0xE7BF [?] [6611]*/ + 0x20,0x20,0x27,0x45,0x55,0xF7,0x25,0x25,0x47,0xF5,0x45,0x07,0x35,0xC0,0x00,0x03, + 0x10,0x10,0x10,0x10,0x14,0x52,0x52,0x92,0x10,0x14,0x08,0x10,0x20,0x40,0x80,0x00, + /* 0xE7C0 [?] [6612]*/ + 0x10,0x10,0x21,0x25,0x45,0xF8,0x13,0x20,0x41,0xFD,0x41,0x01,0x1D,0xE0,0x40,0x03, + 0x20,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xE7C1 [?] [6613]*/ + 0x10,0x11,0x21,0x21,0x49,0xF9,0x11,0x21,0x40,0xF8,0x40,0x02,0x1A,0xE4,0x40,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x00,0x40,0x24,0xA2,0x8A,0x88,0x78,0x00, + /* 0xE7C2 [?] [6614]*/ + 0x11,0x11,0x21,0x22,0x4A,0xF2,0x16,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x42,0x02, + 0x00,0xFE,0x10,0x10,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x90,0x50,0x20,0x58,0x86, + /* 0xE7C3 [?] [6615]*/ + 0x11,0x11,0x21,0x22,0x4A,0xF6,0x1A,0x22,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x42,0x02, + 0x00,0x78,0x08,0x08,0xFE,0x40,0x40,0x7C,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xE7C4 [?] [6616]*/ + 0x10,0x12,0x21,0x25,0x44,0xF8,0x13,0x21,0x41,0xFD,0x41,0x01,0x1D,0xE2,0x44,0x00, + 0x10,0x20,0x7C,0x44,0x44,0x7C,0x40,0x40,0x7C,0x44,0x44,0x7C,0x44,0x80,0x7E,0x00, + /* 0xE7C5 [?] [6617]*/ + 0x10,0x13,0x22,0x23,0x4A,0xFB,0x12,0x22,0x43,0xF8,0x43,0x02,0x1B,0xE2,0x43,0x02, + 0x00,0xFC,0x04,0xFC,0x20,0xFE,0x10,0x8A,0x06,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xE7C6 [?] [6618]*/ + 0x10,0x13,0x20,0x22,0x49,0xF8,0x17,0x20,0x41,0xF9,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x00,0xFC,0x90,0x94,0x98,0x90,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08, + /* 0xE7C7 [?] [6619]*/ + 0x10,0x10,0x27,0x20,0x4B,0xFA,0x13,0x22,0x43,0xFA,0x43,0x02,0x1F,0xE1,0x42,0x04, + 0x40,0x40,0xFC,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xFE,0x10,0x08,0x04, + /* 0xE7C8 [?] [6620]*/ + 0x10,0x13,0x22,0x22,0x4A,0xFB,0x12,0x22,0x42,0xFA,0x42,0x03,0x1A,0xE4,0x44,0x08, + 0x00,0xFE,0x00,0xFC,0x00,0xFE,0xA8,0x90,0xC8,0x86,0x08,0xFE,0x88,0x48,0x08,0x18, + /* 0xE7C9 [?] [6621]*/ + 0x10,0x10,0x23,0x20,0x49,0xF9,0x11,0x20,0x43,0xFA,0x42,0x02,0x1A,0xE2,0x42,0x02, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE7CA [?] [6622]*/ + 0x10,0x10,0x23,0x20,0x49,0xF9,0x11,0x21,0x40,0xFB,0x42,0x02,0x1A,0xE2,0x42,0x02, + 0x40,0x20,0xFE,0x00,0x54,0x24,0x54,0xFC,0x20,0xFE,0x42,0x92,0xFA,0x0A,0x02,0x06, + /* 0xE7CB [?] [6623]*/ + 0x11,0x10,0x20,0x20,0x4B,0xF8,0x10,0x21,0x42,0xF9,0x41,0x01,0x19,0xE1,0x47,0x00, + 0x04,0x84,0x88,0x00,0xFE,0x00,0x88,0x04,0x02,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xE7CC [?] [6624]*/ + 0x10,0x10,0x20,0x25,0x44,0xF9,0x10,0x23,0x40,0xFD,0x40,0x00,0x1D,0xE2,0x40,0x00, + 0x88,0x50,0x00,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50,0x50, + /* 0xE7CD [?] [6625]*/ + 0x10,0x10,0x23,0x22,0x4C,0xF9,0x11,0x21,0x41,0xF9,0x41,0x07,0x18,0xE0,0x41,0x02, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xE7CE [?] [6626]*/ + 0x10,0x13,0x20,0x25,0x45,0xF9,0x11,0x20,0x41,0xFC,0x43,0x00,0x1C,0xE1,0x42,0x00, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xE7CF [?] [6627]*/ + 0x10,0x11,0x21,0x21,0x49,0xF9,0x10,0x23,0x42,0xFB,0x40,0x01,0x18,0xE0,0x41,0x06, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0xFC,0x00,0xF8,0x90,0x60,0x98,0x06, + /* 0xE7D0 [?] [6628]*/ + 0x10,0x11,0x21,0x25,0x45,0xF9,0x10,0x20,0x41,0xFC,0x40,0x03,0x1C,0xE1,0x42,0x00, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x40,0x88,0xF0,0x20,0x44,0xFE,0x22,0x24,0x22,0x60, + /* 0xE7D1 [?] [6629]*/ + 0x10,0x17,0x20,0x24,0x4A,0xF4,0x10,0x21,0x46,0xF8,0x43,0x00,0x1B,0xE0,0x40,0x07, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x50,0x88,0x26,0xC0,0x10,0x64,0x88,0x30,0xC0,0x00, + /* 0xE7D2 [?] [6630]*/ + 0x11,0x12,0x21,0x24,0x45,0xF9,0x11,0x21,0x41,0xFC,0x43,0x00,0x1C,0xE1,0x46,0x00, + 0x24,0x48,0x24,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xE7D3 [?] [6631]*/ + 0x22,0x22,0x22,0x4F,0x52,0xF2,0x27,0x20,0x40,0xF7,0x45,0x05,0x35,0xC7,0x05,0x00, + 0x00,0xFE,0x10,0xA0,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xE7D4 [?] [6632]*/ + 0x10,0x10,0x23,0x20,0x4A,0xF9,0x13,0x25,0x41,0xF9,0x41,0x00,0x19,0xE2,0x44,0x00, + 0x20,0x20,0xFE,0x50,0x8A,0x04,0xFE,0x04,0xFC,0x04,0xFC,0x20,0x24,0x22,0xA2,0x40, + /* 0xE7D5 [?] [6633]*/ + 0x11,0x10,0x20,0x23,0x4A,0xFA,0x12,0x22,0x43,0xF8,0x41,0x01,0x19,0xE1,0x41,0x01, + 0x04,0x88,0x00,0xFE,0x22,0xAA,0x72,0x22,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xE7D6 [?] [6634]*/ + 0x10,0x13,0x20,0x25,0x45,0xF9,0x11,0x23,0x40,0xFD,0x41,0x01,0x1D,0xE1,0x40,0x03, + 0x00,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE, + /* 0xE7D7 [?] [6635]*/ + 0x10,0x14,0x22,0x22,0x48,0xF9,0x10,0x2E,0x42,0xFA,0x42,0x02,0x1A,0xE2,0x45,0x08, + 0x10,0xFE,0x92,0xFE,0x10,0xFE,0x00,0xFE,0x82,0xFE,0x80,0xFE,0x82,0xFE,0x00,0xFE, + /* 0xE7D8 [?] [6636]*/ + 0x11,0x11,0x21,0x21,0x48,0xFB,0x12,0x22,0x43,0xF8,0x47,0x00,0x18,0xE1,0x46,0x00, + 0xFC,0x04,0x04,0xFC,0x00,0xDE,0x52,0x52,0xDE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xE7D9 [?] [6637]*/ + 0x10,0x13,0x22,0x22,0x4B,0xF8,0x17,0x20,0x43,0xFA,0x43,0x00,0x19,0xE3,0x4D,0x01, + 0x00,0xFC,0x94,0x94,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0xA2,0x14,0x08,0x44,0x82, + /* 0xE7DA [?] [6638]*/ + 0x21,0x25,0x27,0x49,0x57,0xF3,0x25,0x29,0x40,0xF3,0x42,0x02,0x32,0xC0,0x01,0x06, + 0x08,0x28,0xBE,0x48,0xBE,0x18,0xAA,0x46,0x00,0xF8,0x08,0x48,0x48,0xB0,0x08,0x04, + /* 0xE7DB [?] [6639]*/ + 0x02,0x02,0x04,0x08,0x10,0x20,0x7F,0x20,0x01,0x02,0x04,0x08,0x10,0x3F,0x10,0x00, + 0x00,0x00,0x00,0x10,0x10,0x20,0xC0,0x80,0x00,0x00,0x00,0x20,0x10,0xF8,0x08,0x00, + /* 0xE7DC [?] [6640]*/ + 0x11,0x21,0x45,0x79,0x11,0x25,0x7D,0x05,0x01,0xFF,0x00,0x7C,0x54,0x7C,0x54,0x7D, + 0x10,0x20,0x44,0x78,0x10,0x24,0x7C,0x24,0x10,0xFE,0x80,0x88,0x52,0x22,0x5A,0x86, + /* 0xE7DD [?] [6641]*/ + 0x00,0x00,0x08,0x08,0x08,0x11,0x11,0x22,0x22,0x11,0x11,0x08,0x08,0x08,0x00,0x00, + 0x00,0x00,0x88,0x88,0x88,0x10,0x10,0x20,0x20,0x10,0x10,0x88,0x88,0x88,0x00,0x00, + /* 0xE7DE [?] [6642]*/ + 0x08,0x11,0x22,0x11,0x08,0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x20, + 0x88,0x10,0x20,0x10,0x88,0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xE7DF [?] [6643]*/ + 0x08,0x11,0x22,0x11,0x08,0x1F,0x10,0x1F,0x00,0x3F,0x21,0x21,0x3F,0x20,0x20,0x1F, + 0x88,0x10,0x20,0x10,0x88,0xF0,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x02,0x02,0xFE, + /* 0xE7E0 [?] [6644]*/ + 0x00,0x00,0xFE,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x1E,0xF0,0x40,0x00,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xE7E1 [?] [6645]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE2,0x42,0x04, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xE7E2 [?] [6646]*/ + 0x00,0x00,0xFC,0x13,0x10,0x10,0x11,0x7C,0x10,0x13,0x10,0x10,0x1C,0xE0,0x40,0x00, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x40,0x40,0xFE,0x42,0x42,0x4A,0x44,0x40,0x40, + /* 0xE7E3 [?] [6647]*/ + 0x00,0x00,0xFC,0x10,0x11,0x11,0x12,0x7D,0x10,0x10,0x10,0x10,0x1D,0xE1,0x42,0x04, + 0x10,0x90,0x90,0x88,0x08,0x04,0x04,0xFA,0x88,0x88,0x88,0x88,0x08,0x08,0x28,0x10, + /* 0xE7E4 [?] [6648]*/ + 0x00,0x00,0xFC,0x13,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x1C,0xE0,0x41,0x06, + 0x40,0x20,0x20,0xFE,0x88,0x88,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xE7E5 [?] [6649]*/ + 0x00,0x00,0xFD,0x10,0x10,0x10,0x10,0x7C,0x11,0x10,0x10,0x10,0x1C,0xE0,0x43,0x00, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x24,0x20,0xFE,0x00, + /* 0xE7E6 [?] [6650]*/ + 0x00,0x00,0xFD,0x10,0x10,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1C,0xE0,0x40,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xE7E7 [?] [6651]*/ + 0x00,0x00,0xFC,0x10,0x13,0x10,0x10,0x7C,0x10,0x10,0x11,0x11,0x1D,0xE2,0x42,0x04, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0xA8,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xE7E8 [?] [6652]*/ + 0x00,0x00,0xFC,0x10,0x10,0x10,0x10,0x7C,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE7E9 [?] [6653]*/ + 0x00,0x00,0xFC,0x10,0x10,0x11,0x11,0x7E,0x10,0x10,0x10,0x10,0x1C,0xE0,0x40,0x00, + 0x50,0x54,0x52,0x92,0x90,0x9E,0xF0,0x90,0x90,0x90,0x90,0x90,0x8A,0x8A,0x86,0x82, + /* 0xE7EA [?] [6654]*/ + 0x00,0x00,0xFC,0x11,0x11,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE7EB [?] [6655]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0x10,0x12,0x4A,0x86,0x02, + /* 0xE7EC [?] [6656]*/ + 0x02,0x02,0xFA,0x22,0x27,0x22,0x22,0xFA,0x22,0x22,0x22,0x3A,0xE4,0x44,0x09,0x10, + 0x00,0x00,0x00,0x1E,0xD2,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x5E,0x52,0x80, + /* 0xE7ED [?] [6657]*/ + 0x00,0x03,0xFD,0x11,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE3,0x40,0x00,0x00, + 0x00,0xFE,0x08,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x1E,0xE8,0x08,0x08,0x08, + /* 0xE7EE [?] [6658]*/ + 0x00,0x00,0xFC,0x10,0x13,0x10,0x10,0x7C,0x10,0x17,0x10,0x10,0x1C,0xE1,0x42,0x04, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xFE,0x00,0x88,0x84,0x04,0x02,0x02, + /* 0xE7EF [?] [6659]*/ + 0x00,0x01,0x7C,0x10,0x11,0x11,0x7D,0x11,0x11,0x11,0x11,0x1D,0xE0,0x40,0x01,0x02, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xE7F0 [?] [6660]*/ + 0x00,0x07,0xF8,0x24,0x24,0x24,0x27,0xF8,0x21,0x21,0x22,0x3A,0xE4,0x48,0x02,0x01, + 0x00,0xDE,0x92,0x92,0x94,0x94,0xD8,0x94,0x92,0x92,0x92,0x9A,0x94,0x90,0x90,0x10, + /* 0xE7F1 [?] [6661]*/ + 0x00,0x00,0xF9,0x22,0x24,0x20,0x21,0xFB,0x25,0x21,0x21,0x39,0xE1,0x41,0x01,0x01, + 0x80,0x80,0x3C,0x00,0x80,0x80,0x7E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xE7F2 [?] [6662]*/ + 0x00,0x00,0xF8,0x22,0x21,0x20,0x20,0xF9,0x22,0x24,0x20,0x20,0x39,0xE1,0x02,0x04, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xE7F3 [?] [6663]*/ + 0x00,0x00,0xF8,0x21,0x23,0x24,0x20,0xF8,0x21,0x22,0x25,0x21,0x39,0xE1,0x01,0x01, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xE7F4 [?] [6664]*/ + 0x08,0x08,0x1F,0x21,0x41,0x09,0x11,0x25,0x02,0x7F,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x00,0x00,0xFC,0x04,0x08,0x20,0x10,0x08,0x00,0xFC,0x00,0xF8,0x20,0x10,0xFE,0x00, + /* 0xE7F5 [?] [6665]*/ + 0x00,0x03,0xFA,0x24,0x20,0x23,0x20,0xF8,0x21,0x21,0x20,0x38,0xE3,0x40,0x00,0x00, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE7F6 [?] [6666]*/ + 0x00,0x04,0xFA,0x22,0x20,0x20,0x2E,0xFA,0x22,0x22,0x23,0x3A,0xE2,0x45,0x08,0x00, + 0x20,0x20,0x20,0xFE,0x40,0x50,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xE7F7 [?] [6667]*/ + 0x01,0x01,0xFB,0x21,0x21,0x21,0x21,0xF9,0x21,0x21,0x21,0x3B,0xE0,0x40,0x01,0x02, + 0x08,0x08,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00,0x90,0x08,0x04, + /* 0xE7F8 [?] [6668]*/ + 0x00,0x00,0xFB,0x20,0x20,0x20,0x21,0xF9,0x21,0x21,0x23,0x38,0xE0,0x40,0x01,0x02, + 0x88,0x88,0xFE,0x88,0xA8,0x20,0xFC,0x24,0x24,0x24,0xFE,0x20,0x50,0x88,0x04,0x02, + /* 0xE7F9 [?] [6669]*/ + 0x00,0x00,0xFB,0x20,0x21,0x22,0x27,0xF8,0x23,0x22,0x22,0x3A,0xE3,0x40,0x00,0x00, + 0x40,0x40,0xFC,0xA0,0x10,0x08,0xFE,0x08,0xC8,0x48,0x48,0x48,0xC8,0x08,0x28,0x10, + /* 0xE7FA [?] [6670]*/ + 0x00,0x00,0xF8,0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x22,0x3A,0xE4,0x44,0x09,0x12, + 0x40,0x40,0x7C,0x40,0xFC,0x44,0x70,0xC0,0x44,0x3C,0x00,0xF0,0x90,0x92,0x12,0x0E, + /* 0xE7FB [?] [6671]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7D,0x10,0x11,0x11,0x11,0x1D,0xE1,0x41,0x01, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xE7FC [?] [6672]*/ + 0x00,0x01,0xF9,0x22,0x20,0x20,0x23,0xF8,0x20,0x21,0x21,0x22,0x38,0xE0,0x01,0x06, + 0x20,0x22,0x22,0x24,0x50,0x88,0x04,0x22,0x20,0x24,0x24,0x28,0x50,0x88,0x04,0x02, + /* 0xE7FD [?] [6673]*/ + 0x00,0x00,0xFB,0x22,0x20,0x21,0x20,0xF8,0x23,0x20,0x21,0x39,0xE2,0x44,0x00,0x00, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xE7FE [?] [6674]*/ + 0x00,0x00,0xFB,0x22,0x25,0x21,0x21,0xFA,0x22,0x23,0x24,0x38,0xE1,0x41,0x02,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xE8A1 [?] [6675]*/ + 0x00,0x07,0xFC,0x24,0x21,0x22,0x20,0xF8,0x27,0x20,0x20,0x39,0xE2,0x4C,0x00,0x00, + 0x00,0xFC,0x04,0xA4,0x10,0x08,0x40,0x40,0xFC,0x40,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xE8A2 [?] [6676]*/ + 0x00,0x03,0xFA,0x22,0x23,0x22,0x22,0xFB,0x22,0x22,0x22,0x3A,0xE2,0x44,0x04,0x08, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xE8A3 [?] [6677]*/ + 0x00,0x01,0xFD,0x11,0x11,0x11,0x11,0x7C,0x10,0x10,0x10,0x10,0x1C,0xE0,0x40,0x00, + 0x00,0xFE,0x02,0x7A,0x02,0x7A,0x02,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0xFC,0x84, + /* 0xE8A4 [?] [6678]*/ + 0x00,0x00,0xF9,0x22,0x25,0x20,0x23,0xFA,0x22,0x23,0x22,0x3A,0xE3,0x42,0x02,0x02, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xE8A5 [?] [6679]*/ + 0x00,0x07,0xFA,0x21,0x20,0x23,0x20,0xF8,0x27,0x21,0x21,0x3A,0xE2,0x44,0x08,0x03, + 0x3C,0xC0,0x44,0x28,0x00,0xFC,0x80,0x80,0xFE,0x00,0xF8,0x88,0x50,0x20,0xD8,0x06, + /* 0xE8A6 [?] [6680]*/ + 0x00,0x03,0xFA,0x22,0x22,0x23,0x22,0xFA,0x23,0x22,0x22,0x3B,0xE2,0x42,0x02,0x02, + 0x00,0xDE,0x42,0x42,0x42,0xDE,0x00,0x3E,0xD2,0x12,0x14,0xD4,0x08,0x14,0x24,0x42, + /* 0xE8A7 [?] [6681]*/ + 0x00,0x01,0xFA,0x21,0x20,0x20,0x20,0xFB,0x22,0x22,0x22,0x3A,0xE2,0x42,0x03,0x02, + 0x92,0x24,0x48,0x24,0x92,0x40,0x80,0xFE,0x02,0x8A,0x52,0x22,0x52,0x8A,0xFE,0x02, + /* 0xE8A8 [?] [6682]*/ + 0x00,0x03,0xF8,0x22,0x21,0x23,0x22,0xF8,0x23,0x20,0x20,0x39,0xE1,0x42,0x04,0x01, + 0x0E,0xF0,0x44,0x24,0x08,0xFE,0x42,0x40,0xFE,0x80,0xFC,0x44,0x28,0x10,0x68,0x86, + /* 0xE8A9 [?] [6683]*/ + 0x00,0x00,0xFB,0x22,0x22,0x22,0x23,0xFA,0x22,0x22,0x22,0x3A,0xE2,0x44,0x04,0x08, + 0x20,0x10,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xE8AA [?] [6684]*/ + 0x00,0x00,0xFB,0x20,0x20,0x20,0x21,0xF9,0x21,0x20,0x23,0x38,0xE1,0x40,0x03,0x00, + 0x88,0x88,0xFE,0x88,0xF8,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE8AB [?] [6685]*/ + 0x00,0x00,0xFD,0x10,0x10,0x13,0x10,0x7D,0x11,0x11,0x11,0x11,0x1C,0xE0,0x41,0x02, + 0x88,0x88,0xFC,0x88,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0x88,0x04,0x02, + /* 0xE8AC [?] [6686]*/ + 0x00,0x0F,0xF8,0x2A,0x2A,0x2A,0x25,0xF8,0x20,0x2F,0x21,0x3A,0xE3,0x40,0x01,0x0E, + 0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0x80,0xFE,0x10,0x10,0xA0,0x60,0x98,0x04, + /* 0xE8AD [?] [6687]*/ + 0x00,0x02,0xFB,0x20,0x20,0x21,0x23,0xFD,0x21,0x21,0x21,0x39,0xE1,0x41,0x01,0x01, + 0x20,0x22,0xFE,0x90,0x88,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xE8AE [?] [6688]*/ + 0x00,0x00,0xFB,0x22,0x22,0x23,0x22,0xFA,0x22,0x23,0x20,0x38,0xE5,0x45,0x09,0x00, + 0x40,0x80,0xFC,0x44,0xF4,0x14,0xA4,0x44,0xA4,0xFC,0x40,0x24,0x22,0x0A,0x08,0xF8, + /* 0xE8AF [?] [6689]*/ + 0x02,0x01,0xF9,0x27,0x22,0x22,0x23,0xFA,0x22,0x22,0x22,0x3A,0xE4,0x45,0x08,0x10, + 0x10,0x10,0x10,0xBE,0x40,0x00,0xBE,0x8A,0x88,0xA8,0xAE,0xA8,0xA8,0xA8,0x5E,0x80, + /* 0xE8B0 [?] [6690]*/ + 0x00,0x01,0xFC,0x10,0x13,0x10,0x7D,0x11,0x11,0x11,0x11,0x1C,0xE3,0x40,0x00,0x00, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xE8B1 [?] [6691]*/ + 0x00,0x02,0xF9,0x20,0x23,0x20,0x20,0xFB,0x20,0x21,0x20,0x3B,0xE0,0x40,0x01,0x06, + 0x50,0x52,0x54,0x50,0xFE,0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xE8B2 [?] [6692]*/ + 0x00,0x00,0xFA,0x23,0x24,0x2A,0x23,0xFC,0x22,0x21,0x27,0x38,0xE1,0x42,0x0C,0x00, + 0x80,0xDC,0x84,0xD4,0x48,0x94,0x24,0x40,0x48,0x50,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xE8B3 [?] [6693]*/ + 0x00,0x00,0xF8,0x23,0x22,0x22,0x23,0xFA,0x22,0x23,0x22,0x3B,0xE2,0x45,0x04,0x09, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x00,0xFE,0x40,0xA4,0x58,0xB4,0x52,0xB0, + /* 0xE8B4 [?] [6694]*/ + 0x00,0x07,0xFC,0x24,0x24,0x27,0x21,0xF9,0x21,0x25,0x25,0x3D,0xE5,0x45,0x0E,0x00, + 0x10,0x90,0xBC,0xA4,0xC4,0xA8,0x10,0x28,0x46,0xC0,0x3C,0x24,0x24,0xA4,0x3C,0x24, + /* 0xE8B5 [?] [6695]*/ + 0x3E,0x22,0x3E,0x20,0x7E,0xA2,0x3E,0x22,0x00,0x7F,0x01,0x3F,0x01,0x01,0xFF,0x00, + 0x10,0xFE,0x44,0x28,0xFE,0x10,0xFC,0x10,0x00,0xFC,0x00,0xF8,0x20,0x10,0xFE,0x00, + /* 0xE8B6 [?] [6696]*/ + 0x01,0x05,0xFF,0x29,0x27,0x23,0x25,0xF9,0x20,0x23,0x22,0x3A,0xE2,0x40,0x01,0x06, + 0x08,0x28,0xBE,0x48,0xBE,0x18,0xAA,0x46,0x00,0xF8,0x08,0x48,0x48,0xB0,0x08,0x04, + /* 0xE8B7 [?] [6697]*/ + 0x2F,0x48,0x4B,0x68,0x4B,0x6A,0x4B,0x48,0xFF,0x80,0x7F,0x01,0x3F,0x01,0x01,0xFF, + 0xEC,0x24,0xA4,0x2C,0xA4,0xAC,0xA4,0x24,0xFE,0x02,0xFC,0x00,0xF8,0x20,0x10,0xFE, + /* 0xE8B8 [?] [6698]*/ + 0x00,0x3E,0x22,0x3E,0x22,0x3E,0x00,0xFF,0x08,0x08,0x2F,0x28,0x28,0x58,0x4F,0x80, + 0x20,0x20,0xFC,0x20,0x20,0xF8,0x20,0x20,0xFC,0x24,0x24,0x34,0x28,0x20,0xFE,0x00, + /* 0xE8B9 [?] [6699]*/ + 0x20,0x20,0x20,0xFC,0x20,0x20,0xF8,0x20,0x20,0xFD,0x25,0x25,0x35,0x29,0x23,0x20, + 0x00,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xE8BA [?] [6700]*/ + 0x20,0x21,0x20,0xFD,0x20,0x20,0xF8,0x21,0x21,0xFD,0x25,0x25,0x35,0x29,0x21,0x21, + 0x1E,0xE0,0x22,0x12,0x94,0x80,0x20,0xCE,0x02,0x02,0xCE,0x02,0x02,0x02,0xFE,0x02, + /* 0xE8BB [?] [6701]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x00,0x00,0xFC,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xE8BC [?] [6702]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x30,0x39,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xE8BD [?] [6703]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x30,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x10,0x10, + 0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE8BE [?] [6704]*/ + 0x10,0x13,0x11,0x11,0xFD,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x11,0x16, + 0x00,0xFC,0x04,0x44,0x24,0xA8,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xE8BF [?] [6705]*/ + 0x10,0x13,0x10,0x10,0xFD,0x11,0x31,0x39,0x54,0x54,0x90,0x13,0x10,0x10,0x10,0x10, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xFC,0x04,0x04,0x04,0xF4,0x04,0x04,0x28,0x10, + /* 0xE8C0 [?] [6706]*/ + 0x20,0x23,0x22,0x22,0xFA,0x22,0x22,0x72,0x6A,0xA2,0xA2,0x22,0x24,0x24,0x29,0x32, + 0x00,0xFE,0x00,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xE8C1 [?] [6707]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x10, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xE8C2 [?] [6708]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x31,0x39,0x56,0x54,0x90,0x10,0x10,0x10,0x10,0x13, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xE8C3 [?] [6709]*/ + 0x01,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xE8C4 [?] [6710]*/ + 0x10,0x10,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xE8C5 [?] [6711]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x10,0x10,0x11,0x12,0x14, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xE8C6 [?] [6712]*/ + 0x10,0x10,0x10,0x11,0xFD,0x12,0x30,0x38,0x57,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xE8C7 [?] [6713]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x30,0x3B,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x80,0x84,0x84,0x88,0x90,0xA0,0x80,0xFE,0xA0,0x90,0x90,0x88,0x84,0xA2,0xC0,0x80, + /* 0xE8C8 [?] [6714]*/ + 0x11,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x52,0x92,0x12,0x14,0x14,0x18,0x11, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xA8,0x68,0x28,0x44,0x44,0x84,0x02, + /* 0xE8C9 [?] [6715]*/ + 0x01,0x02,0x1F,0x10,0x12,0x11,0x10,0x1F,0x01,0x01,0x7F,0x03,0x05,0x19,0xE1,0x01, + 0x00,0x00,0xF0,0x10,0x10,0x50,0x20,0xFC,0x04,0x04,0xF4,0x88,0x40,0x30,0x0E,0x00, + /* 0xE8CA [?] [6716]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xE8CB [?] [6717]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x10,0x10, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE8CC [?] [6718]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x00,0xF8,0x08,0x50,0x20,0x10,0xFE,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xE8CD [?] [6719]*/ + 0x01,0x01,0x7F,0x05,0x09,0x31,0xCF,0x00,0x00,0x7F,0x01,0x11,0x11,0x21,0x45,0x02, + 0x00,0x00,0xFC,0x40,0x20,0x18,0xE6,0x00,0x00,0xFC,0x00,0x10,0x08,0x04,0x04,0x00, + /* 0xE8CE [?] [6720]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x88,0x88,0xFE,0x88,0x88,0x00,0xFE,0x42,0x42,0x42,0x42,0x4A,0x44,0x40,0x40,0x40, + /* 0xE8CF [?] [6721]*/ + 0x10,0x10,0x13,0x10,0xFC,0x10,0x30,0x38,0x55,0x52,0x94,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xE8D0 [?] [6722]*/ + 0x10,0x10,0x10,0x10,0xFB,0x10,0x30,0x38,0x54,0x51,0x91,0x11,0x12,0x12,0x14,0x18, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0x28,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xE8D1 [?] [6723]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x32,0x3A,0x57,0x52,0x92,0x12,0x13,0x12,0x13,0x10, + 0x00,0xFC,0x00,0x40,0x40,0x78,0x88,0x90,0x10,0x20,0x50,0x88,0x04,0x00,0xFE,0x00, + /* 0xE8D2 [?] [6724]*/ + 0x10,0x11,0x10,0x10,0xFD,0x10,0x30,0x38,0x57,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xE8D3 [?] [6725]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x20,0x20,0x3E,0x20,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00, + /* 0xE8D4 [?] [6726]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x10,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xE8D5 [?] [6727]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x30,0x3B,0x54,0x55,0x91,0x10,0x10,0x10,0x10,0x10, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0xFE,0x80,0x00,0xF8,0x08,0x08,0x08,0x50,0x20, + /* 0xE8D6 [?] [6728]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xE8D7 [?] [6729]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x10,0x10,0x11,0x12,0x14, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xE8D8 [?] [6730]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x08,0x1C,0xE0,0x00,0x00,0x00,0xFE,0x10,0x10,0x30,0x18,0x14,0x12,0x10,0x10,0x10, + /* 0xE8D9 [?] [6731]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x12,0x14, + 0x1C,0xE0,0x00,0x00,0xFE,0x00,0x00,0x7C,0x44,0x44,0x54,0x48,0x42,0x42,0x3E,0x00, + /* 0xE8DA [?] [6732]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x32,0x38,0x55,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xE8DB [?] [6733]*/ + 0x10,0x10,0x10,0x11,0xFD,0x12,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0x24,0xE4,0x24,0x04,0x28,0x10, + /* 0xE8DC [?] [6734]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x32,0x3B,0x56,0x52,0x92,0x12,0x12,0x12,0x13,0x12, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xE8DD [?] [6735]*/ + 0x10,0x10,0x13,0x12,0xFE,0x12,0x32,0x3B,0x54,0x54,0x91,0x11,0x12,0x14,0x10,0x10, + 0x08,0x3C,0xC0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xE8DE [?] [6736]*/ + 0x10,0x10,0x10,0x11,0xFD,0x12,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xE8DF [?] [6737]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x30,0x38,0x57,0x50,0x91,0x10,0x10,0x10,0x13,0x10, + 0x00,0xFC,0x84,0x88,0x50,0x20,0x50,0x88,0x26,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE8E0 [?] [6738]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x38,0x55,0x52,0x94,0x10,0x10,0x10,0x10,0x10, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xE8E1 [?] [6739]*/ + 0x10,0x10,0x10,0x11,0xFC,0x10,0x33,0x38,0x54,0x55,0x92,0x14,0x10,0x10,0x10,0x10, + 0x40,0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0x84,0x98,0xE0,0x82,0x82,0x7E,0x00, + /* 0xE8E2 [?] [6740]*/ + 0x10,0x11,0x10,0x10,0xFC,0x10,0x32,0x39,0x55,0x55,0x90,0x10,0x10,0x10,0x13,0x10, + 0x00,0xFE,0x48,0x48,0x48,0x48,0x48,0x4A,0x4A,0x4C,0x48,0x48,0x48,0x48,0xFE,0x00, + /* 0xE8E3 [?] [6741]*/ + 0x10,0x10,0x10,0x13,0xFC,0x10,0x30,0x3B,0x54,0x53,0x90,0x10,0x11,0x11,0x12,0x14, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xE8E4 [?] [6742]*/ + 0x10,0x13,0x10,0x10,0xFC,0x11,0x33,0x38,0x54,0x54,0x93,0x10,0x10,0x10,0x17,0x10, + 0x00,0xFE,0x20,0x40,0x88,0x04,0xFE,0x22,0x20,0x20,0xFE,0x20,0x20,0x20,0xFE,0x00, + /* 0xE8E5 [?] [6743]*/ + 0x10,0x10,0x10,0x10,0xFC,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x10,0x11, + 0x20,0x20,0x3E,0x20,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xE8E6 [?] [6744]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x11,0x11,0x12,0x14, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xE8E7 [?] [6745]*/ + 0x10,0x11,0x11,0x11,0xFD,0x10,0x31,0x38,0x54,0x55,0x91,0x11,0x11,0x11,0x10,0x10, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xE8E8 [?] [6746]*/ + 0x20,0x20,0x27,0x21,0xF9,0x22,0x32,0x6F,0x61,0xA5,0xA5,0x22,0x22,0x25,0x28,0x30, + 0x00,0x0C,0x70,0x10,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,0xFE,0x00, + /* 0xE8E9 [?] [6747]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x38,0x54,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xE8EA [?] [6748]*/ + 0x10,0x10,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x10, + 0x00,0x40,0x9C,0x04,0x04,0x04,0x04,0xDC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00, + /* 0xE8EB [?] [6749]*/ + 0x10,0x10,0x11,0x11,0xFB,0x15,0x31,0x39,0x55,0x50,0x93,0x10,0x10,0x10,0x10,0x10, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xE8EC [?] [6750]*/ + 0x10,0x10,0x11,0x12,0xFC,0x10,0x31,0x3B,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x80,0x80,0x3C,0x00,0x80,0x80,0x7E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xE8ED [?] [6751]*/ + 0x10,0x10,0x10,0x10,0xFD,0x12,0x38,0x34,0x50,0x53,0x90,0x10,0x10,0x11,0x13,0x11, + 0x20,0x20,0x50,0x88,0x04,0x02,0xF8,0x00,0x00,0xFE,0x20,0x40,0x88,0x04,0xFE,0x02, + /* 0xE8EE [?] [6752]*/ + 0x10,0x10,0x3E,0x42,0xA4,0x14,0x08,0x10,0x20,0x41,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x10,0x10,0xFC,0x10,0x90,0x90,0xFE,0x10,0x10,0x10,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE8EF [?] [6753]*/ + 0x02,0x01,0xFF,0x04,0x14,0x14,0x24,0x44,0x00,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x44,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE8F0 [?] [6754]*/ + 0x01,0x11,0x09,0x3F,0x02,0x02,0x7F,0x08,0x11,0x21,0xDF,0x03,0x05,0x19,0x61,0x01, + 0x00,0x10,0x20,0xF8,0x00,0x00,0xFC,0x20,0x10,0x08,0xF6,0x00,0xC0,0x30,0x08,0x00, + /* 0xE8F1 [?] [6755]*/ + 0x10,0x10,0x10,0x13,0xFE,0x14,0x30,0x3B,0x54,0x54,0x91,0x10,0x10,0x10,0x10,0x13, + 0x40,0x20,0x20,0xFE,0x02,0x44,0x40,0xFE,0x88,0x88,0x08,0xD0,0x20,0x50,0x88,0x04, + /* 0xE8F2 [?] [6756]*/ + 0x10,0x13,0x10,0x10,0xFE,0x11,0x31,0x38,0x54,0x51,0x92,0x10,0x10,0x10,0x11,0x10, + 0x00,0xDE,0x42,0x42,0x52,0x4A,0x4A,0x42,0xC6,0x4A,0x52,0x42,0x42,0x42,0x4A,0x84, + /* 0xE8F3 [?] [6757]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC8,0x00,0x0F,0x08,0x08,0x0A,0x09,0x11,0x20,0x40, + 0x20,0x20,0xFC,0x20,0x70,0xA8,0x26,0x00,0xE0,0x20,0x20,0x20,0x20,0x22,0x22,0x1E, + /* 0xE8F4 [?] [6758]*/ + 0x10,0x11,0x11,0x11,0xFD,0x12,0x30,0x3B,0x54,0x54,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xE8F5 [?] [6759]*/ + 0x10,0x10,0x11,0x10,0xFD,0x10,0x30,0x39,0x54,0x50,0x93,0x10,0x10,0x10,0x10,0x10, + 0x08,0x3C,0xC0,0x04,0x44,0xA8,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xE8F6 [?] [6760]*/ + 0x10,0x10,0x10,0x11,0xFA,0x15,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x24,0x24,0x14,0x08, + /* 0xE8F7 [?] [6761]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x33,0x38,0x54,0x54,0x91,0x10,0x10,0x10,0x10,0x10, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20, + /* 0xE8F8 [?] [6762]*/ + 0x20,0x22,0x21,0x21,0xF4,0x22,0x22,0x70,0x68,0xA1,0xA6,0x22,0x22,0x22,0x22,0x20, + 0x10,0x10,0x10,0x10,0x54,0x52,0x52,0x90,0x10,0x14,0x04,0x08,0x08,0x10,0x20,0xC0, + /* 0xE8F9 [?] [6763]*/ + 0x10,0x13,0x10,0x10,0xFD,0x10,0x30,0x3B,0x54,0x51,0x91,0x12,0x10,0x11,0x12,0x14, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x40,0x48,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xE8FA [?] [6764]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x38,0x54,0x51,0x92,0x10,0x10,0x10,0x10,0x10, + 0x20,0x22,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xE8FB [?] [6765]*/ + 0x08,0x08,0x7E,0x08,0x1C,0x2A,0xC8,0x04,0x08,0x10,0x2F,0xC4,0x04,0x08,0x10,0x60, + 0x20,0x20,0xFC,0x20,0x70,0xA8,0x24,0x40,0x20,0x10,0xE8,0x26,0x20,0x20,0xA0,0x40, + /* 0xE8FC [?] [6766]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x30,0x38,0x54,0x55,0x90,0x13,0x10,0x10,0x10,0x13, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x10,0x90,0xFE,0x28,0x44,0x82,0x02, + /* 0xE8FD [?] [6767]*/ + 0x10,0xFE,0x20,0x48,0x7E,0x08,0x0E,0xF9,0x4A,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE8FE [?] [6768]*/ + 0x10,0x10,0x10,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x13,0x10,0x10,0x10,0x10, + 0x20,0x20,0x3E,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE9A1 [?] [6769]*/ + 0x10,0x13,0x12,0x12,0xFE,0x13,0x30,0x38,0x54,0x51,0x92,0x10,0x10,0x10,0x11,0x16, + 0x00,0xFE,0x52,0x52,0x52,0xFE,0x20,0x40,0xFC,0x04,0x88,0x50,0x20,0x40,0x80,0x00, + /* 0xE9A2 [?] [6770]*/ + 0x20,0x20,0x23,0x20,0xF8,0x27,0x22,0x72,0x6F,0xA2,0xA2,0x27,0x20,0x20,0x27,0x20, + 0x10,0x78,0xC0,0x40,0x40,0xFC,0x48,0x48,0xFE,0x48,0x48,0xFC,0x40,0x40,0xFC,0x00, + /* 0xE9A3 [?] [6771]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x31,0x39,0x55,0x54,0x91,0x11,0x12,0x14,0x10,0x10, + 0x40,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xE9A4 [?] [6772]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x31,0x38,0x55,0x54,0x90,0x13,0x10,0x10,0x10,0x10, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFC,0x08,0x10,0xFE,0x20,0x20,0xA0,0x40, + /* 0xE9A5 [?] [6773]*/ + 0x20,0x20,0x20,0x2E,0xFB,0x22,0x24,0x74,0x6E,0xA2,0xA2,0x2B,0x24,0x26,0x29,0x30, + 0x20,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFE,0x00, + /* 0xE9A6 [?] [6774]*/ + 0x10,0x10,0x11,0x10,0xFC,0x13,0x38,0x34,0x51,0x52,0x91,0x10,0x11,0x12,0x10,0x10, + 0x20,0x20,0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x22,0x74,0xA8,0x24,0x22,0xA0,0x40, + /* 0xE9A7 [?] [6775]*/ + 0x10,0x13,0x12,0x12,0xFB,0x12,0x32,0x3B,0x56,0x52,0x92,0x12,0x12,0x14,0x14,0x18, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xE9A8 [?] [6776]*/ + 0x20,0x20,0x27,0x20,0xFB,0x20,0x27,0x71,0x6A,0xA5,0xA0,0x23,0x20,0x20,0x21,0x26, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x08,0xF6,0x40,0xF8,0x40,0xA0,0x10,0x08, + /* 0xE9A9 [?] [6777]*/ + 0x11,0x11,0x17,0x11,0xFD,0x11,0x39,0x35,0x51,0x57,0x92,0x12,0x13,0x12,0x13,0x10, + 0x10,0x10,0xFC,0x10,0xF0,0x10,0xF0,0x10,0x10,0xFE,0x00,0x90,0x08,0x00,0xFC,0x00, + /* 0xE9AA [?] [6778]*/ + 0x10,0x10,0x13,0x10,0xFC,0x13,0x32,0x3A,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x8A,0x52,0xFA,0x22,0x22,0xFA,0x22,0x22,0x2A,0x04, + /* 0xE9AB [?] [6779]*/ + 0x10,0x10,0x13,0x10,0xFC,0x11,0x32,0x39,0x55,0x51,0x91,0x11,0x11,0x10,0x13,0x10, + 0x20,0x20,0xFE,0x70,0xA8,0x24,0x22,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xE9AC [?] [6780]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x10,0x10,0x11,0x12,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x24,0xAC,0x74,0x24,0xFC,0x20,0x70,0xA8,0x24,0x22,0x20, + /* 0xE9AD [?] [6781]*/ + 0x10,0x12,0x12,0x12,0xFE,0x10,0x31,0x39,0x55,0x55,0x91,0x11,0x10,0x10,0x11,0x16, + 0x90,0x90,0x9E,0xA8,0xC4,0x80,0xFC,0x04,0x24,0x24,0x24,0x54,0x50,0x90,0x12,0x0E, + /* 0xE9AE [?] [6782]*/ + 0x10,0x11,0x11,0x11,0xFD,0x10,0x37,0x39,0x55,0x55,0x91,0x11,0x11,0x17,0x10,0x10, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0xFE,0x08,0xF8,0x08,0xF8,0x08,0x3E,0xC8,0x08,0x08, + /* 0xE9AF [?] [6783]*/ + 0x10,0x10,0x10,0x10,0xFC,0x10,0x30,0x38,0x54,0x53,0x92,0x12,0x12,0x12,0x13,0x12, + 0x00,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88,0x00,0xDE,0x52,0x52,0x52,0x52,0xDE,0x52, + /* 0xE9B0 [?] [6784]*/ + 0x20,0x20,0x3E,0x48,0x88,0x7E,0x14,0x22,0x40,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0xFC,0x80,0xF8,0x88,0xF8,0x80,0xFC,0x00,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE9B1 [?] [6785]*/ + 0x20,0x21,0x27,0x21,0xF9,0x21,0x27,0x71,0x6B,0xA3,0xA5,0x25,0x29,0x21,0x21,0x21, + 0x88,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xE9B2 [?] [6786]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x17,0x11,0x11,0x11, + 0x20,0xDC,0x14,0x14,0x14,0xD4,0x26,0x00,0xDC,0x14,0x14,0xD4,0x08,0x08,0x14,0x22, + /* 0xE9B3 [?] [6787]*/ + 0x10,0x12,0x11,0x11,0xFC,0x10,0x33,0x39,0x55,0x55,0x91,0x11,0x11,0x12,0x14,0x10, + 0x10,0x20,0x7C,0x44,0x44,0x7C,0x40,0x40,0x7C,0x44,0x44,0x7C,0x44,0x80,0x7E,0x00, + /* 0xE9B4 [?] [6788]*/ + 0x10,0x10,0x11,0x10,0xFC,0x10,0x33,0x38,0x54,0x55,0x90,0x10,0x11,0x12,0x10,0x10, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x20,0x20,0xFC,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xE9B5 [?] [6789]*/ + 0x11,0x10,0x12,0x12,0xFE,0x12,0x32,0x3A,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12, + 0x00,0xBC,0x84,0x04,0xF4,0x94,0x94,0xF4,0x04,0xF4,0x94,0x94,0xF4,0x04,0x14,0x08, + /* 0xE9B6 [?] [6790]*/ + 0x11,0x10,0x10,0x13,0xFC,0x11,0x30,0x3B,0x54,0x55,0x91,0x12,0x14,0x18,0x13,0x10, + 0x08,0x88,0x90,0xFC,0x40,0xF8,0x40,0xFE,0x80,0x00,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE9B7 [?] [6791]*/ + 0x10,0x11,0x10,0x10,0xFB,0x10,0x31,0x3A,0x54,0x50,0x90,0x13,0x10,0x10,0x10,0x10, + 0x44,0x24,0x88,0x10,0xFE,0x88,0x24,0x22,0xF8,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE9B8 [?] [6792]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x30,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x13,0x10, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xE9B9 [?] [6793]*/ + 0x10,0x13,0x12,0x12,0xFB,0x12,0x32,0x3A,0x56,0x52,0x92,0x12,0x12,0x12,0x14,0x18, + 0x00,0xFC,0x24,0x24,0xFC,0x00,0xFC,0x84,0x84,0xFC,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xE9BA [?] [6794]*/ + 0x10,0x13,0x11,0x11,0xFD,0x12,0x32,0x3A,0x54,0x51,0x93,0x12,0x12,0x12,0x17,0x10, + 0x00,0xF8,0x08,0x10,0x1C,0xE4,0xA4,0x54,0xA8,0x00,0xFC,0x94,0x94,0x94,0xFE,0x00, + /* 0xE9BB [?] [6795]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x3B,0x34,0x51,0x52,0x90,0x11,0x10,0x10,0x13,0x10, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x34,0xE2,0x20,0xFC,0x70,0xAC,0x22,0x20, + /* 0xE9BC [?] [6796]*/ + 0x10,0x13,0x12,0x12,0xFE,0x12,0x32,0x3A,0x56,0x52,0x92,0x12,0x12,0x12,0x13,0x10, + 0x00,0xFE,0x28,0x28,0xEE,0x28,0x28,0xEE,0x28,0x28,0xEE,0x28,0x28,0x28,0xFE,0x00, + /* 0xE9BD [?] [6797]*/ + 0x10,0x11,0x11,0x11,0xFD,0x11,0x38,0x34,0x53,0x50,0x92,0x11,0x12,0x10,0x11,0x10, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0x00,0xDE,0x42,0x52,0x4A,0x52,0x42,0x4A,0x84, + /* 0xE9BE [?] [6798]*/ + 0x10,0x10,0x11,0x13,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x13,0x10,0x10,0x10,0x10, + 0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xE9BF [?] [6799]*/ + 0x20,0x21,0x23,0x22,0xFB,0x22,0x33,0x6A,0x62,0xA7,0xA0,0x21,0x22,0x24,0x21,0x20, + 0x84,0x04,0xC4,0x44,0xDE,0x44,0xC4,0x64,0x54,0xD4,0xC4,0x44,0x44,0x44,0x54,0x88, + /* 0xE9C0 [?] [6800]*/ + 0x10,0x10,0x13,0x12,0xFB,0x12,0x33,0x38,0x57,0x51,0x92,0x14,0x1B,0x10,0x10,0x10, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x80,0xFC,0x10,0x48,0x44,0xFA,0x40,0x40,0x40, + /* 0xE9C1 [?] [6801]*/ + 0x20,0x20,0x27,0x20,0xFB,0x22,0x2F,0x72,0x6B,0xA0,0xA1,0x23,0x25,0x29,0x21,0x21, + 0x80,0x40,0xFE,0x00,0xF8,0x08,0xFE,0x08,0xF8,0xA4,0x28,0x10,0x10,0x48,0x86,0x00, + /* 0xE9C2 [?] [6802]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x31,0x38,0x57,0x52,0x92,0x12,0x12,0x12,0x12,0x12, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xE9C3 [?] [6803]*/ + 0x22,0x14,0xFF,0x08,0x49,0x49,0x7F,0x08,0x10,0x21,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x94,0x08,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE9C4 [?] [6804]*/ + 0x10,0x10,0x13,0x12,0xFC,0x11,0x31,0x39,0x55,0x51,0x91,0x17,0x10,0x10,0x11,0x12, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xE9C5 [?] [6805]*/ + 0x10,0x10,0x13,0x12,0xFC,0x10,0x31,0x38,0x54,0x51,0x92,0x10,0x10,0x10,0x10,0x10, + 0x40,0x20,0xFE,0x02,0x50,0x88,0x24,0x50,0x88,0x04,0xFA,0x88,0x88,0x88,0xF8,0x88, + /* 0xE9C6 [?] [6806]*/ + 0x20,0x24,0x22,0x22,0xF8,0x21,0x2E,0x72,0x6A,0xA3,0xA2,0x22,0x22,0x23,0x22,0x20, + 0x20,0x20,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x44,0x44,0x7C,0xC4,0x44,0x7C,0x44, + /* 0xE9C7 [?] [6807]*/ + 0x20,0x23,0x22,0x22,0xFB,0x22,0x22,0x72,0x6A,0xA2,0xA2,0x22,0x22,0x24,0x24,0x28, + 0x00,0xFE,0x02,0x02,0xFE,0x10,0x92,0x54,0xFE,0x82,0xFE,0x82,0xFE,0x82,0x8A,0x84, + /* 0xE9C8 [?] [6808]*/ + 0x10,0x10,0x17,0x10,0xFC,0x10,0x31,0x39,0x55,0x50,0x93,0x10,0x11,0x10,0x17,0x10, + 0x88,0x88,0xFE,0x88,0xF8,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00, + /* 0xE9C9 [?] [6809]*/ + 0x10,0x10,0x13,0x10,0xFD,0x10,0x33,0x38,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0xFE,0x20,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x74,0x54,0x74,0x04,0xFC,0x04, + /* 0xE9CA [?] [6810]*/ + 0x20,0x20,0x20,0x27,0xFC,0x24,0x24,0x74,0x6F,0xA4,0xA4,0x25,0x2A,0x28,0x31,0x20, + 0x14,0x12,0x10,0xFE,0x10,0x90,0xD2,0x92,0xF2,0x94,0x94,0xC8,0xAA,0x9A,0xA6,0x42, + /* 0xE9CB [?] [6811]*/ + 0x11,0x10,0x13,0x12,0xFD,0x10,0x31,0x38,0x55,0x50,0x93,0x10,0x10,0x10,0x10,0x10, + 0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFC,0x00,0xFE,0x80,0xFC,0x04,0x28,0x10, + /* 0xE9CC [?] [6812]*/ + 0x10,0x11,0x10,0x13,0xFE,0x10,0x30,0x38,0x54,0x54,0x90,0x11,0x10,0x10,0x13,0x10, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xE9CD [?] [6813]*/ + 0x28,0x11,0x28,0x4B,0x98,0x29,0x4E,0x88,0x28,0x10,0x01,0x7F,0x05,0x19,0xE1,0x01, + 0x22,0xFC,0x28,0xFE,0x40,0xFC,0x84,0xFC,0x84,0xFC,0x00,0xFC,0x40,0x30,0x0E,0x00, + /* 0xE9CE [?] [6814]*/ + 0x22,0x22,0x27,0x24,0xF9,0x27,0x25,0x75,0x6F,0xA5,0xA5,0x27,0x25,0x25,0x24,0x28, + 0x04,0x04,0x84,0x94,0x0C,0xC4,0x64,0x54,0xC4,0x46,0x7C,0xC4,0x44,0x44,0x44,0xC4, + /* 0xE9CF [?] [6815]*/ + 0x20,0x27,0x20,0x21,0xFF,0x24,0x24,0x77,0x6C,0xA7,0xA4,0x24,0x27,0x2C,0x20,0x20, + 0x08,0x88,0x88,0x10,0xDE,0x94,0xA4,0x94,0x94,0x94,0x94,0xC8,0x88,0x94,0xA4,0xC2, + /* 0xE9D0 [?] [6816]*/ + 0x21,0x21,0x21,0x27,0xF9,0x21,0x2F,0x71,0x69,0xA5,0xA5,0x25,0x27,0x25,0x24,0x28, + 0x14,0x12,0x12,0x90,0x7E,0x50,0xD4,0x54,0x54,0x48,0xEA,0x56,0x22,0x00,0xFE,0x00, + /* 0xE9D1 [?] [6817]*/ + 0x24,0xFF,0x24,0x7E,0x82,0x7A,0x4A,0x7A,0x04,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x20,0x20,0x3E,0x44,0x84,0x28,0x10,0x28,0x44,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xE9D2 [?] [6818]*/ + 0x01,0x7F,0x11,0x1F,0x01,0xFF,0x80,0x3F,0x04,0x1F,0x68,0x0F,0x01,0xFF,0x09,0x71, + 0x00,0xFC,0x10,0xF0,0x00,0xFE,0x02,0xF8,0x00,0xF0,0x10,0xF0,0x00,0xFE,0x20,0x1C, + /* 0xE9D3 [?] [6819]*/ + 0x20,0x2F,0x28,0x2A,0xF9,0x2B,0x28,0x78,0x6A,0xAA,0xAB,0x28,0x28,0x29,0x29,0x32, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xE9D4 [?] [6820]*/ + 0x10,0x10,0x11,0x11,0xFB,0x15,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14, + 0x90,0x88,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0xA4,0x52,0x52, + /* 0xE9D5 [?] [6821]*/ + 0x10,0x10,0x10,0x11,0xFE,0x10,0x31,0x39,0x55,0x50,0x93,0x12,0x12,0x12,0x12,0x12, + 0x20,0x50,0x88,0x24,0xFA,0x50,0x24,0x54,0xFC,0x20,0xFE,0x42,0x92,0xFA,0x0A,0x06, + /* 0xE9D6 [?] [6822]*/ + 0x10,0x10,0x11,0x13,0xFD,0x11,0x39,0x35,0x50,0x53,0x90,0x11,0x11,0x11,0x11,0x11, + 0x80,0xF8,0x10,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC, + /* 0xE9D7 [?] [6823]*/ + 0x10,0x10,0x13,0x10,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x13,0x11,0x10,0x10,0x10, + 0x88,0x50,0xFE,0x50,0xFC,0x54,0x8C,0x74,0x04,0xFC,0x08,0xFE,0x08,0x88,0xA8,0x10, + /* 0xE9D8 [?] [6824]*/ + 0x20,0x23,0x22,0x23,0xFA,0x22,0x22,0x72,0x6A,0xA2,0xA2,0x22,0x22,0x25,0x24,0x28, + 0x00,0xFE,0x02,0xFE,0x10,0x54,0x38,0x54,0x82,0x50,0x7C,0x90,0x10,0xFE,0x10,0x10, + /* 0xE9D9 [?] [6825]*/ + 0x10,0x13,0x10,0x10,0xFB,0x10,0x30,0x3B,0x54,0x53,0x92,0x12,0x13,0x12,0x12,0x12, + 0x00,0xFC,0x48,0x30,0xFE,0x52,0x94,0x50,0x20,0xFE,0x52,0x8A,0x76,0x52,0x72,0x06, + /* 0xE9DA [?] [6826]*/ + 0x22,0x22,0x24,0x25,0xF9,0x2E,0x22,0x74,0x68,0xAF,0xA0,0x20,0x23,0x2C,0x20,0x20, + 0x20,0x3C,0x44,0x78,0x08,0xFE,0x20,0xD2,0x1A,0x2C,0xCC,0x1A,0x2A,0xC8,0x28,0x10, + /* 0xE9DB [?] [6827]*/ + 0x10,0x11,0x10,0x13,0xFA,0x11,0x30,0x39,0x54,0x51,0x91,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC, + /* 0xE9DC [?] [6828]*/ + 0x11,0x11,0x12,0x17,0xFA,0x13,0x33,0x3A,0x56,0x52,0x92,0x12,0x12,0x14,0x14,0x18, + 0x00,0xF8,0x08,0xFE,0x88,0x24,0xFE,0x00,0xFC,0x00,0xFC,0x00,0xFC,0x84,0xFC,0x84, + /* 0xE9DD [?] [6829]*/ + 0x10,0x13,0x10,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x90,0x11,0x10,0x13,0x11,0x12, + 0x20,0xFE,0x00,0xFC,0x04,0x74,0x54,0x74,0x04,0xFC,0x00,0xFC,0x00,0xFE,0x24,0x62, + /* 0xE9DE [?] [6830]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3C,0x01,0x7F,0x05,0x19,0xE1,0x01, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xFC,0x40,0x30,0x0E,0x00, + /* 0xE9DF [?] [6831]*/ + 0x20,0x20,0x27,0x24,0xFA,0x23,0x34,0x6A,0x65,0xA2,0xA4,0x2B,0x20,0x22,0x24,0x20, + 0x80,0x40,0xFE,0x02,0x24,0xBC,0xA4,0xA8,0x10,0xE8,0x04,0xFA,0x40,0x48,0x44,0xC0, + /* 0xE9E0 [?] [6832]*/ + 0x22,0x12,0x14,0xFF,0x14,0x14,0x7F,0x55,0x55,0x63,0x41,0x7F,0x41,0x41,0x7F,0x41, + 0x10,0x14,0x12,0x92,0x10,0xFE,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x84,0x02, + /* 0xE9E1 [?] [6833]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x20,0x3E,0x42,0x87,0x01,0x7F,0x02,0x04,0x18,0xE0, + 0x20,0x20,0x3E,0x44,0x84,0x28,0x10,0x28,0x44,0x22,0x10,0xFC,0x80,0x40,0x30,0x0E, + /* 0xE9E2 [?] [6834]*/ + 0x00,0x00,0xFC,0x20,0x20,0x3D,0x46,0x45,0x64,0x94,0x08,0x08,0x10,0x20,0x40,0x83, + 0x00,0xF8,0x88,0x88,0x88,0x06,0x00,0xFC,0x84,0x84,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xE9E3 [?] [6835]*/ + 0x00,0x01,0xFD,0x21,0x21,0x3D,0x45,0x45,0x65,0x95,0x09,0x09,0x11,0x21,0x47,0x80, + 0x00,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x08,0xFE,0x00, + /* 0xE9E4 [?] [6836]*/ + 0x00,0x00,0xFC,0x21,0x22,0x3C,0x44,0x44,0x65,0x94,0x08,0x09,0x12,0x24,0x40,0x81, + 0x80,0x80,0xFE,0x00,0xF8,0x10,0x20,0x40,0xFC,0x94,0x94,0x24,0x24,0x44,0xA8,0x10, + /* 0xE9E5 [?] [6837]*/ + 0x00,0x00,0xFC,0x20,0x21,0x3E,0x44,0x44,0x65,0x94,0x08,0x08,0x11,0x20,0x40,0x83, + 0x20,0x20,0x50,0x88,0x04,0x12,0x20,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80, + /* 0xE9E6 [?] [6838]*/ + 0x00,0x00,0xFC,0x20,0x20,0x3C,0x45,0x45,0x65,0x95,0x09,0x09,0x10,0x20,0x40,0x83, + 0x00,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xE9E7 [?] [6839]*/ + 0x00,0x00,0xFC,0x20,0x20,0x3D,0x46,0x44,0x64,0x94,0x09,0x08,0x10,0x20,0x43,0x80, + 0x20,0x20,0x50,0x50,0x88,0x04,0xFA,0x00,0x44,0x24,0x24,0xA8,0x88,0x10,0xFE,0x00, + /* 0xE9E8 [?] [6840]*/ + 0x00,0x00,0xFD,0x20,0x21,0x3C,0x44,0x45,0x64,0x94,0x0B,0x08,0x10,0x20,0x40,0x80, + 0x08,0x3C,0xC0,0x04,0x44,0xA8,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xE9E9 [?] [6841]*/ + 0x01,0x00,0xFC,0x21,0x21,0x3D,0x45,0x45,0x65,0x95,0x08,0x08,0x13,0x20,0x40,0x80, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xE9EA [?] [6842]*/ + 0x00,0x03,0xF8,0x20,0x20,0x3B,0x4A,0x4A,0x6A,0x9A,0x0B,0x10,0x10,0x20,0x47,0x80, + 0x00,0xFC,0x08,0x10,0x20,0xAE,0xA2,0xAA,0xA4,0xA4,0xAA,0x32,0xA0,0x40,0xFE,0x00, + /* 0xE9EB [?] [6843]*/ + 0x00,0x00,0xFB,0x22,0x24,0x39,0x49,0x49,0x69,0x99,0x09,0x17,0x10,0x20,0x41,0x82, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xE9EC [?] [6844]*/ + 0x00,0x03,0xF8,0x21,0x20,0x3B,0x4A,0x49,0x68,0x99,0x09,0x11,0x11,0x20,0x43,0x80, + 0x20,0xFE,0x20,0xFC,0x00,0xFE,0x02,0xFC,0x00,0xFC,0x04,0xFC,0x04,0x88,0xFE,0x00, + /* 0xE9ED [?] [6845]*/ + 0x10,0x10,0x10,0xFE,0x20,0x28,0x48,0x7E,0x08,0x09,0x0E,0xF8,0x48,0x08,0x09,0x0A, + 0x00,0x00,0xFC,0x24,0x24,0xA4,0xA4,0xA4,0xA4,0x24,0x24,0x44,0x44,0x84,0x28,0x10, + /* 0xE9EE [?] [6846]*/ + 0x20,0x21,0x21,0xFD,0x41,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x11,0x12,0x14, + 0x00,0xFE,0x00,0x00,0x78,0x48,0x48,0x48,0x48,0x68,0x50,0x42,0x42,0x42,0x3E,0x00, + /* 0xE9EF [?] [6847]*/ + 0x10,0x10,0x10,0xFE,0x21,0x28,0x48,0x7E,0x08,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xE9F0 [?] [6848]*/ + 0x20,0x20,0x21,0xFC,0x40,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x50,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xE9F1 [?] [6849]*/ + 0x20,0x20,0x20,0xFC,0x40,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x12,0x12,0x14, + 0x20,0x20,0x3E,0x20,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x00,0x00,0x00, + /* 0xE9F2 [?] [6850]*/ + 0x20,0x20,0x21,0xFD,0x41,0x51,0x91,0xFD,0x11,0x11,0x1C,0xF0,0x50,0x11,0x12,0x14, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x90,0x88,0x04,0x02,0x02, + /* 0xE9F3 [?] [6851]*/ + 0x20,0x20,0x21,0xFD,0x41,0x51,0x92,0xFC,0x13,0x10,0x1C,0xF0,0x50,0x10,0x11,0x12, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xE9F4 [?] [6852]*/ + 0x20,0x20,0x20,0xFC,0x41,0x52,0x90,0xFC,0x11,0x10,0x1C,0xF0,0x51,0x10,0x10,0x13, + 0x20,0x20,0x50,0x88,0x04,0x12,0x20,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80, + /* 0xE9F5 [?] [6853]*/ + 0x20,0x20,0x23,0xFC,0x41,0x50,0x90,0xFC,0x13,0x10,0x1C,0xF0,0x50,0x10,0x10,0x10, + 0x08,0x3C,0xE0,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xE9F6 [?] [6854]*/ + 0x20,0x20,0x21,0xFD,0x41,0x51,0x91,0xFD,0x10,0x10,0x1C,0xF0,0x51,0x12,0x10,0x10, + 0x08,0x1C,0xE0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xE9F7 [?] [6855]*/ + 0x10,0x11,0x10,0xFE,0x20,0x28,0x48,0x7E,0x09,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x94,0x88,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xE9F8 [?] [6856]*/ + 0x20,0x20,0x20,0xFC,0x41,0x50,0x90,0xFD,0x10,0x10,0x1C,0xF0,0x50,0x13,0x10,0x10, + 0x10,0x14,0x12,0x10,0xFE,0x10,0x10,0xD0,0x90,0x90,0x90,0x88,0xEA,0x8A,0x06,0x02, + /* 0xE9F9 [?] [6857]*/ + 0x10,0x10,0x10,0xFE,0x20,0x28,0x48,0x7E,0x08,0x08,0x0E,0xF8,0x48,0x08,0x09,0x08, + 0x00,0xFE,0x10,0x20,0x44,0x82,0xFE,0x12,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xE9FA [?] [6858]*/ + 0x20,0x20,0x20,0xFC,0x41,0x52,0x91,0xFC,0x10,0x10,0x1D,0xF0,0x50,0x10,0x13,0x10, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xE9FB [?] [6859]*/ + 0x10,0x10,0x10,0xFE,0x21,0x28,0x48,0x7E,0x09,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xE9FC [?] [6860]*/ + 0x20,0x23,0x21,0xFD,0x41,0x51,0x91,0xFD,0x11,0x11,0x1D,0xF1,0x51,0x13,0x10,0x10, + 0x00,0xFE,0x20,0x28,0x28,0xE8,0x28,0x28,0x28,0xE8,0x28,0x2A,0x3A,0xEA,0x26,0x20, + /* 0xE9FD [?] [6861]*/ + 0x08,0x08,0x7E,0x08,0xFE,0x14,0x22,0x42,0xBF,0x05,0x09,0x1F,0x01,0xFF,0x01,0x01, + 0x20,0x20,0xFC,0x20,0xFE,0x50,0x88,0x06,0xF8,0x00,0x00,0xF0,0x00,0xFE,0x00,0x00, + /* 0xE9FE [?] [6862]*/ + 0x20,0x23,0x22,0xFA,0x42,0x53,0x92,0xFE,0x13,0x12,0x1E,0xF2,0x52,0x12,0x12,0x12, + 0x00,0xFE,0x02,0x8A,0x52,0xFE,0x42,0x22,0xFE,0x82,0x82,0x82,0xFA,0x02,0x0A,0x04, + /* 0xEAA1 [?] [6863]*/ + 0x20,0x23,0x20,0xFD,0x40,0x51,0x92,0xFC,0x10,0x13,0x1C,0xF1,0x50,0x11,0x12,0x14, + 0x00,0xDE,0x42,0x4A,0x84,0x4A,0x52,0x20,0x00,0xDE,0x52,0x52,0x94,0x48,0x54,0x22, + /* 0xEAA2 [?] [6864]*/ + 0x20,0x20,0x21,0xFA,0x41,0x50,0x90,0xFC,0x11,0x11,0x1D,0xF1,0x51,0x11,0x11,0x11, + 0x92,0x92,0x24,0x48,0x24,0x92,0x92,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xEAA3 [?] [6865]*/ + 0x20,0x20,0x23,0xFC,0x41,0x50,0x93,0xFC,0x11,0x12,0x1C,0xF1,0x50,0x10,0x10,0x13, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x20,0xFC,0x20,0x50,0x88,0x04, + /* 0xEAA4 [?] [6866]*/ + 0x20,0x20,0x23,0xFA,0x42,0x53,0x92,0xFE,0x13,0x12,0x1E,0xF2,0x52,0x14,0x14,0x18, + 0x40,0x20,0xFE,0x50,0x50,0xFE,0x52,0x52,0xFE,0x00,0x92,0xD4,0x98,0x92,0xD2,0x8E, + /* 0xEAA5 [?] [6867]*/ + 0x20,0x21,0x20,0xFB,0x20,0x41,0x52,0x91,0xF9,0x11,0x1A,0xF5,0x50,0x11,0x12,0x14, + 0x20,0x24,0xA8,0xFE,0xA8,0x24,0x22,0x04,0x04,0xDE,0x44,0x54,0x9E,0x04,0x04,0x04, + /* 0xEAA6 [?] [6868]*/ + 0x01,0x7F,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x01,0xFF,0x01,0x3F,0x20,0x20,0x3F,0x20, + 0x00,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xEAA7 [?] [6869]*/ + 0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0xFF,0x02,0x01,0x01,0x01,0x0E,0x70,0x00, + 0x40,0x20,0x20,0xFC,0x00,0x00,0x00,0x3E,0xC0,0x10,0x20,0x40,0x84,0x44,0x34,0x0C, + /* 0xEAA8 [?] [6870]*/ + 0x08,0x08,0x14,0x12,0x21,0x40,0xBE,0x22,0x22,0x22,0x2A,0x24,0x21,0x21,0x1F,0x00, + 0x28,0x24,0x24,0x20,0x2E,0xF0,0x20,0x24,0x24,0x28,0x28,0x10,0x12,0x2A,0x46,0x82, + /* 0xEAA9 [?] [6871]*/ + 0x7F,0x02,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x02,0x03,0x7E,0x01,0x00,0x07,0x38, + 0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x40,0xF8,0x20,0x40,0x84,0x64,0x1C, + /* 0xEAAA [?] [6872]*/ + 0x08,0x08,0xFF,0x08,0x7F,0x41,0x7F,0x41,0x7F,0x49,0x08,0xFF,0x08,0x08,0x08,0x09, + 0x20,0x28,0xA4,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x90,0x32,0x4A,0x86,0x02, + /* 0xEAAB [?] [6873]*/ + 0x3F,0x21,0x21,0x3F,0x00,0xFF,0x21,0x3F,0x21,0x3F,0x21,0x27,0xF9,0x41,0x01,0x01, + 0x28,0x24,0x24,0x20,0x20,0xFE,0x20,0x24,0x24,0x28,0x28,0xD0,0x12,0x2A,0x46,0x82, + /* 0xEAAC [?] [6874]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x22,0x3F,0x22,0x22,0xFF,0x40,0x54,0x62,0x40,0x7E,0x01, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xEAAD [?] [6875]*/ + 0x00,0x7E,0x42,0x7E,0x42,0x7E,0x09,0x48,0x7F,0x88,0x7E,0x08,0x0F,0xF0,0x40,0x01, + 0x20,0x28,0x24,0x24,0x20,0x3E,0xE0,0x24,0x24,0x28,0x28,0x10,0x32,0x4A,0x86,0x02, + /* 0xEAAE [?] [6876]*/ + 0x00,0x7E,0x22,0x24,0x3F,0x55,0x49,0x55,0xA2,0x00,0x7F,0x55,0x55,0x57,0xFC,0x00, + 0x10,0x14,0x12,0x10,0x16,0x78,0x12,0x12,0x12,0x14,0x14,0x08,0x1A,0xAA,0x46,0x82, + /* 0xEAAF [?] [6877]*/ + 0x00,0x7F,0x12,0x52,0x33,0x12,0xFF,0x00,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21, + 0x10,0x94,0x12,0x90,0x16,0x78,0xD2,0x12,0x12,0x14,0x14,0x08,0x1A,0x2A,0x46,0x82, + /* 0xEAB0 [?] [6878]*/ + 0x00,0x00,0x5F,0x50,0x57,0x75,0x15,0x17,0xF4,0x54,0x57,0x55,0x95,0x27,0x20,0x40, + 0x28,0x24,0xFE,0x20,0xA0,0x20,0x20,0xA4,0xA4,0xA8,0xA8,0x10,0x12,0xAA,0x46,0x82, + /* 0xEAB1 [?] [6879]*/ + 0x00,0x7E,0x40,0x44,0x64,0x54,0x48,0x48,0x54,0x54,0x64,0x40,0x40,0x7E,0x00,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xEAB2 [?] [6880]*/ + 0x10,0x10,0x28,0x24,0x42,0x91,0x08,0x08,0xFE,0x02,0x44,0x28,0x10,0x08,0x08,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xEAB3 [?] [6881]*/ + 0x10,0x08,0x7F,0x00,0x22,0x14,0xFF,0x00,0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x00, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xEAB4 [?] [6882]*/ + 0x08,0x7F,0x08,0x3E,0x00,0x3E,0x22,0x3E,0x14,0x7F,0x00,0x7F,0x08,0x0F,0x11,0x1C, + 0x04,0x08,0x10,0x64,0x08,0x10,0x64,0x08,0x10,0x60,0x00,0xFC,0x00,0xE0,0x24,0x9C, + /* 0xEAB5 [?] [6883]*/ + 0x44,0x24,0x28,0xFE,0x92,0xD6,0xBA,0x92,0xFE,0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44, + 0x00,0xFC,0x40,0x40,0x40,0x78,0x48,0x48,0xA8,0x98,0x88,0x88,0xAA,0xCA,0x8A,0x06, + /* 0xEAB6 [?] [6884]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3C,0x00,0x7F,0x08,0x0F,0x11,0x1C, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xFC,0x00,0xE0,0x24,0x9C, + /* 0xEAB7 [?] [6885]*/ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x10,0x08,0x04,0x02,0x01,0x06,0x18,0xE0, + 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0xC0,0x30,0x0E, + /* 0xEAB8 [?] [6886]*/ + 0x02,0x02,0x3F,0x04,0x08,0x30,0xC0,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x00,0xE0,0x20,0x22,0x22,0x1E,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xEAB9 [?] [6887]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x02,0x02,0x7F,0x04,0x04,0x08,0x10,0x60, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xE0,0x20,0x20,0x22,0x22,0x1E, + /* 0xEABA [?] [6888]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7D,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xEABB [?] [6889]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x00,0x3F,0x01,0x01,0xFF,0x02,0x04,0x18,0xE0, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x30,0x0E, + /* 0xEABC [?] [6890]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x00,0x00,0xFF,0x04,0x08,0x10,0x3F,0x10, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xF8,0x00,0x00,0xFE,0x00,0x20,0x10,0xF8,0x08, + /* 0xEABD [?] [6891]*/ + 0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x01,0x01,0x7F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xFC,0x80,0x40,0x20,0x18,0x06,0x00, + /* 0xEABE [?] [6892]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x20,0x20,0x21,0x21,0x22,0x44,0x48,0x90, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x80,0x80,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xEABF [?] [6893]*/ + 0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x7C,0x45,0x01,0x02, + 0x04,0x0E,0xF0,0x80,0x80,0x80,0xFE,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xEAC0 [?] [6894]*/ + 0x00,0x00,0x7C,0x44,0x45,0x46,0x44,0x7C,0x44,0x44,0x44,0x44,0x7D,0x44,0x00,0x00, + 0x40,0x40,0x80,0xFC,0x04,0x04,0x84,0x44,0x44,0x14,0x24,0x44,0x84,0x04,0x28,0x10, + /* 0xEAC1 [?] [6895]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x01,0x11,0x11,0x22,0x04,0x08,0x30,0xC0, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x08,0x10,0x80,0x40,0x20,0x18,0x06, + /* 0xEAC2 [?] [6896]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x08,0x08,0x1F,0x21,0x52,0x94,0x10,0x1F,0x00,0x00, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xFC,0x04,0x84,0x44,0x04,0x84,0x28,0x10, + /* 0xEAC3 [?] [6897]*/ + 0x10,0x10,0x3E,0x22,0x54,0x08,0x17,0x20,0xDF,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x40,0x40,0x50,0x48,0x44,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xEAC4 [?] [6898]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x0C,0x70,0x44,0x44,0x5C,0x64,0x48,0x10,0x60, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xFC,0x84,0x84,0x84,0x94,0x88,0x80,0x80, + /* 0xEAC5 [?] [6899]*/ + 0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x02,0x01,0x01,0x7F,0x00,0x10,0x08,0x04,0xFF, + 0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0x00,0xFC,0x00,0x10,0x20,0x40,0xFE, + /* 0xEAC6 [?] [6900]*/ + 0x08,0x04,0x02,0x3C,0x04,0x04,0x75,0x16,0x16,0x15,0x25,0x24,0x44,0x84,0x14,0x08, + 0x00,0x00,0x7C,0x44,0x44,0xC4,0x7C,0x44,0x44,0x44,0x7C,0x80,0x40,0x30,0x0E,0x00, + /* 0xEAC7 [?] [6901]*/ + 0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x49,0x79,0x4A,0x02,0x04, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xEAC8 [?] [6902]*/ + 0x02,0x3F,0x02,0xFF,0x02,0x0C,0x3F,0xC8,0x07,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x08,0xD0,0x20,0xFE,0x00,0x70,0x84,0x04,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xEAC9 [?] [6903]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x00,0x3F,0x20,0x20,0x3E,0x22,0x22,0x2A,0x44,0x41,0x86, + 0xF0,0x10,0xF0,0x10,0xF0,0x88,0xFC,0x80,0x88,0x88,0x50,0x50,0x24,0x54,0x8C,0x04, + /* 0xEACA [?] [6904]*/ + 0x00,0x00,0x79,0x49,0x4B,0x4D,0x49,0x79,0x49,0x48,0x4B,0x48,0x78,0x48,0x00,0x00, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xEACB [?] [6905]*/ + 0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x24,0x14,0x0C,0x14,0x64,0x08,0x10,0x60, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x48,0x50,0x60,0x50,0x48,0x42,0x42,0x3E, + /* 0xEACC [?] [6906]*/ + 0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x7F,0x42,0x02,0xFF,0x08,0x1C,0x03,0x0C,0x70, + 0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x04,0x00,0xFE,0x20,0x40,0x80,0x70,0x08, + /* 0xEACD [?] [6907]*/ + 0x00,0x03,0x7A,0x4C,0x48,0x4B,0x48,0x78,0x49,0x49,0x48,0x48,0x7B,0x48,0x00,0x00, + 0x00,0xFE,0x02,0x44,0x40,0xFC,0x80,0xA0,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xEACE [?] [6908]*/ + 0x00,0x00,0x7B,0x48,0x48,0x4B,0x4A,0x7A,0x4B,0x4A,0x4A,0x4B,0x7A,0x4A,0x02,0x02, + 0x48,0x44,0xFE,0x40,0x40,0xFC,0x44,0x44,0xFC,0x44,0x44,0xFC,0x44,0x44,0x54,0x08, + /* 0xEACF [?] [6909]*/ + 0x00,0x00,0x78,0x49,0x4A,0x4C,0x49,0x78,0x48,0x48,0x4B,0x4A,0x7A,0x4A,0x03,0x02, + 0x40,0x40,0xA0,0x10,0x88,0x46,0xF0,0x10,0x20,0x40,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xEAD0 [?] [6910]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x08,0x1F,0x22,0x54,0x08,0x37,0xC0,0x1F,0x10,0x10,0x1F, + 0xF0,0x10,0xF0,0x10,0xF0,0x40,0x60,0x50,0x48,0x40,0xFE,0x00,0xF0,0x10,0x10,0xF0, + /* 0xEAD1 [?] [6911]*/ + 0x00,0x00,0x7B,0x4A,0x4C,0x49,0x48,0x79,0x49,0x49,0x49,0x49,0x79,0x48,0x03,0x00, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xEAD2 [?] [6912]*/ + 0x00,0x03,0x78,0x4A,0x49,0x48,0x49,0x7A,0x48,0x48,0x4B,0x48,0x78,0x48,0x01,0x02, + 0x10,0xD4,0x58,0x52,0x8C,0x88,0x04,0xFA,0x20,0x20,0xFE,0x20,0x50,0x88,0x04,0x02, + /* 0xEAD3 [?] [6913]*/ + 0x00,0x03,0x78,0x4A,0x49,0x4B,0x7A,0x48,0x4B,0x48,0x48,0x79,0x49,0x02,0x04,0x01, + 0x0E,0xF0,0x44,0x24,0x08,0xFE,0x42,0x40,0xFE,0x80,0xFC,0x44,0x28,0x10,0x68,0x86, + /* 0xEAD4 [?] [6914]*/ + 0x00,0x03,0x7A,0x48,0x49,0x49,0x49,0x79,0x49,0x48,0x48,0x4B,0x78,0x48,0x01,0x02, + 0x00,0xFE,0x02,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xFE,0x00,0x88,0x04,0x02, + /* 0xEAD5 [?] [6915]*/ + 0x02,0x01,0xF7,0x90,0x97,0x94,0x97,0xF0,0x97,0x90,0x91,0x91,0xF7,0x91,0x05,0x02, + 0x08,0x08,0xC8,0x10,0x9E,0x94,0xA4,0x14,0x94,0x94,0x14,0xC8,0x08,0x14,0x24,0x42, + /* 0xEAD6 [?] [6916]*/ + 0x00,0x07,0xF0,0x9F,0x90,0x97,0x95,0xF4,0x97,0x90,0x97,0x90,0xFF,0x90,0x05,0x08, + 0x3C,0xC0,0x40,0xFE,0x40,0xFC,0x54,0xE4,0xFC,0x40,0xFC,0x40,0xFE,0x00,0x24,0x92, + /* 0xEAD7 [?] [6917]*/ + 0x00,0x07,0xF0,0x94,0x92,0x94,0x91,0xF2,0x97,0x9A,0x93,0x92,0xF3,0x92,0x03,0x02, + 0x00,0xBC,0x84,0xA4,0x94,0xA4,0x20,0x10,0xFC,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xEAD8 [?] [6918]*/ + 0x01,0x07,0xF0,0x93,0x90,0x97,0x90,0xF3,0x91,0x97,0x93,0x95,0xF3,0x90,0x02,0x01, + 0x10,0xFC,0x40,0xF8,0x40,0xFC,0x00,0xD4,0x12,0xFE,0x50,0x34,0x8C,0x8A,0x96,0x02, + /* 0xEAD9 [?] [6919]*/ + 0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x22,0x3E,0x04,0x3F,0x04,0xFF,0x04,0x1C,0x67, + 0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x88,0xF8,0x40,0xF8,0x40,0xFE,0x90,0x60,0x1C, + /* 0xEADA [?] [6920]*/ + 0x01,0x3F,0x01,0x08,0xFF,0x08,0x00,0x1F,0x10,0x11,0x11,0x11,0x12,0x04,0x18,0x60, + 0x00,0xF8,0x00,0x20,0xFE,0x20,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xEADB [?] [6921]*/ + 0x12,0x12,0xFF,0x12,0x13,0x10,0x1F,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x20,0x20,0xFE,0x20,0xE0,0x00,0xF8,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xEADC [?] [6922]*/ + 0x00,0x7D,0x45,0x45,0x55,0x55,0x55,0x54,0x54,0x54,0x54,0x10,0x28,0x25,0x42,0x84, + 0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x50,0x50,0x50,0x50,0x92,0x92,0x12,0x0E,0x00, + /* 0xEADD [?] [6923]*/ + 0x00,0x7C,0x44,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x54,0x10,0x28,0x24,0x44,0x80, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xEADE [?] [6924]*/ + 0x10,0x10,0xFB,0x10,0x19,0xF0,0x11,0x52,0x24,0x1F,0x10,0x11,0x11,0x02,0x0C,0x30, + 0x80,0x80,0xF0,0x90,0x90,0x94,0x54,0x0C,0x04,0xF0,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xEADF [?] [6925]*/ + 0x08,0x08,0x2E,0x28,0x28,0x2E,0xF0,0x00,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x80,0x88,0x90,0xE0,0x84,0x84,0x7C,0x00,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xEAE0 [?] [6926]*/ + 0x00,0x7C,0x44,0x47,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x13,0x28,0x24,0x40,0x83, + 0x20,0x10,0x10,0xFE,0x20,0x42,0x84,0xF8,0x10,0x22,0xC4,0x08,0x10,0x28,0xC4,0x02, + /* 0xEAE1 [?] [6927]*/ + 0x00,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x55,0x55,0x12,0x28,0x24,0x44,0x80, + 0x00,0xFC,0x84,0x84,0xFC,0x90,0x90,0x88,0x84,0x32,0x08,0x00,0x60,0x18,0x04,0x00, + /* 0xEAE2 [?] [6928]*/ + 0x00,0x7D,0x45,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x29,0x26,0x42,0x84, + 0x00,0xFE,0x00,0x00,0x7C,0x00,0x00,0xFE,0x50,0x52,0x54,0x48,0x48,0x44,0x52,0x60, + /* 0xEAE3 [?] [6929]*/ + 0x01,0x01,0x7F,0x11,0x09,0xFF,0x05,0x09,0x30,0xDF,0x10,0x11,0x11,0x02,0x0C,0x30, + 0x00,0x00,0xFC,0x10,0x20,0xFE,0x40,0x20,0x18,0xF6,0x10,0x10,0x10,0xC0,0x30,0x08, + /* 0xEAE4 [?] [6930]*/ + 0x00,0x7C,0x44,0x54,0x55,0x54,0x55,0x54,0x54,0x54,0x54,0x11,0x2A,0x24,0x44,0x80, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0xB2,0xB4,0x68,0xA8,0x24,0x22,0x20,0xA0,0x40, + /* 0xEAE5 [?] [6931]*/ + 0x01,0x7F,0x09,0x09,0x15,0x7F,0x40,0x80,0x1F,0x10,0x11,0x11,0x11,0x02,0x0C,0x70, + 0x00,0xFC,0x20,0x20,0x50,0xFE,0x02,0x04,0xF0,0x10,0x10,0x10,0x10,0x60,0x18,0x04, + /* 0xEAE6 [?] [6932]*/ + 0x00,0x7C,0x44,0x45,0x54,0x54,0x57,0x54,0x54,0x54,0x54,0x11,0x28,0x24,0x41,0x82, + 0x20,0xA2,0xA2,0x24,0x50,0x88,0x04,0x22,0x20,0xA4,0xA4,0x28,0x50,0x88,0x04,0x02, + /* 0xEAE7 [?] [6933]*/ + 0x00,0x7C,0x47,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x13,0x28,0x24,0x44,0x80, + 0x28,0x24,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x08,0xFE,0x88,0x48,0x48,0x18, + /* 0xEAE8 [?] [6934]*/ + 0x10,0x11,0x11,0x1F,0x11,0x11,0x11,0x11,0x7D,0x45,0x44,0x44,0x44,0x7D,0x46,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xEAE9 [?] [6935]*/ + 0x08,0x49,0x49,0x49,0x7F,0x00,0x7F,0x01,0x01,0x3F,0x20,0x20,0x23,0x2C,0x30,0x01, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x8A,0x06, + /* 0xEAEA [?] [6936]*/ + 0x00,0x00,0x7F,0x08,0x08,0x2A,0x2A,0x2A,0x5D,0x49,0x88,0x08,0x0F,0xF0,0x40,0x01, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x8A,0x06, + /* 0xEAEB [?] [6937]*/ + 0x08,0x08,0x7E,0x08,0x08,0xFF,0x01,0x2A,0x18,0x48,0x28,0xFF,0x14,0x22,0x41,0x81, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x4A,0x86, + /* 0xEAEC [?] [6938]*/ + 0x10,0x28,0x44,0x82,0x7D,0x00,0xF1,0x95,0x95,0xF5,0x95,0x95,0xF5,0x91,0x95,0xB2, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x4A,0x86, + /* 0xEAED [?] [6939]*/ + 0x24,0x24,0xFF,0x24,0x7E,0x24,0xFF,0x08,0x7E,0x4A,0x7E,0x4A,0xFF,0x42,0x4A,0x44, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x4A,0x86, + /* 0xEAEE [?] [6940]*/ + 0x22,0x22,0xFF,0x22,0x3E,0x08,0x7F,0x49,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x0F,0xF0, + 0x00,0x7C,0xC4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x28,0x4A,0x4A,0x86, + /* 0xEAEF [?] [6941]*/ + 0x10,0x1E,0x10,0x7F,0x51,0x5C,0x72,0x4E,0x40,0x4A,0x6A,0x5B,0x4A,0x8F,0x78,0x00, + 0x00,0x7C,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x90,0x28,0x28,0x4A,0x4A,0x86, + /* 0xEAF0 [?] [6942]*/ + 0x08,0x10,0x30,0x57,0x90,0x10,0x10,0x11,0x09,0x1F,0x21,0x01,0xFF,0x01,0x01,0x01, + 0xA0,0x90,0xBE,0xC0,0x40,0x24,0x14,0x0C,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xEAF1 [?] [6943]*/ + 0x7C,0x04,0x04,0x7C,0x41,0x7D,0x05,0x04,0x2B,0x10,0x11,0x1F,0x21,0xFF,0x01,0x01, + 0xF8,0x88,0xF8,0x20,0xFC,0x24,0xFC,0x28,0xFC,0x04,0x00,0xF8,0x00,0xFE,0x00,0x00, + /* 0xEAF2 [?] [6944]*/ + 0x08,0x08,0x48,0x48,0x7E,0x48,0x88,0x08,0x0E,0xF8,0x48,0x08,0x08,0x08,0x08,0x08, + 0x80,0x80,0x80,0x84,0x88,0x90,0xA0,0xC0,0x80,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xEAF3 [?] [6945]*/ + 0x08,0x08,0x49,0x48,0x7E,0x48,0x89,0x08,0x0E,0xF8,0x4B,0x08,0x08,0x08,0x08,0x08, + 0x08,0x3C,0xE0,0x20,0x20,0x3C,0xE0,0x20,0x20,0x3E,0xE0,0x20,0x22,0x22,0x22,0x1E, + /* 0xEAF4 [?] [6946]*/ + 0x10,0x10,0x50,0x50,0x7D,0x50,0x90,0x10,0x1D,0xF1,0x51,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xEAF5 [?] [6947]*/ + 0x10,0x13,0x50,0x50,0x7D,0x50,0x90,0x13,0x1C,0xF0,0x51,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEAF6 [?] [6948]*/ + 0x10,0x11,0x51,0x51,0x7D,0x52,0x90,0x13,0x1C,0xF0,0x51,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEAF7 [?] [6949]*/ + 0x10,0x10,0x51,0x50,0x7C,0x51,0x93,0x10,0x1D,0xF1,0x51,0x11,0x11,0x10,0x10,0x10, + 0x20,0x20,0xFC,0x50,0x88,0x04,0xFE,0x08,0xE8,0x28,0x28,0xE8,0x28,0x08,0x28,0x10, + /* 0xEAF8 [?] [6950]*/ + 0x10,0x11,0x51,0x51,0x7D,0x51,0x91,0x11,0x1D,0xF1,0x51,0x17,0x10,0x10,0x11,0x12, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x08,0xFE,0x00,0x90,0x08,0x04, + /* 0xEAF9 [?] [6951]*/ + 0x10,0x10,0x57,0x51,0x7D,0x52,0x92,0x17,0x1D,0xF5,0x55,0x12,0x12,0x15,0x18,0x10, + 0x10,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x10,0x00,0xFE,0x00, + /* 0xEAFA [?] [6952]*/ + 0x10,0x10,0x53,0x52,0x7E,0x53,0x92,0x12,0x1F,0xF3,0x53,0x15,0x15,0x15,0x19,0x11, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x54,0x54,0xFC,0x54,0x54,0x44,0x0C, + /* 0xEAFB [?] [6953]*/ + 0x10,0x10,0x53,0x50,0x7D,0x51,0x91,0x10,0x1F,0xF2,0x52,0x12,0x12,0x12,0x12,0x12, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xFA,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xEAFC [?] [6954]*/ + 0x08,0x7F,0x08,0x3E,0x08,0x7F,0x08,0x08,0x3F,0x01,0x3F,0x01,0x7F,0x01,0x05,0x02, + 0x00,0x7C,0x24,0x24,0x24,0x44,0x54,0xF8,0x00,0x00,0xF8,0x00,0xFC,0x00,0x00,0x00, + /* 0xEAFD [?] [6955]*/ + 0x20,0x12,0x44,0x20,0x08,0x73,0x20,0x00,0x3F,0x01,0x3F,0x01,0x7F,0x01,0x05,0x02, + 0x40,0x48,0x44,0x14,0x60,0x80,0x00,0xF0,0x00,0x00,0xF8,0x00,0xFC,0x00,0x00,0x00, + /* 0xEAFE [?] [6956]*/ + 0x10,0x3A,0xE2,0x24,0x24,0xF8,0x20,0x27,0x22,0xFA,0x22,0x24,0x24,0x2A,0x51,0x80, + 0x00,0x86,0xB8,0x88,0x48,0x5E,0x28,0x88,0x88,0xBE,0x88,0x88,0x88,0x88,0x28,0x10, + /* 0xEBA1 [?] [6957]*/ + 0x11,0x39,0xE2,0x22,0x24,0xF8,0x23,0x20,0x20,0xFB,0x22,0x22,0x22,0x23,0x42,0x80, + 0x00,0x06,0xB8,0x88,0x48,0x5E,0x88,0x08,0x08,0xBE,0x88,0x88,0x88,0x88,0xA8,0x10, + /* 0xEBA2 [?] [6958]*/ + 0x3E,0x22,0x3E,0x20,0x7E,0xA2,0x3E,0x22,0x00,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x03, + 0x10,0xFE,0x44,0x28,0xFE,0x10,0xFC,0x10,0x20,0xC0,0x00,0xF8,0x00,0xFC,0x00,0x00, + /* 0xEBA3 [?] [6959]*/ + 0x02,0x3F,0x02,0xFF,0x02,0x0F,0x34,0xC3,0x00,0x01,0x3E,0x03,0x3E,0x03,0x7E,0x01, + 0x20,0xC0,0x80,0xFE,0x20,0xC0,0x08,0xF8,0x00,0xF0,0x00,0xF0,0x00,0xFA,0x02,0xFE, + /* 0xEBA4 [?] [6960]*/ + 0x10,0x38,0xE0,0x21,0x23,0x38,0xE1,0x21,0x21,0x3A,0xE7,0x20,0x20,0x20,0x20,0x1F, + 0x40,0x40,0x90,0x08,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE,0x20,0x22,0x22,0x22,0xFE, + /* 0xEBA5 [?] [6961]*/ + 0x01,0x3E,0x03,0x3E,0x03,0x7E,0x01,0x00,0x18,0x71,0x1C,0x71,0x1C,0x71,0x14,0x18, + 0xF0,0x00,0xF0,0x00,0xFA,0x02,0xFE,0x00,0x30,0xC0,0x78,0xC0,0x78,0xC4,0x44,0x3C, + /* 0xEBA6 [?] [6962]*/ + 0x10,0x38,0xE7,0x21,0x22,0x3A,0xE7,0x21,0x21,0x39,0xE6,0x22,0x25,0x28,0x20,0x1F, + 0x10,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x12,0xFE,0x02,0xFE, + /* 0xEBA7 [?] [6963]*/ + 0x08,0x10,0x24,0x7E,0x10,0xFF,0x24,0x42,0x89,0x30,0xC4,0x08,0x32,0xC4,0x38,0xC0, + 0x08,0x1C,0xE0,0x20,0x20,0x3C,0xE0,0x20,0x20,0x3C,0xE0,0x22,0x22,0x22,0x1E,0x00, + /* 0xEBA8 [?] [6964]*/ + 0x08,0x14,0x22,0x41,0xBE,0x00,0x78,0x4A,0x4A,0x7A,0x4A,0x4A,0x7A,0x48,0x4A,0x59, + 0x04,0x0E,0x70,0x10,0x90,0x1C,0xF0,0x90,0x90,0x9E,0xF0,0x90,0x92,0x92,0x92,0x0E, + /* 0xEBA9 [?] [6965]*/ + 0x08,0x49,0x2A,0x7F,0x41,0x5D,0x55,0x5D,0x42,0x3F,0x01,0x3F,0x01,0x7F,0x01,0x00, + 0x20,0x20,0x3E,0x48,0xA8,0x28,0x10,0x28,0xF6,0x00,0xF0,0x00,0xF8,0x02,0x02,0xFE, + /* 0xEBAA [?] [6966]*/ + 0x11,0x3B,0xE4,0x2B,0x22,0x3B,0xE2,0x27,0x20,0x3B,0xE2,0x23,0x22,0x23,0x20,0x1F, + 0x00,0xF0,0x10,0xF8,0x48,0xF8,0x48,0xFC,0x00,0xF8,0x08,0xF8,0x0A,0xFA,0x02,0xFE, + /* 0xEBAB [?] [6967]*/ + 0x11,0x38,0xE3,0x20,0x22,0x39,0xE0,0x27,0x20,0x39,0xE1,0x21,0x21,0x21,0x20,0x1F, + 0x08,0x90,0xFC,0x90,0x94,0x98,0x90,0xFE,0x00,0xF8,0x08,0xF8,0x0A,0xFA,0x02,0xFE, + /* 0xEBAC [?] [6968]*/ + 0x77,0x55,0x77,0x55,0x77,0x55,0x77,0x22,0x7F,0xA4,0x3F,0x24,0x3F,0x24,0x3F,0x20, + 0x04,0x0E,0x70,0x10,0x10,0x1C,0x70,0x10,0x90,0x1E,0x70,0x10,0x12,0x12,0x92,0x0E, + /* 0xEBAD [?] [6969]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x0A,0x0A,0x06,0x02, + /* 0xEBAE [?] [6970]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x00,0x11,0x11,0x11,0x21,0x21,0x41,0x81, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x0A,0x0A,0x06,0x02, + /* 0xEBAF [?] [6971]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x04,0x04,0x44,0x44,0x44,0x7F,0x00,0x00, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x10,0x10,0x50,0x50,0x4A,0xCA,0x46,0x02, + /* 0xEBB0 [?] [6972]*/ + 0x10,0x10,0x3F,0x20,0x4F,0x80,0x3F,0x00,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x80, + 0x00,0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x90,0x90,0x90,0x8A,0x8A,0x86,0x82, + /* 0xEBB1 [?] [6973]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x10,0x1F,0x20,0x51,0x0E,0x31,0xCC,0x03,0x1C,0x03, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x90,0x10,0x10,0x92,0x6A,0x0A,0x06,0x02, + /* 0xEBB2 [?] [6974]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x7F,0x12,0x12,0x92,0x53,0x52,0x12,0xFF,0x00, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x10,0x50,0x90,0x12,0x0A,0x0A,0xC6,0x02, + /* 0xEBB3 [?] [6975]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x7F,0x44,0x44,0x5F,0x44,0x4A,0x51,0x7F,0x40, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x50,0x50,0x50,0x52,0x4A,0x4A,0xC6,0x42, + /* 0xEBB4 [?] [6976]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x04,0x7F,0x04,0x3F,0x20,0x3F,0x0A,0x12,0x22,0x41, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0xD0,0x10,0x90,0x90,0x92,0x0A,0x4A,0x46,0xC2, + /* 0xEBB5 [?] [6977]*/ + 0x20,0x3F,0x40,0x9F,0x00,0x7F,0x00,0x3F,0x20,0x3F,0x20,0x3F,0x00,0x7F,0x4A,0xFF, + 0x00,0xFC,0x00,0xF0,0x00,0xF0,0x10,0x90,0x90,0x90,0x90,0x92,0x0A,0xCA,0x46,0xE2, + /* 0xEBB6 [?] [6978]*/ + 0x04,0x04,0x04,0x0F,0x08,0x10,0x30,0x48,0x84,0x02,0x01,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x80,0x40,0x20,0x18,0x06, + /* 0xEBB7 [?] [6979]*/ + 0x08,0x08,0xFF,0x08,0x08,0x7F,0x49,0x49,0x7F,0x08,0x1C,0x2A,0x49,0x88,0x08,0x09, + 0x20,0x20,0xA0,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xEBB8 [?] [6980]*/ + 0x08,0x10,0x7E,0x42,0x7E,0x42,0x7E,0x10,0x08,0xFF,0x20,0x3E,0x22,0x42,0x4A,0x85, + 0x20,0x20,0x20,0x3E,0x44,0x44,0x44,0xA4,0x28,0x28,0x10,0x10,0x28,0x48,0x84,0x02, + /* 0xEBB9 [?] [6981]*/ + 0x08,0x48,0x48,0x48,0x48,0x7D,0x40,0x40,0x78,0x48,0x48,0x49,0x48,0x48,0x48,0x89, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x02,0x94,0x50,0x90,0x50,0xFE,0x28,0x44,0x82,0x02, + /* 0xEBBA [?] [6982]*/ + 0x08,0x49,0x49,0x4B,0x49,0x7D,0x41,0x41,0x79,0x48,0x4B,0x48,0x48,0x49,0x4E,0x88, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xEBBB [?] [6983]*/ + 0x08,0x48,0x4B,0x4A,0x4B,0x7E,0x43,0x42,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4C,0x88, + 0x40,0x20,0xFE,0x02,0xFE,0x14,0xFE,0x10,0xFE,0x92,0xFE,0x92,0xFE,0x92,0x92,0x96, + /* 0xEBBC [?] [6984]*/ + 0x00,0x01,0x7E,0x22,0x11,0x3F,0x02,0x02,0x7F,0x04,0x0F,0x14,0x22,0x41,0x86,0x38, + 0x08,0xFC,0x10,0x10,0x20,0xF8,0x00,0x00,0xFC,0x00,0xE0,0x20,0x40,0x80,0x60,0x1C, + /* 0xEBBD [?] [6985]*/ + 0x04,0x1E,0xE0,0x22,0x92,0x54,0x40,0x04,0xFF,0x04,0x44,0x24,0x24,0x05,0x15,0x0A, + 0x10,0x1E,0x10,0xFE,0x92,0x9C,0xF0,0x92,0x8E,0x80,0xB8,0xA8,0xA8,0x2A,0x2A,0x46, + /* 0xEBBE [?] [6986]*/ + 0x00,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x3F,0x21,0x21,0x21,0x41,0x45,0x82, + 0x04,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04,0x14,0x08, + /* 0xEBBF [?] [6987]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3D,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x00,0xFC,0x00,0x00,0x00,0xFE,0x40,0x40,0x80,0xFC,0x04,0x04,0x04,0x04,0x28,0x10, + /* 0xEBC0 [?] [6988]*/ + 0x00,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x42,0x4A,0x84, + 0x04,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x22,0x42,0x04,0x08,0x10,0x20,0xC0, + /* 0xEBC1 [?] [6989]*/ + 0x02,0x01,0xFF,0x10,0x10,0x1F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xEBC2 [?] [6990]*/ + 0x00,0x78,0x48,0x48,0x4B,0x78,0x48,0x48,0x4F,0x78,0x48,0x48,0x48,0x49,0x49,0x9A, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xEBC3 [?] [6991]*/ + 0x00,0x78,0x49,0x48,0x48,0x78,0x4B,0x48,0x48,0x78,0x48,0x48,0x48,0x49,0x49,0x9A, + 0x00,0x00,0xFC,0x00,0x00,0x00,0xFE,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E, + /* 0xEBC4 [?] [6992]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3D,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0xC8,0x24,0x02, + /* 0xEBC5 [?] [6993]*/ + 0x00,0x78,0x48,0x48,0x4B,0x78,0x48,0x48,0x48,0x79,0x49,0x4A,0x4A,0x4C,0x49,0x98, + 0x40,0x40,0x40,0x40,0xFE,0x40,0x80,0x90,0x90,0x20,0x20,0x48,0x44,0x84,0xFE,0x82, + /* 0xEBC6 [?] [6994]*/ + 0x00,0x78,0x48,0x4B,0x48,0x7A,0x4A,0x4A,0x4A,0x7B,0x48,0x48,0x48,0x48,0x48,0x98, + 0x40,0x40,0x40,0xFC,0x40,0x48,0x48,0x48,0x48,0xF8,0x48,0x40,0x42,0x42,0x3E,0x00, + /* 0xEBC7 [?] [6995]*/ + 0x00,0x3C,0x24,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x89, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xEBC8 [?] [6996]*/ + 0x18,0x06,0x01,0x06,0x3A,0x02,0xFF,0x04,0x0F,0x18,0x2F,0x48,0x8F,0x08,0x08,0x08, + 0x18,0x60,0x80,0x60,0x18,0x00,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xEBC9 [?] [6997]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x25,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x40,0x40,0x40,0x7C,0x84,0x88,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEBCA [?] [6998]*/ + 0x00,0x78,0x48,0x48,0x4B,0x78,0x48,0x48,0x48,0x78,0x49,0x49,0x49,0x4A,0x4A,0x9C, + 0x90,0x88,0x88,0x80,0xFE,0xA0,0xA0,0xA4,0xA4,0xA8,0x28,0x32,0x22,0x62,0x9E,0x00, + /* 0xEBCB [?] [6999]*/ + 0x00,0x78,0x48,0x4F,0x48,0x79,0x49,0x4A,0x4B,0x78,0x49,0x49,0x4A,0x4C,0x48,0x98, + 0x40,0x40,0x40,0xFE,0x80,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xEBCC [?] [7000]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x27,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFE,0x40,0x40,0x50,0x48,0x44,0x40,0x40,0x40, + /* 0xEBCD [?] [7001]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x45,0x55,0x8A, + 0x20,0x20,0x3C,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84,0x80,0x80,0x00,0x00,0x00, + /* 0xEBCE [?] [7002]*/ + 0x00,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x24,0x24,0x44,0x54,0x88, + 0x00,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xEBCF [?] [7003]*/ + 0x00,0x3C,0x24,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x44,0x54,0x88, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20, + /* 0xEBD0 [?] [7004]*/ + 0x01,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10, + 0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x50,0x20, + /* 0xEBD1 [?] [7005]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3D,0x26,0x24,0x24,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xEBD2 [?] [7006]*/ + 0x00,0x78,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x4A,0x4A,0x9C, + 0x08,0x1C,0xF0,0x50,0x50,0x50,0x50,0x50,0x50,0x48,0x48,0x68,0x54,0x74,0x52,0x00, + /* 0xEBD3 [?] [7007]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3E,0x24,0x24,0x25,0x3C,0x24,0x24,0x25,0x44,0x54,0x8B, + 0x20,0x20,0x50,0x88,0x04,0x12,0x20,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80, + /* 0xEBD4 [?] [7008]*/ + 0x00,0x3C,0x25,0x25,0x26,0x3C,0x25,0x25,0x25,0x3D,0x25,0x25,0x24,0x44,0x54,0x88, + 0x80,0x80,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x24,0x04,0x04,0x28,0x10, + /* 0xEBD5 [?] [7009]*/ + 0x00,0x3C,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x89, + 0x04,0x1E,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x08,0x0A,0x4A,0xA6,0x12, + /* 0xEBD6 [?] [7010]*/ + 0x00,0x79,0x48,0x48,0x48,0x78,0x48,0x4B,0x48,0x79,0x48,0x48,0x48,0x48,0x4B,0x98, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xEBD7 [?] [7011]*/ + 0x00,0x78,0x4A,0x49,0x49,0x78,0x4F,0x48,0x48,0x78,0x48,0x48,0x49,0x49,0x4A,0x9C, + 0x40,0x44,0x44,0x48,0x50,0x40,0xFE,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xEBD8 [?] [7012]*/ + 0x00,0x7B,0x4A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x9A, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xF4,0x94,0x94,0x94,0xF4,0x04,0x04,0x14,0x08, + /* 0xEBD9 [?] [7013]*/ + 0x00,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x89, + 0x00,0xFC,0x04,0x24,0x24,0x24,0xFC,0x24,0x24,0x54,0x4C,0x8C,0x04,0x04,0xFC,0x04, + /* 0xEBDA [?] [7014]*/ + 0x00,0x78,0x48,0x48,0x49,0x7A,0x48,0x48,0x48,0x7B,0x48,0x48,0x48,0x49,0x4B,0x99, + 0x20,0x20,0x50,0x88,0x04,0x02,0xF8,0x00,0x00,0xFE,0x20,0x40,0x88,0x04,0xFE,0x02, + /* 0xEBDB [?] [7015]*/ + 0x00,0x79,0x48,0x48,0x48,0x78,0x49,0x48,0x4B,0x78,0x48,0x48,0x49,0x4A,0x48,0x98, + 0x04,0x88,0x50,0x20,0x50,0x88,0x24,0x20,0xFE,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xEBDC [?] [7016]*/ + 0x00,0x78,0x4B,0x48,0x48,0x78,0x49,0x4B,0x48,0x78,0x48,0x49,0x4A,0x48,0x48,0x9B, + 0x40,0x20,0xFE,0x40,0x90,0x90,0x24,0xE4,0x44,0x48,0x88,0x10,0x30,0x48,0x84,0x04, + /* 0xEBDD [?] [7017]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x24,0x44,0x54,0x89, + 0x84,0x48,0x00,0xFC,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xEBDE [?] [7018]*/ + 0x00,0x3C,0x24,0x24,0x25,0x3C,0x24,0x24,0x27,0x3C,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x88,0x48,0x50,0x00,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEBDF [?] [7019]*/ + 0x00,0x3C,0x25,0x24,0x24,0x3C,0x24,0x27,0x24,0x3C,0x24,0x25,0x25,0x46,0x54,0x88, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xEBE0 [?] [7020]*/ + 0x00,0x7B,0x48,0x48,0x49,0x7A,0x48,0x48,0x49,0x7A,0x48,0x48,0x49,0x4A,0x48,0x98, + 0x00,0xFE,0x40,0x80,0x44,0x24,0x68,0xB0,0x30,0x28,0x68,0xA4,0x22,0x20,0xA0,0x40, + /* 0xEBE1 [?] [7021]*/ + 0x00,0x79,0x49,0x49,0x49,0x79,0x48,0x48,0x4B,0x7A,0x4A,0x4A,0x4B,0x4A,0x4A,0x9A, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x52,0x8A,0x0A,0x02,0x0A,0x04, + /* 0xEBE2 [?] [7022]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3D,0x26,0x24,0x24,0x3D,0x24,0x24,0x24,0x44,0x57,0x88, + 0x20,0x20,0xA8,0xA8,0xA8,0x74,0x22,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xEBE3 [?] [7023]*/ + 0x00,0x78,0x4B,0x48,0x4A,0x79,0x48,0x4B,0x48,0x78,0x4F,0x48,0x48,0x48,0x48,0x98, + 0x08,0x3C,0xC0,0x04,0x44,0x28,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xEBE4 [?] [7024]*/ + 0x00,0x78,0x4B,0x4A,0x4C,0x79,0x48,0x48,0x4B,0x78,0x48,0x48,0x49,0x49,0x4A,0x9C, + 0x40,0x20,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xEBE5 [?] [7025]*/ + 0x00,0x7B,0x4A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4D,0x4D,0x4A,0x98, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x20,0x22,0xB2,0xB4,0xA8,0xA8,0x24,0x24,0xA2,0x40, + /* 0xEBE6 [?] [7026]*/ + 0x00,0x78,0x4B,0x48,0x49,0x78,0x4B,0x48,0x49,0x79,0x49,0x49,0x49,0x49,0x49,0x99, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xEBE7 [?] [7027]*/ + 0x00,0x78,0x4B,0x49,0x4A,0x7C,0x4B,0x4A,0x4A,0x7B,0x4A,0x4A,0x4B,0x48,0x48,0x98, + 0x40,0x80,0xFC,0x10,0x48,0x46,0xF8,0x48,0x48,0xF8,0x48,0x48,0xF8,0x42,0x42,0x3E, + /* 0xEBE8 [?] [7028]*/ + 0x00,0x78,0x48,0x4F,0x48,0x78,0x48,0x4B,0x48,0x78,0x48,0x4F,0x48,0x48,0x48,0x98, + 0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x9C,0x90,0x90,0x90,0x9E,0x90,0x90,0x90,0x90, + /* 0xEBE9 [?] [7029]*/ + 0x00,0x3C,0x24,0x25,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x24,0x24,0x44,0x55,0x8A, + 0x20,0x20,0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x24,0x50,0x50,0x88,0x04,0x02, + /* 0xEBEA [?] [7030]*/ + 0x00,0x78,0x4B,0x4A,0x48,0x79,0x48,0x48,0x4B,0x78,0x49,0x49,0x4A,0x4C,0x48,0x98, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xEBEB [?] [7031]*/ + 0x00,0x78,0x4B,0x4A,0x4C,0x78,0x4B,0x48,0x48,0x79,0x49,0x49,0x4A,0x4A,0x4C,0x98, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xEBEC [?] [7032]*/ + 0x00,0x78,0x48,0x4B,0x49,0x79,0x4A,0x4A,0x4F,0x79,0x49,0x4D,0x4A,0x4B,0x4C,0x98, + 0x10,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x10,0x00,0xFE,0x00, + /* 0xEBED [?] [7033]*/ + 0x00,0x78,0x4B,0x48,0x49,0x78,0x4B,0x48,0x49,0x7A,0x48,0x49,0x48,0x48,0x48,0x9B, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x20,0xFC,0x20,0x50,0x88,0x04, + /* 0xEBEE [?] [7034]*/ + 0x00,0x78,0x4B,0x48,0x48,0x7B,0x4A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x9A, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x8A,0x52,0xFA,0x22,0x22,0xFA,0x22,0x22,0x2A,0x04, + /* 0xEBEF [?] [7035]*/ + 0x00,0x3D,0x24,0x24,0x25,0x3D,0x25,0x25,0x25,0x3D,0x25,0x25,0x25,0x45,0x55,0x89, + 0x00,0xFE,0x20,0x40,0xFC,0x54,0x54,0x74,0x54,0x54,0x74,0x54,0x54,0x54,0xFC,0x04, + /* 0xEBF0 [?] [7036]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3C,0x24,0x24,0x24,0x3D,0x25,0x25,0x25,0x45,0x57,0x88, + 0x00,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xEBF1 [?] [7037]*/ + 0x00,0x3D,0x25,0x25,0x25,0x3C,0x25,0x24,0x25,0x3C,0x24,0x24,0x24,0x44,0x54,0x88, + 0x00,0xDC,0x54,0x54,0xDC,0x00,0xFC,0x00,0xFE,0x80,0xFC,0x04,0x04,0x04,0x28,0x10, + /* 0xEBF2 [?] [7038]*/ + 0x00,0x78,0x49,0x4A,0x4D,0x78,0x4B,0x4A,0x4A,0x7B,0x4A,0x4A,0x4B,0x4A,0x4A,0x9A, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xEBF3 [?] [7039]*/ + 0x00,0x79,0x48,0x48,0x49,0x78,0x4B,0x48,0x49,0x7A,0x4C,0x49,0x48,0x48,0x4B,0x98, + 0x20,0x24,0xA8,0x20,0xFC,0x40,0xFE,0x88,0x24,0x22,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEBF4 [?] [7040]*/ + 0x00,0x79,0x48,0x48,0x49,0x78,0x4B,0x48,0x49,0x7A,0x4D,0x48,0x49,0x48,0x48,0x99, + 0x20,0x24,0xA8,0x20,0xFC,0x40,0xFE,0x88,0x44,0x42,0xFC,0x88,0xD0,0x30,0x48,0x84, + /* 0xEBF5 [?] [7041]*/ + 0x00,0x7B,0x48,0x49,0x49,0x79,0x49,0x48,0x4B,0x7A,0x4A,0x4B,0x4A,0x4A,0x4A,0x9A, + 0x00,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x8A,0x52,0xFE,0x22,0x22,0x2A,0x04, + /* 0xEBF6 [?] [7042]*/ + 0x20,0xFE,0x21,0x3C,0x24,0x44,0x54,0x88,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10, + 0x40,0xFE,0x00,0x1C,0xE0,0x94,0xA8,0xC6,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x50,0x20, + /* 0xEBF7 [?] [7043]*/ + 0x00,0x78,0x4B,0x4A,0x4C,0x79,0x49,0x49,0x49,0x79,0x49,0x4F,0x48,0x48,0x49,0x9A, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xEBF8 [?] [7044]*/ + 0x00,0x79,0x48,0x49,0x48,0x78,0x4B,0x48,0x49,0x7A,0x4D,0x48,0x49,0x4A,0x48,0x98, + 0x20,0x24,0xA8,0xFC,0x20,0x40,0xFE,0x88,0x24,0x22,0x24,0xA8,0x24,0x22,0xA0,0x40, + /* 0xEBF9 [?] [7045]*/ + 0x00,0x78,0x4B,0x4A,0x49,0x7B,0x48,0x48,0x49,0x78,0x48,0x49,0x48,0x48,0x4B,0x98, + 0x40,0x20,0xFE,0x8A,0x04,0xFE,0x40,0x88,0xFC,0x24,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEBFA [?] [7046]*/ + 0x00,0x78,0x49,0x48,0x48,0x7B,0x4A,0x4C,0x49,0x79,0x49,0x48,0x49,0x49,0x49,0x99, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x2C,0x20,0xFC,0x04,0xFC,0x04, + /* 0xEBFB [?] [7047]*/ + 0x00,0x78,0x4F,0x48,0x48,0x7B,0x48,0x4B,0x4A,0x7A,0x4B,0x4A,0x49,0x48,0x4F,0x9A, + 0x88,0x88,0xC8,0xBE,0x88,0xC8,0x1C,0xD4,0x54,0x54,0xD4,0x48,0x88,0xD4,0x14,0x22, + /* 0xEBFC [?] [7048]*/ + 0x00,0x7B,0x48,0x4B,0x4A,0x79,0x48,0x4B,0x48,0x78,0x4B,0x48,0x4B,0x48,0x4B,0x98, + 0x88,0xFE,0x88,0xFE,0x02,0xFC,0x00,0xFE,0x40,0xA2,0x54,0xB8,0x54,0x92,0x50,0x20, + /* 0xEBFD [?] [7049]*/ + 0x00,0x3C,0x24,0x24,0x24,0x3D,0x25,0x25,0x25,0x3C,0x27,0x24,0x24,0x45,0x56,0x88, + 0xF8,0x88,0x88,0xF8,0x00,0xDC,0x54,0x54,0xDC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xEBFE [?] [7050]*/ + 0x00,0x7B,0x48,0x4B,0x4A,0x7A,0x4A,0x4B,0x48,0x79,0x49,0x49,0x49,0x49,0x48,0x9B, + 0x20,0xFE,0x00,0xFC,0x04,0xF4,0x94,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE, + /* 0xECA1 [?] [7051]*/ + 0x00,0x7B,0x4A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4A,0x4D,0x4E,0x98, + 0x20,0xFE,0x88,0x50,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50, + /* 0xECA2 [?] [7052]*/ + 0x00,0x79,0x48,0x4B,0x48,0x79,0x4A,0x49,0x49,0x79,0x4A,0x4D,0x48,0x49,0x4A,0x9C, + 0x20,0x24,0xA8,0xFE,0xA8,0x24,0x22,0x04,0x04,0xDE,0x44,0x54,0x9E,0x04,0x04,0x04, + /* 0xECA3 [?] [7053]*/ + 0x20,0x20,0x20,0x3F,0x20,0x40,0x40,0x7E,0x02,0x02,0x1A,0xE2,0x42,0x02,0x14,0x09, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xECA4 [?] [7054]*/ + 0x42,0x24,0x18,0x24,0x52,0x10,0xFF,0x20,0x28,0x7E,0xAA,0x2A,0x2A,0x2E,0x08,0x09, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xECA5 [?] [7055]*/ + 0x08,0x08,0x7F,0x14,0x22,0x41,0xFF,0x02,0x7A,0x4A,0x4A,0x7A,0x4A,0x02,0x0A,0x04, + 0x20,0x20,0x20,0x3E,0x22,0x44,0x50,0x90,0x10,0x10,0x10,0x28,0x28,0x44,0x44,0x82, + /* 0xECA6 [?] [7056]*/ + 0x02,0x0F,0x78,0x08,0x08,0xFF,0x28,0x4B,0x49,0x49,0x6B,0x49,0x49,0x7F,0x41,0x01, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xECA7 [?] [7057]*/ + 0x10,0x08,0xFF,0x00,0x42,0x24,0xFF,0x00,0x7E,0x42,0x42,0x7E,0x42,0x42,0x7E,0x43, + 0x20,0x20,0x20,0x7E,0x42,0x84,0x10,0x10,0x10,0x10,0x28,0x28,0x48,0x44,0x84,0x02, + /* 0xECA8 [?] [7058]*/ + 0x08,0x14,0x22,0x5D,0x80,0x3E,0x22,0x3E,0x00,0x77,0x11,0x55,0x33,0x55,0x11,0x33, + 0x20,0x20,0x20,0x3E,0xA2,0x44,0x50,0x90,0x10,0x10,0x10,0x28,0x28,0x44,0x44,0x82, + /* 0xECA9 [?] [7059]*/ + 0x00,0x7C,0x44,0x45,0x46,0x4C,0x6C,0x54,0x54,0x54,0x6C,0x44,0x44,0x42,0x41,0x80, + 0x40,0x40,0xFC,0x04,0xF4,0x94,0xF4,0x84,0x94,0x8A,0x82,0x7E,0x00,0x02,0xFE,0x00, + /* 0xECAA [?] [7060]*/ + 0x20,0x13,0x12,0xFE,0x03,0x0A,0x8A,0x8A,0x4A,0x4A,0x52,0x53,0x1C,0xE4,0x48,0x10, + 0x00,0xF8,0x08,0x08,0x28,0xA8,0xA8,0x48,0x48,0xA8,0xA8,0x2A,0x0A,0x0A,0x06,0x02, + /* 0xECAB [?] [7061]*/ + 0x00,0x7C,0x44,0x44,0x44,0x4C,0x6C,0x54,0x54,0x55,0x6C,0x44,0x44,0x42,0x41,0x80, + 0x00,0xF8,0x88,0xF8,0x88,0xF8,0x88,0xF8,0x88,0xFC,0x00,0x50,0x88,0x02,0xFE,0x00, + /* 0xECAC [?] [7062]*/ + 0x00,0x7D,0x45,0x45,0x45,0x4D,0x6C,0x55,0x54,0x54,0x6C,0x44,0x45,0x42,0x41,0x80, + 0xA0,0x2C,0x24,0xAC,0x24,0xFC,0x20,0xFC,0x04,0xC8,0x30,0x48,0x84,0x02,0xFE,0x00, + /* 0xECAD [?] [7063]*/ + 0x00,0x14,0x10,0xFE,0x28,0x44,0x82,0x24,0x36,0x24,0xFF,0x24,0x54,0x4B,0x89,0x12, + 0x00,0xF8,0x88,0x88,0x88,0x98,0xD8,0xA8,0xA8,0xA8,0xD8,0x8A,0x8A,0x0A,0x06,0x02, + /* 0xECAE [?] [7064]*/ + 0x00,0x7C,0x44,0x45,0x44,0x4C,0x6D,0x54,0x56,0x55,0x6C,0x45,0x46,0x42,0x41,0x80, + 0x20,0xA4,0xA4,0x28,0x50,0x88,0x04,0x88,0xAA,0xDC,0x88,0x54,0x22,0x02,0xFE,0x00, + /* 0xECAF [?] [7065]*/ + 0x00,0x0F,0x08,0x08,0x08,0x10,0x20,0xC0,0x3F,0x10,0x08,0x04,0x03,0x0C,0x30,0xC0, + 0x00,0xE0,0x20,0x20,0x20,0x20,0x1E,0x00,0xF0,0x10,0x20,0x40,0x80,0x60,0x18,0x06, + /* 0xECB0 [?] [7066]*/ + 0x10,0xFE,0x10,0x7C,0x00,0xFE,0x82,0x7C,0x00,0x7C,0x04,0x7C,0x40,0x7C,0x04,0x0D, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xECB1 [?] [7067]*/ + 0x10,0xFE,0x10,0x7C,0x00,0xFE,0x82,0x10,0x7C,0x20,0x50,0x7C,0x10,0xFE,0x10,0x11, + 0x00,0x78,0x48,0x48,0x48,0x86,0x00,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xECB2 [?] [7068]*/ + 0x08,0xFF,0x08,0x7F,0x00,0xFF,0xA0,0x3E,0x42,0xFF,0x49,0x7F,0x49,0x7F,0x49,0x8B, + 0x00,0xB8,0x28,0x28,0x28,0xC6,0x80,0x7C,0x24,0x24,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xECB3 [?] [7069]*/ + 0x04,0x7C,0x04,0x04,0x3C,0x04,0x04,0x7C,0x04,0x01,0xFF,0x08,0x04,0x03,0x1C,0xE0, + 0x40,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x40,0x00,0xFE,0x20,0x40,0x80,0x70,0x0E, + /* 0xECB4 [?] [7070]*/ + 0x02,0x01,0x7F,0x08,0x04,0x03,0x1C,0xE2,0x2E,0x22,0x2E,0x22,0x2E,0x22,0x5F,0x80, + 0x00,0x00,0xFC,0x20,0x40,0x80,0x70,0x8E,0xE8,0x88,0xE8,0x88,0xE8,0x88,0xF8,0x08, + /* 0xECB5 [?] [7071]*/ + 0x02,0x41,0x25,0x04,0xFD,0x14,0x15,0x15,0x95,0x55,0x25,0x25,0x54,0x55,0x84,0x04, + 0x00,0x7C,0x04,0x44,0xF4,0x44,0xF4,0x54,0x74,0xD4,0x54,0xF4,0xE4,0x54,0x44,0x4C, + /* 0xECB6 [?] [7072]*/ + 0x20,0x10,0x00,0xFE,0x20,0x20,0x3D,0x26,0x24,0x24,0x24,0x24,0x44,0x54,0x88,0x00, + 0x20,0x20,0x20,0x50,0x50,0x88,0x04,0x02,0x60,0x10,0x00,0xC0,0x20,0x10,0x08,0x00, + /* 0xECB7 [?] [7073]*/ + 0x20,0x10,0x10,0x01,0xFE,0x21,0x20,0x3C,0x25,0x25,0x25,0x25,0x25,0x45,0x54,0x88, + 0x80,0x80,0xFE,0x20,0x20,0xFE,0x20,0x20,0xFC,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xECB8 [?] [7074]*/ + 0x20,0x10,0x10,0x01,0xFE,0x21,0x20,0x3C,0x25,0x24,0x24,0x27,0x24,0x44,0x54,0x88, + 0x80,0x80,0xFE,0x00,0x1C,0xE0,0x20,0x3C,0xE0,0x20,0x3E,0xE0,0x20,0x22,0x22,0x1E, + /* 0xECB9 [?] [7075]*/ + 0x20,0x10,0x10,0x01,0xFE,0x20,0x20,0x3C,0x24,0x24,0x25,0x24,0x24,0x45,0x55,0x8A, + 0x80,0x80,0xFE,0x00,0x00,0xFC,0x84,0xA4,0x94,0x84,0xFE,0x84,0x84,0x04,0x14,0x08, + /* 0xECBA [?] [7076]*/ + 0x20,0x10,0x10,0x01,0xFE,0x20,0x20,0x3C,0x25,0x24,0x24,0x24,0x24,0x44,0x55,0x88, + 0x80,0x80,0xFE,0x10,0x10,0x90,0xFE,0x90,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xECBB [?] [7077]*/ + 0x20,0x10,0x10,0x01,0xFE,0x20,0x20,0x3C,0x24,0x24,0x24,0x24,0x24,0x45,0x55,0x8A, + 0x80,0x80,0xFE,0x00,0x00,0xFC,0x84,0x84,0xFC,0x80,0xA4,0xA8,0xB0,0x22,0x22,0x1E, + /* 0xECBC [?] [7078]*/ + 0x21,0x11,0x11,0x02,0xFC,0x21,0x20,0x3C,0x25,0x24,0x24,0x24,0x24,0x44,0x55,0x8A, + 0x00,0x00,0xFE,0x40,0x20,0xFE,0x40,0x84,0xFE,0x02,0xA8,0xA8,0xA8,0xAA,0x2A,0x26, + /* 0xECBD [?] [7079]*/ + 0x21,0x11,0x11,0x02,0xFC,0x21,0x20,0x3C,0x27,0x24,0x25,0x25,0x25,0x44,0x54,0x88, + 0x00,0x00,0xFE,0x00,0x20,0xFC,0x50,0x88,0xFE,0x08,0xE8,0x28,0xE8,0x08,0x28,0x10, + /* 0xECBE [?] [7080]*/ + 0x10,0x11,0x10,0x14,0x58,0x50,0x51,0x90,0x10,0x10,0x11,0x29,0x26,0x44,0x40,0x81, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xECBF [?] [7081]*/ + 0x10,0x10,0x10,0x13,0x54,0x58,0x51,0x90,0x10,0x13,0x10,0x28,0x24,0x44,0x40,0x80, + 0x40,0x40,0x40,0xFE,0x40,0x40,0xFC,0x40,0x40,0xFE,0x42,0x42,0x4A,0x44,0x40,0x40, + /* 0xECC0 [?] [7082]*/ + 0x10,0x10,0x10,0x11,0x54,0x59,0x51,0x91,0x11,0x11,0x10,0x28,0x24,0x44,0x40,0x80, + 0x20,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x22,0x22,0x1E,0x00, + /* 0xECC1 [?] [7083]*/ + 0x10,0x10,0x10,0x14,0x59,0x52,0x54,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x40,0x80, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0x06,0xF0,0x10,0x10,0x50,0x20,0x04,0x04,0xFC,0x00, + /* 0xECC2 [?] [7084]*/ + 0x10,0x10,0x13,0x10,0x54,0x58,0x50,0x90,0x11,0x12,0x14,0x28,0x24,0x44,0x40,0x80, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xECC3 [?] [7085]*/ + 0x10,0x10,0x13,0x10,0x55,0x58,0x50,0x90,0x13,0x10,0x10,0x28,0x24,0x44,0x40,0x80, + 0x08,0x3C,0xE0,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xECC4 [?] [7086]*/ + 0x10,0x10,0x10,0x15,0x58,0x50,0x50,0x90,0x11,0x10,0x10,0x28,0x24,0x40,0x43,0x80, + 0x40,0x20,0x00,0xFE,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xECC5 [?] [7087]*/ + 0x10,0x10,0x10,0x15,0x58,0x50,0x50,0x90,0x11,0x10,0x10,0x28,0x24,0x45,0x40,0x80, + 0x20,0x10,0x10,0xFE,0x20,0x20,0x44,0x84,0xF8,0x10,0x20,0x44,0x82,0xFE,0x82,0x00, + /* 0xECC6 [?] [7088]*/ + 0x02,0x04,0x08,0x10,0x3F,0x00,0x1F,0x10,0x10,0x1F,0x01,0x11,0x22,0x04,0x18,0xE0, + 0x00,0x00,0x20,0x10,0xF8,0x08,0xF0,0x10,0x10,0xF0,0x00,0x10,0xA0,0x40,0x30,0x0E, + /* 0xECC7 [?] [7089]*/ + 0x10,0x10,0x11,0x15,0x5B,0x55,0x51,0x91,0x11,0x10,0x13,0x28,0x24,0x44,0x40,0x80, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xECC8 [?] [7090]*/ + 0x11,0x10,0x10,0x14,0x5B,0x50,0x50,0x91,0x10,0x10,0x13,0x28,0x24,0x44,0x40,0x80, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xECC9 [?] [7091]*/ + 0x10,0x13,0x10,0x10,0x55,0x58,0x50,0x93,0x10,0x10,0x11,0x29,0x25,0x45,0x41,0x81, + 0x00,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xECCA [?] [7092]*/ + 0x10,0x10,0x10,0x14,0x59,0x52,0x50,0x90,0x10,0x10,0x11,0x29,0x25,0x45,0x41,0x81, + 0x20,0x20,0x50,0x88,0x44,0x22,0xF8,0x08,0x10,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xECCB [?] [7093]*/ + 0x11,0x10,0x12,0x16,0x5A,0x52,0x52,0x92,0x12,0x13,0x12,0x2A,0x26,0x42,0x42,0x82, + 0x00,0xBE,0x82,0x02,0x22,0x12,0x52,0x42,0xCA,0x56,0x52,0x32,0x02,0x02,0x0A,0x04, + /* 0xECCC [?] [7094]*/ + 0x10,0x10,0x10,0x14,0x59,0x51,0x51,0x91,0x11,0x11,0x10,0x2B,0x24,0x44,0x40,0x80, + 0x20,0x20,0x3E,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xECCD [?] [7095]*/ + 0x01,0x11,0x11,0x22,0x04,0x18,0xE0,0x08,0x0A,0x2A,0x2C,0x48,0x14,0x22,0x42,0x80, + 0x00,0x08,0x08,0x90,0x40,0x30,0x0E,0x10,0x10,0x54,0x54,0x98,0x10,0x28,0x44,0x82, + /* 0xECCE [?] [7096]*/ + 0x11,0x11,0x11,0x17,0x59,0x51,0x51,0x93,0x12,0x12,0x12,0x2A,0x27,0x44,0x40,0x80, + 0x00,0x3C,0x24,0xA4,0x24,0x3C,0x24,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0x44,0x54,0x88, + /* 0xECCF [?] [7097]*/ + 0x10,0x11,0x11,0x15,0x59,0x51,0x51,0x90,0x10,0x13,0x10,0x29,0x24,0x40,0x47,0x80, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x40,0x20,0xFE,0x00,0x04,0x88,0x00,0xFE,0x00, + /* 0xECD0 [?] [7098]*/ + 0x10,0x11,0x11,0x11,0x55,0x59,0x51,0x91,0x10,0x13,0x11,0x29,0x25,0x45,0x41,0x81, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x00,0xFE,0x20,0x22,0x14,0x48,0x84,0x02, + /* 0xECD1 [?] [7099]*/ + 0x10,0x11,0x11,0x11,0x55,0x59,0x51,0x91,0x11,0x11,0x11,0x29,0x27,0x45,0x41,0x81, + 0x20,0xDC,0x14,0x14,0x14,0xD4,0x26,0x00,0xDC,0x14,0x14,0xD4,0x08,0x08,0x14,0x22, + /* 0xECD2 [?] [7100]*/ + 0x08,0x0B,0x12,0x33,0x50,0x97,0x11,0x12,0x14,0x10,0x01,0x11,0x22,0x04,0x18,0xE0, + 0x00,0xF8,0x08,0xF8,0x40,0xFC,0x50,0x48,0x44,0x40,0x00,0x10,0xA0,0x40,0x30,0x0E, + /* 0xECD3 [?] [7101]*/ + 0x10,0x10,0x13,0x12,0x54,0x59,0x50,0x91,0x11,0x11,0x11,0x29,0x25,0x44,0x43,0x80, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xECD4 [?] [7102]*/ + 0x10,0x10,0x11,0x11,0x55,0x59,0x51,0x91,0x11,0x11,0x12,0x2A,0x24,0x44,0x40,0x80, + 0x40,0x20,0xFE,0x02,0x02,0xFE,0x00,0x00,0xFE,0xAA,0xAA,0xFE,0xAA,0xAA,0xA2,0x86, + /* 0xECD5 [?] [7103]*/ + 0x20,0x24,0x22,0x22,0xA8,0xB0,0xAE,0xA2,0x22,0x22,0x22,0x22,0x52,0x4A,0x45,0x88, + 0x00,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0xA2,0x94,0x88,0xA8,0xC4,0x84,0x00,0xFE, + /* 0xECD6 [?] [7104]*/ + 0x10,0x13,0x12,0x16,0x5A,0x52,0x53,0x90,0x13,0x12,0x12,0x2B,0x26,0x42,0x43,0x82, + 0x40,0xBE,0x12,0x92,0x52,0xAA,0x24,0x40,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xECD7 [?] [7105]*/ + 0x10,0x11,0x11,0x11,0x55,0x59,0x50,0x93,0x12,0x13,0x10,0x29,0x24,0x44,0x41,0x86, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0xFC,0x00,0xF8,0x90,0x60,0x98,0x06, + /* 0xECD8 [?] [7106]*/ + 0x10,0x10,0x13,0x14,0x58,0x53,0x52,0x92,0x13,0x12,0x12,0x2A,0x26,0x42,0x42,0x82, + 0x40,0x20,0xFE,0x88,0x50,0xFE,0x52,0x8A,0x06,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xECD9 [?] [7107]*/ + 0x3F,0x21,0x3F,0x20,0x2F,0x20,0x5F,0x44,0x95,0x2C,0x01,0x11,0x22,0x04,0x18,0xE0, + 0x08,0x08,0x7E,0x08,0x48,0x28,0xA8,0x08,0x28,0x90,0x00,0x10,0xA0,0x40,0x30,0x0E, + /* 0xECDA [?] [7108]*/ + 0x10,0x13,0x10,0x12,0x55,0x5A,0x50,0x90,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x81, + 0x00,0xDE,0x42,0x52,0x4A,0x52,0x42,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xECDB [?] [7109]*/ + 0x20,0x21,0x27,0x24,0xAD,0xB4,0xA7,0xA4,0x25,0x24,0x20,0x27,0x50,0x49,0x42,0x8C, + 0x80,0x00,0xFC,0x44,0x54,0x44,0xFC,0xE4,0x54,0x04,0x40,0xFE,0xA0,0x10,0x08,0x06, + /* 0xECDC [?] [7110]*/ + 0x10,0x13,0x11,0x10,0x55,0x58,0x51,0x92,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x81, + 0x3C,0xE0,0x24,0xA8,0xFE,0xA8,0x24,0x02,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xECDD [?] [7111]*/ + 0x10,0x12,0x11,0x14,0x58,0x50,0x53,0x91,0x11,0x11,0x11,0x29,0x25,0x41,0x42,0x84, + 0x44,0x24,0x28,0x7E,0x10,0x28,0x4A,0x1C,0x28,0x4C,0x1A,0x2A,0x48,0x10,0xFE,0x00, + /* 0xECDE [?] [7112]*/ + 0xFE,0x20,0x50,0x9A,0x2C,0x48,0x9C,0x2A,0xC8,0x18,0x01,0x11,0x22,0x04,0x18,0xE0, + 0xFE,0x20,0x50,0x9A,0x2C,0x48,0x9C,0x2A,0xC8,0x18,0x00,0x10,0xA0,0x40,0x30,0x0E, + /* 0xECDF [?] [7113]*/ + 0x10,0x13,0x11,0x14,0x5B,0x52,0x53,0x90,0x13,0x12,0x13,0x2A,0x27,0x42,0x42,0x83, + 0x1E,0xE0,0x22,0x94,0xFE,0x52,0xFE,0x04,0xC4,0x7E,0xC4,0x54,0xCC,0x84,0xD4,0x48, + /* 0xECE0 [?] [7114]*/ + 0x2F,0x48,0x6B,0x48,0x6B,0x4A,0xFF,0x88,0x7E,0x2C,0x4A,0xFF,0x11,0x29,0xC6,0x18, + 0xEC,0x24,0xAC,0x24,0xAC,0xA4,0xFE,0x22,0xFC,0x68,0xA4,0xFE,0x10,0x28,0xC6,0x30, + /* 0xECE1 [?] [7115]*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x22,0x42,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x44,0x44,0x04, + /* 0xECE2 [?] [7116]*/ + 0x02,0x02,0x7F,0x02,0x3F,0x04,0xFF,0x08,0x1F,0x20,0x44,0x82,0x02,0x00,0x24,0x42, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x20,0xFC,0x20,0x20,0x20,0xA0,0x40,0x88,0x44, + /* 0xECE3 [?] [7117]*/ + 0x01,0x79,0x49,0x4A,0x4C,0x79,0x49,0x49,0x49,0x48,0x78,0x00,0x24,0x22,0x42,0x80, + 0x00,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x04,0x28,0x10,0x88,0x44,0x44,0x04, + /* 0xECE4 [?] [7118]*/ + 0x01,0x7F,0x01,0x3F,0x00,0x3F,0x20,0x3F,0x08,0xFF,0x00,0x3F,0x20,0x3F,0x24,0x42, + 0x00,0xFC,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x20,0xFE,0x00,0xF8,0x08,0xF8,0x88,0x44, + /* 0xECE5 [?] [7119]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x20,0x2F,0x21,0x21,0x42,0x44,0x88,0x10, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x80,0xA0,0x90,0xFC,0x40,0x40,0x20,0x10,0x08,0x06, + /* 0xECE6 [?] [7120]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x22,0x21,0x24,0x22,0x20,0x5F,0x40,0x80,0x00, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x00,0x20,0x20,0x20,0x20,0x7E,0xA0,0x20,0x20,0x20, + /* 0xECE7 [?] [7121]*/ + 0x02,0x01,0x3F,0x20,0x20,0x3F,0x20,0x20,0x2F,0x28,0x29,0x29,0x49,0x49,0x88,0x08, + 0x00,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x04,0xE4,0x24,0x24,0xE4,0x14,0x08, + /* 0xECE8 [?] [7122]*/ + 0x01,0x00,0x3F,0x20,0x3F,0x20,0x27,0x24,0x27,0x20,0x2F,0x28,0x4F,0x48,0x88,0x07, + 0x00,0x80,0xFC,0x04,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x88,0xF8,0x02,0x02,0xFE, + /* 0xECE9 [?] [7123]*/ + 0x01,0x00,0x3F,0x20,0x3F,0x21,0x21,0x3F,0x21,0x21,0x2F,0x21,0x41,0x5F,0x81,0x01, + 0x00,0x80,0xFC,0x04,0xFC,0x20,0x20,0x3E,0x20,0x20,0x3C,0x20,0x20,0x3E,0x20,0x20, + /* 0xECEA [?] [7124]*/ + 0x20,0x10,0x10,0xF8,0x08,0x10,0x10,0x38,0x54,0x94,0x10,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xECEB [?] [7125]*/ + 0x20,0x10,0x11,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x11,0x11,0x10,0x10, + 0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0x02,0x02,0x02,0xFE,0x00, + /* 0xECEC [?] [7126]*/ + 0x20,0x10,0x11,0xF8,0x08,0x10,0x10,0x3B,0x54,0x94,0x10,0x10,0x10,0x10,0x11,0x12, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xECED [?] [7127]*/ + 0x20,0x10,0x10,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x11,0x11,0x17,0x10, + 0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xECEE [?] [7128]*/ + 0x20,0x10,0x10,0xF9,0x08,0x10,0x10,0x3B,0x54,0x94,0x10,0x10,0x10,0x11,0x10,0x10, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00, + /* 0xECEF [?] [7129]*/ + 0x20,0x10,0x10,0xF8,0x0B,0x10,0x10,0x38,0x55,0x95,0x11,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xECF0 [?] [7130]*/ + 0x20,0x10,0x10,0xF8,0x0B,0x10,0x10,0x38,0x55,0x95,0x11,0x11,0x12,0x12,0x14,0x11, + 0x50,0x48,0x48,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xECF1 [?] [7131]*/ + 0x20,0x10,0x10,0xF8,0x09,0x11,0x12,0x38,0x54,0x94,0x10,0x10,0x10,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xECF2 [?] [7132]*/ + 0x20,0x10,0x10,0xF8,0x09,0x11,0x12,0x38,0x54,0x94,0x11,0x11,0x12,0x10,0x10,0x10, + 0x80,0x80,0x80,0xFE,0x02,0x04,0x20,0x20,0xA8,0xA4,0x24,0x22,0x22,0x20,0xA0,0x40, + /* 0xECF3 [?] [7133]*/ + 0x40,0x20,0x23,0xFA,0x12,0x12,0x22,0x33,0x6A,0xAA,0x22,0x22,0x22,0x22,0x23,0x22, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x10,0x10,0x12,0x0A,0x8A,0x26,0x12, + /* 0xECF4 [?] [7134]*/ + 0x20,0x11,0x10,0xF8,0x0B,0x10,0x10,0x39,0x55,0x95,0x11,0x11,0x10,0x10,0x10,0x10, + 0x00,0xFC,0x04,0x04,0xF4,0x04,0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x14,0x08, + /* 0xECF5 [?] [7135]*/ + 0x20,0x10,0x10,0xF8,0x08,0x11,0x11,0x39,0x55,0x95,0x11,0x11,0x10,0x10,0x10,0x11, + 0x20,0x20,0x3E,0x20,0x20,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x04, + /* 0xECF6 [?] [7136]*/ + 0x20,0x10,0x10,0xFA,0x09,0x10,0x18,0x35,0x52,0x94,0x10,0x10,0x11,0x11,0x12,0x14, + 0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x98,0x94,0x92,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xECF7 [?] [7137]*/ + 0x21,0x11,0x13,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x11,0x17,0x10,0x10,0x11,0x12, + 0x08,0x08,0xFC,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0xFE,0x00,0x90,0x08,0x04, + /* 0xECF8 [?] [7138]*/ + 0x21,0x10,0x10,0xF9,0x09,0x11,0x11,0x39,0x55,0x95,0x10,0x10,0x13,0x10,0x10,0x10, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xECF9 [?] [7139]*/ + 0x41,0x21,0x27,0xF9,0x13,0x11,0x27,0x31,0x69,0xA8,0x27,0x20,0x20,0x21,0x22,0x2C, + 0x00,0x3C,0xD4,0x14,0x94,0x14,0xD4,0x24,0x4C,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xECFA [?] [7140]*/ + 0x21,0x10,0x10,0xF8,0x0B,0x10,0x18,0x35,0x50,0x90,0x13,0x10,0x12,0x12,0x14,0x10, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00,0xA4,0x52,0x52,0x00, + /* 0xECFB [?] [7141]*/ + 0x40,0x27,0x20,0xFB,0x10,0x13,0x22,0x33,0x69,0xAF,0x20,0x23,0x22,0x22,0x23,0x22, + 0x40,0xFC,0x40,0xF8,0x00,0xF8,0x08,0xF8,0x10,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xECFC [?] [7142]*/ + 0x20,0x13,0x10,0xF9,0x09,0x11,0x18,0x37,0x50,0x93,0x10,0x17,0x10,0x11,0x16,0x10, + 0x20,0xFE,0x00,0xDC,0x54,0xDC,0x88,0xFE,0x88,0xFE,0x88,0xFE,0x94,0x88,0xA4,0xC2, + /* 0xECFD [?] [7143]*/ + 0x00,0xFF,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0xFE,0x00,0x40,0x20,0x10,0x08,0x00,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xECFE [?] [7144]*/ + 0x02,0x02,0x02,0x03,0x02,0x02,0x02,0xFF,0x00,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xEDA1 [?] [7145]*/ + 0x00,0x00,0x7E,0x02,0x24,0x14,0x08,0x14,0x22,0x40,0x01,0x08,0x48,0x48,0x87,0x00, + 0x08,0x08,0x08,0xFE,0x08,0x48,0x28,0x08,0x28,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDA2 [?] [7146]*/ + 0x08,0x08,0x7F,0x08,0x3E,0x08,0x7F,0x08,0x08,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x00,0x00,0x7C,0x24,0x24,0x24,0x44,0x54,0x88,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xEDA3 [?] [7147]*/ + 0x01,0x3F,0x01,0x01,0xFF,0x00,0x01,0x3F,0x01,0x01,0xFF,0x02,0x51,0x51,0x90,0x0F, + 0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x04,0x12,0x12,0xF0, + /* 0xEDA4 [?] [7148]*/ + 0x00,0xFF,0x02,0x04,0x3F,0x24,0x24,0x24,0x24,0x20,0x01,0x08,0x48,0x48,0x87,0x00, + 0x00,0xFE,0x00,0x00,0xF8,0x88,0x88,0x88,0xA8,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDA5 [?] [7149]*/ + 0x08,0x0B,0x10,0x30,0x57,0x90,0x10,0x10,0x13,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x38,0xC0,0x40,0x40,0xFC,0x40,0x40,0x40,0xF8,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xEDA6 [?] [7150]*/ + 0x08,0x04,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x20,0x40,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xEDA7 [?] [7151]*/ + 0x40,0x20,0x09,0x12,0x24,0xE0,0x20,0x23,0x2C,0x01,0x08,0x48,0x48,0x48,0x87,0x00, + 0x80,0x80,0xFC,0x04,0x48,0x40,0xA0,0x18,0x06,0x00,0x88,0x84,0x12,0x12,0xF0,0x00, + /* 0xEDA8 [?] [7152]*/ + 0x01,0x7F,0x01,0x3F,0x00,0x7F,0x40,0x8F,0x08,0x10,0x20,0xC1,0x28,0x28,0x48,0x07, + 0x00,0xFC,0x00,0xF8,0x00,0xFE,0x02,0xE4,0x20,0x22,0x22,0x1E,0x88,0xA4,0x24,0xE0, + /* 0xEDA9 [?] [7153]*/ + 0x12,0x21,0x48,0x94,0x21,0x62,0xAE,0x22,0x22,0x22,0x21,0x08,0x48,0x48,0x87,0x00, + 0x00,0x3C,0x00,0x00,0x7E,0x08,0x08,0x08,0x28,0x10,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDAA [?] [7154]*/ + 0x00,0x7F,0x41,0x7F,0x48,0x7F,0x48,0x45,0x53,0x61,0x01,0x08,0x48,0x48,0x87,0x00, + 0x20,0x20,0x3E,0x44,0xA4,0x24,0x28,0x10,0x28,0x46,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDAB [?] [7155]*/ + 0x3F,0x24,0x2F,0x25,0x3F,0x22,0x27,0x2A,0x33,0x20,0x3F,0x02,0x51,0x51,0x90,0x0F, + 0xFC,0x20,0xF8,0x20,0xFC,0x00,0xF0,0x10,0xF0,0x00,0xFC,0x00,0x04,0x12,0x12,0xF0, + /* 0xEDAC [?] [7156]*/ + 0x1C,0x70,0x10,0xFE,0x10,0x7C,0x44,0x44,0x7C,0x44,0x01,0x08,0x48,0x48,0x87,0x00, + 0x10,0x20,0xFC,0x84,0xFC,0x84,0xFC,0x84,0xFC,0x00,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDAD [?] [7157]*/ + 0x08,0x7F,0x00,0x3E,0x23,0x3E,0x00,0x3E,0x04,0x7F,0x08,0x29,0x11,0x48,0x48,0x87, + 0x40,0x40,0x7E,0x88,0x48,0x48,0x50,0x50,0x20,0x50,0x88,0x04,0x00,0x84,0x12,0xF2, + /* 0xEDAE [?] [7158]*/ + 0x27,0x20,0xFA,0x21,0x77,0x6B,0xA5,0x29,0x25,0x22,0x01,0x08,0x48,0x48,0x87,0x00, + 0x88,0x88,0xBE,0x08,0xD8,0x5C,0x2A,0x48,0x08,0x08,0x00,0x84,0x92,0x12,0xF0,0x00, + /* 0xEDAF [?] [7159]*/ + 0x01,0x4F,0x21,0x27,0x80,0x47,0x54,0x14,0xE5,0x26,0x24,0x24,0x01,0x48,0x48,0x87, + 0x10,0xFE,0x10,0xFC,0xA0,0xFC,0xA4,0xA4,0x64,0x54,0x84,0x0C,0x00,0x84,0x12,0xF2, + /* 0xEDB0 [?] [7160]*/ + 0x10,0xFE,0x29,0xFE,0x01,0x7C,0x44,0x7D,0x44,0x7C,0x10,0xFE,0x11,0x48,0x48,0x87, + 0x40,0xF8,0x48,0x30,0xCE,0xF8,0x20,0xFC,0x88,0xA8,0xA8,0x50,0x88,0x84,0x12,0xF2, + /* 0xEDB1 [?] [7161]*/ + 0x01,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xEDB2 [?] [7162]*/ + 0x01,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01, + 0x00,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xEDB3 [?] [7163]*/ + 0x01,0x01,0x7D,0x05,0x09,0x31,0xC5,0x02,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x10, + 0x00,0x08,0x10,0xA0,0x60,0x18,0x06,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x10, + /* 0xEDB4 [?] [7164]*/ + 0x22,0x11,0x11,0x00,0x7F,0x40,0x80,0x01,0x01,0x7D,0x05,0x09,0x11,0x21,0xC5,0x02, + 0x08,0x08,0x10,0x20,0xFE,0x02,0x04,0x00,0x04,0x88,0x50,0x20,0x10,0x08,0x06,0x00, + /* 0xEDB5 [?] [7165]*/ + 0x01,0x01,0x7D,0x05,0x09,0x31,0xC5,0x02,0x08,0x0A,0x6A,0x2C,0x2A,0x4A,0xA9,0x10, + 0x00,0x08,0x10,0xA0,0x60,0x18,0x06,0x00,0x10,0x14,0xD4,0x58,0x54,0x94,0x52,0x20, + /* 0xEDB6 [?] [7166]*/ + 0x00,0x01,0xF9,0x21,0x21,0x41,0x79,0xC9,0x49,0x49,0x49,0x49,0x7A,0x42,0x04,0x08, + 0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0x12,0x0E,0x00, + /* 0xEDB7 [?] [7167]*/ + 0x00,0x01,0xFC,0x10,0x10,0x20,0x3C,0x67,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xEDB8 [?] [7168]*/ + 0x00,0x01,0xFC,0x10,0x10,0x20,0x3D,0x64,0x64,0xA4,0x25,0x25,0x3E,0x24,0x20,0x01, + 0x00,0xF8,0x10,0x20,0x40,0x80,0xFE,0x92,0x92,0x92,0x12,0x22,0x22,0x42,0x94,0x08, + /* 0xEDB9 [?] [7169]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x01,0x7F,0x01,0x7F,0x04,0x08,0x3F,0xC8,0x08,0x0F,0x08, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFC,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xEDBA [?] [7170]*/ + 0x00,0x00,0xFC,0x13,0x10,0x20,0x3D,0x65,0x64,0xA4,0x24,0x27,0x3C,0x24,0x20,0x00, + 0x40,0x40,0x40,0xFE,0x80,0xA0,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xEDBB [?] [7171]*/ + 0x00,0x00,0xFC,0x13,0x10,0x21,0x3D,0x65,0x65,0xA5,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x22,0x22,0x1E,0x00, + /* 0xEDBC [?] [7172]*/ + 0x00,0x03,0xF8,0x21,0x21,0x41,0x7A,0xCB,0x48,0x48,0x48,0x49,0x7A,0x44,0x00,0x00, + 0x00,0xFC,0x10,0x10,0x10,0x10,0x10,0xFE,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20, + /* 0xEDBD [?] [7173]*/ + 0x00,0x00,0xFC,0x10,0x10,0x20,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3D,0x25,0x22,0x04, + 0x08,0x1C,0xE0,0x80,0x80,0x80,0xFE,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08,0x08, + /* 0xEDBE [?] [7174]*/ + 0x00,0x00,0xFD,0x10,0x10,0x20,0x3D,0x64,0x64,0xA4,0x24,0x24,0x3C,0x25,0x22,0x00, + 0x04,0x1E,0xE0,0x00,0x20,0x10,0xFE,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x3E,0x00, + /* 0xEDBF [?] [7175]*/ + 0x00,0x03,0xFA,0x22,0x23,0x42,0x7A,0xCA,0x4A,0x4A,0x4A,0x4B,0x7C,0x44,0x08,0x10, + 0x00,0xF8,0x08,0x08,0x28,0xA8,0xA8,0x48,0x48,0xA8,0xA8,0x2A,0x0A,0x0A,0x06,0x02, + /* 0xEDC0 [?] [7176]*/ + 0x00,0x00,0xFC,0x11,0x10,0x20,0x3C,0x65,0x64,0xA4,0x24,0x24,0x3C,0x25,0x20,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00, + /* 0xEDC1 [?] [7177]*/ + 0x01,0x01,0xFB,0x21,0x21,0x40,0x7A,0xCA,0x49,0x49,0x48,0x48,0x78,0x41,0x02,0x0C, + 0x10,0x10,0xFC,0x10,0x10,0x00,0x08,0x08,0x10,0x10,0xA0,0x40,0xA0,0x10,0x08,0x06, + /* 0xEDC2 [?] [7178]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x22,0x02,0x04, + 0x00,0xFE,0x00,0x00,0x00,0xFE,0x20,0x20,0x3C,0x24,0x24,0x24,0x24,0x44,0x54,0x88, + /* 0xEDC3 [?] [7179]*/ + 0x04,0x04,0xFF,0x09,0x11,0x21,0x4F,0x80,0x00,0xFF,0x08,0x1F,0x28,0xC8,0x0F,0x08, + 0x40,0x20,0xFC,0x10,0x60,0x84,0x04,0xFC,0x00,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xEDC4 [?] [7180]*/ + 0x00,0x00,0xFC,0x10,0x11,0x21,0x3E,0x64,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xEDC5 [?] [7181]*/ + 0x00,0x00,0xFC,0x10,0x10,0x21,0x3E,0x64,0x65,0xA4,0x24,0x24,0x3C,0x24,0x23,0x00, + 0x20,0x20,0x50,0x50,0x88,0x04,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xEDC6 [?] [7182]*/ + 0x00,0x00,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x04,0x1E,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x08,0x0A,0x4A,0xA6,0x12, + /* 0xEDC7 [?] [7183]*/ + 0x00,0x00,0xFC,0x10,0x11,0x20,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3C,0x24,0x23,0x00, + 0x40,0x20,0x20,0x00,0xFE,0x00,0x04,0x84,0x84,0x48,0x48,0x48,0x50,0x10,0xFE,0x00, + /* 0xEDC8 [?] [7184]*/ + 0x00,0x00,0xFC,0x11,0x11,0x22,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xEDC9 [?] [7185]*/ + 0x00,0x00,0xF8,0x23,0x20,0x40,0x7B,0x4A,0xCA,0x4B,0x48,0x48,0x79,0x49,0x02,0x04, + 0x90,0x90,0x90,0xFC,0x94,0x94,0xFC,0x90,0x90,0xFE,0x92,0x92,0x1A,0x14,0x10,0x10, + /* 0xEDCA [?] [7186]*/ + 0x00,0x07,0xFA,0x22,0x22,0x42,0x7A,0x4F,0xCA,0x4A,0x4A,0x4A,0x7A,0x4C,0x04,0x08, + 0x02,0xE2,0x42,0x4A,0x4A,0x4A,0x4A,0xEA,0x4A,0x4A,0x4A,0x4A,0x42,0x42,0x4A,0x44, + /* 0xEDCB [?] [7187]*/ + 0x00,0x00,0xFD,0x10,0x10,0x20,0x3C,0x65,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x48,0x48,0xFE,0x48,0x48,0x20,0x10,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0xFC,0x00, + /* 0xEDCC [?] [7188]*/ + 0x00,0x00,0xFC,0x11,0x10,0x21,0x3C,0x64,0x64,0xA7,0x24,0x24,0x3C,0x24,0x21,0x02, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEDCD [?] [7189]*/ + 0x00,0x00,0xF8,0x23,0x20,0x40,0x78,0x4B,0xC8,0x4B,0x48,0x48,0x79,0x49,0x02,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xEDCE [?] [7190]*/ + 0x08,0x08,0x2E,0x28,0x28,0x2E,0xF0,0x00,0x7F,0x04,0x08,0x3F,0xC8,0x08,0x0F,0x08, + 0x80,0x88,0x90,0xE0,0x84,0x84,0x7C,0x00,0xFC,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xEDCF [?] [7191]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x00,0xFE,0x02,0x02,0x7A,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x7A,0x02,0x02,0x0A,0x04, + /* 0xEDD0 [?] [7192]*/ + 0x00,0x00,0xFC,0x11,0x11,0x21,0x3D,0x65,0x65,0xA5,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x20,0x20,0x40,0xFC,0x04,0x04,0x94,0x54,0x24,0x24,0x54,0x94,0x04,0x04,0xFC,0x04, + /* 0xEDD1 [?] [7193]*/ + 0x00,0x00,0xFC,0x10,0x11,0x20,0x3C,0x64,0x65,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xEDD2 [?] [7194]*/ + 0x00,0x00,0xFB,0x20,0x20,0x43,0x78,0x48,0xC8,0x48,0x4B,0x48,0x78,0x48,0x02,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x02, + /* 0xEDD3 [?] [7195]*/ + 0x00,0x00,0xFB,0x20,0x21,0x40,0x7B,0x48,0xC9,0x49,0x49,0x49,0x79,0x48,0x00,0x03, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xEDD4 [?] [7196]*/ + 0x00,0x00,0xFC,0x10,0x11,0x22,0x3C,0x64,0x64,0xA4,0x24,0x24,0x3C,0x24,0x20,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xEDD5 [?] [7197]*/ + 0x00,0x00,0xFD,0x10,0x11,0x20,0x3C,0x67,0x64,0xA4,0x25,0x25,0x3D,0x25,0x21,0x01, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEDD6 [?] [7198]*/ + 0x00,0x00,0xFB,0x22,0x24,0x40,0x7B,0x48,0xC8,0x49,0x49,0x49,0x7A,0x4A,0x04,0x08, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xFE,0x20,0x20,0x20,0x3C,0x20,0xA0,0x60,0x3E,0x00, + /* 0xEDD7 [?] [7199]*/ + 0x00,0x00,0xF9,0x23,0x20,0x47,0x79,0x4A,0xCC,0x4B,0x48,0x48,0x7B,0x48,0x00,0x07, + 0x80,0x90,0x08,0xFC,0x40,0xFE,0x10,0x48,0x86,0x10,0x20,0xC4,0x08,0x30,0xC0,0x00, + /* 0xEDD8 [?] [7200]*/ + 0x00,0x01,0xFC,0x10,0x10,0x21,0x3C,0x64,0x64,0xA4,0x25,0x24,0x3D,0x25,0x20,0x00, + 0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0xA4,0x94,0xFE,0xA4,0x14,0xFE,0x04,0x18, + /* 0xEDD9 [?] [7201]*/ + 0x00,0x01,0xFD,0x11,0x11,0x21,0x3C,0x65,0x66,0xA5,0x25,0x25,0x3D,0x24,0x20,0x00, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFE,0x22,0x22,0x52,0x02,0xFA,0x02,0x14,0x08, + /* 0xEDDA [?] [7202]*/ + 0x00,0x00,0xF9,0x20,0x20,0x40,0x7B,0x4A,0xCC,0x49,0x49,0x49,0x79,0x49,0x00,0x00, + 0x40,0x20,0xFC,0x00,0x88,0x50,0xFE,0x22,0x24,0xFC,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xEDDB [?] [7203]*/ + 0x00,0x00,0xFB,0x22,0x24,0x41,0x78,0x49,0xC9,0x49,0x49,0x49,0x79,0x48,0x03,0x00, + 0x40,0x20,0xFE,0x02,0x04,0xFC,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x00,0xFE,0x00, + /* 0xEDDC [?] [7204]*/ + 0x00,0x00,0xFB,0x22,0x22,0x43,0x7A,0xCA,0x4B,0x4B,0x4B,0x4D,0x7D,0x45,0x09,0x01, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x54,0x54,0xFC,0x54,0x54,0x44,0x0C, + /* 0xEDDD [?] [7205]*/ + 0x02,0x02,0xF3,0x24,0x2A,0x41,0x72,0xD4,0x58,0x57,0x50,0x51,0x72,0x5C,0x00,0x00, + 0x08,0x08,0xBE,0x88,0xA8,0x3E,0x08,0x48,0x48,0xFC,0xE0,0x50,0x48,0x46,0x40,0x40, + /* 0xEDDE [?] [7206]*/ + 0x00,0x00,0xFB,0x20,0x21,0x42,0x78,0x49,0xC8,0x48,0x48,0x49,0x7A,0x4C,0x00,0x00, + 0x40,0x20,0xFE,0x88,0x24,0x42,0x90,0xF8,0x08,0x44,0xA8,0x90,0x88,0xA4,0xC2,0x80, + /* 0xEDDF [?] [7207]*/ + 0x03,0x01,0xF0,0x23,0x20,0x47,0x74,0xD3,0x54,0x50,0x57,0x50,0x71,0x52,0x0C,0x00, + 0xF0,0x10,0xE0,0x18,0x00,0xBC,0xA4,0x18,0xA4,0x40,0xFC,0xE0,0x50,0x48,0x46,0x40, + /* 0xEDE0 [?] [7208]*/ + 0x08,0x7F,0x08,0x3E,0x00,0x3E,0x2A,0x3E,0x40,0xFF,0x08,0x1F,0x28,0xC8,0x0F,0x08, + 0x00,0x78,0x48,0x48,0x86,0x78,0x48,0x30,0x48,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xEDE1 [?] [7209]*/ + 0x02,0x01,0xF8,0x24,0x22,0x40,0x79,0x4E,0xCA,0x48,0x4B,0x48,0x78,0x49,0x02,0x00, + 0x00,0x7E,0x40,0x7C,0x44,0xFC,0x40,0x7E,0x20,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xEDE2 [?] [7210]*/ + 0x02,0x01,0xF7,0x20,0x27,0x44,0x77,0xD0,0x57,0x50,0x51,0x51,0x77,0x51,0x05,0x02, + 0x08,0x08,0xC8,0x10,0x9E,0x94,0xA4,0x14,0x94,0x94,0x14,0xC8,0x08,0x14,0x24,0x42, + /* 0xEDE3 [?] [7211]*/ + 0x00,0x07,0xF0,0x22,0x21,0x42,0x75,0xD8,0x53,0x52,0x52,0x53,0x72,0x51,0x0F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xEDE4 [?] [7212]*/ + 0x00,0x03,0xFC,0x11,0x11,0x21,0x3D,0x67,0x64,0xA5,0x25,0x25,0x3D,0x25,0x20,0x03, + 0x00,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE, + /* 0xEDE5 [?] [7213]*/ + 0x00,0x00,0xFB,0x20,0x21,0x41,0x7A,0x4D,0xCA,0x49,0x4A,0x49,0x78,0x49,0x02,0x00, + 0x88,0x88,0xFE,0x88,0x10,0xDE,0x52,0x54,0x88,0x74,0x02,0xFC,0x20,0x24,0x22,0x60, + /* 0xEDE6 [?] [7214]*/ + 0x00,0x03,0xF8,0x23,0x22,0x41,0x78,0x4B,0xC8,0x48,0x4B,0x48,0x7B,0x48,0x03,0x00, + 0x88,0xFE,0x88,0xFE,0x02,0xFC,0x00,0xFE,0x40,0xA2,0x54,0xB8,0x54,0x92,0x50,0x20, + /* 0xEDE7 [?] [7215]*/ + 0x00,0x03,0xF0,0x24,0x22,0x40,0x74,0xD2,0x52,0x50,0x51,0x52,0x76,0x52,0x02,0x02, + 0x88,0xFE,0x88,0x12,0xFE,0x10,0xFE,0x92,0xFE,0x92,0xFE,0x92,0x04,0xFE,0x44,0x2C, + /* 0xEDE8 [?] [7216]*/ + 0x01,0x06,0x18,0xEF,0x00,0x1F,0x10,0x1F,0x04,0x04,0xFF,0x09,0x11,0x21,0x4F,0x80, + 0x00,0xC0,0x30,0xEE,0x00,0xF0,0x10,0xF0,0x40,0x20,0xFE,0x10,0x60,0x84,0x04,0xFC, + /* 0xEDE9 [?] [7217]*/ + 0x04,0x24,0x14,0x04,0xFF,0x01,0x11,0x09,0x3F,0x21,0x25,0x25,0x29,0x21,0x21,0x21, + 0x40,0x48,0x50,0x40,0xFE,0x00,0x10,0x20,0xF8,0x08,0x48,0x28,0x28,0x08,0x28,0x10, + /* 0xEDEA [?] [7218]*/ + 0x14,0x55,0x36,0x14,0xFF,0x49,0x2A,0x7F,0x49,0x49,0x5D,0x6B,0x49,0x49,0x49,0x4B, + 0x28,0x24,0x24,0x20,0x7E,0x20,0x20,0x3C,0x34,0x54,0x54,0x54,0x88,0x88,0x14,0x22, + /* 0xEDEB [?] [7219]*/ + 0x14,0x55,0x36,0x14,0xFF,0x49,0x2A,0x7F,0x49,0x49,0x5D,0x6B,0x49,0x49,0x49,0x4B, + 0x14,0x12,0x7E,0x10,0x10,0x7E,0x52,0x52,0x7E,0x52,0x52,0x7E,0x52,0x52,0x52,0x46, + /* 0xEDEC [?] [7220]*/ + 0x00,0x01,0x7C,0x44,0x44,0x7C,0x44,0x47,0x7C,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + 0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xEDED [?] [7221]*/ + 0x00,0x03,0x7C,0x44,0x45,0x7D,0x45,0x45,0x7D,0x45,0x44,0x44,0x7C,0x44,0x00,0x00, + 0x00,0xFE,0x20,0x20,0x20,0x3E,0x22,0x22,0x22,0xFE,0x02,0x02,0x02,0x02,0x14,0x08, + /* 0xEDEE [?] [7222]*/ + 0x00,0x01,0x7D,0x45,0x45,0x7D,0x45,0x45,0x7D,0x45,0x45,0x45,0x7D,0x45,0x01,0x00, + 0x00,0xFE,0x00,0x04,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x00,0xFE,0x00, + /* 0xEDEF [?] [7223]*/ + 0x00,0x00,0x78,0x4B,0x48,0x79,0x49,0x49,0x79,0x49,0x48,0x48,0x78,0x48,0x00,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x22,0x22,0x1E,0x00, + /* 0xEDF0 [?] [7224]*/ + 0x00,0x00,0x78,0x49,0x49,0x7A,0x4A,0x4C,0x78,0x48,0x48,0x48,0x78,0x48,0x01,0x06, + 0x40,0x40,0x40,0x48,0x44,0x42,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0x40,0x80,0x00, + /* 0xEDF1 [?] [7225]*/ + 0x00,0x00,0x78,0x4B,0x4A,0x7C,0x48,0x48,0x78,0x48,0x48,0x49,0x79,0x4A,0x04,0x08, + 0x40,0x40,0x40,0xFC,0x44,0x48,0x40,0x40,0xA0,0xA0,0xA0,0x20,0x22,0x22,0x1E,0x00, + /* 0xEDF2 [?] [7226]*/ + 0x01,0x11,0x1F,0x21,0x5F,0x01,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0x00,0xF8,0x00,0xF0,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xEDF3 [?] [7227]*/ + 0x10,0x1E,0x22,0x62,0x94,0x08,0x30,0xC0,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0xF8,0x88,0xA8,0x92,0x82,0x7E,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xEDF4 [?] [7228]*/ + 0x00,0x00,0x7C,0x44,0x44,0x7C,0x45,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x00,0x00, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xEDF5 [?] [7229]*/ + 0x00,0x00,0x7D,0x44,0x44,0x7C,0x47,0x44,0x7C,0x44,0x45,0x44,0x7C,0x44,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xEDF6 [?] [7230]*/ + 0x00,0x00,0x78,0x4A,0x4A,0x7A,0x4A,0x4A,0x7A,0x4A,0x4A,0x4A,0x7A,0x4F,0x02,0x00, + 0x90,0x90,0x90,0x90,0x92,0xD4,0x98,0x90,0x90,0x90,0x90,0x92,0xD2,0x12,0x0E,0x00, + /* 0xEDF7 [?] [7231]*/ + 0x00,0x00,0x7C,0x44,0x45,0x7C,0x44,0x44,0x7D,0x44,0x44,0x45,0x7C,0x44,0x00,0x01, + 0x20,0x20,0x7C,0x84,0x48,0x30,0x20,0x48,0x90,0x3E,0x42,0xA4,0x18,0x10,0x60,0x80, + /* 0xEDF8 [?] [7232]*/ + 0x00,0x00,0x78,0x49,0x4B,0x78,0x49,0x49,0x79,0x4A,0x48,0x4F,0x78,0x48,0x00,0x00, + 0x40,0x40,0x90,0x08,0xFC,0x24,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xEDF9 [?] [7233]*/ + 0x00,0x00,0x78,0x4B,0x48,0x79,0x48,0x48,0x7B,0x48,0x48,0x48,0x79,0x4A,0x04,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x24,0xA4,0xA8,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20, + /* 0xEDFA [?] [7234]*/ + 0x00,0x00,0x78,0x48,0x49,0x7A,0x4D,0x48,0x78,0x48,0x4A,0x49,0x79,0x48,0x07,0x00, + 0x40,0x40,0xA0,0xA0,0x10,0x08,0xF6,0x00,0x88,0x48,0x48,0x50,0x10,0x20,0xFE,0x00, + /* 0xEDFB [?] [7235]*/ + 0x01,0x00,0x78,0x4B,0x48,0x78,0x4B,0x4A,0x7A,0x4B,0x48,0x48,0x79,0x4A,0x04,0x00, + 0x08,0x88,0x90,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x62,0xA2,0x2A,0x24,0x20,0x20, + /* 0xEDFC [?] [7236]*/ + 0x00,0x00,0x78,0x49,0x4B,0x78,0x48,0x49,0x7A,0x48,0x49,0x4A,0x78,0x48,0x01,0x06, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xEDFD [?] [7237]*/ + 0x00,0x03,0x7A,0x4A,0x4A,0x7A,0x4A,0x4B,0x7A,0x4A,0x4A,0x4A,0x7A,0x4C,0x05,0x08, + 0x00,0xFE,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00,0x10,0x10,0xFE,0x10,0x10,0xFE,0x00, + /* 0xEDFE [?] [7238]*/ + 0x00,0x00,0x7B,0x4A,0x4A,0x7B,0x4A,0x4A,0x7B,0x48,0x48,0x48,0x78,0x49,0x02,0x04, + 0x00,0x40,0x9C,0x04,0x04,0x9C,0x04,0x04,0xFC,0x90,0x90,0x90,0x90,0x12,0x12,0x0E, + /* 0xEEA1 [?] [7239]*/ + 0x00,0x00,0x78,0x49,0x49,0x7B,0x4D,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x01,0x01, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xEEA2 [?] [7240]*/ + 0x00,0x00,0x7B,0x4A,0x4A,0x7B,0x4A,0x4A,0x7B,0x48,0x49,0x4F,0x78,0x48,0x00,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xEEA3 [?] [7241]*/ + 0x01,0x01,0x01,0x7F,0x40,0x9F,0x09,0x32,0x0C,0x3F,0xD0,0x1F,0x10,0x1F,0x10,0x1F, + 0x00,0xF8,0x00,0xFE,0x02,0xF4,0x20,0x90,0x60,0xF8,0x16,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xEEA4 [?] [7242]*/ + 0x01,0x06,0xF4,0x94,0x97,0xF4,0x94,0x97,0xF0,0x97,0x92,0x91,0xF0,0x90,0x01,0x0E, + 0x40,0x5C,0x44,0x44,0x5C,0x44,0x44,0xFC,0x40,0xFC,0x08,0x10,0xA0,0x40,0xB0,0x0E, + /* 0xEEA5 [?] [7243]*/ + 0x00,0x03,0x78,0x4A,0x49,0x78,0x49,0x4A,0x78,0x48,0x4B,0x48,0x78,0x48,0x01,0x02, + 0x10,0xD4,0x58,0x52,0x8C,0x88,0x04,0xFA,0x20,0x20,0xFE,0x20,0x50,0x88,0x04,0x02, + /* 0xEEA6 [?] [7244]*/ + 0x7E,0x24,0x18,0xFF,0x29,0x4A,0x98,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x20,0x3E,0x48,0xA8,0x10,0x28,0x46,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xEEA7 [?] [7245]*/ + 0x00,0x00,0x79,0x48,0x48,0x7B,0x48,0x49,0x7B,0x48,0x4B,0x4A,0x7A,0x4A,0x07,0x00, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x80,0x04,0xFE,0x02,0xFC,0x94,0x94,0x94,0xFE,0x00, + /* 0xEEA8 [?] [7246]*/ + 0x00,0x03,0x7A,0x48,0x49,0x79,0x49,0x49,0x79,0x48,0x48,0x4B,0x78,0x48,0x01,0x02, + 0x00,0xFE,0x02,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xFE,0x00,0x88,0x04,0x02, + /* 0xEEA9 [?] [7247]*/ + 0x00,0x03,0x78,0x49,0x49,0x79,0x49,0x48,0x79,0x48,0x4B,0x48,0x78,0x49,0x02,0x00, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xEEAA [?] [7248]*/ + 0x00,0x01,0x78,0x4B,0x4A,0x78,0x48,0x48,0x78,0x48,0x48,0x49,0x78,0x48,0x03,0x00, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEEAB [?] [7249]*/ + 0x00,0x07,0xF0,0x91,0x9F,0xF4,0x94,0x97,0xF4,0x97,0x94,0x94,0xF7,0x9C,0x00,0x00, + 0x08,0x88,0x88,0x10,0xDE,0x94,0xA4,0x94,0x94,0x94,0x94,0xC8,0x88,0x94,0xA4,0xC2, + /* 0xEEAC [?] [7250]*/ + 0x00,0x02,0xF1,0x97,0x91,0xF2,0x94,0x92,0xF2,0x93,0x94,0x9A,0xF1,0x92,0x04,0x08, + 0x40,0x48,0x50,0xFC,0x50,0x48,0x44,0x08,0x08,0xBE,0x88,0xA8,0x3E,0x08,0x08,0x08, + /* 0xEEAD [?] [7251]*/ + 0x08,0xFF,0x08,0x7E,0x42,0x7E,0x24,0xFE,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F, + 0x10,0x7E,0x10,0x7C,0x44,0x28,0x18,0xE6,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xEEAE [?] [7252]*/ + 0x00,0x00,0x7D,0x54,0x54,0x54,0x54,0x7C,0x54,0x54,0x54,0x54,0x7C,0x44,0x00,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xEEAF [?] [7253]*/ + 0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00,0x00,0xFF,0x08,0x08,0x08,0x10,0x20, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xEEB0 [?] [7254]*/ + 0x00,0x00,0x7C,0x54,0x54,0x55,0x54,0x7C,0x54,0x54,0x54,0x54,0x7C,0x44,0x01,0x02, + 0x20,0x28,0x24,0x24,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEEB1 [?] [7255]*/ + 0x00,0x00,0x7C,0x54,0x54,0x55,0x56,0x7C,0x54,0x54,0x54,0x54,0x7C,0x44,0x01,0x02, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xEEB2 [?] [7256]*/ + 0x00,0x00,0x7D,0x55,0x55,0x55,0x55,0x7D,0x55,0x55,0x55,0x55,0x7D,0x46,0x02,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xEEB3 [?] [7257]*/ + 0x00,0x00,0x7C,0x54,0x55,0x56,0x54,0x7C,0x55,0x54,0x54,0x54,0x7D,0x44,0x00,0x03, + 0x20,0x20,0x50,0x88,0x04,0x12,0x20,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80, + /* 0xEEB4 [?] [7258]*/ + 0x01,0x02,0x0C,0x37,0xC0,0x3F,0x09,0x11,0x25,0x02,0x3F,0x21,0x3F,0x21,0x3F,0x20, + 0x00,0x80,0x60,0xD8,0x06,0xF8,0x20,0x10,0x08,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xEEB5 [?] [7259]*/ + 0x00,0x00,0xFB,0xAA,0xAD,0xA9,0xF9,0xAA,0xAA,0xAB,0xAC,0xF8,0x89,0x01,0x02,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xEEB6 [?] [7260]*/ + 0x00,0x01,0x7C,0x54,0x57,0x54,0x55,0x7D,0x55,0x55,0x55,0x54,0x7D,0x44,0x03,0x00, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xEEB7 [?] [7261]*/ + 0x00,0x3F,0x24,0x24,0x3F,0x00,0x00,0x7F,0x01,0x03,0x05,0x09,0x31,0xC1,0x01,0x01, + 0x00,0xF8,0x48,0x48,0xF8,0x00,0x00,0xFC,0x00,0x00,0x70,0x0C,0x02,0x00,0x00,0x00, + /* 0xEEB8 [?] [7262]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x00,0x00,0x7F,0x01,0x11,0x11,0x11,0x11,0x11,0xFF,0x00, + 0x00,0xFC,0x44,0x44,0xFC,0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE,0x00, + /* 0xEEB9 [?] [7263]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x01,0x01,0xFF,0x01,0x01,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x00,0xFC,0x44,0x44,0xFC,0x00,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xEEBA [?] [7264]*/ + 0x00,0x3F,0x24,0x24,0x3F,0x01,0xFF,0x00,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x3F,0x20, + 0x00,0xF8,0x48,0x48,0xF8,0x00,0xFE,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x08, + /* 0xEEBB [?] [7265]*/ + 0x3F,0x24,0x24,0x3F,0x02,0x7F,0x04,0x09,0x3F,0xD1,0x1F,0x11,0x1F,0x01,0x01,0x00, + 0xF8,0x48,0x48,0xF8,0x00,0xFC,0x40,0x20,0xF8,0x16,0xF0,0x10,0xF4,0x04,0x04,0xFC, + /* 0xEEBC [?] [7266]*/ + 0x3F,0x24,0x24,0x3F,0x01,0x01,0x3F,0x01,0xFF,0x04,0x08,0x1F,0x00,0x48,0x44,0x84, + 0xF8,0x48,0x48,0xF8,0x00,0x00,0xF8,0x00,0xFE,0x00,0x20,0xF0,0x10,0x88,0x44,0x44, + /* 0xEEBD [?] [7267]*/ + 0x7F,0x44,0x44,0x7F,0x01,0xFF,0x01,0x3F,0x24,0x22,0x2F,0x21,0x3F,0x21,0x21,0x20, + 0xFC,0x44,0x44,0xFC,0x00,0xFE,0x00,0xF8,0x48,0x88,0xE8,0x08,0xF8,0x08,0x28,0x10, + /* 0xEEBE [?] [7268]*/ + 0x00,0x7F,0x44,0x44,0x7F,0x10,0x10,0x19,0x55,0x53,0x95,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x44,0x44,0xFC,0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEEBF [?] [7269]*/ + 0x00,0x7F,0x44,0x7F,0x22,0x7F,0x22,0x3E,0x08,0x7F,0x49,0x7F,0x08,0xFF,0x08,0x08, + 0x00,0xFC,0x44,0xFC,0x00,0x78,0x08,0x48,0x48,0x7C,0x04,0x04,0xF4,0x04,0x14,0x08, + /* 0xEEC0 [?] [7270]*/ + 0x3F,0x24,0x24,0x3F,0x08,0x04,0x3F,0x29,0x25,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F, + 0xF8,0x48,0x48,0xF8,0x20,0x40,0xF8,0x28,0x48,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0, + /* 0xEEC1 [?] [7271]*/ + 0x01,0x01,0x3F,0x01,0x01,0xFF,0x04,0x08,0x1F,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,0x20,0xF0,0x10,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xEEC2 [?] [7272]*/ + 0x11,0x61,0x4D,0x45,0x75,0x49,0x49,0x75,0x42,0x00,0x3F,0x24,0x24,0x24,0xFF,0x00, + 0x00,0x1C,0x44,0x44,0x9C,0x84,0x44,0x5C,0x04,0x00,0xF8,0x48,0x48,0x48,0xFE,0x00, + /* 0xEEC3 [?] [7273]*/ + 0x44,0x24,0x28,0x00,0xFE,0x00,0x28,0x45,0x82,0x00,0xFE,0xAA,0xAA,0xAA,0xAF,0xF8, + 0x00,0xFE,0xAA,0xAA,0xFE,0x40,0xFE,0x22,0xFA,0xAA,0xAA,0xFA,0x22,0xFA,0x0A,0x04, + /* 0xEEC4 [?] [7274]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xEEC5 [?] [7275]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x84,0x7C,0x00, + /* 0xEEC6 [?] [7276]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x11,0x11,0x15,0x19,0x10,0x00, + 0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x40,0x80,0x80,0x00,0x04,0x04,0x04,0xFC,0x00, + /* 0xEEC7 [?] [7277]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40, + /* 0xEEC8 [?] [7278]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x04,0x04,0x04,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x04,0x04,0x04,0x14,0x08, + /* 0xEEC9 [?] [7279]*/ + 0x10,0x11,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x00, + 0x00,0xFC,0x04,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xEECA [?] [7280]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x11,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x13,0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xEECB [?] [7281]*/ + 0x11,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x04,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x04,0x04, + /* 0xEECC [?] [7282]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x10,0x03, + 0x08,0x08,0x10,0x20,0x40,0x88,0x08,0x10,0x20,0x44,0x84,0x08,0x10,0x20,0xC0,0x00, + /* 0xEECD [?] [7283]*/ + 0x10,0x10,0x3C,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x80,0x40,0x5E,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x0A,0x04, + /* 0xEECE [?] [7284]*/ + 0x10,0x13,0x3D,0x21,0x41,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x11,0x06, + 0x00,0xFC,0x04,0x44,0x24,0xA8,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xEECF [?] [7285]*/ + 0x10,0x10,0x3C,0x20,0x43,0xBC,0x10,0x10,0xFC,0x11,0x10,0x10,0x14,0x18,0x10,0x03, + 0x40,0x40,0x40,0x40,0xFE,0x88,0x88,0x88,0x88,0x08,0x90,0x50,0x20,0x50,0x88,0x04, + /* 0xEED0 [?] [7286]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x10,0xFC,0x11,0x12,0x10,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x20,0x20,0x68,0xA4,0x22,0x22,0x20,0x20,0x20,0x20,0x20, + /* 0xEED1 [?] [7287]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7D,0x90,0x10,0xFE,0x10,0x10,0x12,0x14,0x18,0x11,0x02, + 0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0xC8,0x24,0x02, + /* 0xEED2 [?] [7288]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x00, + 0x00,0xFE,0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,0xFE,0x00, + /* 0xEED3 [?] [7289]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x08,0x1C,0xE0,0x00,0x00,0xFC,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x44,0x82, + /* 0xEED4 [?] [7290]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBD,0x12,0x10,0xFC,0x11,0x10,0x10,0x14,0x18,0x10,0x00, + 0x20,0x20,0x50,0x50,0x88,0x44,0x22,0x20,0x00,0xFC,0x04,0x08,0x08,0x10,0x10,0x20, + /* 0xEED5 [?] [7291]*/ + 0x10,0x10,0x3C,0x23,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x40,0x20,0x20,0xFE,0x80,0x80,0x80,0xFC,0x84,0x84,0x84,0x84,0x04,0x04,0x28,0x10, + /* 0xEED6 [?] [7292]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x19,0x11,0x02, + 0x40,0x20,0x00,0xFC,0x00,0x00,0xF0,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xEED7 [?] [7293]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBD,0x10,0x10,0xFC,0x10,0x13,0x10,0x14,0x18,0x10,0x00, + 0x10,0x10,0x90,0x90,0x10,0x10,0x90,0x90,0x10,0x1E,0xF0,0x10,0x10,0x10,0x10,0x10, + /* 0xEED8 [?] [7294]*/ + 0x10,0x10,0x1E,0x20,0x20,0x7C,0x90,0x11,0xFE,0x10,0x10,0x12,0x14,0x18,0x11,0x02, + 0x20,0x20,0x20,0x24,0xA4,0xA4,0xA8,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEED9 [?] [7295]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xEEDA [?] [7296]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x10,0xFD,0x10,0x10,0x10,0x14,0x18,0x13,0x00, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x28,0x24,0x24,0x20,0xFE,0x00, + /* 0xEEDB [?] [7297]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x13,0x00, + 0x00,0x00,0xFE,0x10,0x10,0x10,0x90,0x90,0x9E,0x90,0x90,0x90,0x90,0x90,0xFE,0x00, + /* 0xEEDC [?] [7298]*/ + 0x10,0x10,0x3C,0x20,0x43,0xBC,0x10,0x10,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xEEDD [?] [7299]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x14,0x18,0x10,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xEEDE [?] [7300]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x00, + 0x00,0xFE,0x00,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x7C,0x44,0x00,0x00,0xFE,0x00, + /* 0xEEDF [?] [7301]*/ + 0x20,0x20,0x38,0x23,0x40,0x78,0xA1,0x21,0xFB,0x25,0x21,0x21,0x29,0x31,0x20,0x00, + 0x40,0x40,0x40,0xFE,0x80,0xA0,0x20,0xFC,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xEEE0 [?] [7302]*/ + 0x10,0x10,0x3C,0x20,0x43,0xBC,0x10,0x10,0xFD,0x11,0x11,0x11,0x16,0x1A,0x14,0x01, + 0x50,0x48,0x48,0x40,0xFE,0x80,0x80,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xEEE1 [?] [7303]*/ + 0x20,0x20,0x38,0x20,0x43,0x7A,0xA2,0x22,0xFA,0x22,0x22,0x22,0x2B,0x32,0x20,0x00, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x24,0x24,0x24,0x28,0x28,0x90,0x12,0x2A,0x46,0x82, + /* 0xEEE2 [?] [7304]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xEEE3 [?] [7305]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x14,0x18,0x13,0x00, + 0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x00,0x00,0xFE,0x00, + /* 0xEEE4 [?] [7306]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xEEE5 [?] [7307]*/ + 0x20,0x20,0x3B,0x22,0x42,0x7A,0xA2,0x23,0xF8,0x20,0x21,0x21,0x2A,0x34,0x20,0x00, + 0x08,0x3C,0xC0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xEEE6 [?] [7308]*/ + 0x10,0x10,0x3C,0x23,0x40,0xBC,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x40,0x20,0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20, + /* 0xEEE7 [?] [7309]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBC,0x10,0x10,0xFD,0x10,0x10,0x10,0x14,0x19,0x10,0x00, + 0x20,0x10,0x10,0xFE,0x20,0x20,0x44,0x84,0xF8,0x10,0x20,0x44,0x82,0xFE,0x82,0x00, + /* 0xEEE8 [?] [7310]*/ + 0x10,0x10,0x3C,0x21,0x41,0xBE,0x10,0x10,0xFC,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xEEE9 [?] [7311]*/ + 0x10,0x10,0x3C,0x20,0x40,0xBC,0x10,0x11,0xFD,0x11,0x12,0x10,0x14,0x19,0x12,0x00, + 0x40,0x20,0x28,0x08,0x08,0x48,0x54,0x52,0x52,0x60,0x60,0x44,0xC4,0x44,0x3C,0x00, + /* 0xEEEA [?] [7312]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x40,0x44,0x48,0x70,0x40,0x42,0x42,0x3E,0x00, + /* 0xEEEB [?] [7313]*/ + 0x10,0x10,0x3C,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x1A,0x12,0x04, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xEEEC [?] [7314]*/ + 0x10,0x13,0x3D,0x20,0x40,0xBC,0x10,0x13,0xFC,0x11,0x10,0x10,0x17,0x18,0x10,0x00, + 0x00,0xFC,0x04,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xEEED [?] [7315]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBD,0x10,0x10,0xFD,0x12,0x14,0x10,0x14,0x18,0x10,0x00, + 0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0xFE,0x40,0x80,0xFC,0x04,0x04,0x28,0x10, + /* 0xEEEE [?] [7316]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBC,0x13,0x10,0xFC,0x11,0x12,0x10,0x14,0x18,0x10,0x00, + 0x40,0x40,0x44,0xF4,0x48,0x50,0xFE,0x40,0x80,0x84,0x98,0xE0,0x82,0x82,0x7E,0x00, + /* 0xEEEF [?] [7317]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBC,0x10,0x10,0xFC,0x10,0x10,0x10,0x15,0x18,0x10,0x00, + 0x00,0xFE,0x88,0x88,0x88,0xF8,0x88,0x88,0xF8,0x88,0x88,0x9E,0xE8,0x08,0x08,0x08, + /* 0xEEF0 [?] [7318]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBC,0x10,0x11,0xFE,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x20,0x20,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0x94,0x88, + /* 0xEEF1 [?] [7319]*/ + 0x20,0x20,0x38,0x20,0x43,0x7A,0xA2,0x22,0xFB,0x22,0x22,0x22,0x2A,0x35,0x24,0x08, + 0x28,0x24,0x24,0x20,0xFE,0x20,0x24,0x24,0xA4,0xA8,0xA8,0x90,0x92,0xAA,0x46,0x82, + /* 0xEEF2 [?] [7320]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBD,0x10,0x10,0xFC,0x13,0x10,0x10,0x14,0x18,0x11,0x02, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xEEF3 [?] [7321]*/ + 0x20,0x20,0x38,0x23,0x40,0x78,0xA0,0x23,0xF8,0x23,0x20,0x20,0x29,0x31,0x22,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xEEF4 [?] [7322]*/ + 0x20,0x27,0x38,0x44,0x44,0x7C,0xA7,0x20,0xF9,0x21,0x22,0x2A,0x34,0x28,0x02,0x01, + 0x00,0xDE,0x92,0x92,0x94,0x94,0xD8,0x94,0x92,0x92,0x92,0x9A,0x94,0x90,0x90,0x10, + /* 0xEEF5 [?] [7323]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBC,0x13,0x10,0xFC,0x10,0x11,0x10,0x14,0x18,0x13,0x00, + 0x20,0x24,0xA4,0xA4,0xA8,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEEF6 [?] [7324]*/ + 0x20,0x21,0x39,0x21,0x41,0x78,0xA0,0x23,0xFA,0x22,0x22,0x22,0x2A,0x32,0x20,0x00, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x2A,0x24,0x20,0x20, + /* 0xEEF7 [?] [7325]*/ + 0x20,0x23,0x3A,0x22,0x42,0x7A,0xA3,0x22,0xFA,0x22,0x22,0x22,0x2B,0x32,0x23,0x02, + 0x00,0xFE,0x02,0x22,0x22,0x22,0xFE,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0xFE,0x02, + /* 0xEEF8 [?] [7326]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBC,0x11,0x10,0xFC,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xEEF9 [?] [7327]*/ + 0x20,0x21,0x39,0x21,0x41,0x7A,0xA0,0x23,0xF8,0x20,0x20,0x21,0x29,0x32,0x20,0x00, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xEEFA [?] [7328]*/ + 0x20,0x20,0x3B,0x20,0x40,0x79,0xA1,0x23,0xF8,0x22,0x22,0x21,0x29,0x32,0x24,0x08, + 0x00,0x06,0xB8,0x88,0x88,0x08,0x3E,0x88,0x88,0x88,0x88,0x3E,0x00,0x80,0x7E,0x00, + /* 0xEEFB [?] [7329]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBD,0x10,0x10,0xFC,0x13,0x10,0x10,0x14,0x19,0x13,0x01, + 0x08,0x3C,0xE0,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x40,0x88,0x04,0xFE,0x02, + /* 0xEEFC [?] [7330]*/ + 0x10,0x10,0x3D,0x21,0x43,0xBD,0x11,0x11,0xFD,0x10,0x13,0x10,0x14,0x18,0x10,0x00, + 0x90,0x94,0x14,0x18,0x10,0x32,0x52,0x0E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xEEFD [?] [7331]*/ + 0x20,0x20,0x38,0x21,0x42,0x7C,0xA3,0x20,0xF8,0x20,0x23,0x20,0x28,0x30,0x27,0x00, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x40,0x40,0x40,0xF8,0x40,0x40,0x40,0xFE,0x00, + /* 0xEEFE [?] [7332]*/ + 0x20,0x20,0x38,0x21,0x42,0x7C,0xA3,0x20,0xF8,0x23,0x22,0x22,0x2A,0x32,0x23,0x02, + 0x40,0x40,0xA0,0x10,0x08,0x06,0xF8,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xEFA1 [?] [7333]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBC,0x11,0x10,0xFF,0x10,0x10,0x10,0x15,0x1A,0x10,0x00, + 0x04,0x88,0x50,0x20,0x50,0x88,0x24,0x20,0xFE,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xEFA2 [?] [7334]*/ + 0x10,0x10,0x3C,0x21,0x40,0xBC,0x10,0x10,0xFC,0x11,0x12,0x10,0x14,0x18,0x11,0x02, + 0x50,0x50,0x50,0x52,0xD4,0x58,0x50,0x58,0xD4,0x52,0x50,0x50,0x92,0x92,0x12,0x0E, + /* 0xEFA3 [?] [7335]*/ + 0x20,0x20,0x39,0x22,0x40,0x7B,0xA0,0x20,0xFB,0x20,0x20,0x23,0x28,0x30,0x20,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0xFE,0x24,0x24,0xFC,0x24,0x20,0xA0,0x40, + /* 0xEFA4 [?] [7336]*/ + 0x10,0x10,0x3C,0x21,0x42,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x10,0x00, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xEFA5 [?] [7337]*/ + 0x10,0x10,0x3C,0x23,0x40,0xBC,0x11,0x13,0xFC,0x10,0x10,0x10,0x15,0x19,0x12,0x04, + 0x40,0x20,0x20,0xFE,0x40,0x88,0x04,0xFE,0x92,0x90,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xEFA6 [?] [7338]*/ + 0x22,0x21,0x39,0x24,0x42,0x7A,0xA0,0x21,0xF9,0x22,0x26,0x22,0x2A,0x33,0x22,0x00, + 0x00,0x7C,0x04,0x08,0x10,0x20,0x7E,0x2A,0x2A,0x2A,0x4A,0x52,0x92,0x22,0x4A,0x84, + /* 0xEFA7 [?] [7339]*/ + 0x20,0x20,0x38,0x23,0x42,0x7C,0xA0,0x23,0xF8,0x20,0x21,0x20,0x28,0x30,0x20,0x03, + 0x40,0x20,0x20,0xFE,0x02,0x44,0x40,0xFE,0x88,0x88,0x08,0xD0,0x20,0x50,0x88,0x04, + /* 0xEFA8 [?] [7340]*/ + 0x21,0x21,0x39,0x21,0x47,0x7A,0xA2,0x22,0xFA,0x24,0x22,0x21,0x2A,0x32,0x24,0x08, + 0x00,0x00,0x00,0x1E,0xD2,0x52,0x52,0x52,0x52,0x92,0x92,0x12,0x92,0x5E,0x52,0x00, + /* 0xEFA9 [?] [7341]*/ + 0x20,0x20,0x3B,0x20,0x40,0x7B,0xA2,0x24,0xF8,0x23,0x20,0x20,0x28,0x31,0x22,0x04, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x44,0x40,0xFC,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xEFAA [?] [7342]*/ + 0x20,0x20,0x38,0x23,0x40,0x79,0xA0,0x20,0xFB,0x20,0x20,0x20,0x29,0x32,0x24,0x00, + 0x20,0x20,0x20,0xFE,0x20,0x24,0xA4,0xA8,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20,0x20, + /* 0xEFAB [?] [7343]*/ + 0x20,0x20,0x38,0x20,0x43,0x78,0xA0,0x20,0xF8,0x20,0x20,0x22,0x2A,0x32,0x24,0x00, + 0x10,0x14,0x12,0x10,0xFE,0x10,0x90,0x50,0x48,0x08,0x88,0xA8,0x9A,0xAA,0x66,0x02, + /* 0xEFAC [?] [7344]*/ + 0x20,0x22,0x3A,0x22,0x42,0x7A,0xA2,0x20,0xF8,0x20,0x21,0x20,0x28,0x30,0x23,0x00, + 0x80,0xFC,0xA4,0xA4,0xA8,0x90,0xA8,0xC6,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xEFAD [?] [7345]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x10,0x10,0xFD,0x10,0x10,0x11,0x14,0x18,0x13,0x00, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEFAE [?] [7346]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFC,0x10,0x11,0x10,0x14,0x18,0x13,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xEFAF [?] [7347]*/ + 0x20,0x21,0x39,0x21,0x41,0x7A,0xA0,0x23,0xF8,0x20,0x21,0x21,0x29,0x31,0x21,0x01, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEFB0 [?] [7348]*/ + 0x20,0x20,0x3B,0x20,0x40,0x7B,0xA0,0x20,0xF8,0x20,0x23,0x20,0x28,0x30,0x22,0x01, + 0x10,0xD8,0x94,0x94,0x90,0xFE,0x90,0x94,0x94,0xD8,0x98,0x90,0xAA,0xCA,0x86,0x02, + /* 0xEFB1 [?] [7349]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x12,0x14,0xFC,0x10,0x11,0x10,0x14,0x18,0x13,0x00, + 0x20,0x20,0x24,0x24,0x24,0x24,0xAA,0x72,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xEFB2 [?] [7350]*/ + 0x10,0x10,0x3D,0x20,0x41,0xBC,0x10,0x10,0xFD,0x10,0x10,0x10,0x14,0x18,0x10,0x00, + 0x04,0x1E,0xE0,0x22,0x12,0x94,0x80,0x08,0xFE,0x08,0x88,0x48,0x48,0x08,0x28,0x10, + /* 0xEFB3 [?] [7351]*/ + 0x20,0x20,0x3B,0x20,0x40,0x79,0xA3,0x20,0xF9,0x21,0x21,0x21,0x2A,0x32,0x24,0x08, + 0x40,0x20,0xFC,0x40,0x90,0x08,0xFC,0x04,0x50,0x50,0x50,0x50,0x50,0x52,0x52,0x0E, + /* 0xEFB4 [?] [7352]*/ + 0x21,0x20,0x3A,0x22,0x42,0x7A,0xA2,0x22,0xFB,0x22,0x22,0x22,0x2B,0x32,0x22,0x02, + 0x00,0xBE,0x82,0x02,0xFA,0x52,0x52,0x52,0xFE,0x52,0x52,0x92,0x12,0x02,0x0A,0x04, + /* 0xEFB5 [?] [7353]*/ + 0x21,0x20,0x3A,0x22,0x42,0x7A,0xA2,0x22,0xFA,0x22,0x22,0x22,0x2A,0x32,0x22,0x02, + 0x00,0xBE,0x82,0x02,0x02,0xFA,0x8A,0x8A,0xFA,0x8A,0x8A,0xFA,0x02,0x02,0x0A,0x04, + /* 0xEFB6 [?] [7354]*/ + 0x10,0x10,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xEFB7 [?] [7355]*/ + 0x10,0x11,0x3C,0x20,0x40,0xBD,0x10,0x13,0xFE,0x11,0x10,0x10,0x14,0x18,0x10,0x03, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x02,0xF8,0x88,0x88,0x50,0x20,0xD8,0x06, + /* 0xEFB8 [?] [7356]*/ + 0x20,0x23,0x3A,0x42,0x43,0x7A,0xA2,0x23,0xFA,0x22,0x22,0x2A,0x34,0x24,0x08,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0xF4,0x94,0x94,0xF4,0x04,0x28,0x10, + /* 0xEFB9 [?] [7357]*/ + 0x20,0x27,0x3D,0x25,0x45,0x7D,0xA6,0x25,0xFD,0x25,0x25,0x25,0x2E,0x34,0x24,0x04, + 0x00,0x7E,0x04,0x04,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x54,0x04,0x04,0x14,0x08, + /* 0xEFBA [?] [7358]*/ + 0x20,0x20,0x3B,0x20,0x41,0x78,0xA3,0x20,0xF9,0x21,0x21,0x21,0x29,0x31,0x21,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xEFBB [?] [7359]*/ + 0x20,0x20,0x3B,0x20,0x40,0x78,0xA3,0x20,0xF8,0x20,0x21,0x22,0x28,0x30,0x20,0x00, + 0x88,0x88,0xFE,0x88,0xA8,0x20,0xFE,0x40,0x80,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xEFBC [?] [7360]*/ + 0x20,0x20,0x3B,0x20,0x40,0x79,0xA2,0x20,0xF8,0x20,0x23,0x20,0x28,0x30,0x21,0x02, + 0x20,0x20,0xFE,0x50,0xA8,0x24,0xFA,0x20,0xA8,0x88,0xFE,0x88,0x88,0x88,0x08,0x08, + /* 0xEFBD [?] [7361]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x10,0x11,0xFC,0x13,0x10,0x11,0x14,0x18,0x10,0x00, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x08,0xFE,0x08,0x08,0x88,0x08,0x28,0x10, + /* 0xEFBE [?] [7362]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFC,0x13,0x10,0x10,0x15,0x1A,0x10,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xEFBF [?] [7363]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFC,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xEFC0 [?] [7364]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x00,0xFC,0x04,0x24,0x24,0xFC,0x24,0x24,0x74,0x54,0x54,0x74,0x04,0x04,0xFC,0x04, + /* 0xEFC1 [?] [7365]*/ + 0x20,0x20,0x38,0x21,0x42,0x78,0xA1,0x22,0xF8,0x21,0x20,0x20,0x2A,0x32,0x24,0x00, + 0x80,0x80,0xFC,0x54,0x54,0xA4,0x24,0x44,0x94,0x08,0x40,0xA4,0xAA,0x8A,0x78,0x00, + /* 0xEFC2 [?] [7366]*/ + 0x10,0x10,0x3D,0x20,0x41,0xBC,0x10,0x13,0xFC,0x10,0x11,0x11,0x15,0x19,0x11,0x01, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xEFC3 [?] [7367]*/ + 0x10,0x11,0x3C,0x20,0x41,0xBC,0x13,0x10,0xFD,0x12,0x14,0x10,0x14,0x18,0x10,0x00, + 0x20,0x24,0xA8,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x88,0x88,0xA8,0x92,0x82,0x7E, + /* 0xEFC4 [?] [7368]*/ + 0x20,0x22,0x3A,0x24,0x40,0x79,0xA6,0x20,0xF8,0x22,0x22,0x24,0x28,0x31,0x22,0x0C, + 0x40,0x44,0x44,0x48,0xA0,0x10,0x08,0x44,0x40,0x48,0x48,0x50,0xA0,0x10,0x08,0x06, + /* 0xEFC5 [?] [7369]*/ + 0x10,0x10,0x3D,0x22,0x41,0xBC,0x10,0x10,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x92,0x92,0x24,0x48,0x24,0x92,0x92,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xEFC6 [?] [7370]*/ + 0x21,0x21,0x3B,0x21,0x43,0x79,0xA7,0x21,0xF9,0x20,0x27,0x20,0x28,0x31,0x22,0x0C, + 0x00,0x3C,0xD4,0x14,0x94,0x14,0xD4,0x24,0x4C,0x40,0xFE,0x40,0xA0,0x10,0x08,0x06, + /* 0xEFC7 [?] [7371]*/ + 0x11,0x11,0x3D,0x21,0x41,0xBD,0x11,0x10,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x10,0x12,0xD4,0x18,0x52,0x92,0x2E,0x40,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xEFC8 [?] [7372]*/ + 0x20,0x21,0x39,0x21,0x41,0x79,0xA1,0x21,0xF8,0x20,0x20,0x22,0x2A,0x34,0x20,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x00,0x40,0x24,0xA2,0x8A,0x88,0x78,0x00, + /* 0xEFC9 [?] [7373]*/ + 0x20,0x23,0x3A,0x22,0x43,0x78,0xA1,0x20,0xFB,0x20,0x21,0x21,0x28,0x30,0x20,0x00, + 0x00,0xDE,0x52,0x52,0xDE,0x00,0xFC,0x00,0xFE,0x80,0x00,0xFC,0x04,0x04,0x28,0x10, + /* 0xEFCA [?] [7374]*/ + 0x10,0x10,0x3D,0x20,0x40,0xBD,0x10,0x10,0xFD,0x11,0x11,0x11,0x15,0x19,0x11,0x01, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x04, + /* 0xEFCB [?] [7375]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x11,0x11,0xFC,0x11,0x10,0x10,0x14,0x18,0x10,0x03, + 0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x20,0xFC,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xEFCC [?] [7376]*/ + 0x10,0x13,0x3C,0x21,0x40,0xBD,0x10,0x10,0xFD,0x10,0x10,0x11,0x15,0x1A,0x10,0x01, + 0x1E,0xE0,0x44,0x24,0x88,0xFC,0x40,0x40,0xFE,0x80,0xFC,0x44,0x28,0x10,0x68,0x86, + /* 0xEFCD [?] [7377]*/ + 0x20,0x20,0x3B,0x20,0x41,0x79,0xA1,0x21,0xF9,0x20,0x20,0x21,0x2A,0x34,0x20,0x00, + 0x40,0x20,0xFE,0x00,0xFC,0x04,0x04,0x04,0xFC,0x52,0x94,0x88,0x88,0xA4,0xC2,0x80, + /* 0xEFCE [?] [7378]*/ + 0x10,0x11,0x3C,0x20,0x43,0xBC,0x11,0x12,0xFC,0x13,0x10,0x11,0x15,0x18,0x11,0x06, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xEFCF [?] [7379]*/ + 0x10,0x10,0x3C,0x22,0x41,0xBC,0x10,0x10,0xFD,0x12,0x14,0x10,0x14,0x18,0x10,0x00, + 0x90,0x90,0x9E,0xA2,0xD4,0x88,0x94,0xA4,0xFE,0x84,0xA4,0x94,0x94,0x84,0x94,0x88, + /* 0xEFD0 [?] [7380]*/ + 0x20,0x27,0x38,0x23,0x42,0x7B,0xA1,0x22,0xFD,0x21,0x21,0x21,0x29,0x30,0x20,0x03, + 0x90,0xFC,0x94,0xFC,0x90,0xFE,0x12,0x16,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xEFD1 [?] [7381]*/ + 0x20,0x23,0x3A,0x42,0x43,0x7A,0xA2,0x22,0xFA,0x22,0x22,0x2A,0x34,0x24,0x08,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x00,0xFC,0x84,0x84,0xFC,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xEFD2 [?] [7382]*/ + 0x20,0x20,0x3B,0x20,0x40,0x79,0xA1,0x21,0xF9,0x21,0x20,0x23,0x28,0x30,0x21,0x02, + 0x88,0x88,0xFE,0x88,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xEFD3 [?] [7383]*/ + 0x20,0x23,0x38,0x21,0x41,0x79,0xA1,0x20,0xFB,0x22,0x22,0x23,0x2A,0x32,0x22,0x02, + 0x00,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x00,0xFE,0x8A,0x52,0xFE,0x22,0x22,0x2A,0x04, + /* 0xEFD4 [?] [7384]*/ + 0x20,0x20,0x39,0x23,0x45,0x79,0xA1,0x21,0xF9,0x21,0x23,0x20,0x28,0x31,0x22,0x04, + 0xA0,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x9E,0x02,0x0A,0x04, + /* 0xEFD5 [?] [7385]*/ + 0x10,0x10,0x3C,0x21,0x42,0xBC,0x10,0x10,0xFC,0x11,0x10,0x11,0x14,0x1B,0x10,0x00, + 0x20,0x50,0x88,0x74,0x02,0xF8,0x88,0xF8,0x0C,0xF0,0x20,0xFC,0x20,0xFE,0x20,0x60, + /* 0xEFD6 [?] [7386]*/ + 0x20,0x23,0x3A,0x22,0x42,0x7A,0xA3,0x20,0xFB,0x22,0x22,0x23,0x2A,0x32,0x23,0x02, + 0x40,0xBE,0x12,0x92,0x52,0xAA,0x24,0x40,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xEFD7 [?] [7387]*/ + 0x21,0x20,0x38,0x20,0x43,0x78,0xA0,0x21,0xFA,0x21,0x21,0x21,0x29,0x31,0x27,0x00, + 0x04,0x84,0x88,0x00,0xFE,0x00,0x88,0x04,0x02,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xEFD8 [?] [7388]*/ + 0x20,0x20,0x3B,0x22,0x40,0x79,0xA0,0x20,0xFB,0x20,0x20,0x23,0x28,0x30,0x23,0x00, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x40,0xA2,0x34,0x58,0x94,0x34,0x52,0x90,0x50,0x20, + /* 0xEFD9 [?] [7389]*/ + 0x20,0x20,0x3B,0x22,0x44,0x79,0xA1,0x21,0xF9,0x21,0x21,0x27,0x28,0x30,0x21,0x02, + 0x40,0x20,0xFE,0x02,0x14,0xE0,0x00,0x00,0xFC,0x10,0x10,0xFE,0x00,0x90,0x08,0x04, + /* 0xEFDA [?] [7390]*/ + 0x10,0x13,0x3C,0x21,0x41,0xBD,0x11,0x10,0xFD,0x10,0x13,0x10,0x14,0x19,0x12,0x00, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xEFDB [?] [7391]*/ + 0x20,0x21,0x38,0x23,0x42,0x78,0xA0,0x20,0xF8,0x20,0x20,0x21,0x28,0x30,0x23,0x00, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xEFDC [?] [7392]*/ + 0x20,0x21,0x39,0x21,0x41,0x79,0xA0,0x23,0xFA,0x23,0x20,0x21,0x28,0x30,0x21,0x06, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0xFC,0x00,0xF8,0x90,0x60,0x98,0x06, + /* 0xEFDD [?] [7393]*/ + 0x10,0x11,0x3D,0x21,0x41,0xBD,0x10,0x10,0xFD,0x10,0x10,0x13,0x14,0x19,0x12,0x00, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x40,0x88,0xF0,0x20,0x44,0xFE,0x22,0x24,0x22,0x60, + /* 0xEFDE [?] [7394]*/ + 0x20,0x27,0x3C,0x25,0x44,0x77,0xA4,0x25,0xFC,0x25,0x25,0x25,0x2D,0x39,0x29,0x11, + 0x20,0xFE,0x20,0xFC,0x24,0xFE,0x24,0xFC,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x2C, + /* 0xEFDF [?] [7395]*/ + 0x22,0x21,0x39,0x47,0x42,0x7A,0xA3,0x22,0xFA,0x22,0x22,0x2A,0x34,0x25,0x08,0x10, + 0x20,0x20,0x20,0xBE,0x40,0x20,0xBC,0xD0,0x90,0x90,0xFE,0x90,0xA8,0xA8,0x44,0x82, + /* 0xEFE0 [?] [7396]*/ + 0x22,0x21,0x39,0x47,0x42,0x7A,0xA3,0x22,0xFA,0x22,0x22,0x2A,0x34,0x25,0x08,0x10, + 0x10,0x10,0x10,0xBE,0x40,0x00,0xBE,0x8A,0x88,0xA8,0xAE,0xA8,0xA8,0xA8,0x5E,0x80, + /* 0xEFE1 [?] [7397]*/ + 0x20,0x20,0x3B,0x20,0x40,0x7B,0xA2,0x22,0xFA,0x22,0x22,0x22,0x2A,0x32,0x22,0x02, + 0x40,0x20,0xFE,0x88,0x50,0xFE,0x22,0xFA,0x22,0xFA,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xEFE2 [?] [7398]*/ + 0x20,0x23,0x38,0x23,0x42,0x7B,0xA0,0x21,0xF9,0x21,0x21,0x21,0x28,0x33,0x20,0x00, + 0x00,0xFE,0x50,0xFE,0x52,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20, + /* 0xEFE3 [?] [7399]*/ + 0x20,0x2F,0x38,0x4A,0x49,0x7B,0xA8,0x28,0xFA,0x2A,0x2B,0x28,0x38,0x29,0x09,0x12, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xEFE4 [?] [7400]*/ + 0x20,0x24,0x3A,0x20,0x47,0x79,0xA0,0x27,0xF8,0x23,0x20,0x27,0x28,0x31,0x22,0x0C, + 0xA0,0xA4,0xA8,0xA0,0xFC,0x10,0xA0,0xFC,0x40,0xF8,0x40,0xFC,0xA0,0x10,0x08,0x06, + /* 0xEFE5 [?] [7401]*/ + 0x20,0x20,0x39,0x23,0x45,0x79,0xA1,0x21,0xF8,0x23,0x20,0x21,0x29,0x31,0x21,0x01, + 0x80,0xF8,0x10,0xFC,0x24,0xFC,0x24,0xFC,0x00,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC, + /* 0xEFE6 [?] [7402]*/ + 0x21,0x20,0x3B,0x20,0x43,0x7A,0xA3,0x20,0xFB,0x20,0x20,0x20,0x2B,0x30,0x22,0x01, + 0x08,0x88,0xC8,0x10,0xDE,0x64,0xD4,0x14,0xD4,0x54,0x94,0xE8,0x88,0x94,0x94,0x22, + /* 0xEFE7 [?] [7403]*/ + 0x22,0x21,0x3D,0x24,0x45,0x7C,0xA5,0x25,0xFD,0x25,0x25,0x25,0x2C,0x35,0x24,0x04, + 0x00,0x7C,0x04,0x44,0xF4,0x44,0xF4,0x54,0x74,0xD4,0x54,0xF4,0xE4,0x54,0x44,0x4C, + /* 0xEFE8 [?] [7404]*/ + 0x21,0x20,0x3B,0x20,0x42,0x79,0xA0,0x27,0xF8,0x21,0x21,0x21,0x29,0x31,0x21,0x01, + 0x08,0x90,0xFC,0x90,0x94,0x98,0x90,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8, + /* 0xEFE9 [?] [7405]*/ + 0x20,0x20,0x3B,0x22,0x41,0x7A,0xA1,0x21,0xF9,0x20,0x23,0x22,0x2B,0x32,0x20,0x00, + 0x40,0x20,0xFE,0x8A,0x24,0x22,0xFC,0x24,0xFC,0x20,0xFE,0x22,0xFE,0x22,0x20,0x20, + /* 0xEFEA [?] [7406]*/ + 0x20,0x23,0x38,0x20,0x40,0x7B,0xA2,0x22,0xFA,0x23,0x20,0x20,0x28,0x30,0x25,0x02, + 0x00,0xBE,0xA2,0xA2,0xBE,0x88,0x08,0x3E,0x2A,0xAA,0xAA,0xBE,0x88,0x8A,0x7E,0x02, + /* 0xEFEB [?] [7407]*/ + 0x20,0x27,0x38,0x22,0x41,0x7A,0xA5,0x28,0xFB,0x22,0x22,0x23,0x2A,0x31,0x2F,0x00, + 0x20,0xA4,0xA8,0x92,0x14,0x08,0xF4,0x02,0xF8,0x08,0x08,0xF8,0x08,0x10,0xFE,0x00, + /* 0xEFEC [?] [7408]*/ + 0x20,0x23,0x38,0x20,0x41,0x7B,0xA1,0x21,0xF9,0x21,0x21,0x21,0x2B,0x30,0x20,0x03, + 0x88,0xFE,0xA8,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x70,0x8E, + /* 0xEFED [?] [7409]*/ + 0x20,0x23,0x3A,0x22,0x43,0x79,0xA3,0x24,0xFB,0x22,0x22,0x23,0x28,0x37,0x20,0x00, + 0x00,0xF8,0xA8,0xA8,0xF8,0x00,0xFC,0x84,0xE4,0xA4,0xA4,0xE4,0x94,0xF4,0x14,0x08, + /* 0xEFEE [?] [7410]*/ + 0x20,0x20,0x39,0x20,0x40,0x7B,0xA0,0x21,0xF9,0x21,0x21,0x21,0x28,0x32,0x22,0x04, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x94,0x8A,0x7A, + /* 0xEFEF [?] [7411]*/ + 0x20,0x20,0x37,0x44,0x4A,0x73,0xA4,0x2A,0xF5,0x22,0x24,0x23,0x28,0x32,0x24,0x00, + 0x80,0x40,0xFE,0x02,0x24,0xBC,0xA4,0xA8,0x10,0xE8,0x04,0xF8,0x40,0x48,0x44,0xC0, + /* 0xEFF0 [?] [7412]*/ + 0x20,0x20,0x3B,0x22,0x43,0x7A,0xA3,0x22,0xFA,0x22,0x22,0x22,0x2A,0x34,0x25,0x0A, + 0x40,0x20,0xFE,0x50,0xFE,0x52,0xFE,0x00,0x94,0xD8,0x90,0xD2,0x8E,0x00,0x54,0x2A, + /* 0xEFF1 [?] [7413]*/ + 0x10,0x10,0x3D,0x20,0x43,0xBC,0x11,0x11,0xFD,0x11,0x11,0x10,0x15,0x18,0x13,0x00, + 0x08,0x3C,0xE0,0x20,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xEFF2 [?] [7414]*/ + 0x20,0x21,0x3C,0x50,0x90,0x11,0x11,0xFF,0x11,0x11,0x10,0x28,0x24,0x44,0x41,0x80, + 0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0xE4,0x24,0x24,0x24,0x24,0x44,0x84, + /* 0xEFF3 [?] [7415]*/ + 0x20,0x20,0x21,0x7D,0x51,0x91,0x12,0xFC,0x10,0x10,0x11,0x28,0x24,0x44,0x43,0x80, + 0x20,0x20,0x24,0x24,0x24,0x24,0xAA,0x72,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xEFF4 [?] [7416]*/ + 0x20,0x20,0x20,0x7D,0x51,0x93,0x15,0xFD,0x11,0x11,0x11,0x29,0x25,0x45,0x41,0x81, + 0xA0,0x90,0x80,0xFE,0x10,0x10,0xFC,0x10,0x10,0xFC,0x10,0x10,0x10,0xFE,0x00,0x00, + /* 0xEFF5 [?] [7417]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x10, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xEFF6 [?] [7418]*/ + 0x08,0x1C,0xF0,0x11,0x11,0xFD,0x11,0x39,0x34,0x54,0x50,0x91,0x16,0x10,0x10,0x10, + 0x20,0x20,0x2E,0xF0,0x20,0x20,0x20,0xFE,0x22,0x62,0xA2,0x2A,0x24,0x20,0x20,0x20, + /* 0xEFF7 [?] [7419]*/ + 0x08,0x1C,0xF0,0x13,0x10,0xFC,0x10,0x31,0x38,0x54,0x54,0x91,0x11,0x12,0x10,0x10, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x70,0xA8,0xA8,0x24,0x24,0x22,0x20,0x20, + /* 0xEFF8 [?] [7420]*/ + 0x08,0x1C,0xF0,0x10,0x17,0xFC,0x10,0x38,0x35,0x51,0x52,0x94,0x18,0x10,0x10,0x10, + 0x40,0x50,0x48,0x40,0xFC,0x40,0xE0,0xE0,0x50,0x50,0x48,0x44,0x42,0x40,0x40,0x40, + /* 0xEFF9 [?] [7421]*/ + 0x08,0x1C,0xF0,0x10,0x10,0xFC,0x10,0x38,0x34,0x55,0x51,0x91,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x00,0x00,0xFE,0x02,0x02,0x02,0x02,0xFE,0x02, + /* 0xEFFA [?] [7422]*/ + 0x08,0x1C,0xF0,0x13,0x10,0xFC,0x10,0x38,0x35,0x54,0x50,0x91,0x11,0x11,0x11,0x10, + 0x48,0x44,0x40,0xFE,0x50,0x50,0x92,0x92,0x0E,0x20,0x20,0x24,0x24,0x24,0xFC,0x04, + /* 0xEFFB [?] [7423]*/ + 0x08,0x1C,0xF1,0x10,0x11,0xFC,0x10,0x39,0x34,0x50,0x53,0x90,0x10,0x10,0x10,0x10, + 0x04,0x1E,0xE0,0x02,0x22,0x94,0x00,0xFC,0x08,0x10,0xFE,0x10,0x10,0x10,0x50,0x20, + /* 0xEFFC [?] [7424]*/ + 0x08,0x1C,0xF1,0x11,0x11,0xFD,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xEFFD [?] [7425]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x11,0x31,0x38,0x57,0x54,0x90,0x11,0x12,0x10,0x10, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xEFFE [?] [7426]*/ + 0x08,0x1C,0xF0,0x10,0x11,0xFE,0x11,0x38,0x34,0x54,0x50,0x92,0x12,0x12,0x14,0x10, + 0x20,0x20,0x50,0x88,0x44,0x22,0xF8,0x08,0x50,0x20,0xA4,0x82,0x8A,0x8A,0x78,0x00, + /* 0xF0A1 [?] [7427]*/ + 0x08,0x1C,0xF3,0x10,0x11,0xFD,0x11,0x39,0x35,0x55,0x51,0x91,0x17,0x10,0x11,0x12, + 0x20,0x20,0xFE,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFE,0x88,0x04,0x02, + /* 0xF0A2 [?] [7428]*/ + 0x08,0x1D,0xF1,0x11,0x11,0xFD,0x10,0x31,0x3A,0x54,0x51,0x92,0x10,0x10,0x11,0x16, + 0x00,0xFC,0x24,0xFC,0x24,0xFC,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xF0A3 [?] [7429]*/ + 0x08,0x1C,0xF3,0x10,0x11,0xFC,0x13,0x30,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x20,0x20,0xFE,0x20,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x74,0x54,0x74,0x04,0xFC,0x04, + /* 0xF0A4 [?] [7430]*/ + 0x0C,0x70,0x10,0xFE,0x38,0x54,0x90,0x28,0x55,0x91,0x55,0x39,0x55,0x93,0x51,0x21, + 0x20,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF0A5 [?] [7431]*/ + 0x04,0x78,0x10,0xFE,0x11,0x3A,0x54,0x90,0x7C,0x44,0x44,0x7C,0x45,0x44,0x7C,0x45, + 0x40,0x40,0xFE,0x80,0xFC,0x84,0xFC,0x84,0xFC,0x40,0x7C,0xC4,0x28,0x10,0x68,0x86, + /* 0xF0A6 [?] [7432]*/ + 0x10,0xE7,0x20,0x23,0x22,0xFB,0x21,0x37,0x69,0x67,0xA1,0x2F,0x21,0x23,0x2D,0x21, + 0x40,0xFC,0x00,0xB8,0xA8,0xB8,0x10,0xFC,0x10,0xFC,0x10,0xFE,0x28,0x10,0x48,0x86, + /* 0xF0A7 [?] [7433]*/ + 0x10,0x10,0x20,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x45,0x7D,0x46,0x00, + 0x04,0x0E,0xF0,0x80,0x80,0xFC,0xA4,0xA4,0xA4,0xA8,0xA8,0x90,0x10,0x28,0x44,0x82, + /* 0xF0A8 [?] [7434]*/ + 0x10,0x10,0x20,0x7B,0x48,0x48,0x49,0x4A,0x78,0x48,0x48,0x48,0x48,0x78,0x49,0x06, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xF0A9 [?] [7435]*/ + 0x10,0x11,0x21,0x7D,0x45,0x46,0x44,0x47,0x7C,0x44,0x45,0x45,0x45,0x7D,0x45,0x01, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xF0AA [?] [7436]*/ + 0x08,0x08,0x7E,0x18,0x2C,0x2A,0x48,0x88,0x09,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x88,0x08,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xF0AB [?] [7437]*/ + 0x10,0x13,0x21,0x78,0x4B,0x48,0x49,0x4A,0x79,0x49,0x49,0x49,0x49,0x79,0x49,0x01, + 0x3C,0xE0,0x24,0xA8,0xFE,0xA8,0x24,0x02,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xF0AC [?] [7438]*/ + 0x02,0x07,0x38,0x2A,0x2A,0x2B,0x2A,0x2A,0x2A,0x29,0x29,0x28,0x28,0x4A,0x4D,0x89, + 0x10,0x10,0x50,0x7C,0x90,0x10,0xFE,0x10,0x28,0x24,0x42,0x82,0x40,0x30,0x0E,0x00, + /* 0xF0AD [?] [7439]*/ + 0x10,0x10,0xFE,0x28,0x44,0x82,0x7C,0x00,0xFE,0x20,0x40,0x7C,0x04,0x05,0x29,0x12, + 0x08,0x1C,0xE8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA4,0xA4,0xA4,0xA2,0x28,0x34,0x24, + /* 0xF0AE [?] [7440]*/ + 0x00,0x3F,0x00,0x06,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21,0x21,0x21,0x20, + 0x00,0xF0,0x20,0x40,0x80,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x08,0x08,0x28,0x10, + /* 0xF0AF [?] [7441]*/ + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0x25,0x26,0x45,0x40,0x80,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0B0 [?] [7442]*/ + 0x04,0x04,0x02,0xFF,0x00,0x00,0x02,0x1F,0x14,0x12,0x10,0x1F,0x00,0x7F,0x00,0x00, + 0x20,0x10,0x3E,0xC0,0x80,0x42,0x32,0xEE,0x20,0x60,0x00,0xF8,0x08,0x88,0x28,0x10, + /* 0xF0B1 [?] [7443]*/ + 0x40,0x48,0x50,0x60,0x44,0x44,0x3C,0x10,0x10,0x10,0xFE,0x10,0x11,0x10,0x10,0x10, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0B2 [?] [7444]*/ + 0x08,0x08,0x08,0x7F,0x49,0x08,0x08,0x14,0x14,0x14,0x14,0x25,0x26,0x44,0x80,0x00, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0B3 [?] [7445]*/ + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x7C,0x44,0x44,0x44,0x45,0x7C,0x44,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0B4 [?] [7446]*/ + 0x10,0x10,0x10,0xFF,0x20,0x28,0x48,0x48,0x7E,0x08,0x2C,0x2A,0x49,0x89,0x28,0x10, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0B5 [?] [7447]*/ + 0x10,0x10,0x1E,0x10,0x10,0x7C,0x44,0x44,0x44,0x7C,0x44,0x40,0x41,0x40,0x80,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0B6 [?] [7448]*/ + 0x20,0x20,0x40,0x7E,0x82,0x02,0x7A,0x4A,0x4A,0x4A,0x7A,0x4A,0x03,0x02,0x14,0x08, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0B7 [?] [7449]*/ + 0x01,0x07,0x7C,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x42,0x42,0x52,0x69,0x44, + 0x10,0xA0,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0xFA,0x82,0x8A,0x84, + /* 0xF0B8 [?] [7450]*/ + 0x10,0x24,0x78,0x10,0x7E,0x00,0xFF,0x02,0x04,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x20,0x48,0xF0,0x20,0xFC,0x00,0xFE,0x00,0x00,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xF0B9 [?] [7451]*/ + 0x00,0x7F,0x08,0x08,0x10,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x45,0x42, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0BA [?] [7452]*/ + 0x10,0x10,0xFB,0x10,0x19,0xF0,0x11,0x52,0x24,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x80,0x80,0xF0,0x90,0x90,0x94,0x54,0x0C,0x04,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xF0BB [?] [7453]*/ + 0x04,0x0E,0x38,0x08,0x08,0xFF,0x08,0x08,0x3E,0x22,0x22,0x22,0x23,0x3E,0x22,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0BC [?] [7454]*/ + 0x12,0x12,0x12,0x22,0x2F,0x62,0xA6,0x27,0x2A,0x2A,0x32,0x22,0x22,0x22,0x22,0x22, + 0x08,0x10,0x3E,0x22,0xB2,0x2A,0x22,0x26,0xA0,0xBE,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0BD [?] [7455]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x42,0x1F,0x14,0x12,0x10,0x1F,0x00,0x7F,0x00,0x00, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x04,0xE0,0x20,0x60,0x00,0xF8,0x08,0x88,0x28,0x10, + /* 0xF0BE [?] [7456]*/ + 0x10,0x10,0xFE,0x10,0x10,0xFE,0x82,0x04,0x78,0x08,0x10,0x1E,0xF1,0x10,0x50,0x20, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0BF [?] [7457]*/ + 0x00,0xFF,0x00,0x00,0xF7,0x94,0x94,0x94,0xD6,0xB5,0x94,0x94,0x94,0x94,0x94,0xB5, + 0x08,0x90,0x3E,0x22,0xB2,0xAA,0xA2,0xA6,0xA0,0xBE,0x82,0x82,0xFA,0x82,0x8A,0x84, + /* 0xF0C0 [?] [7458]*/ + 0x08,0x48,0x48,0x7F,0x88,0x08,0x08,0xFF,0x00,0x00,0x7E,0x42,0x42,0x42,0x7E,0x42, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C1 [?] [7459]*/ + 0x28,0x24,0x42,0x92,0x10,0x28,0x44,0x82,0x7C,0x44,0x44,0x44,0x45,0x7C,0x44,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0C2 [?] [7460]*/ + 0x40,0x2F,0x01,0x49,0x49,0x49,0x7F,0x49,0x5D,0x6B,0x49,0x49,0x49,0x41,0x45,0x42, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C3 [?] [7461]*/ + 0x44,0x24,0x28,0xFC,0x14,0x14,0xFC,0x90,0x90,0xFE,0x32,0x32,0x53,0x96,0x10,0x10, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0C4 [?] [7462]*/ + 0x04,0x06,0x75,0x05,0x04,0xFF,0x04,0x14,0x14,0x5C,0x54,0x54,0x55,0x5D,0xE3,0x41, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C5 [?] [7463]*/ + 0x22,0x22,0xFF,0x22,0x22,0x00,0x7F,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x7F,0x41, + 0x08,0x10,0xBE,0x22,0x32,0x2A,0x22,0x26,0x20,0x3E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C6 [?] [7464]*/ + 0x08,0x08,0xFF,0x14,0x22,0x49,0x88,0x7F,0x49,0x7F,0x49,0x7F,0x08,0x0A,0x0C,0x08, + 0x08,0x10,0xBE,0x22,0x32,0x2A,0xA2,0x26,0x20,0x3E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C7 [?] [7465]*/ + 0x10,0x20,0x7F,0x49,0x49,0x7F,0x49,0x51,0x7F,0x24,0x44,0xFF,0x04,0x04,0x04,0x04, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x82,0x7A,0x02,0x0A,0x04, + /* 0xF0C8 [?] [7466]*/ + 0x10,0x08,0xFF,0x00,0x7E,0x42,0x7E,0x00,0x7E,0x04,0x08,0x0F,0xF8,0x08,0x28,0x10, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0C9 [?] [7467]*/ + 0x20,0x27,0x24,0xFC,0x24,0x27,0x24,0x74,0x54,0x57,0x54,0x54,0x74,0x08,0x0A,0x11, + 0x08,0x90,0xBE,0xA2,0xB2,0xAA,0xA2,0xA6,0xA0,0xBE,0x82,0x82,0xFA,0x82,0x8A,0x04, + /* 0xF0CA [?] [7468]*/ + 0x00,0x77,0x55,0x55,0x77,0x00,0x7F,0x00,0xFF,0x20,0x3F,0x01,0x01,0x01,0x0A,0x04, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0xC0,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0CB [?] [7469]*/ + 0x21,0x11,0x12,0xFF,0x21,0x21,0x42,0x52,0x94,0xE7,0x21,0x42,0x42,0x94,0xF7,0x10, + 0x08,0x10,0x3E,0xE2,0x32,0x2A,0x22,0xA6,0xA0,0x3E,0x02,0x02,0x7A,0x82,0x8A,0x84, + /* 0xF0CC [?] [7470]*/ + 0x00,0x7F,0x49,0x49,0x7F,0x40,0x5F,0x51,0x51,0x5F,0x51,0x5F,0x51,0x51,0x9F,0x11, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0CD [?] [7471]*/ + 0x00,0x7E,0x24,0x18,0xFF,0x29,0x4A,0x9A,0x04,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x20,0x20,0x7E,0xA4,0x28,0x10,0x28,0xC6,0x00,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xF0CE [?] [7472]*/ + 0x0E,0xF0,0x22,0x92,0x44,0x20,0x3C,0x50,0x10,0xFE,0x10,0x54,0x55,0x5C,0x64,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0CF [?] [7473]*/ + 0x22,0x14,0x00,0x7F,0x14,0x7F,0x15,0xFF,0x15,0x7F,0x14,0x36,0x55,0x94,0x14,0x14, + 0x10,0x20,0x7C,0xC4,0x64,0x54,0x44,0xCC,0x40,0x7E,0x02,0x02,0x7A,0x82,0x0A,0x04, + /* 0xF0D0 [?] [7474]*/ + 0x00,0x77,0x55,0x55,0x55,0x55,0x22,0x55,0x08,0xFF,0x12,0x22,0x34,0x0C,0x32,0xC1, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0D1 [?] [7475]*/ + 0x10,0x08,0x7F,0x40,0x52,0x52,0x7F,0x52,0x52,0x5E,0x40,0x55,0x55,0x55,0x80,0x00, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0D2 [?] [7476]*/ + 0x00,0x77,0x11,0x55,0x33,0x55,0x0C,0x33,0xC4,0x18,0x62,0x0C,0x71,0x06,0x18,0xE0, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0xC0,0x7E,0x02,0x82,0x7A,0x02,0x0A,0x04, + /* 0xF0D3 [?] [7477]*/ + 0x08,0x08,0x7F,0x08,0x55,0x22,0x41,0xBE,0x22,0x3E,0x22,0x3E,0x08,0x2A,0x49,0x18, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0xCC,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0D4 [?] [7478]*/ + 0x28,0x24,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x7E,0x41,0xAA,0xAA,0x00, + 0x20,0x40,0xFC,0x84,0xA4,0x84,0x94,0x88,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF0D5 [?] [7479]*/ + 0x08,0x7F,0x00,0x3E,0x22,0x3E,0x49,0x9A,0x04,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x28,0x24,0xFE,0x20,0x50,0x50,0x52,0x8E,0x00,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xF0D6 [?] [7480]*/ + 0x7E,0x14,0x08,0xFF,0x29,0x4A,0xA8,0x10,0x7F,0x55,0x63,0x5D,0x55,0x5D,0x41,0x43, + 0x10,0x20,0x7C,0x44,0x64,0x54,0x44,0x4C,0x40,0x7E,0x02,0x02,0x7A,0x02,0x0A,0x04, + /* 0xF0D7 [?] [7481]*/ + 0x10,0x21,0x7C,0x44,0x64,0x55,0x44,0x4C,0x40,0x7C,0x04,0x04,0xF5,0x04,0x14,0x09, + 0x44,0xFE,0x54,0x48,0xFE,0x90,0xFE,0x90,0xFE,0x90,0xFE,0x80,0xFE,0x44,0x38,0xC6, + /* 0xF0D8 [?] [7482]*/ + 0x00,0x3E,0x23,0x3E,0x09,0x2E,0x28,0x7E,0x04,0x1F,0x12,0x11,0x1F,0x00,0x7F,0x00, + 0x40,0xFC,0x48,0x30,0xCE,0x78,0x48,0x78,0x00,0xE0,0x20,0x60,0xFC,0x04,0xD4,0x08, + /* 0xF0D9 [?] [7483]*/ + 0x22,0xFF,0x22,0xF7,0x94,0xF7,0x28,0x24,0x7F,0x48,0xFF,0x48,0x7F,0x48,0x7F,0x40, + 0x08,0x90,0x3E,0xA2,0xB2,0xAA,0x22,0x26,0xA0,0x3E,0x02,0x02,0x7A,0x02,0x8A,0x04, + /* 0xF0DA [?] [7484]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x50,0x10,0x30,0x50,0x90,0x10,0x20,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xF0DB [?] [7485]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x30,0x50,0x90,0x10,0x20,0x20,0x41,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80, + /* 0xF0DC [?] [7486]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x30,0x50,0x90,0x10,0x20,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x94,0x88,0x80,0x80,0x80,0x80, + /* 0xF0DD [?] [7487]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x51,0x11,0x31,0x51,0x91,0x12,0x22,0x24,0x48,0x90, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x50,0x20, + /* 0xF0DE [?] [7488]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x50,0x14,0x34,0x54,0x94,0x14,0x24,0x27,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0xFC,0x04,0x00, + /* 0xF0DF [?] [7489]*/ + 0x00,0x00,0x1F,0x10,0x93,0x52,0x52,0x12,0x32,0x52,0x92,0x12,0x22,0x24,0x44,0x89, + 0x80,0x40,0xFE,0x00,0xFE,0x00,0x20,0x20,0xFC,0x24,0x24,0x44,0x44,0x84,0xA8,0x10, + /* 0xF0E0 [?] [7490]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x50,0x17,0x30,0x51,0x91,0x11,0x22,0x22,0x44,0x88, + 0x80,0x40,0xFE,0x00,0x90,0x88,0x80,0xFE,0xA0,0x20,0x20,0x20,0x22,0x22,0x22,0x1E, + /* 0xF0E1 [?] [7491]*/ + 0x00,0x00,0x1F,0x10,0x92,0x52,0x5F,0x12,0x32,0x52,0x93,0x12,0x22,0x22,0x43,0x82, + 0x80,0x40,0xFE,0x00,0x08,0x08,0xFE,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xF0E2 [?] [7492]*/ + 0x00,0x00,0x1F,0x10,0x90,0x57,0x50,0x10,0x33,0x52,0x92,0x13,0x22,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFE,0x08,0x08,0xC8,0x48,0x48,0xC8,0x48,0x08,0x28,0x10, + /* 0xF0E3 [?] [7493]*/ + 0x01,0x00,0x3F,0x20,0x20,0xA7,0x64,0x24,0x27,0x64,0xA4,0x27,0x20,0x40,0x5F,0x80, + 0x00,0x80,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFE,0x00, + /* 0xF0E4 [?] [7494]*/ + 0x00,0x00,0x1F,0x12,0x92,0x53,0x55,0x19,0x31,0x51,0x91,0x11,0x21,0x21,0x41,0x81, + 0x80,0x40,0xFE,0x00,0x00,0xFE,0x00,0x00,0xF8,0x00,0x00,0xFC,0x00,0x00,0x00,0x00, + /* 0xF0E5 [?] [7495]*/ + 0x00,0x00,0x1F,0x12,0x92,0x53,0x54,0x1B,0x32,0x52,0x93,0x12,0x22,0x22,0x42,0x81, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x04,0xE4,0x24,0x24,0xE4,0x14,0x08,0x02,0x02,0xFE, + /* 0xF0E6 [?] [7496]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x57,0x10,0x30,0x50,0x93,0x10,0x20,0x20,0x4F,0x80, + 0x80,0x40,0xFE,0x80,0x40,0x00,0xFC,0x40,0x40,0x40,0xF8,0x40,0x40,0x40,0xFE,0x00, + /* 0xF0E7 [?] [7497]*/ + 0x00,0x00,0x1F,0x10,0x90,0x5F,0x50,0x11,0x32,0x57,0x90,0x10,0x21,0x22,0x47,0x82, + 0x80,0x40,0xFE,0x80,0x40,0xFE,0x80,0x08,0x10,0xE0,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xF0E8 [?] [7498]*/ + 0x01,0x00,0x3F,0x24,0x24,0xA4,0x6F,0x24,0x24,0x64,0xA4,0x24,0x28,0x48,0x52,0xA1, + 0x00,0x80,0xFE,0x00,0x00,0x00,0xBC,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xBC,0xA4,0x00, + /* 0xF0E9 [?] [7499]*/ + 0x00,0x00,0x1F,0x10,0x90,0x53,0x50,0x10,0x34,0x52,0x92,0x10,0x20,0x20,0x47,0x80, + 0x80,0x40,0xFE,0x00,0x00,0xFC,0x90,0x90,0x92,0x92,0x94,0x98,0x90,0x90,0xFE,0x00, + /* 0xF0EA [?] [7500]*/ + 0x00,0x00,0x1F,0x10,0x9F,0x50,0x5F,0x10,0x37,0x54,0x97,0x10,0x20,0x21,0x42,0x8C, + 0x80,0x40,0xFE,0x40,0xFE,0x40,0xFC,0x44,0xFC,0x40,0xFE,0x42,0xAA,0x14,0x08,0x06, + /* 0xF0EB [?] [7501]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x57,0x10,0x30,0x53,0x90,0x10,0x21,0x25,0x45,0x88, + 0x80,0x40,0xFE,0x00,0x40,0x40,0xFC,0x40,0x40,0xFC,0x00,0x40,0x24,0x2A,0x0A,0xF8, + /* 0xF0EC [?] [7502]*/ + 0x00,0x00,0x1F,0x11,0x91,0x57,0x51,0x10,0x37,0x54,0x90,0x17,0x20,0x21,0x42,0x8C, + 0x80,0x40,0xFE,0x08,0x08,0xFE,0x08,0x00,0xFE,0x02,0x40,0xFC,0x84,0x04,0x28,0x10, + /* 0xF0ED [?] [7503]*/ + 0x00,0x00,0x1F,0x10,0x97,0x50,0x53,0x10,0x31,0x5F,0x90,0x13,0x22,0x22,0x43,0x82, + 0x80,0x40,0xFE,0x00,0xFC,0x80,0xF8,0x88,0x08,0xFE,0x00,0xF8,0x08,0x08,0xF8,0x08, + /* 0xF0EE [?] [7504]*/ + 0x00,0x00,0x1F,0x10,0x90,0x52,0x52,0x15,0x38,0x50,0x90,0x17,0x20,0x20,0x40,0x8F, + 0x80,0x40,0xFE,0x40,0x40,0x48,0x48,0x54,0xE2,0x40,0x40,0xFC,0x40,0x40,0x40,0xFE, + /* 0xF0EF [?] [7505]*/ + 0x00,0x00,0x1F,0x10,0x92,0x51,0x54,0x14,0x35,0x54,0x94,0x15,0x26,0x24,0x44,0x84, + 0x80,0x40,0xFE,0x00,0x00,0x7C,0x04,0x44,0xF4,0x44,0xE4,0x54,0x44,0x44,0x54,0x08, + /* 0xF0F0 [?] [7506]*/ + 0x00,0x00,0x1F,0x10,0x92,0x51,0x51,0x14,0x32,0x52,0x91,0x16,0x22,0x22,0x42,0x80, + 0x80,0x40,0xFE,0x10,0x10,0x10,0x54,0x52,0x92,0x10,0x14,0x04,0x08,0x10,0x20,0xC0, + /* 0xF0F1 [?] [7507]*/ + 0x01,0x00,0x3F,0x20,0x2F,0xA1,0x63,0x24,0x2D,0x62,0xA5,0x29,0x22,0x44,0x59,0x80, + 0x00,0x80,0xFE,0x00,0xFC,0x00,0x08,0x88,0x50,0x60,0xE0,0x50,0x50,0x48,0x44,0x80, + /* 0xF0F2 [?] [7508]*/ + 0x00,0x00,0x1F,0x10,0x90,0x50,0x57,0x10,0x30,0x53,0x90,0x10,0x27,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x00,0x90,0x90,0x9E,0x90,0x90,0x9C,0x90,0x90,0x9E,0x90,0x90,0x90, + /* 0xF0F3 [?] [7509]*/ + 0x00,0x00,0x1F,0x10,0x97,0x54,0x54,0x17,0x34,0x55,0x95,0x15,0x25,0x24,0x47,0x84, + 0x80,0x40,0xFE,0x00,0xFC,0x44,0x44,0xFC,0x44,0xF4,0x14,0x14,0xF4,0x04,0xFC,0x04, + /* 0xF0F4 [?] [7510]*/ + 0x00,0x00,0x1F,0x10,0x97,0x50,0x5F,0x11,0x32,0x5C,0x90,0x1F,0x21,0x23,0x40,0x8F, + 0x80,0x40,0xFE,0x38,0xC0,0x40,0xFE,0x50,0x48,0x46,0x80,0xFE,0x08,0x10,0xE0,0x1C, + /* 0xF0F5 [?] [7511]*/ + 0x01,0x00,0x3F,0x20,0x22,0xAC,0x68,0x28,0x2E,0x68,0xA8,0x2F,0x21,0x42,0x4C,0xB0, + 0x00,0x80,0xFE,0x00,0x80,0xB8,0x88,0x88,0xB8,0x88,0x88,0xF8,0x40,0x20,0x18,0x06, + /* 0xF0F6 [?] [7512]*/ + 0x01,0x00,0x3F,0x20,0x24,0xA2,0x6F,0x24,0x24,0x67,0xA4,0x24,0x28,0x48,0x52,0xA1, + 0x00,0x80,0xFE,0x00,0x10,0x10,0xA8,0x28,0x44,0x92,0x88,0x88,0xA0,0x90,0x88,0x08, + /* 0xF0F7 [?] [7513]*/ + 0x00,0x00,0x1F,0x12,0x91,0x57,0x54,0x17,0x34,0x57,0x94,0x10,0x2F,0x20,0x40,0x80, + 0x80,0x40,0xFE,0x08,0x10,0xFC,0x44,0xFC,0x44,0xFC,0x44,0x40,0xFE,0x40,0x40,0x40, + /* 0xF0F8 [?] [7514]*/ + 0x00,0x00,0x1F,0x11,0x91,0x57,0x51,0x17,0x35,0x57,0x91,0x13,0x25,0x29,0x41,0x81, + 0x80,0x40,0xFE,0x00,0x04,0xC4,0x14,0xD4,0x54,0xD4,0x14,0x94,0x54,0x44,0x14,0x08, + /* 0xF0F9 [?] [7515]*/ + 0x01,0x00,0x3F,0x20,0x2F,0xA4,0x62,0x3F,0x21,0x62,0xAC,0x30,0x2F,0x40,0x40,0x9F, + 0x00,0x80,0xFE,0x80,0xF8,0x90,0xA0,0xFE,0x40,0x20,0x98,0x86,0xF8,0x80,0x80,0xFC, + /* 0xF0FA [?] [7516]*/ + 0x01,0x00,0x3F,0x20,0x22,0xA2,0x64,0x2D,0x34,0x64,0xA5,0x24,0x25,0x44,0x44,0x85, + 0x00,0x80,0xFE,0x00,0xF8,0x08,0x08,0xFE,0x80,0xF8,0x20,0x20,0xFE,0x50,0x88,0x06, + /* 0xF0FB [?] [7517]*/ + 0x00,0x00,0x1F,0x11,0x90,0x57,0x50,0x13,0x30,0x57,0x91,0x13,0x24,0x28,0x47,0x80, + 0x80,0x40,0xFE,0x10,0xA0,0xFC,0x40,0xF8,0x80,0xFC,0x00,0xF8,0x40,0x40,0xFE,0x00, + /* 0xF0FC [?] [7518]*/ + 0x00,0x00,0x1F,0x12,0x91,0x5F,0x51,0x12,0x34,0x50,0x9F,0x11,0x23,0x20,0x41,0x86, + 0x80,0x40,0xFE,0x48,0x50,0xFE,0x50,0x48,0x44,0x80,0xFE,0x08,0x90,0x60,0x98,0x04, + /* 0xF0FD [?] [7519]*/ + 0x00,0x00,0x1F,0x10,0x97,0x54,0x54,0x17,0x34,0x54,0x97,0x14,0x24,0x27,0x44,0x84, + 0x80,0x40,0xFE,0x00,0xBC,0x84,0x84,0xBC,0x00,0x7C,0xA4,0x24,0x28,0x90,0x28,0x46, + /* 0xF0FE [?] [7520]*/ + 0x00,0x00,0x1F,0x10,0x97,0x52,0x51,0x10,0x33,0x5C,0x93,0x12,0x23,0x20,0x47,0x80, + 0x80,0x40,0xFE,0x00,0xFC,0x48,0x10,0xE0,0x18,0x46,0xF8,0x48,0xF8,0x44,0xFC,0x04, + /* 0xF1A1 [?] [7521]*/ + 0x00,0x00,0x1F,0x11,0x97,0x51,0x53,0x11,0x37,0x51,0x91,0x10,0x20,0x25,0x45,0x88, + 0x80,0x40,0xFE,0x00,0xBC,0x14,0x94,0x14,0xA4,0x4C,0x00,0x40,0x24,0x22,0x0A,0xF8, + /* 0xF1A2 [?] [7522]*/ + 0x00,0x00,0x1F,0x11,0x97,0x51,0x53,0x12,0x33,0x52,0x93,0x10,0x2F,0x20,0x43,0x8C, + 0x80,0x40,0xFE,0x10,0xFC,0x10,0xF8,0x08,0xF8,0x08,0xF8,0x40,0xFE,0xA0,0x18,0x06, + /* 0xF1A3 [?] [7523]*/ + 0x01,0x00,0x3F,0x24,0x2F,0xA9,0x6D,0x2B,0x3F,0x69,0xA9,0x2D,0x2B,0x49,0x49,0x93, + 0x00,0x80,0xFE,0x00,0x78,0x48,0x48,0x86,0x00,0x78,0x48,0x48,0x28,0x10,0x28,0x46, + /* 0xF1A4 [?] [7524]*/ + 0x00,0x00,0x1F,0x14,0x92,0x54,0x51,0x12,0x37,0x5A,0x93,0x12,0x23,0x22,0x42,0x82, + 0x80,0x40,0xFE,0x44,0x48,0xA4,0x10,0x08,0xFC,0x0A,0xF8,0x08,0xF8,0x08,0x28,0x10, + /* 0xF1A5 [?] [7525]*/ + 0x01,0x00,0x3F,0x22,0x2F,0xA2,0x7F,0x20,0x2F,0x68,0xAF,0x28,0x2F,0x42,0x44,0x88, + 0x00,0x80,0xFE,0x20,0xF8,0x20,0xFC,0x80,0xF8,0x88,0xF8,0x88,0xF8,0x20,0x10,0x08, + /* 0xF1A6 [?] [7526]*/ + 0x00,0x3F,0x20,0x3F,0xA1,0x6F,0x29,0x2F,0x60,0xA7,0x20,0x2F,0x22,0x44,0x49,0x80, + 0x80,0xFE,0x00,0xFE,0x20,0xFC,0x24,0xFC,0x00,0xF8,0x00,0xFC,0x48,0x44,0x42,0x80, + /* 0xF1A7 [?] [7527]*/ + 0x00,0x3F,0x20,0x27,0xA4,0x67,0x24,0x27,0x61,0xA2,0x27,0x20,0x2F,0x44,0x49,0x90, + 0x80,0xFE,0x00,0xFC,0x44,0xFC,0x44,0xFC,0x00,0x08,0xF0,0xC4,0xFE,0x48,0x44,0x82, + /* 0xF1A8 [?] [7528]*/ + 0x00,0x3F,0x20,0x2F,0xA8,0x6A,0x2A,0x2A,0x65,0xA8,0x3F,0x22,0x27,0x40,0x43,0x9C, + 0x80,0xFE,0x00,0xBE,0xA2,0xAA,0xAA,0xAA,0x14,0xA2,0xFE,0x08,0x10,0xE0,0x1C,0x02, + /* 0xF1A9 [?] [7529]*/ + 0x01,0x00,0x3F,0x22,0x23,0xA4,0x6A,0x25,0x22,0x65,0xA8,0x27,0x22,0x44,0x49,0x80, + 0x00,0x80,0xFE,0x20,0xBC,0xA4,0xA8,0x10,0x08,0xF6,0x00,0xFC,0x50,0x48,0x44,0x80, + /* 0xF1AA [?] [7530]*/ + 0x00,0x3F,0x20,0x2F,0xA9,0x6A,0x2C,0x2A,0x69,0xA9,0x2D,0x2A,0x28,0x48,0x48,0x88, + 0x80,0xFE,0x20,0x3C,0x44,0xA8,0x10,0x28,0x46,0x38,0x50,0x7E,0x90,0x7C,0x10,0xFE, + /* 0xF1AB [?] [7531]*/ + 0x00,0x3F,0x20,0x2E,0xAA,0x6B,0x2C,0x2A,0x6A,0xAA,0x2B,0x2E,0x28,0x49,0x49,0x8A, + 0x80,0xFE,0x40,0x78,0x88,0x10,0xFC,0x04,0xFC,0x04,0xFC,0x20,0x14,0x52,0x4A,0x38, + /* 0xF1AC [?] [7532]*/ + 0x00,0x3F,0x20,0x2F,0xA9,0x65,0x29,0x21,0x66,0xB8,0x23,0x2C,0x21,0x4E,0x41,0x8E, + 0x80,0xFE,0x00,0x7C,0x24,0x14,0xA4,0x60,0x18,0x86,0x20,0x40,0x88,0x30,0xC0,0x00, + /* 0xF1AD [?] [7533]*/ + 0x01,0x00,0x3F,0x20,0x2E,0xA4,0x65,0x24,0x25,0x6E,0xA4,0x24,0x24,0x46,0x59,0x82, + 0x00,0x80,0xFE,0x80,0x4E,0x44,0xF4,0x24,0x24,0xAE,0x44,0x44,0xA4,0xA4,0x0E,0x00, + /* 0xF1AE [?] [7534]*/ + 0x00,0x3F,0x22,0x2F,0xA2,0x62,0x2F,0x2A,0x6A,0xAF,0x22,0x27,0x2A,0x52,0x42,0x82, + 0x80,0xFE,0x10,0x9C,0x24,0x48,0xBE,0xA2,0xAA,0xAA,0x2A,0x2A,0xAA,0x94,0x22,0x42, + /* 0xF1AF [?] [7535]*/ + 0x00,0x00,0x1F,0x10,0x97,0x51,0x5F,0x10,0x33,0x52,0x93,0x12,0x23,0x25,0x45,0x88, + 0x80,0x40,0xFE,0x40,0xFC,0x10,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x44,0x2A,0xFA, + /* 0xF1B0 [?] [7536]*/ + 0x01,0x00,0x3F,0x20,0x2F,0xA8,0x6F,0x2A,0x2A,0x6F,0xAA,0x2F,0x28,0x52,0x54,0xA8, + 0x00,0x80,0xFE,0x00,0xDC,0x54,0xD4,0xA2,0x80,0xDC,0x94,0xD4,0x08,0x88,0x54,0x62, + /* 0xF1B1 [?] [7537]*/ + 0x01,0x00,0x3F,0x20,0x27,0xA4,0x64,0x27,0x24,0x64,0xAF,0x2C,0x34,0x47,0x44,0x80, + 0x00,0x80,0xFE,0x10,0x88,0xBE,0x80,0xA2,0x94,0x3E,0x88,0x88,0xBE,0x88,0x88,0x08, + /* 0xF1B2 [?] [7538]*/ + 0x00,0x3F,0x24,0x3F,0xA4,0x6F,0x29,0x2F,0x69,0xAF,0x29,0x2F,0x29,0x7F,0x49,0x90, + 0x80,0xFE,0x00,0xBE,0x08,0x10,0x3E,0x22,0x2A,0x2A,0x2A,0x2A,0x2A,0x94,0x12,0xA2, + /* 0xF1B3 [?] [7539]*/ + 0x00,0x1F,0x14,0x17,0x94,0x57,0x14,0x37,0x51,0x93,0x12,0x17,0x2A,0x23,0x42,0x83, + 0x80,0xFE,0xA4,0xBC,0xA4,0xBC,0xA4,0xBC,0x20,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE, + /* 0xF1B4 [?] [7540]*/ + 0x20,0x13,0x10,0xFC,0x02,0x09,0x89,0x88,0x48,0x49,0x52,0x50,0x1C,0xE0,0x41,0x00, + 0x00,0xDE,0x42,0x42,0x52,0x4A,0x4A,0x42,0xC6,0x4A,0x52,0x42,0x42,0x42,0x4A,0x84, + /* 0xF1B5 [?] [7541]*/ + 0x20,0x10,0x13,0xFC,0x00,0x09,0x89,0x89,0x49,0x48,0x50,0x50,0x1D,0xE2,0x40,0x00, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xF1B6 [?] [7542]*/ + 0x02,0x01,0x7F,0x40,0x88,0x10,0x22,0x04,0x0F,0x10,0x68,0x04,0x02,0x03,0x1C,0xE0, + 0x00,0x00,0xFE,0x02,0x24,0x10,0x08,0x00,0xF0,0x10,0x20,0x40,0x80,0x00,0x00,0x00, + /* 0xF1B7 [?] [7543]*/ + 0x02,0x01,0x7F,0x48,0x90,0x2F,0x00,0x00,0x1F,0x10,0x20,0x3F,0x00,0x00,0x00,0x00, + 0x00,0x00,0xFE,0x22,0x14,0xF8,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xF1B8 [?] [7544]*/ + 0x02,0x01,0x7F,0x48,0x91,0x21,0xFF,0x01,0x21,0x21,0x21,0x3F,0x01,0x01,0x01,0x00, + 0x00,0x00,0xFE,0x22,0x14,0x08,0xFE,0x00,0x08,0x08,0x08,0xF8,0x0A,0x02,0x02,0xFE, + /* 0xF1B9 [?] [7545]*/ + 0x02,0x01,0x7F,0x48,0x90,0x01,0x3E,0x02,0x01,0x7F,0x00,0x01,0x0E,0x30,0x48,0x87, + 0x00,0x00,0xFE,0x22,0x14,0xF0,0x00,0x00,0x00,0xF8,0x60,0x80,0x00,0x00,0x00,0xFE, + /* 0xF1BA [?] [7546]*/ + 0x02,0x01,0x7F,0x48,0x90,0x08,0x08,0x12,0x22,0x7C,0x08,0x14,0x22,0x7E,0x21,0x02, + 0x00,0x00,0xFE,0x22,0x14,0x40,0x40,0xF8,0x48,0x48,0x48,0x48,0x88,0x88,0x28,0x10, + /* 0xF1BB [?] [7547]*/ + 0x02,0x01,0x7F,0x48,0x90,0x04,0x44,0x24,0x24,0x0C,0x34,0xC8,0x08,0x10,0x20,0x40, + 0x00,0x00,0xFE,0x22,0x14,0x40,0x48,0x50,0x60,0x40,0x60,0x52,0x4A,0x42,0x3E,0x00, + /* 0xF1BC [?] [7548]*/ + 0x02,0x01,0x7F,0x48,0x91,0x2F,0x01,0x7F,0x04,0x12,0x09,0xFF,0x02,0x04,0x18,0x60, + 0x00,0x00,0xFE,0x22,0x14,0xE8,0x00,0xFC,0x84,0x88,0x00,0xFE,0x60,0x10,0x08,0x04, + /* 0xF1BD [?] [7549]*/ + 0x02,0x01,0x7F,0x48,0x90,0x3F,0x11,0x1F,0x11,0x1F,0x01,0xFF,0x05,0x09,0x31,0xC1, + 0x00,0x00,0xFE,0x22,0x14,0xF8,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x40,0x20,0x18,0x06, + /* 0xF1BE [?] [7550]*/ + 0x02,0x01,0x7F,0x49,0x92,0x0C,0x37,0xC0,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x22,0x26, + 0x00,0x00,0xFE,0x22,0x94,0x60,0xD8,0x06,0x08,0x48,0x48,0x48,0x48,0x08,0x28,0x10, + /* 0xF1BF [?] [7551]*/ + 0x02,0x01,0x7F,0x4A,0x91,0x3F,0x08,0x04,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10, + 0x00,0x00,0xFE,0x22,0x14,0xF8,0x20,0x40,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xF1C0 [?] [7552]*/ + 0x02,0x01,0x7F,0x48,0x91,0x09,0x7F,0x05,0x19,0x61,0x04,0xFF,0x08,0x1E,0x03,0x3C, + 0x00,0x00,0xFE,0x22,0x14,0x20,0xFC,0x40,0x30,0x0C,0x00,0xFE,0x20,0x40,0xC0,0x38, + /* 0xF1C1 [?] [7553]*/ + 0x02,0x01,0x7F,0x48,0x90,0x06,0x38,0x28,0x2C,0x2A,0x2A,0x2A,0x28,0x55,0x5D,0x82, + 0x00,0x00,0xFE,0x22,0x14,0x1C,0xE8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA4,0x54,0x74,0x12, + /* 0xF1C2 [?] [7554]*/ + 0x20,0x10,0x00,0xFC,0x08,0x10,0x10,0x34,0x58,0x94,0x14,0x10,0x10,0x10,0x10,0x10, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xF1C3 [?] [7555]*/ + 0x20,0x13,0x01,0xF9,0x09,0x10,0x10,0x34,0x58,0x94,0x14,0x10,0x10,0x10,0x11,0x16, + 0x00,0xFC,0x04,0x44,0x24,0xA8,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xF1C4 [?] [7556]*/ + 0x20,0x10,0x00,0xFD,0x09,0x11,0x11,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xF1C5 [?] [7557]*/ + 0x20,0x10,0x01,0xFC,0x08,0x10,0x10,0x35,0x58,0x94,0x14,0x10,0x10,0x10,0x11,0x10, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00, + /* 0xF1C6 [?] [7558]*/ + 0x20,0x10,0x00,0xFC,0x08,0x11,0x12,0x34,0x58,0x95,0x14,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x50,0x50,0x88,0x44,0x22,0x20,0x00,0xFC,0x04,0x08,0x08,0x10,0x10,0x20, + /* 0xF1C7 [?] [7559]*/ + 0x20,0x10,0x00,0xF9,0x08,0x10,0x14,0x38,0x55,0x90,0x10,0x10,0x10,0x10,0x11,0x12, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF1C8 [?] [7560]*/ + 0x20,0x10,0x01,0xF8,0x08,0x10,0x15,0x38,0x54,0x90,0x13,0x10,0x10,0x10,0x10,0x10, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF1C9 [?] [7561]*/ + 0x20,0x11,0x00,0xFC,0x08,0x10,0x13,0x34,0x58,0x94,0x15,0x10,0x10,0x10,0x13,0x10, + 0x20,0x24,0xA4,0xA4,0xA8,0x20,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xF1CA [?] [7562]*/ + 0x20,0x10,0x00,0xF8,0x09,0x12,0x11,0x34,0x58,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF1CB [?] [7563]*/ + 0x20,0x10,0x00,0xF9,0x0B,0x14,0x10,0x34,0x59,0x96,0x15,0x11,0x11,0x11,0x11,0x11, + 0x80,0x80,0xF8,0x08,0x10,0xA0,0x40,0xA0,0x18,0x06,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xF1CC [?] [7564]*/ + 0x20,0x11,0x01,0xF9,0x09,0x11,0x11,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x44,0x48,0x30,0x20,0x10,0x48,0x86,0x00, + /* 0xF1CD [?] [7565]*/ + 0x20,0x12,0x01,0xF9,0x08,0x10,0x17,0x35,0x59,0x95,0x15,0x11,0x11,0x12,0x14,0x10, + 0x10,0x10,0x10,0x7E,0x20,0x28,0x48,0x7E,0x08,0x08,0xFE,0x08,0x08,0x88,0x7E,0x00, + /* 0xF1CE [?] [7566]*/ + 0x20,0x11,0x01,0xF9,0x09,0x11,0x10,0x34,0x59,0x94,0x14,0x11,0x10,0x10,0x13,0x10, + 0x00,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xF1CF [?] [7567]*/ + 0x20,0x10,0x00,0xF8,0x09,0x12,0x11,0x34,0x58,0x94,0x11,0x10,0x10,0x10,0x13,0x10, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x00,0x44,0x24,0x24,0xA8,0x88,0x10,0xFE,0x00, + /* 0xF1D0 [?] [7568]*/ + 0x21,0x10,0x02,0xF2,0x12,0x22,0x22,0x6A,0xB2,0x2A,0x22,0x22,0x22,0x22,0x22,0x22, + 0x00,0xBE,0x82,0x02,0x02,0xFA,0x8A,0x8A,0xFA,0x8A,0x8A,0xFA,0x02,0x02,0x0A,0x04, + /* 0xF1D1 [?] [7569]*/ + 0x20,0x10,0x03,0xF8,0x08,0x11,0x10,0x34,0x5B,0x94,0x14,0x11,0x12,0x14,0x10,0x10, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x40,0xA4,0xA8,0x90,0x88,0xC6,0x80, + /* 0xF1D2 [?] [7570]*/ + 0x20,0x10,0x01,0xF8,0x08,0x13,0x14,0x38,0x54,0x91,0x12,0x10,0x10,0x10,0x10,0x10, + 0x20,0x22,0xFA,0x24,0x28,0xFE,0x20,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xF1D3 [?] [7571]*/ + 0x20,0x11,0x01,0xF9,0x09,0x11,0x15,0x39,0x54,0x91,0x12,0x14,0x11,0x12,0x10,0x11, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x80,0xFC,0x54,0x94,0x24,0x44,0x94,0x08, + /* 0xF1D4 [?] [7572]*/ + 0x20,0x10,0x03,0xFA,0x0A,0x13,0x16,0x3A,0x57,0x90,0x11,0x17,0x10,0x10,0x10,0x10, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xF1D5 [?] [7573]*/ + 0x20,0x13,0x02,0xF2,0x13,0x22,0x22,0x6B,0xB2,0x2A,0x22,0x22,0x22,0x24,0x24,0x28, + 0x00,0xFC,0x04,0x04,0xFC,0x20,0x20,0xFE,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xF1D6 [?] [7574]*/ + 0x20,0x17,0x00,0xF2,0x11,0x22,0x24,0x68,0xB0,0x2F,0x20,0x22,0x21,0x22,0x24,0x28, + 0x00,0xBC,0x84,0x94,0x08,0x94,0xA4,0x40,0x00,0xBC,0xA4,0xA4,0x28,0x90,0xA8,0x46, + /* 0xF1D7 [?] [7575]*/ + 0x20,0x10,0x03,0xF8,0x08,0x10,0x14,0x39,0x56,0x90,0x10,0x11,0x11,0x11,0x11,0x11, + 0x88,0x88,0xFE,0x88,0x20,0x50,0x88,0x04,0xFA,0x00,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF1D8 [?] [7576]*/ + 0x20,0x10,0x03,0xF8,0x08,0x13,0x10,0x35,0x59,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x50,0x52,0xDC,0x50,0xD2,0x4E,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xF1D9 [?] [7577]*/ + 0x21,0x11,0x01,0xF2,0x12,0x26,0x2A,0x6A,0xB2,0x2A,0x22,0x22,0x22,0x23,0x22,0x22, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x10,0x10,0xFE,0x38,0x54,0x54,0x94,0x12,0x10,0x10, + /* 0xF1DA [?] [7578]*/ + 0x20,0x11,0x00,0xF0,0x13,0x20,0x21,0x6A,0xB0,0x2B,0x20,0x21,0x21,0x20,0x21,0x26, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xF1DB [?] [7579]*/ + 0x20,0x10,0x03,0xF2,0x12,0x23,0x22,0x6A,0xB3,0x2B,0x23,0x25,0x25,0x25,0x29,0x21, + 0x80,0x40,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x54,0x54,0xFC,0x54,0x54,0x44,0x0C, + /* 0xF1DC [?] [7580]*/ + 0x20,0x11,0x01,0xF9,0x09,0x11,0x11,0x34,0x58,0x95,0x15,0x11,0x11,0x11,0x17,0x10, + 0x48,0x48,0x4E,0x50,0x68,0x44,0x44,0x40,0x00,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xF1DD [?] [7581]*/ + 0x20,0x10,0x03,0xF2,0x12,0x22,0x22,0x6A,0xB2,0x2A,0x22,0x22,0x22,0x24,0x25,0x2A, + 0x04,0x1E,0xF0,0x1E,0x10,0xFE,0x92,0x98,0xF2,0x8E,0x80,0xB8,0xA8,0xAA,0x4A,0x86, + /* 0xF1DE [?] [7582]*/ + 0x20,0x13,0x00,0xFA,0x09,0x12,0x10,0x34,0x59,0x95,0x15,0x11,0x11,0x11,0x11,0x11, + 0x00,0xDE,0x42,0x52,0x4A,0x52,0x42,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF1DF [?] [7583]*/ + 0x20,0x13,0x00,0xF0,0x10,0x23,0x22,0x6A,0xB2,0x2B,0x20,0x20,0x20,0x20,0x25,0x22, + 0x00,0xBE,0xA2,0xA2,0xBE,0x88,0x08,0x3E,0x2A,0xAA,0xAA,0xBE,0x88,0x8A,0x7E,0x02, + /* 0xF1E0 [?] [7584]*/ + 0x20,0x11,0x00,0xFB,0x0A,0x11,0x14,0x39,0x54,0x93,0x10,0x11,0x11,0x11,0x11,0x11, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFE,0x20,0xFC,0x54,0x54,0x54,0x0C, + /* 0xF1E1 [?] [7585]*/ + 0x22,0x12,0x07,0xF2,0x17,0x2A,0x22,0x6F,0xB2,0x2D,0x28,0x23,0x20,0x27,0x20,0x20, + 0xA8,0x48,0xBE,0xA8,0x5C,0xAA,0x88,0xFE,0x18,0xE4,0x42,0xF8,0x40,0xFC,0x40,0xC0, + /* 0xF1E2 [?] [7586]*/ + 0x00,0x00,0x7F,0x01,0x01,0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x29,0x25,0x43,0x80, + 0x00,0x00,0xFC,0x04,0x08,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xF1E3 [?] [7587]*/ + 0x7F,0x01,0x11,0x11,0x11,0x29,0x47,0x80,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10, + 0xFC,0x04,0x00,0xF8,0x00,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x50,0x20, + /* 0xF1E4 [?] [7588]*/ + 0x00,0xFF,0x91,0x10,0xFE,0x20,0x28,0x48,0x7E,0x08,0x08,0x0E,0xF8,0x49,0x09,0x0A, + 0x10,0x10,0x10,0xFE,0x92,0x94,0x90,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0x28,0x44,0x82, + /* 0xF1E5 [?] [7589]*/ + 0x10,0x10,0x20,0x44,0xFE,0x28,0x44,0xA2,0x3C,0x44,0x44,0xA8,0x10,0x29,0x45,0x82, + 0x10,0x10,0x10,0xFE,0x92,0x94,0x90,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0x28,0x44,0x82, + /* 0xF1E6 [?] [7590]*/ + 0x00,0x7E,0x02,0x24,0x18,0x09,0xFE,0x0A,0x18,0x19,0x28,0x48,0x88,0x08,0x28,0x10, + 0x20,0x20,0x50,0x50,0x88,0x44,0x22,0x20,0x00,0xFC,0x04,0x08,0x08,0x10,0x10,0x20, + /* 0xF1E7 [?] [7591]*/ + 0x01,0x01,0x7F,0x01,0x01,0x3F,0x01,0x01,0xFF,0x03,0x05,0x09,0x31,0xC1,0x01,0x01, + 0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x80,0x40,0x20,0x18,0x06,0x00,0x00, + /* 0xF1E8 [?] [7592]*/ + 0x10,0x10,0x10,0xFC,0x10,0x78,0x10,0xFD,0x10,0x38,0x34,0x54,0x90,0x10,0x10,0x10, + 0x00,0xFC,0x04,0x08,0x08,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xF1E9 [?] [7593]*/ + 0x10,0x10,0x10,0xFC,0x10,0x78,0x11,0xFD,0x12,0x38,0x34,0x54,0x90,0x10,0x10,0x13, + 0x20,0x20,0x20,0xA8,0xA4,0xA2,0x22,0x20,0x24,0x24,0x28,0x08,0x10,0x20,0xC0,0x00, + /* 0xF1EA [?] [7594]*/ + 0x10,0x11,0x11,0xFD,0x11,0x79,0x11,0xFD,0x11,0x39,0x35,0x55,0x91,0x11,0x11,0x11, + 0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF1EB [?] [7595]*/ + 0x10,0x10,0x10,0xFC,0x11,0x7A,0x11,0xFC,0x10,0x39,0x35,0x55,0x91,0x11,0x11,0x11, + 0x20,0x20,0x50,0x88,0x04,0x02,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF1EC [?] [7596]*/ + 0x10,0x10,0x13,0xFC,0x10,0x7B,0x12,0xFC,0x10,0x3B,0x34,0x54,0x90,0x11,0x12,0x14, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x44,0x40,0xFC,0x44,0x84,0x84,0x04,0x28,0x10, + /* 0xF1ED [?] [7597]*/ + 0x10,0x11,0x10,0xFC,0x10,0x7B,0x12,0xFE,0x12,0x3A,0x36,0x52,0x52,0x92,0x12,0x12, + 0x20,0x24,0xA4,0xA8,0x20,0xFE,0x02,0x02,0xFA,0x8A,0x8A,0x8A,0xFA,0x02,0x0A,0x04, + /* 0xF1EE [?] [7598]*/ + 0x11,0x11,0x11,0xFD,0x11,0x79,0x11,0xFC,0x10,0x3B,0x36,0x52,0x52,0x92,0x12,0x12, + 0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x22,0x2A,0xFA,0x0A,0x02,0x06, + /* 0xF1EF [?] [7599]*/ + 0x10,0x11,0x10,0xFC,0x13,0x78,0x11,0xFE,0x10,0x3B,0x34,0x51,0x51,0x90,0x11,0x16, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xF1F0 [?] [7600]*/ + 0x10,0x10,0x13,0xFC,0x11,0x78,0x13,0xFC,0x11,0x39,0x35,0x51,0x53,0x91,0x11,0x11, + 0x88,0x88,0xFE,0x88,0xFC,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFE,0x04,0x14,0x08, + /* 0xF1F1 [?] [7601]*/ + 0x10,0x11,0x11,0xFD,0x11,0x79,0x11,0xFD,0x11,0x39,0x35,0x51,0x51,0x92,0x12,0x14, + 0x00,0xFE,0x00,0x7E,0x00,0xFE,0x54,0x48,0x64,0x42,0x08,0xFE,0x48,0x28,0x08,0x18, + /* 0xF1F2 [?] [7602]*/ + 0x10,0x10,0x13,0xFE,0x13,0x7A,0x12,0xFF,0x12,0x3B,0x36,0x52,0x52,0x93,0x14,0x18, + 0x40,0x20,0xFE,0x48,0xFE,0x48,0xEC,0x5A,0x48,0xFE,0x20,0x7C,0xC4,0x44,0x7C,0x44, + /* 0xF1F3 [?] [7603]*/ + 0x02,0x3F,0x02,0xFF,0x02,0x0F,0x34,0xC3,0x00,0x7F,0x08,0x1F,0x01,0x1F,0x01,0x7F, + 0x20,0xC0,0x80,0xFE,0x20,0xC0,0x08,0xF8,0x00,0xFC,0x20,0xF0,0x00,0xF0,0x00,0xFC, + /* 0xF1F4 [?] [7604]*/ + 0x00,0xFF,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0x27,0xFA,0x42,0x02,0x02,0x02, + 0x00,0x80,0x7E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x08,0x08,0x08,0x28,0x10, + /* 0xF1F5 [?] [7605]*/ + 0x00,0xFF,0x24,0x25,0x3D,0x25,0x25,0x3D,0x25,0x25,0x2F,0xF5,0x45,0x05,0x05,0x05, + 0x20,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0xFE,0x04,0x04,0x04,0x14,0x08, + /* 0xF1F6 [?] [7606]*/ + 0x00,0xFF,0x24,0x24,0x3C,0x25,0x26,0x3C,0x25,0x24,0x2E,0xF4,0x44,0x04,0x04,0x04, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xF1F7 [?] [7607]*/ + 0x00,0xFC,0x48,0x4B,0x7A,0x4C,0x48,0x78,0x4B,0x48,0x4C,0x78,0xC8,0x08,0x08,0x08, + 0x40,0x20,0x20,0xFE,0x02,0x04,0x00,0x00,0xFE,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + /* 0xF1F8 [?] [7608]*/ + 0x00,0xFF,0x24,0x24,0x3C,0x25,0x24,0x3C,0x24,0x24,0x2E,0xF4,0x44,0x04,0x04,0x04, + 0x08,0x1C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF1F9 [?] [7609]*/ + 0x00,0xFC,0x49,0x49,0x79,0x48,0x4B,0x78,0x49,0x49,0x4D,0x79,0xC9,0x08,0x08,0x0B, + 0x20,0x20,0xFC,0x24,0xFC,0x20,0xFE,0x00,0xFC,0x04,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xF1FA [?] [7610]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x10,0x1E,0x22,0x7F,0x88,0x0F,0x08,0xFF,0x00,0x00, + 0x20,0x20,0x7E,0x44,0xA4,0x28,0x10,0x28,0x44,0xFE,0x20,0xE0,0x3E,0xE0,0x20,0x20, + /* 0xF1FB [?] [7611]*/ + 0xFF,0x04,0x3F,0x24,0x3F,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x01,0x01,0x01, + 0xFE,0x40,0xF8,0x48,0xF8,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0x00,0x00, + /* 0xF1FC [?] [7612]*/ + 0x00,0x79,0x10,0x10,0x11,0x11,0x11,0xFD,0x11,0x11,0x11,0x11,0x10,0x10,0x11,0x12, + 0x00,0xFE,0x20,0x40,0xFC,0x04,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x04,0x02, + /* 0xF1FD [?] [7613]*/ + 0x08,0x1C,0x60,0x40,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x0B, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF1FE [?] [7614]*/ + 0x10,0x08,0x08,0xFF,0x00,0x00,0x3C,0x24,0x24,0x24,0x24,0x25,0x46,0x44,0x80,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF2A1 [?] [7615]*/ + 0x10,0x10,0x10,0xFE,0x10,0x10,0x7C,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF2A2 [?] [7616]*/ + 0x10,0x10,0x28,0x24,0x42,0x80,0x7C,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF2A3 [?] [7617]*/ + 0x20,0x24,0x38,0x22,0x22,0x1E,0x00,0x08,0x0A,0xEC,0x28,0x2C,0x4A,0x4A,0xA8,0x13, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF2A4 [?] [7618]*/ + 0x10,0x08,0x08,0xFF,0x08,0x10,0x22,0x7C,0x09,0x12,0x24,0xC8,0x14,0x22,0xC0,0x03, + 0x00,0xFE,0x20,0x40,0xFC,0x84,0x94,0x94,0x94,0x94,0x94,0xA4,0x30,0x48,0x84,0x02, + /* 0xF2A5 [?] [7619]*/ + 0x08,0x08,0x14,0x22,0x51,0x88,0x7E,0x02,0x04,0x08,0x7E,0x42,0x42,0x7E,0x42,0x00, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xF2A6 [?] [7620]*/ + 0x00,0xEE,0xAA,0xAA,0xEE,0x00,0xFE,0x00,0xFF,0x40,0x7E,0x02,0x02,0x02,0x14,0x08, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xF2A7 [?] [7621]*/ + 0x08,0x49,0x49,0x49,0x7F,0x00,0xFF,0x08,0x10,0x7F,0x55,0x55,0x55,0x55,0x55,0x43, + 0x00,0x7E,0x10,0x20,0x7C,0x44,0xD4,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xF2A8 [?] [7622]*/ + 0x00,0x7F,0x22,0x3E,0x22,0x3E,0x23,0xFE,0x02,0xF7,0x11,0x55,0x22,0x55,0x89,0x10, + 0x00,0x7E,0x10,0x20,0x7C,0x44,0xD4,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xF2A9 [?] [7623]*/ + 0x24,0x24,0xFF,0x24,0x00,0xFF,0x24,0x24,0xFF,0xA5,0xA5,0xDB,0x91,0x81,0x85,0x82, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xF2AA [?] [7624]*/ + 0x00,0x7E,0x22,0x1C,0x22,0x77,0x55,0x22,0x55,0x08,0x7F,0x1C,0x2A,0x49,0x88,0x08, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x24,0x42,0x82, + /* 0xF2AB [?] [7625]*/ + 0x00,0x7F,0x41,0x7F,0x41,0x7F,0x08,0xFF,0x00,0x7F,0x41,0x7F,0x08,0x49,0x88,0x18, + 0x00,0x7E,0x10,0x20,0x7C,0x44,0x54,0xD4,0x54,0x54,0x54,0x54,0x20,0x28,0xC4,0x82, + /* 0xF2AC [?] [7626]*/ + 0x00,0x7F,0x08,0xFF,0x88,0x6B,0x08,0x6B,0x00,0xFF,0x08,0x7F,0x55,0x55,0x55,0x43, + 0x00,0x7E,0x10,0xA0,0xFC,0x44,0x54,0x54,0x54,0xD4,0x54,0x54,0x20,0x28,0x44,0x82, + /* 0xF2AD [?] [7627]*/ + 0x08,0x2E,0x28,0xFF,0x2A,0x4C,0x32,0xC4,0x3F,0x21,0x3F,0x22,0x3F,0x08,0xFF,0x00, + 0x00,0xFE,0x20,0x7C,0x54,0x54,0x28,0x44,0xF8,0x08,0xF8,0x08,0xF8,0x80,0xFE,0x80, + /* 0xF2AE [?] [7628]*/ + 0x01,0x01,0x01,0x01,0x01,0x3F,0x20,0x21,0x21,0x21,0x21,0x2F,0x21,0x41,0x40,0x80, + 0x00,0x00,0xF8,0x00,0x00,0xFC,0x04,0x08,0x00,0x18,0xE0,0x00,0x04,0x04,0xFC,0x00, + /* 0xF2AF [?] [7629]*/ + 0x01,0x01,0x01,0x3F,0x21,0x21,0x2F,0x20,0x21,0x20,0x2F,0x22,0x21,0x40,0x43,0x8C, + 0x00,0xF8,0x00,0xFE,0x02,0xF0,0x04,0xFC,0x00,0x80,0xF8,0x20,0x40,0x80,0x60,0x1C, + /* 0xF2B0 [?] [7630]*/ + 0x08,0x08,0x08,0x7F,0x49,0x49,0x49,0x49,0x7F,0x48,0x08,0x0A,0x0F,0xF1,0x40,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x3C,0x00, + /* 0xF2B1 [?] [7631]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1C,0xE5,0x41,0x02, + 0x00,0x00,0xF0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x92,0x12,0x0E,0x00, + /* 0xF2B2 [?] [7632]*/ + 0x00,0xFF,0x04,0x07,0x08,0x10,0x20,0x41,0x3F,0x21,0x21,0x3F,0x01,0x01,0x7F,0x20, + 0x00,0xFE,0x00,0xF0,0x10,0x10,0xA0,0x40,0xF8,0x08,0x08,0xF8,0x00,0x08,0xFC,0x04, + /* 0xF2B3 [?] [7633]*/ + 0x00,0x00,0xFE,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x25,0x24,0x44,0x43,0x80, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0xFC,0x20,0x20,0x28,0xFC,0x04,0x02,0xFE,0x00, + /* 0xF2B4 [?] [7634]*/ + 0x10,0x10,0x10,0x7C,0x55,0x56,0x54,0x54,0x7C,0x50,0x10,0x14,0x1D,0xE5,0x40,0x00, + 0x40,0x40,0x80,0xFE,0x00,0x00,0xFC,0x08,0x10,0x20,0x40,0x80,0x02,0x02,0xFE,0x00, + /* 0xF2B5 [?] [7635]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x20,0x10,0x10,0x00,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFC,0x00, + /* 0xF2B6 [?] [7636]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x54,0x7D,0x50,0x10,0x14,0x1E,0xE2,0x41,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF2B7 [?] [7637]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x00, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xF2B8 [?] [7638]*/ + 0x10,0x10,0x10,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x20,0x20,0xFE,0x22,0x22,0x22,0x22,0x52,0x4A,0x8A,0x02,0x02,0x02,0x0A,0x04, + /* 0xF2B9 [?] [7639]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x10,0x14,0x1C,0xE5,0x42,0x04, + 0x00,0xFC,0x04,0x04,0x24,0x24,0x24,0x24,0x24,0x54,0x50,0x90,0x90,0x12,0x12,0x0E, + /* 0xF2BA [?] [7640]*/ + 0x10,0x10,0x11,0x7C,0x54,0x54,0x55,0x54,0x7C,0x50,0x13,0x14,0x1E,0xE2,0x40,0x00, + 0x08,0x3C,0xE0,0x20,0x20,0x3C,0xE0,0x20,0x20,0x3E,0xE0,0x20,0x22,0x22,0x22,0x1E, + /* 0xF2BB [?] [7641]*/ + 0x10,0x10,0x10,0x7C,0x54,0x55,0x56,0x54,0x7C,0x50,0x10,0x14,0x1C,0xE5,0x41,0x02, + 0x20,0x20,0x50,0x50,0x88,0x04,0x02,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xF2BC [?] [7642]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x55,0x7C,0x50,0x10,0x14,0x1C,0xE5,0x40,0x00, + 0x08,0x48,0x48,0x48,0x44,0x84,0xA4,0x22,0x20,0x40,0x40,0x48,0x84,0xFE,0x82,0x00, + /* 0xF2BD [?] [7643]*/ + 0x10,0x11,0x10,0x7C,0x54,0x55,0x54,0x54,0x7C,0x50,0x13,0x14,0x1E,0xE2,0x40,0x00, + 0x10,0x10,0x90,0x90,0x10,0x10,0x90,0x90,0x10,0x1E,0xF0,0x10,0x10,0x10,0x10,0x10, + /* 0xF2BE [?] [7644]*/ + 0x10,0x11,0x10,0x7C,0x54,0x55,0x55,0x55,0x7D,0x51,0x10,0x14,0x1C,0xE4,0x41,0x00, + 0x04,0xE4,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0xE4,0x24,0x24,0x24,0x24,0x44,0x84, + /* 0xF2BF [?] [7645]*/ + 0x01,0x21,0x21,0x3F,0x01,0xFF,0x00,0x01,0x3F,0x21,0x21,0x3F,0x01,0x01,0x7F,0x20, + 0x00,0x08,0x08,0xF8,0x00,0xFE,0x00,0x00,0xF8,0x08,0x08,0xF8,0x00,0x08,0xFC,0x04, + /* 0xF2C0 [?] [7646]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x88,0x88,0x88,0x88,0xFE,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xF2C1 [?] [7647]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x54,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF2C2 [?] [7648]*/ + 0x10,0x10,0x13,0x7C,0x54,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1C,0xE4,0x40,0x00, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xF2C3 [?] [7649]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE6,0x42,0x04, + 0x00,0xFE,0x00,0x00,0x00,0xFE,0x20,0x20,0x3C,0x24,0x24,0x24,0x24,0x44,0x54,0x88, + /* 0xF2C4 [?] [7650]*/ + 0x10,0x10,0x10,0x7C,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xF2C5 [?] [7651]*/ + 0x10,0x10,0x10,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x17,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0x24,0xFE,0x04,0x04,0x04,0x14,0x08, + /* 0xF2C6 [?] [7652]*/ + 0x10,0x10,0x10,0x7C,0x55,0x55,0x56,0x54,0x7C,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xF2C7 [?] [7653]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x14,0x1C,0xE4,0x43,0x00, + 0x04,0x0E,0xF0,0x80,0x80,0x80,0x80,0xFE,0x88,0x88,0x88,0x88,0x88,0x88,0xFE,0x00, + /* 0xF2C8 [?] [7654]*/ + 0x10,0x10,0x10,0x7C,0x54,0x55,0x56,0x54,0x7D,0x50,0x10,0x14,0x1E,0xE2,0x40,0x00, + 0x20,0x20,0x50,0x50,0x88,0x24,0x12,0x10,0xFC,0x04,0x08,0x88,0x50,0x20,0x10,0x10, + /* 0xF2C9 [?] [7655]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x54,0x54,0x7F,0x50,0x11,0x14,0x1C,0xE4,0x43,0x00, + 0x00,0xFC,0x84,0x88,0x50,0x20,0x50,0x88,0x26,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xF2CA [?] [7656]*/ + 0x20,0x20,0x20,0xF9,0xA9,0xAA,0xAB,0xA8,0xF9,0xA1,0x22,0x2B,0x38,0xE8,0x40,0x00, + 0x10,0x90,0x90,0x10,0x7E,0x52,0x92,0x92,0x12,0x12,0x52,0xD2,0x62,0x22,0x4A,0x84, + /* 0xF2CB [?] [7657]*/ + 0x00,0x7D,0x11,0x11,0x11,0x1D,0xE2,0x45,0x1F,0x11,0x11,0x1F,0x11,0x01,0x7F,0x20, + 0x00,0xF0,0x10,0x90,0x52,0x12,0x0E,0x00,0xF0,0x10,0x10,0xF0,0x00,0x08,0xFC,0x04, + /* 0xF2CC [?] [7658]*/ + 0x10,0x10,0x10,0x7D,0x54,0x55,0x54,0x54,0x7C,0x53,0x10,0x14,0x1E,0xE2,0x41,0x02, + 0x20,0x20,0x20,0xFC,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF2CD [?] [7659]*/ + 0x20,0x20,0x20,0xFB,0xA8,0xA8,0xA8,0xAB,0xF8,0xA3,0x20,0x28,0x39,0xE9,0x42,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xF2CE [?] [7660]*/ + 0x10,0x11,0x10,0x7C,0x54,0x55,0x55,0x54,0x7C,0x50,0x11,0x14,0x1C,0xE4,0x43,0x00, + 0x00,0xFE,0x20,0x40,0x88,0x04,0xFE,0x22,0x20,0x20,0xFE,0x20,0x20,0x20,0xFE,0x00, + /* 0xF2CF [?] [7661]*/ + 0x20,0x20,0x20,0xFA,0xAA,0xAA,0xAA,0xAA,0xFA,0xA2,0x22,0x28,0x39,0xE9,0x42,0x04, + 0x80,0xBE,0x88,0x88,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x2E,0x08,0x08,0x08, + /* 0xF2D0 [?] [7662]*/ + 0x10,0x10,0x10,0x7C,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x50,0x50,0x50,0x50,0xFC,0x54,0x54,0x54,0x54,0xFC,0x54,0x54,0x54,0x54,0xFC,0x04, + /* 0xF2D1 [?] [7663]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xA9,0xA9,0xAB,0xF8,0xA2,0x22,0x29,0x39,0xEA,0x44,0x08, + 0x00,0x06,0xB8,0x88,0x88,0x08,0x3E,0x88,0x88,0x88,0x88,0x3E,0x00,0x80,0x7E,0x00, + /* 0xF2D2 [?] [7664]*/ + 0x10,0x10,0x11,0x7C,0x54,0x57,0x54,0x54,0x7C,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x08,0x3C,0xE0,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF2D3 [?] [7665]*/ + 0x10,0x10,0x13,0x7C,0x54,0x54,0x54,0x54,0x7D,0x50,0x10,0x14,0x1C,0xE5,0x41,0x02, + 0x40,0x20,0xFE,0x88,0x50,0x20,0x50,0x88,0x06,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xF2D4 [?] [7666]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x55,0x56,0x7C,0x50,0x10,0x14,0x1C,0xE4,0x40,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xF2D5 [?] [7667]*/ + 0x11,0x10,0x10,0x7C,0x57,0x54,0x54,0x55,0x7C,0x50,0x13,0x14,0x1E,0xE2,0x40,0x00, + 0x04,0x84,0x88,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF2D6 [?] [7668]*/ + 0x10,0x10,0x10,0x7C,0x55,0x54,0x54,0x54,0x7C,0x51,0x10,0x17,0x1C,0xE4,0x40,0x00, + 0x20,0x20,0x48,0x84,0xFE,0x12,0x90,0x90,0xFE,0x10,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xF2D7 [?] [7669]*/ + 0x3F,0x20,0x2F,0x20,0x3F,0x24,0x24,0x26,0x20,0x2F,0x28,0x48,0x4F,0x80,0x1F,0x08, + 0xFC,0x00,0xF8,0x00,0xFC,0x48,0x30,0x0E,0x80,0xF8,0x88,0x88,0xF8,0x84,0xFE,0x02, + /* 0xF2D8 [?] [7670]*/ + 0x08,0x08,0x7E,0x08,0x0E,0x78,0x08,0x29,0x12,0x01,0x3F,0x21,0x3F,0x01,0x7F,0x00, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0x00,0xF8,0x08,0xF8,0x08,0xFC,0x04, + /* 0xF2D9 [?] [7671]*/ + 0x10,0x11,0x10,0x7C,0x54,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xF2DA [?] [7672]*/ + 0x10,0x11,0x11,0x7D,0x55,0x54,0x54,0x55,0x7C,0x50,0x13,0x14,0x1C,0xE4,0x41,0x02, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,0x20,0x20,0xFE,0x20,0x50,0x88,0x04,0x02, + /* 0xF2DB [?] [7673]*/ + 0x20,0x21,0x27,0xF9,0xA9,0xA9,0xAF,0xA9,0xFB,0xA3,0x25,0x2D,0x39,0xE9,0x41,0x01, + 0x84,0xC4,0x04,0x14,0x14,0x14,0xD4,0x14,0x14,0x94,0x54,0x04,0x04,0x04,0x14,0x08, + /* 0xF2DC [?] [7674]*/ + 0x10,0x10,0x10,0x7C,0x55,0x56,0x54,0x54,0x7C,0x53,0x10,0x15,0x1D,0xE6,0x40,0x00, + 0x20,0x20,0x50,0x88,0x04,0x02,0xF8,0x20,0x20,0xFE,0x20,0x24,0x22,0x22,0xA0,0x40, + /* 0xF2DD [?] [7675]*/ + 0x10,0x10,0x11,0x7C,0x55,0x54,0x54,0x55,0x7C,0x50,0x13,0x14,0x1E,0xE2,0x40,0x00, + 0x08,0x3C,0xC0,0x04,0x44,0xA8,0x00,0xF8,0x10,0x20,0xFE,0x20,0x20,0x20,0xA0,0x40, + /* 0xF2DE [?] [7676]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x55,0x54,0x7C,0x53,0x10,0x14,0x1C,0xE4,0x41,0x02, + 0x88,0x48,0x50,0xFC,0x20,0x20,0xFC,0x20,0x20,0xFE,0x50,0x50,0x90,0x92,0x12,0x0E, + /* 0xF2DF [?] [7677]*/ + 0x10,0x10,0x13,0x7C,0x55,0x54,0x57,0x54,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xF2E0 [?] [7678]*/ + 0x10,0x10,0x11,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x10,0x15,0x1C,0xE4,0x41,0x02, + 0x88,0x88,0xFC,0x88,0x88,0xF8,0x88,0x88,0xF8,0x88,0x88,0xFE,0x00,0x88,0x04,0x02, + /* 0xF2E1 [?] [7679]*/ + 0x21,0x21,0x21,0xF9,0xAF,0xA9,0xA9,0xAB,0xFB,0xA5,0x25,0x29,0x39,0xE9,0x41,0x01, + 0x00,0x06,0x38,0x20,0xA0,0x20,0x3E,0x24,0xA4,0x64,0x24,0x24,0x24,0x24,0x24,0x44, + /* 0xF2E2 [?] [7680]*/ + 0x20,0x20,0x20,0xFB,0xA8,0xA8,0xAB,0xAA,0xFA,0xA2,0x23,0x28,0x38,0xEB,0x41,0x00, + 0x14,0x12,0x10,0xFE,0x10,0x10,0xD2,0x52,0x52,0x54,0xD4,0x0C,0x6A,0x8A,0x16,0x22, + /* 0xF2E3 [?] [7681]*/ + 0x04,0x04,0x7C,0x04,0x3C,0x04,0x7C,0x04,0x01,0x1F,0x11,0x11,0x1F,0x01,0x7F,0x20, + 0x40,0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x00,0xF0,0x10,0x10,0xF0,0x08,0xFC,0x04, + /* 0xF2E4 [?] [7682]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7C,0x53,0x10,0x14,0x1D,0xE6,0x40,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xF2E5 [?] [7683]*/ + 0x20,0x23,0x22,0xFA,0xAB,0xAA,0xAA,0xAA,0xFA,0xA2,0x22,0x2B,0x3A,0xEA,0x43,0x02, + 0x00,0xFE,0x02,0x02,0xFE,0x22,0x22,0xFA,0x22,0x32,0x2A,0xFE,0x02,0x02,0xFE,0x02, + /* 0xF2E6 [?] [7684]*/ + 0x10,0x10,0x10,0x7C,0x54,0x54,0x54,0x54,0x7C,0x50,0x11,0x14,0x1C,0xE5,0x40,0x00, + 0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x40,0xFE,0x2A,0x4A,0x92,0x22,0x4A,0x84, + /* 0xF2E7 [?] [7685]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x50,0x11,0x17,0x1C,0xE4,0x40,0x00, + 0x40,0x80,0xFC,0x24,0x24,0xFC,0x24,0x44,0xFC,0x90,0x10,0xFE,0x10,0x10,0x10,0x10, + /* 0xF2E8 [?] [7686]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE6,0x42,0x04, + 0x00,0xFC,0x24,0x24,0x74,0x24,0xFC,0x04,0x74,0x54,0x54,0x74,0x04,0x04,0x14,0x08, + /* 0xF2E9 [?] [7687]*/ + 0x10,0x11,0x10,0x7C,0x55,0x54,0x57,0x54,0x7D,0x52,0x14,0x14,0x1C,0xE4,0x40,0x00, + 0x20,0x24,0xA8,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x88,0x88,0xA8,0x92,0x82,0x7E, + /* 0xF2EA [?] [7688]*/ + 0x20,0x20,0x23,0xFA,0xAD,0xA9,0xA9,0xAA,0xFA,0xA3,0x24,0x28,0x39,0xE9,0x42,0x04, + 0x40,0x20,0xFE,0x02,0x04,0x00,0xDE,0x52,0x52,0x52,0x9A,0x94,0x10,0x12,0x12,0x0E, + /* 0xF2EB [?] [7689]*/ + 0x21,0x20,0x23,0xFA,0xAA,0xAB,0xAA,0xAA,0xFB,0xA2,0x22,0x2A,0x3A,0xEB,0x42,0x00, + 0x00,0x9E,0xD2,0x52,0x54,0xD4,0x58,0x54,0xD2,0x12,0x92,0x5A,0xD4,0x50,0x10,0x10, + /* 0xF2EC [?] [7690]*/ + 0x10,0x11,0x10,0x7C,0x54,0x57,0x54,0x54,0x7C,0x51,0x11,0x15,0x1D,0xE5,0x43,0x00, + 0x00,0xFC,0x08,0x10,0x20,0xFE,0x20,0xA0,0x40,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xF2ED [?] [7691]*/ + 0x10,0x10,0x13,0x7C,0x55,0x54,0x57,0x54,0x7D,0x52,0x10,0x14,0x1C,0xE4,0x40,0x00, + 0x20,0x20,0xFE,0x20,0xFC,0x40,0xFE,0x88,0x04,0xFA,0x88,0x88,0xF8,0x88,0x88,0xF8, + /* 0xF2EE [?] [7692]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xAB,0xAA,0xAC,0xF8,0xA3,0x20,0x28,0x38,0xE9,0x42,0x00, + 0x88,0x88,0xFE,0x88,0x00,0xFE,0x02,0x24,0x20,0xFE,0x70,0xA8,0xA8,0x24,0x22,0x20, + /* 0xF2EF [?] [7693]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xAB,0xAA,0xAA,0xFA,0xA2,0x22,0x2A,0x3A,0xEA,0x42,0x02, + 0x20,0x20,0xFE,0x20,0x20,0xFE,0x8A,0x52,0xFA,0x22,0x22,0xFA,0x22,0x22,0x2A,0x04, + /* 0xF2F0 [?] [7694]*/ + 0x10,0x11,0x10,0x7C,0x54,0x54,0x54,0x54,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x00,0xFE,0x00,0xFC,0x84,0x84,0xFC,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xF2F1 [?] [7695]*/ + 0x10,0x10,0x13,0x7C,0x54,0x57,0x55,0x54,0x7C,0x53,0x10,0x14,0x1D,0xE4,0x40,0x03, + 0x20,0x20,0xFE,0x50,0x88,0x26,0xFC,0x20,0x20,0xFE,0x00,0x20,0xFC,0x20,0x20,0xFE, + /* 0xF2F2 [?] [7696]*/ + 0x20,0x27,0x21,0xF9,0xA9,0xAF,0xA9,0xA9,0xFB,0xA3,0x25,0x2D,0x39,0xE9,0x41,0x01, + 0xC4,0x04,0x24,0x14,0x14,0x84,0x24,0x14,0x94,0x46,0x3C,0x04,0x04,0x04,0x04,0x04, + /* 0xF2F3 [?] [7697]*/ + 0x10,0x10,0x10,0x7C,0x55,0x56,0x54,0x54,0x7C,0x50,0x10,0x14,0x1D,0xE4,0x40,0x01, + 0x40,0x40,0xFE,0x80,0xFC,0x84,0xFC,0x84,0xFC,0x40,0x7C,0xC4,0x28,0x10,0x68,0x86, + /* 0xF2F4 [?] [7698]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7C,0x51,0x10,0x14,0x1E,0xE2,0x40,0x03, + 0xA0,0x2C,0x24,0x24,0xAC,0x24,0x24,0xFC,0x20,0xFC,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xF2F5 [?] [7699]*/ + 0x20,0x20,0x21,0xFA,0xAD,0xA8,0xAB,0xAA,0xFA,0xA3,0x22,0x2A,0x3B,0xEA,0x42,0x02, + 0x40,0xA0,0x10,0x08,0xF6,0x00,0xC4,0x54,0x54,0xD4,0x54,0x54,0xD4,0x44,0x54,0xC8, + /* 0xF2F6 [?] [7700]*/ + 0x21,0x20,0x20,0xFB,0xA9,0xA9,0xA9,0xA9,0xF9,0xA1,0x21,0x29,0x3A,0xEA,0x44,0x08, + 0x08,0x88,0x88,0xDE,0x10,0x20,0xDE,0x42,0x44,0x44,0x5E,0x44,0x44,0x44,0xD4,0x08, + /* 0xF2F7 [?] [7701]*/ + 0x20,0x21,0x20,0xF8,0xAB,0xA8,0xA9,0xAA,0xF8,0xA7,0x20,0x29,0x39,0xE8,0x41,0x06, + 0x20,0x24,0xA8,0x20,0xFE,0xA8,0x24,0x02,0x40,0xFE,0x88,0x08,0x90,0x60,0x98,0x04, + /* 0xF2F8 [?] [7702]*/ + 0x10,0x10,0x10,0x7D,0x54,0x54,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x88,0x48,0x50,0xFE,0x50,0x50,0xFC,0x54,0x54,0x8C,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF2F9 [?] [7703]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x12,0x14,0x1C,0xE4,0x40,0x00, + 0x20,0x10,0xFE,0x02,0x02,0xFE,0x00,0x00,0xFE,0xAA,0xAA,0xFE,0xAA,0xAA,0xAA,0x86, + /* 0xF2FA [?] [7704]*/ + 0x00,0x7E,0x24,0x18,0xFF,0x29,0x4A,0x98,0x01,0x1F,0x11,0x11,0x1F,0x01,0x7F,0x20, + 0x20,0x20,0x7E,0xA4,0x28,0x10,0x28,0xC6,0x00,0xF0,0x10,0x10,0xF0,0x08,0xFC,0x04, + /* 0xF2FB [?] [7705]*/ + 0x20,0x20,0x27,0xF8,0xAB,0xA8,0xAF,0xA9,0xFA,0xA5,0x20,0x2B,0x38,0xE9,0x46,0x00, + 0x40,0x40,0xFC,0x40,0xF8,0x80,0xFC,0x10,0x68,0xC6,0x40,0xF8,0xE0,0x58,0x44,0x40, + /* 0xF2FC [?] [7706]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x10,0x1E,0x22,0x46,0x81,0x3F,0x21,0x3F,0x01,0x7F, + 0x20,0x20,0x7E,0x44,0xA4,0x28,0x10,0x28,0x44,0x82,0x00,0xF8,0x08,0xF8,0x04,0xFE, + /* 0xF2FD [?] [7707]*/ + 0x10,0x10,0x11,0x7C,0x54,0x55,0x54,0x54,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x01, + 0x48,0x48,0xFE,0x48,0x00,0xFE,0x48,0x48,0xFE,0x4A,0x4A,0xB6,0x22,0x02,0x0A,0x04, + /* 0xF2FE [?] [7708]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xAB,0xA8,0xA8,0xF9,0xA2,0x20,0x2B,0x38,0xE8,0x41,0x02, + 0x88,0x88,0xFE,0x88,0x24,0xFE,0x50,0x88,0x04,0x8A,0x88,0xFE,0x88,0x88,0x08,0x08, + /* 0xF3A1 [?] [7709]*/ + 0x10,0x10,0x13,0x7C,0x54,0x55,0x55,0x55,0x7D,0x51,0x10,0x17,0x1C,0xE4,0x41,0x02, + 0x88,0x88,0xFE,0x88,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xF3A2 [?] [7710]*/ + 0x10,0x11,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1F,0xE2,0x42,0x04, + 0x00,0xFE,0x10,0x20,0x7C,0x44,0x7C,0x44,0x7C,0x10,0x10,0x54,0x52,0x92,0x50,0x20, + /* 0xF3A3 [?] [7711]*/ + 0x20,0x20,0x21,0xF9,0xA9,0xA9,0xA9,0xA9,0xF9,0xA0,0x20,0x28,0x3A,0xEA,0x44,0x00, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x04,0xFC,0x40,0x20,0xA4,0x8A,0x8A,0x78,0x00, + /* 0xF3A4 [?] [7712]*/ + 0x20,0x20,0x23,0xF8,0xA9,0xA9,0xA9,0xA9,0xF8,0xA3,0x22,0x2A,0x3A,0xEA,0x42,0x02, + 0x40,0x20,0xFE,0x00,0x54,0x24,0x54,0xFC,0x20,0xFE,0x42,0x92,0xFA,0x0A,0x02,0x06, + /* 0xF3A5 [?] [7713]*/ + 0x10,0x10,0x11,0x7D,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE6,0x42,0x04, + 0x20,0x10,0xFE,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xF3A6 [?] [7714]*/ + 0x20,0x20,0x23,0xF9,0xA8,0xAB,0xAA,0xAC,0xF8,0xA3,0x20,0x28,0x38,0xE9,0x41,0x02, + 0x40,0x20,0xFC,0x08,0x90,0xFE,0x02,0x44,0x20,0xFC,0x80,0xF8,0x88,0x08,0x28,0x10, + /* 0xF3A7 [?] [7715]*/ + 0x08,0x7F,0x08,0xFF,0x14,0x56,0xA5,0x4C,0x81,0x1F,0x11,0x11,0x1F,0x01,0x7F,0x20, + 0x20,0x20,0x3E,0x44,0xA8,0x10,0x28,0x46,0x00,0xF0,0x10,0x10,0xF0,0x08,0xFC,0x04, + /* 0xF3A8 [?] [7716]*/ + 0x10,0x10,0x11,0x7C,0x54,0x57,0x54,0x55,0x7D,0x51,0x11,0x15,0x1C,0xE4,0x41,0x02, + 0x88,0x88,0xFC,0x88,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x00,0x88,0x04,0x02, + /* 0xF3A9 [?] [7717]*/ + 0x20,0x20,0x27,0xF8,0xAB,0xAA,0xAB,0xAA,0xFB,0xA0,0x21,0x29,0x39,0xE9,0x41,0x01, + 0x90,0x90,0xFE,0x90,0xFC,0x94,0xFC,0x94,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x08, + /* 0xF3AA [?] [7718]*/ + 0x10,0x13,0x10,0x7D,0x55,0x55,0x55,0x54,0x7D,0x50,0x13,0x14,0x1C,0xE5,0x42,0x00, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xF3AB [?] [7719]*/ + 0x20,0x21,0x20,0xFB,0xAA,0xA8,0xA8,0xA8,0xF8,0xA0,0x20,0x29,0x38,0xE8,0x43,0x00, + 0x20,0x24,0xA8,0xFE,0x02,0xF8,0x88,0x88,0xF8,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xF3AC [?] [7720]*/ + 0x20,0x21,0x20,0xF9,0xA8,0xAB,0xA8,0xA8,0xF9,0xA2,0x20,0x28,0x3A,0xEA,0x44,0x00, + 0x1C,0xE0,0x20,0x24,0xA8,0xFE,0x70,0xA8,0x24,0x22,0x40,0x24,0xA2,0x8A,0x88,0x78, + /* 0xF3AD [?] [7721]*/ + 0x20,0x20,0x21,0xFB,0xAD,0xA9,0xA9,0xA8,0xF8,0xA3,0x20,0x2B,0x38,0xE8,0x43,0x00, + 0x80,0xF8,0x08,0xFE,0x12,0x22,0xFE,0x40,0xA2,0x54,0x98,0x34,0x54,0x92,0x50,0x20, + /* 0xF3AE [?] [7722]*/ + 0x08,0x1F,0x28,0x07,0x18,0xE1,0x0C,0x03,0x10,0x7E,0x52,0x7E,0x10,0x14,0xFE,0x02, + 0x00,0xF0,0x20,0xC0,0x30,0x8E,0x40,0x00,0xA0,0xFC,0xA4,0xFC,0x20,0x24,0xFE,0x02, + /* 0xF3AF [?] [7723]*/ + 0x10,0x11,0x10,0x7C,0x57,0x54,0x55,0x55,0x7D,0x51,0x11,0x14,0x1F,0xE4,0x40,0x00, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xF3B0 [?] [7724]*/ + 0x20,0x20,0x23,0xF8,0xA8,0xAA,0xA9,0xAA,0xF8,0xA0,0x20,0x2B,0x38,0xE8,0x40,0x00, + 0x40,0x20,0xFE,0x20,0x48,0xF2,0x24,0x52,0xF8,0x08,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xF3B1 [?] [7725]*/ + 0x1F,0x02,0x01,0x7F,0x04,0x18,0x62,0x01,0x10,0x7E,0x52,0x7E,0x10,0x14,0xFE,0x02, + 0xF0,0x20,0x40,0xFC,0x84,0x88,0x80,0x00,0x20,0xFC,0xA4,0xFC,0x20,0x24,0xFE,0x02, + /* 0xF3B2 [?] [7726]*/ + 0x20,0x20,0x27,0xF8,0xA8,0xAB,0xA8,0xAB,0xFA,0xA2,0x23,0x2A,0x39,0xE8,0x47,0x02, + 0x82,0x82,0xF4,0x88,0x80,0xE2,0x02,0xE4,0x28,0x20,0xE0,0x22,0x42,0x74,0x88,0x10, + /* 0xF3B3 [?] [7727]*/ + 0x20,0x20,0x23,0xF8,0xA9,0xA9,0xA9,0xA9,0xF9,0xA0,0x23,0x28,0x38,0xEA,0x42,0x04, + 0x20,0x20,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x22,0xFE,0x42,0x24,0xA2,0x8A,0x78, + /* 0xF3B4 [?] [7728]*/ + 0x20,0x23,0x21,0xF8,0xAB,0xA8,0xA9,0xAA,0xF9,0xA1,0x21,0x29,0x39,0xE9,0x41,0x01, + 0x3C,0xE0,0x24,0xA8,0xFE,0xA8,0x24,0x02,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xF3B5 [?] [7729]*/ + 0x10,0x10,0x13,0x7C,0x55,0x54,0x57,0x55,0x7C,0x53,0x10,0x15,0x1D,0xE5,0x41,0x01, + 0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF3B6 [?] [7730]*/ + 0x10,0x13,0x10,0x7C,0x55,0x57,0x55,0x55,0x7D,0x51,0x11,0x15,0x1F,0xE4,0x40,0x03, + 0x88,0xFE,0xA8,0x90,0xFE,0x20,0xFC,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x70,0x8E, + /* 0xF3B7 [?] [7731]*/ + 0x20,0x23,0x20,0xFB,0xAA,0xA9,0xA8,0xAB,0xF8,0xA0,0x23,0x28,0x3B,0xE8,0x43,0x00, + 0x88,0xFE,0x88,0xFE,0x02,0xFC,0x00,0xFE,0x40,0xA2,0x54,0xB8,0x54,0x92,0x50,0x20, + /* 0xF3B8 [?] [7732]*/ + 0x10,0x10,0x11,0x7F,0x55,0x55,0x55,0x55,0x7D,0x51,0x11,0x15,0x1D,0xE5,0x41,0x02, + 0x80,0xF8,0x08,0xFE,0x44,0x92,0xFE,0x00,0x7C,0x00,0x7C,0x00,0x7C,0x44,0x7C,0x44, + /* 0xF3B9 [?] [7733]*/ + 0x20,0x23,0x22,0xFA,0xAB,0xAA,0xAA,0xAA,0xFB,0xA2,0x22,0x2A,0x3A,0xED,0x46,0x08, + 0x20,0xFE,0x88,0x50,0xFE,0x50,0xFC,0x54,0xFE,0x54,0xFC,0x50,0xD8,0x54,0x52,0x50, + /* 0xF3BA [?] [7734]*/ + 0x10,0x11,0x10,0x7C,0x55,0x55,0x55,0x55,0x7C,0x51,0x11,0x15,0x1D,0xE5,0x41,0x02, + 0x48,0xFE,0x48,0x00,0xFE,0x4A,0x4A,0xFE,0x14,0xFE,0x10,0x92,0x4C,0x4A,0x16,0x22, + /* 0xF3BB [?] [7735]*/ + 0x0F,0x10,0x1F,0x00,0xFF,0x0C,0x73,0x0D,0x72,0x0C,0xF3,0x7C,0x54,0x7C,0x12,0xFE, + 0xE0,0x20,0xC0,0x40,0xFE,0x10,0x20,0xC0,0xB0,0x8E,0x20,0xF8,0xA8,0xF8,0x24,0xFC, + /* 0xF3BC [?] [7736]*/ + 0x01,0x7F,0x11,0x1F,0x01,0xFF,0x88,0x1F,0x68,0x0F,0x10,0x7C,0x54,0x7C,0x12,0xFE, + 0x00,0xFC,0x10,0xF0,0x00,0xFE,0x02,0xF0,0x10,0xF0,0x20,0xF8,0xA8,0xF8,0x24,0xFC, + /* 0xF3BD [?] [7737]*/ + 0x23,0x22,0x23,0xFA,0xAB,0xA8,0xA9,0xAB,0xFD,0xA1,0x21,0x28,0x39,0xE8,0x40,0x07, + 0xDE,0x52,0xDE,0x52,0xDE,0xA0,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x88,0x70,0x8E, + /* 0xF3BE [?] [7738]*/ + 0x08,0x08,0x10,0x1F,0x21,0x41,0x01,0x01,0xFF,0x01,0x21,0x21,0x21,0x21,0x3F,0x00, + 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0xFE,0x00,0x08,0x08,0x08,0x08,0xF8,0x08, + /* 0xF3BF [?] [7739]*/ + 0x3E,0x22,0x2A,0x2A,0x2A,0x14,0x22,0x49,0x1F,0x21,0x01,0xFF,0x01,0x21,0x3F,0x00, + 0xF8,0x88,0xA8,0xA8,0xA8,0x50,0x88,0x04,0xF8,0x00,0x00,0xFE,0x00,0x08,0xF8,0x08, + /* 0xF3C0 [?] [7740]*/ + 0x08,0x7F,0x08,0x3E,0x00,0x3E,0x2A,0x3E,0x40,0x90,0x1F,0x21,0xFF,0x01,0x21,0x3F, + 0x00,0x78,0x48,0x48,0x86,0x78,0x48,0x30,0x48,0x86,0xF0,0x00,0xFE,0x00,0x08,0xF8, + /* 0xF3C1 [?] [7741]*/ + 0x20,0x20,0x3C,0x51,0x91,0x11,0xFF,0x11,0x11,0x55,0x55,0x55,0x5E,0x66,0x04,0x00, + 0x20,0x3E,0x20,0xFE,0x20,0x3C,0xE2,0x1E,0x04,0x78,0x92,0x54,0xFE,0x10,0x50,0x20, + /* 0xF3C2 [?] [7742]*/ + 0x08,0x1C,0x71,0x11,0x11,0xFD,0x11,0x11,0x7D,0x45,0x45,0x45,0x45,0x7D,0x45,0x01, + 0x04,0x1E,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x08,0x0A,0x4A,0x86,0x02, + /* 0xF3C3 [?] [7743]*/ + 0x10,0x10,0x1F,0x28,0x24,0x45,0x80,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, + 0x40,0x40,0x7E,0x90,0x88,0x08,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + /* 0xF3C4 [?] [7744]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x05,0x02, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + /* 0xF3C5 [?] [7745]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x08,0x08,0x0C,0x0A,0x12,0x11,0x20,0x43,0x8C, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xE0,0x20,0x40,0x78,0x08,0x10,0x20,0xC0,0x30,0x0E, + /* 0xF3C6 [?] [7746]*/ + 0x10,0x10,0x3F,0x28,0x45,0xBF,0x00,0x10,0x10,0x1F,0x00,0x00,0x7F,0x00,0x00,0x00, + 0x40,0x40,0x7E,0x90,0x08,0xF0,0x10,0x10,0x10,0xFC,0x04,0x04,0xE4,0x04,0x28,0x10, + /* 0xF3C7 [?] [7747]*/ + 0x10,0x10,0x3F,0x48,0x85,0x00,0x7F,0x08,0x08,0x08,0xFF,0x08,0x08,0x10,0x20,0x40, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF3C8 [?] [7748]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x1F,0x10,0x11,0x11,0x11,0x12,0x14,0x08,0x30,0xC0, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF0,0x10,0x10,0x10,0x10,0x90,0x90,0x82,0x82,0x7E, + /* 0xF3C9 [?] [7749]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x00,0x1F,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x82, + 0x40,0x40,0x7E,0x90,0x08,0x10,0xF8,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x02, + /* 0xF3CA [?] [7750]*/ + 0x10,0x10,0x3F,0x28,0x45,0x81,0x1F,0x11,0x21,0x3F,0x03,0x05,0x09,0x31,0xC1,0x01, + 0x40,0x40,0x7E,0x90,0x08,0x70,0x80,0x00,0x00,0xFC,0x04,0x04,0x04,0x28,0x10,0x00, + /* 0xF3CB [?] [7751]*/ + 0x10,0x10,0x3F,0x48,0x95,0x10,0x1F,0x22,0x42,0x84,0x08,0x11,0x22,0x44,0x08,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x48,0x48,0x88,0x88,0x08,0x08,0x08,0x50,0x20, + /* 0xF3CC [?] [7752]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x7E,0x08,0x08,0x08,0x08,0x08,0x0E,0xF0,0x40,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x84,0x88,0x90,0x88,0x84,0x84,0xA8,0x90,0x80, + /* 0xF3CD [?] [7753]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x20,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x3F, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0xF8,0x00,0x00,0xFE, + /* 0xF3CE [?] [7754]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0xFF,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0xFE,0x00, + /* 0xF3CF [?] [7755]*/ + 0x10,0x10,0x3F,0x28,0x45,0x91,0x11,0x3F,0x41,0x81,0x01,0x3F,0x01,0x01,0x01,0xFF, + 0x40,0x40,0x7E,0x90,0x08,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFE, + /* 0xF3D0 [?] [7756]*/ + 0x10,0x10,0x3F,0x28,0x45,0x88,0x08,0x1F,0x24,0x44,0x87,0x04,0x04,0x07,0x04,0x04, + 0x40,0x40,0x7E,0x90,0x08,0x00,0x00,0xFC,0x00,0x00,0xF0,0x00,0x00,0xF8,0x00,0x00, + /* 0xF3D1 [?] [7757]*/ + 0x10,0x10,0x3F,0x48,0x95,0x10,0x1F,0x20,0x40,0x9F,0x10,0x10,0x1F,0x00,0x00,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0x08,0x88,0x88,0x88,0x88,0x08,0x50,0x20, + /* 0xF3D2 [?] [7758]*/ + 0x10,0x10,0x1F,0x28,0x24,0x45,0x82,0x01,0x01,0x7F,0x00,0x10,0x08,0x04,0x00,0xFF, + 0x40,0x40,0x7E,0x90,0x88,0x08,0x00,0x00,0x00,0xFC,0x00,0x10,0x20,0x40,0x00,0xFE, + /* 0xF3D3 [?] [7759]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x00,0x7F,0x00,0x1F,0x10,0x10,0x1F,0x10,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0xE8,0x08,0x88,0x88,0x88,0x88,0xA8,0x10, + /* 0xF3D4 [?] [7760]*/ + 0x20,0x3F,0x48,0x85,0x00,0x7F,0x04,0x08,0x10,0x20,0xDF,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0x08,0x50,0x20,0xF8,0x08,0x08,0x08,0xF8,0x08, + /* 0xF3D5 [?] [7761]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x10,0x7E,0x12,0x12,0x12,0x12,0x22,0x22,0x4A,0x84, + 0x40,0x40,0x7E,0x90,0x08,0x00,0x7C,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xF3D6 [?] [7762]*/ + 0x10,0x10,0x3F,0x48,0x85,0x20,0x10,0x17,0x00,0x70,0x11,0x11,0x12,0x14,0x28,0x47, + 0x40,0x40,0x7E,0x90,0x08,0x80,0x80,0xF8,0x88,0x88,0x08,0x08,0x28,0x10,0x00,0xFE, + /* 0xF3D7 [?] [7763]*/ + 0x10,0x10,0x3F,0x48,0x85,0x08,0x10,0x3F,0x00,0x00,0x1F,0x10,0x10,0x10,0x1F,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x20,0x10,0xF8,0x08,0x00,0xF0,0x10,0x10,0x10,0xF0,0x10, + /* 0xF3D8 [?] [7764]*/ + 0x10,0x10,0x3F,0x28,0x45,0x88,0x08,0x7E,0x08,0x08,0x0E,0x78,0x08,0x08,0x28,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84,0x00, + /* 0xF3D9 [?] [7765]*/ + 0x20,0x3F,0x48,0x85,0x20,0x20,0x3E,0x20,0x20,0x26,0x39,0x01,0xFF,0x01,0x01,0x01, + 0x40,0x7E,0x90,0x08,0x80,0x88,0xB0,0xC4,0x84,0x7C,0x00,0x00,0xFE,0x00,0x00,0x00, + /* 0xF3DA [?] [7766]*/ + 0x10,0x10,0x3F,0x48,0x85,0x11,0x11,0x3F,0x41,0x01,0xFF,0x04,0x08,0x10,0x20,0xC0, + 0x40,0x40,0x7E,0x90,0x08,0x00,0x00,0xF8,0x00,0x00,0xFE,0x40,0x40,0x42,0x42,0x3E, + /* 0xF3DB [?] [7767]*/ + 0x20,0x3F,0x48,0x85,0x00,0x7B,0x08,0x10,0x22,0x7A,0x0A,0x2B,0x10,0x28,0x47,0x80, + 0x40,0x7E,0x90,0x08,0x18,0xE0,0x40,0x40,0x78,0x40,0x40,0xFC,0x00,0x00,0xFE,0x00, + /* 0xF3DC [?] [7768]*/ + 0x10,0x10,0x3F,0x28,0x45,0x82,0x04,0x08,0x30,0xCF,0x01,0x01,0x1F,0x01,0x01,0x7F, + 0x40,0x40,0x7E,0x90,0x08,0x80,0x40,0x20,0x18,0xE6,0x00,0x00,0xF0,0x00,0x00,0xFC, + /* 0xF3DD [?] [7769]*/ + 0x10,0x10,0x3F,0x28,0x45,0x88,0x1F,0x20,0x5F,0x01,0xFF,0x01,0x1F,0x01,0x05,0x02, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xF0,0x20,0xF8,0x08,0xFE,0x08,0xF8,0x08,0x00,0x00, + /* 0xF3DE [?] [7770]*/ + 0x10,0x10,0x3F,0x28,0x45,0x90,0x10,0x7D,0x12,0x10,0x10,0x1C,0xE0,0x41,0x00,0x00, + 0x40,0x40,0x7E,0x90,0x08,0x80,0xFC,0x04,0x04,0x84,0x54,0x24,0x44,0x84,0x28,0x10, + /* 0xF3DF [?] [7771]*/ + 0x10,0x10,0x3F,0x48,0x85,0x00,0x7F,0x01,0x11,0x11,0x11,0x29,0x45,0x85,0x01,0xFF, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x00,0x10,0x10,0x10,0x28,0x44,0x84,0x00,0xFE, + /* 0xF3E0 [?] [7772]*/ + 0x20,0x3F,0x48,0x85,0x7F,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x21,0x1A,0x06,0x19,0x60, + 0x40,0x7E,0x90,0x08,0xFC,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x00,0x00,0xC0,0x3E, + /* 0xF3E1 [?] [7773]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x11,0xFD,0x11,0x11,0x1D,0xF1,0x11,0x11,0x51,0x20, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xFC,0x24,0x24,0x24,0xFC,0x00,0x00,0x02,0x02,0xFE, + /* 0xF3E2 [?] [7774]*/ + 0x10,0x10,0x3F,0x48,0x85,0x11,0x09,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10,0x10,0x10, + 0x40,0x40,0x7E,0x90,0x08,0x10,0x20,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x10,0x50,0x20, + /* 0xF3E3 [?] [7775]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x10,0x24,0x24,0x64,0xA5,0x24,0x24,0x20,0x20,0x23, + 0x40,0x40,0x7E,0x90,0x08,0x40,0x40,0x7E,0x88,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xF3E4 [?] [7776]*/ + 0x20,0x3F,0x49,0xBF,0x01,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x10, + 0x40,0x7E,0x90,0xF8,0x00,0xF0,0x00,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0x30, + /* 0xF3E5 [?] [7777]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x01,0x1F,0x01,0x7F,0x00,0x1F,0x10,0x11,0x02,0x0C,0x70, + 0x40,0x7E,0x90,0x08,0xF8,0x00,0xF0,0x00,0xFC,0x00,0xF0,0x10,0x10,0xC0,0x30,0x08, + /* 0xF3E6 [?] [7778]*/ + 0x20,0x3F,0x48,0x85,0x00,0x3F,0x20,0x20,0x2F,0x24,0x22,0x2F,0x21,0x22,0x24,0x3F, + 0x40,0x7E,0x90,0x08,0x00,0xFC,0x80,0x80,0xF8,0x90,0xA0,0xFC,0x40,0x20,0x10,0xFE, + /* 0xF3E7 [?] [7779]*/ + 0x10,0x10,0x3F,0x28,0x45,0x82,0x1F,0x02,0xFF,0x03,0x0F,0x38,0xCF,0x08,0x0F,0x08, + 0x40,0x40,0x7E,0x90,0x08,0x00,0xD0,0x20,0xFE,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10, + /* 0xF3E8 [?] [7780]*/ + 0x20,0x3F,0x48,0x85,0x08,0x7F,0x08,0x02,0xFF,0x04,0x08,0x1F,0x28,0xC8,0x0F,0x08, + 0x40,0x7E,0x90,0x08,0x20,0xFC,0x20,0x00,0xFE,0x00,0x00,0xF0,0x10,0x10,0xF0,0x10, + /* 0xF3E9 [?] [7781]*/ + 0x10,0x10,0x3F,0x48,0x85,0x10,0x10,0xFB,0x10,0x10,0x1C,0xF0,0x10,0x10,0x50,0x20, + 0x40,0x40,0x7E,0x90,0x08,0x88,0x88,0xFE,0x88,0x88,0xF8,0x88,0x88,0x88,0xF8,0x88, + /* 0xF3EA [?] [7782]*/ + 0x20,0x3F,0x48,0x85,0x10,0x11,0x10,0xFC,0x13,0x10,0x1D,0x30,0xD3,0x10,0x50,0x20, + 0x40,0x7E,0x90,0x08,0x00,0xFC,0x88,0x70,0x8E,0x20,0xFC,0x20,0xFE,0x20,0x20,0x20, + /* 0xF3EB [?] [7783]*/ + 0x10,0x10,0x3F,0x48,0x85,0x3F,0x21,0x3F,0x21,0x3F,0x00,0xFF,0x08,0x08,0x10,0x20, + 0x40,0x40,0x7E,0x90,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x20,0x20,0x20,0x20, + /* 0xF3EC [?] [7784]*/ + 0x20,0x3F,0x48,0x85,0x08,0x04,0x3F,0x21,0x3F,0x21,0x3F,0x01,0xFF,0x01,0x01,0x01, + 0x40,0x7E,0x90,0x08,0x20,0x40,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFE,0x00,0x00,0x00, + /* 0xF3ED [?] [7785]*/ + 0x20,0x3F,0x48,0x85,0x01,0x7F,0x40,0x88,0x10,0x20,0x1F,0x01,0x01,0x01,0x7F,0x00, + 0x40,0x7E,0x90,0x08,0x00,0xFE,0x02,0x24,0x10,0x08,0xF0,0x00,0x00,0x00,0xFC,0x00, + /* 0xF3EE [?] [7786]*/ + 0x20,0x20,0x7E,0x51,0x8A,0x01,0x7F,0x40,0x90,0x1E,0x22,0x24,0x54,0x08,0x10,0x60, + 0x40,0x40,0xFE,0x10,0x08,0x00,0xFE,0x02,0x04,0xF8,0x88,0xA8,0x90,0x84,0x84,0x7C, + /* 0xF3EF [?] [7787]*/ + 0x20,0x3F,0x48,0x85,0x01,0x3F,0x01,0xFF,0x01,0x3F,0x01,0x25,0x25,0x29,0x41,0x81, + 0x40,0x7E,0x90,0x08,0x00,0xF8,0x08,0xFE,0x08,0xF8,0x00,0x48,0x28,0x28,0x08,0x08, + /* 0xF3F0 [?] [7788]*/ + 0x10,0x10,0x3F,0x28,0x45,0x80,0x3F,0x20,0x2F,0x20,0x2F,0x28,0x28,0x4F,0x40,0x80, + 0x40,0x40,0x7E,0x90,0x28,0x24,0xFE,0x20,0xA4,0x24,0xA8,0x98,0x92,0xAA,0x46,0x82, + /* 0xF3F1 [?] [7789]*/ + 0x20,0x3F,0x48,0x85,0x1F,0x11,0x1F,0x01,0xFF,0x00,0x1F,0x10,0x11,0x02,0x0C,0x70, + 0x40,0x7E,0x90,0x08,0xF0,0x10,0xF0,0x00,0xFE,0x00,0xF0,0x10,0x10,0xC0,0x30,0x08, + /* 0xF3F2 [?] [7790]*/ + 0x20,0x20,0x7E,0x51,0x8A,0x1F,0x10,0x1F,0x10,0x1F,0x00,0x7F,0x01,0x3F,0x01,0xFF, + 0x40,0x40,0xFE,0x10,0x08,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x00,0xF8,0x00,0xFE, + /* 0xF3F3 [?] [7791]*/ + 0x20,0x3F,0x48,0x85,0x09,0x08,0x10,0x37,0x51,0x91,0x12,0x10,0x17,0x10,0x11,0x12, + 0x40,0x7E,0x90,0x08,0xF0,0x10,0x10,0xFC,0x00,0xF8,0x40,0x40,0xFC,0xA0,0x10,0x0C, + /* 0xF3F4 [?] [7792]*/ + 0x20,0x3F,0x48,0x85,0x7F,0x04,0x3F,0x04,0xFF,0x11,0x1F,0x11,0xFF,0x10,0x10,0x10, + 0x40,0x7E,0x90,0x48,0xFC,0x40,0xF8,0x40,0xFE,0x10,0xF0,0x10,0xFE,0x10,0x50,0x20, + /* 0xF3F5 [?] [7793]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x22,0x22,0x3E,0x22,0x2E,0x22,0x3E,0x22,0x22,0x3F,0x00, + 0x40,0x7E,0x90,0x08,0xFC,0x40,0x40,0x78,0x40,0x70,0x40,0x78,0x40,0x40,0xFC,0x00, + /* 0xF3F6 [?] [7794]*/ + 0x10,0x10,0x3F,0x48,0x85,0x7F,0x04,0x3F,0x24,0x3F,0x01,0x7F,0x05,0x19,0xE1,0x01, + 0x40,0x40,0x7E,0x90,0x08,0xFC,0x40,0xF8,0x48,0xF8,0x00,0xFC,0x40,0x30,0x0E,0x00, + /* 0xF3F7 [?] [7795]*/ + 0x20,0x3E,0x48,0x82,0x3F,0x24,0x23,0x24,0x3F,0x00,0x20,0x3E,0x20,0x20,0x26,0x38, + 0x40,0x7E,0x90,0x00,0xF8,0x48,0x88,0x48,0xF8,0x00,0x84,0x98,0xE0,0x84,0x84,0x7C, + /* 0xF3F8 [?] [7796]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x20,0x20,0x2F,0x28,0x28,0x2B,0x28,0x48,0x51,0x92,0x24, + 0x40,0x7E,0x90,0x7C,0x80,0xF8,0x80,0xFC,0x84,0xF0,0x88,0x78,0x00,0xE0,0x24,0x1C, + /* 0xF3F9 [?] [7797]*/ + 0x20,0x3F,0x48,0x85,0x08,0xFF,0x08,0x7F,0x49,0x49,0x7F,0x1C,0x2A,0x49,0x88,0x08, + 0x40,0x7E,0x90,0x08,0x20,0xA0,0x3E,0x42,0x94,0x10,0x10,0x10,0x28,0x28,0x44,0x82, + /* 0xF3FA [?] [7798]*/ + 0x20,0x3F,0x48,0x85,0x3F,0x24,0x24,0x3F,0x00,0x3F,0x20,0x30,0x28,0x24,0x40,0x83, + 0x40,0x7E,0x90,0x08,0xF8,0x48,0x48,0xF8,0x90,0xFC,0x80,0x48,0x50,0x24,0xD4,0x0C, + /* 0xF3FB [?] [7799]*/ + 0x20,0x3F,0x48,0x85,0x12,0x67,0x44,0x47,0x44,0x57,0x60,0x04,0x04,0x08,0x10,0x60, + 0x40,0x7E,0x90,0x08,0x00,0xDC,0x44,0xC4,0x44,0xDC,0x00,0x40,0x40,0x42,0x42,0x3E, + /* 0xF3FC [?] [7800]*/ + 0x20,0x3F,0x48,0x85,0x00,0x3F,0x22,0x3F,0x22,0x3F,0x28,0x28,0x2F,0x48,0x4B,0x8C, + 0x40,0x7E,0x90,0x08,0x80,0xFE,0x20,0xFC,0x24,0xFC,0x40,0x48,0x70,0x44,0x44,0x3C, + /* 0xF3FD [?] [7801]*/ + 0x20,0x3F,0x48,0x85,0x04,0x55,0x4E,0x44,0x5F,0x44,0x4E,0x55,0x44,0x7F,0x00,0x01, + 0x40,0x7E,0x90,0x08,0x0C,0x70,0x40,0x40,0x7E,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xF3FE [?] [7802]*/ + 0x20,0x3F,0x48,0x85,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x14,0x18,0x3F,0x24,0x24,0xFF, + 0x40,0x7E,0x90,0x08,0xF0,0x10,0xF0,0x10,0xF4,0x88,0x70,0x0E,0xF8,0x48,0x48,0xFE, + /* 0xF4A1 [?] [7803]*/ + 0x20,0x3E,0x48,0xFF,0x04,0x3F,0x24,0x3F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x01,0x01, + 0x40,0x7E,0x90,0xFC,0x40,0xF8,0x48,0xF8,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00,0x00, + /* 0xF4A2 [?] [7804]*/ + 0x20,0x3F,0x48,0x85,0x3E,0x08,0x48,0x7E,0x14,0x24,0x46,0x3F,0x20,0x3F,0x20,0x3F, + 0x40,0x7E,0x90,0x08,0x7C,0x10,0x90,0xFE,0x28,0x4A,0x86,0xF8,0x08,0xF8,0x08,0xF8, + /* 0xF4A3 [?] [7805]*/ + 0x20,0x3F,0x48,0x85,0x00,0x7E,0x04,0x28,0x17,0x20,0xDF,0x10,0x1F,0x08,0x04,0x7F, + 0x40,0x7E,0x90,0x08,0x90,0xA0,0x44,0x28,0xD0,0x08,0xF6,0x10,0xF0,0x20,0x40,0xFC, + /* 0xF4A4 [?] [7806]*/ + 0x20,0x3F,0x48,0x85,0x24,0x24,0xFE,0x24,0x3C,0x24,0x3C,0x24,0xFE,0x29,0x45,0x82, + 0x40,0x7E,0x90,0x08,0x10,0x10,0xFE,0x92,0x90,0xFC,0xA4,0xA4,0xA8,0x10,0x28,0x46, + /* 0xF4A5 [?] [7807]*/ + 0x20,0x3F,0x48,0x85,0x08,0x7F,0x08,0x3E,0x2A,0x2A,0x3E,0x08,0x1C,0x2A,0x48,0x08, + 0x40,0x7E,0x90,0x08,0x20,0x3C,0x44,0x88,0x7C,0x44,0x54,0x54,0x54,0x28,0x44,0x82, + /* 0xF4A6 [?] [7808]*/ + 0x20,0x3F,0x48,0x85,0x20,0x27,0xF4,0x25,0x36,0x20,0xE7,0x24,0x27,0x24,0xA7,0x44, + 0x40,0x7E,0x90,0x08,0x80,0x7C,0xA4,0xA4,0x54,0x88,0xFC,0x44,0xFC,0x44,0xFC,0x04, + /* 0xF4A7 [?] [7809]*/ + 0x01,0x05,0x39,0x21,0x21,0x3D,0x21,0x21,0x21,0x3F,0x21,0x02,0x04,0x08,0x30,0xC0, + 0x00,0x00,0x78,0x08,0x08,0x78,0x08,0x08,0x08,0xF8,0x08,0x80,0x40,0x20,0x18,0x06, + /* 0xF4A8 [?] [7810]*/ + 0x06,0x38,0x20,0x20,0x3E,0x20,0x20,0x3F,0x08,0x08,0xFF,0x08,0x08,0x10,0x20,0x40, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF4A9 [?] [7811]*/ + 0x01,0x01,0x7F,0x01,0x3F,0x02,0xFF,0x04,0x08,0x34,0xD8,0x10,0x1C,0x10,0x1F,0x10, + 0x00,0x00,0xFC,0x00,0xF8,0x00,0xFE,0x40,0x20,0x18,0x76,0x10,0x70,0x10,0xF0,0x10, + /* 0xF4AA [?] [7812]*/ + 0x06,0x38,0x20,0x20,0x3E,0x20,0x20,0x3F,0x10,0x3F,0x40,0x89,0x24,0x24,0x40,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x00,0xFC,0x04,0x24,0x94,0x94,0x28,0x10, + /* 0xF4AB [?] [7813]*/ + 0x02,0x04,0x1F,0x10,0x1F,0x10,0x1F,0x10,0x1F,0x01,0xFF,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x40,0x20,0x18,0x06,0x00, + /* 0xF4AC [?] [7814]*/ + 0x08,0x08,0x10,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x57,0xFC,0x01,0x00, + 0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x44,0x44,0x44,0x44,0xC4,0x44,0xFE,0x00, + /* 0xF4AD [?] [7815]*/ + 0x08,0x10,0x3E,0x22,0x32,0x2A,0x2A,0xFE,0x22,0x32,0x2A,0x2A,0x22,0x42,0x4A,0x84, + 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00, + /* 0xF4AE [?] [7816]*/ + 0x10,0x20,0x7C,0x44,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x54,0x88, + 0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00, + /* 0xF4AF [?] [7817]*/ + 0x10,0x20,0x7D,0x45,0x65,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x44,0x44,0x55,0x8A, + 0x40,0x24,0x24,0x04,0x04,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x04,0x02, + /* 0xF4B0 [?] [7818]*/ + 0x10,0x21,0x7D,0x45,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x88, + 0x10,0x10,0x10,0x12,0x12,0x14,0xD8,0x10,0x10,0x10,0x10,0x12,0x52,0x92,0x0E,0x00, + /* 0xF4B1 [?] [7819]*/ + 0x10,0x20,0x7C,0x44,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x54,0x44,0x44,0x54,0x88, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x20,0x20,0x20,0x20,0x20, + /* 0xF4B2 [?] [7820]*/ + 0x10,0x20,0x7C,0x44,0x64,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x45,0x45,0x56,0x88, + 0x04,0x0E,0xF0,0x80,0x80,0xFC,0xA4,0xA4,0xA4,0xA8,0xA8,0x90,0x10,0x28,0x44,0x82, + /* 0xF4B3 [?] [7821]*/ + 0x10,0x20,0x7C,0x45,0x64,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x44,0x44,0x55,0x8A, + 0x40,0x20,0x20,0xFE,0x40,0x40,0x40,0x7C,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xF4B4 [?] [7822]*/ + 0x10,0x20,0x7D,0x44,0x64,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x44,0x44,0x54,0x88, + 0x00,0x00,0xFE,0x08,0x08,0xE8,0x28,0x28,0x28,0x28,0xE8,0x28,0x08,0x08,0x28,0x10, + /* 0xF4B5 [?] [7823]*/ + 0x10,0x20,0x7C,0x44,0x64,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x44,0x45,0x55,0x8A, + 0x20,0x20,0x3C,0x20,0x20,0xFC,0x84,0x84,0x84,0xFC,0x84,0x80,0x80,0x00,0x00,0x00, + /* 0xF4B6 [?] [7824]*/ + 0x10,0x20,0x7C,0x44,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89, + 0x20,0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFC,0x24,0x24,0x24,0x24,0xFC,0x04, + /* 0xF4B7 [?] [7825]*/ + 0x10,0x20,0x7C,0x44,0x65,0x55,0x56,0xFC,0x44,0x64,0x54,0x54,0x44,0x44,0x54,0x88, + 0x80,0x80,0x80,0xFE,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40, + /* 0xF4B8 [?] [7826]*/ + 0x10,0x23,0x7C,0x44,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89, + 0x00,0xFE,0x50,0x50,0xFC,0x54,0x54,0x54,0x54,0x54,0x8C,0x04,0x04,0x04,0xFC,0x04, + /* 0xF4B9 [?] [7827]*/ + 0x10,0x21,0x7C,0x44,0x64,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89, + 0x20,0x24,0xA4,0xA8,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x04,0x04,0x14,0x08, + /* 0xF4BA [?] [7828]*/ + 0x10,0x21,0x7D,0x45,0x65,0x55,0x55,0xFD,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x8A, + 0x00,0xFC,0x04,0x04,0xFC,0x00,0x1C,0x70,0x1C,0x70,0x1E,0xF0,0x10,0x12,0x12,0x0E, + /* 0xF4BB [?] [7829]*/ + 0x10,0x21,0x7C,0x44,0x64,0x57,0x54,0xFC,0x44,0x65,0x55,0x55,0x45,0x45,0x57,0x88, + 0x00,0xFC,0x08,0x10,0x20,0xFE,0x20,0xA0,0x40,0xFC,0x54,0x54,0x54,0x54,0xFE,0x00, + /* 0xF4BC [?] [7830]*/ + 0x10,0x20,0x7D,0x44,0x64,0x54,0x54,0xFC,0x44,0x64,0x54,0x54,0x44,0x44,0x54,0x88, + 0x84,0x48,0xFE,0x20,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xF4BD [?] [7831]*/ + 0x10,0x20,0x7D,0x44,0x65,0x55,0x55,0xFD,0x45,0x64,0x54,0x54,0x44,0x44,0x54,0x88, + 0x50,0x50,0xFE,0x50,0xFC,0x54,0xFC,0x54,0xFC,0x00,0xF8,0x88,0xF8,0x88,0xF8,0x88, + /* 0xF4BE [?] [7832]*/ + 0x10,0x21,0x7C,0x44,0x67,0x54,0x55,0xFD,0x45,0x65,0x55,0x54,0x45,0x44,0x57,0x88, + 0x20,0xFC,0x88,0x50,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xF4BF [?] [7833]*/ + 0x10,0x23,0x78,0x4B,0x6A,0x59,0x48,0xFB,0x48,0x48,0x6B,0x58,0x4B,0x48,0x4B,0x98, + 0x88,0xFE,0x88,0xFE,0x02,0xFC,0x00,0xFE,0x40,0xA2,0x54,0xB8,0x54,0x92,0x50,0x20, + /* 0xF4C0 [?] [7834]*/ + 0x01,0x02,0x04,0x09,0x30,0xCF,0x00,0x02,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x80,0x40,0x20,0x98,0xE6,0x40,0x80,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xF4C1 [?] [7835]*/ + 0x04,0x1F,0x14,0x12,0x10,0x1F,0x00,0x02,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0xE0,0x20,0xA0,0x40,0xFC,0x04,0x14,0x08,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xF4C2 [?] [7836]*/ + 0x08,0x08,0x7F,0x09,0x11,0x11,0x25,0x42,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xF4C3 [?] [7837]*/ + 0x01,0x01,0x7F,0x11,0x09,0x05,0x19,0x62,0x01,0xFF,0x05,0x0C,0x34,0xC5,0x06,0x04, + 0x20,0x10,0xFC,0x10,0xA0,0x40,0x30,0x08,0x00,0xFE,0x00,0x88,0x50,0x30,0x0E,0x00, + /* 0xF4C4 [?] [7838]*/ + 0x10,0x08,0x40,0x24,0x09,0x72,0x10,0x10,0x07,0x01,0xFF,0x04,0x0C,0x34,0xC5,0x06, + 0x20,0x20,0xA8,0xA4,0x22,0x28,0x30,0xC0,0x00,0x00,0xFE,0x88,0x50,0x20,0x18,0x06, + /* 0xF4C5 [?] [7839]*/ + 0x00,0x7C,0x45,0x44,0x7C,0x43,0x7C,0xA5,0x24,0x3E,0x01,0xFF,0x06,0x1C,0xE5,0x06, + 0x40,0x20,0xFC,0x88,0x50,0xFE,0x20,0xFC,0x20,0x20,0x00,0xFE,0x80,0x48,0x30,0x0E, + /* 0xF4C6 [?] [7840]*/ + 0x44,0x24,0x29,0xFD,0x11,0x11,0x7D,0x11,0x11,0xFD,0x11,0x11,0x21,0x21,0x41,0x81, + 0x04,0x1E,0xF0,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x08,0x0A,0x4A,0xA6,0x12, + /* 0xF4C7 [?] [7841]*/ + 0x44,0x25,0x28,0xFC,0x10,0x10,0x7C,0x13,0x10,0xFD,0x10,0x10,0x20,0x20,0x43,0x80, + 0x00,0xFC,0x08,0x10,0x30,0x48,0x84,0x02,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xF4C8 [?] [7842]*/ + 0x44,0x24,0x28,0xFD,0x13,0x10,0x7C,0x11,0x12,0xFC,0x11,0x12,0x20,0x20,0x41,0x86, + 0x40,0x40,0x88,0x04,0xFE,0x02,0x88,0x44,0x42,0xF8,0x88,0x50,0x20,0x50,0x88,0x06, + /* 0xF4C9 [?] [7843]*/ + 0x44,0x25,0x29,0xFD,0x11,0x11,0x7C,0x11,0x12,0xFD,0x11,0x11,0x21,0x20,0x40,0x80, + 0x00,0xFC,0x04,0xFC,0x04,0xFC,0x80,0xFE,0x22,0x22,0x52,0x02,0xFA,0x02,0x14,0x08, + /* 0xF4CA [?] [7844]*/ + 0x44,0x25,0x29,0xFD,0x11,0x10,0x7C,0x13,0x10,0xFD,0x11,0x12,0x22,0x24,0x48,0x80, + 0x20,0x24,0x24,0x24,0xFC,0x80,0x80,0xFE,0x90,0x10,0x52,0x54,0xA8,0x28,0x44,0x82, + /* 0xF4CB [?] [7845]*/ + 0x04,0x7F,0x01,0x3F,0x01,0xFF,0x00,0x3E,0x08,0xFF,0x2A,0x7D,0x90,0x1E,0x02,0x0C, + 0x40,0xFC,0x00,0xF8,0x00,0xFE,0x28,0x24,0x24,0xFE,0x20,0x24,0xA8,0x12,0x2A,0x46, + /* 0xF4CC [?] [7846]*/ + 0x10,0x10,0x94,0x54,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x10, + 0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xFC,0x04,0x00, + /* 0xF4CD [?] [7847]*/ + 0x10,0x10,0x94,0x54,0x58,0x11,0xFE,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x11,0x12, + 0x40,0x40,0x40,0x80,0xFE,0x08,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x04,0x02, + /* 0xF4CE [?] [7848]*/ + 0x10,0x10,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x10, + 0x00,0x00,0xFC,0x24,0x24,0x24,0x24,0x24,0xFC,0x00,0x00,0x00,0x02,0x02,0xFE,0x00, + /* 0xF4CF [?] [7849]*/ + 0x10,0x11,0x95,0x55,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x12,0x12,0x14, + 0x00,0xFE,0x00,0x00,0x00,0xFE,0x20,0x20,0x3C,0x24,0x24,0x24,0x24,0x44,0x54,0x88, + /* 0xF4D0 [?] [7850]*/ + 0x01,0x11,0x11,0x1F,0x41,0x41,0x7F,0x00,0x11,0x09,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x10,0x10,0xF0,0x04,0x04,0xFC,0x00,0x10,0x20,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xF4D1 [?] [7851]*/ + 0x10,0x13,0x94,0x54,0x59,0x11,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x00,0xFE,0x50,0x50,0xFC,0x54,0x54,0x54,0x54,0x54,0x8C,0x04,0x04,0x04,0xFC,0x04, + /* 0xF4D2 [?] [7852]*/ + 0x01,0x41,0x21,0x0A,0x14,0xE0,0x21,0x26,0x11,0x09,0x7F,0x05,0x09,0x31,0xC1,0x01, + 0x00,0x00,0xFC,0x44,0x48,0xA0,0x10,0x08,0x10,0x20,0xFC,0x40,0x20,0x18,0x06,0x00, + /* 0xF4D3 [?] [7853]*/ + 0x08,0x0F,0x28,0x3F,0x61,0x92,0x0C,0x31,0xC0,0x11,0x09,0x7F,0x05,0x09,0x31,0xC1, + 0x00,0x7C,0x04,0x44,0x28,0x10,0x68,0x84,0x00,0x10,0x20,0xFC,0x40,0x20,0x18,0x06, + /* 0xF4D4 [?] [7854]*/ + 0x08,0x49,0x2A,0x08,0xFF,0x2A,0x49,0x88,0x42,0x77,0x92,0x5A,0x2F,0x22,0x42,0x82, + 0x00,0x12,0x12,0x12,0x24,0x24,0x48,0x90,0x48,0x48,0x24,0x24,0x92,0x12,0x12,0x00, + /* 0xF4D5 [?] [7855]*/ + 0x20,0x20,0x23,0xAA,0x70,0x21,0xF8,0x20,0x73,0x68,0xA9,0x21,0x22,0x24,0x20,0x20, + 0x40,0x20,0xFE,0x02,0x00,0xFC,0x00,0x00,0xFE,0x20,0x28,0x24,0x22,0x22,0xA0,0x40, + /* 0xF4D6 [?] [7856]*/ + 0x10,0x10,0x94,0x55,0x58,0x13,0xFC,0x31,0x3A,0x55,0x54,0x90,0x11,0x10,0x10,0x13, + 0x40,0x48,0x84,0xFE,0x20,0xFE,0x88,0x24,0x42,0x88,0x10,0x62,0x84,0x18,0x60,0x80, + /* 0xF4D7 [?] [7857]*/ + 0x10,0x10,0x94,0x55,0x59,0x13,0xFD,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11, + 0x80,0xBC,0x84,0x08,0xFE,0x20,0x20,0x7C,0x90,0x10,0xFE,0x10,0x28,0x28,0x44,0x82, + /* 0xF4D8 [?] [7858]*/ + 0x20,0x20,0x21,0xA9,0x72,0x25,0xF8,0x21,0x76,0x69,0xA9,0x21,0x21,0x21,0x21,0x21, + 0x88,0x88,0xEC,0x2A,0x28,0x48,0x88,0x7E,0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC, + /* 0xF4D9 [?] [7859]*/ + 0x21,0x20,0x20,0xAF,0x71,0x21,0xFA,0x22,0x74,0x6F,0xA9,0x22,0x22,0x24,0x27,0x20, + 0x08,0x88,0x90,0xFE,0x08,0x08,0x10,0x94,0xA4,0x38,0x08,0x10,0x10,0xA4,0xBC,0x84, + /* 0xF4DA [?] [7860]*/ + 0x20,0x23,0x20,0xA9,0x71,0x21,0xFA,0x24,0x71,0x69,0xA9,0x21,0x21,0x21,0x21,0x21, + 0x00,0xFE,0x22,0x20,0x3C,0x20,0xFE,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04,0x14,0x08, + /* 0xF4DB [?] [7861]*/ + 0x20,0x21,0x20,0xA8,0x73,0x20,0xF8,0x21,0x72,0x68,0xAB,0x20,0x20,0x21,0x26,0x20, + 0x00,0xFC,0x48,0x30,0xFE,0x52,0x94,0x10,0x30,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xF4DC [?] [7862]*/ + 0x20,0x20,0x23,0xAA,0x73,0x22,0xFB,0x22,0x73,0x68,0xA8,0x27,0x20,0x21,0x22,0x2C, + 0x40,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0xF8,0x50,0x48,0xFE,0xA0,0x10,0x08,0x06, + /* 0xF4DD [?] [7863]*/ + 0x20,0x23,0x20,0xA8,0x70,0x23,0xFA,0x22,0x72,0x6B,0xA8,0x20,0x20,0x20,0x25,0x22, + 0x00,0xBE,0xA2,0xA2,0xBE,0x88,0x08,0x3E,0x2A,0xAA,0xAA,0xBE,0x88,0x8A,0x7E,0x02, + /* 0xF4DE [?] [7864]*/ + 0x00,0x3F,0x20,0x20,0x3F,0x20,0x20,0x3F,0x22,0x22,0x21,0x20,0x24,0x28,0x30,0x20, + 0x00,0xF0,0x10,0x10,0xF0,0x10,0x10,0xF0,0x00,0x08,0x10,0xA0,0x40,0x20,0x18,0x06, + /* 0xF4DF [?] [7865]*/ + 0x7D,0x44,0x7D,0x45,0x7C,0x48,0x54,0x65,0x1F,0x10,0x1F,0x10,0x1F,0x00,0xFF,0x00, + 0xFC,0x20,0x20,0xFE,0x50,0x52,0x92,0x0E,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00, + /* 0xF4E0 [?] [7866]*/ + 0x00,0x7E,0x22,0x12,0x06,0x1A,0x62,0x02,0x04,0x04,0x7F,0x04,0x04,0x08,0x10,0x20, + 0x00,0xFC,0x44,0x24,0x0C,0x34,0xC4,0x04,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF4E1 [?] [7867]*/ + 0x10,0x11,0x28,0x24,0x43,0x90,0x08,0x00,0xFC,0x04,0x09,0x50,0x20,0x10,0x11,0x00, + 0x00,0xDC,0x44,0x44,0x54,0xCC,0x44,0x44,0x4C,0xD4,0x64,0x44,0x44,0x44,0x54,0x88, + /* 0xF4E2 [?] [7868]*/ + 0x01,0x06,0x18,0xEF,0x00,0x1F,0x10,0x1F,0x00,0x7E,0x22,0x12,0x0A,0x12,0x6A,0x04, + 0x00,0xC0,0x30,0xEE,0x00,0xF0,0x10,0xF0,0x00,0xFC,0x44,0x24,0x14,0x24,0xD4,0x08, + /* 0xF4E3 [?] [7869]*/ + 0x01,0x1F,0x01,0x7F,0x02,0x0F,0x38,0xCF,0x08,0x0F,0x00,0x7E,0x22,0x1A,0x62,0x06, + 0x08,0xD0,0x20,0xFC,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFC,0x44,0x34,0xC4,0x0C, + /* 0xF4E4 [?] [7870]*/ + 0x04,0x7C,0x04,0x3C,0x04,0x7C,0x04,0x04,0x00,0x7E,0x22,0x12,0x0A,0x12,0x6A,0x04, + 0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x40,0x00,0xFC,0x44,0x24,0x14,0x24,0xD4,0x08, + /* 0xF4E5 [?] [7871]*/ + 0x08,0xFF,0x00,0x3E,0x22,0x3E,0x22,0x3E,0x22,0x26,0x00,0x7E,0x22,0x1A,0x62,0x06, + 0x20,0xFE,0x00,0x08,0x48,0x48,0x48,0x48,0x08,0x18,0x00,0xFC,0x44,0x34,0xC4,0x0C, + /* 0xF4E6 [?] [7872]*/ + 0x10,0x08,0x7E,0x42,0x42,0x7E,0x42,0x40,0x7F,0x55,0x55,0x7F,0xD5,0x55,0x55,0x43, + 0x00,0xEE,0x22,0x22,0xAA,0x66,0x22,0x22,0x26,0x6A,0xB2,0x22,0x22,0x22,0xAA,0x44, + /* 0xF4E7 [?] [7873]*/ + 0x00,0xFE,0x00,0x7C,0x44,0x7C,0x00,0xFE,0x82,0xAA,0x92,0xFE,0x92,0x92,0x92,0x86, + 0x00,0xEE,0x22,0x22,0xAA,0x66,0x22,0x22,0x26,0x6A,0xB2,0x22,0x22,0x22,0xAA,0x44, + /* 0xF4E8 [?] [7874]*/ + 0x00,0x7F,0x48,0x5F,0x64,0x5F,0x44,0x4A,0x51,0x7F,0x00,0x7E,0x22,0x1A,0x62,0x06, + 0x00,0x78,0x48,0x4C,0x80,0x78,0x48,0x48,0x30,0x4C,0x00,0xFC,0x44,0x34,0xC4,0x0C, + /* 0xF4E9 [?] [7875]*/ + 0x02,0x04,0x08,0x10,0x3F,0x01,0x06,0x18,0x7F,0x01,0x09,0x09,0x11,0x21,0x45,0x02, + 0x00,0x00,0x20,0x40,0x80,0x00,0x10,0x08,0xFC,0x04,0x20,0x10,0x08,0x04,0x04,0x00, + /* 0xF4EA [?] [7876]*/ + 0x10,0xFB,0x10,0x19,0xF0,0x11,0x52,0x24,0x1F,0x01,0x06,0x3F,0x01,0x11,0x25,0x42, + 0x80,0xF0,0x90,0x90,0x94,0x54,0x0C,0x24,0xC0,0x80,0x10,0xF8,0x08,0x20,0x10,0x08, + /* 0xF4EB [?] [7877]*/ + 0x08,0x7F,0x08,0x0F,0x08,0x0F,0x08,0xFF,0x14,0x28,0xDF,0x02,0x3F,0x01,0x15,0x22, + 0x20,0xFC,0x20,0xE0,0x20,0xE0,0x20,0xFE,0x50,0x88,0x06,0x10,0xF8,0x08,0x20,0x10, + /* 0xF4EC [?] [7878]*/ + 0x10,0x08,0x3E,0x22,0x23,0x3E,0x20,0x41,0x84,0x08,0x1F,0x02,0x3F,0x01,0x15,0x22, + 0x40,0x40,0x7E,0x88,0x50,0x20,0x58,0x86,0x40,0x80,0x00,0x10,0xF8,0x08,0x20,0x10, + /* 0xF4ED [?] [7879]*/ + 0x00,0x0E,0xF0,0x22,0x92,0x44,0x20,0x3C,0x50,0x10,0xFE,0x10,0x54,0x55,0x5C,0x64, + 0x00,0x0C,0xF0,0x20,0x44,0xF8,0x10,0x24,0xFE,0x12,0x50,0x54,0x92,0x12,0x50,0x20, + /* 0xF4EE [?] [7880]*/ + 0x01,0xFF,0x01,0x1F,0x12,0xFF,0x10,0x1F,0x00,0x3E,0x22,0x2A,0x2A,0xFF,0x2A,0x59, + 0x00,0xFE,0x00,0xF0,0x10,0xFE,0x90,0xF0,0x1C,0xE0,0x24,0xF8,0x24,0xFE,0x54,0xB2, + /* 0xF4EF [?] [7881]*/ + 0x10,0x10,0xFE,0x10,0x7D,0x10,0xFE,0x20,0x3D,0x44,0x48,0xA8,0x10,0x28,0x41,0x82, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF4F0 [?] [7882]*/ + 0x10,0x10,0xFE,0x55,0x56,0xBA,0x10,0x38,0x55,0xA2,0x3C,0x44,0xA9,0x10,0x28,0xC0, + 0x80,0x80,0xFE,0x02,0x22,0xAA,0x72,0x22,0xFE,0x22,0x72,0xAA,0x22,0x22,0x0A,0x04, + /* 0xF4F1 [?] [7883]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFF,0x08,0x28,0x28,0x2E,0x28,0x28,0x58,0x4F,0x80, + 0x04,0x04,0x44,0x44,0x44,0x44,0x44,0x4C,0x54,0x64,0x04,0x04,0x04,0x00,0xFE,0x00, + /* 0xF4F2 [?] [7884]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFF,0x08,0x28,0x28,0x2E,0x29,0x28,0x58,0x4F,0x80, + 0x00,0xF8,0x88,0x88,0xF8,0x88,0x88,0xF8,0x88,0x88,0x88,0xFE,0x00,0x00,0xFE,0x00, + /* 0xF4F3 [?] [7885]*/ + 0x10,0x13,0x10,0x7C,0x10,0x11,0xFD,0x11,0x12,0x50,0x5C,0x50,0x51,0x72,0x50,0x8F, + 0x02,0xF2,0x82,0x8A,0x8A,0xEA,0x2A,0x2A,0xAA,0x4A,0x4A,0x82,0x0A,0x04,0x00,0xFE, + /* 0xF4F4 [?] [7886]*/ + 0x10,0x12,0x11,0x7D,0x10,0x10,0xFC,0x10,0x13,0x51,0x5D,0x51,0x51,0x70,0x50,0x8F, + 0x20,0x20,0x20,0x3E,0x42,0x84,0x90,0x90,0x10,0x10,0x28,0x24,0x42,0x82,0x00,0xFE, + /* 0xF4F5 [?] [7887]*/ + 0x11,0x15,0x17,0x79,0x17,0x13,0xFD,0x19,0x13,0x52,0x5A,0x52,0x50,0x71,0x52,0x8F, + 0x08,0x28,0xBE,0x48,0xBE,0x18,0xAA,0x46,0xF8,0x08,0x48,0x48,0xA0,0x10,0x08,0xFE, + /* 0xF4F6 [?] [7888]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFF,0x14,0x14,0x56,0x55,0x94,0x24,0x24,0x54,0x88, + 0x00,0xFC,0x84,0x84,0x94,0x88,0x80,0xFC,0xA4,0xA4,0xA8,0xA8,0x90,0xA8,0xC4,0x82, + /* 0xF4F7 [?] [7889]*/ + 0x08,0x08,0x08,0x7E,0x08,0x08,0xFF,0x14,0x14,0x56,0x55,0x95,0x24,0x24,0x54,0x88, + 0x20,0x24,0xF4,0x28,0x28,0xFE,0x10,0x20,0x7C,0xC4,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xF4F8 [?] [7890]*/ + 0x00,0xFE,0x01,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x44,0x28,0x2E,0xF0,0x43,0x00, + 0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x00, + /* 0xF4F9 [?] [7891]*/ + 0x00,0xFE,0x00,0x01,0x7C,0x44,0x44,0x45,0x7C,0x00,0x44,0x28,0x2E,0xF0,0x41,0x06, + 0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xF4FA [?] [7892]*/ + 0x00,0xFF,0x14,0x14,0x7F,0x55,0x55,0x55,0x57,0x61,0x41,0x7F,0x41,0x41,0x7F,0x41, + 0x00,0x80,0x7E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + /* 0xF4FB [?] [7893]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + /* 0xF4FC [?] [7894]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x08,0x08,0x08,0x08,0xFE,0x08,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x28,0x10, + /* 0xF4FD [?] [7895]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAB,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x20,0x20,0xA0,0xAC,0xB4,0xE4,0xA4,0xA4,0xB4,0xA8,0xA2,0xA2,0x82,0x7E,0x00, + /* 0xF4FE [?] [7896]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x7C,0x44,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xF5A1 [?] [7897]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAB,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x40,0x40,0x40,0x7E,0xA0,0xA0,0x20,0x3C,0x20,0x20,0x20,0x3E,0x20,0x20,0x20,0x20, + /* 0xF5A2 [?] [7898]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x10,0x10,0xFE,0x82,0x84,0x40,0x44,0x48,0x50,0x60,0x42,0x42,0x42,0x3E,0x00, + /* 0xF5A3 [?] [7899]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x10,0x50,0x50,0x7C,0x90,0x10,0x10,0xFE,0x28,0x28,0x28,0x28,0x4A,0x4A,0x86,0x00, + /* 0xF5A4 [?] [7900]*/ + 0x00,0xFE,0x28,0x28,0xFF,0xAA,0xAA,0xAA,0xAE,0xC2,0x83,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x20,0x7E,0x82,0x44,0x28,0x10,0x20,0x40,0xFE,0x42,0x42,0x42,0x42,0x7E,0x42, + /* 0xF5A5 [?] [7901]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x80,0x82,0x8C,0xF0,0x82,0x82,0x7E,0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84, + /* 0xF5A6 [?] [7902]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x83,0xFF,0x82, + 0x00,0xFE,0x28,0xAA,0x6C,0x28,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00, + /* 0xF5A7 [?] [7903]*/ + 0x00,0xFB,0x20,0x20,0xFB,0xAA,0xAA,0xAA,0xDB,0x8A,0x8A,0xFA,0x8A,0x8A,0xFA,0x8A, + 0x00,0xFE,0x00,0x00,0xDE,0x52,0x52,0x52,0x5A,0xD6,0x52,0x52,0x52,0x52,0x52,0xD6, + /* 0xF5A8 [?] [7904]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x00,0xFE,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00, + /* 0xF5A9 [?] [7905]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x83,0xFE,0x82, + 0x10,0x10,0x28,0x28,0x44,0xBA,0x10,0x10,0xFE,0x10,0x58,0x54,0x92,0x12,0x50,0x20, + /* 0xF5AA [?] [7906]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAF,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x04,0x1E,0xE0,0x22,0x92,0x54,0x40,0x08,0xFE,0x08,0x88,0x48,0x48,0x08,0x28,0x10, + /* 0xF5AB [?] [7907]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x00,0x90,0x92,0xF4,0x98,0x92,0xD2,0x8E, + /* 0xF5AC [?] [7908]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x20,0x10,0xFC,0x00,0x84,0x48,0x00,0xFE,0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xF5AD [?] [7909]*/ + 0x01,0xF9,0x21,0x27,0xF9,0xA9,0xA9,0xAB,0xDA,0x8A,0x8A,0xFA,0x8B,0x88,0xF8,0x88, + 0x00,0x3C,0x24,0xE4,0x24,0x3C,0x24,0xA4,0xA4,0xBC,0xA4,0xA4,0xA4,0x44,0x54,0x88, + /* 0xF5AE [?] [7910]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAB,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x00,0xFE,0x10,0x10,0x5E,0x50,0x50,0xB0,0x9E,0x00, + /* 0xF5AF [?] [7911]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0xFC,0x14,0x50,0x5C,0x50,0x7E,0x80,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x4C, + /* 0xF5B0 [?] [7912]*/ + 0x00,0xF8,0x23,0x20,0xF8,0xA9,0xAA,0xAC,0xD8,0x88,0x89,0xF9,0x89,0x89,0xFB,0x88, + 0x20,0x20,0xFC,0x40,0x80,0xF8,0x88,0x88,0xF8,0x00,0xFC,0x54,0x54,0x54,0xFE,0x00, + /* 0xF5B1 [?] [7913]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x20,0x10,0xFE,0x90,0xBC,0x94,0xFE,0x94,0xBC,0x90,0xBC,0xA4,0xA4,0xA4,0xBC,0x24, + /* 0xF5B2 [?] [7914]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC3,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x00,0xEE,0x22,0xAA,0x66,0xAA,0x10,0x28,0x44,0x92,0x20,0xC8,0x32,0xC4,0x18,0xE0, + /* 0xF5B3 [?] [7915]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x28,0xAA,0x6C,0x28,0xFE,0x44,0x28,0xFE,0x10,0x7C,0x10,0xFE,0x10,0x28,0x44,0x82, + /* 0xF5B4 [?] [7916]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAB,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x83, + 0x28,0x24,0x40,0x7E,0xC8,0x48,0x7E,0x48,0x48,0x7E,0x48,0x48,0x7E,0x40,0xAA,0x2A, + /* 0xF5B5 [?] [7917]*/ + 0x00,0xF8,0x23,0x20,0xF8,0xA9,0xA8,0xA8,0xD9,0x8A,0x89,0xF9,0x89,0x89,0xFB,0x88, + 0x40,0x20,0xFE,0x40,0x84,0xFE,0xA8,0xAA,0x26,0x00,0xFC,0x54,0x54,0x54,0xFE,0x00, + /* 0xF5B6 [?] [7918]*/ + 0x00,0xF8,0x20,0x23,0xFA,0xAA,0xAB,0xAA,0xDA,0x8B,0x8A,0xFB,0x8A,0x8D,0xFC,0x89, + 0x40,0x7C,0x40,0xFE,0x42,0x78,0xC4,0x3C,0x00,0xFE,0x40,0xA4,0x58,0xB4,0x52,0xB0, + /* 0xF5B7 [?] [7919]*/ + 0x00,0xFE,0x28,0x28,0xFE,0xAA,0xAA,0xAA,0xAE,0xC2,0x82,0xFE,0x82,0x82,0xFE,0x82, + 0x28,0xFE,0xAA,0xFE,0xAA,0xFE,0x00,0xFE,0x00,0xFE,0x82,0xFE,0x44,0x28,0xFE,0x00, + /* 0xF5B8 [?] [7920]*/ + 0x00,0xF9,0x20,0x23,0xF8,0xA9,0xA9,0xA9,0xD9,0x88,0x89,0xF8,0x8B,0x88,0xF9,0x8A, + 0x1C,0xE0,0x20,0xFE,0x20,0xFC,0xAC,0x74,0xFC,0x20,0xFC,0x20,0xFE,0x00,0x54,0x2A, + /* 0xF5B9 [?] [7921]*/ + 0x00,0x7F,0x02,0x06,0x09,0x11,0x62,0x04,0x08,0x11,0x62,0x04,0x08,0x30,0xC2,0x01, + 0x00,0xFC,0x00,0x00,0x08,0x90,0xA0,0xC0,0xC0,0xA0,0x90,0x88,0x86,0x80,0x80,0x00, + /* 0xF5BA [?] [7922]*/ + 0x20,0x20,0x3C,0x21,0x20,0xFC,0x84,0x95,0xD4,0xA4,0xD4,0x95,0x86,0xFC,0x85,0x00, + 0x84,0x44,0x48,0xFE,0x20,0xFC,0x20,0xFE,0x40,0x80,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xF5BB [?] [7923]*/ + 0x00,0xFF,0x04,0x07,0x08,0x10,0x60,0x00,0x1F,0x10,0x1F,0x01,0x11,0x11,0x29,0x47, + 0x00,0xFE,0x00,0xF0,0x10,0xA0,0x40,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x00,0x00,0xFE, + /* 0xF5BC [?] [7924]*/ + 0x00,0x7D,0x11,0x11,0x11,0x1D,0xE2,0x44,0x1F,0x10,0x1F,0x01,0x11,0x11,0x29,0x47, + 0x00,0xF0,0x10,0x90,0x52,0x12,0x0E,0x00,0xF0,0x10,0xF0,0x00,0xF8,0x00,0x00,0xFE, + /* 0xF5BD [?] [7925]*/ + 0x08,0x08,0x7E,0x08,0x0E,0x78,0x08,0x29,0x12,0x1F,0x10,0x1F,0x01,0x11,0x31,0xCF, + 0x0C,0xF0,0x80,0x80,0xFE,0x88,0x88,0x08,0x08,0xF0,0x10,0xF0,0x00,0xF8,0x00,0xFE, + /* 0xF5BE [?] [7926]*/ + 0x00,0x3F,0x22,0x23,0x22,0x3F,0x2B,0x52,0x46,0x9F,0x10,0x1F,0x01,0x11,0x31,0xCF, + 0x24,0xFE,0x20,0xA4,0x24,0xA8,0x10,0x9A,0x26,0xF2,0x10,0xF0,0x00,0xF8,0x00,0xFE, + /* 0xF5BF [?] [7927]*/ + 0x49,0x2A,0x7F,0x49,0x5D,0x6B,0x49,0x41,0x1F,0x10,0x1F,0x01,0x11,0x11,0x29,0x47, + 0x20,0x3E,0x48,0x48,0xA8,0x10,0x28,0x46,0xF0,0x10,0xF0,0x00,0xF8,0x00,0x00,0xFE, + /* 0xF5C0 [?] [7928]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7D,0x10,0x11,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x00,0x00, + 0x40,0x40,0x40,0xFC,0x84,0x04,0x04,0x04,0x84,0x44,0x44,0x04,0x04,0x04,0x28,0x10, + /* 0xF5C1 [?] [7929]*/ + 0x00,0x7B,0x48,0x48,0x48,0x78,0x10,0x10,0x51,0x5D,0x51,0x51,0x5A,0xE2,0x04,0x01, + 0x00,0xFC,0x84,0x88,0x88,0x90,0x9C,0x84,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xF5C2 [?] [7930]*/ + 0x00,0x7D,0x44,0x44,0x44,0x7C,0x10,0x13,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x01,0x02, + 0x00,0xFE,0x48,0x48,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x48,0x88,0x88,0x08,0x08, + /* 0xF5C3 [?] [7931]*/ + 0x00,0x7C,0x44,0x44,0x45,0x7C,0x10,0x10,0x5D,0x50,0x50,0x50,0x5C,0xE0,0x01,0x02, + 0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF5C4 [?] [7932]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7D,0x12,0x10,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x00,0x00, + 0x20,0x20,0x50,0x50,0x88,0x04,0x02,0xF8,0x88,0x88,0xA8,0x90,0x82,0x82,0x7E,0x00, + /* 0xF5C5 [?] [7933]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7C,0x10,0x10,0x10,0x5D,0x52,0x50,0x50,0x5C,0xE0,0x00, + 0x00,0x00,0xFE,0x20,0x20,0x40,0x40,0xFC,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF5C6 [?] [7934]*/ + 0x00,0x78,0x48,0x49,0x49,0x7B,0x15,0x11,0x51,0x5D,0x51,0x51,0x59,0xE1,0x01,0x01, + 0x88,0x88,0x88,0x08,0x7E,0x08,0x08,0x48,0x28,0x28,0x08,0x08,0x08,0x08,0x28,0x10, + /* 0xF5C7 [?] [7935]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x13,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x00,0xDC,0x54,0x54,0x54,0x54,0x54,0xFE,0x54,0x54,0x54,0x54,0x54,0xD4,0x24,0x4C, + /* 0xF5C8 [?] [7936]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x5C,0x50,0x50,0x50,0x5D,0xE2,0x00,0x00, + 0x08,0x1C,0xE0,0x00,0x20,0x20,0x20,0xFE,0x20,0x20,0xA8,0xA4,0x22,0x22,0xA0,0x40, + /* 0xF5C9 [?] [7937]*/ + 0x00,0x7C,0x44,0x45,0x45,0x7E,0x10,0x10,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x00,0x00, + 0x20,0x10,0x10,0xFE,0x02,0x04,0x80,0x88,0x90,0xA0,0xC0,0x82,0x82,0x82,0x7E,0x00, + /* 0xF5CA [?] [7938]*/ + 0x01,0x79,0x49,0x49,0x4B,0x79,0x11,0x11,0x51,0x5D,0x51,0x51,0x59,0xE2,0x03,0x04, + 0x00,0x00,0x00,0x1C,0xD4,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5C,0x54,0x80, + /* 0xF5CB [?] [7939]*/ + 0x00,0x7C,0x44,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x10,0x10,0x10,0xFE,0x12,0x14,0x10,0xFC,0x44,0x44,0x28,0x28,0x10,0x28,0x44,0x82, + /* 0xF5CC [?] [7940]*/ + 0x00,0x7C,0x44,0x44,0x44,0x7D,0x13,0x10,0x10,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01, + 0x20,0x20,0x40,0x40,0x88,0x04,0xFE,0x02,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF5CD [?] [7941]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7C,0x13,0x10,0x5C,0x50,0x51,0x50,0x5C,0xE0,0x03,0x00, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xF5CE [?] [7942]*/ + 0x00,0x7C,0x44,0x47,0x44,0x7C,0x10,0x13,0x5C,0x53,0x50,0x50,0x5D,0xE1,0x02,0x04, + 0x80,0x80,0xBC,0xC0,0x50,0x24,0xD4,0x0C,0x00,0xFE,0x90,0x90,0x12,0x12,0x0E,0x00, + /* 0xF5CF [?] [7943]*/ + 0x01,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x11,0x5C,0x53,0x50,0x50,0x5C,0xE0,0x00, + 0x10,0x12,0x14,0xD8,0x10,0x12,0x52,0x8E,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20, + /* 0xF5D0 [?] [7944]*/ + 0x00,0x79,0x49,0x49,0x49,0x7A,0x10,0x13,0x50,0x5C,0x50,0x50,0x59,0xE1,0x02,0x04, + 0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x90,0x90,0x90,0x90,0x12,0x12,0x12,0x0E, + /* 0xF5D1 [?] [7945]*/ + 0x00,0x7A,0x49,0x49,0x48,0x78,0x10,0x17,0x51,0x5D,0x51,0x51,0x59,0xE2,0x04,0x00, + 0x00,0x0C,0x70,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x7E,0x00, + /* 0xF5D2 [?] [7946]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7C,0x10,0x10,0x11,0x5C,0x50,0x50,0x50,0x5D,0xE1,0x02, + 0x40,0x20,0xFE,0x88,0x50,0x20,0x50,0x88,0x06,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xF5D3 [?] [7947]*/ + 0x00,0x7C,0x44,0x45,0x44,0x7C,0x11,0x12,0x10,0x5C,0x50,0x50,0x50,0x5C,0xE0,0x03, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xF5D4 [?] [7948]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01, + 0x40,0x20,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x20,0x22,0x14,0x08,0x44,0x82,0x00, + /* 0xF5D5 [?] [7949]*/ + 0x00,0x7D,0x44,0x44,0x45,0x7D,0x11,0x11,0x5C,0x50,0x50,0x50,0x5E,0xE2,0x04,0x00, + 0x00,0xF8,0x08,0x08,0xF8,0x00,0x04,0x04,0xFC,0x40,0x20,0xA4,0x8A,0x8A,0x78,0x00, + /* 0xF5D6 [?] [7950]*/ + 0x00,0x7C,0x44,0x44,0x45,0x7D,0x11,0x11,0x5D,0x51,0x50,0x53,0x5C,0xE0,0x00,0x00, + 0x20,0x20,0x3E,0x20,0xFC,0x04,0xFC,0x04,0xFC,0x24,0x20,0xFE,0x20,0x20,0x20,0x20, + /* 0xF5D7 [?] [7951]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x10,0x5D,0x50,0x50,0x51,0x5E,0xE0,0x00, + 0x00,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xF5D8 [?] [7952]*/ + 0x01,0x79,0x49,0x4B,0x4A,0x7C,0x10,0x10,0x53,0x5C,0x50,0x51,0x59,0xE2,0x04,0x08, + 0x00,0x00,0x00,0xDE,0x92,0x92,0x92,0x92,0xF2,0x92,0x92,0x52,0x5E,0x20,0x20,0x00, + /* 0xF5D9 [?] [7953]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x1C,0xE0,0x10,0x10,0xFE,0x10,0x10,0x7C,0x44,0x54,0x54,0x54,0x54,0x28,0x44,0x82, + /* 0xF5DA [?] [7954]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x20,0x10,0xFE,0x00,0x20,0x20,0x3C,0x20,0x20,0x7C,0x44,0x44,0x44,0x44,0x7C,0x44, + /* 0xF5DB [?] [7955]*/ + 0x00,0x7C,0x45,0x44,0x45,0x7C,0x10,0x13,0x10,0x5C,0x51,0x51,0x51,0x5D,0xE1,0x01, + 0x40,0x20,0xFC,0x00,0x08,0x90,0x00,0xFE,0x00,0x00,0xFC,0x04,0x04,0x04,0xFC,0x04, + /* 0xF5DC [?] [7956]*/ + 0x04,0xF2,0x92,0x90,0x97,0xF1,0x21,0x21,0xA7,0xB9,0xA1,0xA1,0xBA,0xE2,0x04,0x08, + 0x40,0x5E,0x92,0x12,0xD4,0x14,0x18,0x14,0xF2,0x12,0x12,0x1A,0x94,0x50,0x50,0x10, + /* 0xF5DD [?] [7957]*/ + 0x00,0x78,0x4F,0x49,0x49,0x7A,0x12,0x17,0x51,0x5D,0x55,0x52,0x5A,0xE5,0x08,0x00, + 0x10,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x10,0xFE,0x10,0x10,0x00,0xFE,0x00, + /* 0xF5DE [?] [7958]*/ + 0x00,0x7D,0x45,0x47,0x45,0x7D,0x11,0x11,0x5D,0x50,0x53,0x50,0x5C,0xE1,0x06,0x00, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xF5DF [?] [7959]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7C,0x13,0x10,0x5C,0x51,0x51,0x51,0x5D,0xE1,0x01,0x01, + 0x20,0x24,0x24,0x24,0xFC,0x00,0xFE,0x20,0x40,0xFC,0x54,0x54,0x54,0x54,0x54,0x0C, + /* 0xF5E0 [?] [7960]*/ + 0x00,0x7C,0x45,0x44,0x47,0x7C,0x11,0x11,0x5D,0x51,0x51,0x50,0x5D,0xE0,0x03,0x00, + 0x08,0x3C,0xE0,0x20,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xF5E1 [?] [7961]*/ + 0x00,0x7C,0x47,0x44,0x45,0x7D,0x11,0x11,0x5C,0x53,0x52,0x52,0x5E,0xE2,0x02,0x02, + 0x04,0x1E,0xE0,0x20,0xFC,0x24,0x24,0xFC,0x20,0xFE,0x22,0x2A,0xFA,0x02,0x0A,0x04, + /* 0xF5E2 [?] [7962]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE2,0x02,0x04, + 0x40,0x20,0xFE,0x48,0x48,0xFE,0x48,0x78,0x00,0xFC,0x44,0x48,0x28,0x10,0x28,0xC6, + /* 0xF5E3 [?] [7963]*/ + 0x00,0x7C,0x44,0x45,0x44,0x7C,0x10,0x11,0x5C,0x50,0x50,0x51,0x5E,0xE4,0x01,0x00, + 0x84,0x44,0x48,0xFE,0x20,0xFC,0x20,0xFE,0x40,0x80,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xF5E4 [?] [7964]*/ + 0x00,0x7C,0x45,0x45,0x45,0x7D,0x11,0x11,0x5D,0x51,0x51,0x52,0x5E,0xE2,0x04,0x00, + 0x40,0x20,0xFE,0x02,0x02,0xFE,0x00,0x00,0xFE,0xAA,0xAA,0xFE,0xAA,0xAA,0xA2,0x86, + /* 0xF5E5 [?] [7965]*/ + 0x00,0x7D,0x44,0x44,0x47,0x7C,0x10,0x11,0x5E,0x50,0x53,0x50,0x5C,0xE1,0x06,0x00, + 0x00,0xFC,0x48,0x30,0xFE,0x52,0x94,0x10,0x30,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xF5E6 [?] [7966]*/ + 0x00,0x7D,0x44,0x44,0x44,0x7C,0x10,0x13,0x5C,0x53,0x50,0x51,0x5C,0xE1,0x02,0x04, + 0x00,0xFE,0x84,0xFC,0x84,0xFC,0x86,0xFC,0x04,0xDE,0x52,0x52,0x94,0x48,0x54,0x22, + /* 0xF5E7 [?] [7967]*/ + 0x00,0x7C,0x45,0x44,0x44,0x7D,0x10,0x10,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01,0x01, + 0x48,0x48,0xFE,0x48,0x00,0xFE,0x48,0x48,0xFE,0x4A,0x4A,0xB6,0x22,0x02,0x0A,0x04, + /* 0xF5E8 [?] [7968]*/ + 0x00,0x7B,0x49,0x48,0x48,0x78,0x11,0x10,0x50,0x5D,0x50,0x50,0x5B,0xE0,0x00,0x03, + 0x1E,0xE0,0x22,0x94,0x40,0x88,0xF0,0x20,0xC4,0xFE,0x22,0x20,0xFE,0x50,0x88,0x06, + /* 0xF5E9 [?] [7969]*/ + 0x00,0x7B,0x4A,0x4A,0x4B,0x7A,0x12,0x12,0x52,0x5E,0x52,0x52,0x5A,0xE2,0x05,0x00, + 0x00,0xFE,0x00,0x04,0xF4,0x04,0xEE,0xA4,0xA4,0xEC,0x04,0xA4,0x44,0x74,0x94,0x08, + /* 0xF5EA [?] [7970]*/ + 0x00,0xF7,0x94,0x96,0x95,0xF7,0x24,0x24,0xA6,0xBE,0xA7,0xA4,0xBC,0xE5,0x09,0x12, + 0x00,0xFE,0x00,0x28,0x48,0xEE,0x92,0x84,0xA0,0xA8,0xE8,0x88,0x94,0x14,0x24,0x42, + /* 0xF5EB [?] [7971]*/ + 0x00,0x7A,0x49,0x48,0x4B,0x78,0x10,0x13,0x50,0x5D,0x50,0x53,0x58,0xE0,0x01,0x06, + 0x50,0x52,0x54,0x50,0xFE,0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xF5EC [?] [7972]*/ + 0x00,0x7D,0x45,0x44,0x45,0x7C,0x11,0x12,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01,0x01, + 0x3C,0xE0,0x24,0xA8,0xFE,0xA8,0x24,0x02,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x04, + /* 0xF5ED [?] [7973]*/ + 0x02,0xF1,0x9F,0x90,0x90,0xF7,0x24,0x24,0xA7,0xB9,0xA5,0xA5,0xA9,0xB1,0xC5,0x02, + 0x14,0x12,0xD2,0x10,0x7E,0x90,0x90,0x90,0x90,0x28,0xA8,0x68,0x28,0x4A,0x4A,0x86, + /* 0xF5EE [?] [7974]*/ + 0x00,0x7D,0x45,0x45,0x45,0x7C,0x11,0x12,0x11,0x5D,0x51,0x51,0x50,0x5D,0xE0,0x00, + 0x00,0xFC,0x54,0x54,0xFC,0x80,0xFC,0x44,0xF4,0x54,0x54,0xF4,0x44,0xF4,0x14,0x08, + /* 0xF5EF [?] [7975]*/ + 0x00,0x7D,0x44,0x45,0x44,0x7C,0x11,0x11,0x11,0x5D,0x51,0x51,0x51,0x5D,0xE1,0x01, + 0x48,0xFE,0x48,0x00,0xBE,0x82,0x52,0x7E,0xD2,0x7E,0x52,0x7E,0x52,0x7E,0x42,0x06, + /* 0xF5F0 [?] [7976]*/ + 0x00,0xF7,0x94,0x95,0x95,0xF5,0x25,0x25,0xA4,0xBD,0xA4,0xA7,0xBD,0xEA,0x08,0x13, + 0x20,0xFE,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x24,0xFA,0x20,0xFE, + /* 0xF5F1 [?] [7977]*/ + 0x01,0x7A,0x49,0x48,0x4B,0x7A,0x12,0x12,0x13,0x5E,0x53,0x52,0x53,0x5E,0xE2,0x03, + 0x24,0x48,0x24,0x00,0xFC,0x94,0x64,0x94,0xFC,0x48,0x68,0x48,0x6A,0x4A,0x46,0x62, + /* 0xF5F2 [?] [7978]*/ + 0x01,0xF5,0x97,0x99,0x97,0xF3,0x25,0x29,0xA0,0xBB,0xA2,0xA2,0xBA,0xE0,0x01,0x06, + 0x08,0x28,0xBE,0x48,0xBE,0x18,0xAA,0x46,0x00,0xF8,0x08,0x48,0x48,0xB0,0x08,0x04, + /* 0xF5F3 [?] [7979]*/ + 0x02,0xF2,0x93,0x96,0x9A,0xF2,0x22,0x22,0xA5,0xB8,0xA0,0xA3,0xB9,0xE0,0x03,0x0C, + 0x48,0xE8,0x08,0xEA,0x1C,0xE8,0x08,0xE8,0xB4,0xE2,0x00,0xF8,0x10,0xE0,0x18,0x06, + /* 0xF5F4 [?] [7980]*/ + 0x00,0x07,0x7A,0x11,0x08,0x07,0x78,0x00,0x03,0x0C,0x70,0x01,0x06,0x18,0xE0,0x00, + 0xE0,0x00,0x0C,0x30,0xC0,0x80,0x40,0xA0,0x30,0x50,0x90,0x10,0x10,0x10,0xA0,0x40, + /* 0xF5F5 [?] [7981]*/ + 0x0C,0x31,0xC2,0x14,0x48,0x30,0xC8,0x14,0x25,0xCC,0x14,0x24,0xC4,0x04,0x28,0x10, + 0x00,0xFC,0x44,0x44,0x44,0x44,0x94,0x88,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF5F6 [?] [7982]*/ + 0x0C,0x30,0xC2,0x14,0x48,0x30,0xC8,0x14,0x24,0xCC,0x14,0x24,0xC4,0x04,0x28,0x10, + 0x00,0xFE,0x20,0x20,0x40,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF5F7 [?] [7983]*/ + 0x10,0x20,0xD4,0x09,0x51,0x23,0xD5,0x19,0x29,0xC9,0x19,0x29,0xC9,0x09,0x51,0x21, + 0x90,0x90,0x90,0x10,0xFE,0x10,0x10,0x38,0x38,0x54,0x54,0x92,0x10,0x10,0x10,0x10, + /* 0xF5F8 [?] [7984]*/ + 0x0C,0x30,0xC3,0x14,0x48,0x31,0xC9,0x15,0x25,0xCD,0x14,0x25,0xC4,0x04,0x29,0x12, + 0x88,0x88,0xFE,0x88,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x20,0xFE,0x50,0x88,0x04,0x02, + /* 0xF5F9 [?] [7985]*/ + 0x0C,0x30,0xC3,0x15,0x49,0x31,0xC9,0x15,0x25,0xCC,0x15,0x25,0xC5,0x05,0x29,0x11, + 0x20,0x40,0xFC,0x04,0x54,0x24,0x54,0x04,0xFC,0x00,0x12,0xD4,0x18,0x52,0x92,0x0E, + /* 0xF5FA [?] [7986]*/ + 0x10,0x10,0x3C,0x24,0x48,0xBE,0x2A,0x2A,0x3E,0x2A,0x2A,0x3E,0x2A,0x4A,0x42,0x86, + 0x08,0x88,0x48,0x48,0x08,0x88,0x48,0x48,0x08,0x0E,0xF8,0x08,0x08,0x08,0x08,0x08, + /* 0xF5FB [?] [7987]*/ + 0x20,0x20,0x78,0x49,0x90,0x7C,0x54,0x54,0x7D,0x54,0x54,0x7C,0x54,0x54,0x45,0x8E, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x88,0x04,0x02, + /* 0xF5FC [?] [7988]*/ + 0x10,0x10,0x3C,0x24,0x49,0xBE,0x2A,0x2A,0x3E,0x2A,0x2A,0x3E,0x2B,0x4A,0x42,0x86, + 0x40,0x40,0x7E,0x80,0x7C,0x08,0x10,0x20,0xFE,0x4A,0x4A,0x92,0x12,0x22,0x54,0x88, + /* 0xF5FD [?] [7989]*/ + 0x20,0x20,0x79,0x49,0x91,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x55,0x56,0x46,0x8C, + 0x08,0x1C,0xF0,0x50,0x50,0x50,0x50,0x50,0x50,0x48,0x48,0x68,0x54,0x74,0x52,0x00, + /* 0xF5FE [?] [7990]*/ + 0x08,0x28,0x2E,0x28,0x2E,0xF0,0x08,0x0F,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x11,0x21, + 0x80,0x88,0xF0,0x84,0x84,0x7C,0x00,0xC0,0x80,0xF8,0x08,0xF8,0x08,0xF8,0x08,0x18, + /* 0xF6A1 [?] [7991]*/ + 0x20,0x20,0x79,0x48,0x90,0x7C,0x55,0x54,0x7C,0x54,0x54,0x7C,0x55,0x55,0x46,0x8C, + 0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x0E,0x00, + /* 0xF6A2 [?] [7992]*/ + 0x20,0x20,0x79,0x48,0x90,0x7D,0x55,0x55,0x7D,0x54,0x54,0x7C,0x55,0x56,0x44,0x8C, + 0x20,0x20,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x20,0x70,0xA8,0x24,0x22,0x20,0x20, + /* 0xF6A3 [?] [7993]*/ + 0x21,0x20,0x78,0x49,0x91,0x7D,0x55,0x55,0x7D,0x55,0x54,0x7C,0x57,0x54,0x44,0x8C, + 0x04,0x88,0x50,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0x20,0xFE,0x20,0x20,0x20, + /* 0xF6A4 [?] [7994]*/ + 0x08,0x28,0x2E,0x28,0x2E,0xF0,0x01,0x7F,0x00,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x3F, + 0x80,0x88,0xF0,0x84,0x84,0x7C,0x00,0xFC,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x08,0xF8, + /* 0xF6A5 [?] [7995]*/ + 0x08,0xFF,0x08,0x3E,0x2A,0x3E,0x41,0xFF,0x00,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x3F, + 0x78,0x48,0x86,0x78,0x48,0x30,0x48,0xFC,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x08,0xF8, + /* 0xF6A6 [?] [7996]*/ + 0x10,0x10,0xFE,0x10,0x7C,0x10,0xFE,0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x54,0x49, + 0x00,0xFC,0x84,0x84,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0x50,0x50,0x50,0x92,0x92,0x0E, + /* 0xF6A7 [?] [7997]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x00,0xFF,0x04,0x0F,0x00,0x00,0x00, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x00,0xFE,0x00,0xF0,0x10,0xA0,0x40, + /* 0xF6A8 [?] [7998]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x3F,0x20,0x21,0x2F,0x21,0x42,0x44,0x98, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xFC,0x00,0x00,0xF8,0x08,0x08,0x50,0x20, + /* 0xF6A9 [?] [7999]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x02,0x01,0x7F,0x08,0x04,0x03,0x04,0x18,0xE0, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0x00,0xFC,0x20,0x40,0x80,0x40,0x30,0x0E, + /* 0xF6AA [?] [8000]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x7C,0x09,0x10,0x3D,0x44,0x2B,0x10,0x6F, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x08,0x3C,0xE0,0x20,0xFC,0x20,0xFE,0x00,0xFE, + /* 0xF6AB [?] [8001]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x00,0x7F,0x08,0x07,0x18,0xE4,0x04,0x08,0x10, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x80,0xFC,0x20,0xC0,0x30,0x4E,0x40,0x40,0x40, + /* 0xF6AC [?] [8002]*/ + 0x00,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x20,0x17,0x40,0x2B,0x0A,0x72,0x12,0x10, + 0x00,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x40,0xFC,0x40,0xF8,0x48,0x48,0x58,0x40, + /* 0xF6AD [?] [8003]*/ + 0x00,0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x04,0x7C,0x04,0x3C,0x04,0x7C,0x04,0x04, + 0x00,0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x40,0x7C,0x40,0x78,0x40,0x7C,0x40,0x40, + /* 0xF6AE [?] [8004]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x02,0x3F,0x08,0x7F,0x02,0xFF,0x08,0x07,0x78, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x00,0xF8,0x20,0xFC,0x00,0xFE,0x20,0xC0,0x38, + /* 0xF6AF [?] [8005]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x01,0x1D,0x20,0x17,0x82,0x41,0x17,0x20,0xEF,0x20,0x27, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x70,0x3C,0xC0,0x44,0x28,0xFC,0x40,0xFE,0x40,0xFC, + /* 0xF6B0 [?] [8006]*/ + 0x3F,0x01,0x7F,0x49,0x84,0x23,0x12,0x03,0x72,0x13,0x11,0x13,0x14,0x1A,0x13,0x00, + 0xF8,0x00,0xFE,0x22,0x14,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x44,0xA4,0xF4,0x0C, + /* 0xF6B1 [?] [8007]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x00,0x12,0x3F,0x12,0x7F,0x00,0x3F,0x21,0x3F,0x21,0x23, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0x20,0x20,0x3E,0x44,0xA4,0x24,0x28,0x10,0x28,0x46, + /* 0xF6B2 [?] [8008]*/ + 0x3F,0x01,0x7F,0x41,0x9D,0x30,0xCB,0x2D,0x31,0xC9,0x15,0x64,0x0D,0x34,0xC5,0x18, + 0xF8,0x00,0xFE,0x02,0x74,0x00,0xFC,0x24,0xFC,0x24,0xFC,0x20,0xFC,0x20,0xFE,0x00, + /* 0xF6B3 [?] [8009]*/ + 0x08,0x08,0x28,0x2F,0x28,0x28,0xFF,0x00,0x49,0x49,0x55,0x63,0x41,0x47,0x79,0x01, + 0x20,0x20,0x20,0x22,0x22,0x24,0x28,0x30,0x20,0x60,0xA0,0x22,0x22,0x22,0x1E,0x00, + /* 0xF6B4 [?] [8010]*/ + 0x08,0x08,0x28,0x2F,0x28,0x28,0xFF,0x00,0x49,0x49,0x55,0x63,0x41,0x47,0x79,0x01, + 0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0xFE,0x00, + /* 0xF6B5 [?] [8011]*/ + 0x10,0x10,0x50,0x5E,0x50,0x51,0xFE,0x00,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x02, + 0x40,0x40,0x7C,0x84,0x84,0xF4,0x94,0x94,0x94,0xF4,0x84,0xA8,0x92,0x82,0x7E,0x00, + /* 0xF6B6 [?] [8012]*/ + 0x08,0x08,0x28,0x2F,0x28,0x28,0xFF,0x00,0x49,0x49,0x55,0x63,0x41,0x47,0x79,0x01, + 0x00,0xFE,0x22,0x22,0x22,0x22,0x4A,0x44,0x80,0x7E,0x42,0x42,0x42,0x42,0x7E,0x42, + /* 0xF6B7 [?] [8013]*/ + 0x10,0x10,0x50,0x5E,0x50,0x50,0xFE,0x00,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x03, + 0x08,0x28,0x28,0x28,0xA8,0xAA,0xBC,0xA8,0xA8,0xA8,0xA8,0xA8,0xAA,0xBA,0xEA,0x86, + /* 0xF6B8 [?] [8014]*/ + 0x10,0x10,0x50,0x5E,0x50,0x50,0xFE,0x00,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x02, + 0x00,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0xA2,0xA4,0x98,0x90,0x88,0xA4,0xC2,0x80, + /* 0xF6B9 [?] [8015]*/ + 0x10,0x11,0x50,0x5E,0x50,0x50,0xFE,0x01,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF2,0x02, + 0x00,0xFC,0x20,0x20,0xFC,0x44,0x44,0xFE,0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84, + /* 0xF6BA [?] [8016]*/ + 0x08,0x08,0x28,0x2F,0x28,0x28,0xFF,0x00,0x49,0x49,0x55,0x63,0x41,0x47,0x79,0x01, + 0x00,0x7C,0x44,0x44,0x44,0x44,0x7C,0x10,0x10,0x50,0x5E,0x50,0x50,0x70,0x9E,0x00, + /* 0xF6BB [?] [8017]*/ + 0x10,0x10,0x50,0x5E,0x50,0x50,0xFE,0x00,0x92,0x92,0xAA,0xC6,0x82,0x8E,0xF3,0x02, + 0x00,0xFE,0x82,0x82,0xFE,0x80,0xFE,0x90,0xA4,0xFE,0x92,0x90,0xFC,0x90,0x10,0xFE, + /* 0xF6BC [?] [8018]*/ + 0x1F,0x10,0x10,0x1F,0x01,0x3F,0x21,0x21,0x3F,0x21,0x21,0x3F,0x21,0x01,0x01,0x00, + 0xF0,0x10,0x10,0xF0,0x00,0xF8,0x08,0x08,0xF8,0x08,0x08,0xF8,0x0A,0x02,0x02,0xFE, + /* 0xF6BD [?] [8019]*/ + 0x1F,0x00,0xFF,0x08,0x30,0xDF,0x10,0x1F,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x01,0x00, + 0xF0,0x00,0xFE,0x44,0x3C,0xF0,0x10,0xF0,0x00,0xF8,0x08,0xF8,0x08,0xFA,0x02,0xFE, + /* 0xF6BE [?] [8020]*/ + 0x00,0x3E,0x22,0x3F,0x11,0x1F,0x11,0xFF,0x01,0x3F,0x21,0x3F,0x21,0x3F,0x01,0x00, + 0x00,0xF8,0x88,0xF8,0x10,0xF0,0x10,0xFE,0x00,0xF8,0x08,0xF8,0x08,0xFA,0x02,0xFE, + /* 0xF6BF [?] [8021]*/ + 0x09,0x08,0x08,0x1F,0x10,0x30,0x5F,0x90,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10, + 0x00,0x80,0x80,0xFC,0x80,0x80,0xF8,0x80,0x80,0xF8,0x80,0x80,0x80,0xFC,0x00,0x00, + /* 0xF6C0 [?] [8022]*/ + 0x09,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x11,0x01,0xFF,0x01,0x01,0x01,0x01, + 0x00,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + /* 0xF6C1 [?] [8023]*/ + 0x09,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x10,0x3F,0x04,0x04,0x08,0x30,0xC0, + 0x00,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00,0xE0,0x20,0x7C,0x04,0x14,0x08, + /* 0xF6C2 [?] [8024]*/ + 0x00,0x7C,0x44,0x44,0x45,0x7E,0x44,0x44,0x7C,0x44,0x44,0x44,0x4E,0xF0,0x00,0x00, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xF6C3 [?] [8025]*/ + 0x20,0x20,0x3C,0x44,0xC5,0x2A,0x10,0x28,0x44,0x82,0x7C,0x44,0x44,0x44,0x7C,0x44, + 0x50,0x48,0x80,0xFE,0x90,0x90,0xFC,0x90,0x90,0xFC,0x90,0x90,0x90,0xFE,0x80,0x80, + /* 0xF6C4 [?] [8026]*/ + 0x3E,0x22,0x3E,0x22,0x3E,0x22,0x3E,0x08,0x1F,0x30,0x5F,0x90,0x1F,0x10,0x1F,0x10, + 0xF8,0x88,0xF8,0x88,0xF8,0x88,0xF8,0x80,0xFC,0x80,0xF8,0x80,0xF8,0x80,0xFC,0x00, + /* 0xF6C5 [?] [8027]*/ + 0x30,0x2A,0x41,0x7D,0xD0,0x53,0x7D,0x51,0x51,0x7D,0x51,0x51,0x51,0x7D,0x40,0x40, + 0x18,0x14,0x20,0x3E,0x68,0x28,0x3E,0x28,0x28,0x3E,0x28,0x68,0xA8,0x3E,0x20,0x20, + /* 0xF6C6 [?] [8028]*/ + 0x00,0x7D,0x11,0x11,0x11,0x1D,0xE2,0x45,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x00,0xF0,0x10,0x90,0x52,0x12,0x0E,0x00,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6C7 [?] [8029]*/ + 0x02,0x01,0xFF,0x04,0x14,0x24,0x44,0x01,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x00,0x00,0xFE,0x40,0x50,0x48,0x44,0x00,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6C8 [?] [8030]*/ + 0x10,0x09,0x40,0x24,0x0B,0x70,0x10,0x11,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x1C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6C9 [?] [8031]*/ + 0x10,0xFF,0x28,0x7F,0x08,0x0F,0xF8,0x09,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x04,0x78,0x40,0x7E,0x48,0x48,0x88,0x08,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6CA [?] [8032]*/ + 0x00,0x7E,0x24,0x18,0xFF,0x29,0x4A,0x99,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x20,0x20,0x7E,0x84,0x28,0x10,0x28,0x44,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6CB [?] [8033]*/ + 0x08,0x7F,0x08,0x7E,0x08,0xFF,0x20,0x3E,0x43,0x86,0x18,0xEF,0x01,0x3F,0x09,0xFF, + 0x20,0x20,0x3E,0x44,0x84,0x28,0x10,0x28,0x44,0xC2,0x30,0xEE,0x00,0xF8,0x20,0xFE, + /* 0xF6CC [?] [8034]*/ + 0x20,0x17,0x80,0x49,0x13,0xE1,0x22,0x24,0x01,0x06,0x18,0xEF,0x01,0x3F,0x09,0xFF, + 0x40,0xFE,0x90,0x08,0xFC,0x50,0x52,0x4E,0x00,0xC0,0x30,0xEE,0x00,0xF8,0x20,0xFE, + /* 0xF6CD [?] [8035]*/ + 0x3E,0x22,0x3E,0x20,0x7E,0xA2,0x3E,0x23,0x06,0x18,0xEF,0x01,0x3F,0x11,0x09,0xFF, + 0x10,0xFE,0x44,0x28,0xFE,0x10,0xFC,0x10,0xC0,0x30,0xEE,0x00,0xF8,0x10,0x20,0xFE, + /* 0xF6CE [?] [8036]*/ + 0x01,0x06,0x18,0xEF,0x01,0x1F,0x09,0x3F,0x10,0x28,0x7C,0x92,0x7C,0x10,0x54,0xFE, + 0x00,0xC0,0x30,0xEE,0x00,0xF0,0x20,0xF8,0x10,0x28,0x7C,0x92,0x7C,0x10,0x54,0xFE, + /* 0xF6CF [?] [8037]*/ + 0x20,0x20,0x7C,0x44,0x88,0x7D,0x54,0x54,0x7C,0x54,0x54,0x7C,0x00,0x1D,0xE1,0x42, + 0x40,0x50,0x48,0x48,0x40,0xFE,0x50,0x50,0x50,0x50,0x90,0x90,0x92,0x12,0x0E,0x00, + /* 0xF6D0 [?] [8038]*/ + 0x10,0x10,0x1E,0x23,0x24,0x7E,0xAA,0x2A,0x3E,0x2A,0x2A,0x3E,0x00,0x0E,0x71,0x22, + 0x20,0x10,0x10,0xFE,0x40,0x40,0x40,0x7C,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10, + /* 0xF6D1 [?] [8039]*/ + 0x20,0x20,0x7C,0x44,0x89,0x7C,0x54,0x54,0x7C,0x54,0x54,0x7D,0x01,0x1E,0xE0,0x40, + 0x50,0x48,0x48,0x40,0xFE,0x40,0x40,0x7C,0xA4,0xA4,0xA8,0x28,0x10,0x28,0x44,0x82, + /* 0xF6D2 [?] [8040]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7D,0x54,0x54,0x7C,0x57,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x00,0x00,0xFC,0x20,0x20,0x24,0xA4,0xA8,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20, + /* 0xF6D3 [?] [8041]*/ + 0x10,0x10,0x1E,0x22,0x24,0x7E,0xAA,0x2A,0x3E,0x2A,0x2A,0x3E,0x00,0x0E,0x70,0x20, + 0x10,0x10,0x10,0x10,0x1E,0x10,0x10,0x10,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF6D4 [?] [8042]*/ + 0x10,0x10,0x1E,0x22,0x24,0x7E,0xAA,0x2A,0x3E,0x2A,0x2A,0x3E,0x00,0x0F,0x71,0x22, + 0x10,0x10,0x1E,0x10,0x10,0xFE,0x82,0x82,0x82,0xFE,0x82,0x80,0x80,0x00,0x00,0x00, + /* 0xF6D5 [?] [8043]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x55,0x54,0x7C,0x54,0x54,0x7C,0x01,0x1C,0xE0,0x40, + 0x08,0x3C,0xE0,0x20,0x20,0x20,0xFE,0x20,0x70,0x68,0xA8,0xA4,0x22,0x20,0x20,0x20, + /* 0xF6D6 [?] [8044]*/ + 0x20,0x20,0x7C,0x44,0x88,0x7D,0x56,0x54,0x7C,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x44,0x44,0x44,0x84,0xBE,0x84,0x84,0xA4,0x94,0x94,0x84,0x84,0x84,0x84,0x94,0x88, + /* 0xF6D7 [?] [8045]*/ + 0x22,0x11,0x00,0x7F,0x44,0x84,0x0F,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF,0x00, + 0x08,0x10,0x20,0xFC,0x04,0x08,0xC0,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE,0x00, + /* 0xF6D8 [?] [8046]*/ + 0x10,0x10,0x1E,0x22,0x24,0x7E,0xAB,0x2A,0x3E,0x2A,0x2A,0x3E,0x00,0x0E,0x70,0x20, + 0x20,0x20,0x20,0x40,0x48,0x84,0xFE,0x82,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF6D9 [?] [8047]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x57,0x54,0x7C,0x54,0x55,0x7C,0x00,0x1C,0xE3,0x40, + 0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00,0x20,0x20,0xFC,0x20,0x20,0x20,0xFE,0x00, + /* 0xF6DA [?] [8048]*/ + 0x20,0x20,0x7C,0x47,0x88,0x7C,0x55,0x54,0x7C,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0xFC,0x04, + /* 0xF6DB [?] [8049]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x54,0x55,0x7E,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x20,0x20,0xFE,0x40,0x40,0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x84,0x84,0x94,0x88, + /* 0xF6DC [?] [8050]*/ + 0x20,0x21,0x7C,0x44,0x88,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x00,0xFE,0x20,0x20,0x40,0xFC,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x04,0x0C, + /* 0xF6DD [?] [8051]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x54,0x54,0x7D,0x54,0x54,0x7C,0x00,0x1D,0xE1,0x42, + 0x40,0x20,0xFE,0x88,0x50,0x20,0x50,0x88,0x06,0x88,0x88,0x88,0x88,0x08,0x08,0x08, + /* 0xF6DE [?] [8052]*/ + 0x20,0x20,0x7C,0x45,0x88,0x7C,0x55,0x56,0x7C,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x43, + 0x40,0x20,0x20,0xFE,0x00,0x88,0x04,0x02,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x06, + /* 0xF6DF [?] [8053]*/ + 0x11,0x09,0x7F,0x02,0xFF,0x08,0x34,0xCF,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF, + 0x10,0x20,0xFC,0x00,0xFE,0x20,0x18,0xC6,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xF6E0 [?] [8054]*/ + 0x20,0x21,0x7C,0x44,0x88,0x7C,0x54,0x55,0x7C,0x54,0x55,0x7C,0x00,0x1C,0xE0,0x40, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x08,0x08,0xFE,0x88,0x48,0x48,0x08,0x18, + /* 0xF6E1 [?] [8055]*/ + 0x20,0x21,0x7C,0x44,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x00,0x1C,0xE0,0x43, + 0x00,0xFE,0x20,0x20,0xFC,0x24,0x24,0xFC,0x24,0x24,0xFC,0x20,0xA0,0x40,0xB0,0x0E, + /* 0xF6E2 [?] [8056]*/ + 0x40,0x43,0x78,0x88,0x13,0xFA,0xAA,0xAA,0xFB,0xAA,0xAA,0xFA,0x02,0x1A,0xE2,0x42, + 0x00,0xFE,0x00,0x00,0xDE,0x52,0x52,0x52,0x5A,0xD6,0x52,0x52,0x52,0x52,0x52,0xD6, + /* 0xF6E3 [?] [8057]*/ + 0x40,0x42,0x79,0x89,0x10,0xF8,0xAF,0xA9,0xF9,0xA9,0xA9,0xF9,0x01,0x1A,0xE4,0x40, + 0x10,0x10,0x10,0x7E,0x20,0x28,0x48,0x7E,0x08,0x08,0xFE,0x08,0x08,0x88,0x7E,0x00, + /* 0xF6E4 [?] [8058]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x54,0x7C,0x54,0x54,0x7C,0x00,0x1C,0xE1,0x40, + 0x40,0x7E,0x52,0x52,0x54,0x48,0x54,0x62,0x10,0x10,0xFE,0x10,0x10,0x10,0xFE,0x00, + /* 0xF6E5 [?] [8059]*/ + 0x40,0x40,0x7B,0x8A,0x12,0xFA,0xAA,0xAB,0xFA,0xAA,0xAA,0xFA,0x03,0x1A,0xE0,0x40, + 0x04,0x04,0xC4,0x44,0x7E,0x44,0x44,0xE4,0x54,0x54,0x44,0x44,0xC4,0x44,0x14,0x08, + /* 0xF6E6 [?] [8060]*/ + 0x20,0x20,0x7C,0x44,0x89,0x7C,0x54,0x57,0x7C,0x55,0x54,0x7D,0x01,0x1E,0xE0,0x40, + 0x40,0x40,0xF8,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x20,0x28,0x24,0x24,0xA0,0x40, + /* 0xF6E7 [?] [8061]*/ + 0x20,0x21,0x7C,0x44,0x88,0x7D,0x54,0x54,0x7D,0x54,0x54,0x7C,0x01,0x1E,0xE0,0x40, + 0x0C,0xF0,0x20,0x44,0x88,0xF0,0x20,0x44,0xFE,0x22,0x20,0xA8,0x24,0x22,0xA0,0x40, + /* 0xF6E8 [?] [8062]*/ + 0x20,0x12,0x44,0x20,0x08,0x73,0x28,0x0F,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF, + 0x40,0x48,0x44,0x14,0x60,0x80,0x00,0xC0,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xF6E9 [?] [8063]*/ + 0x20,0x20,0x7D,0x45,0x8A,0x7C,0x54,0x54,0x7D,0x54,0x54,0x7C,0x00,0x1C,0xE1,0x42, + 0x20,0x10,0xFE,0x02,0x04,0xF8,0x00,0x00,0xFE,0x50,0x50,0x50,0x92,0x92,0x0E,0x00, + /* 0xF6EA [?] [8064]*/ + 0x40,0x43,0x7A,0x8A,0x12,0xFB,0xAA,0xAA,0xFA,0xAB,0xAA,0xFA,0x02,0x1A,0xE3,0x40, + 0x00,0xDE,0x52,0x52,0x52,0xD2,0x52,0x52,0x52,0xD2,0x1A,0x94,0x50,0xB0,0x10,0x10, + /* 0xF6EB [?] [8065]*/ + 0x20,0x20,0x7D,0x44,0x88,0x7C,0x55,0x54,0x7C,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x20,0x20,0xFE,0x20,0xFC,0x20,0xFE,0x00,0xFC,0x84,0xFC,0x84,0xFC,0x84,0x94,0x88, + /* 0xF6EC [?] [8066]*/ + 0x20,0x20,0x7C,0x44,0x88,0x7D,0x54,0x54,0x7D,0x54,0x54,0x7D,0x00,0x1C,0xE0,0x41, + 0x20,0x20,0xFC,0x20,0x20,0xFE,0x48,0x84,0x22,0x78,0x88,0x48,0x50,0x20,0x50,0x8C, + /* 0xF6ED [?] [8067]*/ + 0x20,0x23,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x03,0x1C,0xE0,0x40, + 0x00,0xE0,0x5C,0x54,0x54,0xD4,0x54,0x54,0xD4,0x54,0x48,0x68,0xC8,0x54,0x54,0x62, + /* 0xF6EE [?] [8068]*/ + 0x20,0x20,0x7C,0x47,0x88,0x7C,0x54,0x55,0x7C,0x54,0x54,0x7C,0x03,0x1C,0xE0,0x40, + 0x50,0x50,0x50,0xDE,0x50,0x50,0x50,0xDC,0x50,0x50,0x50,0x50,0xDE,0x50,0x50,0x50, + /* 0xF6EF [?] [8069]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7C,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x00,0xFC,0x04,0x04,0xFC,0x04,0x04,0xFC,0x00,0x12,0xD4,0x18,0x10,0x52,0x92,0x0E, + /* 0xF6F0 [?] [8070]*/ + 0x20,0x20,0x7C,0x44,0x88,0x7C,0x54,0x54,0x7D,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0xFC,0x84,0x84,0xFC,0x84,0x84,0xFC,0x00,0xFE,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02, + /* 0xF6F1 [?] [8071]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x00,0xFC,0x04,0x24,0x24,0xFC,0x24,0x24,0x74,0x54,0x54,0x74,0x04,0x04,0xFC,0x04, + /* 0xF6F2 [?] [8072]*/ + 0x20,0x20,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x54,0x54,0x7C,0x00,0x1C,0xE1,0x42, + 0x00,0x40,0x9C,0x04,0x04,0xDC,0x04,0x04,0xFC,0x50,0x50,0x50,0x90,0x92,0x12,0x0E, + /* 0xF6F3 [?] [8073]*/ + 0x40,0x40,0x78,0x88,0x11,0xFA,0xA9,0xA8,0xF8,0xA8,0xA8,0xFA,0x02,0x1A,0xE4,0x40, + 0x20,0x20,0x50,0x88,0x44,0x22,0xF8,0x08,0x50,0x20,0xA4,0x82,0x8A,0x8A,0x78,0x00, + /* 0xF6F4 [?] [8074]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x01,0x1E,0xE2,0x44, + 0x00,0xFC,0x24,0x24,0x74,0x24,0xFC,0x04,0x74,0x54,0x54,0x74,0x04,0x04,0x14,0x08, + /* 0xF6F5 [?] [8075]*/ + 0x20,0x21,0x7C,0x44,0x89,0x7C,0x54,0x55,0x7D,0x55,0x55,0x7C,0x00,0x1C,0xE1,0x40, + 0x00,0xFC,0x04,0x34,0xC4,0x44,0x44,0xF4,0x54,0x54,0xF4,0x44,0x54,0x76,0x96,0x02, + /* 0xF6F6 [?] [8076]*/ + 0x20,0x20,0x7D,0x46,0x89,0x7C,0x54,0x54,0x7D,0x55,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x92,0x92,0x24,0x48,0x24,0x92,0x92,0x00,0xFE,0x22,0x22,0xFE,0x22,0x22,0xFE,0x02, + /* 0xF6F7 [?] [8077]*/ + 0x20,0x21,0x7C,0x44,0x8B,0x7C,0x54,0x55,0x7D,0x55,0x55,0x7D,0x01,0x1C,0xE0,0x43, + 0x20,0xFC,0x20,0x88,0xFE,0x88,0x00,0xFC,0x04,0x24,0x24,0x24,0x24,0x50,0x88,0x04, + /* 0xF6F8 [?] [8078]*/ + 0x40,0x41,0x79,0x8B,0x11,0xF9,0xA9,0xA9,0xF9,0xA8,0xAB,0xF8,0x00,0x19,0xE6,0x40, + 0x48,0x48,0x48,0xFE,0x48,0x48,0x78,0x00,0xFE,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xF6F9 [?] [8079]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7C,0x55,0x54,0x7D,0x54,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x00,0xDC,0x54,0x54,0xDC,0x00,0xFC,0x00,0xFE,0x80,0xFC,0x04,0x04,0x04,0x28,0x10, + /* 0xF6FA [?] [8080]*/ + 0x40,0x40,0x7B,0x89,0x11,0xF9,0xAB,0xA9,0xF9,0xAB,0xAD,0xF9,0x01,0x19,0xE1,0x41, + 0x08,0xC8,0x08,0x08,0x2A,0x2A,0xAC,0x48,0x08,0x88,0x54,0x14,0x14,0x24,0x24,0x42, + /* 0xF6FB [?] [8081]*/ + 0x20,0x20,0x7C,0x44,0x89,0x7E,0x54,0x54,0x7C,0x54,0x54,0x7C,0x01,0x1C,0xE0,0x41, + 0x40,0x40,0xFE,0x80,0xFC,0x84,0xFC,0x84,0xFC,0x40,0x7C,0xC4,0x28,0x10,0x68,0x86, + /* 0xF6FC [?] [8082]*/ + 0x20,0x20,0x7D,0x45,0x89,0x7D,0x55,0x54,0x7F,0x54,0x54,0x7D,0x00,0x1C,0xE3,0x40, + 0x20,0x40,0xFC,0x04,0xFC,0x04,0xFC,0x00,0xFE,0x20,0x20,0xFC,0x20,0x20,0xFE,0x00, + /* 0xF6FD [?] [8083]*/ + 0x20,0x20,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x55,0x56,0x7C,0x00,0x1C,0xE0,0x40, + 0x20,0x10,0xFE,0x02,0x02,0xFE,0x00,0x00,0xFE,0xAA,0xAA,0xFE,0xAA,0xAA,0xAA,0x86, + /* 0xF6FE [?] [8084]*/ + 0x20,0x21,0x7C,0x44,0x88,0x7C,0x54,0x57,0x7C,0x55,0x55,0x7D,0x01,0x1C,0xE3,0x40, + 0x00,0xFC,0xA4,0x88,0x50,0x20,0xD8,0x26,0x20,0xFC,0x24,0x24,0xFC,0x22,0xFE,0x02, + /* 0xF7A1 [?] [8085]*/ + 0x08,0x7E,0x08,0xFE,0x10,0x1E,0x22,0x4F,0x90,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF, + 0x20,0x20,0x7E,0xC4,0x28,0x10,0x28,0xC6,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xF7A2 [?] [8086]*/ + 0x20,0x20,0x7D,0x44,0x8B,0x7C,0x54,0x55,0x7E,0x54,0x55,0x7D,0x01,0x1D,0xE1,0x41, + 0x40,0x44,0xF8,0x50,0xFE,0x40,0xF8,0x82,0x7E,0x00,0xFC,0x04,0xFC,0x04,0xFC,0x04, + /* 0xF7A3 [?] [8087]*/ + 0x20,0x20,0x7C,0x44,0x88,0x7C,0x54,0x54,0x7D,0x54,0x55,0x7C,0x01,0x1C,0xE1,0x40, + 0x00,0xFC,0x84,0xFC,0x84,0xFC,0x00,0x00,0xDC,0x44,0x54,0xCC,0x54,0x44,0x54,0x88, + /* 0xF7A4 [?] [8088]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x54,0x54,0x7C,0x55,0x54,0x7C,0x00,0x1D,0xE0,0x40, + 0x00,0xFC,0x54,0x54,0x54,0xFC,0x20,0xA8,0xA4,0x24,0x20,0xA8,0xA4,0x24,0x20,0x20, + /* 0xF7A5 [?] [8089]*/ + 0x20,0x20,0x7D,0x44,0x89,0x7C,0x54,0x55,0x7C,0x55,0x54,0x7C,0x00,0x1C,0xE0,0x40, + 0x04,0x1E,0xE0,0x02,0x22,0x94,0xFE,0x10,0x10,0xFE,0x10,0x92,0x92,0x92,0xFE,0x02, + /* 0xF7A6 [?] [8090]*/ + 0x41,0x41,0x7B,0x89,0x11,0xF8,0xAB,0xAA,0xFA,0xAB,0xA8,0xFB,0x00,0x18,0xE0,0x40, + 0x48,0x48,0xE8,0x48,0xDE,0x8A,0xEA,0xAA,0xAA,0xEA,0x8A,0xEA,0x92,0x92,0xAA,0xC4, + /* 0xF7A7 [?] [8091]*/ + 0x20,0x23,0x7C,0x45,0x89,0x7D,0x55,0x54,0x7D,0x54,0x57,0x7C,0x00,0x1D,0xE2,0x40, + 0x00,0xFE,0x50,0xFC,0x54,0x54,0xFC,0x00,0xFC,0x00,0xFE,0x20,0xA8,0x24,0xA2,0x40, + /* 0xF7A8 [?] [8092]*/ + 0x20,0x21,0x7C,0x47,0x8A,0x7D,0x54,0x55,0x7C,0x55,0x54,0x7D,0x00,0x1C,0xE1,0x40, + 0x00,0xFC,0x20,0xFE,0x22,0xAC,0x20,0xAC,0x00,0xFC,0x04,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF7A9 [?] [8093]*/ + 0x40,0x41,0x79,0x89,0x11,0xF9,0xA8,0xAB,0xFA,0xAB,0xA8,0xF9,0x00,0x18,0xE1,0x46, + 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0xFC,0x94,0xFC,0x00,0xF8,0x90,0x60,0x98,0x06, + /* 0xF7AA [?] [8094]*/ + 0x20,0x3F,0x40,0xBE,0x2A,0xFF,0x4A,0x7F,0x10,0x3F,0x51,0x1F,0x11,0x1F,0x00,0xFF, + 0x20,0x20,0x7E,0xA8,0x28,0x10,0x28,0xC6,0x40,0xF0,0x10,0xF0,0x10,0xF0,0x00,0xFE, + /* 0xF7AB [?] [8095]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x01,0x1E,0xE2,0x44, + 0x10,0xFE,0x10,0x7C,0x14,0xFE,0x14,0x7C,0x10,0x7C,0x54,0x7C,0x54,0x7C,0x54,0x4C, + /* 0xF7AC [?] [8096]*/ + 0x40,0x43,0x7A,0x8B,0x12,0xFB,0xAA,0xAA,0xFB,0xAB,0xAB,0xFA,0x02,0x1A,0xE4,0x49, + 0x00,0xFE,0x00,0x14,0xA4,0xF6,0x4A,0x42,0x50,0x54,0xF4,0x44,0x4A,0x8A,0x92,0x20, + /* 0xF7AD [?] [8097]*/ + 0x40,0x40,0x7B,0x88,0x11,0xF8,0xAB,0xA9,0xF8,0xAB,0xA8,0xF9,0x01,0x19,0xE1,0x41, + 0x88,0x50,0xFE,0x20,0xFC,0x20,0xFE,0x24,0xA8,0xFE,0x00,0xFC,0x04,0x04,0xFC,0x04, + /* 0xF7AE [?] [8098]*/ + 0x20,0x20,0x7D,0x44,0x89,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7C,0x01,0x1C,0xE0,0x40, + 0x88,0x50,0xFE,0x50,0xFC,0x54,0x9C,0x04,0xFC,0x04,0xFC,0x08,0xFE,0x88,0x48,0x18, + /* 0xF7AF [?] [8099]*/ + 0x20,0x21,0x7D,0x45,0x89,0x7D,0x54,0x55,0x7C,0x55,0x55,0x7D,0x00,0x1C,0xE3,0x40, + 0x50,0xFC,0x54,0xFC,0x54,0xFC,0x00,0xFC,0x00,0xFC,0x04,0xFC,0x88,0x50,0xFE,0x00, + /* 0xF7B0 [?] [8100]*/ + 0x28,0x28,0xFE,0x28,0x38,0x10,0x7C,0x54,0x54,0x7C,0x10,0xFE,0x10,0x10,0x11,0x10, + 0x00,0x00,0xFC,0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0xFC,0x84,0x00,0x00,0xFE,0x00, + /* 0xF7B1 [?] [8101]*/ + 0x28,0x28,0xFE,0x29,0x39,0x11,0x7D,0x55,0x55,0x7F,0x10,0xFE,0x10,0x10,0x11,0x12, + 0x20,0x20,0x20,0xFC,0x24,0x24,0x24,0x24,0x24,0xFE,0x20,0x50,0x50,0x88,0x04,0x02, + /* 0xF7B2 [?] [8102]*/ + 0x28,0x29,0xFC,0x28,0x38,0x10,0x7D,0x54,0x54,0x7C,0x10,0xFC,0x10,0x11,0x12,0x10, + 0x10,0x10,0x90,0x90,0x7E,0x10,0x90,0x90,0x98,0xA8,0xA4,0xC4,0x80,0x40,0x3E,0x00, + /* 0xF7B3 [?] [8103]*/ + 0x28,0x28,0xFE,0x28,0x38,0x11,0x7C,0x54,0x55,0x7E,0x10,0xFE,0x10,0x10,0x10,0x11, + 0x08,0x1C,0xE0,0x20,0x20,0xFE,0x50,0x88,0x04,0x8A,0x88,0x88,0x88,0x88,0x88,0x08, + /* 0xF7B4 [?] [8104]*/ + 0x28,0x28,0xFC,0x29,0x3A,0x11,0x7D,0x55,0x55,0x7D,0x10,0xFC,0x10,0x10,0x11,0x12, + 0x80,0x80,0xF8,0x08,0x10,0xFC,0x24,0x24,0x24,0xFC,0x50,0x50,0x90,0x92,0x12,0x0E, + /* 0xF7B5 [?] [8105]*/ + 0x28,0x28,0xFD,0x28,0x38,0x11,0x7C,0x54,0x54,0x7D,0x12,0xFC,0x10,0x10,0x10,0x10, + 0x48,0x48,0xFE,0x48,0x20,0xFE,0x40,0x40,0xBC,0x84,0x88,0xBE,0x88,0x88,0xA8,0x90, + /* 0xF7B6 [?] [8106]*/ + 0x28,0x28,0xFC,0x29,0x3A,0x11,0x7C,0x55,0x54,0x7D,0x10,0xFD,0x11,0x11,0x10,0x10, + 0x80,0x80,0xFE,0x02,0x42,0xFA,0x02,0xF2,0x02,0xF2,0x02,0xF2,0x12,0xF2,0x14,0x08, + /* 0xF7B7 [?] [8107]*/ + 0x28,0x29,0xFC,0x28,0x3B,0x10,0x7C,0x55,0x56,0x7C,0x13,0xFC,0x10,0x11,0x16,0x10, + 0x00,0xFC,0x48,0x30,0xFE,0x52,0x94,0x10,0x30,0x20,0xFE,0x70,0xA8,0x24,0x22,0x20, + /* 0xF7B8 [?] [8108]*/ + 0x50,0x50,0xFB,0x50,0x71,0x20,0xFB,0xA8,0xA9,0xF9,0x21,0xF9,0x23,0x21,0x21,0x21, + 0x88,0x88,0xFE,0x88,0xFC,0x88,0xFE,0x20,0xFC,0x24,0xFC,0x24,0xFE,0x04,0x14,0x08, + /* 0xF7B9 [?] [8109]*/ + 0x50,0x50,0xFB,0x50,0x70,0x27,0xF8,0xA9,0xAB,0xFD,0x21,0xF9,0x21,0x21,0x21,0x21, + 0x88,0x88,0xFE,0x88,0x88,0xFE,0x80,0xFC,0x24,0xFC,0x24,0xFC,0x24,0x24,0x24,0x0C, + /* 0xF7BA [?] [8110]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x83,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x49, + 0x20,0x20,0x20,0x50,0x50,0x88,0x06,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x88,0x08, + /* 0xF7BB [?] [8111]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFF,0x82,0x7D,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x4B, + 0x00,0xF8,0x88,0x88,0x88,0x06,0x00,0xFC,0x84,0x84,0x48,0x50,0x20,0x50,0x88,0x06, + /* 0xF7BC [?] [8112]*/ + 0x00,0x7C,0x44,0x74,0x55,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x48, + 0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0xFC,0x84,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF7BD [?] [8113]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7C,0x45,0x44,0x54,0x48, + 0x20,0x40,0xFC,0x84,0xA4,0x94,0x94,0x8C,0x80,0xFE,0x02,0x02,0xFA,0x02,0x14,0x08, + /* 0xF7BE [?] [8114]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x48, + 0x04,0x1E,0xF0,0x90,0x90,0x90,0x90,0xFE,0x90,0x90,0x90,0x88,0x8A,0xAA,0xD6,0x8A, + /* 0xF7BF [?] [8115]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x45,0x55,0x4A, + 0x08,0x1C,0xE0,0x80,0x80,0xFE,0x80,0x80,0xBC,0xA4,0xA4,0xA4,0xA4,0x3C,0x24,0x00, + /* 0xF7C0 [?] [8116]*/ + 0x00,0x7C,0x44,0x74,0x55,0xFE,0x82,0x7C,0x45,0x7C,0x44,0x7C,0x44,0x44,0x54,0x48, + 0x40,0x40,0x78,0x88,0x50,0x20,0x50,0x88,0x06,0xF8,0x88,0x88,0x88,0x88,0xF8,0x88, + /* 0xF7C1 [?] [8117]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7C,0x44,0x7D,0x44,0x7C,0x44,0x45,0x54,0x48, + 0x00,0xF8,0xA8,0xA8,0xF8,0xA8,0xA8,0xF8,0x20,0xFC,0x20,0x70,0xA8,0x26,0x20,0x20, + /* 0xF7C2 [?] [8118]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7D,0x44,0x44,0x54,0x48, + 0x20,0x40,0xFE,0x92,0x92,0xFE,0x92,0xA2,0xFE,0x48,0x88,0xFE,0x08,0x08,0x08,0x08, + /* 0xF7C3 [?] [8119]*/ + 0x00,0x7D,0x44,0x74,0x55,0xFE,0x82,0x7D,0x44,0x7D,0x44,0x7C,0x44,0x44,0x54,0x49, + 0x20,0x24,0xA8,0x20,0xFE,0x68,0xA4,0x02,0x20,0xFE,0x48,0x88,0xD0,0x30,0x4C,0x82, + /* 0xF7C4 [?] [8120]*/ + 0x00,0x7C,0x45,0x75,0x54,0xFE,0x82,0x7D,0x44,0x7C,0x47,0x7C,0x44,0x44,0x54,0x48, + 0x40,0x20,0xFC,0x04,0x40,0x78,0x88,0x50,0x20,0xD8,0x06,0xF8,0x88,0x88,0xF8,0x88, + /* 0xF7C5 [?] [8121]*/ + 0x00,0x7C,0x45,0x75,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x4B, + 0x20,0x10,0xFE,0x02,0x48,0xFC,0x48,0x00,0xFC,0x84,0xA4,0xA4,0xA4,0x50,0x92,0x0E, + /* 0xF7C6 [?] [8122]*/ + 0x00,0x7C,0x45,0x75,0x54,0xFE,0x82,0x7C,0x44,0x7C,0x44,0x7D,0x44,0x44,0x55,0x4A, + 0x40,0x20,0xFE,0x02,0x18,0xE0,0x80,0xFC,0x90,0x90,0x90,0xFE,0x00,0x88,0x04,0x02, + /* 0xF7C7 [?] [8123]*/ + 0x00,0x7C,0x44,0x74,0x54,0xFE,0x82,0x7D,0x44,0x7C,0x44,0x7C,0x44,0x44,0x54,0x48, + 0x00,0xFE,0xAA,0xAA,0xFE,0x40,0xFE,0x22,0xFA,0xAA,0xAA,0xFA,0x22,0xFA,0x0A,0x04, + /* 0xF7C8 [?] [8124]*/ + 0x08,0x10,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x10,0x1A,0x2C,0x2F,0x48,0x48,0x87, + 0x10,0x10,0x10,0x7C,0x10,0x10,0xFE,0x10,0x38,0x54,0x92,0x90,0x90,0x10,0x02,0xFE, + /* 0xF7C9 [?] [8125]*/ + 0x10,0x20,0x7C,0x55,0x54,0x7C,0x54,0x54,0x7C,0x10,0x2A,0x2D,0x4F,0x48,0x87,0x00, + 0x28,0x24,0x20,0xFE,0x20,0x20,0x7C,0x44,0x54,0x88,0x94,0x24,0x40,0x02,0xFE,0x00, + /* 0xF7CA [?] [8126]*/ + 0x3F,0x20,0x3F,0x21,0x26,0x38,0x21,0x2F,0x28,0x2F,0x28,0x2F,0x41,0x42,0x8C,0x30, + 0xFC,0x90,0xFC,0x40,0x30,0x8C,0x00,0xF8,0x88,0xF8,0x88,0xF8,0x50,0xFA,0x8A,0x7E, + /* 0xF7CB [?] [8127]*/ + 0x10,0x21,0x7C,0x54,0x55,0x7D,0x55,0x55,0x7D,0x11,0x2B,0x2D,0x4F,0x48,0x87,0x00, + 0x00,0xFC,0x50,0x50,0xFC,0x54,0x54,0x54,0xAC,0x04,0x04,0x14,0x08,0x02,0xFE,0x00, + /* 0xF7CC [?] [8128]*/ + 0x08,0x10,0x7F,0x49,0x49,0x7F,0x49,0x49,0x7F,0x10,0x1A,0x2C,0x2F,0x48,0x48,0x87, + 0x10,0x54,0x38,0x10,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0xC4,0xC4,0x4C,0x02,0xFE, + /* 0xF7CD [?] [8129]*/ + 0x10,0x21,0x7D,0x55,0x55,0x7D,0x55,0x55,0x7D,0x11,0x2B,0x2D,0x4F,0x48,0x87,0x00, + 0x00,0xFC,0x04,0x8C,0x54,0xFC,0x44,0x24,0xFC,0x44,0x74,0x04,0x0C,0x02,0xFE,0x00, + /* 0xF7CE [?] [8130]*/ + 0x10,0x20,0x7D,0x54,0x55,0x7D,0x55,0x54,0x7D,0x11,0x2B,0x2D,0x4F,0x48,0x87,0x00, + 0x40,0x20,0xFC,0x50,0x24,0x54,0xFC,0x20,0xFC,0x44,0x54,0x74,0x0C,0x02,0xFE,0x00, + /* 0xF7CF [?] [8131]*/ + 0x10,0x10,0x10,0x24,0x24,0x79,0x0A,0x10,0x24,0x7C,0x04,0x08,0x08,0x10,0x20,0x40, + 0x20,0x20,0x50,0x48,0xA4,0xFA,0x88,0xF8,0x88,0xF8,0xA2,0x94,0x88,0xA4,0xC4,0x80, + /* 0xF7D0 [?] [8132]*/ + 0x00,0x3F,0x21,0x3F,0x24,0x28,0x33,0x2C,0x37,0x24,0x27,0x24,0x27,0x44,0x45,0x86, + 0x00,0xFE,0x08,0xFC,0x10,0x88,0x64,0x98,0xF6,0x10,0xF0,0x10,0xF4,0x68,0x18,0x04, + /* 0xF7D1 [?] [8133]*/ + 0x7F,0x10,0x1E,0x23,0x54,0x09,0x10,0x61,0x06,0x1F,0xE8,0x0F,0x08,0x0F,0x08,0x0C, + 0x20,0x50,0x88,0x46,0x90,0x24,0x48,0x90,0x60,0xF8,0x16,0xF0,0x10,0xF4,0x68,0x1C, + /* 0xF7D2 [?] [8134]*/ + 0x7C,0x44,0xFE,0x20,0x7C,0x04,0x28,0x11,0x06,0x1F,0xE8,0x0F,0x08,0x0F,0x08,0x0C, + 0x1C,0x10,0xFE,0x92,0xF8,0x94,0xBC,0xAA,0x66,0xF8,0x16,0xF0,0x10,0xF4,0x68,0x1C, + /* 0xF7D3 [?] [8135]*/ + 0x01,0xFF,0x10,0x25,0x7B,0x15,0x79,0x11,0xE6,0x1F,0xE8,0x0F,0x08,0x0F,0x08,0x0C, + 0x00,0xFE,0xA0,0xFE,0x20,0xFC,0x20,0xFE,0x60,0xF8,0x16,0xF0,0x10,0xF4,0x68,0x1C, + /* 0xF7D4 [?] [8136]*/ + 0x3F,0x20,0x20,0x3E,0x20,0x20,0x3E,0x20,0x20,0xFF,0x10,0x24,0x42,0xFF,0x41,0x00, + 0x04,0x04,0x08,0x10,0x20,0x44,0x04,0x08,0x10,0x22,0x42,0x04,0x08,0x10,0x20,0xC0, + /* 0xF7D5 [?] [8137]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x00,0x7F,0x04,0x04,0x08,0x30,0xC0, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0x00,0xFC,0x40,0x40,0x42,0x42,0x3E, + /* 0xF7D6 [?] [8138]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x01,0x3E,0x03,0x3E,0x03,0x7E,0x01, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0xF0,0x00,0xF0,0x00,0xFA,0x02,0xFE, + /* 0xF7D7 [?] [8139]*/ + 0x3F,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x01,0x3F,0x21,0x3F,0x21,0xFF,0x20,0x20,0x20, + 0x08,0x30,0xC4,0x18,0x62,0x0C,0x70,0x00,0xF8,0x08,0xF8,0x08,0xFE,0x08,0x28,0x10, + /* 0xF7D8 [?] [8140]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x00,0x7F,0x08,0x10,0x3F,0xD0,0x1F, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0x00,0xF8,0x08,0x30,0xF8,0x08,0xF8, + /* 0xF7D9 [?] [8141]*/ + 0x3F,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x01,0xFF,0x01,0x3F,0x00,0x3F,0x20,0x3F,0x20, + 0x08,0x30,0xC4,0x18,0x62,0x0C,0x70,0x00,0xFE,0x00,0xF8,0x00,0xF8,0x08,0xF8,0x08, + /* 0xF7DA [?] [8142]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x08,0x08,0x2E,0x28,0x28,0x2E,0xF0, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0x80,0x88,0x90,0xE0,0x84,0x84,0x7C, + /* 0xF7DB [?] [8143]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x08,0x10,0x37,0xD0,0x13,0x1C,0x10, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0x40,0x40,0xFC,0xE0,0x58,0x46,0x40, + /* 0xF7DC [?] [8144]*/ + 0x3F,0x20,0xFF,0x22,0x7F,0x11,0x09,0x7F,0x04,0xFF,0x10,0x2F,0xC8,0x08,0x08,0x07, + 0x04,0x18,0x62,0x0C,0x70,0x10,0x20,0xFC,0x00,0xFE,0x10,0xE8,0x26,0xA0,0x48,0xF8, + /* 0xF7DD [?] [8145]*/ + 0x3E,0x20,0x3E,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x00,0x7C,0x10,0xFE,0x38,0x54,0x92, + 0x04,0x18,0x60,0x04,0x18,0x62,0x04,0x18,0x60,0x00,0x10,0x52,0x94,0x28,0x44,0x82, + /* 0xF7DE [?] [8146]*/ + 0x3F,0x20,0xFF,0x22,0x7F,0x02,0x01,0x7F,0x40,0x9F,0x10,0x1F,0x10,0xFF,0x10,0x20, + 0x04,0x18,0x62,0x0C,0x70,0x00,0x00,0xFE,0x22,0xC4,0x00,0xF8,0x80,0xFE,0x20,0x10, + /* 0xF7DF [?] [8147]*/ + 0x3F,0x20,0x3E,0x20,0xFF,0x22,0x7F,0x01,0x3F,0x24,0xFF,0x10,0x1F,0x0C,0x34,0xC6, + 0x08,0x30,0xC4,0x18,0x62,0x0C,0x70,0x00,0xF8,0x48,0xFE,0x10,0xF0,0x88,0x70,0x0E, + /* 0xF7E0 [?] [8148]*/ + 0x3F,0x20,0xFF,0x22,0x7F,0x10,0x21,0x10,0x3F,0x24,0x23,0x24,0x3F,0x29,0x25,0x31, + 0x04,0x18,0x62,0x0C,0x70,0x84,0x08,0x84,0xF8,0x48,0x88,0x48,0xF8,0x4A,0x26,0x82, + /* 0xF7E1 [?] [8149]*/ + 0x01,0x00,0x3F,0x22,0x22,0x2F,0x23,0x26,0x2A,0x21,0x22,0x24,0x49,0x42,0x87,0x00, + 0x00,0x80,0xFE,0x10,0x10,0xBC,0x18,0xB4,0x52,0x00,0x40,0x80,0x10,0x08,0xFC,0x04, + /* 0xF7E2 [?] [8150]*/ + 0x01,0x00,0x3F,0x22,0x2F,0x26,0x2B,0x32,0x20,0x2F,0x20,0x2F,0x20,0x5F,0x40,0x80, + 0x00,0x80,0xFE,0x10,0x7C,0x38,0x54,0x92,0x78,0x80,0xF8,0x80,0xFC,0x82,0x82,0x7E, + /* 0xF7E3 [?] [8151]*/ + 0x01,0x00,0x3F,0x22,0x2F,0x26,0x2B,0x32,0x21,0x27,0x20,0x23,0x2F,0x40,0x45,0x88, + 0x00,0x80,0xFE,0x10,0x7C,0x38,0x54,0x92,0x08,0xF0,0x60,0x84,0xFE,0x42,0x48,0x84, + /* 0xF7E4 [?] [8152]*/ + 0x01,0x00,0x3F,0x22,0x3F,0x22,0x3F,0x28,0x2F,0x28,0x2F,0x20,0x23,0x42,0x44,0x98, + 0x00,0x80,0xFE,0x20,0xFC,0x24,0xFC,0x40,0x78,0x42,0x3E,0x00,0xF0,0x10,0x12,0x0E, + /* 0xF7E5 [?] [8153]*/ + 0x00,0x3F,0x22,0x3F,0x22,0x3F,0x24,0x27,0x24,0x27,0x20,0x23,0x20,0x4F,0x41,0x8E, + 0x80,0xFE,0x20,0xFC,0x24,0xFC,0x20,0xBC,0x22,0x9E,0x08,0xF0,0x40,0xFE,0x50,0x4E, + /* 0xF7E6 [?] [8154]*/ + 0x00,0x3F,0x22,0x3F,0x22,0x3F,0x24,0x27,0x24,0x27,0x20,0x2F,0x20,0x47,0x40,0x9F, + 0x80,0xFE,0x20,0xFC,0x24,0xFC,0x20,0xBC,0x22,0x9E,0x80,0xFE,0x40,0xFC,0x40,0xFE, + /* 0xF7E7 [?] [8155]*/ + 0x00,0x3F,0x22,0x3F,0x22,0x3F,0x24,0x27,0x24,0x27,0x22,0x21,0x2F,0x41,0x42,0x8C, + 0x80,0xFE,0x20,0xFC,0x24,0xFC,0x20,0xBC,0x22,0x9E,0x48,0x50,0xFE,0x50,0x48,0x46, + /* 0xF7E8 [?] [8156]*/ + 0x08,0x7F,0x55,0x54,0x7F,0x55,0x55,0x7F,0x54,0x54,0x5E,0x55,0x54,0x5C,0x56,0x80, + 0x44,0x44,0xFE,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44,0x44,0xFE,0x00,0x28,0x44,0x82, + /* 0xF7E9 [?] [8157]*/ + 0x00,0x3F,0x22,0x3F,0x22,0x3F,0x24,0x27,0x24,0x27,0x23,0x2D,0x20,0x47,0x42,0x8F, + 0x80,0xFE,0x20,0xFC,0x24,0xFC,0x20,0xBC,0x62,0xBE,0x18,0xF6,0x40,0xFC,0x48,0xFE, + /* 0xF7EA [?] [8158]*/ + 0x00,0x3F,0x22,0x3F,0x22,0x3F,0x24,0x27,0x24,0x2F,0x29,0x2F,0x29,0x5F,0x45,0x9B, + 0x80,0xFE,0x20,0xFC,0x24,0xFC,0x20,0xBC,0x22,0x9E,0x08,0x7E,0x48,0x28,0x08,0x18, + /* 0xF7EB [?] [8159]*/ + 0x08,0x7F,0x54,0x54,0x7F,0x55,0x55,0x7F,0x54,0x54,0x5E,0x54,0x55,0x5C,0x56,0x81, + 0x10,0x54,0x38,0xFE,0x10,0x38,0x56,0x90,0x84,0xEE,0xA4,0xB4,0x5E,0x44,0x84,0x04, + /* 0xF7EC [?] [8160]*/ + 0x08,0x10,0x30,0xD7,0x10,0x10,0x00,0x3F,0x29,0x25,0x3F,0x01,0x7F,0x01,0xFF,0x44, + 0x90,0x88,0x7E,0xC0,0x22,0x1A,0x06,0xF8,0x28,0x48,0xF8,0x00,0xFC,0x00,0xFE,0x44, + /* 0xF7ED [?] [8161]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x10,0x10,0x92,0x92,0x92,0x92,0xFE,0x10,0x10,0x92,0x92,0x92,0x92,0x92,0xFE,0x02, + /* 0xF7EE [?] [8162]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x93,0xFF,0x10,0xFE,0x11,0x1F,0xE1,0x02,0xAA,0xA8,0x80, + 0x10,0x50,0x50,0x90,0xFC,0x54,0xD4,0x94,0x94,0x14,0x54,0xD4,0x54,0x24,0x34,0x48, + /* 0xF7EF [?] [8163]*/ + 0x00,0xFE,0x92,0xD7,0xBA,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x20,0x20,0x20,0xFE,0x20,0x20,0xFC,0x00,0x00,0xFC,0x84,0x84,0x84,0x84,0xFC,0x84, + /* 0xF7F0 [?] [8164]*/ + 0x00,0xFE,0x92,0xD6,0xBB,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x20,0x20,0x7C,0x84,0x48,0x30,0x20,0x48,0x90,0x3E,0x42,0xA4,0x18,0x10,0x20,0xC0, + /* 0xF7F1 [?] [8165]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x10,0x10,0x20,0x44,0xFE,0x28,0x44,0xA2,0x3C,0x44,0x44,0xA8,0x10,0x28,0x44,0x82, + /* 0xF7F2 [?] [8166]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x93,0xFE,0x10,0xFE,0x10,0x1E,0xE1,0x02,0xAA,0xA8,0x81, + 0x10,0x10,0xFC,0x10,0x10,0xFE,0x02,0x54,0x30,0x90,0x50,0xFE,0x28,0x44,0x82,0x02, + /* 0xF7F3 [?] [8167]*/ + 0x06,0x38,0x08,0x7E,0x1C,0x2A,0x48,0x3F,0x29,0x25,0x3F,0x01,0x7F,0x01,0xFF,0x44, + 0x40,0x7C,0x94,0x24,0x44,0x94,0x08,0xF8,0x28,0x48,0xF8,0x00,0xFC,0x00,0xFE,0x44, + /* 0xF7F4 [?] [8168]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x20,0x10,0xFE,0x00,0x00,0x7C,0x44,0x44,0x7C,0x10,0x54,0x52,0x92,0x10,0x50,0x20, + /* 0xF7F5 [?] [8169]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x93,0xFE,0x11,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x81, + 0x20,0x28,0x44,0xFE,0x20,0xFE,0x88,0x14,0x22,0x48,0x10,0x22,0xC4,0x18,0x60,0x80, + /* 0xF7F6 [?] [8170]*/ + 0x00,0xFE,0x92,0xD6,0xBA,0x92,0xFE,0x10,0xFE,0x10,0x1E,0xE0,0x02,0xAA,0xA8,0x80, + 0x20,0x10,0xFE,0x00,0x44,0x28,0xFE,0x00,0x7C,0x44,0x44,0x7C,0x44,0x44,0x7C,0x44, + /* 0xF7F7 [?] [8171]*/ + 0x20,0xCE,0x82,0xEE,0x82,0x82,0xFE,0x01,0x92,0x92,0xDA,0x92,0xDA,0x92,0x93,0xD9, + 0x08,0x28,0x28,0x28,0x44,0x44,0x82,0x7C,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x08, + /* 0xF7F8 [?] [8172]*/ + 0x20,0xCE,0x82,0xEE,0x82,0x82,0xFE,0x00,0x92,0x92,0xDA,0x92,0xDA,0x92,0x93,0xD9, + 0x10,0x10,0x10,0x10,0xFE,0x92,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0x92,0xFE,0x82, + /* 0xF7F9 [?] [8173]*/ + 0x20,0xCE,0x82,0xEE,0x82,0x82,0xFE,0x00,0x92,0x92,0xDA,0x92,0xDA,0x92,0x93,0xD9, + 0x00,0xFE,0x10,0x10,0x7C,0x24,0x24,0xFE,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44, + /* 0xF7FA [?] [8174]*/ + 0x20,0xCE,0x82,0xEE,0x82,0x82,0xFE,0x00,0x92,0x92,0xDA,0x92,0xDA,0x92,0x93,0xD9, + 0x00,0x7C,0x44,0x7C,0x44,0x7C,0x10,0xFE,0x82,0x10,0xFE,0x24,0x68,0x10,0x28,0x44, + /* 0xF7FB [?] [8175]*/ + 0x20,0xCE,0x82,0xEE,0x82,0x82,0xFE,0x00,0x92,0x92,0xDA,0x92,0xDA,0x92,0x93,0xD9, + 0x0E,0xF0,0x22,0x92,0x44,0x20,0x44,0xF8,0x10,0x24,0xFE,0x10,0xFE,0x28,0x44,0x82, + /* 0xF7FC [?] [8176]*/ + 0x10,0x3E,0x22,0x3E,0x22,0x3E,0x00,0x7F,0x49,0x7F,0x49,0x7F,0x00,0xFF,0x22,0x42, + 0x20,0x20,0x20,0x20,0xF8,0x28,0x28,0x28,0x28,0x28,0x28,0x2A,0x2A,0xCA,0x46,0x80, + /* 0xF7FD [?] [8177]*/ + 0x10,0x3E,0x22,0x3E,0x22,0x3E,0x00,0x7F,0x49,0x7F,0x49,0x7F,0x00,0xFF,0x22,0x42, + 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x90,0x10,0x10, + /* 0xF7FE [?] [8178]*/ + 0x10,0x3E,0x22,0x3E,0x22,0x3E,0x00,0x7F,0x49,0x7F,0x49,0x7F,0x00,0xFF,0x22,0x42, + 0x10,0x10,0xFE,0x38,0x54,0x92,0x00,0x7C,0x44,0x7C,0x44,0x7C,0x44,0x80,0xFE,0x00, + }; + + +const uint8_t s_ascii_font8_16[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/ + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x18,0x18,0x00,0x00,/*"!",1*/ + 0x00,0x12,0x36,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/ + 0x00,0x00,0x00,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x00,0x00,/*"#",3*/ + 0x00,0x00,0x10,0x38,0x54,0x54,0x50,0x30,0x18,0x14,0x14,0x54,0x54,0x38,0x10,0x10,/*"$",4*/ + 0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xA8,0x54,0x1A,0x2A,0x2A,0x2A,0x44,0x00,0x00,/*"%",5*/ + 0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x50,0x6E,0xA4,0x94,0x88,0x89,0x76,0x00,0x00,/*"&",6*/ + 0x00,0x60,0x60,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/ + 0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,/*"(",8*/ + 0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,/*")",9*/ + 0x00,0x00,0x00,0x00,0x10,0x10,0xD6,0x38,0x38,0xD6,0x10,0x10,0x00,0x00,0x00,0x00,/*"*",10*/ + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*"+",11*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0xC0,/*",",12*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,/*".",14*/ + 0x00,0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,/*"/",15*/ + 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"0",16*/ + 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"1",17*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,/*"2",18*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"3",19*/ + 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,/*"4",20*/ + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"5",21*/ + 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"6",22*/ + 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,/*"7",23*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/*"8",24*/ + 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,/*"9",25*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,/*":",26*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,/*";",27*/ + 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,/*"<",28*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,/*"=",29*/ + 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x62,0x02,0x04,0x08,0x08,0x00,0x18,0x18,0x00,0x00,/*"?",31*/ + 0x00,0x00,0x00,0x38,0x44,0x5A,0xAA,0xAA,0xAA,0xAA,0xB4,0x42,0x44,0x38,0x00,0x00,/*"@",32*/ + 0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3C,0x44,0x42,0x42,0xE7,0x00,0x00,/*"A",33*/ + 0x00,0x00,0x00,0xF8,0x44,0x44,0x44,0x78,0x44,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"B",34*/ + 0x00,0x00,0x00,0x3E,0x42,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x44,0x38,0x00,0x00,/*"C",35*/ + 0x00,0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"D",36*/ + 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x42,0x42,0xFC,0x00,0x00,/*"E",37*/ + 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/ + 0x00,0x00,0x00,0x3C,0x44,0x44,0x80,0x80,0x80,0x8E,0x84,0x44,0x44,0x38,0x00,0x00,/*"G",39*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"H",40*/ + 0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"I",41*/ + 0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0xF0,/*"J",42*/ + 0x00,0x00,0x00,0xEE,0x44,0x48,0x50,0x70,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00,/*"K",43*/ + 0x00,0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0xFE,0x00,0x00,/*"L",44*/ + 0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00,/*"M",45*/ + 0x00,0x00,0x00,0xC7,0x62,0x62,0x52,0x52,0x4A,0x4A,0x4A,0x46,0x46,0xE2,0x00,0x00,/*"N",46*/ + 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,/*"O",47*/ + 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/ + 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0xB2,0xCA,0x4C,0x38,0x06,0x00,/*"Q",49*/ + 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x7C,0x48,0x48,0x44,0x44,0x42,0xE3,0x00,0x00,/*"R",50*/ + 0x00,0x00,0x00,0x3E,0x42,0x42,0x40,0x20,0x18,0x04,0x02,0x42,0x42,0x7C,0x00,0x00,/*"S",51*/ + 0x00,0x00,0x00,0xFE,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"T",52*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"U",53*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,/*"V",54*/ + 0x00,0x00,0x00,0xD6,0x92,0x92,0x92,0x92,0xAA,0xAA,0x6C,0x44,0x44,0x44,0x00,0x00,/*"W",55*/ + 0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00,/*"X",56*/ + 0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"Y",57*/ + 0x00,0x00,0x00,0x7E,0x84,0x04,0x08,0x08,0x10,0x20,0x20,0x42,0x42,0xFC,0x00,0x00,/*"Z",58*/ + 0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00,/*"[",59*/ + 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x02,/*"\",60*/ + 0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,/*"]",61*/ + 0x00,0x1C,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,/*"_",63*/ + 0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x1E,0x22,0x42,0x42,0x3F,0x00,0x00,/*"a",65*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x00,0x00,/*"b",66*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,/*"c",67*/ + 0x00,0x00,0x00,0x06,0x02,0x02,0x02,0x1E,0x22,0x42,0x42,0x42,0x26,0x1B,0x00,0x00,/*"d",68*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x40,0x42,0x3C,0x00,0x00,/*"e",69*/ + 0x00,0x00,0x00,0x0F,0x11,0x10,0x10,0x7E,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"f",70*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x44,0x44,0x38,0x40,0x3C,0x42,0x42,0x3C,/*"g",71*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"h",72*/ + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"i",73*/ + 0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x1C,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,/*"j",74*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x4E,0x48,0x50,0x68,0x48,0x44,0xEE,0x00,0x00,/*"k",75*/ + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"l",76*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x49,0x49,0x49,0x49,0x49,0xED,0x00,0x00,/*"m",77*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"n",78*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"o",79*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x44,0x78,0x40,0xE0,/*"p",80*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x22,0x42,0x42,0x42,0x22,0x1E,0x02,0x07,/*"q",81*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x32,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"r",82*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x40,0x3C,0x02,0x42,0x7C,0x00,0x00,/*"s",83*/ + 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,0x00,/*"t",84*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x46,0x3B,0x00,0x00,/*"u",85*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x10,0x10,0x00,0x00,/*"v",86*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD7,0x92,0x92,0xAA,0xAA,0x44,0x44,0x00,0x00,/*"w",87*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00,/*"x",88*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x18,0x10,0x10,0xE0,/*"y",89*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x08,0x10,0x10,0x22,0x7E,0x00,0x00,/*"z",90*/ + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,/*"|",91*/ + 0x30,0x4C,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"~",92*/ +}; + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_animation.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_animation.c new file mode 100644 index 0000000..6fb9a95 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_animation.c @@ -0,0 +1,213 @@ +/** + ***************************************************************************************** + * + * @file gui_animation.c + * + * @brief Animation Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_animation.h" +#include +#include + +#if ANIMATION_EN==1 + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static uint8_t all_move_frame = GUI_X_MOVE_FRAME; +static animation_stop_handle_t now_animation_stop_call; +static animation_type_t now_animation_type = MOVE_LEFT; +static uint8_t now_animation_frame = 0; +static bool start_animation_flag = false; + +static T_COLOR (*gui_display_ram)[GUI_DISPLAY_X_MAX]; +static T_COLOR (*gui_display_buffer)[GUI_DISPLAY_X_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ + /** + ***************************************************************************************** + * @brief Move up animation + * + * @param[in] frame move frame. + ***************************************************************************************** + */ +static void gui_animation_move_up(uint8_t frame) +{ + uint8_t y; + for(y=0; y<(GUI_Y_MOVE_FRAME-1); y++) + { + memcpy(&gui_display_ram[y*GUI_Y_MOVE_PIXEL], &gui_display_ram[(y+1)*GUI_Y_MOVE_PIXEL], GUI_DISPLAY_X_MAX*2*GUI_Y_MOVE_PIXEL); + } + memcpy(&gui_display_ram[GUI_DISPLAY_Y_MAX-1-GUI_Y_MOVE_PIXEL], &gui_display_buffer[frame*GUI_Y_MOVE_PIXEL], GUI_DISPLAY_X_MAX*2*GUI_Y_MOVE_PIXEL); +} + + /** + ***************************************************************************************** + * @brief Move down animation + * + * @param[in] frame move frame. + ***************************************************************************************** + */ +static void gui_animation_move_down(uint8_t frame) +{ + uint8_t y; + for(y=GUI_Y_MOVE_FRAME-1; y>0; y--) + { + memcpy(&gui_display_ram[y*GUI_Y_MOVE_PIXEL], &gui_display_ram[(y-1)*GUI_Y_MOVE_PIXEL], GUI_DISPLAY_X_MAX*2*GUI_Y_MOVE_PIXEL); + } + memcpy(&gui_display_ram[0], &gui_display_buffer[(GUI_Y_MOVE_FRAME-1-frame)*GUI_Y_MOVE_PIXEL], GUI_DISPLAY_X_MAX*2*GUI_Y_MOVE_PIXEL); +} + + /** + ***************************************************************************************** + * @brief Move left animation + * + * @param[in] frame move frame. + ***************************************************************************************** + */ +static void gui_animation_move_left(uint8_t frame) +{ + uint16_t x,y; + + for(y=0; y0; x--) + { + memcpy(&gui_display_ram[y][x*GUI_X_MOVE_PIXEL], &gui_display_ram[y][(x-1)*GUI_X_MOVE_PIXEL], GUI_X_MOVE_PIXEL*2); + } + } + + for(y=0; y + + +uint32_t gui_pow(uint32_t m,uint8_t n) +{ + uint32_t result = 1; + while (n--)result *= m; + return result; +} + + +void gui_line_hor(uint16_t x0, uint8_t y0, uint16_t x1, T_COLOR color) +{ + uint8_t temp; + if(x0>x1) + { + temp = x1; + x1 = x0; + x0 = temp; + } + do + { + gui_point(x0, y0, color); + x0++; + } + while(x1>=x0); +} + + +void gui_line_ver(uint16_t x0, uint8_t y0, uint8_t y1, T_COLOR color) +{ + uint8_t temp; + if(y0>y1) + { + temp = y1; + y1 = y0; + y0 = temp; + } + do + { + gui_point(x0, y0, color); + y0++; + } + while(y1>=y0); +} + +void gui_rectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color) +{ gui_line_hor(x0, y0, x1, color); + gui_line_hor(x0, y1, x1, color); + gui_line_ver(x0, y0, y1, color); + gui_line_ver(x1, y0, y1, color); +} + + +void gui_rectangle_fill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color) +{ + uint16_t i; + if(x0>x1) + { i = x0; + x0 = x1; + x1 = i; + } + if(y0>y1) + { i = y0; + y0 = y1; + y1 = i; + } + + if(y0==y1) + { gui_line_hor(x0, y0, x1, color); + return; + } + if(x0==x1) + { gui_line_ver(x0, y0, y1, color); + return; + } + + while(y0<=y1) + { gui_line_hor(x0, y0, x1, color); + y0++; + } +} + + +void gui_square(uint16_t x0, uint16_t y0, uint16_t with, T_COLOR color) +{ if(with==0) return; + if( (x0+with) > GUI_DISPLAY_X_MAX ) return; + if( (y0+with) > GUI_DISPLAY_Y_MAX ) return; + gui_rectangle(x0, y0, x0+with, y0+with, color); +} + + +void gui_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color) +{ int16_t dx; + int16_t dy; + int8_t dx_sym; + int8_t dy_sym; + int16_t dx_x2; + int16_t dy_x2; + int16_t di; + + + dx = x1-x0; + dy = y1-y0; + + + if(dx>0) + { dx_sym = 1; + } + else + { if(dx<0) + { dx_sym = -1; + } + else + { + gui_line_ver(x0, y0, y1, color); + return; + } + } + + if(dy>0) + { dy_sym = 1; + } + else + { if(dy<0) + { dy_sym = -1; + } + else + { + gui_line_hor(x0, y0, x1, color); + return; + } + } + + + dx = dx_sym * dx; + dy = dy_sym * dy; + + + dx_x2 = dx*2; + dy_x2 = dy*2; + + /* Bresenham draw line */ + if(dx>=dy) + { di = dy_x2 - dx; + while(x0!=x1) + { gui_point(x0, y0, color); + x0 += dx_sym; + if(di<0) + { di += dy_x2; + } + else + { di += dy_x2 - dx_x2; + y0 += dy_sym; + } + } + gui_point(x0, y0, color); + } + else + { di = dx_x2 - dy; + while(y0!=y1) + { gui_point(x0, y0, color); + y0 += dy_sym; + if(di<0) + { di += dx_x2; + } + else + { di += dx_x2 - dy_x2; + x0 += dx_sym; + } + } + gui_point(x0, y0, color); + } + +} + + +void gui_line_width(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t width, T_COLOR color) +{ int16_t dx; + int16_t dy; + int8_t dx_sym; + int8_t dy_sym; + int16_t dx_x2; + int16_t dy_x2; + int16_t di; + + int16_t wx, wy; + int16_t draw_a, draw_b; + + + if(width==0) return; + if(width>50) width = 50; + + dx = x1-x0; + dy = y1-y0; + + wx = width/2; + wy = width-wx-1; + + + if(dx>0) + { dx_sym = 1; + } + else + { if(dx<0) + { dx_sym = -1; + } + else + { + wx = x0-wx; + if(wx<0) wx = 0; + wy = x0+wy; + + while(1) + { x0 = wx; + gui_line_ver(x0, y0, y1, color); + if(wx>=wy) break; + wx++; + } + return; + } + } + + if(dy>0) + { dy_sym = 1; + } + else + { if(dy<0) + { dy_sym = -1; + } + else + { + wx = y0-wx; + if(wx<0) wx = 0; + wy = y0+wy; + + while(1) + { + y0 = wx; + gui_line_hor(x0, y0, x1, color); + if(wx>=wy) break; + wx++; + } + return; + } + } + + + dx = dx_sym * dx; + dy = dy_sym * dy; + + + dx_x2 = dx*2; + dy_x2 = dy*2; + + + if(dx>=dy) + { di = dy_x2 - dx; + while(x0!=x1) + { + draw_a = y0-wx; + if(draw_a<0) draw_a = 0; + draw_b = y0+wy; + gui_line_ver(x0, draw_a, draw_b, color); + + x0 += dx_sym; + if(di<0) + { di += dy_x2; + } + else + { di += dy_x2 - dx_x2; + y0 += dy_sym; + } + } + draw_a = y0-wx; + if(draw_a<0) draw_a = 0; + draw_b = y0+wy; + gui_line_ver(x0, draw_a, draw_b, color); + } + else + { di = dx_x2 - dy; + while(y0!=y1) + { + draw_a = x0-wx; + if(draw_a<0) draw_a = 0; + draw_b = x0+wy; + gui_line_hor(draw_a, y0, draw_b, color); + + y0 += dy_sym; + if(di<0) + { di += dx_x2; + } + else + { di += dx_x2 - dy_x2; + x0 += dx_sym; + } + } + draw_a = x0-wx; + if(draw_a<0) draw_a = 0; + draw_b = x0+wy; + gui_line_hor(draw_a, y0, draw_b, color); + } +} + + + +void gui_line_s(uint16_t const *points, uint8_t no, T_COLOR color) +{ uint16_t x0, y0; + uint16_t x1, y1; + uint8_t i; + + + if(0==no) return; + if(1==no) + { x0 = *points++; + y0 = *points; + gui_point(x0, y0, color); + } + + + x0 = *points++; + y0 = *points++; + for(i=1; i=0) gui_point(draw_x2, draw_y2, color); + + + draw_x4 = draw_x6 = x0 + r; + draw_y4 = draw_y6 = y0; + if(draw_x4=0) gui_point(draw_x5, draw_y5, color); + if(1==r) return; + + + + di = 3 - 2*r; + + xx = 0; + yy = r; + while(xx=0) ) + { gui_point(draw_x0, draw_y0, color); + } + if( (draw_x1>=0)&&(draw_y1>=0) ) + { gui_point(draw_x1, draw_y1, color); + } + if( (draw_x2<=GUI_DISPLAY_X_MAX)&&(draw_y2<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x2, draw_y2, color); + } + if( (draw_x3>=0)&&(draw_y3<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x3, draw_y3, color); + } + if( (draw_x4<=GUI_DISPLAY_X_MAX)&&(draw_y4>=0) ) + { gui_point(draw_x4, draw_y4, color); + } + if( (draw_x5>=0)&&(draw_y5>=0) ) + { gui_point(draw_x5, draw_y5, color); + } + if( (draw_x6<=GUI_DISPLAY_X_MAX)&&(draw_y6<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x6, draw_y6, color); + } + if( (draw_x7>=0)&&(draw_y7<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x7, draw_y7, color); + } + } +} + + +void gui_circle_fill(uint16_t x0, uint16_t y0, uint16_t r, T_COLOR color) +{ int16_t draw_x0, draw_y0; + int16_t draw_x1, draw_y1; + int16_t draw_x2, draw_y2; + int16_t draw_x3, draw_y3; + int16_t draw_x4, draw_y4; + int16_t draw_x5, draw_y5; + int16_t draw_x6, draw_y6; + int16_t draw_x7, draw_y7; + int16_t fill_x0, fill_y0; + int16_t fill_x1; + int16_t xx, yy; + + int16_t di; + + + if(0==r) return; + + draw_x0 = draw_x1 = x0; + draw_y0 = draw_y1 = y0 + r; + if(draw_y0=0) + { gui_point(draw_x2, draw_y2, color); + } + + draw_x4 = draw_x6 = x0 + r; + draw_y4 = draw_y6 = y0; + if(draw_x4=0) + { gui_point(draw_x5, draw_y5, color); + } + if(1==r) return; + + + + di = 3 - 2*r; + + xx = 0; + yy = r; + while(xx=0) ) + { gui_point(draw_x0, draw_y0, color); + } + if( (draw_x1>=0)&&(draw_y1>=0) ) + { gui_point(draw_x1, draw_y1, color); + } + + + if(draw_x1>=0) + { + fill_x0 = draw_x1; + + fill_y0 = draw_y1; + if(fill_y0>GUI_DISPLAY_Y_MAX) fill_y0 = GUI_DISPLAY_Y_MAX; + if(fill_y0<0) fill_y0 = 0; + + fill_x1 = x0*2 - draw_x1; + if(fill_x1>GUI_DISPLAY_X_MAX) fill_x1 = GUI_DISPLAY_X_MAX; + gui_line_hor(fill_x0, fill_y0, fill_x1, color); + } + + + if( (draw_x2<=GUI_DISPLAY_X_MAX)&&(draw_y2<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x2, draw_y2, color); + } + + if( (draw_x3>=0)&&(draw_y3<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x3, draw_y3, color); + } + + + if(draw_x3>=0) + { + fill_x0 = draw_x3; + + fill_y0 = draw_y3; + if(fill_y0>GUI_DISPLAY_Y_MAX) fill_y0 = GUI_DISPLAY_Y_MAX; + if(fill_y0<0) fill_y0 = 0; + + fill_x1 = x0*2 - draw_x3; + if(fill_x1>GUI_DISPLAY_X_MAX) fill_x1 = GUI_DISPLAY_X_MAX; + gui_line_hor(fill_x0, fill_y0, fill_x1, color); + } + + + if( (draw_x4<=GUI_DISPLAY_X_MAX)&&(draw_y4>=0) ) + { gui_point(draw_x4, draw_y4, color); + } + if( (draw_x5>=0)&&(draw_y5>=0) ) + { gui_point(draw_x5, draw_y5, color); + } + + + if(draw_x5>=0) + { + fill_x0 = draw_x5; + + fill_y0 = draw_y5; + if(fill_y0>GUI_DISPLAY_Y_MAX) fill_y0 = GUI_DISPLAY_Y_MAX; + if(fill_y0<0) fill_y0 = 0; + + fill_x1 = x0*2 - draw_x5; + if(fill_x1>GUI_DISPLAY_X_MAX) fill_x1 = GUI_DISPLAY_X_MAX; + gui_line_hor(fill_x0, fill_y0, fill_x1, color); + } + + + if( (draw_x6<=GUI_DISPLAY_X_MAX)&&(draw_y6<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x6, draw_y6, color); + } + + if( (draw_x7>=0)&&(draw_y7<=GUI_DISPLAY_Y_MAX) ) + { gui_point(draw_x7, draw_y7, color); + } + + + if(draw_x7>=0) + { + fill_x0 = draw_x7; + + fill_y0 = draw_y7; + if(fill_y0>GUI_DISPLAY_Y_MAX) fill_y0 = GUI_DISPLAY_Y_MAX; + if(fill_y0<0) fill_y0 = 0; + + fill_x1 = x0*2 - draw_x7; + if(fill_x1>GUI_DISPLAY_X_MAX) fill_x1 = GUI_DISPLAY_X_MAX; + gui_line_hor(fill_x0, fill_y0, fill_x1, color); + } + + } +} + + + +void gui_ellipse(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, T_COLOR color) +{ int16_t draw_x0, draw_y0; + int16_t draw_x1, draw_y1; + int16_t draw_x2, draw_y2; + int16_t draw_x3, draw_y3; + int16_t xx, yy; + + int16_t center_x, center_y; + int16_t radius_x, radius_y; + int16_t radius_xx, radius_yy; + int16_t radius_xx2, radius_yy2; + int16_t di; + + + if( (x0==x1) || (y0==y1) ) return; + + + center_x = (x0 + x1) >> 1; + center_y = (y0 + y1) >> 1; + + + if(x0 > x1) + { radius_x = (x0 - x1) >> 1; + } + else + { radius_x = (x1 - x0) >> 1; + } + if(y0 > y1) + { radius_y = (y0 - y1) >> 1; + } + else + { radius_y = (y1 - y0) >> 1; + } + + + radius_xx = radius_x * radius_x; + radius_yy = radius_y * radius_y; + + + radius_xx2 = radius_xx<<1; + radius_yy2 = radius_yy<<1; + + + xx = 0; + yy = radius_y; + + di = radius_yy2 + radius_xx - radius_xx2*radius_y ; + + + draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x; + draw_y0 = draw_y1 = center_y + radius_y; + draw_y2 = draw_y3 = center_y - radius_y; + + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x2, draw_y2, color); + + while( (radius_yy*xx) < (radius_xx*yy) ) + { if(di<0) + { di+= radius_yy2*(2*xx+3); + } + else + { di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy; + + yy--; + draw_y0--; + draw_y1--; + draw_y2++; + draw_y3++; + } + + xx ++; + + draw_x0++; + draw_x1--; + draw_x2++; + draw_x3--; + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x1, draw_y1, color); + gui_point(draw_x2, draw_y2, color); + gui_point(draw_x3, draw_y3, color); + } + + di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy; + while(yy>=0) + { if(di<0) + { di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy; + + xx ++; + draw_x0++; + draw_x1--; + draw_x2++; + draw_x3--; + } + else + { di += radius_xx2*3 - 2*radius_xx2*yy; + } + + yy--; + draw_y0--; + draw_y1--; + draw_y2++; + draw_y3++; + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x1, draw_y1, color); + gui_point(draw_x2, draw_y2, color); + gui_point(draw_x3, draw_y3, color); + } +} + + +void gui_ellipse_fill(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, T_COLOR color) +{ int16_t draw_x0, draw_y0; + int16_t draw_x1, draw_y1; + int16_t draw_x2, draw_y2; + int16_t draw_x3, draw_y3; + int16_t xx, yy; + + int16_t center_x, center_y; + int16_t radius_x, radius_y; + int16_t radius_xx, radius_yy; + int16_t radius_xx2, radius_yy2; + int16_t di; + + + if( (x0==x1) || (y0==y1) ) return; + + + center_x = (x0 + x1) >> 1; + center_y = (y0 + y1) >> 1; + + + if(x0 > x1) + { radius_x = (x0 - x1) >> 1; + } + else + { radius_x = (x1 - x0) >> 1; + } + if(y0 > y1) + { radius_y = (y0 - y1) >> 1; + } + else + { radius_y = (y1 - y0) >> 1; + } + + + radius_xx = radius_x * radius_x; + radius_yy = radius_y * radius_y; + + + radius_xx2 = radius_xx<<1; + radius_yy2 = radius_yy<<1; + + + xx = 0; + yy = radius_y; + + di = radius_yy2 + radius_xx - radius_xx2*radius_y ; + + + draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x; + draw_y0 = draw_y1 = center_y + radius_y; + draw_y2 = draw_y3 = center_y - radius_y; + + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x2, draw_y2, color); + + while( (radius_yy*xx) < (radius_xx*yy) ) + { if(di<0) + { di+= radius_yy2*(2*xx+3); + } + else + { di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy; + + yy--; + draw_y0--; + draw_y1--; + draw_y2++; + draw_y3++; + } + + xx ++; + + draw_x0++; + draw_x1--; + draw_x2++; + draw_x3--; + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x1, draw_y1, color); + gui_point(draw_x2, draw_y2, color); + gui_point(draw_x3, draw_y3, color); + + + if(di>=0) + { gui_line_hor(draw_x0, draw_y0, draw_x1, color); + gui_line_hor(draw_x2, draw_y2, draw_x3, color); + } + } + + di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy; + while(yy>=0) + { if(di<0) + { di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy; + + xx ++; + draw_x0++; + draw_x1--; + draw_x2++; + draw_x3--; + } + else + { di += radius_xx2*3 - 2*radius_xx2*yy; + } + + yy--; + draw_y0--; + draw_y1--; + draw_y2++; + draw_y3++; + + gui_point(draw_x0, draw_y0, color); + gui_point(draw_x1, draw_y1, color); + gui_point(draw_x2, draw_y2, color); + gui_point(draw_x3, draw_y3, color); + + + gui_line_hor(draw_x0, draw_y0, draw_x1, color); + gui_line_hor(draw_x2, draw_y2, draw_x3, color); + } +} + + +void gui_arc4(uint16_t x, uint16_t y, uint16_t r, uint8_t angle, T_COLOR color) +{ int16_t draw_x, draw_y; + + int16_t op_x, op_y; + int16_t op_2rr; + + if(r==0) return; + + op_2rr = 2*r*r; + + switch(angle) + { case 1: + draw_x = x+r; + draw_y = y; + + op_x = r; + op_y = 0; + + while(1) + { gui_point(draw_x, draw_y, color); + + + op_y++; + draw_y++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x--; + } + if(op_y>=op_x) break; + } + while(1) + { gui_point(draw_x, draw_y, color); + + op_x--; + draw_x--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y++; + } + if(op_x<=0) + { gui_point(draw_x, draw_y, color); + break; + } + } + + break; + + case 2: + draw_x = x-r; + draw_y = y; + + op_x = r; + op_y = 0; + + while(1) + { gui_point(draw_x, draw_y, color); + + op_y++; + draw_y++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x++; + } + if(op_y>=op_x) break; + } + while(1) + { gui_point(draw_x, draw_y, color); + + op_x--; + draw_x++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y++; + } + if(op_x<=0) + { gui_point(draw_x, draw_y, color); + break; + } + } + + break; + + case 3: + draw_x = x-r; + draw_y = y; + + op_x = r; + op_y = 0; + + while(1) + { gui_point(draw_x, draw_y, color); + + op_y++; + draw_y--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x++; + } + if(op_y>=op_x) break; + } + while(1) + { gui_point(draw_x, draw_y, color); + + op_x--; + draw_x++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y--; + } + if(op_x<=0) + { gui_point(draw_x, draw_y, color); + break; + } + } + + break; + + case 4: + draw_x = x+r; + draw_y = y; + + op_x = r; + op_y = 0; + + while(1) + { gui_point(draw_x, draw_y, color); + + op_y++; + draw_y--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x--; + } + if(op_y>=op_x) break; + } + while(1) + { gui_point(draw_x, draw_y, color); + + op_x--; + draw_x--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y--; + } + if(op_x<=0) + { gui_point(draw_x, draw_y, color); + break; + } + } + break; + + default: + break; + + } + +} + +void gui_arc(uint16_t x, uint16_t y, uint16_t r, uint16_t stangle, uint16_t endangle, T_COLOR color) +{ int16_t draw_x, draw_y; + int16_t op_x, op_y; + int16_t op_2rr; + + int16_t pno_angle; + uint8_t draw_on; + + if(r==0) return; + if(stangle==endangle) return; + if( (stangle>=360) || (endangle>=360) ) return; + + op_2rr = 2*r*r; + pno_angle = 0; + + op_x = r; + op_y = 0; + while(1) + { pno_angle++; + op_y++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + } + if(op_y>=op_x) break; + } + + draw_on = 0; + + if(endangle>stangle) draw_on = 1; + stangle = (360-stangle)*pno_angle/45; + endangle = (360-endangle)*pno_angle/45; + if(stangle==0) stangle=1; + if(endangle==0) endangle=1; + + pno_angle = 0; + + draw_x = x+r; + draw_y = y; + op_x = r; + op_y = 0; + while(1) + { + op_y++; + draw_y--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x--; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + if(op_y>=op_x) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + while(1) + { + op_x--; + draw_x--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y--; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + + if(op_x<=0) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + + draw_y = y-r; + draw_x = x; + op_y = r; + op_x = 0; + while(1) + { + op_x++; + draw_x--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) + { op_y--; + draw_y++; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + + if(op_x>=op_y) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + while(1) + { + op_y--; + draw_y++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) + { op_x++; + draw_x--; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + if(op_y<=0) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + draw_x = x-r; + draw_y = y; + op_x = r; + op_y = 0; + while(1) + { + op_y++; + draw_y++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) + { op_x--; + draw_x++; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + if(op_y>=op_x) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + while(1) + { + op_x--; + draw_x++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) + { op_y++; + draw_y++; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + + if(op_x<=0) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + draw_y = y+r; + draw_x = x; + op_y = r; + op_x = 0; + while(1) + { + op_x++; + draw_x++; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) + { op_y--; + draw_y--; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + + if(op_x>=op_y) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + + while(1) + { + op_y--; + draw_y--; + if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) + { op_x++; + draw_x++; + } + if(draw_on==1) gui_point(draw_x, draw_y, color); + pno_angle++; + if( (pno_angle==stangle)||(pno_angle==endangle) ) + { draw_on = 1-draw_on; + if(draw_on==1) gui_point(draw_x, draw_y, color); + } + if(op_y<=0) + { if(draw_on==1) gui_point(draw_x, draw_y, color); + break; + } + } + +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_basic.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_basic.h new file mode 100644 index 0000000..af87afa --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_basic.h @@ -0,0 +1,225 @@ +/** + ***************************************************************************************** + * + * @file gui_basic.h + * + * @brief Gui basic function API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +#ifndef GUI_BASIC_H +#define GUI_BASIC_H + +#include "gui_config.h" + + +uint32_t gui_pow(uint32_t m,uint8_t n); + +/** + ***************************************************************************************** + * @brief Draw a horizontal line. + * + * @param[in] x0: X coordinate at the beginning of the horizontal line. + * @param[in] y0: Y coordinate at the beginning of the horizontal line. + * @param[in] x1: X coordinate at the end of the horizontal line. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_line_hor(uint16_t x0, uint8_t y0, uint16_t x1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a vertical line. + * + * @param[in] x0: X coordinate at the beginning of the vertical line. + * @param[in] y0: Y coordinate at the beginning of the vertical line. + * @param[in] x1: X coordinate at the end of the vertical line. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_line_ver(uint16_t x0, uint8_t y0, uint8_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a rectangle. + * + * @param[in] x0: The x coordinate of the upper-left corner of the rectangle. + * @param[in] y0: The y coordinate of the upper-left corner of the rectangle. + * @param[in] x1: The x coordinate of the bottom right corner of the rectangle. + * @param[in] y1: The y coordinate of the bottom right corner of the rectangle. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_rectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a filled rectangle. + * + * @param[in] x0: The x coordinate of the upper-left corner of the rectangle. + * @param[in] y0: The y coordinate of the upper-left corner of the rectangle. + * @param[in] x1: The x coordinate of the bottom right corner of the rectangle. + * @param[in] y1: The y coordinate of the bottom right corner of the rectangle. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_rectangle_fill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a square. + * + * @param[in] x0: The x coordinate of the upper-left corner of the rectangle. + * @param[in] y0: The y coordinate of the upper-left corner of the rectangle. + * @param[in] with: With of square. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_square(uint16_t x0, uint16_t y0, uint16_t with, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a line between any two points. + * + * @param[in] x0: The x coordinate of the starting of the line. + * @param[in] y0: The y coordinate of the starting of the line. + * @param[in] x1: The x coordinate of the end of the line. + * @param[in] y1: The y coordinate of the end of the line. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a line between any two points and can set width. + * + * @param[in] x0: The x coordinate of the starting of the line. + * @param[in] y0: The y coordinate of the starting of the line. + * @param[in] x1: The x coordinate of the end of the line. + * @param[in] y1: The y coordinate of the end of the line. + * @param[in] width: Line width. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_line_width(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t width, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a line of points. + * + * @param[in] points: line points. + * @param[in] no: count of points. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_line_s(uint16_t const *points, uint8_t no, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a circle. + * + * @param[in] x0: The x coordinate of the center of the circle. + * @param[in] y0: The y coordinate of the center of the circle. + * @param[in] r: The radius of the circle + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_circle(uint16_t x0, uint16_t y0, uint16_t r, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a fill circle. + * + * @param[in] x0: The x coordinate of the center of the circle. + * @param[in] y0: The y coordinate of the center of the circle. + * @param[in] r: The radius of the circle + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_circle_fill(uint16_t x0, uint16_t y0, uint16_t r, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a ellipse. + * + * @param[in] x0: The x coordinate of the left of the ellipse. + * @param[in] x1: The x coordinate on the right of the ellipse. + * @param[in] y0: The y coordinate on the up of the ellipse. + * @param[in] y1: The y coordinate on the down of the ellipse. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_ellipse(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a fill ellipse. + * + * @param[in] x0: The x coordinate of the left of the ellipse. + * @param[in] x1: The x coordinate on the right of the ellipse. + * @param[in] y0: The y coordinate on the up of the ellipse. + * @param[in] y1: The y coordinate on the down of the ellipse. + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_ellipse_fill(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a arc. + * @note The angle must be 0,90,-90,-180,180,-270,270 + * + * @param[in] x: The x coordinate of the center of the arc. + * @param[in] y: The y coordinate of the center of the arc. + * @param[in] r: The radius of the arc + * @param[in] angle: The angle of the arc + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_arc4(uint16_t x, uint16_t y, uint16_t r, uint8_t angle, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a any angle arc. + * + * @param[in] x: The x coordinate of the center of the arc. + * @param[in] y: The y coordinate of the center of the arc. + * @param[in] r: The radius of the arc + * @param[in] stangle: Start angle of the arc + * @param[in] endangle: End angle of the arc + * @param[in] color: Display color. + ***************************************************************************************** + */ +void gui_arc(uint16_t x, uint16_t y, uint16_t r, uint16_t stangle, uint16_t endangle, T_COLOR color); + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_color.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_color.c new file mode 100644 index 0000000..3d59954 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_color.c @@ -0,0 +1,99 @@ +/** + **************************************************************************************** + * + * @file gui_color.c + * + * @brief Function of set color + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_color.h" +#include "gui_config.h" + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint8_t const DCB2HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +static T_COLOR s_disp_color;/**< Display color. */ +static T_COLOR s_back_color;/**< Back color. */ + + +uint8_t gui_dcb_to_hex(uint8_t dcb) +{ + return DCB2HEX_TAB[dcb]; +} + +void gui_set_color(T_COLOR disp_color, T_COLOR back_color) +{ + s_disp_color = disp_color; + s_back_color = back_color; +} + +T_COLOR gui_get_back_color(void) +{ + return s_back_color; +} + +T_COLOR gui_get_disp_color(void) +{ + return s_disp_color; +} + + +void gui_exchange_color(void) +{ + T_COLOR bakc; + bakc = s_disp_color; + s_disp_color = s_back_color; + s_back_color = bakc; +} + + +void gui_point_color(uint8_t x, uint8_t y, uint8_t font_dat, uint8_t num) +{ + uint8_t j; + uint8_t x_coord = x; + T_COLOR bakc; + for(j=0; jXQEOir%NYvFKM*IVir9mi?t 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Ⓢ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 G>;DJq)CV&F literal 0 HcmV?d00001 diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gb2312_font.hex b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gb2312_font.hex new file mode 100644 index 0000000..f2e6b0f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gb2312_font.hex @@ -0,0 +1,8231 @@ +:020000040103F6 +:20D00000000000000000000000000000000000000000000000000000000000000000000010 +:20D020000000000000000000000020180C04000000000000000000000000000000000000A8 +:20D04000000000000000000000001824241800000000000000000000000000000000000058 +:20D060000000000000000000010100000000000000000000000000008080000000000000AE +:20D080000000000F000000000000000000000000000000E0000000000000000000000000A1 +:20D0A000000804020100000000000000000000000020408000000000000000000000000081 +:20D0C0000000000C0C00000000000000000000000000006060000000000000000000000078 +:20D0E000000000000202020404090000000000000000000040404080800000000000000059 +:20D1000000000404040F081020050201010000000000000020F020408000000000000000C3 +:20D12000000000000000007F000000000000000000000000000000FC000000000000000074 +:20D14000000000000000001C23400000000000000000000000000004887000000000000054 +:20D16000000202020202020202020202020202000040404040404040404040404040400013 +:20D18000000000000000636300000000000000000000000000001818000000000000000099 +:20D1A0000000000000000000000000000000000000081020303000000000000000000000D7 +:20D1C0000018180810200000000000000000000000000000000000000000000000000000E7 +:20D1E00000000102030300000000000000000000008810203030000000000000000000000E +:20D20000001919081122000000000000000000000080808000000000000000000000000021 +:20D2200000000000000000000000000000000000000810202020202020202020201008007E +:20D2400000201008080808080808080808102000000000000000000000000000000000001E +:20D260000000000000000001000000000000000000040810204080008040201008040000B5 +:20D28000002010080402010001020408102000000000000000000080000000000000000090 +:20D2A00000000000010204090402010000000000102448902040800080402090482410007F +:20D2C000082412090402010001020409122408000000000080402090204080000000000062 +:20D2E00000000000000000000000000000000000003C2020202020202020202000000000B2 +:20D3000000000000040404040404040404043C0000000000000000000000000000000000A9 +:20D320000000000000000000000000000000000000FC84BCA0A0A0A0A0A0A0E00000000071 +:20D340000000000007050505050505053D213F000000000000000000000000000000000006 +:20D360000001010101010101010101010101010000FC081010202020202020101008FC0097 +:20D38000003F1008080404040404040808103F0000808080808080808080808080808000B7 +:20D3A0000001010101010101010101010101010000FCF8F0E0E0C0C0C0C0E0E0F0F8FC0017 +:20D3C000003F1F0F07070303030307070F1F3F00008080808080808080808080808080004B +:20D3E0000000010101011F01010101001F000000000000000000F00000000000F000000007 +:20D400000000001008040201020408100000000000000010204080008040201000000000EF +:20D42000000000030300003F000003030000000000000000000000F00000000000000000B1 +:20D440000000000006060000000606000000000000000000000000000000000000000000B4 +:20D460000001010202040408081010202040000000000080804040202010100808040000FA +:20D480000000402020101008080404020201010000000408081010202040408080000000DA +:20D4A000007F30180C0603010102040810207F0000FC040400000080000000000404FC0049 +:20D4C000007F1818181818181818181818183C0000F8606060606060606060606060F00009 +:20D4E000002020202020202020202020100807000008080808080808080808081020C00065 +:20D500000007081020202020202020202020200000C0201008080808080808080808080044 +:20D52000000106080810101F101010080806010000E00000000000E0000000000000E000AE +:20D540000000001818000000000018180000000000000030300000000000303000000000AB +:20D5600000000000000000000000040A12010000020204040808101020204040800000000E +:20D5800000010101010101010101010101013F000000000000000000000000000000F80047 +:20D5A00002020202020204040404040909090909404040404040808080808000000000001E +:20D5C000000000000000000102040810207F000000040810204080000000000000FC000095 +:20D5E00000000718202040400000000000000000000080601010080800000000000000003C +:20D60000000007182020404343402020180700000000806010100808080810106080000026 +:20D620000000010101010101010101010109060000C02000000000000000000000000000F0 +:20D6400000010101010709090909070101010906C020000000C020202020C00000000000A2 +:20D6600000000000007F007F007F0000000000000000000000FC00FC00FC00000000000039 +:20D6800000001820414142221C007F007F00000000007088040404083000FC00FC0000001E +:20D6A00000000000001C23401C234000000000000000000000048870048870000000000074 +:20D6C00000000000384080818182423C000000000000000078848202020204380000000090 +:20D6E000000000003C4281818181423C00000000000000007E8000000000807E000000002E +:20D7000000000000007F0101027F0408081010000020204040FC000000FC0000000000001B +:20D7200000010101030D31C1310D030101010000000C30C000000000000000C0300C0000A8 +:20D740000061190701010101010101071961000000000000806018061860800000000000CA +:20D76000000000030C30C030CC330C03000000000C30C000000000000000C030CC300C0078 +:20D78000601806010000000000010619661860000000008060180618669860800000000018 +:20D7A000000000003C42818181423C000000000000000000788402020284780000000000EC +:20D7C000000000303000000000000003030000000000003030000000000000000000000083 +:20D7E000000000030300000000000030300000000000000000000000000000303000000063 +:20D8000000010305091101010101030404040300000080402010000000008040404080001F +:20D8200000030404040301013F010101010101000080404040800000F800000000000000D7 +:20D84000001824241800000000000000000000000000000000000000000000000000000050 +:20D86000000808101020000000000000000000000000000000000000000000000000000058 +:20D880000012122424480000000000000000000000000000000000000000000000000000D4 +:20D8A0006091966C08181818181818080C06010000F40C0404000000000000000408F000BE +:20D8C000010F11313131190F03010101110D070100E0301000000000C07018181830E00098 +:20D8E00000402017081010101010100817204000000204E81008080808080810E80402009E +:20D90000000007183060616162626438181720401020E858488000000000000810E0000077 +:20D92000000101010202023F0404080808107F00E0100000000000C0000000000000C00080 +:20D94000003048484849320408132444840403000810204080000000000C929292920C00DA +:20D960000304040402050908080405020100080780404000000000808080000000808000DD +:20D98000602131313929292D2D2527272323A14180400000182424242424242418007E00BA +:20D9A000010102020204FC4030080811161820000000808080407E041820209050300800CE +:20D9C000010103030307FF7F3F0F0F1F1E1820000000808080C0FEFCF8E0E0F0F0300800DB +:20D9E00000071C3030606060606030301C07000000C07018180C0C0C0C0C181870C0000045 +:20DA000000071F3F3F7F7F7F7F7F3F3F1F07000000C0F0F8F8FCFCFCFCFCF8F8F0C0000017 +:20DA20000007182324485050504824231807000000C03088482414141424488830C0000096 +:20DA400001020408102040804020100804020100008040201008040204081020408000004E +:20DA60000103070F1F3F7FFF7F3F1F0F070301000080C0E0F0F8FCFEFCF8F0E0C0800000B3 +:20DA8000007F40404040404040404040407F000000FC0404040404040404040404FC0000A4 +:20DAA000007F7F7F7F7F7F7F7F7F7F7F7F7F000000FCFCFCFCFCFCFCFCFCFCFCFCFC000027 +:20DAC000000101020204040808101020207F000000000080804040202010100808FC00005D +:20DAE000000101030307070F0F1F1F3F3F7F00000000008080C0C0E0E0F0F0F8F8FC0000AB +:20DB000000432310080402616204081023438000000408102040800C8C40201008040200AA +:20DB200000000000000000FF000000000000000000000000806038FE3860800000000000B8 +:20DB400000000000020C38FF380C02000000000000000000000000FE00000000000000003C +:20DB60000101030307050901010101010101010100008080C040200000000000000000005F +:20DB8000010101010101010101090507030301010000000000000000002040C0808000003F +:20DBA0000000007F7F7F0000007F7F7F00000000000000FCFCFC000000FCFCFC0000000083 +:20DBC0000001000001030501010101010300000000000000000000000000000080000000B3 +:20DBE0000008000008180808080808081C0000000040000040C0404040404040E000000011 +:20DC00000011000011331111111111113B000000001000001030101010101010B8000000A6 +:20DC200000100000163212111110101038000000000000000C08081010A0A04040000000F4 +:20DC400000000000180808040402020101000000000000003020204040808000000000009E +:20DC600000000000C14141222214140808000000001000009030101010101010380000007D +:20DC800000000000C644444428282810100000000044000044CC444444444444EE00000080 +:20DCA00000010000C5474545292929111300000000240000246C242424242424AE000000F4 +:20DCC00000200000276221202020212277000000000000001C0810A040A010081C00000078 +:20DCE000000000001C080402010204081C000000000000007020408000804020700000002F +:20DD0000000000000000000000000000000000000000000000000000000000000000000003 +:20DD20000000000000000000000000000000000000000000000000000000000000000000E3 +:20DD40000000000000000000000000000000000000000000000000000000000000000000C3 +:20DD60000000000000000000000000000000000000000000000000000000000000000000A3 +:20DD8000000000000000000000000000000000000000000000000000000000000000000083 +:20DDA000000000000000000000000000000000000000000000000000000000000000000063 +:20DDC000010305010101010101010101000000000000000000000000000018180000000001 +:20DDE0000F100000000102040810101F000000000080808080000000000018980000000006 +:20DE00001F000102060100000000110E00000000808000000000808080801818000000008A +:20DE200002020404090911111F010101000000000000000000000000C00018180000000090 +:20DE40001F1010101E0100000000110E000000008000000000008080808018180000000085 +:20DE600002040808101718101010100F00000000000000000000808080809818000000004E +:20DE80001F000000010102020202020200000000C040808000000000000018180000000025 +:20DEA0000F101010090609101010100F00000000008080800000008080809818000000000C +:20DEC0000F10101010110E000101020400000000008080808080808000001818000000001C +:20DEE0002364A424242424242424242300000000C02020202020202020202CCC00000000DC +:20DF00002061A220202020202020202000000000808080808080808080808C8C00000000A6 +:20DF20002364A020202020212224242700000000C02020202040800000000CEC0000000090 +:20DF40002760A020212020202020242300000000E02040808040202020204C8C000000009A +:20DF60002060A1212222242427202020000000008080000040404040F0404C4C0000000084 +:20DF80002764A424272020202020242300000000E00000008040202020204C8C0000000028 +:20DFA0002061A2222425262424242423000000008000000000C0202020202CCC0000000042 +:20DFC0002760A020202020202020202000000000F01020204040808080808C8C0000000022 +:20DFE0002364A424222122242424242300000000C02020204080402020202CCC0000000042 +:20E000002364A424242423202020202100000000C02020202060A02040408C0C000000002D +:20E0200038450505050911212141417C00000000E010101010101010101016E6000000008E +:20E040001020414385818181818181814141201010080404020202020202020204040810FE +:20E06000102047488080808081828488484F201010088444424242820202020204C40810FB +:20E0800010204F408081838080808080484720101008C4448202028242424242840408102E +:20E0A000102041418282848488888F804040201010080404020282828282E2828484081023 +:20E0C000102047448484878080808080444320101008E4040202824222222222448408108F +:20E0E000102041428484888B8C8888884847201010080404020202824242424244840810DF +:20E1000010204F408080808081818181414120101008E424424282820202020204040810BA +:20E1200010204748888884838488888848472010100884444242820282424242448408101E +:20E14000102043448484848483808080404120101008C42422222262A22242428404081094 +:20E1600010204859A989898989898989494820101008E414121212121212121214E40810F5 +:20E1800010204858A8888888888888884848201010082464A22222222222222224240810FF +:20E1A00010204859A888888888888889494920101008E414121212224282820204F40810AB +:20E1C00010204B58A8888888888888884A4920101008F4142242C2221212121224C4081099 +:20E1E00010204858A88889898A8A8B884848201010084444828222222222FA22242408107E +:20E2000010204B5AAA8A8B88888888884A4920101008F4040202C2221212121224C40810BF +:20E2200010204858A9898A8A8B8A8A8A4A49201010084484020202E21212121214E40810BC +:20E2400010204B58A888888888888888484820101008F414222242428282828284840810BB +:20E260001020495AAA8A8988898A8A8A4A4920101008E414121222C22212121214E408101C +:20E280001020495AAA8A8A8A89888888484820101008E41412121232D21222224484081002 +:20E2A00010204C528282828484889090505E201010086494929292929292929294640810CC +:20E2C00007182041438581818181414120180700C030080404020202020204040830C00027 +:20E2E00007182043448080808182444720180700C030088444424282020204C40830C00081 +:20E3000007182047408081838080444320180700C03008C444820202824244840830C000E3 +:20E320000718204142828484888F404020180700C03008040402828282E284840830C00051 +:20E3400007182047448487808080484720180700C03008C404028242424284040830C00010 +:20E3600007182041428284858684444320180700C030080404020282424244840830C000B6 +:20E3800007182047408080818181414120180700C03008C444828202020204040830C00069 +:20E3A00007182043448484838484444320180700C030088444424282424244840830C00034 +:20E3C00007182043448484838080414220180700C0300884444242C2428204040830C00060 +:20E3E000071820495AAA8A8A8A8A4A4920180700C03008C424222222222224C40830C0002D +:20E40000000000010608083F181F080C06010000000000E0100000E000C0000030C00000D4 +:20E420000000000000000000000000000000000000000000000000000000000000000000DC +:20E4400010204040808080BF808080804040201010080404020202FA0202020204040810D5 +:20E46000102040409F8080808080BF804040201010080404F20202020202FA0204040810A6 +:20E480001020405F8080808F808080BF40402010100804F4020202E2020202FA0404081097 +:20E4A000102040409F9292929498909F5040201010080404F2929292721212F214040810BC +:20E4C0001020404F8181818F828282825F402010100804E4020202E222222222FC0408100C +:20E4E000102040428180BF808084848850402010100804040202FA02024222121404081092 +:20E500001020424282828283BE8282824241201010080404020202F20202222224E40810C7 +:20E520001020404484848484848888904040201010088484828282424222221204040810A3 +:20E5400010204242829F828282848488504020101008040402C2424242424A4A3C04081038 +:20E5600010204141818181BF818181814140201010080404020202FA0202020204040810AA +:20E5800000000000000000000000000000000000000000000000000000000000000000007B +:20E5A00000000000000000000000000000000000000000000000000000000000000000005B +:20E5C000000301010101010101010101010103000080000000000000000000000000800029 +:20E5E000000E0404040404040404040404040E0000E0404040404040404040404040E0000F +:20E60000003B1111111111111111111111113B0000B8101010101010101010101010B80088 +:20E6200000772222222121212120202020207000001C08080810101010A0A0A0A0404000F5 +:20E6400000702010100808080404040202010100001C08101020202040404080800000007C +:20E660000071202020111111110A0A0A0A04040000DC8888880808080808080808081C007D +:20E6800000E3414141222222221414141408080000FE2424242424242424242424247E00C0 +:20E6A00000E3414141222222221414141408080000FE545454545454545454545454FE00E0 +:20E6C00000772221212020202020202121227700001C081010A0A04040A0A01010081C003C +:20E6E00000702010080402010204040810207000001C0810204080008040402010081C0051 +:20E7000000E3412222141408081414222241E300009C0808080808080808080808089C0031 +:20E7200000E3412222141408081414222241E30000BE141414141414141414141414BE003D +:20E740000000000000000000000000000000000000000000000000000000000000000000B9 +:20E76000000000000000000000000000000000000000000000000000000000000000000099 +:20E780000010101010101010101000001010000000000000000000000000000000000000C9 +:20E7A000000C0C0C08080000000000000000000000C0C0C0808000000000000000000000E5 +:20E7C00000020202023F040404043F08080808000020202020FC40404040FC80808080000B +:20E7E0000000100804020101010F010101010100000010204080000000E000000000000014 +:20E80000001824242424241902040810204000000004081020408000609090909090600009 +:20E820000006091010090A040A12212020110E000000008080000000007020A040A01000D6 +:20E840000038383810101000000000000000000000000000000000000000000000000000E0 +:20E86000000000000000000000000000000000000008102020404040404040202010080068 +:20E880000020100808040404040404080810200000000000000000000000000000000000E0 +:20E8A000000001010101310D0302040810000000000000000000186080804020100000000D +:20E8C000000001010101013F010101010100000000000000000000F80000000000000000F7 +:20E8E000000000000000000000000030301020000000000000000000000000000000000088 +:20E90000000000000000001F000000000000000000000000000000F00000000000000000E8 +:20E92000000000000000000000000000303000000000000000000000000000000000000077 +:20E9400000000000000000000102040810204000000204081020408000000000000000003A +:20E9600007081010101010101010080700000000C020101010101010101020C000000000B9 +:20E98000010305010101010101010101000000000000000000000000000000000000000065 +:20E9A00007081000000000010204081F000000008040202020408000000000F0000000003A +:20E9C0000F000000010000000000080700000000F0204080C0201010101020C00000000048 +:20E9E00002020404080810103F000000000000000000008080808080F080808000000000AC +:20EA00001F1010101F0000000000100F00000000C0000000008040404040800000000000A9 +:20EA200000010204080F101010100807000000008000000000804020202040800000000009 +:20EA40001F000000000101020202020200000000F02040808000000000000000000000003B +:20EA60000708101008070810101008070000000080402020408040202020408000000000F1 +:20EA800007081010100807000001020400000000804020202020C040800000000000000061 +:20EAA000000000000000000000303000303000000000000000000000000000000000000096 +:20EAC000000000000000000030300030301020000000000000000000000000000000000046 +:20EAE00000000000030C30C0300C030000000000000C30C000000000000000C0300C0000E0 +:20EB00000000000000003F00003F000000000000000000000000F80000F800000000000087 +:20EB20000060180601000000000001061860000000000000806018061860800000000000E1 +:20EB4000000E1121313103060606060006060000000000808080000000000000000000006C +:20EB6000001F20000E1120202020110E0000000000E0100888888888888890600000000080 +:20EB8000000102020404080F101020700000000000008080404020E01010081C00000000DD +:20EBA000001F080808080F080808081F0000000000E010101020C020101010E000000000A8 +:20EBC0000007081010101010101008070000000000C0201000000000001020C000000000C7 +:20EBE000003F1010101010101010103F0000000000C0201010101010101020C000000000D7 +:20EC0000003F101010101F101010103F0000000000F0101000808080001010F00000000037 +:20EC2000003F101010101F10101010380000000000F010100040C04000000000000000006E +:20EC40000007081010101010101008070000000000D0301000000078101030D0000000007E +:20EC60000038101010101F101010103800000000007020202020E0202020207000000000C5 +:20EC8000000301010101010101010103000000000080000000000000000000800000000065 +:20ECA00000030101010101010111110E00000000008000000000000000000000000000009A +:20ECC000001C0808090A0E090808081C000000000070408000000000804020380000000062 +:20ECE00000381010101010101010103F000000000000000000000000000020E0000000000D +:20ED0000003018141412121111101038000000000018305050909010101010380000000065 +:20ED2000003018141412111110101038000000000070202020202020A0A0602000000000D7 +:20ED40000007081020202020201008070000000000804020101010101020408000000000C5 +:20ED6000003F101010101F10101010380000000000C020101020C00000000000000000009D +:20ED800000070810202020202011080700000000008040201010101010A040A018000000CC +:20EDA000003F101010101F12111010380000000000C020101020C00000804030000000006A +:20EDC0000007081010080700001018170000000000D030100000C020101020C000000000C6 +:20EDE000003F212101010101010101030000000000F8080800000000000000800000000000 +:20EE00000038101010101010101008070000000000702020202020202020408000000000FB +:20EE200000702010100808040402020100000000001C081010202040408080000000000001 +:20EE400000732121212212121414080800000000009C080808889090505020200000000022 +:20EE600000380804040201020404083800000000003820404080008040402038000000004D +:20EE8000003810080404020101010103000000000038102040408000000000800000000029 +:20EEA000001F1010000001020204081F0000000000F0204080800000001010F00000000083 +:20EEC00000000000000000000000000000000000001C1010101010101010101010101C003A +:20EEE000004020100804020100000000000000000000000000000000804020100804020095 +:20EF0000003808080808080808080808080838000000000000000000000000000000000021 +:20EF20000001020408000000000000000000000000008040200000000000000000000000E2 +:20EF40000000000000000000000000000000007F000000000000000000000000000000FC36 +:20EF6000000000000000000000000000000000000020202010100800000000000000000009 +:20EF8000000000000F10000F1010100F0000000000000000804040C0404040A000000000E4 +:20EFA000080808080B0C080808080C0B0000000000000000804020202020408000000000E3 +:20EFC0000000000007081010101008070000000000000000C0200000000020C00000000013 +:20EFE0000000000003040808080804030000000020202020A0602020202060A000000000E3 +:20F00000000000000304080F080804030000000000000000804020E0000020C0000000001B +:20F020000000010101010701010101010101010000C020200000C0000000000000000000FD +:20F040000000000003040808080403000008070000000000A06020202060A020204080001B +:20F0600008080808090A0C08080808080000000000000000C0202020202020200000000089 +:20F08000010100000701010101010101000000000000000000000000000000000000000060 +:20F0A000010100000701010101010101010906000000000000000000000000000000000030 +:20F0C000000808080808090A0D080808000000000000000040800000008040200000000030 +:20F0E000010101010101010101010100000000000000000000000000000020E00000000005 +:20F10000000000001A0D0909090909090000000000000000C02020202020202000000000F2 +:20F12000000000000B0C080808080808000000000000000000808080808080800000000008 +:20F14000000000000304080808080403000000000000000080402020202040800000000081 +:20F16000000000001B0C080808080C0B080808000000000080402020202040800000000019 +:20F180000000000003040808080804030000000000000000A0602020202060A02020300051 +:20F1A00000000000050202020202020200000000000000008040000000000000000000007C +:20F1C0000000000007080806010008070000000000000000804000008040408000000000C2 +:20F1E0000101010107010101010101000000000000000000C000000000004080000000007E +:20F20000000000000C040404040404030000000000000000404040404040C0400000000047 +:20F220000000000008080404020201010000000000000000202040408080000000000000F0 +:20F2400000000000111111090A0A0404000000000000000010101020A0A040400000000046 +:20F260000000000000080402010204080000000000000000002040800080402000000000B1 +:20F280000000000008040402020101020204080000000000204040808000000000000000A8 +:20F2A000000000000F0000010204080F0000000000000000C0408000000000C000000000E1 +:20F2C000000000000000000000000000000000000408080808081020100808080808040096 +:20F2E000000101010101010101010101010101000000000000000000000000000000000000 +:20F300002010101010100804081010101010200000000000000000000000000000000000F9 +:20F32000FF000000000000000000000000000000FE000000000000000000000000000000D0 +:20F340000000000404053E04070C1423222518000000000000F00040E0908808081020C08D +:20F36000040404077C04041F244445422619000000006080004040F0888404040408300009 +:20F380000000000000100808080808090A06000000000000000000201008181000000000BC +:20F3A000000000201010101010202122140C00000000000000102804020206040000000010 +:20F3C000000807000100110E0000000000030C00000000800000C02020204040800000004F +:20F3E0000807000100211E000000000000010E000080408000E0101010102020C00000004F +:20F4000000000403000100031C0103040810200000000000800000C080000080804038004D +:20F420000807000100033C0102030404081020000000800000C080000000808080403C007B +:20F440000000000404043F0405060C14341508000000000000080402E41008080830C000D7 +:20F46000000404073C040405061C2464350C040000000884020C00F00804040418E00000AF +:20F480000002020202231C040404080810244300000000001088444242444040808000006E +:20F4A000000404040447380808081010214986000804120824108884848890800000000013 +:20F4C000020202031D00031C00030010100807000000608000E0804040E020000000C00035 +:20F4E000040404073A0107380007002020100F000008C41208C4008080C0400000008000EF +:20F500000001000001020408100804020100000000008080000000000000000000808000BC +:20F52000000100000102040810080402010000000008849208040000000000000080800072 +:20F54000002010101020204740405050602001000080404040407CC04040404040800000B7 +:20F56000002010101020204740405050602001000884524844407CC040404040408000006D +:20F580000000100F00030400202020100F000000000000E08000000000000010F80000005E +:20F5A0000000100F00030400202020100F000000000804D28804000000000010F800000034 +:20F5C000000402023F0100000108101010080700000030C000008040E02000000000E0000B +:20F5E000000402023F0100000108101010080700000804D208048040E02000000000E000F1 +:20F6000000201010101010101010101010090600000000000000000000001020408000001B +:20F620000020101010101010101010101009060000100824100800000000102040800000A7 +:20F64000000301413F010709090906000000010600000000F800008040404040808000007E +:20F66000030101413F010709090906000000010608241208F000008040404040808000001F +:20F6800000001008080B7C08080A0908080807000080404040FC4040404040800000F00095 +:20F6A00000001008080B7C08080A0908080807000884524844F04040404040800000F00057 +:20F6C00000110E000106187F0204040402010000008040800010F8000000000000F0000024 +:20F6E00000110E000106187F020404040201000008A452880010F8000000000000F00000BE +:20F70000000404473C09080810101222214000000000000000E030400000000008FC00003C +:20F72000000404473C09080810101222214000000804120804E030400000000008FC0000F2 +:20F7400000040405077C080B0C1810000000000300000000800000C0201010102020C0003F +:20F7600000040405077C080B0C1810000000000300080412880400C0201010102020C000F5 +:20F7800000000000000000001F0800000000010000000000000000C0201010102040800051 +:20F7A00000000001067820000000000000070000000000E01008080808101020C000000093 +:20F7C000000000030CF0400000000000010E0000080412C824101010102020408000000091 +:20F7E00000000000007F2102040404040402010000000008FCC00000000000000000F0009C +:20F8000000000000007F2102040404040402010000000008FCC00804120804000000F00051 +:20F820000000020101010101070810101008070000000000002030C0000000000000F00073 +:20F840000000020101010101070810101008070008041208042030C0000000000000F00029 +:20F8600000040404073C040808101023440403000000100884040820202040E05048840053 +:20F88000002010101320202040404A5251202000000000F8081000000000000008FC0000F4 +:20F8A0000002021111131519112A2A44444A320000000000F0080404040468989462020078 +:20F8C00000080808083E090A0C182848492918000000000060900808080810F01824C2008B +:20F8E00000000007192142424244442810000000000000C030080404040408081020C00039 +:20F90000002010101423202040484853546423000080404040F84040404040C070488400BE +:20F92000002010101423202040484853546423000884524844F04040404040C0704884007C +:20F94000002010101423202040484853546423000C92524C40F04040404040C0704884004A +:20F960000000023E040808101020202020100F000000002020302824202040404080000038 +:20F980000000023E040808101020202020100F00080412082430282420204040408000000E +:20F9A0000000023E040808101020202020100F000C12120C203028242020404040800000DC +:20F9C00000030000010202010003044458260100000080C000000000E098848C808000008C +:20F9E00000030000010202010003044458260100080492C804000000E098848C8080000042 +:20FA0000000300000102020100030444582601000C1292CC00000000E098848C808000000F +:20FA2000000000000609106000000000000000000000000000804020180600000000000049 +:20FA40000000000006091060000000000000000000080412088440201806000000000000FF +:20FA6000000000000609106000000000000000000018242418804020180600000000000091 +:20FA8000002013101024232040484853546423000070C0404040F840404040C070488400CA +:20FAA000002013101024232040484853546423000864C2484440F840404040C070488400A0 +:20FAC00000201310102423204048485354642300006CD2524C40F840404040C0704884005E +:20FAE0000001211F0101110F0101011D23211E00000000F0200000E000000000C030080039 +:20FB00000000130C00000101011A27444830000100000080808000101020A07048448000E9 +:20FB200000080404077C041C2626160C0808070000000080C0080402060800101018F00009 +:20FB400000012010101F112945424548300000000000808080C02010080808101020C0003F +:20FB600002020202231E0404443F04040404030000000000C0001008C80808080808F000E6 +:20FB800000000003000009241F020201010000000000000080800070880810600080804060 +:20FBA00000020100000910117E0808040202010000008040408030C8040488700000008089 +:20FBC00000000001001011122424282A31100102000000008080E0908888888890E0000013 +:20FBE00000001010111222242424282A3110000300804040F04844444242424458E080001C +:20FC000000000002010101010101010F11110E00000000000020F000000000C03008040090 +:20FC2000000201010101010101011F2141423C00000000001038C000000000C030080400B7 +:20FC4000001804020204081010131418000000030000000000000000E01008080830C0001E +:20FC6000001008090A0A0A0C0C08080000000102000080402020202020204040808000001A +:20FC8000000007040000010207080001020201000040A020408000F0080404844448F00081 +:20FCA000000808080E790A0C0818282868180800000000C0A0202020404040424224180057 +:20FCC00000031C000102040F182000000000010000C040800000E01008080810106080002E +:20FCE0000000080404073C070C1424340C040000000000000000F0080808081020C0000022 +:20FD0000001008080F780B0C0818284868180800000000000000E01804040404081060008D +:20FD200000000718000007081021414224180000000080808080E0908804046494887000B5 +:20FD4000000F000107081003040302041826210000808000E0101090A0C000003844880011 +:20FD6000000201110F0101020404080102020100000010E0000888505060C0404000F8008E +:20FD800000030101010202020306040408081000000000000000000080404040487000002E +:20FDA000000000000000000000000000000000000000000000000000000000000000000043 +:20FDC000000000000000000000000000000000000000000000000000000000000000000023 +:20FDE000000000000000000000000000000000000000000000000000000000000000000003 +:20FE00000000000000000000000000000000000000000000000000000000000000000000E2 +:20FE20000000000000000000000000000000000000000000000000000000000000000000C2 +:20FE40000000000000000000000000000000000000000000000000000000000000000000A2 +:20FE6000000000000000000000000000000000000000000000000000000000000000000082 +:20FE8000000000000000000000000000000000000000000000000000000000000000000062 +:20FEA000000000000000000000000000000000000000000000000000000000000000000042 +:20FEC000000000000000000000000000000000000000000000000000000000000000000022 +:20FEE000000000000000000000000000000000000000000000000000000000000000000002 +:20FF0000000000001F000201010101020204080000000000F01060800000000000000000CC +:20FF200000003F000000020101010102020408000000F8081020C00000000000000000007C +:20FF400000000000000001030509110101010100000000404080000000000000000000007A +:20FF60000000000000010305091121010101010100404080800000000000000000000000B8 +:20FF800000000101111F10101000000000030C000000000010F81010202040408000000088 +:20FFA000000101213F2020200000000000030C0000000008FC08081010202040800000003C +:20FFC000000000001F01010101013F000000000000000020F00000000010F80000000000A6 +:20FFE000000000003F0101010101017F0000000000000010F8000000000008FC0000000031 +:020000040104F5 +:2000000000000101013F030509112101050200000000000010F8000000000000000000004B +:2000200000000000007F000102040810204201000080808088FC80808080808080800000BB +:2000400000020202023F020204040808102140000000000020F020202020202040408000FC +:2000600000020202023F020204040808102140000804120824F020202020202040408000B2 +:2000800000101008043F0202013F00000000000000000000E00000007080804040201000B1 +:2000A00000101008043F0202013F00000000000008041208E4000000708080404020100067 +:2000C000000202020304040810200001020C300000000010F8102020404080000000000040 +:2000E0000004040407080810204001020418600008041208E4204040808000000000000044 +:20010000000808080F102040000101020408300000000010F8404080800000000000000080 +:20012000000808080F102040000101020408300008041208F440408080000000000000004E +:20014000000000001F00000000001F000000000000000010F81010102020F00000000000F9 +:2001600000000000003F000000003F00000000000804120824F020202040E0000000000047 +:200180000000040404047F040404040400010200004040404048FC40404040808000000075 +:2001A000000000040404047F040404040400010208045248444048FC40404040808000002B +:2001C00000001804023008040000010224180000000000000008102040800000000000008E +:2001E000000000180402300804000001022418000804120804000810204080000000000044 +:200200000000003F000000000102040810200000000000E020404080008040201808000060 +:20022000000000003F000000000102040810200008041208E4204040800080402018080016 +:200240000004040404077C0404040404040300000000000000E020408000000020F0000020 +:200260000004040404077C0404040404040300000804120804E020408000000020F00000D6 +:20028000000000001008040602000001020C3000000020101010202040408000000000006B +:2002A00000000000002010080C04000102041860080412482420204040808000000000002D +:2002C00000040407040808102402010204186000000020F0202040408080008040000000B6 +:2002E0000008080F08101020490502050830C000080452E844408080000000000000000080 +:200300000000011F01017F0101020204040810000020F0000008FC00000000000000000002 +:20032000000000033E0202FF0202040408081020080452E8040010F80000000000000000DB +:20034000000000000403211808000000010618000000000000101010202040800000000006 +:200360000000040221110808000001020408300000000010101020204080000000000000C6 +:200380000000080442221010000102040810600008041228242040408000000000000000C4 +:2003A00000001F0000007F0101020204040810200020F0000008FC00000000000000000045 +:2003C0000000003F000000FF0202040408081020080452E8040010F8000000000000000041 +:2003E0000004040404060504040404040404040000000000000000C0602000000000000082 +:200400000004040404060504040404040404040008041208040000C0602000000000000037 +:2004200000010101017F010101010202040408000000000008FC000000000000000000001D +:2004400000000000001F000000007F00000000000000000020F000000008FC0000000000EA +:2004600000001F00000C020100000102040830000010F8102020404080C0301000000000B7 +:20048000020100001F000103050911210101010000808000C0800000403010000000000033 +:2004A00000000000000000000001010204081000000020202040408080000000000000003C +:2004C000000000000402020404081020400000000000000040201008080404040000000008 +:2004E0000000000004020204040810204000000008041208442010080804040400000000BE +:2005000000000000040202040408102040000000000C12124C20100808040404000000008B +:20052000000008080808090E0808080807000000000000004060800000000020F00000002D +:20054000000000202021212638202020201F000008041208040080000000000080C0000032 +:20056000000000202021212638202020201F0000000C12120C0080000000000080C0000000 +:200580000000007F000000000001020408102000000020F0204040808000000000000000ED +:2005A000000000007F000000010102040810200008041248E44080800000000000000000F2 +:2005C000000000007F0000000101020408102000000C1252EC4080800000000000000000C0 +:2005E000000000000018244300000000000000000000000000000000C0300E00000000007E +:20060000000000000018244300000000000000000804120804000000C0300E000000000033 +:2006200000000000001824430000000000000000000C12120C000000C0300E000000000001 +:2006400000010101017F010109091121010502000000000008FC0000201008080000000085 +:200660000001010101017F010111112141050200080412080400FC00002010080800000003 +:200680000001010101017F0101111121410502000C12120C0008FC000020100808000000C9 +:2006A000000000003F000000060100000000000000000010F81020204080804040000000DC +:2006C00000000E0100001C0300001C0300000000000000806020008080000000E0200000CD +:2006E000000000010101020204040808103F1000000000000000000000402010F808080004 +:20070000000000000004020100010204081060000000402020204040806020000000000033 +:200720000000033E0202037E02020202020100000040E0000008FC000000000010F80000BC +:2007400000000000100808241F0201010000000000000000000000788810200080804000C2 +:200760000010100808443F0202010100000000000000000000788810200000808040200030 +:200780000000000000000F00000000003F000000000000000020F02020204048FC00000017 +:2007A0000000001F0000000000007F0000000000000010F8101010202024FE000000000001 +:2007C0000000000000001F00001F00001F000000000000000010F81010F01010F010000084 +:2007E00000003F0000003F0000003F00000000000010F8101010F0101010F01000000000E4 +:2008000000000F00003F000000000000010618000040E00010F81010202040800000000023 +:200820000000040404040404040400000101020C0040404040404040404080800000000048 +:20084000000000000404040404080810204000000000000080808080848890A0C080000088 +:200860000000002010101010101112141810000000000000001020408000000000000000B9 +:200880000000101F1010101010101F1000000000000020F0202020204040E00000000000AA +:2008A0000000101F101000000000010204000000000020F020202040408000000000000072 +:2008C0000000203F202000000000000001020400000010F8101010202040408000000000FA +:2008E000000101011F090909097F01010101010000000040E000000008FC0000000000000A +:200900000000001F0002010101017F0000000000000000E0408000000008FC00000000008F +:200920000000001F00003F000000000000010600000010F81010FC102020404080000000DE +:2009400000001008060200000001022418000000000000040810204080000000000000003C +:20096000000202223F202000000001010204080008041248E44040408080000000000000B8 +:2009800000000101010F010202020405080000000000000020F0202020204040800000009D +:2009A000000004040407081001010204080000000000000040E080800000000000000000DC +:2009C000000000000000000000000000000000000000000000000000000000000000000017 +:2009E0000000000000000000000000000000000000000000000000000000000000000000F7 +:200A00000000000000000000000000000000000000000000000000000000000000000000D6 +:200A20000000000000000000000000000000000000000000000000000000000000000000B6 +:200A4000000000000000000000000000000000000000000000000000000000000000000096 +:200A6000000000000000000000000000000000000000000000000000000000000000000076 +:200A8000000000000000000000000000000000000000000000000000000000000000000056 +:200AA000000000000000000000000000000000000000000000000000000000000000000036 +:200AC000000102020404080F101020700000000000008080404020E01010081C000000007E +:200AE000001F080808080F080808081F0000000000E010101020C020101010E00000000049 +:200B0000003F101010101010101010380000000000F01010000000000000000000000000BE +:200B200000010202040408081010207F000000000000808040402020101008FC00000000F5 +:200B4000003F101010101F101010103F0000000000F0101000808080001010F000000000D8 +:200B6000001F0000000001020204081F0000000000F0204080800000000000F000000000E6 +:200B80000038101010101F101010103800000000007020202020E020202020700000000086 +:200BA00000030C101024272410100C0300000000008060101048C848101060800000000010 +:200BC000000301010101010101010103000000000080000000000000000000800000000006 +:200BE000001C0808090A0E090808081C000000000070408000000000804020380000000023 +:200C00000001020204040808101020700000000000008080404020201010081C0000000003 +:200C2000003018141412121111101038000000000018305050909010101010380000000026 +:200C4000003018141412111110101038000000000070202020202020A0A060200000000098 +:200C6000003F202000080F080020203F0000000000F010100040C040001010F000000000F7 +:200C800000030C101020202010100C0300000000008060101008080810106080000000007E +:200CA000003F101010101010101010380000000000F02020202020202020207000000000AD +:200CC000003F101010101F10101010380000000000C020101020C00000000000000000001E +:200CE000003F1008040201020408103F0000000000F0101000000000001010F00000000019 +:200D0000003F212101010101010101030000000000F80808000000000000008000000000C0 +:200D2000000006090101010101010103000000000040A0000000000000000080000000003A +:200D40000003010F11212121110F010300000000008000E01008080810E0008000000000F0 +:200D600000380804040201020404083800000000003820404080008040402038000000002E +:200D8000004321111111110F010101030000000000840810101010E000000080000000006A +:200DA00000070810202020201008243C000000000080402010101010204090F0000000001C +:200DC000000000000000000000000000000000000000000000000000000000000000000013 +:200DE0000000000000000000000000000000000000000000000000000000000000000000F3 +:200E00000000000000000000000000000000000000000000000000000000000000000000D2 +:200E20000000000000000000000000000000000000000000000000000000000000000000B2 +:200E4000000000000000000000000000000000000000000000000000000000000000000092 +:200E6000000000000000000000000000000000000000000000000000000000000000000072 +:200E8000000000000000000000000000000000000000000000000000000000000000000052 +:200EA000000000000000000000000000000000000000000000000000000000000000000032 +:200EC0000000000708101010101008070000000000000060C04040404040C0300000000054 +:200EE00000070808080F080808080C0B08080800008040408000C020202040800000000015 +:200F00000000000C1222010101010101010101000000001020204040800000000000000038 +:200F20000003040201020408080804030000000000804000008040202020408000000000E2 +:200F4000000000030404020102040403000000000000008040000080000040800000000076 +:200F60000002040403020408080804030000030000000040C0000000000000C02020C0007C +:200F80000000000D161404040404040400000000000000C0202020202020202020202000E2 +:200FA0000003040808080F080808040300000000008040202020E0202020408000000000C4 +:200FC000000000030101010101010101000000000000000000000000000040800000000046 +:200FE0000000001808080D0A0908081C00000000000000304080000000804070000000005D +:2010000000040A0101010102020404080000000000000000000000808040502000000000FA +:20102000000000080808080808080C0B0808080000000040404040404040D0200000000099 +:20104000000000180808080404020201000000000000002010202040408080000000000063 +:20106000000408070808070408080807000403000000008000008000000000C02020C0005C +:201080000000000708101010101008070000000000000080402020202020408000000000C2 +:2010A0000000001F240404040404081000000000000000F8404040404040502000000000D9 +:2010C000000000070810101010181413101010000000008040202020202040800000000032 +:2010E00000000007081010101010080700000000000000F8402020202020408000000000EA +:2011000000000007090101010101010000000000000000C000000000000040800000000039 +:20112000000000081404040404040403000000000000004020202020202020C00000000098 +:2011400000010107091111111111090701010100000000C020101010101020C00000000005 +:20116000000000081404020201010204080810000000001020204080000080804050200063 +:20118000000101112909090909090907010101000000004020202020202020C000000000F3 +:2011A000000000040810111111110A040000000000000040201010101010A0400000000031 +:2011C00000000000000000000000000000000000000000303010200000000000000000007F +:2011E0000000000000000000000000000000000000000030484830000000000000000000FF +:2012000000000000000000000000000000000000000040203010000000000000000000002E +:201220000000000000000000000000000000000000000000303000000030300000000000EE +:2012400000000000000000000000000000000000000000303000303010200000000000009E +:201260000000000000000000000000000000000000000030303030303030000030300000BE +:2012800000000000010101000000000000000000000070880C8C8C183030303000303000F7 +:2012A00000000000000000000007182040000000000000000000000000C0300804000000B3 +:2012C00000000040201807000000000000000000000000040830C000000000000000000093 +:2012E000000000000000000000001F204000000000000000000000000000F0080400000073 +:2013000000000040201F000000000000000000000000000408F00000000000000000000052 +:20132000000000000000000000000106186000000000000000000000000000C0300C000032 +:201340000000601806010000000000000000000000000C30C0000000000000000000000012 +:20136000000000000000000106186106186000000000000000000000C0300CC0300C000077 +:201380000000601806611806010000000000000000000C30C00C30C0000000000000000057 +:2013A000000000000000000000007F000000000000000000000000000000FC0404040000A6 +:2013C00000004040407F000000000000000000000000000000FC00000000000000000000D2 +:2013E0000000000000000000007F407F00000000000000000000000000FC04F4141C00008B +:20140000000070505F407F00000000000000000000000000FC04FC000000000000000000F2 +:2014200000000000000000007F404758604000000000000000000000FC04C4340C040000A6 +:20144000000040605847407F00000000000000000000040C34C404FC000000000000000086 +:2014600000000000000000007F7F7F78604000000000000000000000FCFCFC3C0C04000097 +:2014800000004060787F7F7F00000000000000000000040C3CFCFCFC000000000000000077 +:2014A00000000000000000000001023C4000000000000000000000000000807804000000B1 +:2014C000000000403C02010000000000000000000000000478800000000000000000000091 +:2014E0000101010101010101010101010101010100000000000000000000000000000000DC +:201500000001010100000101010000010101000000000000000000000000000000000000C2 +:2015200000010101010101010101010101010100000000000000000000000000000000009D +:20154000010202010102020101020201010202010000000000000000000000000000000073 +:2015600000000000000000000000000000000000000000000000000000000000000000006B +:2015800000000000000000000000000000000000000000000000000000000000000000004B +:2015A00000000000000000000000000000000000000000000000000000000000000000002B +:2015C00000000000000000000000000000000000000000000000000000000000000000000B +:2015E0000000000000000000000000000000000000000000000000000000000000000000EB +:201600000000000000000000000000000000000000000000000000000000000000000000CA +:201620000000000000000000000000000000000000000000000000000000000000000000AA +:2016400000000000000000000000000000000000000000000000000000000000000000008A +:2016600000000000000000000000000000000000000000000000000000000000000000006A +:20168000000102020404080F101020700000000000008080404020E01010081C00000000B2 +:2016A000001F080808080F080808081F0000000000F010100000C020101010E0000000009D +:2016C000001F080808080F080808081F0000000000E010101020C020101010E0000000005D +:2016E000003F101010101010101010380000000000F01010000000000000000000000000D3 +:20170000000F0202020202040408101F2020000000F0202020202020202020F00808000021 +:20172000003F101010101F101010103F0000000000F0101000808080001010F000000000EC +:2017400004003F1010101F101010103F000000004000F0100040C040000010F000000000F8 +:201760000023510909050305091111630000000000881420204080402010108C00000000A0 +:20178000000B0C0800000100101008070000000000C020101020C020101020C000000000FA +:2017A00000381010101111121414183000000000003060A0A020202020202070000000001D +:2017C00004047320202021222428306000000000404098305090101010101038000000005F +:2017E0000038101111121E11101010380000000000609000000000008040403000000000B6 +:20180000001F080808080808080828100000000000F02020202020202020207000000000B1 +:2018200000301814141212111110103800000000001830505090901010101038000000001A +:201840000038101010101F101010103800000000007020202020E0202020207000000000B9 +:2018600000070810202020202010080700000000008040201010101010204080000000007A +:20188000003F101010101010101010380000000000F02020202020202020207000000000C1 +:2018A000003F101010101F10101010380000000000C020101020C000000000000000000032 +:2018C0000007081010101010101008070000000000D0301000000000081020C00000000072 +:2018E000003F212101010101010101030000000000F80808000000000000008000000000D5 +:20190000001C08080404020201022418000000000070202040408080000000000000000020 +:201920000003010F11212121110F010300000000008000E01008080810E000800000000004 +:20194000003808040402010204040838000000000038204040800080404020380000000042 +:2019600000381010101010101010103F000000000070202020202020202020F008080000D0 +:201980000038101010100807000000000000000000702020202060A0202020700000000000 +:2019A000003B1111111111111111113F0000000000B8101010101010101010F800000000D4 +:2019C000003B1111111111111111113F0000000000B8101010101010101010F804040000AC +:2019E000003E2404040704040404040F000000000000000000E01008080810E0000000005B +:201A000000702020203C22212121227C000000000070202020202020202020700000000097 +:201A2000001C0808080F08080808081F000000000000000000C02010101020C0000000002C +:201A4000002F3020000007000020100F00000000008040201010F0101020408000000000D1 +:201A60000071222424243C24242422710000000000C0201010101010101020C000000000FC +:201A80000007081010080701020408300000000000F020202020E020202020700000000089 +:201AA000000000000000000000000000000000000000000000000000000000000000000026 +:201AC000000000000000000000000000000000000000000000000000000000000000000006 +:201AE0000000000000000000000000000000000000000000000000000000000000000000E6 +:201B00000000000000000000000000000000000000000000000000000000000000000000C5 +:201B20000000000000000000000000000000000000000000000000000000000000000000A5 +:201B4000000000000000000000000000000000000000000000000000000000000000000085 +:201B6000000000000000000000000000000000000000000000000000000000000000000065 +:201B8000000000000000000000000000000000000000000000000000000000000000000045 +:201BA000000000000000000000000000000000000000000000000000000000000000000025 +:201BC000000000000000000000000000000000000000000000000000000000000000000005 +:201BE0000000000000000000000000000000000000000000000000000000000000000000E5 +:201C00000000000000000000000000000000000000000000000000000000000000000000C4 +:201C20000000000000000000000000000000000000000000000000000000000000000000A4 +:201C4000000000000000000000000000000000000000000000000000000000000000000084 +:201C6000000000000000000000000000000000000000000000000000000000000000000064 +:201C80000000000708000F10101008070000000000000080404040C04040D0200000000077 +:201CA0000007081017181010101008070000000020C00000804020202020408000000000A7 +:201CC0000000001F0808080F0808081F000000000000008040404080404040800000000087 +:201CE0000000001F080808080808081C00000000000000E020000000000000000000000071 +:201D000000000007020202020404081F20200000000000F020202020202020F00808000075 +:201D2000000000070810101F101008070000000000000080402020E0000020C00000000066 +:201D4000000400070810101F101008070000000000800080402020E0000020C000000000C2 +:201D60000000003309090507090911230000000000000098202040C020201088000000001C +:201D80000000000B0C0800010000080700000000000000C0202020C0202020C00000000014 +:201DA00000000038101010111214183000000000000000702060A0202020207000000000BC +:201DC00000040338101010111214183000000000008000702060A020202020700000000015 +:201DE0000000001C0808090E0A09081C000000000000006080800000000080600000000029 +:201E00000000000F0202020202020A0400000000000000F020202020202020700000000059 +:201E2000000000381018141212111038000000000000003810305090901010380000000071 +:201E40000000001C0808080F0808081C0000000000000070202020E020202070000000008B +:201E600000000003040808080808040300000000000000804020202020204080000000000C +:201E80000000001F080808080808081C00000000000000F02020202020202070000000008F +:201EA0000000000B1C080808080C0B0808081C000000008040202020204080000000000090 +:201EC0000000000708101010101008070000000000000080404000000020408000000000B4 +:201EE0000000001F110101010101010300000000000000F010000000000000800000000029 +:201F00000000001C080804040202010224180000000000702020404080800000000000001A +:201F2000000101010D1311111111130D010103000000000060901010101090600000800075 +:201F40000000001C080402010204081C00000000000000702040800080402070000000008C +:201F60000000001C080808080808081F000000000000007020202020202020F0080800009E +:201F80000000001C080808070000000000000000000000E0404040C0404040E00000000006 +:201FA0000000003B111111111111113F00000000000000B810101010101010F80000000010 +:201FC0000000003B111111111111113F00000000000000B810101010101010F804040000E8 +:201FE0000000007C4808080F0808081F0000000000000000000000C0202020C000000000E7 +:20200000000000381010101E1111113E000000000000007020202020202020700000000009 +:202020000000001C0808080F0808081F0000000000000000000000C0202020C00000000046 +:202040000000000708000003000008070000000000000080402020E020204080000000007F +:20206000000000381112121E1212113800000000000000C020101010101020C00000000058 +:20208000000000030404040301020A0400000000000000F0202020E020202070000000001D +:2020A000000000000000000000000000000000000000000000000000000000000000000020 +:2020C000000000000000000000000000000000000000000000000000000000000000000000 +:2020E0000000000000000000000000000000000000000000000000000000000000000000E0 +:202100000000000000000000000000000000000000000000000000000000000000000000BF +:2021200000000000000000000000000000000000000000000000000000000000000000009F +:2021400000000000000000000000000000000000000000000000000000000000000000007F +:2021600000000000000000000000000000000000000000000000000000000000000000005F +:2021800000000000000000000000000000000000000000000000000000000000000000003F +:2021A00000000000000000000000000000000000000000000000000000000000000000001F +:2021C0000000000000000000000000000000000000000000000000000000000000000000FF +:2021E0000000000000000000000000000000000000000000000000000000000000000000DF +:202200000000000000000000000000000000000000000000000000000000000000000000BE +:2022200000000000000000000000000000000000000000000000000000000000000000009E +:202240000000FC0000748C8484848C760000000000000000000000000000000000000000F4 +:202260000810200000748C8484848C76000000000000000000000000000000000000000098 +:202280004428100000748C8484848C76000000000000000000000000000000000000000034 +:2022A0004020100000748C8484848C76000000000000000000000000000000000000000020 +:2022C0000000FC0000384482FE80423C000000000000000000000000000000000000000008 +:2022E0000810200000384482FE80423C0000000000000000000000000000000000000000AC +:202300004428100000384482FE80423C000000000000000000000000000000000000000047 +:202320004020100000384482FE80423C000000000000000000000000000000000000000033 +:202340000000380000101010101010100000000000000000000000000000000000000000D5 +:202360000810200000101010101010100000000000000000000000000000000000000000B5 +:20238000442810000010101010101010000000000000000000000000000000000000000051 +:2023A000201008000010101010101010000000000000000000000000000000000000000075 +:2023C0000000FC000038448282824438000000000000000000000000000000000000000083 +:2023E000081020000038448282824438000000000000000000000000000000000000000027 +:202400004428100000384482828244380000000000000000000000000000000000000000C2 +:202420002010080000384482828244380000000000000000000000000000000000000000E6 +:202440000000FC000084848484848C760000000000000000000000000000000000000000EA +:20246000081020000084848484848C7600000000000000000000000000000000000000008E +:20248000442810000084848484848C7600000000000000000000000000000000000000002A +:2024A000201008000084848484848C7600000000000000000000000000000000000000004E +:2024C0000000FC004800848484848C760000000000000000000000000000000000000000A6 +:2024E000102040004800848484848C76000000000000000000000000000000000000000012 +:20250000885020004800848484848C76000000000000000000000000000000000000000069 +:20252000402010004800848484848C760000000000000000000000000000000000000000D1 +:20254000000000004800848484848C76000000000000000000000000000000000000000021 +:202560001028440000384482FE80423C0000000000000000000000000000000000000000E5 +:202580000000000000748C8484848C760000000000000000000000000000000000000000AD +:2025A0000810200000ACD2929292929200000000000000000000000000000000000000008B +:2025C0000810200000B8C484848484840000000000000000000000000000000000000000B3 +:2025E0004428100000B8C4848484848400000000000000000000000000000000000000004F +:20260000000000101008007C4242424242E7000000000000000000000000000000000000E5 +:2026200000000000003A44443840407C82827C000000000000000000000000000000000024 +:2026400000000000000000000000000000000000000000000000000000000000000000007A +:2026600000000000000000000000000000000000000000000000000000000000000000005A +:2026800000000000000000000000000000000000000000000000000000000000000000003A +:2026A00000000000000000000000000000000000000000000000000000000000000000001A +:2026C000000808103F000000000000000001000000000000F8080808080808081010A0406A +:2026E000000404081F00000001000000030C300000000000F808081010A040A010100000A3 +:20270000000000003F202020202020200000000000000000F808080808080808000000006A +:2027200000003F101010101010101010100F00000000F800000000000000000000FC0000B7 +:20274000000404081F010101010202040811200000000000F8080808080808081010A040D5 +:2027600000010101017F0101020204081F0000000000000000FC000000000020F008000091 +:2027800000003F000001030000000000000100000000C0408000F808080808081010A04055 +:2027A0000001090911113F010102020404081020000000000000F8080808080808105020B7 +:2027C000000002020404080811080804040202000000202040408080008080404020200030 +:2027E00000007F040404080F00000000000000000000FC00000000F0101010101020A040FB +:2028000000003F101010101010101020204080000000FC00000000000000000000000000FD +:20282000000004040404040408090E0000000000002020202020202060A0202020202020C1 +:2028400000000000010102040201010000000000008080800000000000000080804040006C +:2028600000007F010101010101010101010101000000FC00000000000000000000000000D1 +:202880000001011111111111111F0101017F0000000000101010101010F0000000FC0000E3 +:2028A000000000010204081103050911010101010040800000408000000000000000000052 +:2028C00000001F0000001F1010101010202040800000F8080808F800000000000000000062 +:2028E00000000F0808080A0908080808080F00000000E02020202020A020202020E00000E7 +:2029000000003F040404040404050404040404040000F010101010101020C0000000000013 +:20292000000202027F0404040F0000000000000100000000FC000000F010102020408000EA +:202940000001010101020202040408103F000000000000000000000000004020F0100000AE +:20296000001008040200010101010101010101010008102040800000000000000000000037 +:2029800000007F0101010F1020202020100F00000000FC00000000000000000810E0000003 +:2029A000000101017F01010F1020202020100F0000000000FC000000000000000810E000E1 +:2029C00000000808087F080808080809080700000000404040FC40404080800000F00000B4 +:2029E00000007F0909111F0101010202040810000000FC000000F808080808081010200097 +:202A000000001C04040402020201010000000000000000000000000000000080402018008E +:202A2000000202040408081F010204081F000000000000202040408000004020F01000008D +:202A40000000001F000004020100000102040800000000F010202040408080402000000021 +:202A6000003F08080808101F000000000000000000E02020404040F8080808101020400058 +:202A800000080808080808101F000000000000000000000000000000F80808081010200087 +:202AA00000020202027F020202040404081060000000000000FC80808080808080807C008D +:202AC0000000010101020204040810203F000000000000000000000000000000F800000078 +:202AE0000000040404040404040404080810600000008080808080808080808084847C00AE +:202B00000001010101010101010101010101010100000000000000000000000000000000A6 +:202B20000000000008040201000001020418600000101010202040408080402010000000A7 +:202B400000000000101010101010203F0000000000000008080808080808F8080800000076 +:202B6000000000000000000000000000000000000000000000000000000000000000000055 +:202B8000000000000000000000000000000000000000000000000000000000000000000035 +:202BA000000000000000000000000000000000000000000000000000000000000000000015 +:202BC0000000000000000000000000000000000000000000000000000000000000000000F5 +:202BE0000000000000000000000000000000000000000000000000000000000000000000D5 +:202C00000000000000000000000000000000000000000000000000000000000000000000B4 +:202C2000000000000000000000000000000000000000000000000000000000000000000094 +:202C4000000000000000000000000000000000000000000000000000000000000000000074 +:202C6000000000000000000000000000000000000000000000000000000000000000000054 +:202C8000000000000000000000000000000000000000000000000000000000000000000034 +:202CA000000000000000000000000000000000000000000000000000000000000000000014 +:202CC0000000000000000000000000000000000000000000000000000000000000000000F4 +:202CE0000000000000000000000000000000000000000000000000000000000000000000D4 +:202D00000000000000000000000000000000000000000000000000000000000000000000B3 +:202D2000000000000000000000000000000000000000000000000000000000000000000093 +:202D4000000000000000000000000000000000000000000000000000000000000000000073 +:202D6000000000000000000000000000000000000000000000000000000000000000000053 +:202D8000000000000000000000000000000000000000000000000000000000000000000033 +:202DA000000000000000000000000000000000000000000000000000000000000000000013 +:202DC0000000000000000000000000000000000000000000000000000000000000000000F3 +:202DE0000000000000000000000000000000000000000000000000000000000000000000D3 +:202E00000000000000000000000000000000000000000000000000000000000000000000B2 +:202E2000000000000000000000000000000000000000000000000000000000000000000092 +:202E4000000000000000000000000000000000000000000000000000000000000000000072 +:202E600000000000000000FF000000000000000000000000000000FE000000000000000055 +:202E800000000000000000FFFF0000000000000000000000000000FEFE0000000000000038 +:202EA000010101010101010101010101010101010000000000000000000000000000000002 +:202EC0000101010101010101010101010101010180808080808080808080808080808080E2 +:202EE000000000000000003B000000000000000000000000000000B80000000000000000DF +:202F0000000000000000003B3B0000000000000000000000000000B8B800000000000000CB +:202F2000000001010100010101000101010000000000000000000000000000000000000088 +:202F40000000010101000101010001010100000000008080800080808000808080000000E8 +:202F600000000000000000EE000000000000000000000000000000EE000000000000000075 +:202F800000000000000000EEEE0000000000000000000000000000EEEE0000000000000079 +:202FA000010101000101010001010100010101000000000000000000000000000000000005 +:202FC0000101010001010100010101000101010080808000808080008080800080808000E5 +:202FE0000000000000000001010101010101010100000000000000FE0000000000000000CA +:203000000000000000000001010101010101010100000000000000FEFE00000000000000AB +:203020000000000000000001010101010101010100000000000000FE808080808080808089 +:203040000000000000000001010101010101010100000000000000FEFE80808080808080EB +:2030600000000000000000FF01010101010101010000000000000000000000000000000049 +:2030800000000000000000FFFF01010101010101000000000000000000000000000000002B +:2030A00000000000000000FF01010101010101010000000000000080808080808080808089 +:2030C00000000000000000FFFF01010101010101000000000000008080808080808080806B +:2030E0000101010101010101000000000000000000000000000000FE0000000000000000CA +:203100000101010101010101010000000000000000000000000000FEFE00000000000000AA +:203120000101010101010101000000000000000080808080808080FE000000000000000009 +:203140000101010101010101010000000000000080808080808080FEFE00000000000000EA +:2031600001010101010101FF00000000000000000000000000000000000000000000000049 +:2031800001010101010101FFFF00000000000000000000000000000000000000000000002A +:2031A00001010101010101FF00000000000000008080808080808080000000000000000009 +:2031C00001010101010101FFFF00000000000000808080808080808080000000000000006A +:2031E0000101010101010101010101010101010100000000000000FE0000000000000000C1 +:203200000101010101010101010101010101010100000000000000FEFE00000000000000A2 +:203220000101010101010101010101010101010180808080808080FE000000000000000000 +:203240000101010101010101010101010101010100000000000000FE808080808080808060 +:203260000101010101010101010101010101010180808080808080FE8080808080808080C0 +:203280000101010101010101010101010101010180808080808080FEFE00000000000000A2 +:2032A0000101010101010101010101010101010100000000000000FEFE8080808080808082 +:2032C0000101010101010101010101010101010180808080808080FEFE80808080808080E2 +:2032E00001010101010101FF010101010101010100000000000000000000000000000000C0 +:2033000001010101010101FFFF0101010101010100000000000000000000000000000000A1 +:2033200001010101010101FF0101010101010101808080808080808000000000000000007F +:2033400001010101010101FF010101010101010100000000000000808080808080808080DF +:2033600001010101010101FF0101010101010101808080808080808080808080808080803F +:2033800001010101010101FFFF010101010101018080808080808080000000000000000021 +:2033A00001010101010101FFFF010101010101010000000000000080808080808080808081 +:2033C00001010101010101FFFF0101010101010180808080808080808080808080808080E1 +:2033E00000000000000000FF010101010101010100000000000000FE0000000000000000C8 +:2034000000000000000000FFFF0101010101010100000000000000FE0000000000000000A9 +:2034200000000000000000FF010101010101010100000000000000FEFE0000000000000089 +:2034400000000000000000FFFF0101010101010100000000000000FEFE000000000000006B +:2034600000000000000000FF010101010101010100000000000000FE808080808080808047 +:2034800000000000000000FFFF0101010101010100000000000000FE808080808080808029 +:2034A00000000000000000FF010101010101010100000000000000FEFE8080808080808089 +:2034C00000000000000000FFFF0101010101010100000000000000FEFE808080808080806B +:2034E00001010101010101FF000000000000000000000000000000FE0000000000000000C8 +:2035000001010101010101FFFF0000000000000000000000000000FE0000000000000000A8 +:2035200001010101010101FF010000000000000000000000000000FEFE0000000000000088 +:2035400001010101010101FFFF0000000000000000000000000000FEFE000000000000006A +:2035600001010101010101FF000000000000000080808080808080FE0000000000000000C7 +:2035800001010101010101FFFF0000000000000080808080808080FE800000000000000028 +:2035A00001010101010101FF010000000000000080808080808080FEFE0000000000000088 +:2035C00001010101010101FFFF0000000000000080808080808080FEFE000000000000006A +:2035E00001010101010101FF010101010101010100000000000000FE0000000000000000BF +:2036000001010101010101FFFF0101010101010100000000000000FE0000000000000000A0 +:2036200001010101010101FF010101010101010100000000000000FEFE0000000000000080 +:2036400001010101010101FFFF0101010101010100000000000000FEFE0000000000000062 +:2036600001010101010101FF010101010101010180808080808080FE0000000000000000BE +:2036800001010101010101FF010101010101010100000000000000FE80808080808080801E +:2036A00001010101010101FF010101010101010180808080808080FE80808080808080807E +:2036C00001010101010101FFFF0101010101010180808080808080FE000000000000000060 +:2036E00001010101010101FF010101010101010180808080808080FEFE0000000000000040 +:2037000001010101010101FFFF0101010101010100000000000000FE80808080808080809F +:2037200001010101010101FF010101010101010100000000000000FEFE80808080808080FF +:2037400001010101010101FFFF0101010101010180808080808080FEFE00000000000000E1 +:2037600001010101010101FFFF0101010101010100000000000000FEFE80808080808080C1 +:2037800001010101010101FFFF0101010101010180808080808080FE80808080808080809F +:2037A00001010101010101FF010101010101010180808080808080FEFE80808080808080FF +:2037C00001010101010101FFFF0101010101010180808080808080FEFE80808080808080E1 +:2037E0000000000000000000000000000000000000000000000000000000000000000000C9 +:203800000000000000000000000000000000000000000000000000000000000000000000A8 +:20382000000000000000000000000000000000000000000000000000000000000000000088 +:20384000000000000000000000000000000000000000000000000000000000000000000068 +:20386000000000000000000000000000000000000000000000000000000000000000000048 +:20388000000000000000000000000000000000000000000000000000000000000000000028 +:2038A000000000000000000000000000000000000000000000000000000000000000000008 +:2038C0000000000000000000000000000000000000000000000000000000000000000000E8 +:2038E0000000000000000000000000000000000000000000000000000000000000000000C8 +:203900000000000000000000000000000000000000000000000000000000000000000000A7 +:20392000000000000000000000000000000000000000000000000000000000000000000087 +:20394000000000000000000000000000000000000000000000000000000000000000000067 +:20396000000000000000000000000000000000000000000000000000000000000000000047 +:20398000000000000000000000000000000000000000000000000000000000000000000027 +:2039A000000000000000000000000000000000000000000000000000000000000000000007 +:2039C0000000000000000000000000000000000000000000000000000000000000000000E7 +:2039E0000000000000000000000000000000000000000000000000000000000000000000C7 +:203A00000000000000000000000000000000000000000000000000000000000000000000A6 +:203A2000000000000000000000000000000000000000000000000000000000000000000086 +:203A4000000000000000000000000000000000000000000000000000000000000000000066 +:203A6000000000000000000000000000000000000000000000000000000000000000000046 +:203A8000000000000000000000000000000000000000000000000000000000000000000026 +:203AA000000000000000000000000000000000000000000000000000000000000000000006 +:203AC0000000000000000000000000000000000000000000000000000000000000000000E6 +:203AE0000000000000000000000000000000000000000000000000000000000000000000C6 +:203B00000000000000000000000000000000000000000000000000000000000000000000A5 +:203B2000000000000000000000000000000000000000000000000000000000000000000085 +:203B4000000000000000000000000000000000000000000000000000000000000000000065 +:203B6000000000000000000000000000000000000000000000000000000000000000000045 +:203B8000000000000000000000000000000000000000000000000000000000000000000025 +:203BA000000000000000000000000000000000000000000000000000000000000000000005 +:203BC0000000000000000000000000000000000000000000000000000000000000000000E5 +:203BE0000000000000000000000000000000000000000000000000000000000000000000C5 +:203C00000000000000000000000000000000000000000000000000000000000000000000A4 +:203C2000000000000000000000000000000000000000000000000000000000000000000084 +:203C4000000000000000000000000000000000000000000000000000000000000000000064 +:203C6000000000000000000000000000000000000000000000000000000000000000000044 +:203C8000000000000000000000000000000000000000000000000000000000000000000024 +:203CA000000000000000000000000000000000000000000000000000000000000000000004 +:203CC0000000000000000000000000000000000000000000000000000000000000000000E4 +:203CE0000000000000000000000000000000000000000000000000000000000000000000C4 +:203D00000000000000000000000000000000000000000000000000000000000000000000A3 +:203D2000000000000000000000000000000000000000000000000000000000000000000083 +:203D4000000000000000000000000000000000000000000000000000000000000000000063 +:203D6000000000000000000000000000000000000000000000000000000000000000000043 +:203D8000000000000000000000000000000000000000000000000000000000000000000023 +:203DA000000000000000000000000000000000000000000000000000000000000000000003 +:203DC0000000000000000000000000000000000000000000000000000000000000000000E3 +:203DE0000000000000000000000000000000000000000000000000000000000000000000C3 +:203E00000000000000000000000000000000000000000000000000000000000000000000A2 +:203E2000000000000000000000000000000000000000000000000000000000000000000082 +:203E4000000000000000000000000000000000000000000000000000000000000000000062 +:203E6000000000000000000000000000000000000000000000000000000000000000000042 +:203E8000000000000000000000000000000000000000000000000000000000000000000022 +:203EA000000000000000000000000000000000000000000000000000000000000000000002 +:203EC0000000000000000000000000000000000000000000000000000000000000000000E2 +:203EE0000000000000000000000000000000000000000000000000000000000000000000C2 +:203F00000000000000000000000000000000000000000000000000000000000000000000A1 +:203F2000000000000000000000000000000000000000000000000000000000000000000081 +:203F4000000000000000000000000000000000000000000000000000000000000000000061 +:203F6000000000000000000000000000000000000000000000000000000000000000000041 +:203F8000000000000000000000000000000000000000000000000000000000000000000021 +:203FA000000000000000000000000000000000000000000000000000000000000000000001 +:203FC0000000000000000000000000000000000000000000000000000000000000000000E1 +:203FE0000000000000000000000000000000000000000000000000000000000000000000C1 +:204000000000000000000000000000000000000000000000000000000000000000000000A0 +:20402000000000000000000000000000000000000000000000000000000000000000000080 +:20404000000000000000000000000000000000000000000000000000000000000000000060 +:20406000000000000000000000000000000000000000000000000000000000000000000040 +:20408000000000000000000000000000000000000000000000000000000000000000000020 +:2040A000000000000000000000000000000000000000000000000000000000000000000000 +:2040C0000000000000000000000000000000000000000000000000000000000000000000E0 +:2040E0000000000000000000000000000000000000000000000000000000000000000000C0 +:2041000000000000000000000000000000000000000000000000000000000000000000009F +:2041200000000000000000000000000000000000000000000000000000000000000000007F +:2041400000000000000000000000000000000000000000000000000000000000000000005F +:2041600000000000000000000000000000000000000000000000000000000000000000003F +:2041800000000000000000000000000000000000000000000000000000000000000000001F +:2041A0000000000000000000000000000000000000000000000000000000000000000000FF +:2041C0000000000000000000000000000000000000000000000000000000000000000000DF +:2041E0000000000000000000000000000000000000000000000000000000000000000000BF +:2042000000000000000000000000000000000000000000000000000000000000000000009E +:2042200000000000000000000000000000000000000000000000000000000000000000007E +:2042400000000000000000000000000000000000000000000000000000000000000000005E +:2042600000000000000000000000000000000000000000000000000000000000000000003E +:2042800000000000000000000000000000000000000000000000000000000000000000001E +:2042A0000000000000000000000000000000000000000000000000000000000000000000FE +:2042C0000000000000000000000000000000000000000000000000000000000000000000DE +:2042E0000000000000000000000000000000000000000000000000000000000000000000BE +:2043000000000000000000000000000000000000000000000000000000000000000000009D +:2043200000000000000000000000000000000000000000000000000000000000000000007D +:2043400000000000000000000000000000000000000000000000000000000000000000005D +:2043600000000000000000000000000000000000000000000000000000000000000000003D +:2043800000000000000000000000000000000000000000000000000000000000000000001D +:2043A0000000000000000000000000000000000000000000000000000000000000000000FD +:2043C0000010202439217F21213C24271C101000001090941C103252122C20FE202020000B +:2043E00000101121254B7911215B6305314101000000101010EC18D858343452501010009C +:20440000000004382120207F242020211860030000009096F81002FC08F048F05040FE0096 +:2044200000001110103C10181070501011123400000020A0A022FE224264948404041C002C +:204440000002053920233E2B6A2A2A2A1204040800001020FE5024F89090AC9898A42240CA +:2044600000007D1111111139111111163A4408000000FC04FC105054547C109292926E00BF +:2044800000007C111212133A111313173D450910004020FC0404F800FC5454FC54540C0481 +:2044A0000001212322223F22232222126302000000001EE46464FC64E43CA464E424440096 +:2044C000000004791111117D101011157A440000000C7080102020FE20A8A426222260002B +:2044E00000181110143B121E36325292121210100000FE0012FC5454DCD4545454545C0064 +:20450000000404043F083702121F12151419120000202026F808F0404CF848A888082810E6 +:204520000018112E430F013E0F0909090A040870006044B808F000F8F010101090700C0467 +:204540000000043B10101370131212123F420200009090FC9000FCA0FCA4D4AC24040C0011 +:204560000000000F08282908186F121212224300008040BC404CB02026D828080808F8009B +:204580000000003C444445447C4744447C00000000202026F820FC2020FC2424243C202069 +:2045A000000005381010103810101318600000000000FC0404FC04FC1016F890901030002D +:2045C0000000017D4545453D454545447C41020C00000CF82848484848506062A222120C33 +:2045E000001011112547791121217D01067A44080004022424242424242424242404000095 +:204600000001003F21222722252930284F4840BF000084FE1024F80008248084F888867836 +:2046200000004428112A4D081B2A2A4A0A0A3916004040B04C70A048B868484840B00C04DE +:204640000002023F04040F701F0C080F001F0000006024D898E0827CF01024DC28D87810D5 +:204660000010102438207C10107E1111151A12040004F880808082FC8888080808080800EB +:2046800000080A13121232521312121414141801000006F820247820FE2020FC202022DC6F +:2046A000000021213F04083E080E19292949080000800404FC2020FC307068A82420202069 +:2046C00000003C0404245840407E040404041900000086F884C4A8988898A4C4C080FE0027 +:2046E000000014147F14147F547F14142424448000003E24A4A8A82824E4A4A4BC2020009B +:204700000000463409196A081415264404083800004080FC88905020588E301000601000DA +:204720000000027C2828671A181929490909190000006060908804F80008F8080808F80078 +:2047400000001010141408515010101D17224400000004F8404042FC60A0A02024221E00D0 +:2047600000040C0908101033501017101010100000001CE040404CF04046F84044427E0094 +:204780000000101001001031101010141A1A000000202020FC2020FC0020A4C28288FC001B +:2047A0000010101428217E10107F10111418010000206060900C0C7040FC4044C8C0FE00D3 +:2047C0000000080B3C1A28490808093E1A284900001020263868A4202020223C68A4220097 +:2047E0000000473910284909191828C8090838000000FE444084F82020F82022FC20200091 +:2048000000004438112A4808191A29C9090938000000C884045050880608F8080808F80094 +:2048200000101111557D5454547C50141A6102040000FC040404F84044FC4484840418002F +:204840000000010E001F00031C0B080F080F08370030C008708438C000F010F010F012ECC1 +:2048600000001020263C409011101012141810000000808C90A0C080FCC0A09098AEC48065 +:20488000000001391311117D1110131439420C000048484AFC483800FC40FED0484640002F +:2048A00000001010000013301010111E1C1800000008FC404040FC60D0D0484C46404000F8 +:2048C000001010102C203D51167F101014181100002060609090080608F020202020FE0058 +:2048E000002010110000731010101314181001000010709C9490FE9494F49898A8C682000A +:204900000008131D116F476B5B535B6743427E0000101010101274981010101072921E00FA +:20492000000001795351514949497F41020204080000021E94145898141292121E1010009D +:2049400000001011010569290911113020202000000004FC2424FC2424FC24202020202097 +:2049600000101011117D111111111F6101030400000038C00000F8101010FE0088040400FE +:20498000001012223A424E32147C1312161A070000809092ACA0D8840000F8A8A8A8FE00B3 +:2049A0000000180801452A0D091010301010130C00009088040610181090A06060900E00DA +:2049C000000031205F427AA322792023291204000000FCA0FCA4A45C485062DC504C464077 +:2049E00000002110160B0B0A13123011103001060000FC3024FCFC24FC4444BC84842818AF +:204A00000004091E091E7F413F213F213F21230000000C0810208608102042040810608001 +:204A200000001F00014141414141414143403F000010F86080080808080808080808F8089D +:204A40000000223E2222222A2A2222234382000000007E444850504C424242CA44404000C6 +:204A6000000033100000701011101014181000000000FE2020202022FC2020202020E000EA +:204A80000000007E1010107E101010123C4000000004044444444444445C640404040400BC +:204AA000000808087F08097F49494949090808080000447C48506058444242424C40404064 +:204AC000000808087F08080B36221C0C162241000000467CC85050484642424246404000E7 +:204AE000000808101010315191121214141810000000404026E8D060505048444340C000C2 +:204B00000001003F20212F2121275941418180000000847810E000000CF000080808F800A8 +:204B200000001011004828101010102122222000000002FC8080FC848488880808381000B5 +:204B40000010101010145251501010101010101000000478202020FE2020202020206000A4 +:204B6000000010180101133010101014141801000000202004FE0800000000000002FC000F +:204B800000007C4B4A52524B4A464E7A4241000000087CA0202024F820202050920A060068 +:204BA00000000810107E1312242424281C122040000048444444F84040202020120A0600FA +:204BC0000000023C1010101C111010121C6000000000FE0810202020FC202020202060001A +:204BE000000011121212163A121212121A6201000000FE0004884830102844840002FC0059 +:204C00000000102020212E752121202119E10000004040A0900806801820C0000804FC00C5 +:204C200000100920202F2B28292A2A2D2C3320000000FE8494E4F4B4E4A414F414F40C0426 +:204C40000002043F040D090F1121013F01010100002044F8000000F8000004F80000000021 +:204C60000002043F1008093F0101020204083000002044F8808000FC040888484808703029 +:204C8000001010116C2028503C10147809090E00000004F8909090909090909212121E0027 +:204CA000000000497A4848494948784040010E00000080980600181010A0A040A01804002E +:204CC000000011212125A5A5A5A5A5AE76020500000002FC2020223C2424242444840C00F8 +:204CE0000018101F21257D252539212320201F00000022BE2424282824222222AE64A020B0 +:204D0000000013080004281908101070111214080000FC40404044F860A0A0A024221C00C2 +:204D20000000101003002F28081710702020200000404044F840F84044FC444444484040F2 +:204D4000000010080140240B081010301020100000202040F84044B880887810A0601000DF +:204D6000000011110141212911111130202126000000FC08284848484848406098060200E7 +:204D800000002010100011701710101418111600004090888870804CF048502060940C0004 +:204DA000000808292929291F0A294949493700000000007E44484850484444445C48400041 +:204DC00000101010172C2524244B48301C20408000204046F840FC4040FE4244444440008E +:204DE000000008121227381212123F12122242000000223E2428282824A424223C20202085 +:204E000000007C04272524487E0202FC04041F0000402022DC088888905060205088060001 +:204E20000000101021264A70102078000539020400404040FC48406060A0A0A020221E0021 +:204E400000007E04242424243E03067A0404090200404040FC4848484AF46050888C0600D0 +:204E6000000004391111153911111014384003000000FC04242424242424242058860200C8 +:204E80000001017D11111115391111121E64090200101010101010B070282828448402008F +:204EA00000001212121F12127F121121204000000000223EA4242828E42422A2BEA0202074 +:204EC0000004047F04001F1010100F0006083040002024F82010F0101010F040300C04006F +:204EE000001010117F2129513F1117790909090000001CE0202020FC101010102A468200E2 +:204F000000001010223C407D90127C101214180000404048484458E040202020101A0E0284 +:204F200000001110105454555555555C640000000000FC0414E404E4242424C404040C0858 +:204F4000000418181F28280916141414152220000000047C44484850484444C45C404000E8 +:204F60000008080813103052931414191112121400806040FE90909094969212101030006B +:204F800000080B0A1010315191101010111010100000FE404084F82020F82020FC202000A2 +:204FA0000008090B141432519010121212121310000024C890884424002044444444FC0087 +:204FC0000000040C1020401F080F080F0877000000404020180E08F020E020E024F820008B +:204FE00000007E42465A5A4A5B56664580800000002020FC20247826FA24243EA2621E0091 +:20500000000021110101017111111113151911000000FC0808F80808F8445820106886009F +:2050200000007F013F01013F01023F12020206000000265C4448504848C444444C4040000C +:2050400000003C4A4A51504944444549414141000020444444FC00FC0808F00000048678D7 +:2050600000003C4B495050484547457941424608008040FE10A060E01E1010101010101021 +:2050800000101011102C2424454A2C1814204300000004F84040C0D0484440404040FE007B +:2050A00000181010102E2424254A281814204000001020205C5050FC94949494941C1010A7 +:2050C00000101010102D2525454929191521400300202C2422FC2024242828529A2CC600AC +:2050E00000101011253F2424284848301C20408000402020FE040006F82020202020E040AF +:2051000000007C0B282828494834047C04043801000004F84040C05048444040404006F8F4 +:2051200000001C04252525253F03037B03050D0100202024FC2424FC2424FE0404041C00D3 +:2051400000001D05252525253F03037B03050D000000FE02024A7A4A4A4A7A0202020E0092 +:205160000010111226467A12222E72020E720200000002FC044C74545454744404040C0430 +:20518000000C093E091E7F080B027F040403033C0000003E242444880000FC2040E0180092 +:2051A000000004381011101C311111121C6810070000488886F88084FC48483020588E0052 +:2051C000000004381011111D311111111E620408002040467844BC0404FC00000000000032 +:2051E000000004381113101C3010131119620408000040800CF400909092FC10101010107A +:2052000000101111127F14181B715111111234280020404048F04044B820202222221E005A +:2052200000001011111638101311111D63000000008088F8503070AE30FC2024FE202020BD +:205240000004047F040828202724242720202000002044FE2004F808C848488808081808E7 +:205260000004047F04003F09091F091F09112302002044FE2000FE4448504C445C40400004 +:2052800000081010123D101C35305091111213000020404044F84040FE4080100804F800C1 +:2052A0000000003F202720203F2A2B29294A44000000DE2224E42868A462A2222EA4602000 +:2052C0000000003D1111112D2565252525390100000006F804442818081824444000FE00B2 +:2052E000000008087F2B1A1C7F0A19182848890000002020207E22A2E222244444841C0019 +:2053000000003D4545457D45457D44447C01020C0000FC042444444444706060A4241E00A0 +:20532000000011113F00001F101E12222224410000000808F890AC504848505020548E003E +:205340000000101051575555555555554D7101000000505050FC545454FC54545454A800EC +:205360000010102438217C10107F1010141912040020202024F8202026F85050880C0600FE +:20538000001010243B207C10107F10101418100000202026F820FC2022FE22222224200093 +:2053A0000010102438207C10117E1010141810000080848890E08086F8A0A09088F6800012 +:2053C0000000023C1010203E6464A4242418000000202024F82024F8202026F820202020CF +:2053E00000001024384146381014381014181000006040609008068098A0C0808888F8003C +:20540000000010102849111171121212121414090040584844F8484848A83030304C8400F3 +:2054200000003C2424243C24243C24254646480000000CF0000006F820A8AC2424246000AD +:2054400000007E42465A5A495B5667458080000000002418484C526244C46C1282621E00E0 +:2054600000001111131549511110191513224200000002FE2222FE2222FE22222222260050 +:20548000000010100E0B6A2A13121222222420030020584042BC2024A4A82810386E8600D3 +:2054A000000040242400203E242424243C362900002020245850A0A47820FE202020FE0097 +:2054C00000101010112F24242448483914204000005090969C90B0D2922C20FE2020202033 +:2054E000000019112325592911213901017D0100000002FC2424FC2424344C4C8404F800F7 +:205500000000043C242928284F34047C04091E000020A0A0FC202022DC50909090121E00B6 +:2055200000001310214D4A7120207301097204000000BC90101014F89090103C80601C000C +:2055400000101021214A7213204175031162040000008E70101034D8D050507E00C03C00B6 +:205560000000007C1213127F1212121E650408100000242422FC20E654545898982A460216 +:205580000000007C11111115391110101C61420000204044FC44FC4444BC242830D20E029C +:2055A0000000091E3F0936213E2A2A2A0E1121000010101010FE12122222222444448C0821 +:2055C000000004381011157A1011101C610608000000F89090100E2044F8E0D04C4600004F +:2055E0000010101310143B12101114684001020C009090FE90A0FE4840FC488888083000BB +:205600000004047F0503060837001F010D112701002024F8A0806018E408F000300C040060 +:20562000000004041B01013E000700080F080F0000002024F88008F030E00010F010E0001E +:20564000001810101438191435335050101112140020202026F828A830FE6050980C060074 +:20566000000811117F10127E42241408142040010002FC2020DC8494949494902824C2025C +:20568000001010217E2050537C10123C5011120000202424A8A8B0FE9090909090121E00D5 +:2056A000000011110F021F0E126F090F017F010000800808F000FC300EF000F004F80000DA +:2056C0000010102438207F10107C101116181000000040484844F86050D0C8444640400056 +:2056E0000010102438217D11117D1311151A1204002020263820DC0404F8000000000000EE +:205700000010102439217D11117D1311141810000020202024FC24FC2424FC2020202020EB +:205720000010112438207C10137C1111151911000000FE444444849C10FC04040404FC004E +:205740000010102438207C11117D1111151810000000FC88E8A8AAFE4828080AFC083810A9 +:2057600000080838282F5988880D784808090A04000050505056585050DC909092121E0039 +:2057800000090810121332531213101013101000000890A024DC44FC44FC4042FC40400010 +:2057A0000008083E22223E223E221E0B122246000010101010505454929292121010702044 +:2057C0000008080E11225C483F08093622221C0000007E4448485048C44242425E44404058 +:2057E00000043C24243C2724243C242444458E00000898705884202026F870A8A422200093 +:2058000000001021205F451911111010171A1400002020FE2024FC2424F870A82C2620208B +:20582000004424281738107D11117D111020400000102020FE2022FC24242424242020005C +:20584000004424080A34103F11127C10101021460040404086F888485050302030C8060019 +:20586000000008080A2C2968080B0814102020400004FC04FC04FC1012FC909010103010F4 +:2058800000001109093F40003F081F2848080F000010102020FE0404F800F8101010E00013 +:2058A00000007C4B4A52534A49444840404142000040840C04448C04FC60A0A0A0141C00FC +:2058C00000000C7A4B5250494845467A4344481000402004FC1008F04048704040C07C00C4 +:2058E00000001110107F252525254938161223400000FC0000FC080808F808885090FE00E2 +:2059000000101010102F2425264868181522448000202024F824A832EC60B0A82C26202056 +:2059200000101020207D2648484948301D2244800020605088040A7020FE20A82422E0002E +:2059400000001010102E2526244549381420400000202060508806F8004428A8B01016E8F8 +:2059600000001010102F252525454939152341000004FC5030FE2424FC2424FC24240C00BF +:2059800000003C0424242524261B047C05061C000020205048860A3020FC20AC222260002A +:2059A000001010102444781121217F050D70000000087038C04046B820FC2424242C2020E1 +:2059C0000000081011273C0810233C000438030400201022DE04047802FC505050920F0042 +:2059E0000000043C25252525271B0D7505051D00002020FC0808F80808F02C30106886004A +:205A0000000C081E0A1C093E0B001F040B3808070000043C244444AC1806F808F80808F0B9 +:205A20000000043B1111153A1011110E7400000700202024382020DC20A0242C5820C000FB +:205A4000000000043811121038111011156A0400006060A0900C1C6024F820382424E000D6 +:205A60000000081010113D11111010143B0000000080485012EC24FC24FC2021FE2020004A +:205A80000000112221217A2427242319620408000004FCA8189C2440FCA4281890A8C60060 +:205AA0000000043F050F020C001F0F10100F0000002046F8C0F0C02006F890909090700088 +:205AC0000000043F0101111E101F1F017F010100000044F80008F01010F0F004F800000052 +:205AE0000002043F243F64040F11013F1111111E002044F840FE0010F00004F8081010E047 +:205B00000000043F041F101F1018282F28484F00000040FC40F808F8808888F08488700042 +:205B20000000003E212020396969A929293A240000101010101638101028244080807E00AA +:205B40000000017C494A4A7B4A4B49487040010E0004F840FC4848F848F440C040A01E0091 +:205B6000000000057D4545457D454545457D0100004020FC0808F80808F4483010688600E7 +:205B800000081010107E5252527E5252527E400300007C20A4DC84A4A4A4A4A03844820254 +:205BA00000101010507C545555547C14177A000000202042FC809010FE10D89612107000CA +:205BC000001010527C54547C54546F4544444C000000EE2222BAAA2222EE2A3222226600B5 +:205BE0000010102438207C11107C10111418110000202024F82020FE202024F82020FE005E +:205C00000010112539237D11117D1310151916080090101014F810101010FE90880402003F +:205C20000010102539217C13117D1111151912000000101010FE10901824244080807E005A +:205C40000010103F254408083F08080F08080F00004040BC10302026F82020E02020C00015 +:205C600000081129692519290D354D1525051D020000FC000C88483010284C44800006F8D7 +:205C800000002438282838292939282848495E8800884850AE24A47820FE6262AA242020D0 +:205CA000000837424A75203F242428282B1020400000E6BCA4A8B0A8A4A2A2A22EA4202030 +:205CC00000101010141850501010111D2620400000202026F844F842FC8AFC480808180026 +:205CE0000000120504442C2C1414143425242700000002FE0AF2424272524A4AB202FE0083 +:205D0000001008403D0809321516001F010F3F000008F04084FCA444C43804F808F0FE0084 +:205D2000001010101814575011121112141010170020202CF022DC8C4288F85020708E00B9 +:205D4000000017000007143414131018171007000000FCA0A0FCA4A4A4584044F840FE002A +:205D600000001000030212331313151D1514080000102C24FE1014F414F45848D82646805E +:205D800000001101010111311013111A131408000000F808F80808F002FC447840C03E0040 +:205DA0000000100302031232131013191010030C0040C44C445C4444FC48B810A0E01E00E7 +:205DC00000000C7B4A52554F4847464A42404106000040FC4848F0FE08F8484848B80C04BA +:205DE00000101010106C25242549493915204003002024F82478FE00FC24242448488600F2 +:205E000000001010102C2526244829191521410100202066B8A82C2660FC0404FC04FC00FD +:205E200000101011204478091025380105790100002020FE20FC22DC04FCFC04FC041C08E3 +:205E400000007C08292828484834047F0404380000505050DE505052DC5050DC50505000B6 +:205E600000007C09292A292A2C17057D0508180000808002FE82F2444CF44C5454A41C0859 +:205E80000000101021457911112179000972040000402026D8FC040404F820AC2622E04036 +:205EA0000000101321457911102178030C700100004040FE08F808F80CF820FE4040C04086 +:205EC00000007C08282828484936047C050538000000FC08F8080AF420B6B8A8A426E0005B +:205EE0000000073A1212137E121312167B0200000000E07E5454D45454D84868D45462004E +:205F00000000043B1017107C1011111678000106004040F840FE24A0A02020FC4078840036 +:205F20000000073A1212127E121212167A0201000000FE04F424FC346C6CA4242404F80099 +:205F40000000043B1013117D171111157A000100000878C040FC4848FE48484AF440FC0074 +:205F60000000053810111039121110103F4000000008F02022FCA82648B82022FC20E04036 +:205F80000000043B1011117D1315111579010100004020FEA0205C6458C8283010284680F6 +:205FA0000002093120232A732222242C740811000010101858A426C290888080908C040050 +:205FC00000101110153B11111C73121212123202000CF020FC2828F022FE242CD40404046B +:205FE000001011101017391112101F1160000007002048D044F848464080FC10A0788400DC +:2060000000101011111539111111131D6202040000201002FC04F80082FEB2FEAAAAA200D5 +:20602000001010131439101B3453519313141810000040FE40FC4AFC48F0403C40C07E0603 +:2060400000101013163A121A3252529214141810000438E0207C20DC8494A4A4A04C840055 +:2060600000080E0B7C083F49497F497F49490B00000020DCA4949488807E02FA02020E006A +:2060800000003F013F211F407F52545F484841400080263C24283028E4A2A2A2AEA4A0200A +:2060A000001010136D2129517F11123C480809020000609E04448404FC50505050941E00B0 +:2060C000000808282C287F080849595565615F20000010304844822428484848488888009F +:2060E0000000097A4A4A7A4A4A4A7A4A4B7A02000000821C041464445464444CB4040C0438 +:206100000000487E4B4A7A4A4A4A7A4A4A7A42000000829E0404FC9494F494F484040C04A2 +:2061200000003C4444443811315D51514F7000000000FC88E8A8AAFE4828080AFC08381095 +:206140000008084A4A4A347E02023E20232C30030000FC20A4DC84A4A4A4A4A0384682006B +:20616000001010243B207C10117911161418110600204044F848F044B808F89060708E0042 +:20618000000111213D434931232D35292911010100000010109010FC5050101010126C00DE +:2061A0000010102438217E1110781013141810000020584844B824647850C8484640C0006A +:2061C0000010111529203C51117F1111111D11000000FC0808F000FC04FC04FC04041C089E +:2061E000001010253B237C1010781010151A1C0000402020DE604046F8A0A0A04884FC0099 +:2062000000001418595A1C181E7958292A2440830000FC20A4DC84A4A4A4A4A038448200F4 +:2062200000003D2A2A2A3A2A2A3A2A4A4A4A9900000002FC242C742474ACA4240404F8006C +:2062400000003C2424243C24253C242424444C0000402024D8885050AC00F8888888F00029 +:206260000010101E247F202E32323230534C000300027C2022DC8494949494902844820099 +:206280000000101C287E2A2B3E2A2A36023C01020020203050488648484848484888080000 +:2062A00000241828344418010F090808077F00000004F848F040BC00F0102004FCE42810CF +:2062C00000004438083B480B1A192ACA0B0A3A000060609088F700E254D45454D454CC447D +:2062E000000100102F24252A2926252644450200000080847820245C501030282844860000 +:20630000001008082F222F2A2A2D2127212620000000FC04F484F49494E414E414E41C0821 +:2063200000000810131549511111101C132020400000C850FC2424FC24FC2026F8202000AC +:2063400000001008090225080810113011151400008080F82024DC04FC04F8280412F80010 +:2063600000101111112D2524244B4939152141000000FC2424FC24DC00FE24281028C60074 +:2063800000011121227E2E4E4A4A52321A2242800080023C10FC947C9494F85020304E8030 +:2063A00000007C08282848484E350C7506281800002022FC247826F822DC80FC8484FC00B9 +:2063C00000007C0424282828473C0C7405261A040000FC88F888F000FE20A4B8A0603E00A9 +:2063E00000007B08315252525229087B080839100000DE428C949494944A42DE4242CE8460 +:206400000000043F1111163D1A13121B62020200000080FE08F020FE08F808F808081C083C +:20642000000000073810131A3011111539410000004020FC8890FE2444FC484848484000C9 +:206440000000007E1310117A141011147841060000402024DC900C544846F8A090080600F4 +:2064600000001F017F020C32021E021E023E02000010E000FC4038448CF088F086784000E1 +:20648000001010111538101F1430515011121410004020FC0890A25C2022FCF0A826200015 +:2064A00000007E2829FFACACACC584FC8484780000202020FE246050D498888884A6C000AD +:2064C000000004381020273C6565A5253D212100001020A4B8A25C04FC04FC04FC041C0030 +:2064E0000000023C1111152D6564A4241F20000000884850AE2424FC24F82022FC2020007E +:206500000000043823243C246458081310204300001090909E9090949890909C9090FC005C +:20652000000910142B20294D39090D794909090000088890FE5054FC949C0404FC04FC0058 +:20654000000810102C2028483F080D7848090E0000007C2020FC60A06020FC70A82C202074 +:2065600000041415047B413F211F04041F043B000000BE2464A82828242222A22C20202075 +:20658000000007007052525150537046060601000000FCA0A4A4A8B0A2DC442A0A08F800F7 +:2065A0000000037A494A4A7B484C4F7C040407000000F808F80808F80004F8A8A8A8FE00A6 +:2065C00000080F080F1F09051A021D060910631C0010F010F0E81030C00CF03040807C0039 +:2065E00000003C4445443810505851505438410600202024F824A4A82026F85050880600F6 +:20660000001010137E5656565656565A13151618000478902038E6A8F49488F050524A84B3 +:20662000001010122D203E50107E10131418010200088888FC88788888F888744884020087 +:20664000000011223E424F32121D32121A121500000072DE5252DE5252DE52525262EE00B8 +:206660000010101729217D10103C101114181000004020FE08F808F808F820FE2020E000C7 +:206680000020222931457B21227A262222390200000810107E5050506C64A8989824478013 +:2066A0000010102C282AFF2A3E2A2A36003C400000404040BC8454BC9494947404041C006B +:2066C0000010102C29735E527E52522E003C400000201022DC0040444C50604044443C00A4 +:2066E00000003929292838292A382B294848580700004C4850ECD04C4640FE10D038C40095 +:2067000000100809222D2A2D2221272529312000000004FC04C444C44424C46424041C08FD +:206720000010101014145B521011101C25224C0000109096F8906E2040FE60B0282620204C +:2067400000001800043808171979151311101102002024F820F826DC2424242448488600DC +:2067600000003E12133E127E10322E62221E00010002FC2020DC8494949494102826C200C7 +:20678000000005392929292929160E760A0A1D000000FE1020DC84FC847C105C7692702095 +:2067A000000004392828282928150C74080819060004FC24A83048F048FC2446F8900C0099 +:2067C0000000101112163A121212161A62050400002020FE20782A7C2830F668A824E00087 +:2067E0000000111111143B1010111E11600100030000FC4C4CDC20609826409064986080F9 +:2068000000081110143B121D3531505010101106002020A8B04E08F80808F860A0A2120CE6 +:206820000000437C52525E5E4876544D4A727F00002020DCA494889890EE02FC04040C009B +:2068400000000C332020392A69A8A82B30200001002020FE508846B81030D22EE40830C0F1 +:206860000000063A22223C282969A92930200106005090A4B8C884807C28485062A2120C0F +:206880000000073A22213C282869A828302000000040DC5454D800F802FC847C0408380089 +:2068A000000404152624257A02051B290F081F0000604448F040C23E20C03810F000FE001F +:2068C00000001F101F0F1808133C0A111F2422400000F010F0F020204CF02048F4884400A8 +:2068E0000010302837407820217620212931010000109096F86060901EE208F80808F80068 +:206900000010102539217D11127E1111151A1400002040FC08F80808F0E4D8504846C0405F +:206920000010102539227D13117D1311151911000000BC080A74203C5090FC182824428096 +:206940000010112E45060F011E0409721D06091E006046B80420F000F840BC408030C00090 +:20696000000C0A1121DE3F1A294909011F013F000008482808684A3C08080808F000FE0041 +:2069800000007D49484879494F7949494948880700282850E846B806F82848484848860211 +:2069A00000102039527E5A5A7A5A5A22057902040080809C9092FCD4D4D4D4D41010100008 +:2069C0000010102C282BFE2A3E2A2B36003C01020000505052D4C85058D6525052920E0048 +:2069E0000010102C282AFF2A3E2A2A36003D01020020205C90D2ACA4BCA4A4A4A0223E00D2 +:206A00000010102C282BFE2A3E2A2A36003C0003002010A2DE2420427C4888701826C200B6 +:206A2000002A11721D6A1120010E09090F001F0000202422FC28C48200F02020FC24C818A2 +:206A4000002010137E21213D252525244448980000282CF024FC24FC24FC0AFC48483800CD +:206A6000002010211E0D12321B087F080F080F080040C0301EE01808F820FC20E020E0001C +:206A80000008043B3E223C223F03013F020C3000000004F878887888880002FCA0988400F3 +:206AA00000001017020372131210131C15150D00000040F840FC48F84848F6826E0AFA006F +:206AC00000001811264448791121790101780106000020FE0404F824F828F828D88C02024C +:206AE0000000007C1311101439101310186000000004F822FCAC2020FC02FC847C0838109E +:206B000000002020277868696A7861292D5400000028A8A8FCA8A8FE2424FC24242C20201E +:206B2000000001211E0808773F223E2A2948090000800408F0204848FE50505090921E00F1 +:206B4000000010103D2244B810143911111E11000010D090284488F844CC5454CC74DC00DC +:206B60000010103C2853FD553D545428003C410200004088F010EE2424FC305052921E00E4 +:206B80000010101C282B7E2A3E2B2B36001C210000004044F8503028E410FE206CA2200053 +:206BA00000043715044C34341616252429292A100002FC48D0AED0E8C8C89898182446000E +:206BC00000013F443F243F093E090908177F00000000FE4CF040F810FE206004FCE438007C +:206BE0000000100F003C0B0A1A36521212121210004020FE90ACD4447C54B494F4041C004D +:206C0000000013120201123211111110191E10000000FC94946C9000F808FAA498ACC48038 +:206C200000101021213E2A2D48494A301822428000008834F2B0FC5898244280945A4000F8 +:206C4000000078484948484B7C09196B080912040020A4A8FE70AC2080DE78689E0808008E +:206C60000000043B101111391110111F61010000004892EC847C8404F8FE2232CA1AFC003F +:206C80000000073A1313113A10111119610101010000FE9828DC98F6200CF808F808F80047 +:206CA00000000D3324242C352525242A7302020000007E444CF44CFC6C4CF4CC4C040C00BE +:206CC000000003391212127E1212121E650408010000FCFC0878127C20224448BC889880CE +:206CE0000000073A1312113810111018610003040040FC64BC12DE9090FC90906CC402007A +:206D00000004043F0C083A2C2A1D2A2B4C083043002046F844B8C4BC84B4A4A4B44C820271 +:206D20000009120F013F211F3F523F3F110F08300000E43C24282830E8A4A2A23E24A0208C +:206D400000101022312050547B12123E5116100000004428122C6698305C2A48B0A07E0034 +:206D6000000808282C287E104B525A6662425E20002020FC20588802FC7898987808080808 +:206D8000000808282C282B1448525A5A66624E71002044848484C48484F8505052528E00CD +:206DA0000001017857525370535253724302020000080850906CF454949898888894A2404E +:206DC00000012121227A6E6A6A6A32322A7202020010227C5488B6C2BCA4BCA4BC242C0056 +:206DE00000101011557D5555557D59163B420400004024DC04FC00FE24BCA4EC34246C00B2 +:206E000000101013565756545554575C67000300000092EC807E0C74E8CC70B858947020CE +:206E20000000202123696E6D6F6D6D5D050404000000882ECA0AFCC84C4C54D454626200D1 +:206E40000010102738217C13107D121014181300008888DE88DC88DEA800FC04FC04FC00B9 +:206E60000010102538207F11117D111115191204009090FC90966824FCFC2424D884020085 +:206E80000000312B37417B25257D27272D1504040010107050ACF474D4D848485854E20086 +:206EA0000018112F443F080F0807382227212000004042BC10FC10F010E01848F80838003D +:206EC00000001020273D4911111110101418110000002002FC04745424DCA488F880FE00B9 +:206EE00000100A141A122A4F0809090F001F00000040B840B8704884705020FC28D8380037 +:206F000000202123102868672023222322222201000010FC304CF0FEC81CE8B4A4A4A658DB +:206F20000000102120447B102129110118620000000020FE90926CFC08F800208282F80097 +:206F4000000008312321267D272525253D4404000000882ECA0AFCC84C4C54D454626200D0 +:206F60000000033E2223212A32272221285300000000FCA4A45C04FA52F454F454AC1C00E1 +:206F800000101027382144391014381115191100002020FE24D8FC08F84850AC540808F05A +:206FA000001010253921453810143810141A12000000FEAC6C5424FC24F820DC945A4A002F +:206FC0000010112538204F30111F3111151911000000FC24A832FCA82604FC24FC24DC00FF +:206FE0000010102439204C33111D3311141912040020ACB0FC70AE2888DE5868BC08080010 +:20700000001010243B214D31111D31101718100000889026F864549C04FC080AFC083800CC +:207020000000302B31407827227E22222B13040000004C30162822D428582E4A8810FE0081 +:207040000010102439204C33111D3111151911000004F820FE64A060BE4CD47454240C040D +:2070600000001E2A1A053E2B2A7F2A2A3E2A34000010207CA4948488807E020A72021C001D +:2070800000101C2428367D353D34352D027C0000000084A4DCACECACACEC4CAC84848C00D3 +:2070A0000010142D28735F537F53532E003F0200002020FE2026FC6CB4FC7070A826202014 +:2070C0000010142D29735F527E52532E003C0003002060AC24A424FC2024DC4830708E00D8 +:2070E0000010253D497F55557D557D5556970F00000478901418E694FC96A8B8A8284A044A +:2071000000003F3E223E223E2708117F110E3F000000F880A4783252CE4088788878FE00F1 +:2071200000001112274A781020487105196101000004F820FE20202002FCFE545454140C48 +:207140000000101027493111214831001F6002000000F820FCFCACB4FC24F826D8725200F8 +:207160000001010F3110111E3116181539410600000814F810F012FC48B640F8404CC440B2 +:2071800000011E111F28312E1F10087705093100000830CC30C67838D090A0DC2018060068 +:2071A0000000043F021C24243C7E665E52524640002046B82020D8A8888C827E0A74040CFE +:2071C00000012123247869696A73202F2D5106000000109C2244B81010FC90103C00F6088C +:2071E00000003E2C3C2C53423E223E223E220F00002020FCA4A4FCA4FC38385C5A921E0003 +:207200000008112E41010E023F0F111F0F010F3F006046B81010E040FCF010F0F018E8FC83 +:2072200000100834140936494A7E3E0A3C0B3C000000007E24A46C64242CF42424246400A9 +:20724000002212146B4B5D4937023E223E223E000000007E24A46C64242CF4242424640029 +:2072600000101011213F25244748493915214080005052FCFC5454AA56FC08F808F8F800F7 +:20728000000011112724780811213E00057801000004FC7424F82CF20C564220FC20FE0087 +:2072A0000000047F0C142D557555270508081060000404D4548444D45446FC0484840404BD +:2072C000001013107B11123C30505314101310000040909EEACAD2EE60B826F870ACE00073 +:2072E00000001010137C585858597919157D01000000F822FC20202004FC24FC2424DC009F +:20730000002A3B2A2A3B2A14142F5F241F243B000080BEA4A4A8A828A424A424BC2020006D +:2073200000101C25287EB4343C343428027C0000001022FC2458FC84FC4852ACFC84FC003C +:207340000010083F2419192141020C731F053F00000834D478B0C80404807E80F820FE009E +:2073600000001010171910511112162B262342010000F842FCD840C024F824F824F826D80C +:2073800000001011224A7910214178010C730400004024D86464B894F8FC92ECA898E60091 +:2073A0000002023F2626222B3428232110600304004058AACCE8A8EEAAD02C18B0609C04E0 +:2073C000000810303F304F0A525A5A46423F01000048888AFCBCAA08027CA09CA0601E0033 +:2073E00000000079484B4A7949494B4D71410100009090FCA4BCA49820FC24F824F8FE00D7 +:207400000000037A4B4A4A4979494F4D497101000000FC64FC6464B82CF02CF0FC20FC0082 +:207420000000037A4B4A7A4949794F4D497101000000FC64FC6464B82CF02CF0FC20FC0032 +:2074400000081010131549511111191513204000000000FC24242424D800000002827C001B +:207460000000000149784848484849784040010000202024A8B020DC0404FC040404FC0024 +:20748000000000497848484B484878404103040800003CC0404040FC60609090080C060006 +:2074A0000000001F503031103153101010204000008080780008F08000FC0808101070004C +:2074C000001010101B1A5451111315191111101000202040FEC4A024AC101010084482005E +:2074E00000101322224F5A72222373020E7202000000FE0246669A8ACA566622020206004C +:20750000000010101011781212111119604007000000889014F89096949898909090FE00F0 +:207520000000101011107C11111315153940000000404040BCA0A0FE2424242424242020E4 +:20754000000008091612142F49087F0808080800000004F8404878486848484894B4CE0025 +:2075600000101010147810183430505111101010000050505052D448505050D252524C00D1 +:20758000000810101738101D143050531010100000202024F82020F8202020FC20202020C0 +:2075A0000000001F503017107254151921224400008040B88040BCA0A8A4242020106000D6 +:2075C0000000017F417F3F09092B2C280E10204300202040447C9810303030304844860060 +:2075E00000101909010171111111111129460100000004F8080808F8080808F00000FC0011 +:20760000000004382021243F672524253F21010100885056A8FC20DC1020DC181028468063 +:20762000000048784B4879494A7A4C487840030400004040FC404824ACD0605090880600AC +:2076400000001010214648781021780004384000004080847800A0A4FCA4A4AC8282FE00CC +:20766000000011112146487911237D010539410100002424D8A0D0FE2026F824F820DC00AA +:2076800000041E3010113F101C375290101112040010909094949890909C909092121E002E +:2076A00000007E087F142B481625EA1C3A49080000000E30D24C84106E42426242427E002C +:2076C000000010101B56565112121211101112040010A0A4FCA4A4FCA4A4A458880402008E +:2076E0000008080810103F509010111112121418008090888886F8A4ACA8302262A23E0087 +:207700000010102438417E111279121219111100002060508814E0E454D45454C444CC005F +:20772000001008023C24140B34027E42423E050600202024382020DC8888505020508E00C9 +:207740000014243E24251A3E4A3E4A4A34126200002010EC84FC8478007C10FC101070009E +:207760000010302438407C90147C1010141811000004F8888888F8888888F888888A74000A +:20778000000018082021222C3120272423202000000004FC0484447C8424C444C4041C0857 +:2077A0000000000000000000000000000000000000000000000000000000000000000000C9 +:2077C0000000000000000000000000000000000000000000000000000000000000000000A9 +:2077E000000000000000000000000000000000000000000000000000000000000000000089 +:20780000000000000000000000000000000000000000000000000000000000000000000068 +:20782000000000000000000000000000000000000000000000000000000000000000000048 +:20784000000000000000000000000000000000000000000000000000000000000000000028 +:20786000000000000000000000000000000000000000000000000000000000000000000008 +:207880000000000000000000000000000000000000000000000000000000000000000000E8 +:2078A0000000000000000000000000000000000000000000000000000000000000000000C8 +:2078C0000000000000000000000000000000000000000000000000000000000000000000A8 +:2078E000000000000000000000000000000000000000000000000000000000000000000088 +:20790000000000000000000000000000000000000000000000000000000000000000000067 +:20792000000000000000000000000000000000000000000000000000000000000000000047 +:20794000000000000000000000000000000000000000000000000000000000000000000027 +:20796000000000000000000000000000000000000000000000000000000000000000000007 +:207980000000000000000000000000000000000000000000000000000000000000000000E7 +:2079A0000000000000000000000000000000000000000000000000000000000000000000C7 +:2079C0000000000000000000000000000000000000000000000000000000000000000000A7 +:2079E000000000000000000000000000000000000000000000000000000000000000000087 +:207A0000000000000000000000000000000000000000000000000000000000000000000066 +:207A2000000000000000000000000000000000000000000000000000000000000000000046 +:207A4000000000000000000000000000000000000000000000000000000000000000000026 +:207A6000000000000000000000000000000000000000000000000000000000000000000006 +:207A80000000000000000000000000000000000000000000000000000000000000000000E6 +:207AA0000000000000000000000000000000000000000000000000000000000000000000C6 +:207AC0000000000000000000000000000000000000000000000000000000000000000000A6 +:207AE000000000000000000000000000000000000000000000000000000000000000000086 +:207B0000000000000000000000000000000000000000000000000000000000000000000065 +:207B2000000000000000000000000000000000000000000000000000000000000000000045 +:207B4000000000000000000000000000000000000000000000000000000000000000000025 +:207B6000000000000000000000000000000000000000000000000000000000000000000005 +:207B80000000000000000000000000000000000000000000000000000000000000000000E5 +:207BA0000000000000000000000000000000000000000000000000000000000000000000C5 +:207BC0000000000000000000000000000000000000000000000000000000000000000000A5 +:207BE000000000000000000000000000000000000000000000000000000000000000000085 +:207C0000000000000000000000000000000000000000000000000000000000000000000064 +:207C2000000000000000000000000000000000000000000000000000000000000000000044 +:207C4000000000000000000000000000000000000000000000000000000000000000000024 +:207C6000000000000000000000000000000000000000000000000000000000000000000004 +:207C80000000000000000000000000000000000000000000000000000000000000000000E4 +:207CA0000000000000000000000000000000000000000000000000000000000000000000C4 +:207CC0000000000000000000000000000000000000000000000000000000000000000000A4 +:207CE000000000000000000000000000000000000000000000000000000000000000000084 +:207D0000000000000000000000000000000000000000000000000000000000000000000063 +:207D2000000000000000000000000000000000000000000000000000000000000000000043 +:207D4000000000000000000000000000000000000000000000000000000000000000000023 +:207D6000000000000000000000000000000000000000000000000000000000000000000003 +:207D80000000000000000000000000000000000000000000000000000000000000000000E3 +:207DA0000000000000000000000000000000000000000000000000000000000000000000C3 +:207DC0000000000000000000000000000000000000000000000000000000000000000000A3 +:207DE000000000000000000000000000000000000000000000000000000000000000000083 +:207E0000000000000000000000000000000000000000000000000000000000000000000062 +:207E2000000000000000000000000000000000000000000000000000000000000000000042 +:207E4000000000000000000000000000000000000000000000000000000000000000000022 +:207E6000000000000000000000000000000000000000000000000000000000000000000002 +:207E80000000000000000000000000000000000000000000000000000000000000000000E2 +:207EA0000000000000000000000000000000000000000000000000000000000000000000C2 +:207EC0000000000000000000000000000000000000000000000000000000000000000000A2 +:207EE000000000000000000000000000000000000000000000000000000000000000000082 +:207F0000000000000000000000000000000000000000000000000000000000000000000061 +:207F2000000000000000000000000000000000000000000000000000000000000000000041 +:207F4000000000000000000000000000000000000000000000000000000000000000000021 +:207F6000000000000000000000000000000000000000000000000000000000000000000001 +:207F80000000000000000000000000000000000000000000000000000000000000000000E1 +:207FA0000000000000000000000000000000000000000000000000000000000000000000C1 +:207FC0000000000000000000000000000000000000000000000000000000000000000000A1 +:207FE000000000000000000000000000000000000000000000000000000000000000000081 +:20800000000000000000000000000000000000000000000000000000000000000000000060 +:20802000000000000000000000000000000000000000000000000000000000000000000040 +:20804000000EEAAAAAAAACAAAAAAEAAA0C08080800FC0808E8A8A8A8A8A8E8A808082810B4 +:20806000007D444849514949454545695040404000FE0808E82828282828E828080828106D +:208080002020212227F9212324202738E041020C40801008FC0400F84040FE40A0100806DB +:2080A00020202122F721212334E02F202021A24C40801008FC0400F84040FE40A010080603 +:2080C00001017B4949484A4A494978480001020C1010FC10100008081010A040A01008064A +:2080E0000000F1929791919394909FF09001020C40801008FC0400F84040FE40A010080613 +:208100000201FF00001F10101F02040C34C506040000FE0000F01010F080442810080600E2 +:208120001011217D454445447C454545457D440020242424FC00FC0404FC00000202FE0093 +:2081400000001F109352531037549710242447808040FE00F808F800BCA4BC404444FC04CD +:2081600008FF0843222302E3212324222A33200020FE20F808F808F800FC44A404F414084E +:2081800020213C50931011FE10131029244440811CE02020FEA8244240FE8808D0304884F9 +:2081A0000404FF040008080404020102040830C04040FE402020204040800080402018067F +:2081C0000001FD1111213C6564A724253C24200000F808F808F800FC10FE101090105020B7 +:2081E00000017E22117F42827F04070A1120431C08FC101020FE0204F800F01020C0300E08 +:2082000002794948575061524C4B4A6A52424F4008081000FC00100804F8A8A8A8A8FE00BC +:208220002828FC2B3A147C57547C11FC10101013402020FE024440FE888808D020508804A0 +:20824000203F409F007F047F4008FF11320C1B6000FC00F000F010D05010D0120A0A068233 +:2082600002013F20420202FF0408180601020C700000FC04080000FE2020404080601008F0 +:2082800008080B111234335292131212131010104080FC104846F84848F84848F842423EB7 +:2082A00010101013FA14101B30D0111010105023402020FE024440FE888808D020508804A8 +:2082C00000007B4849484F7849494949794901018040FC000890FE00F80808F80808F80839 +:2082E0000121213F003F202F20203F2040408000000808F800FC00F88080FE808080808055 +:208300000078484B4A7C484B487849484848489B402020FE024440FE888808D0205088044F +:20832000017F4004FF081E033C01FF050931C10100FC0400FE2040C03800FE402018060042 +:20834000003C2425243C2424243C24242445558A402000FC0000F0909090909292120E0030 +:208360003F203F203F000C704040404C70400000F808F808F80000FC8484848494888080A8 +:2083800001011F1111FF020C30C03F242424FF000000F01010FE80601806F8484848FE0019 +:2083A000007C4444444444444447404040407F40007C44444444444444C404040404FC0433 +:2083C0000808087F083E08FF101E1212222A44812020203E444444A42828101028488402E2 +:2083E00008087F087E08FF101E224680242242802020207E44A42810284482008844440443 +:2084000010217C447D447C10FE2855927C10111000DC444454CC44444CD46444444454882C +:20842000201001FC081011345894141010101112083CE0202020FE20205050508888040297 +:2084400012121F222F62BF2424272424242928301010D020BE44A42424A8A890A8A8448217 +:2084600002043F2029252F25292001FF020C30C00000F8082848E848280800FE80601806E2 +:208480002021272435ACA7A4A524202F2021222C8000FC445444FCE4540440FEA0100806F1 +:2084A00000211714854447141524E02F2021220C8000FC445444FCE4540440FEA010080609 +:2084C0000808FF08003F2121213F202020201F002020FE2000F8080808F800020202FE009B +:2084E00020272424FC27222A37E222222424A95004C4445454D41414D454545444445488FC +:2085000010101111FD1111151931D2121214542800202020202020202010101008080402CF +:2085200000007949494949494949794A02040810002020202020202020101010080804029C +:2085400000037A4A4A4A4A4B4A4A7A4A0202010000F84848484848F8080000020202FE006A +:2085600010103F2845803F2121213F202020201F40407E900800F8080808F800020202FE8D +:208580000000040404040404080808101020204000404040404040202020101008080402F5 +:2085A00000001F109053521232529312222241808040FE0000F848484848F8000202FE0047 +:2085C000003F21212121213F2020202020201F0000F80808080808F8080000020202FE0075 +:2085E00010101010FB10141831D111111212542150484840FE8080FC444428281028448257 +:20860000007C4444477C10105D5151515EE2040150484840FE8080FC4444282810284482EE +:208620002829FD2939117D55557D11FD1111101000FC2424242424FC040000000202FE00D3 +:2086400010111111FD1111151931D1111111502000FC2424242424FC040000000202FE0033 +:20866000101011FD117911FD11393555911110100000FC2424242424FC0000000202FE00F0 +:208680001011111111FD11111111111CE040010600FC0404242424242424245048840202D1 +:2086A0003F017F419D227F223E087F497F08FF08F800FE0274007C44447C44447C445488AE +:2086C000007F44447F01013F0101FF0408103F1000FC4444FC0000F80000FE002010F808C1 +:2086E00004081824030C30C01F11111F1010100F4020508800C0300EF01010F0100404FC4A +:208700000102043F202020203F20202020203F20000000F808080808F80808080808F8081D +:2087200010101011FD1131395555911111111111202040FC04040404FC0404040404FC0454 +:2087400000FF0102043F2020203F202020203F2000FE000000F8080808F808080808F80830 +:2087600010131212FB10141930D017101011532100FE5252FE2020FC2020FE408804FE02D8 +:20878000080B081010313151911111111111111100FE202040FC040404FC04040404FC0451 +:2087A000007C445454555654545454102824458240404080FE0888888850502050880402B7 +:2087C000041EF01010FE101010FE11102020408000FC2020FC2020FC2020FE2020202020C8 +:2087E000081CF11111FD113935545193101010104080FC2424FC2444FC9010FE101010100C +:208800000002F9212F2024FA2221213AE244080000003E08C8888888BE08088888487E00B9 +:208820000000F822222222FA22242039E14204088080BE88888888BE88888808083E00006E +:2088400021222724F625242F34E426252424A449003CA4A4A4A4C280BCA4A4A4948894A27C +:2088600010101111FD1111151931D11111125224081CE00000FC4444442828101028448293 +:2088800008103E22322A2AFE22322A2A22424A8500784848488600FC444428281028448259 +:2088A000002928244545817D252525252444558A00FE2040FC0424242424244450880402AC +:2088C00010101111FD1131395555911111121214081CE00000FC444444282810102844821F +:2088E00008484949497D414179494949494A4A8C081CE00000FC4444442828101028448267 +:2089000010101010FD1112151830D0101111522410909088080404FA8888888808082810F8 +:2089200010101110FC1011141830D31010105020202024A4A820FC202020FE202020202040 +:20894000080A091110373050901F1010101010104044485040FC404040FE4040404040407F +:20896000402127FD055525FD252575252549499190C8083E8054487E48485C280848A8285E +:208980000121110909013F010101FF0101010101000808102000F8000000FE000000000015 +:2089A000020202027F020212122444080810204000000000F0101018141212101010A040B0 +:2089C0001010212444F8112040FC43001CE04000202024A4A820FC202020FE202020202040 +:2089E000080808FF08087E0808FF081010204080007C444848504848444444685040404047 +:208A00000808FF087E08FF102041BF2121212101007C4850484454484000F8080828100049 +:208A20002121212FF121277169AFA12122222428001E12D21414D81412D2121A1410101026 +:208A400010101311FC13323C54539010101111124020FC0890FE024420FC80F88808281036 +:208A600000784B49487B4A4C487B48484849499A4020FC0890FE024420FC80F88808281036 +:208A80002121214751F1272141F7410131C20204001E12D21414D81412D2121A14101010C5 +:208AA00010101310FD10333855529010131010102020FE20FC40FE882422F820FE20202095 +:208AC0000000FB2120437A4CC84B4848784901024020FC0890FE024420FC80F88808281056 +:208AE0001010107D545454557C5010171CE44000202020FC202020FC202020FE20202020AF +:208B000020203B21407BA224F8232020283121024020FC0890FE024420FC80F888082810CD +:208B200010101722216764A820272121212222248040FC0810FE028440FC00F80808281062 +:208B4000002013110003F21410131010141911024020FC0890FE024420FC80F888082810B1 +:208B60000404FF04081F205F10101F1010100F004040FE4000F01090909090502404FC0054 +:208B8000007849494A7D494949794949494948988080FC0404F4141414F404281202FE0046 +:208BA00008081F10205F9010101F101010100F000000F01010909090909050200404FC0085 +:208BC00001FF080B12335097111203040C35C60400FE00F808F840FE5048008850300E003F +:208BE000007E023E02FF0809492A1C2AC90928100404042424A424242424242404041408EE +:208C000008FF080027101382434A0B12F027222120FE2048FC40F848F848F84810FC1030A7 +:208C20003F017F419D011D081F205F101F10100FF800FE0274007000F0109090D02004FC89 +:208C4000080B0A1212333050971011121418101000F8080808F84040FCE050484442404008 +:208C6000080B1233509711121411013F0101FF0000F808F840FC5048464000F80000FE00E4 +:208C8000202021394A55812121212121293120008080FC0404F4141414F404281202FE0095 +:208CA00002017F4080007F0101013F010101FF000000FE020400FC000000F8002010FE0089 +:208CC00010101111FA15111931D11111111150208080FC0404F4141414F404281202FE00FD +:208CE00010111111FD1111151931D1111111512100FC0404140800FC44442828102844824B +:208D00001F101F101F087F08FF0831C905091522F010F010F020FC20FE2018264020100801 +:208D20000C30C2144932C81524CC1424C4042810404080FC04040404844444040404281045 +:208D400020207C44897E54547C54547C001CE0404040FC8404F49494F484948882827E0052 +:208D600011111115595053901710112A24404180FC04FC04FC88FE88FE8824AA70A824609E +:208D800010101310FC10383451529410101010100000FE20204040D04844444040404040F3 +:208DA0000000FD1111213D6565A425273C2420004080FC2424FC2444FC9010FE10101010BA +:208DC00004047C04043C04047C0401084848870040407C40407840407C4000849212F000DB +:208DE00002043F21213F22223F0810FF000000000000F80808F80808F88080FE808080800D +:208E000004040404047C0404040404041CE4440440404044485060404040404242423E0062 +:208E2000047C043C047C06023F05091F01FF0101407C4078407C4000F80000F000FE000026 +:208E400004047C041CE4401F101F101F101010108098E084847C00F010F010F01010502091 +:208E6000001F101010111111111112020408102000F0101010101010101010804020100886 +:208E800010113D2141BD1111FD1111101418110600FC0404242424242424245048840202A1 +:208EA00008080B101231315790101312121213128040FC00080810FE0000FC040404FC04CC +:208EC0000045291129498909192949880808512600FC040424242424242424504884020255 +:208EE00004040F1864031CE01F11111F11111F100000F0204080700EF01010F01010F010C1 +:208F0000080F102C031CE01F111F111F0148488700F0204080700EF010F010F0008412F2A2 +:208F2000101011105558509310101129254541814020FC00089000FE0000FC040404FC04E0 +:208F4000201000F9091115395591111111121214101010FE121410FC4444282810284482F9 +:208F600002027F040931CF0109087F08081010200000FC402018E6002020FC20202020204A +:208F80000808FF0801017F030509112FC10101012020FE200000FC80402010E806000000EC +:208FA000010101017F0305050911214F8101010100000000FC804040201008E402000000F9 +:208FC00010103F4885017F030509112FC101010140407E900800FC80402010E80600000060 +:208FE0000121213F003E22223E22223E22224A85000808F8007C44447C44447C44449408EA +:209000002027244454F7242444F7440434C40A1100BCA4A4A4BCA4A4A4BCA4A4A4A4A44CEC +:209020007F010719E1003F21213F21213F414181FC00700C0200F80808F80808F8082810A9 +:2090400000FF04081F28C80F01017D091121C50200FE0000F01010F000048850201806004E +:20906000007A4A4B487B1212535E52535AE20508202222FE00DE5252DE5252DE52525AA475 +:20908000022110170101F1171111121214284700081000FC101010FE101010101000FE0023 +:2090A000002710130203F017141714171428470000FC00F808F800FC44FC44FC0400FE000F +:2090C000021F101F101F003F213F213F00FF081000F010F010F000F808F808F800FE2020D5 +:2090E0000020202020203E202020202026382000808080848890A0C08080808282827E0074 +:209100001F11111F047F043F202E2A2E203F2000003E222424E824A4A2A2A2B4A8A0A0200A +:2091200010103F4885003F01013F01017F01010040407E9008F80000F80000FC020202FE7A +:20914000080810234A0A12335292121212141419202020FE222420FC848848502050880676 +:2091600000FE107C101EF0007F04083FC8080F082040FC84FC84FC00FC0000F01010F0102E +:2091800008FF08023F2423243F00203E2020263820FE2000F8488848F8008498E084847C13 +:2091A0000404FF0408492A7F49495D6B494145424040FE4020203E44A424282810284482A9 +:2091C0002020203E202026382101FF01010101018088B0C08084847C0000FE0000000000B3 +:2091E00041417D414D7000FF10103E42140830C00018E00404FC00FE808890E08084847C51 +:209200002020203E2020263801004848890E18E78088B0C08084847C0090A442821010F067 +:2092200000017F01013F2121212121212101010108FC000000F80808080808281000000027 +:2092400001003F202424242427242424454684000080FE00202024283020202222221E007E +:2092600000001F109352531233509F11212142848040FE00F848F848F800FE1010101010B6 +:2092800020170040405F4041424448504241404000FC048484F4848484848484840414085E +:2092A0000849292A087F49495D6B494949414542101010203E4424242428281028284482D2 +:2092C00008492A7F495D6B49430808FF0810204020203E4848A81028462020FE202020207E +:2092E000000402010108282828494A8C081827400000101020204844840202121010F000AA +:20930000007C4445447C40417C64A5A4243C2400402020FC008850FE2020FC20202020202C +:20932000007C45447C437CA5243D013F0101FF004020FC8850FE20FC202000F80000FE0022 +:209340003E223E207EA23E22001F101F101F101010FE4428FE10FC1000F010F010F010306E +:20936000004724240407E4282F34242724508F001088BE80A2943E0888BE88888800FE0068 +:20938000027A4A535262524B48486B5040404740202428B02022A21E4040FC404040FE00B9 +:2093A0002828FE2939137D55557D11FF1111111180FE907C54547C54547C90502030488622 +:2093C000002010130000F0101011111214284700404040FC44444484840404281000FE00B5 +:2093E000101023224AFB122243FB43051DE549018040FC0404FC0000FC5454FC5454440C65 +:20940000007C4544545455545454541028254280083CC0002010FC040810204080403E0031 +:2094200002013F20203F20202F29292F494989080000FC0404FC0000FC2424FC2424240CA0 +:2094400010171027246467A4242722212021222C00FE40FC4444FC4444FC40408040300E3E +:209460000201FF04142444003F080402010618E00000FE4050484400F020408000C0300E36 +:2094800002010100FF020202020202020202020200000000FE000040201010000000000035 +:2094A0002010107C002A12FE12107C1111222440108888BE809488BE88889C080808080864 +:2094C0002012117D002B11FD11117D11112120401008083E0014083E08081C488808080885 +:2094E0002010107D012B10FC11137C10102320401088883E40D488BE08C81C08C8080808A8 +:20950000002013120203F21313151519111128478040FC0404FC00FC5454FC54440C00FE13 +:2095200010111010FC133038555592121410101000FC000000FE2020282424222220A040F3 +:209540000407043F24273C23202F292949519020008404C850248488102404081222FE00E6 +:20956000007B48494979494849784B4848494A9800FE50FC5454FC00FC00FE20A824A2400F +:2095800001017F01013F0101FF05081828C90A0C0000FC0000F80000FE00885020180600D4 +:2095A000492A7F495D6B494F103F511F111F00FF203E4848A81028C640F010F010F000FE60 +:2095C00008492A7F495D6B49494301084848870020203E44A4282810284600849212F0003F +:2095E000007F4141417F1010FF11111121214A8404040424242424242424242404041408D4 +:20960000003F2127A467242764A721263A43428180FE00F808F808F808F82018668808F83F +:2096200010101010FB103039555292141010101082828488D08282C4A8908282848890A0C9 +:2096400000201100FC0B08482812122A2A4A87021014D21210FE109090D090908AEA06025D +:2096600042222A8B4A4A1F20224ACA4B51424418007E10A07C44D45454D4D454202844821A +:209680000020171488434A0A1312E22F202122048040FE0214E00000FC1010FE00100804D9 +:2096A00002017F40801F10101F1010FF000810200000FE0274800000F88080FE0040201059 +:2096C00010101312FC1111151931D117101051224020FE0214E00000FC1010FE0090080443 +:2096E00000001F10101F10101010FF000810204020F0000000F880808080FE0040201008D7 +:20970000004020200007111121E222242820210040404044687060505048484442404080FC +:2097200010131010FC13323A565292131212121200FE202020FE2222524A8A0202020A04FC +:2097400000FF0101017F4141424244484040404000FE000000FC04048444242404041408C0 +:20976000003F017F013F01FF013F03050931C101F80000FC00F808FE08F8804020180600B6 +:20978000212020384B508020202720202931220404848800FE88888888FE88880808080892 +:2097A00010131014585352921212122B2642428200FE202020FE2222524A8A0202020A046C +:2097C00000001F109057501037549415262444848040FE0000FC4040FC44A4141404140867 +:2097E000100808007F08080808FF08081010204010102000FC20202020FE202020202020A1 +:209800000000F823222222FB2222223AE2440409202020FE222420FC848848502050880697 +:209820000404FF0420101382424B0A12E22424294040FE402020FC2420F888885020508CCA +:2098400020272221FB21222C33E222232222A34278C04850FC504806F84848F84848F80817 +:2098600010101212FB10141831D111121214582340484440FE8080FC444448502050880683 +:2098800010103C2041BC1010FD1112101418100020202020FE70A8A8242422F820202020A3 +:2098A0000020101382424A0B1212E22222242409202020FE222420FC84884850205088064F +:2098C00020202F2027FC27242724202F222121205048FE40FC44FC44FC4408FE0808281089 +:2098E00008087F08087F41823C04080F7808291220202020FC2424242424244444842810DD +:2099000010101310FD1111151931D013101050202824FE20FC24FC24FC2408FE8848481813 +:2099200010103C2141BD1111FD11111115191101202040FC04040404FC0404040404FC047E +:2099400010103F4885100949212505097111111140407E902840FC040404FC040404FC047B +:2099600008080813123232529312121212121312404080FC04040404FC0404040404FC04C6 +:2099800001021F101F101F01013F2121212101010000F010F010F00000F808082810000050 +:2099A00008103E22322A2AFE22322A2A22424A84101020FC84848484FC8484848484FC8475 +:2099C00000784B48487B4A4C4978484B484848982020FE2020FE0204F81020FE2020A04097 +:2099E00000784B48497949494979484B484848982824FE20FC24FC24FC2408FE8848481843 +:209A000002825F02825F50202F41C2435E424A041010D0103ED252921212129222224A84DF +:209A20000020101382424A0A1312E22222222302404080FC04040404FC0404040404FC041D +:209A400000F808484848497C04041CE4440428130888502050880008888850502050880650 +:209A600010101710FC1312161B32D213121252224844FE4040FC4444FC4444FC44445408AC +:209A80000202020202020202020202020202020200000000008040201010000000000000A6 +:209AA0000000F790909392929392F293020202024844FE4040FC4444FC4444FC4444540834 +:209AC0001008007E0204081A2C4A0A080808080840404040406050484444404040404040E0 +:209AE0001010111111FD111111101CE3400000002040FC04FC00FC04FC2020FE202020207E +:209B0000007F000001010305091121418101010100FC808000004020100804040000000040 +:209B2000020202FF0409113F5191111111110101000000FE000000F808080808281000004D +:209B4000010111111111FF010111112140031CE00000F8000000FE0000081020C00000004E +:209B6000203F488527101382434A0B12F0272221407E9048FC40F848F848F84810FC10300B +:209B800010087F002112FF00003F2121213F2100003EA2242428E424222222342820202080 +:209BA00010101013185451519315111111111010404040FE80A020FC242424243428202022 +:209BC00020202724FA23242A35E2242B2022A4408040FE0224BCA4A810E804FA404844C095 +:209BE00000442B1029488B0819294989090951212020FE20FC20FE00FC04FC04FC041408B6 +:209C000008087F0808FF1008FF102966A22930204048444440FE40444444282A122A468225 +:209C200008080808FE08181C2A2A48880808080808080808FE0818182828488808082810C8 +:209C400000000000FF010202040408102040020180808080FE80808080808080808080007F +:209C6000007C445455545454545454112824448010101010FE1030305050901010105020E4 +:209C800000007B484A7949487B484848794A0400083CC04424280020FE70A8A8242220209B +:209CA000007C4544457C10105D5050505DE20400083CC04424A88020FE70A8A82422202036 +:209CC00000003F02110908017F0305091121C10110F8000010102000FC804020100806005A +:209CE00001077808442520047F0C1615244484040084048890220204881022028408106029 +:209D00000808FF0800003F1108017F050931C1012020FE2010F800102000FC402018060043 +:209D200004FF04101E2254281720DF011121450240FE4080F8885020D806F00010080400E8 +:209D4000080F287FA1173ACD3FC80F080F080A0C007808281028C460F826E020E8D0300829 +:209D60000204081F027F081023CC010618000778004020F000FC20900846801020C00000D6 +:209D8000003F0102FF040831DF11111F11017F2000F80000FE402018F61010F00008FC04F8 +:209DA0000000FC20213C444764940808102043805048405CE0405EE044483022528A060250 +:209DC0002121212F32AAA5A7A121212F2521212100021CD010101ED41414D414142424447F +:209DE00020202133A8A7A1A22C23202023202027809008FC40FE1048861020C40830C00008 +:209E00001010101055595191111111292545408020202020242424242424242424FC040028 +:209E20000808FF080902040830CF0808080808072020FE202080402018E62020A84808F83A +:209E400010207C44645556FC446454544444548820205050880402F88888A89082827E0023 +:209E6000010102040830C00F080808080808070000008040201806E02020A0440404FC0096 +:209E80000040202102844B421222E222222221004040A0100804F210101050200404FC00BF +:209EA00004FF04001F50577517F457559527204040FE4824FE20A024A4A8A81012AA468279 +:209EC00023222223F827242C37E02F212224B840F80808F800BCA4A4BC40FE605048464068 +:209EE000101096555810FC3339555591111112141050507C9010FE007C44447C4400FE0078 +:209F000010101710FB12333A57509111111111119090FE90FC94FC94FC00F808F808F80829 +:209F20000404FF043F243F243F001F101F101F104040FE40F848F848F800F010F010F0104E +:209F40000404FF04001F101F101F01FF010101014040FE4000F010F010F000FE00000000C9 +:209F6000003F202F28282A2A2A2A2A222544489000FE0084A4A4A4A4A4A4A4240484940888 +:209F800010103F488501FF013F2123250911610140407E900800FE00F808885820100C00C0 +:209FA00010171424256565A5252525212222242804C44454545454545454540484441408FA +:209FC000001E1212121212FF121212121212264100784848484848FE484848484888A810B1 +:209FE00000271414854545151525E5212222240804C44454545454545454540484441408AA +:20A00000003F20203F20202F20203F2122444F8400FC0404FC0000FC0000FE001008FC0428 +:20A020000178484B4A7A1212535C515159E10101048800FE22AA7222FE00FC04FC04FC04B7 +:20A0400020202720F82F202936E424272424A744083CC04040FE40405C44445C4444FC04A7 +:20A06000003F10121109080404020102040830C000F01010202020404080008040201806E6 +:20A080000808FF0A0204FF0810305390101017102020FE200000FE004040FC404040FE009A +:20A0A0000808FF080902040931DF0109112105022020FE202080402018F60020100800007A +:20A0C00001017F050931C11F101F101F1000FF000000FC40201806F010F010F01000FE00FB +:20A0E0000000FB2020417A49C9494949794803002020FE70A82422FC04FC04FC0400FE001F +:20A1000010101310FC1010151A31D010111250208888FE88A850882422FC20A82422A040C7 +:20A12000017F40901E2254281720DF011121450200FE0284F8885020D806F0001008040025 +:20A140000408102FC40408106001012121213F00402010E8262020A0400000080808F8081A +:20A1600008047F01013F0202FF0408172040801F2040FC0000F80000FE0000F8808080FC28 +:20A18000002010130204F0131010101714181000402020FE020438C040407EC04042423EB4 +:20A1A00010101111FD1111151931D11111125224081CE0000000FE101030181412101010A4 +:20A1C0000808282E28282EF00101FF050931C101808890A0C084847C0000FE4020180600B1 +:20A1E0000C30C2144930C81424CC1425C404281010101010FE103030505090101010502051 +:20A2000021212224FB22222B30E126202021A04000F01020FC4444FCA0221EC03080601074 +:20A2200010101113FC1711121C33D01013105027809008FC40FE1048861020C40830C000BF +:20A240001110107D555555557D5110141DE44000048850FC2424FC2424FC2020FE202020CB +:20A260002121223C4B528223202126202831200000F01020FC4444FCA0221EC0308060109C +:20A28000012112140302F213101116101419100000F01020FC4444FCA0221EC03080601088 +:20A2A0002020274455F5252545F5450435C808134020FE00FC2424FC2424FC20FC2020FE88 +:20A2C00020203B204178A322FA2222222A3424084020FC000890FE00000000000000000089 +:20A2E00002017F000804043F20202020204040800000FC00202040FE000000000000000073 +:20A3000020170044424F494F494F415F4141404000FC044484E424E424E404F40404140887 +:20A3200008FF00FF81BDA5FF007E427E427E00FE007E10207C4454545454545420284482C5 +:20A340001F10101F10101F003F20203F20203F20F01010F01010F000F80808F80808F808E3 +:20A3600001452911294989081B2A4A8B0A0A5322F80808F80808F800FC0404FC0404FC04A7 +:20A380002023202020F923212121223AE448010200F020408000FC24242424444484281070 +:20A3A000011109017F40801F00007F0408103F1000102000FE0204F00000FC002010F808E9 +:20A3C0000111097F409F101F013F212121210101001020FE02F410F000F8080828100000AB +:20A3E00008080808080908FF0A090808090A0C0800102040800000FE0000804020180600EF +:20A40000080A091017343851901017101112171240485040FE0204F00000FC801008FC048A +:20A42000003D2424243C2524243C25252644548900F810204080FE9292921222224294082D +:20A44000003F202020202020202020202040408000FE00000000000000000000000000005F +:20A460000849292A087F41415D5555555D4145422020203E444444A428281010282844821A +:20A480001011107C54547D5454547D541010111000F810204080FC54549424244484281074 +:20A4A00001017949494949484B4A7A4B02020302F80808F80808F800FC0404FC0404FC0442 +:20A4C00009090911113131509312121312121312F80808F80808F800FC0404FC0404FC046A +:20A4E0000809087E0808FF0828282E2828584F8000FC4444449408FC848484FC0000FE00D3 +:20A5000010101010FC1011151A30D01010105023202020A8A4A22220242428081020C00014 +:20A5200010103C2040BC1111FE10101014181003202020A8A4A22220242428081020C0001C +:20A540000808FF087F417F417F4908FF08080809003EA222223E2222223E22A242428A0498 +:20A560000202EFA2A2AFA8AFA8AFE2A21F020202003CA42424BCA4A4A4BC2424A444548806 +:20A5800001412721018744571427E1212F212101001ED21212DE52D252DE1212D2222A4493 +:20A5A00008112211083F213F213F01FF050931C18810201088F808F808F800FE4020180684 +:20A5C00000007849494A4A4C48487848000001064040404844424248484810102040800092 +:20A5E00010101010545851911210102824444083202020A8A4A22220242428081020C00010 +:20A600000202027F040911213F0101FF01010101000000FC00000000F80000FE0000000040 +:20A6200010101011FD1111151931D111111157202020202020203C20202020202020FE0006 +:20A6400022212722F42F202734E724272424A4450808C8109ED46494949494888894A4C255 +:20A66000243F44FF043F2425001F013F017F010304A424A42484948820C000F800FC0000BD +:20A68000101222429212236EA2222223222020210000FC242424A4242424A424444494080F +:20A6A00002211712844F40171427E427242424050808C8109ED46494949494888894A4C255 +:20A6C000111111117B1111333B55559911111111001E1212D41418149252121A14101010FA +:20A6E000003F2121213F202020203F2121213F0000FC000000F808080808F8000000FC0010 +:20A70000003F20202F20203F242424244445860400FC0000F80000FC8088502010080600E3 +:20A72000010109091121410001013F010101FF0000002010080404000000F8000000FE0019 +:20A740001F101F101F003F202F203F2928484A8CF010F010F000FC00F800FE089060180628 +:20A76000101010131A5450509010101111121418404040FC44484040A0A0A02022221E004E +:20A7800000201312844041111121E121222224080000FE020400F0101010101212120E0042 +:20A7A000007848575061514A4B48695142444040404040FE80202020FC2028242222A040B9 +:20A7C0000808087E0809FE0828282E2828584F802020505088244290204488102040FE001F +:20A7E000201000FC09101034599414101010101010101010FE101010109090101010502041 +:20A8000011101312FC1010141930D1101310502024A8FE02F888F80CF020FC20FE20A0408B +:20A82000081CF01011FD12303854519112101010808080FE02042020A8A424222220A0407C +:20A840002020202724FC24272424243CE6490810282420FE202024A4A4A8A890922A46829D +:20A8600010171012F91235385752921312111F1020A4A8921408F402F80808F80810FE0051 +:20A880000000003F2020203E222222222A444081504840FE4040444444282812324A86029C +:20A8A000001F1010101F00007F01013F0101FF0000F0101010F00000FC0000F80000FE0067 +:20A8C000003F017F0109F90939CB050931C10101F80000FC00243822229E402018060000F7 +:20A8E000081DF11111FD1030395454911010131000FC040404FC0000FE2020FC2020FE00B2 +:20A900001023408911315191171001084848870000FE20203C202020FE0000849212F000E0 +:20A9200000271012814255181322E22322212F0020A4A8921408F402F80808F80810FE00CC +:20A94000004020270404E4272424242C36290810282420FE202024A4A4A8A890922A4682D4 +:20A960001F000001790F09111721214F81010502E040800428F02010D00808E40200000032 +:20A98000032212120300F7101013101017284700F8080808F800FC4040F84040FC00FE00A5 +:20A9A00000F809494949497C07041DE5440428102020FC24FC24FC00FE8000FC0404281033 +:20A9C000081DF01011FC10303B5454901010101000FC202024A4A820FE20202020202020A8 +:20A9E000000079494A4C49484848784902020100808000FE0000F808106080000202FE0028 +:20AA000000001F1292535519315F9111222244888040FE0000BC242424E42424A4BC2400DA +:20AA200010101011FC1013101833D01010105020202020FC2020FE0808FE0888480828102B +:20AA4000003E223E223E00FF08082F2828584F8000404044485060404444443C0000FE0041 +:20AA6000002012128242531E1222E222222221004040405868C84848484858420202FE00BC +:20AA8000002111110101F111111212141028470000F8080808F80820100804040000FE0059 +:20AAA00000F80809097941434179090909095020202020202C3464A4243428222202FE008D +:20AAC00000F808494949497F05051DE545052810202020202C3464A4243428222202FE0099 +:20AAE00000FF24243C24243C24242EF4440405041010109090909E90909090909090FE0028 +:20AB0000010111111111FF002121222428203F000000F8000000FE00080888482808F808DB +:20AB200010101122256060A32C2021262020212E8080F81020C090207C84089060408000C8 +:20AB4000001F101010101F10101010102020408000F808080808F8808080404020100806D9 +:20AB60000101013F0101FF040424244488081120000000F80000FE404048444242404080B7 +:20AB8000101110FE1110FC44452828111824438000DC444454CC44CC544444548800FE0036 +:20ABA00000001F1010101F10101110102020408010F800000000FE4040C0605048404040D8 +:20ABC000101011115559519111111028244542840000FC0404040404FC04009088040202EA +:20ABE0000201FF040408103F04040404080810600000FE00002010F8484040404444443C2E +:20AC0000004020200704141424E427242020200040404040FC4444444444FC44404040403E +:20AC20000101013F212121213F21010101017E00000000F808080808F808001008FC04003C +:20AC40000121213F02017F409F007F0111214502000808F80000FE02F400FC001008040004 +:20AC600002017F40840404FF04080810102041860000FE02241010FE808890A0C282827EAE +:20AC800010101010FD1111151931D1111111512120202020FC24242424FC24242424FC04E8 +:20ACA00000FE2828FEAAAAABAEC282FE8282FE83044454545454DC7454545454545484046C +:20ACC0000000FBA8A9A8FBA8A8A8A9F98A0400002020FE20FC40FE4888FE0848280828103F +:20ACE000007C4744457C13105C5051515EE400002020FE20FC40FE4888FE084828082810BB +:20AD0000081DF11111FD1131395555911112121400FC24247424FC0474545474040414086F +:20AD20000E780808FE192C4A88090A0128284807202024A4A82050508804020088A424E087 +:20AD4000203F4885017F023F04FF081F24428000407E900800FC00F800FE20FC2020A04072 +:20AD60000909091117313151911111121214181000000000F01010101010101212120E0036 +:20AD8000101322224AFA122342FA42021AE2420400FE2222FA2222FE02FA8A8AFA020A0479 +:20ADA0000001F79191F19791F3939595F991010188C808082A2AAC480888541414242442E6 +:20ADC000003F02020202023F040404040404FF0000F01010101010F0101010101010FE0046 +:20ADE00002043F203F203F203F0101FF020418E00000F808F808F808F82010FE8040300ECE +:20AE0000201001FC0810103458941410101112140000FC44444444444444448484042810F2 +:20AE20000101212121213F010101414141417F00000008080808F808000004040404FC0497 +:20AE400020272424F72425756DA5A42524242B2000FE0004E404DE4444D40C4484E4140848 +:20AE6000003F203F202F2929292F202926435C8800FE088808087E08084828080888281039 +:20AE800000784B4848791010535C50515AE400008888FEA822FA2428FE40FC84FC84FC845C +:20AEA00020203B22427AA322FA2322222A3326000808C8485E4ACA4A4ACA4A4A6AD2122698 +:20AEC00020203E42850AFE02027E020202FE0200504880FE9090FC9090FC909090FE8080A1 +:20AEE000402F298A4A4C0A292949CD4A484948081010282844BA1010FE10585492125020A1 +:20AF000000784851526550484F486A52444841404040A01008F64040FC40504844444080A7 +:20AF200008087E081C2AC8007F011111112947802020FC2070A82400FC0400F80000FE003C +:20AF40000000FD1111213D6464A525253D252100202024242424FC20202424242424FC047A +:20AF600010101824246160BC24252624252624202020FA2428FE2040FC44447C44447C4486 +:20AF8000013F010F0809097F087E083E222A2AFF00F800E0202020FC20FC20F888A8A8FE49 +:20AFA00020202720F923202937E027242724A7448040FC8008F06084FE02FC44FC44FC0475 +:20AFC00020207849917D55557D55547C5457458C202020FC24242424FC24202824FE020022 +:20AFE0001010101E1222225294140808142340804040404060504844444040404000FE002E +:20B0000020242424F7202F2030E724242424A44440444444FC00FE4080FCA4A4A4A4A40CAD +:20B02000101010101010101010101010202040800484848484848484848484848484040490 +:20B0400002017F4890003F0010203F01061861000000FE221400FC404040FE4040404080FA +:20B0600021212223F82720716EA0A1262021262000F808F010FE804468B02868A422A0402D +:20B0800008080813103037509113101110101010404040F84080FE8000F80810A040202093 +:20B0A00008103E22322A2AFF22322A2A22424A840078484848488E0000FC84848484FC8407 +:20B0C0000004F49497909F909097F4940404040440444444FC00FE4080FCA4A4A4A4A40CCD +:20B0E00001013F21213F01017F41417F410101010000F80808F80000FC0404FC04000000C4 +:20B1000000001F10905152143B529212222242818040FE40A0100806F0101050200404FC41 +:20B1200002017F4892043F2223242A2122243F200000FE221400F808C84888088808F808B3 +:20B140001011107C575455555555555C1110131020FC8850FE00FC24FC24FC20FC20FE00E6 +:20B1600001003F2020202F2021222224485080000080FE008080FC80C0A0A09088868080A7 +:20B18000201310405F4048484F40405F4041404000FC040484848484E42424A424449408E6 +:20B1A000080814122140BE2222222A2420201F000404042424A424242424242484849408B3 +:20B1C0000000784849494A4C4848784901020408808080FC0408404040A0A0101008040271 +:20B1E000101010125254599010102828244441824040407C84882020205050508888040235 +:20B2000010101310F817121A37D21217101057201078C04040FC4848FE4848FC4040FC008D +:20B2200020203920407BA121FB21212328302300083CE02020FE2424FE2424FE2020FE00F1 +:20B2400000003F01017F0909FF09097F01013F0010F8000000FC2020FE2020FC0000F800D5 +:20B2600001017F013F02FF08102FC8080F08080F0000FC00F800FE2010E82620E02020E077 +:20B2800010101310FD10333855529010101010102020FE20FC40FE8804FA8888F88888F83E +:20B2A00000FE2828FEAAAAAAAEC282FE8282FE822010FE007C447C007C0810FE1010502044 +:20B2C000003F202F203F24242526202F48488F0800FC00F800FE8850300E00F80808F80868 +:20B2E0000020171083424B081310E027202021008040FC00F808F800F81020FC404040804C +:20B300001010202348FA122242FB400018E04000404040FC4048484848F8484042423E0041 +:20B32000017F013F02FF083FC80F107C547C12FE00FC00F800FE20F826E020F8A8F824FCDA +:20B3400000EE22AA66AA01247FC87E487E487F4120282424203EE02424282810324A8602F1 +:20B36000101020204BFA132243FA400718E0400040407E40FC04FC04FC4440FE404040407B +:20B3800000001F10915155153555951525255E888040FE0010101214D810101012D2120EBE +:20B3A0000808FF0840202009121420E02021222C2020FE208080FC04484040A0A0100806B4 +:20B3C0000100F027214172D25457515272540700088890FE08081094A438081010A4BC84DA +:20B3E00014141454555E5454545454545D76C400504880FE9090FC9090FC909090FE80807F +:20B40000081C701110FC10117C444544447C4400402020FC008850FE2020FC2020202020DF +:20B420000804FF1010247810247E0201282848072040FE202048F02048FC040088A424E083 +:20B440000141210A14E02126007F080F091016180000FC4448A0100C00FC00E020A4241C43 +:20B46000002310100700F013121212131418100000FC0404F40404E4242424E404041408A2 +:20B480000404042424272424242424242FF0400040404044485060404040404242423E00FA +:20B4A0000808FF08087F49494D4A1C2A49880808040484242424242424242424048414082A +:20B4C000007C445454545454545455122825448000FC8484FC8484FC40FE2A4A92224A84B0 +:20B4E0000040202001090A1410E0202121222408808080FC0408404040A0A010100804024E +:20B5000000FC48497949497948484C79C9090A08884850FC040404FC20105442424A380033 +:20B520000404FF04081F2A440A112204014848874040FE4000F848488808A810008412F2FC +:20B5400004087F42424748524140414658407F400000FC0404F41424448444240404FC0434 +:20B560000808081F1222429C0609102142040810000000FC444444444484C42414042810D8 +:20B5800008080808080808080814121220214284202020202020202050505088880404021A +:20B5A0000808080808080814122220418200FF002020202020202050508888040200FE0095 +:20B5C000004027200300171122E52023202021064040FC40F880FC1008F640F840A010089A +:20B5E000101195555911FD31395555911111171000F8080808F8080808F808080808FE00B5 +:20B6000000FE2829FEAAABAAAEC282FE8282FE82484848FE4848FE00FC8484FC8484FC847E +:20B62000203F48852010FE21203C252425445489407E90084040FE2040FC2020FE50880658 +:20B64000080B0A1212323350901212121215181000F808080808F84040407C404040FE00D5 +:20B6600000784B4A497A1111515C53525BE200004020FE8A2422FC24FC20FE22FE2220205F +:20B68000203F489F101F101F101F027F041AE40F407E90F810F010F010F000FC40304EE065 +:20B6A00002017F4891013F213F017F417F4101010000FE221400F808F800FC04FC040000E0 +:20B6C00010121310FC1113151931D111111151212022FE9088FE1010FE1010FE1010FE0080 +:20B6E00001417F09081F10305F90101F10101F100004FC0080FC8080F88080F88080FC0044 +:20B70000080A0B101031335591111111111111112022FE9088FE1010FE1010FE1010FE007B +:20B72000003C2425263D2525253D25252545558A4040FC0408FE007C4444544842423E00FA +:20B7400000001F10905751113254901F202040808040FE0040FC1010A84440FE40404040F8 +:20B76000101095545810FD3238545590101010104020FE00888854220020FE2020202020D6 +:20B7800000201710814142141020E720202020008040FC001010A8440040FE40404040406D +:20B7A000007E22121A6202017F08142201FF010100FC442434C40400FC20508800FE000047 +:20B7C00010101010FD103038555490101010101010101010FE1010101090901010105020ED +:20B7E0000404FF080813103050971010101011100000FE0000F8102040FE40404040408073 +:20B8000000000000FF000000100808000000010040404040FE40404040404040404040800A +:20B820000000FC1110203C6564A424253E242100844448FE20FC20FE4080FE101010FE0022 +:20B8400020232223FA23202F34E72427242FA04000F808F808F800FE80BC9494D48894A26F +:20B8600011101013FC1110171831D11214185320088890FC40F840FE8000FC202020FE0019 +:20B8800010101013F810171831D1111111115121888888FE8888FE00FC0404FC0404FC04CA +:20B8A00020202222F225282030E720202020AF40404048484854E24040FC40404040FE0017 +:20B8C000212139274179AF20FB2222232A322302101010FC1010FE00F80808F80808F80800 +:20B8E00021212721F820212A35E020232222A3421010FC1040A01008F60000F80808F808B8 +:20B90000002010100700F010101112141028470040404040FE4040A0900804040000FE005E +:20B9200010103F2845820C30CF001F1010101F1040407E9008806018E600F0101010F0109C +:20B9400000001F119157511031529C13222243828040FE1010FC50A010E806F80808F80863 +:20B9600010101310FC1010141830D010101050200000FE2020202020202020202020A0405E +:20B980000101010101FF010102020404081020C00000000000FE00008080404020100806E1 +:20B9A000001F1010101F01017F0305091121C10100F0101010F00000FC8040201008060089 +:20B9C00000FF0202040708102442010001020C7000FE000000F8081010204080000000005D +:20B9E00008080F101330375192141211121411104040FC40F880FC1048464850484440808B +:20BA0000087F08FF007F497F497F227F22FF2241202824FE202024242428281012AA46826A +:20BA200009097F0909007F41811F1111111101012020FC202000FE0204F0101050200000BD +:20BA400000FC2020203C45446494080810204080202020404884FE8200FC84848484FC8455 +:20BA60000808081010373050901010101010101090888880BEC0804040402022120A060293 +:20BA8000081030D71010001F101111111204186090887EC0221A06F01010101010C03008A7 +:20BAA000081030579010101201FF050C34C50604A090BEC04024140C00FE008850300E00CB +:20BAC00008081023480817305097101211111010404040FC4040FE1010FE10101010502039 +:20BAE000002013100700F31412111214112847004040F848FE48F844485048444080FE0008 +:20BB0000020408103F001F10101F01084848870000002010F808F01010F000849212F00002 +:20BB200000FC484B7A4C487848484C79C90A0C08404040FC44484040A0A0A02022221E008A +:20BB400010101111FD1111151931D111101053200000FC040404FC040404FC040000FE00A2 +:20BB6000001F101012111110FF1010102020408000F0101010101010FE1010101010502005 +:20BB80001008043F21213F21213F0101FF010101102040F80808F80808F80000FE000000CE +:20BBA0004122147F49497F49497F0808FF080808003E22242428242422222234A82020208C +:20BBC00011101011FD1111151931D01013105020048850FC2424FC2424FC2020FE20202034 +:20BBE000003C2424243C2424243C2424244455880000FC848484FC848484FC840000FE009E +:20BC0000001F101010101F101010101F0000FF0000F010101010F010101010F00000FE00FA +:20BC2000203F409F007F04240B106004240B106000FC00F000F01090109050128A0A864227 +:20BC400008080B121232335292121312101017100000FC040404FC040404FC040000FE00D0 +:20BC600011101011195551519111101013101010048850FC2424FC2424FC2020FE2020206F +:20BC800000221214804146101022E2242021220C40444448A010084440484850A0100806B4 +:20BCA00000402F210204EF212929252A33240810081C701010505C505050507C00807E00B4 +:20BCC00001F8080909794141417908080B085020048850FC2424FC2424FC2020FE2020200B +:20BCE0007F011111112947811F11111F11017F20FC0400F80000FE00F01010F00008FC0491 +:20BD00000121110909017F0000003F0000007F00000808102000F8080808F8080808F80840 +:20BD200010121111FD1017101830D31010105720404444444840FC040404FC040404FC0425 +:20BD4000011109097F40801F10101F04040830C000101020FE0204F01010F0404042423E9C +:20BD60000808FF0800231010804B4811E22421222020FE2000F0204080FCA424448428100A +:20BD800010111010FC10333854509110101013102024A4A4A820FC040404FC040404FC04FF +:20BDA00000003F020202020202040408081020400000F808080808080808080808085020F0 +:20BDC00020202322FA22222A33E024242720A0404080F80888481800FE829292F202140898 +:20BDE000007D4445447C1011115D5151515DE1011EE02212948020CE0202CE020202FE02B0 +:20BE000010101F22226467A121272121212E24200404C4141494D41414D41414C4041408B2 +:20BE200001021F10121110101F0222223F0000000000F01010502000FC042424E404281001 +:20BE4000201013F80910133854941111121410102020FE20FC40FE4888FE084828082810D5 +:20BE6000003F20203F20201F0000FF080404000000F01010F00404FC2020FE202020A04014 +:20BE800000FF08102241FF0808087F08080FF840048404242424A4A42424242404841408C7 +:20BEA000081DF01110FC103139555591111111111EE02212948020CE0202CE020202FE024B +:20BEC000101010101B565352931210171010101040407E40FC04FC04FC4440FE4040404044 +:20BEE000022110170003F2131213121312284700081000FC80F808F808F808F80800FE0093 +:20BF00004020091224E020232C003F242424FF008080FC044840A0180600F8484848FE0075 +:20BF200010102F4097142467A02F2020252529204040FE40FCA4A4FC00FE4024220A08F80E +:20BF4000080B12234A0B1033509710121110101000F808F808F800FC10FE10101010502005 +:20BF60001010207E424243427E424242427E42004040407C84840444242404040404281098 +:20BF8000007B484948791214515D515159E0070010D254488A04FA00FC0404FC0488FE008E +:20BFA000101013105458509010101028244440800000FE2020202020202020202020A040F4 +:20BFC000003E022414081720DF10101F08047F008090A4485020D008F61010F02040FC005B +:20BFE000203F4885013F0101FF00007F08040400407E900800F80000FE0020FC2020A040BD +:20C000000007F09291F29598F3929293F2910F0020A4A8921408F402F80808F80810FE0085 +:20C02000007E042B102FC80F047F000F0808106090A044A810E826E040FC00E02022221E73 +:20C04000007E0202422414080814142242800000007C444848504848444444685040404054 +:20C060001011111111FD11111013101DE141020400FC0404FC0404FC00FE20203C20A07E19 +:20C0800008080B12123232539212121212121312083CE020202020FE201010120A8A2612D9 +:20C0A00000201711804744151425E525252424048040FC10A0FC44F444F41414F404140850 +:20C0C000004020270404E4272424242720508F00404040FC444444FC444444FC0000FE00EA +:20C0E000040E380808FF08083E222222223E22012020203E444444A428281010284884023C +:20C1000010103F2845813F2121213F2121213F2040407E900800F8080808F8080808F80879 +:20C12000004428102949890A1828488809095224404040404444485040A0A0901008040298 +:20C1400000201113844041161027E022222421008080F8089060984640FC40484444408006 +:20C16000007E22121A6202091F305F901F101F1000FC442434C40400FC80F880F880FC0022 +:20C1800020202320F84B4A4A4A925222324A4A824020FE8850FE22FA22FA8A8AFA020A0423 +:20C1A00010101312FE1212131A32D21212125322083CE020202020FE201010120A8A26127C +:20C1C00001003F202027242424272424244546840080FE003CC0404040FE2020120A4622AE +:20C1E0001010101111FD11131111111DE1410000202020202C3464A4243428222202FE00AE +:20C2000008FF0A013F08047F41811F111111010120FE2000F82040FE0204F0105020000022 +:20C22000203F48853F01013F21213F030519E101407E9008F80808F80000FC04042810003C +:20C2400002013F0008047F41811F1111111101010000F8002040FE0204F01010502000000E +:20C260000804047F01013F21213F030509116101202040F80808F80000FC04041408000049 +:20C28000012013100003F212131011121428470010A0F84848F84040FCC444544840FE00FC +:20C2A0001010212444F8132244FD41011DE140004020FC008850FE2224FC2424342820208F +:20C2C00008087F083E223E223E223E227F14224100FE10207C44545454545454282442825B +:20C2E00010101312FE1212121A32D212121454284020FE0020203E2020FC84848484FC844B +:20C3000000201710834243121322E3222F2122044040FC40F808F808F808F808FE10080436 +:20C320000000FC1111213D6565A525273C242102505050FC545454FC545454FE00880402D7 +:20C340000202020302023F2020203F0024224280000000FC0000F0101010F00088444404CA +:20C360000404043F2424243F242424FF04081020404040F8484848F8484848FE402010084A +:20C380001010FE107D10FE007C447C447C44554A2010FE820400FE1010909E9090D03E00D7 +:20C3A00008087D080C1968082811013F0101FF004040F84848C84AAA860200F80000FE0097 +:20C3C0000101013F2121213F2121213F21010100000000F8080808F8080808F80A0202FE90 +:20C3E00010101724246464A724242424242724200000FC44444444FC4444444444FC0400D4 +:20C400000808101F2040BF24243F24243F200000000000F8080888888888888888885020D8 +:20C4200001003F202020202020272424444487040080FE808080FC8080F808080808F80868 +:20C44000101013121A56525292121212121414184020FE0020203E2020FC84848484FC84C1 +:20C460000804FF043F283027203F017F020418E02040FE40F84838C808F800FC8040300E3A +:20C4800000201312844043101021E121222224084020FE020400FE2020203C20A0603E0041 +:20C4A000003F21213F202A2A3F2A2A3F204A912100784848488600FC4444282810284482B2 +:20C4C0000001FD1111213D6565A525253D22020400FC24247424FC04745454740404140830 +:20C4E000000378484848484848494A784800000000FC04040414244484040404040428106A +:20C50000007F49495D497F415D55555D414145822824407EC8487E48487E4848487E40407B +:20C52000004724240504141724E525252524240800FC4444F44444FC04F41414F404140840 +:20C54000003F000000000001020408106000000000F8080808488808080808080808502095 +:20C5600010101010FD11151931D110131010502020203E20FC04FC04FC2420FE202020202E +:20C58000001F1010101F01013F2121212121010100F0101010F00000F808080828100000ED +:20C5A00010103C2041BE1011FC10101014181000404080FC0404040484444404040428101B +:20C5C000004724240504E4272425252D3524040800FC4444F44444FC04F41414F404140888 +:20C5E000007C4545457D1210115C5050505CE10220202020FC202020FE2050508888040205 +:20C6000004081824030C32C71A011E010E00033C4020508800C030CE40A0788890608000FD +:20C620000002FA2722427ACA4B484F4879420C00909090FE9090F000FC40FEE05048464048 +:20C64000202121FBA9A9A9A9F9A0232838E94600484848FE48487800FE20FE70A824222016 +:20C66000002212130204F0171010101112284700404040FC404040FE40A090080800FE00AC +:20C68000004222270202E2222320272029322C00909090FE9090F000FC40FEE05048464000 +:20C6A0001F04030C7E221C6200FF901F101F10FFE0408040FC44384400FE12F010F010FE94 +:20C6C000007F010101010101010101010101050200FC0000000000000000000000000000CC +:20C6E00000007B484878484878484848784800000000FE2020202020202020202020A040D9 +:20C7000000007B484848484848487848000000000000FE2020202020202020202020A040A8 +:20C7200010103D2040BC1010FC101010141810000000FE2020202020202020202020A040BA +:20C740000001FE1011111111111111111050210200FE2040FC04242424242444508804028B +:20C760000F080F484F484F407C0404FC24244484E020E024E424E4047C40407C4444444419 +:20C7800020203B224478A320F82121212A3224084020FE020400FE2020203C20A0603E003E +:20C7A00002017F4080003F0101111111112947800000FE020400F8000000F8000000FE00D0 +:20C7C000002013100000F01010101010141810000000FE2020202020202020202020A0405C +:20C7E00000003F01013F010101FF020408103F1010F8000000F8000000FE00002010F8081C +:20C800000202027F040911213F01091121410502000000FC00000000F80020100804000061 +:20C8200004040F102844030C30C00700000E01000000F01020408060180600C02000804052 +:20C8400008FF081F017F011F111F111F013F01FF20FE20F000FC00F010F010F000F800FE5A +:20C860002127212330AFA0A3A22322232027202F10FE10F840FC40F848F848F840FC40FEE6 +:20C8800000007C000100FE2020204844FD45020440404040FC444444448484840404281011 +:20C8A00010101017F811313A5750911112141010404040FE80202020FC2028242222A04004 +:20C8C00010171424256464A5252525252424242400FC0404F40404F4141414F404041408FB +:20C8E0002027242435ACA4A5A52525252424242400FC0404F40404F4141414F40404140893 +:20C90000004020270009091213E0212122242000404040FE80202020FC2028242222A040A7 +:20C9200000271414854444151525E5252424240400FC0404F40404F4141414F4040414088A +:20C94000011267444447444457600404040810600000DC4444C44444C41C40404044443CB7 +:20C9600010111010FC1110141830D310101050201010909010109090101EF010101010109C +:20C980000004020210080800007F0000000000004040404040404040FE4040404040404032 +:20C9A000007C454848504B4844454569524244482020FC202020FE2020203C20A0603E0058 +:20C9C000007F00001F101010101F00100804FF0000FC0000F010101010F000102040FE00B5 +:20C9E000002710100302F213101211171028470000FC0000F80808F8000810FC0000FE000F +:20CA000000001F10905750133252931021204F808040FE0000FC00F80808F80010A0FE00FE +:20CA200008087E090AFF08103F61A13F21213F2100BEA22424E82424222222342820202022 +:20CA4000080E08FF082A49081F101F101F101F1000FC444428102844F210F010F010F01050 +:20CA6000013F011F017F001F1211FF22213F000000F800F000FC00F01010FE1010FC106095 +:20CA8000101051507C5390101CF15013101010132020FC2020FE0294501090FE28448202C5 +:20CAA000004428112949890919294888080B5120202020FC24242424FC24202824FE0200E7 +:20CAC000002011100003F01010111013141810032020FC2020FE0294501090FE28448202A1 +:20CAE00020202320F8272020212B3521C10101014044F44850FE4080F80808F80808F80810 +:20CB000000007B48487F4848794B4D49794901014044F44850FE4080FC0404FC0404FC0407 +:20CB2000007C45545457545454555610282444802022FA2428FE2040FC8484FC8484FC8400 +:20CB400010101010FC1033385454901010101710202020202020FE20202020202020FE00F3 +:20CB600020203B22427BA222FA2222222A3424094020FE4848FE487800FC44482810688652 +:20CB8000003C2424243C2524243C242424445788202020202020FC20202020202020FE00DF +:20CBA00001003F22223F222223202F24424186380080FE2020FC2020E000F01020C0300E9F +:20CBC00000201714844744141425E424242828134020FE8888FE88F800FC84885020D806DD +:20CBE00010101011FD252525254929112A468408402020FE020202FE020000000000000060 +:20CC0000201111FD01088B88484951511DE1410120242424FC00FE2040FC54545454540CB4 +:20CC200020213C50901010FE101010282444418000FE0000FC848484FC0084444800FE0068 +:20CC400020233A22437AA222FB2222232E32220280382828A846007CA42428A810284482C6 +:20CC600006382020203C21203D20202CF020202300F8888888860000FC8488502050880631 +:20CC80000404554E447F444E55654444407F00010004784040407E48484848484888880810 +:20CCA000101322224BFA122243FA42031EE2420280382828A846007CA42428A810284482C6 +:20CCC0002121212322FE2B222223223AE2430202402020FE2020FC2020FC202020FE000043 +:20CCE000100804001F1010101F1404040808106010204000F0101010F05040404444443CB6 +:20CD0000007C44484850484844444469514244484040404040404040A0A0A0101008040281 +:20CD20000000007E02022414080814122240000010101010FE101090505010101010502063 +:20CD400022212F2027FC272027202139EF4105021010D010BEA4D414949414C8081414225F +:20CD60000000784B484A4A4A4A4B784800000000404040FC4048484848F8484042423E0017 +:20CD800000784B4849791111515D505359E000008850FE50FC548C7404FC08FE0888A81056 +:20CDA0001008FF007E427E007E04080FF80828112020203E444444A42828101028488402D8 +:20CDC000101110FE11555555557D11111418110200FE2040FC0424242424244450880402AD +:20CDE000007F41415F4149494F41414140407F4000FC0404F4042424E4141414F404FC0453 +:20CE000020203827407AA222FA23202028302000404040FC4048484848F8484042423E00C2 +:20CE2000003F203F202F28282F28282F48488F087C8080FC80F80808F80808F80808F808D0 +:20CE4000002312120302F21212121214142847001EE02020FE20FC84FC84FC84FC00FE00DF +:20CE600020272022F922242830E720222122A44800BC84940894A44000BCA4A42890A8463C +:20CE80000000F192959090939C90F1960000010E8080F81020C090207C84089060408000B5 +:20CEA000020207083804030C71020C3201010E700000F02040804080F80810204080000063 +:20CEC00001017F02040830C000FF0010080801000000FC804020184640FE4040404040807B +:20CEE0001011111111FD121413101CE14204000000F0101010104E40FC40E050484640401D +:20CF000010207C447C447D4645FC0C142546940800F8888888882620FE2070A8242220201C +:20CF2000000F0808081020C1017F03050931C10100E0202020201E0000FC804020180600DD +:20CF4000007C4444447C11125D5050505DE2000000F8888888882620FE2070A82422202044 +:20CF600008103E22322A2AFE22322A2A22424A84201010FE828440444850604242423E0017 +:20CF8000003E222222498808FF081C2A498808080404042424A42424A424242404841408F2 +:20CFA000101013101956555091111111111111114040FE80FC20FE00FC04FC04FC041408DE +:20CFC000007B4848514A48685041013F0101FF0020FE40FC84FC84FC848C00F80000FE00C9 +:20CFE000202023F8A8ABA8A8F8A0232838E8420110D8949490FE909494D89890AACA86029B +:20D0000010101310545754545454575C6400020110D8949490FE909494D89890AACA860266 +:20D020000436E52524FF24252536E6242A32A14010207C4464D4444C407E0202FA828A849A +:20D0400010111721216F61A121232D212121252228A4242020FE2024A4282810122A468250 +:20D0600010087F41101E22540814227FA2223E2200FE10207C44545454545454282442825D +:20D08000002010110103F5111111111115191101A0A0A0242428302060A0202222221E007D +:20D0A00010101310FC27242424482B102844840110D8949490FE909494D89890AACA868258 +:20D0C000007F0424141404FF000108484848870000FC4048485040FE000088841212F0009C +:20D0E000003F202027242424242424242444438000FE0000F0101010105020040404FC00BD +:20D1000020232222FA22222A32E222222424A85000FE0000F888888888A8908282827E0036 +:20D12000002312130203F113141A12131028470000F808F808F800FC44A404F41408FE00DE +:20D140000077555577007F00FF203F0101010A04003E222424282424A2222234282020208F +:20D160002020233C444BA020202023202830220110D8949490FE909494D89890AACA860271 +:20D18000003F21212F212224283F01084848870000F80808E808884828F800849212F000F1 +:20D1A000007F0101023F2424242424242424202000FC000000F888888888888888882810E1 +:20D1C0000808080808080808080808101020408040404040404040404040404242423E0033 +:20D1E000007F10101F10101F10101017F800000000FC1010F01010F010103ED01010101069 +:20D200000808081F102141810111112141810502000000FC040800000010080402020000AF +:20D220002023213D4549A121212121212B30200000FE080808F80808F808081EE8080808BA +:20D2400000271212834242131222E2232E20200000FC0808F80808F808080EF80808080880 +:20D260000000003F0000000000000000FF000000000000F80000000000000000FE0000007A +:20D280000000FF003F007F003F202424240A11602824FE20A020A020A09090908A0A068235 +:20D2A000011111223F0204070A0911102040031C00100800FC0000F8080810A040A0180660 +:20D2C000007F44447F00201000F010101418100000FC4444FC000888888888888808281054 +:20D2E00010103F2845880810305790101010111640407E9008A09080FC80485024548C04F2 +:20D300000808081010373050901010101011161090888880BEC0804444483022528A0602F3 +:20D3200000017E000201017F0000030C3048870010F80000000000F830C000000000FE00EF +:20D34000201700454549596F49494848494A484000FC04442404F4042424C4945434140816 +:20D3600000201010874040101F20E02122242F0440404040FC404040FE4080001008FC040B +:20D380000000FC111010107D101010101CE14000202020FC202020FE2020404884FE8200D0 +:20D3A00008FF08201712814752142BE22322232220FE2038C04850FC4804FA48F848F808B8 +:20D3C0001011117D555555555555555D1112121400F01010101090505010101212120E00E1 +:20D3E000003F110901FF09103FD1111F11111F10F800102000FE2010F81610F01010F010A6 +:20D400000EF19254FF3854827C54557C54547D4400DC444454CC44444CD4644444445488D8 +:20D420002422F9226472A9222501FF02040830C048883E88589C2A884800FE804020180647 +:20D440000001F921214179C9494949497A42040800F01010101090505010101212120E005D +:20D4600010113D2141BD1111FD111111151A120400F01010101090505010101212120E00D4 +:20D48000203F40BE2AFF4A7F04081F023F01152220203E48A828102846800010F8082010C5 +:20D4A000000F0808080A0908080810102020408000E02020202020A0A020202222221E0076 +:20D4C0001013101055595191111111292444418200FE2040FC0404242424244450880404DC +:20D4E00000003F20203F24242222212041428C3010F8000000F808101020408040201806DC +:20D50000002013120203F2121212121415284700083CC00000FC0488502050880400FE0019 +:20D520000404FF041009492125050971111110004040FE4000F80808082810020202FE007D +:20D54000007C4444545454545454541029254280040EF08080FCA4A4A4A8A8901028448293 +:20D56000004429112949890919294989090950200000F80808080808281000020202FE0037 +:20D580002020213D4549A1212121212129322204081CE00000FC444444282810102844826E +:20D5A00000201710804047101020E02122252800107880008040F810204080000000FC00C1 +:20D5C0001010101310FC10101010101CE1410204402020FE808080FC84848484040428101E +:20D5E0000808FF080A01FF0404070408081020402020FE202000FE0000F010101010A040EB +:20D60000020101FF040404070404040808102040000000FE000000F0101010101010A0403A +:20D62000003C2425243C2424243C24242444558A402020FE4040407C4444444484842810C4 +:20D6400002013F20203F21203F222223444488100000FC0404FC0080FC0000F80808281046 +:20D66000007C444B485048484444446851414244402020FE808080FC8484848404042810E1 +:20D6800010101011FC2424242448281028448102402020FE4040407C444444448484281044 +:20D6A00008080817113131519111111112121418804040FE000000F80808080808085020CD +:20D6C000002010170101F111111111151A120408804040FE000000F80808080808085020E9 +:20D6E0001010202744F8102040FC40001DE14204402020FE808080FC84848484040428104D +:20D70000201000FE20213E24242424244454890240404080FE088888885050205088040209 +:20D720000808FF0808047C04047C0404FC0404042020FE2020407C40407C40407E404040C2 +:20D74000040404FC0404047C04040404FC0404044040407E4040407C404040407E40404069 +:20D760000000F097909090939090F097000000009090909E9090909C9090909E9090909010 +:20D7800000FF000000000000000000000000000000C040444850605048442020120A06020E +:20D7A000003D2525253D2525253D25252545548800FC2424242424FC040000000202FE0092 +:20D7C000007F42427E42425E42427E4242427F0000FC40407C40407840407C404040FE00F5 +:20D7E000002010170000F01310101017181000009090909E9090909C9090909E9090909048 +:20D8000000007848484F484848484879490204084050484840FE4040A0A0A010100804028D +:20D82000003C2427243C2525253D252525445488202020FE2020FC242424243428202020E0 +:20D8400001003F2024282F2121222224244851860080FE809088FE00FC8488502050880696 +:20D8600001211117814147151527E12122222408202020F82828F82020FC242434282020D2 +:20D88000047F043F243F0810205F101111020C3040F848F840FC445408F0101010C03008EC +:20D8A0000808FF080004081020DF0404081021402020FE204040201008E620202020408079 +:20D8C00000FE2828FEAAAAABAEC282FE8282FE83082828284444827C2424242444449408CE +:20D8E0000000784849494A4D484848784901020410909088080404FA888888880808281075 +:20D90000203F409F007F00122140BF111111254200FC00F000F01010109050120A0A060264 +:20D92000000404081020409F040404080810214040402020100804E22020202020204080FD +:20D940001010202049F9122540F8400019E1420410909088080404FA88888888080828100C +:20D960001010101711FD11111110101CE041020C804040FC1010101010A0A040A01008062A +:20D9800008087E081C2AC90809111122040830C02020FC3068A42220201010A04020180679 +:20D9A00000211112824458131121E1212222240810101008080402F8080808080808502070 +:20D9C000101094545810FD32385454901010111210505050888804FA48484848888828107F +:20D9E00001017F02040830C01F11111F11111F100000FC8040201806F01010F01010F010DD +:20DA00000808081011313255901010101111121410909088080404FA8888888808082810E3 +:20DA20000408102FC40408106001084848488700402010E8262020A0400088841212F00035 +:20DA4000101110101B545051911111111110101320FC2088FE8800FC0424242424508804B7 +:20DA60000111097F050931C4043F0404FF081020001020FC4020184640F84040FE201008AF +:20DA80000101017F0101013F010101FF01010101000000FC000000F8000000FE00000000CA +:20DAA0000808087F0808FF0008087F08080FF040080808087E080848282808080808281044 +:20DAC00020232222FB2222726AA2A2232424283000F8080828A8A84848A8A82A0A0A0602F7 +:20DAE0001010107C555454577C5010141FE440004040FC885020D826F820F820FE202020F3 +:20DB000010101010555454575454545C670000004040FC885020D826F820F820FE202020B2 +:20DB200010103C2041BC1013FC101010171810004040FC885020D826F820F820FE202020DE +:20DB4000003F202028242222212122222448408000F0101050509090101090924A4A060256 +:20DB600000001F109053521332529212252448908040FE0000F80828A84848A82A0A0602E3 +:20DB8000101010105558509310101028274440804040FC885020D826F820F820FE20202032 +:20DBA000012113140001F610131013101710284700F8089060980640F840F840FC4040FE81 +:20DBC00000472020020A0A1310E020272020200000F01010101010FC040404F40404281082 +:20DBE0001014222148F8162242FA42021AE24508207C844830CE107C107C10FE1010FE00D3 +:20DC0000004322220302E2222222222B3424081000F8080828A8A84848A8A82A0A0A0602CD +:20DC200001017F013F02FF040931CF01013F01010000FC00F800FE402018E60000F800008A +:20DC4000003F20202F202824222122242840408000F80808C84848888808884A4A0A060253 +:20DC60001111112F216167A5292F212122222428202020FC2424FC2020FE22222A242020DA +:20DC8000007F000103050931C1001F1010101F1000FC8000006018040200F0101010F01069 +:20DCA000010101013F010101FF020404081020C000000000F8000000FE80404020100806E9 +:20DCC0000A09FF087F497F497F4910FF203E42862020A03E444444A4282810902828448209 +:20DCE000003C2424253C2424273C24242444558A20202020FC202020FE2050508888040255 +:20DD000020CE8AAAAAEEAAAAAAAAEEA8284848880EF0229254007C081010FE101010502083 +:20DD200010101010FD1010141B30D0101010512220202020FC202020FE2050508888040204 +:20DD400010101013FC1013161A33D01011115224909090FC9494FC9090FE92921A14101026 +:20DD6000202120FC405090FC11111DF15111111100FE00FC8484FC00FE2222FE2222FE02F4 +:20DD80001011107C545454545555555D1111111100FE00F88888F800FC2424FC2424FC0460 +:20DDA000203F409F007F127F127F527F1213224200FC00F000F01090909010D24A4A860290 +:20DDC00010103F4885080813305190101010101040407E90081010FE10109090101050200F +:20DDE000080808101037305090101011111214184050484840FE4040A0A0A0101008040238 +:20DE000008080B10123130539010171010101010083CC004442800F81020FE202020A04030 +:20DE2000003E2222223E2222223E222222424A8400FC8484948880FCA4A4A8A890A8C48234 +:20DE4000002013108241480B1010E72020202000083CC004442800F81020FE202020A04008 +:20DE600000201310824141171020E322222223028040FC00080810FE0000FC040404FC04C4 +:20DE8000402320F9111121306BAA22232222232200FE00FC0404FC00FE2222FE2222FE022E +:20DEA000201000F909131531559915111111111190949212107E101010282828284444824F +:20DEC0000404047F04043F24243F040808102040404040F84848F84040FC44445448404005 +:20DEE0000101FF01013F21213F21213F212121202010FE0000F80808F80808F808082810DD +:20DF000010131010FC1017101830D0111112542800FC40404040FE40A0A0A02022221E0027 +:20DF2000202023FC405191FD11111DF1511111112824FE2020FC2424FC2424FC2424240C29 +:20DF400010101724246465A527252525292931214020FE008888087E0848282808082810BE +:20DF600004081824030C30C01F01013F0111097F4020508800C0300EF00000F8001020FC16 +:20DF800004081824030C30C01F10101F101020404020508800C030EE000000F8808080804E +:20DFA00000784B48487B4A4A4B7A4A4B4A4A4A9A4844FE4040FC4444FC4444FC444454083B +:20DFC00000784B4A4A7A4A4A4B7A4A4A4C4C48982010FE00444484BE84A49494848494889F +:20DFE00001003F20222224242C342424444484040080FE00080808FE088848480808281081 +:20E00000003F2222252C3424202F292A48498A0880FE0808FE88485880FC44A48444240CFF +:20E020000404043F04047F040424272424544F80202020203028A4242020A0202000FE0092 +:20E04000007F003F20203F007F44447F44447F4002C2028292929212D25252D24242CA44CC +:20E06000FF043F243F1227428B12335193151017FE40F848F800FC08F808F800F810E01E18 +:20E08000007C4444545554545555551129254381080CEA0A08FE4848486848484A6A8602EF +:20E0A00010101F205F901F101F040F1864031CE00000FC00F010F010F000F0204080700EFC +:20E0C00008080F10173437549714101F121111105048FE40FC44FC44FC4408FE0808281039 +:20E0E0000808081017303050911010101010101010101010FE1010101090901010105020F2 +:20E1000002043F203F203F20203F0101FF0101010000F010F000F80808F80000FE0000008B +:20E12000040810204008080404020102040830C04020100824202040408000804020180670 +:20E14000003C2424253E2424243C2424254454894040FE80FC84FC84FC407CC42810688602 +:20E1600004040F10205F101111111112020418600000E02040F0101010101010C02010088D +:20E1800002017F40BF001F101F003F213F213F200000FE02FC00F010F000F808F808F808A5 +:20E1A000002010100000F01010101010141810008080808080A09088848480808080808063 +:20E1C000007C444949534D494545456951414141888888087E08084828280808080828109A +:20E1E00010101110FC24242524482810284580000000FC04040404FC0404040404FC0400C8 +:20E20000101027204BFA132243FA400319E040005048FE40FC44FC44FC4408FE0888A81080 +:20E2200000007849494B4D494949794901010101888888087E08084828280808080828107D +:20E24000000378494949494948497A4D0101000088FE88FC04FC04FC80FE225202FA0A0476 +:20E2600007007B4A4B4A4B4A4B49794F0000010EFC80F808F808F808F8107C809062B20E0B +:20E2800000402F200101E2272020212A3420030C8040FE80101024E44888102050880404B0 +:20E2A0000000FC040505067C4040404458604102404080FE0808888888505020508804028F +:20E2C00020272424FF2424776CA5A4252624202000BE8888A8A8A8BE101898A8AA4A4680E7 +:20E2E00010133C2041BD1111FD1110101418100000FE2020203E202020FE020202021408F7 +:20E3000008047F01013F0101FF00003F242424FF2040FC0000F80000FE0000F8484848FE66 +:20E3200000271414874444171425E4252624200000BE8888A8A8A8BE101898A8AA4A468016 +:20E34000003F0101010101FF010101010101010100F80000000000FE00000000000000007C +:20E36000080808087F080808080F080808080F0810101010FE10101010F010101010F010EA +:20E3800010111010FC10303B545490101010101000FC2020202020FE2020202020202020A3 +:20E3A00010101010FD103038545490101010101088888888FE88888888F888888888F8884A +:20E3C00010103F4885003F010101FF010101010140407E900800F8000000FE00000000003F +:20E3E000003D2424243C2427243C24242444548800FC2020202020FE202020202020202067 +:20E400000808087E0808FE0928282E2828584F8000FC2020202020FE202020202020FE0002 +:20E4200000003F202F202F28284F4080014848872824FE20A424A89892AA4682008412F28A +:20E44000081DF01010FC1033385454901010101000FC2020202020FE2020202020202020FE +:20E46000007E0204FF22223E223E22222FF242022020203E444444A42828101028284482FA +:20E4800010FE4429FE017C447D447C10FE1010114078D0205886F820FC00F888A8A8508884 +:20E4A000007F404040484442414244484040404000FC040404244484048444240404140838 +:20E4C000007F4141655555494955556541414542040404242424242424242424040414080E +:20E4E00010113D2141BD1111FD1111111519110100FC040494545424245454940404140825 +:20E5000020203F488808FF08084949494F79010000007E10101010101010101010FE0000D5 +:20E52000003C2524243C2424243C2424244457880000FC2020202020202020202020FE0065 +:20E54000101322224AFA122242FA42031AE2420200FC040494542424545494040404140883 +:20E560000121213F003F20202422212224282020000808F800F8084848880888480828104D +:20E5800001211711814F4112172AE223222221001010FC1010FE1008F41210F00404FC0007 +:20E5A00010101110FC10303854549010101013100000FC2020202020202020202020FE00C1 +:20E5C000203E4882FF001F101F007F404F484F40407E9000FE00F010F000FC04E424E40CAD +:20E5E00002041F101F101F027F040931CF0101010000F010F010F000FC402018E6000000BD +:20E600000201FF000F08080F007F404F48484F400000FE00E02020E000FC04E42424E40C83 +:20E62000017F080F007F488F001F101F101F101000FC20E000FE22E400F010F010F0103020 +:20E640000804047F0101013F010101FF00484484202040FC000000F8000000FE0088444455 +:20E66000111094545B10FC31385457901212141004848800FE2020FC2020FE00A45252006E +:20E6800010101310FD1111141B32D212121252224020FE00FC04FC00FE02FA8AFA020A0453 +:20E6A00020203B204179A120FB2222222A3222024020FE00FC04FC00FE02FA8AFA020A047B +:20E6C000081CF31011FD113837525292121212124020FE00FC04FC00FE02FA8AFA020A041F +:20E6E0000111111F214101FF00001F1010101F10000000F8000000FE0000F0101010F010E2 +:20E70000007F001F10101F00FF001F10101F000000FC109090909000FE10909090905020B5 +:20E7200000FF027A4A7A00FF027A4A4A7A020A042020207E4284101010102828284444829B +:20E7400022212524F425262434E725252525A544007C0484F414A444A41CF41414F4140852 +:20E760000202020202FF020202010100030C700020101000FE0008081020408042221A0647 +:20E780001010282442807C00007C4444457C44002040FC84A484948880FE0202FA02140808 +:20E7A000003C2424253C2424253C242424445488404078885020508806F888888888F888D9 +:20E7C00000001F119153541833509010212242818040FE0000FC0000F8106080000202FEEC +:20E7E0001008FF80097F087F08FF087F41417F41040484A42424242424A4242404041408AF +:20E8000008087F08080F013F21213F01FF0101012020FC2020E000F80808F800FE0000002C +:20E8200008FF081F101F101F081F215294101F0020FE20F010F010F000FC04844404A8103D +:20E8400010101011FB14303855529511111111118080F80810A040A01806F8080808F808B1 +:20E860001010107C545556547C5010141EE24000202050508804FA0000F888888888F8886B +:20E8800020170242474C5241424C77444447404000FC0404E44484048464DC4444C41408A3 +:20E8A000007B4851516151484B4A6A534242424200FE00FC0404FC00FE8A52FE22222A0457 +:20E8C00010103C2041BC1010FD10101014181000404078885020508806F888888888F888D0 +:20E8E00001010204081021C101010101010101010000804020100806000000000000000010 +:20E9000004040F1824030C30C01F101010101F100000F020C000C0300EF010101010F01019 +:20E92000101020214AF4132040FB42021AE243024040A0100806F80000F808080808F808F7 +:20E9400010131212FB12323B565292121212131200F80808F80808F84448302010880600DF +:20E96000007D4545457D11115D5151515DE1010100F80808F80808F844483020104886005A +:20E98000101010FE117C10FE133834545091111288888888FC888888FE88888888080808ED +:20E9A00000FF01013F21213F21213F110A0619E000FE0000F80808F80808F8000000C03EF7 +:20E9C00001003F20202F20203F20202F41428C300080FE0080F88888FE8888F840201806D1 +:20E9E000047F013F01FF48823F011F01FF020C7040FC00F800FE2482F800F000FE80601CF3 +:20EA00001013101011FD11111111111DE040000300FE2020FC2424FC2424FC20A040B00E90 +:20EA200000FF24243C24243D24242EF44404050620202024A4A4A820205050508888040257 +:20EA400010131010FD113139555591111010101300FE2020FC2424FC2424FC20A040B00EEC +:20EA600000007F01010101010101010101FF00000000FC00000000000000000000FE000014 +:20EA8000000000FE101112101010101EF040010240404080FE088888885050205088040238 +:20EAA000000000FE111010101010101EF141020440404040FC4444444484848404042810B9 +:20EAC00004043F0404FF04081222C21212220A044040F84040FE40201008269048480000DE +:20EAE00004047F09091720C4043F0404FF0810202010FC20C404FC4040F84040FE201008C2 +:20EB00000909091113313151911710111112141810101010FC10101010FE00100808040449 +:20EB200008103E223E223E2222FE060A12224A0400FC0404047C404080FC04040404281023 +:20EB4000000404080810204282040408103F100080808040402010080600402020F010007C +:20EB600002017F40801F10101F003F2020203F200000FE0204F01010F000F8080808F808E3 +:20EB8000007F0000003F2020407F00000000000000F0101010F0000000F808080808502020 +:20EBA00000017D111111111111111DE14202040800F01010101090505010101212120E004E +:20EBC000003F010101FF0001017D05091121C50200F8000000FE000004885020100806005E +:20EBE00010101010FD1010141833D0101011522488888888FE88888888FE00888404020292 +:20EC0000003F01017F00001F101111111204186000F80000FC0000F01010101010C0300818 +:20EC2000040404043F04040404047F000408102020202020FC2020202020FE002010080460 +:20EC400010103C2041BD1210FC10111114181000808080FC0404444484A414F41404281022 +:20EC60000808101F204282040408103F10000000000000F808080808088848E8280850208A +:20EC800001211111824440111122E72220202000000000FC048484044424F41404042810C1 +:20ECA0000404FF04101F20409F10101F100000004040FE4000F808088888888888085020E6 +:20ECC000004429112A4C89091929498908085020808000FC0404E4242424E424040428107E +:20ECE0001010111111FD11111111111DE1420204081CE00000FE00007C444444447C4400DB +:20ED000010101010FD1132385454911110101010808080FC0404444484A414F41404281025 +:20ED2000007C4454555556545454551128244480808080FC0404444484A414F414042810C1 +:20ED40002020407E82027A4A4A4A7A4A0202140820207C44A81020D01E226494081020C01D +:20ED6000017F011F101F013F0804FF013F01010100FC00F010F000F82040FE00F8000000FC +:20ED80000404FF041010FE1222226414081422C04040FE401010FE10107C444444447C4436 +:20EDA000000078484B484848494979490101010120202020FE202020FC0404040404FC042A +:20EDC000203F4885101312FE12121EF212125223407E900800FE2020FCA4A4A4B4A820FE11 +:20EDE0000808081017303050931212121212131240404040FE404040F80808080808F80834 +:20EE000000201010874048081312E2222222230240404040FE404040F80808080808F8082B +:20EE200000F80B1222222A3222E222222224A448083CD09090909090908888C8A4D492004D +:20EE400010101010FD242424254929112945850120202020FE202020FC0404040404FC047F +:20EE60000808FF08087E007E42427E42240FF040101010FE1010FC4444442828102844826C +:20EE800001010101FF0101011F10101010101F1000000000FE000000F01010101010F01090 +:20EEA00001013F21213F01017F003F242424FF000000F80808F80008FC04F8484848FE008F +:20EEC0001F101F10107F409F101F101F10101010F010909090FE02F410F010F01010502094 +:20EEE0000808112142040830C01F101010101F10201008048040201806F010101010F0109A +:20EF0000003C2424243D2625243C24242444548B00F88888880600FC8484485020508806A2 +:20EF200010101010FE1112107C444444447C450240404080FE088888885050205088040295 +:20EF4000007E40405E5252525A5450525458508300FE2040FC849494949494A4304884022C +:20EF6000007F41415F41414F4848484F48407F4000FC0404F40404E4242424E42404FC0496 +:20EF800001003F203F2222272C372427444487040080FC04FC8040FC40F840F84040FC0082 +:20EFA000020F780808FF0808087F414141417F410404042424A4242424242424040414086A +:20EFC00000001F1212121212121212222243428010F820202020202020109050A82804028B +:20EFE000007F4141417F0808FF8894A2C28082810404042424242424A4A4A4A4848494084A +:20F00000017F40BF041F101F101F10FF0837C20C00FE02F400F010F010F010FE20D846C0E4 +:20F0200010101110FC1013101830D110101053202020FC202020FE002020FC202020FE0070 +:20F04000211107F111212F68B129272121212E241010D0101018F4121210D01010D01010D7 +:20F06000001F0101FF01090979090919E901010170800000FE002024283022221E000000E1 +:20F0800010111111FD1110141B30D0101011522400FC040404FC4040FC44448484042810ED +:20F0A00010171211185450539C10171010101F1000F80810A040A0184640FC404040FE00ED +:20F0C00010101312FC11313955559111111111114020FE0204F80808F80000FC0404FC047C +:20F0E000100808003F010101FF010202040830C010102000F8000000FE00808040201806FA +:20F1000002017F40801F10101F10101F10101F100000FE0204F01010F00000F80808F808B5 +:20F12000007F40803E00007E141414142424438000FE02040808FE084828082A1202FE00AB +:20F14000000101FD05054929111128244481020400FC040424242424245450909012120E4D +:20F16000203F4885017F409F101F101F10101F10407E900800FE02E420E000F01010F0100D +:20F180002020233A4C51812121212121293121014020FE0204F80808F80000FC0404FC042B +:20F1A000404378A32223F82021A9ABADB9C9010188FE88DE52DEA090FE20FC20FC20FE000E +:20F1C00011111113195551509111111111101013FC2424FE2424FC00FC0424242458840202 +:20F1E000014F2127048741511322E72A2322230210FE10BCA4BC4020FE20FC20FC20FE00BC +:20F200001F1111FF11111F001F10111111020C70F01010FE1010F000F010101010601804C3 +:20F22000012111090901FF0404040408081020C0000808102000FE404040404242423E0037 +:20F240000100003F202020202020202020404080008080FC00000000000000000000000052 +:20F26000004825220D01E1232D21212A24508F0000807C1010107C101010107E0000FE00ED +:20F280000000FB22222322FA23202038E14102042040FC2424FC2444FC40A8B43C22221EEF +:20F2A0001011117D111111FF111110282445820400FC040424242424245450909012120E76 +:20F2C00001013F010101FF0001013F010101FF000000F8000000FE000000F8000000FE00BC +:20F2E0000000F92020407B48C8484948784803002020FC202020FE002020FC202020FE003A +:20F3000008084B484848484948484808101320400000FC04040404FC0404040404FC0400AA +:20F3200004040F10207FA1213F21213F210101000000E02040F80808F80808F8080202FE10 +:20F34000201700414F41415F40414F41415F404000FC0404E40404F40404E40404F4040CF8 +:20F36000202020FC435090FC10101CF05111121480808080F09090909090909212120E004A +:20F3800002043F21213F22223F050909112141800000F80808F80808F81020487C0202FE1C +:20F3A00001412322040BE222222222222A3424080000F80810FE00F88888A89082827E00D1 +:20F3C000007E0244281020CF01017F010204186090A04448301008E60000FC00C020100864 +:20F3E00010101110FC10333854549110101013102020FC202020FE002020FC202020FE0095 +:20F4000010111111FD113139555591111111111000FE000000FC04040404FC000000FE009E +:20F42000007C4445467D11115D5151515DE202044040FC0408FE007C4444544842423E0065 +:20F44000011F11111F01FF001F10111111020C7000F01010F000FE00F010101010601804C1 +:20F460000808142241BE0000FF10102241FF41000404042424A42424A42424240404140811 +:20F48000202121FD415191FD10111DF15111111100FC0404FC0404FC0012D4181052920E36 +:20F4A00000201711824441131020E123252921018040FC10488420F01088502010488600B8 +:20F4C00010111111FD113139545591111111111100FC0404FC0404FC0012D4181052920EDE +:20F4E000202139214179A020FB2222222B32220200FC040404FC2020FE22528A0A020A04BB +:20F500001008FF007E427E007E04080FF8082810007C444848504848444444685040404051 +:20F52000007F40405F41414F4141415F40407F4000FC0404F40404E4044424F40404FC04EF +:20F54000001F11111F11111F1101FF050931C10100F01010F01010F01000FE40201806005C +:20F5600001FF001F111F111F01FF13650C35C60400FE00F010F010F000FE108850300E0077 +:20F58000002010170000F2111110101010284700101010FE10101010101010502000FE0055 +:20F5A000000078494A4C4B48484B7A4A020203024040A0100806F80000F808080808F808B3 +:20F5C000007C447554FE827C447C447D44445449201010FE202444F8122244881028448244 +:20F5E00000FC040B1010141930D0101310105023201010FE204284F81022C4081028C402E5 +:20F6000001211112854149091711E222232020000000FC00F8084828FE084828FC085020A8 +:20F62000203F409F007F047F08113E0419620D3000FC00F000F010D0101010920A0A06825D +:20F640000201007F020408103F01061860030C70000000FC0000204088102040A0100804BD +:20F6600002017F40813F011F01FF011F10101F100000FE0204F800F000FE00F01010F0107F +:20F6800000F808494848487C04041CE544042811201010FE202444F8122244881028448287 +:20F6A00000FE2828FEAAAAAAAEC282FE8282FE8244444444FE444444447C444444447C4422 +:20F6C0007C04FF223E223E23FE4202012828480720203E44A42828902844820088A424E082 +:20F6E00022222222FF2222223E222222223E2200003E2224A428242422222234282020203D +:20F70000101010FE107C447C447D10FE10101010202020FE2020FC2020FE22222A242020B6 +:20F72000010102040A31C10F00001F1010101F1000008040201806E04080F0101010F0107A +:20F7400000231010844544141425E6252424270000F810204454E444E4544C448404FC045A +:20F7600002017F449F043F04FF081320C00601000000FE42F440F840FE2010884600804074 +:20F78000003F0000514945414549514542407F0000F0204094244404442414040404FC040D +:20F7A00000007057545455545455755505040810141210FE1010D01212D45448DA2A468219 +:20F7C000007F408810201F010101FF010101010100FE02241008F0000000FE000000000062 +:20F7E000101010FE117C457C457C10FE11101110202050880600DC4454CC44CC544454889A +:20F8000020202724F524252535E424282222A4401412FE10D014D458CA164224A28A78003F +:20F8200010111111FD1110141930D0131010502000FC04FC04FC0000FC2020FE20202020E1 +:20F840001F10101F10101F003F0101FF01010101F01010F01010F000F80000FE00000000C1 +:20F860002020272435ACA5A5A5242428222224201412FE10D014D458CA164224A28A780007 +:20F880001011111119555050911010131010101000FC04FC04FC0000FC2020FE202020205D +:20F8A00010111111555950901110102B2444408000FC04FC04FC0000FC2020FE202020203D +:20F8C00000201310804048081710E020202020000000FC4040404040FE4040404040404054 +:20F8E00000271212824149091010E0202021220C00F8080808101010A0A04040A01008065B +:20F9000001017F02040830C1013F0202040810600000FC804020180600F808080808502025 +:20F9200010101013FC1031395555911111121214804040FC0000F0101010101212120E0009 +:20F9400010207C45645454FC446454544445558A402000FC0000F0909090909292120E0026 +:20F9600020272021F921202724232936E146010E40FE00F808F800FE02F88044B868A660AA +:20F980000007F091919190979493F1960106010E40FE00F808F800FE02F88044B868A660BA +:20F9A000017F001F101F007F409F06190639063900FC00F010F000FE02F40020C0B08C8002 +:20F9C000017F001F101F007F40813E033E037E0100FC00F010F000FE02F400F000FA02FE4E +:20F9E00008087F080808FF121253529222224A84003E22242428A4242222A2B4282020203A +:20FA000010101010FC242425244828102844840000FC0408102020FE202020202020A040B3 +:20FA2000101010FE107C10FE1038355450901010081CE020203CE020203EE0202222221ECB +:20FA4000001F1010101F00FF08101F000000000000F0101010F000FE0000F0101010A040F4 +:20FA600000221213844840171020E32222222302404040FC404040FE0000F8080808F808F4 +:20FA800000007B484849494949497949000000000000FE0808E828282828E828080828103E +:20FAA00000037A4B4A4B494B4C4A7A4A0300000000F808F808F800FC4444A404F4042810A4 +:20FAC0000404FF0410172060A7242424272020204040FE4000FE0808C8484848C808281066 +:20FAE0000404FF04201710804B4A12E3222020004040FE4000FE0808C84848C848082810D4 +:20FB000010101013FC1030395454901310101013201010FE204284F81022C4081028C40287 +:20FB200000003F0101017F030505091121C1010110F800000000FC804040201008060000B7 +:20FB4000040E780808FF08181C2A2A48880808080000007C44444444444444447C44000038 +:20FB600008080F101033325292121312101010100000FE0808C848484848C8480808281038 +:20FB8000010102040830CF00001F101010101F10000080402018E60000F010101010F010BA +:20FBA00001020C30CF001F101F003F242424FF0000806018E600F010F000F8484848FE00A3 +:20FBC0001020D4095324D01829CA1D29C90951218080F80810A040A01806F8080808F8087E +:20FBE00020170042415F42444F414658434C404000FC040404F40444842444844424040CFD +:20FC000000201710804342121222E322202020000000FE0808C848484848C848080828109F +:20FC200000271414874444151525E5252524270400FC4444FC4444F4141414F41404FC0455 +:20FC40000808087E0808FE141456559424245489202020F82020FE5050D854525090903020 +:20FC6000201302F31223216BB42A22222320202000F808F808F800FC4444A404F4042810A2 +:20FC800008087F55123F64A43F24243F24243F2010207C446454444C407E02027A020A0436 +:20FCA00010107E12222A449F101111111204186000007C44447C00F01010101010C03008DC +:20FCC0000007F495949497909790F09F0005040800FC4454E444FC40FC4040FE00249292C4 +:20FCE000003F2129253F01013F0101FF0048448400F8082848F80000F80000FE0088444457 +:20FD000000001F109754571437549414242546848040FE00F808F808F884885020180600C8 +:20FD2000080B12224B0A1233529212121212131200F80808F80808F844483020108806000F +:20FD40000045291129498909192949890909512100F80808F80808F84448302010488600C6 +:20FD6000101312121B565253921212121212131200F80808F80808F8444830201088060093 +:20FD800000007B4849494949484B7848000000004020FE00F80808F800FC08302020A04077 +:20FDA0000201FF001F10101F003F0001010105020000FE00F01010F000F0608000000000CC +:20FDC00010101110FC13303955559111101011128888FC8888FE20FC24FC24FC00880402D7 +:20FDE0001213244887152567A52527212F21222400C04E80C0405EC44444C404E4049448DE +:20FE00001013101019555151911111111010131000FE0000FC0404FC0404FC040000FE0084 +:20FE200002027F08113F01FF01013E02140834C20000FC0000F800FE0000F88850205886D3 +:20FE4000010179494B494949494F78490102040810101010FC10101010FE001008080404AE +:20FE60001010101055585090101310282445428488888888FE88888888FE008884040202DB +:20FE80001010117C545454547C5010141EE243000000FC2020202020202020202020FE00D8 +:20FEA0000080401F844444042444C4475C48400010207C446454444C407E02027A020A0478 +:20FEC0000121111187414111112FE0212122240810101010FC10101010FE00100808040472 +:20FEE00002017F4082027F040408091122448F040000FE020400FC00808000002010F808EA +:20FF0000007C0404047C4040407C040507052810202020202040404080888404FE02020062 +:20FF20001010212444F8102040FC40001CE043000000FC2020202020202020202020FE00DB +:20FF40000101715252565A52525272520202020200780808FE40407C9010FE1028284482D2 +:20FF6000080B08101731315394101F101011121C00F80808FE0000F84040FE40A0100806EE +:20FF80000189512252961A12325292121212A24200780808FE40407C9010FE1028284482DA +:20FFA0000007784849494949494F79490101050210D05090101050901010101212120E00BF +:20FFC000003F202724272427202720202F40418000FE00F808F808F800F81020FE40408032 +:20FFE000101310282F6969AB2C282F282821222C00F80808FE0000F84040FE40A01008063E +:020000040105F4 +:2000000000001F10101F1010101714242444870410F8000000FE000000F808080808F808F2 +:2000200000007B48494848484B48784800000000083CE02024A4A820FE2020202020A04037 +:2000400000003F0111090901FF0101010101050210F8000010102000FE00000000000000EB +:2000600008081F122244081122040108484887000000F84848888808281000849212F0008A +:200080000101F927212121FB2222223AE3400000003C24E4243C24A4A4BCA4A4A444548845 +:2000A00001017F01011F007F408404241414047F0000FC0000F000FE02444048485040FCFC +:2000C0000404FF0408087F08083E2222223E22014040FE40007C44447C44447C44849408CB +:2000E000080808087F08083E222222223E220102007C4444447C4444447C44448484140870 +:20010000212121FBA9A9A9ABFAA2222A3BE84000003C24A4243C24A4A4BCA4A4A4445488F8 +:200120000088532252921212325292121214A448083CD09090909090908888C8A4D492002A +:20014000101094555810FC313955559111101010809E92D2929E92D2525E5252D2222A4480 +:2001600001211117814141171424E42724202000001E12D2121E12D2525E52D252222A44A8 +:2001800000F80B0A0A7A4242427A0A0A0A0C5428083CD09090909090908888C8A4D4920092 +:2001A0000101013F21212F21202023222244489000F800FC04608808F800E0202024241C44 +:2001C000000078484B4A4A4B4A4A7A4A0404091240407C40FC4470C0443C00F09092120E5C +:2001E00010101011FD1111151931D11112125428402020FE020202FE02000000000000003A +:20020000007F0404040F080810101F000000FF0000FC000000F010101020E0204040FE003C +:2002200000201013824242131222E22224242810804040FC040404FC0400000000000000A2 +:200240000201011F101010101F10101010202040000000F808080808F80800000000000044 +:200260000808FF080008081030509112141010102020FE20008890A0C080808282827E0006 +:20028000000079494B4D494949487B4800000000909414181032520E2020FE20202020204E +:2002A00008081030519610101101FF0101010101808890E08084847C0000FE000000000057 +:2002C000008B5223529F1813325392131212A24200F808C848FE02F808F808F80808281080 +:2002E00000231213824F48131223E2232222220200F808C848FE02F808F808F80808281098 +:2003000000FF00004F49494F4949494F40407F0000FE0000E42424E4242424E40404FC041F +:200320001014121013FC101111120C081422C10004040424A4242424242424A484849488A5 +:20034000080808101030305091121410101010108080848890A0C0808080808282827E00AE +:20036000002011100003F0101011111115191101083CE02020FE202020FC04040404FC04E8 +:2003800010101111FD11313955549010111112142040FC2424FC2444FC40B0A43C22221EDC +:2003A000080813224A0A123252921212121312100000FC0404F494949494F40404FC0400CD +:2003C000101017101854505091121410101010100000FE20204040D0484442404040404027 +:2003E0000121111382464B121223E22222232202402020FE2020FC2020FC202020FE00009C +:200400001010131010FC101010101DE2440000000000FE101020206864A422222020202078 +:200420000000FC0405492A141028244581020408808080FC0408404040A0A010100804024A +:200440000000FD101010107C101112101CE040000000FE1010202068A42222202020202016 +:2004600010131010FD113139555591111010131000FE0000FC0404FC0404FC040000FE002E +:20048000002310100000F011121410101028470000FC20204040D048444440404000FE0039 +:2004A0001017222148FB102047F941021AE448033CC0442800FC8080FE00F8885020D80663 +:2004C00010101011FA15111931D11710101051268080F80810FC24242424FE50508804021A +:2004E000011F11111F013F21213F01025151900F00F01010F000F80808F80000041212F07E +:200500000101F192949B92929292F7900001020C0000F01020F848484848FEA0A0100806B5 +:2005200000001F119152541B3252921F2021428C8040FE00F01020F8484848FEA01008068B +:2005400011097F04FF102FC619620C710618E2011020FC00FE10C80610A0C0B0888480004D +:20056000101010155A55519111111328244441868080F80810FC24242424FE505088040251 +:2005800001211112844B42121222EF202021220C0000F01020F848484848FEA0A0100806AD +:2005A00002017F40803F21213F2020203F21213F0000FE0204F80000F0101010F00000FC11 +:2005C000080811102242FC0408102442FE4200000000FC0404040404040404040404281068 +:2005E0000808FF0A01FF10101F001111112141812020FE2000FE0000F80010101012120ED7 +:200600002121272130AFA2A2A3202222222424280808FE4820FE0000FC004848484A4A4672 +:20062000043F0404FF011F11111F11111F04081040F84040FE00F01010F01010F04020107C +:200640000000FD1010233C6565A525253C2421028888FC8888FE20FC24FC24FC00880402DE +:20066000202021F9A9A9A9A8FBA0202938E843002040FC04FC04FC00FE2020FC2020FE0062 +:20068000203E48843F04FF013F213F213F081020407E9040F840FE00F808F808F8201008C2 +:2006A00002041F101F101F007F01013F0101FF000000F010F010F000FC0000F80000FE0014 +:2006C000003F222724272427202F2127214F408000F808C848C848C808E808CA0AEA06028F +:2006E000101011111955515093101011101013102040FC04FC04FC00FE2020FC2020FE00CE +:20070000101011155951519013101029244043802040FC04FC04FC00FE2020FC2020FE00B1 +:20072000001F101F101F01110901FF040408106000F010F010F000102000FE404042423E41 +:200740001011117D555554555454575C1011121400FC04FC04FC2024A820FE909012120E9D +:2007600010101219555057901010101011111214404444485040FE909090909212120E0078 +:20078000014127210007E222232022222A3424080808FE4820FE0000FC004848484A4A4691 +:2007A000040404FF080808121224294182041860000000FE0080848488904040201008060A +:2007C00010131214FC1310141931D0101710502000FE024440FC80A020FC2020FE20202082 +:2007E000101392545813FC28292928282B4C488000FE024440FC80A020FC2020FE20202026 +:20080000121A2A4F801F2468AF22243F222A3226109090A03EC424A42428A8D028A844823C +:2008200010101013185450519111121214101011404040FE8090901252549028284484029D +:200840001010117D555555557D5111151DE541000000FE02027A4A4A4A4A7A0202FE02003D +:20086000003F20202724242424242720203F200000F80808C84848484848C80808F8080048 +:2008800020CE8282EE8282FE0000FE10101EF04100784848488600FC444428281028448261 +:2008A0001111111A5551519117111212131010100000FC00F8084828FE084828FC0850207E +:2008C00010FE107C10FE103F001F003F0148488710FE107C10FE10F808F808F8008412F273 +:2008E0000101017F0101090808FF080810102040000000FC0000202020FE202020202020B2 +:2009000001017F013F213F213F01FF01282848070000FC00F808F808F804FE0288A424E08E +:200920000101794A4D4949794F494A4A7B4800000000FC00F8084828FE084828FC08502055 +:20094000007C45545454545556545410282444802020FE4040FC8484FC8484FC848494882D +:20096000081DF11111FC1038355250901010101320242424FC4040FC04844850204080004D +:20098000010102040830CF00007F020408103F10000080402018E60000FC00002010F80852 +:2009A00010101014595250901013102824414381202050880402F80000FE20408804FE02E4 +:2009C0000023121282424A0A1212E2222222230000FE000000000000000000000000FE002D +:2009E000002010170000F3101017101014181000404040FE4040FC4040FE42424A444040E0 +:200A0000012111120501F11117111212171810000000FC00F8084828FE084828FC085020A8 +:200A2000101020214AF4112040FB400019E247024040A0100806F00000FC40801008FC0425 +:200A400008FF08007F42823F09111F0101FF010120FE2000FE0204F80000F00000FE0000A1 +:200A6000003F20203F202830201F10101F10101F78808080FC40221A06F01010F01010F0FD +:200A800020232223FA4A4B4A49915121314949811CE020FE20920A06FC0404FC0404FC0481 +:200AA00000007D010101FF2121204844FC4501022040FC2424FC2424FC4068B2BE20221E29 +:200AC00000231214804348081111E0202720200000FE024440FC80A020FC2020FE202020D7 +:200AE00000271414874444171024E4272424250600FC0404FC0404FC002022AC3022A21ECB +:200B00002010FE82117C107C11FE107C44447C44005048842420508804FA88888888F88853 +:200B200000201310804740101023E222222223021078C04040FE404040F808080808F8081D +:200B400008080810123232549010101111121418404040404444485040A0A01010080402C5 +:200B6000010101111111212142020404081020C000000008081020008080404020100806BB +:200B80000808FF08442810284F982848890952242020FE2040504840FE40A0A01010080619 +:200BA000000000FF00003E2222223E0007782003484440FE4040444444282812324A860236 +:200BC0000000FF003E223E000E700301282848075048FE40402428122AC6020088A424E0C1 +:200BE0003F017F419D011D081F305F901F101F10F800FE0274007080FC80F880F880FC00D2 +:200C000008081030579010001F10111111020C70808098E084847C00F01010101060180405 +:200C2000201111F909111834539212121312121200FC040404FC2020FE22528A0A020A0467 +:200C40000101013F010101FF0101212121213F00000000F8000000FE000008080808F80875 +:200C60001017111111FD111111121EE24404080300F8081010203C040488885020508806A3 +:200C800008087F080F080F08FF081121CF01013F2020FC20E020E020FE201008E60000F8D6 +:200CA00010111111FD113139555591111112121400F01010101010101010101212120E0020 +:200CC00000007D545455577C555555557D4400002020FC508804FE08E82828E8280828100C +:200CE000081CF31011FE113139545491111111115048FCA0221E10E004FC00FC04FC04FC66 +:200D0000040E780808FF08181C2A2A48880808090000FC8484848484FC840048448482021D +:200D2000203F488508087F080F080F08FF081020407E90082020FC20E020E020FE201008A3 +:200D4000003C2424243C2424243C24242445558A00F09090909090909090909292120E0033 +:200D60002021213D4549A121212121212932220400F01010101010101010101212120E00BB +:200D8000002010170000F2121411111214284700402020FE90909492921010502000FE0059 +:200DA00002442F280F884F54122FE42724282A1110109090BEA4D41414D4148888949422A9 +:200DC000002111110101F111111111151912020400F01010101010101010101212120E008F +:200DE000000000FC0404482810102824458000002040FC84A484948880FE0202FA02140890 +:200E000010111111FD252525254929112945850000FE1010107C444444447C101010FE0024 +:200E2000101027204BF0172043FA42021AE041064040FC40F840FE00F808484848A0100895 +:200E40001011212149F0172141F9410119E7400000F80808F800FE08F808F8083EC80808E6 +:200E6000010101FF0101013F00001F1010101F10000000FE000000F80000F0101010F0109A +:200E800010131010FC103038555591111212141100FC848888909C844444282810284482F0 +:200EA0001010FD10107C5454545C1038549510102020FC2020F8A8A8A8B82070A82620200E +:200EC000202121FD415097FD11111DF15117101000F80808F800FE08F808F8083EC80808BA +:200EE000203F4885107C107C11FE103854941010407E900848FC4848FE00FC84FC84FC84A7 +:200F000009081F305F901F101F11FF050931C1010080FC80F880F880FC00FE4020180600BF +:200F2000003F080808080C0A0A0911102020438C00E020204040F808081010A040A0180693 +:200F4000080F10205F00001F00003F025151900F00E02040F80808F80808F800041212F0EA +:200F600000001F1292535214305F90102021428C8040FE0000FC404040FE40A0A0100806A1 +:200F800000271111814149091112E2222424280300F8081010203C04048888502050880678 +:200FA000007E42427E42427E4048444A52600000007C4444444444444444544840404040AF +:200FC00020202121F94D4B49894B3511294A82042010FE0020203C509010FE1028284482E4 +:200FE0001013202048F8102041F941011AE2440100FC848888909C8444442828102844824B +:2010000010101712FD10141936D11111111252248040FE0810A040B00E10101010101010A7 +:20102000000F080808080808080810102020408000E02020202020202020202222221E00BD +:201040002111091224083FC8080F08080F080808081020904820F82620E02020E020A04054 +:20106000003F00000000003F2020202020201F0000F01010101010F0000000040404FC00DB +:201080000404FF04101F227FA43F243F000778204040FE40040424A4A4A4A4A404841408CE +:2010A00010101013FC1010151830D01010105126202020FE202020FC8488485020508806A1 +:2010C000047C041CE43F213F213F043F04FF10204478423E00F808F808F840F840FE100855 +:2010E000001F01017F050931CF0000FF0101050270800000FC402018E64080FE0000000032 +:2011000008080817103030579212111010101116404040FE404040F8080810A040A0180699 +:2011200010103E6294483027C0001F01091125028080FC44483010C80600F00020100800DD +:201140001008FF02641826C122222222224242820404842424242424A424242404041408EF +:201160002023202730A9A2ACA32020272020212038C040FCE0504846F02040FC40404080B5 +:2011800000201712814040111621E121212222048040FE0810A040B00E101010101010106E +:2011A00002017F42823F0408FF001F10101F00000000FE0204F88040FE10909090905020C7 +:2011C00002017F40880F0808FF00082A498928100000FE02047C44444428281010284482C1 +:2011E000002010100000F7101010101014181000404040404040FE4040404040404040406E +:20120000002011100000F01111111111151910000000F808080808F8080000000202FE00F0 +:20122000007D44447D45457C4048444A5260410200FC20202020FE202030505092920E005F +:20124000003F00003F2020201F0108484848870000F01010F0000404FC0088841212F00005 +:20126000007948505063504849496A524440404000FC000000FE2020282424222220A040D2 +:2012800010101013FC2424252448281028448106202020FE202020FC8488485020508806AF +:2012A000101222234AF2132242FA43021AE2430020202024A820FC2070A824202020FE0094 +:2012C0001010232048F0102342FA42021AE241000000F808080808F8080000020202FE0067 +:2012E00001FF013F001F101F08FF107F1121458200FE00F800F010F020FE007C44447C4409 +:20130000222222FA2722726AAAA22222242429300000001ED252525252525252525E528067 +:201320000101017F01110901FF010202040830C0000000FC00102000FE0080804020180667 +:2013400008080B1010303F509010131010101F104040FC404040FE004040FC404040FE000D +:2013600002017F40807F020D71020C710618E2010000FE0204FC000890A0C0A09886800076 +:2013800010101010FE1212121212121222224A840000007C4444444444444444447C4400DF +:2013A0000808FF0801013F011109FF02040830C02020FE200000F8001020FE80402018063B +:2013C0000808087E084A2A2C08FE08141222408300FE2040FC849494949494A43048840252 +:2013E000007F043F24243F001F10111111020C7000FC40F84848F800F0101010106018045C +:20140000003F2121213F2121213F21010101010100F8080808F8080808F808000000000003 +:2014200010113D2141BD1111FD1111101418100000FC242424FC242424FC24202020202012 +:2014400010171424246764A4272424272424242400BC848484BC0000BC2424A810284482C6 +:20146000081CF31210FD10303B545093101013104020FE0200FC40A234589434529050205D +:20148000080808101132345191111111111212144040A0A0100806101010101010101010E1 +:2014A00008087F09111125420101FF050931C10100007C4444447C000000FE4020180600C9 +:2014C00008087F111125421F0008080F007F000000007C44447C00E0202020FC04C4140897 +:2014E00020202322F84948484B90502330484B804020FE0200FC40A2345894345290502021 +:201500000000FD20203C44476494080810204080083CE020202020FE20202020202020202D +:201520000424242424242504003F24242424FF0040407C409088080000F848484848FE008A +:2015400004252524242424250401013F0101FF0000FC048850205886000000F80000FE0076 +:20156000010109091121400101FF0102040830C0000020100804040000FE008040201806A9 +:20158000203F48850202037E0203FE0100073800407E90084020F80000FC1020C044340C39 +:2015A0002013104047444444474444444740404000FC0404C4444444C4444444C404140873 +:2015C0001008FF003E223E223E222A24004844841020FE00484848480808281000884444D0 +:2015E00010087F04043F04FF043F0C1424C404042040FC8080F090FE90F0C0A098868080DF +:2016000001001F10101F101714171427244484040080F80808F800F808F808F8080828102E +:201620000001FD0545452929111129294545810100F80808F80808F8444830201048860089 +:2016400010111010FE222223422414081422428000FC2020202020FE2020202020202020D0 +:201660002020204754F4252444F5450535C40810141210FE1010D01212D45448DA2A46821A +:201680000808FF0809013F2121213F0101017F202020FE202000F8080808F80010F8040410 +:2016A00010101010FD12353854509211111017104040A0A01008F600884848501020FE007B +:2016C0000101FF01013F2129253F23050931C1010000FE0000F8082848F88840201806008A +:2016E0000000F027244475D45455555575540810141210FE1010D01212D45448DA2A46826A +:201700000000F82021427D48C8484A49794807004040A0A01008F600884848501020FE00BA +:2017200010101710FC1311121B30D111121450204040FC8080E02020FC2028242222A04045 +:2017400010101010FD1215101830D211111057204040A0A01008F600884848501020FE00EE +:20176000203F4885100B20272424272424272020407E900800F808C84848C84848C80818CF +:20178000080808101132355090101211111017104040A0A01008F600884848501020FE00EA +:2017A00008FF003E223E223E2226007F0408106020FE000848484848081800F80808502003 +:2017C000004020270404151424E5252525242810141210FE1010D01212D45448DA2A4682F9 +:2017E0000808FF0A027F040908182B48880808082020FE2000FC00F81020FE202020A0404F +:2018000010111111FD113138545591111111171048484E506844444000FC54545454FE00D2 +:20182000042424242425020C30CF013F09057F0040407C908808806018E600F82040FC00C7 +:20184000007C4444457C10115C5050505CE003005048405CE0405EE044483022528A0602C3 +:20186000007C44445554545754545410282443805048405CE0405EE044483022528A0602A1 +:20188000001F10101111111111121204040830C000F0101010101010109090808082827E8E +:2018A00020203B21417AA227F92525222A35280010107C14FE147C107C10FE101000FE0026 +:2018C000203F48851008FF003E223E223E222A24407E90081020FE0048484848080828106B +:2018E0000808091111323254901710101010101020202020FC20202020FE20202020202034 +:201900001010102E236264A42E22222B242629302020FC24FE24FC20FC2020FE2020FE0086 +:2019200010217D45655555FD456554544444558A00FC040424242424245450509092120E01 +:20194000080814122140BE0011094922220778200404042424A42424242424240484140878 +:201960002020203C4548A02320202020283023005048405CE0405EE044483022528A06022C +:201980000141212F028245571121E12F2521210100021CD010101ED41414D414142424443B +:2019A000004F28280A8A4A5A1A2AEA2225242810109492909EF0909EF09494080A9A2642D1 +:2019C00002211514844545151525E52524242404007C040404F41414F41414F4040414080C +:2019E0000000FB08171023780B084837102C43804040F848FE48F840F84040FC4040FE0061 +:201A0000101F1027246764AF202724272427202F00FE00FC44FC44FE00FC44FC44FC00FEA0 +:201A200008047F013F01FF0204FF08101C030C702040FC00F800FE0000FE2020408070085B +:201A40000808094A2828080B182BC8090808080880F80810A040901010FE1010901050203E +:201A6000084828091A284889017D05091121C5024040FC04885060800488502010080600FB +:201A800000201710804048081010E020202F20000000FC40404040404040404040FE0000E6 +:201AA00000FB0809F98181FB4849E9496989502300FE00FC24FC24FE00FC24FC24FC00FE86 +:201AC0000808FF080008492A28081B29488808082020FE2080F810A05090FE10909010304C +:201AE000084828091A28488901FF03050931C1014040FC048850608000FE8040201806001A +:201B0000084828091A2848880901FF02040830C04040FC04885020408000FE8040201806F7 +:201B2000012111110701F1111F1111151912020410101010FC101010FE10101010101010F6 +:201B4000007F4040474444474444444848507F0000FC0038C00000FC202020202020FE0097 +:201B60000848291A28C908FF043F2428303F203F4080FC4830C000FE80F8887808F808F813 +:201B8000007C44494A50494E4445446A534040408080FC089060982620FC2020FE20202055 +:201BA0000808FF09081F305F101F101F102422422020FE2080FC80F880F880FC008844440B +:201BC00021212121F921277069A1A525292125220000DC141414D4141414884848141422E1 +:201BE0000000F92123457949C9494949794A0204A090FE1010FE1010FE1010FE00A4525264 +:201C000009081F10305F90101F10101F104844840080FC8080F88080F88080FC008844445F +:201C20000078484B4878494A487848484848489B402020FE008804028888505020508806C9 +:201C4000020101FF0010102048040201020C30C0000000FE00100824244080008040300ED8 +:201C6000100800FF002442812414081422428000007C4448485048484444446850404040BA +:201C8000002010138040480B1017E020212122048080BCC05024D40C00FE909012120E003F +:201CA00000F80948484B487C05061CE444052912083CE02020FE5088048A8888880808087D +:201CC00010101010FC252424254A281028448401081CE02020FE5088048A8888888888086B +:201CE000000772515754575057547754070505063CC04428FCA4FC0888FE88A89808A890A1 +:201D000024222227FC28232A32E222222021A24C844448FE0204F808484848A8A022221EA6 +:201D200010103C2140BC1112FC10101014181003402020FE008804028888505020508806E2 +:201D40002020217C509310FC1112102824454182083CE02020FE5088048A888888080808B8 +:201D6000080808131030305390171010111112148080BCC05024D40C00FE909012120E0046 +:201D80000179494B4979494F49794A4A4F4A489800001E92121212D212121A94D050101042 +:201DA000004428132848890A1828488808085023402020FE00880402888850502050880654 +:201DC00008081F2040BF21213F21213F214141800000E02040F80808F80808F80808281000 +:201DE0002020203D4448A1222020202028302003402020FE00880402888850502050880642 +:201E00002122274457F4272241F7420332C405080808C850DE64D41414D414C8485454A258 +:201E20001010202544F8112240FC40001CE04003402020FE00880402888850502050880659 +:201E4000499249007F497F497F08FF1C2A49880804040424242424242424A4240404140835 +:201E600008087E090AFF087E24488F78080828112020A03E444444A428281010284884028C +:201E800000FE2928FEABAAAAAFC283FE8282FE822022FA2424FE1020FC8810FE10105020AC +:201EA000202021FC405390FC11121CF050111112083CE02020FE5088048A8888880808087B +:201EC000202020FD405091FE10101CF050101013402020FE0088040288885050205088061D +:201EE00000007C444444444444447C440000000004048484848484848CB4C4840404040412 +:201F000002017F4891090F1101FF001F10101F100000FE221400F00000FE00F01010F0109D +:201F200010131213FE1311131C32D2121310502000F808F808F800FC4444A404F40428100B +:201F400010101310FD1017101837D011101051268040FC000890FE4040FE88089060980457 +:201F600020203C20202C31021F10101F10101F108088B0C084847C00F01010F01010F0107D +:201F8000081CF01310FC11303855559111111111202020FE2020FC0000FC04040404FC0470 +:201FA0001111274181172061A1272121212E24200000DC0000C03E0808C80808C808281017 +:201FC000007C444848514A48444444685041414220205050880402888888888888080808D0 +:201FE00008087F08FF14227FA43F243F243F202020282420FE2024A42428281012AA468233 +:202000000808087E080808FF10102044FE42010220202020FC2424242424244444842810B4 +:202020000808FF0808007F0202020202020202022020FE202000F8080808085020000000EA +:2020400010101013FC1031385455911111111111202020FE2020FC0000FC04040404FC0493 +:202060000101017F0305091121C1010024224280000000FC804020100806000088444404C3 +:2020800020202720FB20272833E022222225A4484040FE40F848FE48F840407C4040FE000F +:2020A00000007B4849784B4879484949794A02042020FE20FC24FE24FC20203E20A07E0095 +:2020C000201111FD010988894A4951511DE0400000FC04FC04FC80FE22225202FA0214080A +:2020E0000040202F008047501023E22222222302404040FE4040FC0000F808080808F80848 +:202100001010202744F8112040FD41011DE14101202020FE2020FC0000FC04040404FC0486 +:2021200010103C2448BE2A2A3E2A2A3E2A4A428600FC2424548810507C9010FE10101010DF +:2021400010111111FD252525254929112945870000F8080808F8080808F808080808FE00FD +:20216000000000FF001212127F12121222224003484440FE4040444444282812324A860272 +:202180000808FF08107C107C11FE1038549410102020FE2048FC4848FE00FC84FC84FC8401 +:2021A0000808FF080902040834C40404080810202020FE2020804020584640404040404035 +:2021C000001F11111F11111F020C34C40408081000F01010F01010F08060584640404040A6 +:2021E0000909091711313F509312121312121312101010FC1010FE00F80808F80808F8086F +:2022000001010204081020C8080808081010204000008040201008262020202020202020F8 +:2022200000001F10905051123D519111212242848040FE4040A01008161010101010101077 +:202240000040202F0002E2222F22222A32240408141210FE10909292D29494888A9A2642E4 +:20226000003F20203F2020202F28282F48488F0800F80808F8808080F88888F88888F808DB +:202280000101013F212121212121212121010101000000F808080808080808281000000068 +:2022A00010103F48853E22223E22223E22424A8540407E90082020FC2424242444449408F7 +:2022C00000001F1010101F10101010102020408010F800000000FE404040404040404040FA +:2022E0000101020408102FC1013F01110909FF00000080402010E80600F800101020FE0057 +:2023000001010204081221C1001F000000000001000080402010080600F01020204080009B +:202320000020131087404B081013E020272020004040F848FE48F84040F84040FC40404004 +:20234000211107F113252968B3282720222429201010BC10B8541200F800FC40484442804D +:2023600004252424242402041F01063F0111254200FC885020508C20C08010F80820100848 +:2023800010103D2141BD1110FC131212161A10002040FC04FC04FC2020FE22222A242020C1 +:2023A000080B091111303050901010101010111600FC0404048888885050202050880402CA +:2023C00001412F210100E72427202F202F302F001010FE10F040FC44FC40FE40FC40FE00E9 +:2023E000002010130000F0171010111112284700909090FC909090FE909010101000FE0028 +:202400002222FF223E087F49497F08FF08080809040E704040407E48484848C84888880851 +:20242000007F04241404FF001F10101F10101F1000FC40485040FE00F01010F01010F010FF +:2024400008087E081C2AC8003F0000FF011125422020FC2070A82600F80000FE0010080475 +:20246000002011110101F1111111121214284700081CE00000FE1010101010101000FE00DD +:202480001011111559515191111214282444408000FC0404FC10100804621000E018040048 +:2024A00000231011804340171423E1212020210600F808F808F800FC04F01010A040B00E78 +:2024C000001F1010101F1010102320408C03000000F8080808F8484020108806000080403E +:2024E000007E040818244281007E0808080EF14220202020FC2424242424244444842810E4 +:202500001212FF12007F121212FF1212222242820404C42424A4242424E424240404140832 +:202520000808087E08087E42427E141425264481202020FE2020FC8484FC50505092920E7D +:202540000404FF04003F00010E701F010101FF004040FE4000F06080700CF0000000FE0099 +:2025600000007B4849784B4879494949794901012020FE20FC20FE00FC04FC04FC04140898 +:202580000F08080F08080F007E42427E42427E42E02020E02020E000FC8484FC8484FC8482 +:2025A00020207D44887C54547C54547C011EE0404020FE0000F8888888F820A82422A040BB +:2025C0000201FF00001F1010101F0111112145020000FE0000F0101010F0001008040400D2 +:2025E000101013101855515191101111121410104020FE0000FC0404FC2028242222A04092 +:20260000101095545810FD3038545490101010102020FE20FC20FE00FC84FC84FC84948858 +:20262000101194545911FD31395555911010101300FE2020FC2424FC2424FC20A040B00EC2 +:202640001011202444F8102340FD40001CE0430000FC08103048840200FC20202020FE005E +:20266000080808087F08080808FF08081010204020202020FC20202020FE20202020202052 +:2026800024FF247E827A4A7A05FF003F003F203F20207EC4281028C600FE00F800F808F83E +:2026A0001F101F101F01FF001F10101F01214502F010F010F000FE00F01010F000080400DC +:2026C000007E040818244281007E0808080EF04000FE10207C4454545454545428244282A7 +:2026E0001010FE107C11FE007D447C457C4454484040788810FC2424FE2424FC2420A04009 +:2027000020202321F82720232223223BE141020C8040F810A0FE00F808F808F82022221E21 +:202720002222FF22407F41817D45457D45010A042020A03E444444A42828101028284482C7 +:2027400020203B214077A023FA2322232931220C8040F810A0FE00F808F808F82022221E99 +:20276000080B102048081136509310101010171000F810206098040200FC40404040FE0015 +:2027800000001F1097505010335C931020204F808040FE00F81020D80402F8404040FE0008 +:2027A000201013FC01088B88494951511DE141012020FE20FC20FE00FC04FC04FC041408B6 +:2027C00002013F0804FF001F101F101F040810600000F82040FE00F010F010F04042423E6B +:2027E00002013F0804FF001F10101F04040830C00000F82040FE00F01010F0404042423E96 +:2028000001412324001710102F20E027202021000000F01020FC4444FE4444FC44404080D7 +:202820001011111559515191111111292545418100FE0202027A4A4A4A4A7A4A02020A04C1 +:2028400002017F48903F04FF043F081F28488F080000FE2214F808FE08F800F80808F80831 +:2028600020212721F921272933E325252921A14188C808082A2AAC4808885414142424429B +:2028800002017F40881222023F020404081020400000FE0224100800E020202022221E0019 +:2028A0001010202444F8102040FC40001CE0400004048484848484848CB4C48404040404D8 +:2028C0000000FC1011117D121010101CE0410204808080F8080810102020505088080402AA +:2028E00004047C0404047C0404047C040404FF0040407C4040407C4040407C404040FE0007 +:20290000040404070808102040000102040830C0000000E0202040408080404020100806C7 +:2029200004040F1020030C7001111122040830C00000E04080601804001010A04020180636 +:20294000040404047F040404080808101020408000000000E02020202020202222221E00A0 +:20296000004F2020078444541526E4272424270400FEA0A0FCA4A4A41C0404FC0404FC049E +:20298000003F202F29292F29292F282A294B4D8800FE007E101050507E102828284A4A86B0 +:2029A00010141210FE111092541038549210512240404080FE08888888505020508804029F +:2029C0002023222222222223222222222223222000FC0404040404FC0404040404FC0400B8 +:2029E000000438202020203C20202020203F200000007808080808780808080808F80800A8 +:202A00003E203C203F001F111F111F027F04186078087808F800F010F010F000F808281021 +:202A200010101E222254081423C01F1010101F104040504844444040FE00F0101010F01005 +:202A40002010FE00007D4444447C1054921151224050484840FE50505050909092120E0099 +:202A600000001F119151531234589010202146988040FE000000F01010202040A010080688 +:202A80002828FE293A107C54557C10FE111010108080FE0222AA7222FE2272AA22220A0497 +:202AA00010101111FA14111931D1111110105020808000FC0404E4242424E424040428104C +:202AC0000045291129498909192949890909572000F8080808F8080808F808080808FE00A0 +:202AE00000001F10905352123352921322224F808040FE0000F80808F80808F80808FE004F +:202B0000003F20203F20203F20202F2848488F0800F80808F88080FE8080F8080808F808AC +:202B200000F809494A4C497D05051DE544042810808000FC0404E4242424E42404042810C7 +:202B40000404FF04101F22528A027F070A1262024040FE4000FC04448404F40484441408CF +:202B6000003F20203F20203F202724244740800000F80808F80000FC04E42424E404281036 +:202B80000001794949494949494979490101070000F8080808F8080808F808080808FE00BB +:202BA00020213D51911111FF111111292545418000FE000000FC04040404FC000000FE0009 +:202BC00022111100FF081121CF01017F0101010108081020FE201008E60000FC00000000CC +:202BE0000023121282434A0A1213E22222222F0000F8080808F8080808F808080808FE00A3 +:202C00007F223E223E23FE02007F0911630519E1007C042810A84400F800048850201806A1 +:202C200010111111FD1111151931D1111111512000FE000000FC04040404FC000000FE005A +:202C400020232222FB22222B32E222222224A44800FC0404FC2020FE2020FC848484FC8473 +:202C6000003F2020203F2020203F202020203F0000F8000000F0101010F000000000FC0014 +:202C8000001F10101F101F101F1010FF0408102000F01010F010F010F01010FE4020100887 +:202CA000007D4545457D11115D5151515DE1010000FE000000FC04040404FC000000FE0096 +:202CC000007D4545457D11115D5151515DE2020400FE0202FE1010FE10107E4242427E4232 +:202CE00020233A22437AA223FA2222222A34240800FC0404FC2020FE2020FC848484FC8443 +:202D0000080B0A12133233529312121F1011121400F80808F808F808F80808FE0010080473 +:202D20000808101F20409F101010101F10000000000000F8080888888888888888085020AE +:202D4000101312121B5653529312121F1011121400F80808F808F808F80808FE00100804CF +:202D60001011111155595191111111292545418000FE000000FC04040404FC000000FE00F5 +:202D8000003F20203F24243F24243F5050901F10048484A4A42424A42424A4A48484948814 +:202DA00010111111FD1013161A33D2121312522200F80808F800FC0404FC0404FC041408AC +:202DC000003E22223E007F41417F41417F41454210207C446454444C407E02027A020A0466 +:202DE00020212121F9484B4A4A935222334A4A8200F80808F800FC0404FC0404FC041408BC +:202E00001012112720616FA2242B322222222221404850FC8000FE1008F41210502404FCA8 +:202E20000111093F027F08102FC80F080F080F08001020F800FC2010E826E020E020E02001 +:202E40000111093F02027F08102FC80808080807001020F80000FC2010E82620A84808F8ED +:202E60001011212149F8132242FB42021BE2420200F80808F800FC0404FC0404FC04140893 +:202E8000202F282AF92B28283AEA2B282829A95200FE002848EE9284A0A8E8889414244222 +:202EA00013121312FB10111B35D1111011105027DE52DE52DEA0FE20FC20FE00FC88708E3A +:202EC00010101013F810141837D0101011115224404040F848484848FE40A0A01010080638 +:202EE00020272424F724252535E524252529A95000FC0404FC20242424FC20242424FC0420 +:202F000010171424276465A5252524252529293000FC0404FC20242424FC20242424FC046F +:202F2000007F22117F447F007E427E427E487442FC000810FC44FC0808FE0848280828108B +:202F40002211007F40801F101111111202041860081020FE0204F010101010908084847C0D +:202F600000402027000010102FE0212122242810808080F888888888FE8040402010080607 +:202F8000002010130000F0101710101419120408404040FC44444444FE40A0A01008040204 +:202FA000101020214AF5112141F9410119E140008080F80810FC242424FC00000202FE0013 +:202FC0001010101011FE10101010101CE1400000404080FC040484444414244484042810C9 +:202FE00008FF08003F202027212F232529213F2020FE2000F808C80808E888482808F808DD +:2030000010103C2041BE1010FC10101015181000404080FC04048444441424448404281060 +:20302000007F4082023F0409113F0101FF01010100FE020400F8000000F80000FE000000BB +:20304000003F0404FF04043F08081F1828488F0800F80808FE0808F80000F8080808F80877 +:2030600020202021ABA8A8A9AAA8A9BAC800010640408804FE02884442F8885020508806BF +:203080000808081113303051921011121010111640408804FE02884442F88850205088064F +:2030A000201010FD030888894A4851521CE0410640408804FE02884442F888502050880657 +:2030C00000201112874041121421E3242020230C80801008FC04108884F010A040A0100C18 +:2030E000007F1111FF11117F20207FA121213F21003E2224E4282424222222342820202093 +:2031000000F808494B48487D06041DE64404291640408804FE02884442F888502050880692 +:2031200000007B4A4848494A48497E49010101014020FE0280F80890609806F80808F808D5 +:203140000404F4949F9494949494F494080812210000003CA4A4A4A4A4A4A4A4A4BCA40031 +:20316000020203020202FF0202020202020202020000F8000000FE000040201008000000C3 +:20318000000078494B4C4848494A7D49010101018080F80810A040A01806F8080808F8082C +:2031A000007F0808080808FF080808081010204000FC2020202020FE20202020202020202F +:2031C00011111111FD1111141931D111111151211012D41852922E40FC0404FC0404FC0450 +:2031E00011111111FD11313855519111111111111012D41852922E40FC0404FC0404FC0420 +:2032000010929292FE00FE02027E40404659610200F09090909090909090909292120E00A4 +:203220002027242437ACA4A7A42524252624202000BE8888A8A8A8BE101898A8AA4A46808F +:20324000007F0808080808FF080808080808080804040424242424A4242424240404140894 +:203260001010131010FC10101013111DE14101008888FE88F888F88888FE00488400FE0085 +:203280002222FF223E223E2222FF405462407F0220202020FC242424242424444484281099 +:2032A0001010101011FD12141010101DE1420408808080FC0408404040A0A0101008040268 +:2032C0000000FC1010203D6464A424243C2421024040407C84882020205050508888040290 +:2032E000007F013F02FF04081F284F880F080F08F80000F800FE0000F010F010F010F010C8 +:2033000001003F202F203F202F282422444892010080FE80F888FE88F880C4A8908886005D +:203320002020272435ACA7A4A5242524292A30204020FE20FC24FE24FC2062B42826A04001 +:20334000101095555911FD3139555591111212142010FE107C14FE147C109254385492306E +:2033600010101110FE1010121C30D010101053200000FC2020202020202020202020FE00C3 +:2033800010101013FC1011151931D11111125224804040FC0000F0101010101212120E0083 +:2033A000020101FF00000F080808080810102040000000FE0000E0202020202222221E0071 +:2033C00010101013545851911111112925464284804040FC0000F0101010101212120E001F +:2033E00002023F0202FF01020F122447800000000008D02040FE0000F80000F01010A0405A +:2034000010101110FC1310141932D410101050204044F44850FE4080FE4080FC04042810B1 +:2034200010101110545B509011121428244440804044F44850FE4080FE4080FC040428106D +:20344000111F21FF001F101F047C043C047C040400F000FE00F010F0407C4078407C4040F8 +:203460002020272020FB22222222233AE04000000000FE0808C848484848C8480808281057 +:203480000808FF08007F00001F11111F110000002020FE2000FC10101010101010105020DB +:2034A00010101710FC13323A56529312101010100000FE0808C848484848C848080828106F +:2034C00010111111FD113139545390101112101000FC2424FC2424FC20FE70A82422202067 +:2034E0000000FC1010213C6465A425253D2523002020FC2020FE4084FE02FC545454FE00E3 +:20350000007F49497F49497F08FF1C2A49880808007E10207C445454545454542028448268 +:20352000081DF01010FD103834505390101010101010909010109090101EF010101010107C +:2035400001017F01011F007F40800F08081020C00000FC0000F000FE0204E0202022221E09 +:203560000000F097909091939090F19600000106402020FE408408F022448810205088049E +:20358000007F00001F11111111111F110000000000FE1010101010101010101010105020DA +:2035A000002312138243490B1412E2222320200000F808F808F800FC4444A404F4042810C9 +:2035C0000101FF01013F2020203F0404081020C00000FE0000F8080808F840404042423E82 +:2035E000100800FF0811217E04091224CC1221C0040404A424242424242424240404148886 +:2036000002017F40880F102C031CE01F10101F100000FE0204F0204080700EF01010F01046 +:20362000004322220302E223202720293224000000F84848F84848F840FCE0504846404091 +:203640000101111111FF001F101F101F101010100000F80000FE00F010F010F01010502003 +:2036600000017949494F484B4A4B7A4B0202020220203C2020FE00FC04FC04FC0404140820 +:20368000003F203F203F22212C31013F0101FF0000F010F010F00890601C00F80000FE0052 +:2036A000003F203F203F22212C3001084848870000F010F010F00890601C00849212F00032 +:2036C0001010101310FC11111111111DE1420204804040FC0000F0101010101212120E0090 +:2036E0000000784F484849494949794902020408804040FC0000F0101010101212120E000D +:2037000002017F40881020001F01010101017F000000FE0224100800F00000000000FC0064 +:20372000007D111111111DE2440801084848870000F01010905012120E0000849212F00023 +:20374000007E020408080A0C38C808080808281040404040404040404040404242423E00A3 +:2037600010101013FA14111A30D1101010105720402020FE0294080400FC20202020FE007B +:2037800010111111FD1111151931D1111111512000FE000444282810102828448400FE0027 +:2037A00000003F202020202020202020203F20000000F808080808080808080808F80800E3 +:2037C00010101111FD1111151931D111111151200000FC04040404040404040404FC040090 +:2037E00002017F40803E00007E141414142424430000FE0224382020F8085020548404FC0C +:2038000010101010FD103038555591111111111120202020FE202020FC0404040404FC0475 +:20382000003C2424243C000101FF0102040830C0007848484878001008FE008040201806C8 +:2038400002017F48903F203F202424272048488F0000FE2214F808F8809090F0808888F85E +:203860000808FF08090101FF01011F1010101F102020FE20200000FE0000F0101010F0100B +:2038800000FE2828FEAAAAAAAEC282FE8282FE821050507C509010FE00007C4444447C4448 +:2038A00001003F21213F2224282F20205F4080000080FE0000FC008080F88080FE8080805B +:2038C000201001FD0911113559951511111212141008FE1010FE2028487E0808FE08080895 +:2038E00001017F04081720C03F04080F000000000000FC4020D00806F80000F01010A040C8 +:203900002020272021FA2D202720213BE04000004040FCA01008F600FC8000F808085020D7 +:2039200020202720F1222D2037E021232020A0404040FCA01008F600FC8000F80808502007 +:2039400000784B4848791610535C505158E000002020FE508804FA00FE4080FC04042810DF +:20396000003C2524243D2624273C2425244454882020FC508804FA00FE4080FC040428101B +:203980001010101310FC10101310101CE1420408404040FC44444444FE40A0A010080402D2 +:2039A00010103F4885101118545053901011121440407E900840F8484848FE40A010080632 +:2039C000080808111234315090171010111217124040A0100806F00000FC40801008FC04E2 +:2039E00010101013185450509710101011111214404040F848484848FE40A0A010100806E5 +:203A000002017F40843F04001F101111120418E00000FE0244F84000F01010109082827E10 +:203A20000808FF08087E007E00FF084A498928112020207E428410101010282848448402C9 +:203A4000007F40404F4040474040404F40407F0000FC0000F88080F0808080F80000FE00E9 +:203A6000203F4885003F202F20202720202F203F407E900800FE00FC8080F88080FC00FE15 +:203A8000004429102848880819284888080853200000FC2020202020FC2020202020FE00DF +:203AA00010111111FD113139555591111111111000FE0000FE10107C101010FE0000FE00F8 +:203AC0000000FC1010203C6464A424243C252102201010FE80808080808080808000000078 +:203AE00000017D45457D45457D4545457D45010000FE0000FE10107C101010FE0000FE00E4 +:203B000000007849494979494949497949020204402020FE0000000000000000000000006D +:203B2000004724240404171121E121222224281000F808080808F8202020202022221E00F1 +:203B4000003F000000FF0404080F00000000000000F8000000FE000000F010101010A04002 +:203B600004047F0812122441820C003F242424FF0000FC404850A010080600F8484848FE95 +:203B80000121213F00084B484848494848101320000808F80000F8080808F8080808F80834 +:203BA00002017F489000117D1111FD11282441860000FE221400FC04242424545090120EE6 +:203BC00008FF08007E0428102FC1017F01020C7020FE2090A0442810E80600FC00C0300861 +:203BE00002027F040931CF01017F00013F0101FF0000FC402018E60000FC0000F80000FE27 +:203C000008107F49497F49497F101A2C2F48488708482828084828280EF80888880802FEE9 +:203C200010101724246764A427202121222428304080FC4444FC4484FC8050647C42423EF9 +:203C40002020213D4548832021212125293020032020FC24FC20FE00FC04242424508804D0 +:203C60002020272434AFA4A4A7202121222428304080FC4444FC4484FC8050647C42423E71 +:203C80000020131283404F101322E222222021064040F848F840FE00F808484848A0100895 +:203CA0001010101111FD11111111111DE1400000202020FC242424FC242424FC2420202072 +:203CC000003F20203F20203F0020203E2020263800F01010F01010F000808498E084847C7B +:203CE00020272424FC27242C34E526242424A74400FC444444FC44C4E45444444404FC0458 +:203D0000007F4141415F41434345495141417F4000FC040404F40484442414140404FC04FF +:203D200010101110FC1310141831D11111115121083CE02020FE202020FC04040404FC0482 +:203D400010101011FD1111151931D11111125224201010FE000000000000000000000000EB +:203D6000003F223F202F282F202F21235E428A0480FE00BC24A4A8A824A424F42820202082 +:203D80002017004845645051444879494949404000FC0434C44444F44444F41414F4040CDE +:203DA0001010101013FC10111110101CE040070080404000FC00080808909090A020FE009D +:203DC00010101010FB10141931D010101010572040202000FE000404048888889010FE00F3 +:203DE000010177515157555557517355090101010404C40414D45454D41494544404140897 +:203E00001010107D545455547C5010141EE24000484848FE4848FE00FC8484FC8484FC8488 +:203E20000078484B48784F484979494949494999888888FE8888FE00FC0404FC0404FC04AC +:203E4000201011FC004529FD1110FC10212240802020FC2020FC2424FC2070A82422202010 +:203E6000010171515751515151537551010105022010107E800444C42424282808107E0049 +:203E80000808FF09013F0111097F03050931C1012020FE2000F8001020FC804020180600AC +:203EA0000101017F01110909FF03050931C10101000000FC00101020FE8040201806000020 +:203EC0001010FE11127D5555557D1139549011128080F80810FC04242424242450880402B5 +:203EE0000808FF080424242425003F242424FF002020FE208080FCA01000F8484848FE0094 +:203F000008087E081C2AC9080A7F04081C0306382020FC3068A4222020FC20408080700854 +:203F200010111010FC13303854559010101013100008889000FE000000FC00000000FE0025 +:203F400010111010FC1310141831D010101053200008889000FE000000FC00000000FE0019 +:203F6000203F48850424242425003F242424FF00407E90088080FCA01000F8484848FE0006 +:203F8000201701415F415F5155535F454951414100FC0404F404F4145494F4442424040C74 +:203FA00010080404007F0000003F00000000FF001010204000FC000000F800000000FE00B2 +:203FC00002211514854445151525E52524252404007C0444F444F45474D454F4E454444C21 +:203FE000024125240504E525252525252C352404007C0444F444F45474D454F4E454444C69 +:2040000010121212FA10151931D111111010512690909EA8C480FC04242424545090120EFD +:204020000424242425041F10111111120204186040407C900800F010101010908084847C9D +:2040400022222F2232AFAAAAAF22272A3222222210109C2448BEA2AAAA2A2AAA8814224202 +:20406000101222224AF8112141F9410118E0410690909EA8C480FC04242424545090120E41 +:20408000101110145853509010111028244043800008889000FE000000FC00000000FE00B8 +:2040A00000241414844444101027E42424242F0090909E90A8A4C48000FCA4A4A4A4FE007A +:2040C0000000FD111111117D111111111DE141014020FC0404FC0404FC2022140844820016 +:2040E00011101312FE13323A5752921212131210009ED25254D45854D212925AD4501010BF +:20410000004429112949890919294989090951214020FC0404FC0404FC20221408448200FD +:2041200001003F22212F282F282F2A292A4C48800080FE0000BEA2A4A8A42222AAA42020EE +:2041400008043F21213F21213F20242225293020003E2224242824242222223428202020D4 +:2041600010087E42427E42427E4048445A624102007C4444447C4444447C44448484140822 +:204180000020131282434A0A1312E222222223028040F80808F80808F8404428108806001D +:2041A00010101310FC1312141833D010101152248888FE8800FE024440FC44848404281027 +:2041C0000808FF08007F42823F020204040810202020FE2000FE0204F01010101010A04080 +:2041E00002017F408111111F214101FF010101010000FE02040000F8000000FE00000000DB +:2042000002023F0202FF01020C182F48880807000008D02040FE000010E000080808F800ED +:2042200008080813103037509011121418101010404044F44850FE40808498E082827E00F1 +:2042400010101011FC24272424492A1028448400404044F44850FE40808498E082827E008F +:2042600000FE2828FEAAAAAAAEC282FE8282FE8220203C44A8102844827C444444447C44CE +:20428000101010155B54509011121529254541818080F80810A040A01806F8080808F808FF +:2042A00001211711804754181027E021212224080808FE0800FE028480FC840404042810FC +:2042C0002222FF223E087F49497F08FF0808090A2020A020FC242424242424C444842810E1 +:2042E00000001F101121213F010909112141050220F00000000000FC002010080404000024 +:20430000003F017F419D011D003F21213F21213F00F800FE0274007000F80808F80808F8BD +:2043200010113C2342BD1011FC1111111519110100FC20FE22AC20AC00FC2424FC2424FC36 +:2043400008FF083F017F419D011D003F213F213F20FE20F800FE0274007000F808F808F882 +:204360007F04081F28488F007E10207EA3223E22FC0000F01010F000FE2040FC44447C44A5 +:20438000003F213F213F02041F01063F0111254200F808F808F80020C08010F8082010089A +:2043A00013121223226263A02F2A2A2F2A2A2F28F84848F84848F800BEAAAABEAAAABEA233 +:2043C0000408103F0810247E0201013F0101FF00002010F8102048FC040000F80000FE00EE +:2043E0002027202FF823202B30E724242724A44700FC40FE4258405800FC4444FC4444FCBC +:20440000003E2222223E2222223E222222424A8520202020FE222222222242424282940893 +:20442000011109017F0509116001FF02040830C000102000FC4020100800FE8040201806C4 +:204440000023121282434A0A1213E2222222230200FC040404FC040404FC04040404FC044E +:2044600010101110FC13303956549112101011162020FC2020FE884442F888502050880699 +:2044800010131212FE133038575490101111121400FC949494FC8040FE80F888080828100F +:2044A000004020200102141023E02021202020004040A0A010482620F8081010A040202013 +:2044C000003F202724242724242720202740408F00FE00FC4444FC4444FC4040FC4040FE06 +:2044E000033C047F0C1625440501FF050931C10108084848484808281000FE40201806007D +:20450000033C047F0C16254405111F2101FF010108084848484808281000F80000FE000090 +:204520000638087E1C2A49020C31C90509112502407C9424449408806018264020100800F0 +:20454000203F488500FF0413141F017F444F4440407E900880FE409050F000FC44E4240C17 +:204560000045291129498909182849880808532000FC2424FC2424FC2020FC202020FE0006 +:204580000201FF001413141F017F42444F4440400000FE00509050F000FC0444E424140820 +:2045A00000201710824242131027E425252424048040FE00A848A8F840FC8424F414040CA0 +:2045C0000001FD111111117D101011101CE0430000FC2424FC2424FC2020FC202020FE007E +:2045E00001017F03050931C10F0000FF010105020000FC8040201806E04080FE0000000088 +:20460000003F21213F21213F01013F010101FF0000F80808F80808F80000F8000000FE0018 +:2046200020217D45897D55557C54557C001CE34000FC2424FC2424FC2020FC202020FE00C9 +:20464000201010F808101038549410101010101080808080808080808080808484847C00F2 +:204660000404FF040006780808FF1C2A498808084040FE40000808484848484848082810BD +:2046800008FF0A023F04186010107E1222224A8520FE2000F010A0402020FC2444449408E7 +:2046A0000101FF01013F2121213F1109060518E00000FE0000F8080808F800000080700EF5 +:2046C000007F04043F24243F0101FF050931C10100FC4040F84848F80000FE402018060013 +:2046E00000FF00003E222222322A2A2222222A2400FE0000F8888888C8A8A8888888A89067 +:20470000003F20202F212121212121222244489000FE0000FE0000F8080808080808502031 +:20472000007F40405F48484F494949494951952210D010107E1212121212121212222A4429 +:204740000000FD1111213D6564A424243D262000081CE000202020FE2020A8A42222A04092 +:20476000003F202020202F20202121222244489000FE00808080FC8484040404040428109B +:2047800001077C040404FF0C1615242444840404048404242424A4242424A4240404140847 +:2047A00010171020276464A72020272021222C2000FCA0A0FCA4A4FC4040FCE05048464000 +:2047C00010101722226362A426252820212224280404C41414D4545454549494040414086F +:2047E0001011172121616FA1232325252921212184C404141414D41414945404040414081E +:2048000000001F10905751113F539315252941818040FE00C4041414D41494540404140834 +:20482000020101007F000010080804040400FF0000000000FC001010202040408000FE0070 +:2048400008084A2A2D08FE181C2A2A488808090820101000FE000484844848485010FE00B0 +:204860000023121282424A0A1212E2222424291200FE00202020FC242424444484842810A0 +:2048800001013F0101FF01013F2111050931C5020000F80808FE0808F80890602018060019 +:2048A000020202027F020202020404080810204000000000F80808080808080808885020B1 +:2048C0000000FB20212121F92023223AE24202024020FE00542454FC20FE4292FA0A020676 +:2048E0000007F494979494979090F79000000F0000FC4444FC4444FC4040FC404040FE00DF +:20490000101F1121216F69A9292A2A2C2828282800FE202020FC242424A4544C840414089D +:2049200000FC4848794848784B484C78C808090A88485000FC202020FE20505088880402E0 +:204940000808FF082017110273101017102847002020FE2080FC4040FC4040FE4040FE007B +:20496000002017100001F31010101710102847004040FE80A020FC202020FE202020FE00B0 +:2049800020233A22437AA222FB2222222A35260820FE8850FE50FC54FE54FC50D854525009 +:2049A00001003F22212F2127213F2127234559810080FE0810FE20FC24FE24FC3028262083 +:2049C000101010185552549013101011101010104040A0A010482620F8081010A0402020E2 +:2049E0000024121280404E121222E32222252800202020FE405090FE1010FE101010FE00DF +:204A000002017F40881021013F212121212101010000FE0224100800F808080828100000B0 +:204A2000080814122140BE0011094922220778212020203E44C444A42828101028488402E6 +:204A40000078484848794A484878494848484B98202050508804FA00442424A88810FE0007 +:204A6000202239214078A721F9212121293224001010107E2028487E0808FE0808887E005F +:204A80000201FF041414244400010848484887000000FE4050484444000088841212F0009A +:204AA00010101710545B519213101129264440804040FC8080E02020FC2028242222A0406E +:204AC0001010272048FB112243F841011AE440004040FC8080E02020FC2028242222A04016 +:204AE000101095555911FD3139555591111111114020FC0404FC0404FC20221408448200D4 +:204B000000402F200003121223E02222242821008040FE0000F80808F8405048444440804D +:204B2000002310825224E1222501FF050931C10100F09094929210502000FE4020180600ED +:204B40000023904212E5222411097F050931C10100F09094921250201020FC4020180600B7 +:204B600002013F20203F20203F222120202428300000F01010F01010F00810A040201806B0 +:204B800000FF0404047F4444444A4A514240404000FE404040FC444444A4941404041408E2 +:204BA000202320FC405392FE12121EF35212121200FE505050FE525252AAA60202020A0470 +:204BC000001F101F10FF001F111F111F011F017F00F010F010FE00F010F010F000F000FC7F +:204BE00000007B484849497949494848794A00004020FE0000FC040404FC20A82422A0406A +:204C000002017F001F101F007F408F08081020C00000FC00F010F000FE02E4202022221E04 +:204C2000002013100001F11111111014191200004020FE0000FC040404FC20A82422A0406D +:204C400020202720F522272A33E223202224A9404040FCA01408FC0AF808F8404844448018 +:204C600000FC4B4A7A4A4A7A4A4A4F7AC808090A00801E525252525252D25A549090101091 +:204C800010101720256267AA23222320222429204040FCA01408FC0AF808F8404844448048 +:204CA00000001F109057501030509010202041808040FE0000FC081020404040404040806B +:204CC00020202720ADB2A7AA23222320524C49804040FCA01408FC0AF808F84048444480E8 +:204CE000017F40BC2414250618E30C310638073800FE02FC482848C0300E408030C00000BE +:204D0000002310100000F010101010111028470000F8102040404040404040408000FE00EA +:204D2000002017108542471A1322E320222429004040FCA01408FC0AF808F8404844448097 +:204D4000007F000000010101010101010101050200F81020408000000000000000000000DC +:204D600020272427FC27212B35E0232C2322A34200FC44FC44FC00F810E01806F808F80822 +:204D800020203B204279A325F9212120293224002020FE508A04FE04FC04FC202422A240B9 +:204DA000003F202F292529212638232C414E810E80FE007C2414A460188620408830C00056 +:204DC00008084A2A2C08FE181C2A2A48880808080888484808884848080EF8080808080837 +:204DE000007F08081F112121528A0404081020400484042424242424242424240404140862 +:204E0000007F081F21520C30C201FF040C34C50604842424242424040C00FE88502018060C +:204E2000007F08081F21510A040830C02422428004842424242424240414080088444404B0 +:204E40000111112141010EF1013F020204081060001008244480000000F808080808502085 +:204E60000044281328488F081929498909095121888888FE8888FE00FC0404FC0404FC0468 +:204E80000101F921272121FB23252539E141010110101010BC101038B85454921010101042 +:204EA00010101010FD103038545091121410101020202020FE207070A8A82422202020201E +:204EC0000001F82320417A49C9494A4D784902042024A8FEA824220404DE44549E04040422 +:204EE0003F017F419D011D08087E081C2AC90808F800FE027400702020FC3068A42220208C +:204F000008080849494A4C484949494949090908808080FE40202000FC24242424FC0400F8 +:204F200008081412214884047F01221408040400007C444848D04848444444685040404090 +:204F40004041788B10F9AAA9F9A9AAFD0019E2442024A8FEA824220404DE44549E040404E9 +:204F600001211111874141131325E5292121210110101010BC101038B854549210101010A1 +:204F8000004F20270405151524E72023202F220440FE00FC04F414F404FC00F800FE48C449 +:204FA0000813305097101013001F101111020C3038C04040FC4040F800F0101010C03008F9 +:204FC00002017F0804030C30C01F101010101F100000FC204080601806F010101010F0102C +:204FE00010101010FD1214101B30D011101050204040A0A010482620F8081010A0402020E4 +:205000000000FC101011127C111010101CE040002020505088241210FC040888502010108A +:205020000808FF08013F01FF1022470814031CE02020FE2000F800FE1008E4204080700ED7 +:205040003F017F419D011D020C32C11F00060100F800FE0274007080601806E02040804094 +:205060001010505E5051FE009392AAC6828EF2022020505088241210FC040888502010105C +:2050800020203820417AA420FB202021283020004040A0A010482620F8081010A040202087 +:2050A000080808101132345093101011101010104040A0A010482620F8081010A04020205F +:2050C000442428FC10117E1011FC1010202040802020505088241210FC040888502010109A +:2050E000004023200007111224E123242020230C4040F84040FE108884F010A040A0100C9A +:20510000003F00001F00003F01111122040830C000F80808F80808F8001010A0402018066B +:2051200000784950506350494A486952404041462020FC2020FE884442F888502050880668 +:2051400010101010545556545554545C640000002020505088241210FC0408885020101031 +:205160001011282443910901FD0509512010110200FE2040FC042424242424445088040211 +:20518000001F1010101F02027F0204040810204000F0101010F00000F808080808085020FC +:2051A000010102040A1121C01F000004020100000000804020100806F010204080008080E7 +:2051C00000271415844546101724E42724242704807C2424A4544880FC4444FC4444FC049B +:2051E0000000FB20202123F821212139E24204084020FC409008FC04505050505052520EF6 +:2052000010131212FE123338575292131212131240BE129252AA2440FE2222FE2222FE02AF +:205220000000FB2020417B48C94949497A4A04084020FC409008FC04505050505052520E45 +:205240002023223A4A528320232222232A32230240BE129252AA2440FE2222FE2222FE02DF +:2052600006784048445A61003F21213F21213F2000FC444444940800F80808F80808F80854 +:20528000100808FF024222141408081424428200040404A424242424242424240404140861 +:2052A00000001F109754551536509714272447848040FE807C24A4544880FC44FC44FC0405 +:2052C00000201710814247101022E222222224088040FE801008FC0400484848484A4A4677 +:2052E00010101312FE12323A565293121010111200801E525252525252D25A549090101013 +:205300000201000000FF000004040808102040000000808000FE000040201008080404007D +:2053200004040404FF040404040808101122448020101000FE80888890A0C08282827E0075 +:205340000404FF091166007F080F080F08FF00008040FE4084FC00FC20E020E03EE020203A +:20536000000078484B484848484979490202040890888880FEA0A0A4A428283222629E009D +:2053800010103F284580047F0404080810234C8040407E90084020FC808890A0C282827EB9 +:2053A000017F4891794A506156494A6B5443404700FE2214F090609806F040F840F840FC60 +:2053C00000794A5550635C4B484A6B5443404F4080F80810E01806F84040FC40F840FE0080 +:2053E0000404FF091111234D8001013F0101FF004020FE1020C00404FC0000F80000FE0001 +:2054000010101010FB10141830D111111212542890888880FEA0A0A4A428283222629E0008 +:20542000007C44484B504848444545695242444890888880FEA0A0A4A428283222629E0098 +:2054400020212020FB20217268A7A021212021262024A820FEA8240240FE88089060980493 +:20546000011109FF050931C002FF04081C030C70001020FE4020180600FE20204080700849 +:2054800010111010FB10111A30D71011111051262024A820FEA8240240FE880890609804A3 +:2054A000203F488511097F05196104FF081E033C407E90081020FC40300C00FE2040C038EC +:2054C00000472424078447541726E62A2A32220200FE0202FE00FE20FE22AA22AA222A0446 +:2054E000007B48505262524A4A4A6A524242434000FE2020FCA4A4A4D48484948800FE00D6 +:205500000808FF0809003F20203F2020204040802020FE202080F80808F808000000000047 +:2055200001010101011F1010101F1010202040800000FC0000F8080808F8080000000000CC +:2055400010101E10107C4444447C44404040800300FE2040FC849494949494A4304884023E +:2055600001003F212027242424272424444888100080FE0080F8080808F808000000000076 +:2055800010101015595151911111112926424488804040FC040404FC0400000000000000A2 +:2055A00020202023FA22232A32E223222424A942407C40FE4278C43C4040FC4484841408DB +:2055C00001010101013F20242221222428203F200000FE0000F80848880888482808F8083D +:2055E0000101013F21212F2120212F212142449800F800FC04608808F800F80808085020A7 +:20560000081F207FA13F213F00FF001F101F101F00E020F808F808F800FE00F010F010F022 +:2056200008087E1C2AC9083F223F223F282F488F2020FC70A826A0FC40F848F84478423ECC +:205640000001F8202140784BC84A4948794A000000F80808F80808FE202274A82422A04015 +:205660003F017F419D011D007C457C115C505CE0F800FE0274007040F84830CE00F888F867 +:20568000007C4444457C1010115C5050505CE000404078885020508806F888888888F88826 +:2056A000007C4454555454545554541028244480404078885020508806F888888888F88802 +:2056C00001003F22223F22223F28282F48488B0C0080FE2020FC2424FC4044586044443CE0 +:2056E00000271414844741111125E52525252E001090BCA4C4A8102846C03C2424A43C2454 +:20570000402120F81110203368AA21202122202000F80808F80808FE202274A82422A04034 +:20572000003F00001F0000FF012111050931C50200F01010F01010FE00089060201806007F +:20574000007C44494850484B4444456951414140202020FC202020FE202024242424FC0442 +:205760000077115533550C33C418620C710618E01014121016781212921414881A2A468286 +:2057800000F808484848487C04041CE444052912402020FC848484FC848080808000000059 +:2057A000001F101010101F00003F202020203F2000F010101010F00000F808080808F80815 +:2057C00010103C2040BC1010FC1111111519110100FC84848484FC0000FE02020202FE02B4 +:2057E00010131222226263A0202724242424272400F808080808F80000FC04040404FC048D +:2058000020101001FE20203C24242424244454888080FE000CF090909294888884A4C2803F +:205820003F203F212932212529392928494A880BFC04FC00FE00FC04FC04FC80FC88708E37 +:205840003F203F24223F222428213F224740830CFC04FC90A0FCA0908800FC1020C030081B +:20586000101120204BF8112240FB400119E041062024A820FEA8240240FE88089060980463 +:205880000101013F21212F21202020202A4A528100F800FC04608808F8008044421210F075 +:2058A000203F409F007F007F003F00FF2415244C00FC00F000F01090909090F28A0A86424B +:2058C000080813204F08133050931010171010104040F848FE48F84040F84040FC404040EF +:2058E00002017F02442F11224F0001FF010101010000FC0044881048E42000FE0000000009 +:2059000000201017844447141424E42425292912407C40FE4270C4443C20105442424A38DA +:205920001011202049F8102340FA410019E2400000F80808F80808FE202274A82422A0404A +:205940000201FF04141424440101212121213F000000FE4050484444000008080808F8086E +:205960000201FF04142444003F013F017F0105020000FE40504844F00000F800FC000000A0 +:205980000201FF0414142444003F0001FF0105020000FE405048444400E08000FE0000006E +:2059A00000402F20028244501027E021222428008040FEA0A8A4A44040FEE0504844424090 +:2059C0000C70444464545444444C74040808102000FC8484A49494848484A8908080808097 +:2059E000040E380808FF08083E222222223E220040404040404040404040404242423E0054 +:205A000010101310FC1111151930D111121450204020FE0000FC0404FC2028242222A04061 +:205A20000000F8A9ABACF8A8A9AAADF9890101018080F80810A040A01806F8080808F8088B +:205A400010101010FD1214111931D111111150204040A0A010080610204080000404FC0042 +:205A6000202020FC415294FD11111DF1511110104040A0A010080610204080000404FC0022 +:205A8000080808101132345191111111111110104040A0A010080610204080000404FC003E +:205AA00001010204081020C808080F0808080700000080402010080630C000080808F800A2 +:205AC00000201010814244111121E121212120004040A0A010080610204080000404FC0006 +:205AE0001010202049FA142141F9410119E140004040A0A010080610204080000404FC0046 +:205B0000002010100102F41111111111151910004040A0A010080610204080000404FC00E9 +:205B200008FF08003F24243F0207083402010E7020FE2000F84848F800F01020408000002C +:205B40001011117D555554547D5010171CE5420000FC24FC24FC4088F02044FE22242260EF +:205B6000003F2424243F02040F10680402031CE000F8484848F80000F01020408000000001 +:205B8000004724240700E122252020212E508F0000FCA4A4FC80F80810A040800000FE00AB +:205BA00020233A22427BA020F82122202830210600FE525252FE2040FC04885020408000E5 +:205BC000203F48853F24243F0207083402010E70407E9008F84848F800F010204080000057 +:205BE00000F909494949487C05041CE744052A1000FC24FC24FC4088F02044FE2224226057 +:205C0000201101F909111539549310101112101000FC2424FC2424FC20FE70A82422202067 +:205C20000808FF0820101182484916E1212121212020FE2080F80890609806F80808F8080A +:205C40000020111285404010132CE322222223028080F80810A040A01806F8080808F80881 +:205C600000F808494B4C487C05061DE5450529118080F80810A040A01806F8080808F80831 +:205C8000101020214BFC102041FA450119E141018080F80810A040A01806F8080808F808B1 +:205CA00010131010FD252525244828132844840000F01010101010FC040404F40404281022 +:205CC00001003F2222223F2226272A2A524282020080FE101010BE101038B4549210101076 +:205CE0000003FC101111117D101010131CE0400000F80808080808FE020202FA0202140828 +:205D00000001FC1010203C6464A424253C24200000F80808888888FE020202FA0202140817 +:205D20001011107C545454547C5010151CE4400000F80808888888FE020202FA0202140877 +:205D4000007F00001010101F000000FF0000000000E02020202020FC040404E404042810CA +:205D6000007C44447C003F0008080F007F00000000F88888F800E0202020FC04E404281066 +:205D80000000F794949497949495F596080810004020FE909090FC90D8B8B4D4929090905D +:205DA00000037848494949494848784B0000000000F01010101010FC040404F4040428102D +:205DC0001011111111FD11111010111CE040030000FC2424FC2424FC2020FC202020FE00C2 +:205DE000007F00080424101001FF0102040830C000FC04888080808000FE00C02010080453 +:205E000001017F01013F0101FF081F2844031CE00000FC0000F80000FE00F0204080700EED +:205E200001013F01017F0402120809FF020418600000F80000FC0488808000FE4020100804 +:205E4000002017100000F01010111112142847000000FE8080FC8484840404281000FE0070 +:205E60000078484948784B48487849494A4C4898402010E02234B8B0A8A828242422A0402E +:205E80000101F79190F79090F7949495F69404040808FE0800FE9090FE92926A46020A0475 +:205EA0002322233A4B508724242720232930230CF808F808F800FCA4A4FC00F810E01806A6 +:205EC0000201FF04142444011F11111F11017F200000FE4050484400F01010F00008FC040C +:205EE00001211711804740101724E425262424040808FE0800FE9090FE92926A46020A0475 +:205F000008FF081F101F107F447F003F080718E020FE20F010F010FC44FC00F020C0300E04 +:205F2000001F101F101F007F447F003F080718E000F010F010F000FC44FC00F020C0300E22 +:205F400023222332ABA0A7A4242720232120232CF808F808F800FCA4A4FC00F810E01806B5 +:205F600003221312834047141427E0232120230CF808F808F800FCA4A4FC00F810E01806CD +:205F8000034223220300E724242720232930230CF808F808F800FCA4A4FC00F810E0180615 +:205FA0000808FF08080201FF0808080808080F002020FE20200000FE000000000000FC0009 +:205FC0000808FF0808201087490911E1212121002020FE20204020FE000000000000FC006C +:205FE0000201FF1010101F001F101F101F101F100000FE000000F800F010F010F010F0109E +:2060000020131202FA434242434242427A02030200FC040404FC2020FE202010128A0602B8 +:20602000101010101B545050901010101010101020101000FE808080808080808080FE0055 +:2060400008FF0802027F040830C8087F0810204020FE204020FC4020182620FC20202020D7 +:2060600000442B102848890919294989090951218888FE888800FC242424FC242424FC0419 +:206080000808FF08003F000601FF02040830C2012020FE2000F0204080FE828480808000F1 +:2060A00020203B204078A121F9212121293121018888FE888800FC242424FC242424FC0405 +:2060C00000017E0202033E020203FE020202020110F8000000F0000000FC0000040404FCF2 +:2060E000001F000201007F010204081020C0020100F010204080FE82848080808080800019 +:2061000020203B22427AA222FA2223222830210200801E525252525252D25A54909010103C +:206120000C70444444444444444C74040808102000FC8484848484848484A89080808080AF +:206140000808FF0800003F2020202020204041862020FE209088FC808888505024548C0478 +:20616000003F202F202F20001F101F101F101F1000F808E808E80800F010F010F010F01086 +:20618000202322FAAAAAAAA8A9A9A9B92121212100FC04F404F40400F808F808F808F808D2 +:2061A0000C30C3154931C91525CC1424C40429122040FC0404FC0404FC50505092920E00C1 +:2061C00006784048445A61001F10111111020C7000FC444444940800F010101010601804CA +:2061E000010102020408102041020408103F100000000000404080800000201008FC0400F7 +:206200000000FE1010117E101010101EF040010240404080FE0888888850502050880402C4 +:2062200010101010FC113238545490101010111240404080FE0888888850502050880402A0 +:2062400011111112FD11393557519212131010100000FC00F8084828FE084828FC08502098 +:2062600000FE2828FFAAAAAAAEC282FE8282FE8240407E807C446454FE44A494FE042810B5 +:206280003F017F419D011D101F205F12FF203F00F800FE0274007000FC00F010FE90FC3093 +:2062A000101013105458509010101328244542808888FE8888F88888F820FE70A8242220CF +:2062C00000211111814254181322E1212020210E00F0101010100E00F8080810A040B00EB2 +:2062E000003F21213F202F28282F282F48488F0800F80808F800F80808F808F80808F80882 +:2063000010101310FC24242424482B10284586008888FE8888F88888F820FE70A82422207E +:2063200021203B204079A020FB202023283020030488FE2020FC2020FE0020FE205088064F +:20634000101F20205F901211FF2022213F00000000FC0000F0101010FE101010FC10A040E5 +:2063600008047F01013F0101FF01017F020418E02040FC0000F80000FE0000FC8040300E85 +:20638000000078494848487B48484849794A0000202020FC202020FE70A8A82424222020E1 +:2063A00002017F408424253C04077C24252644840000FE022420FC2020FE60B02826202038 +:2063C00010101011FC2424272448281129468400202020FC202020FE70A8A8242422202055 +:2063E00010111111FD252525254929112946820400FC2424FC007C44447C447C44447C4489 +:206400002013104040404040404040404040404000FC0404040404040404040404041408B1 +:206420002017004241414454546444434040404000FC040404040424145444C404041408C2 +:20644000090808121232325292121212121212120080BC04040404040404040404041408B5 +:206460000808FF0800007C44447C44447C4401022020FE2000FC8484FC8484FC84841408B4 +:2064800008FF087F408F007F063B0419620C720120FE20FE02E400FC0008B0C0A09886008D +:2064A00021272127F423207768A1A6212621262010FC10FC04F800FC8044A870A826A040A7 +:2064C000007C44447C44447C01023F242424FF0000FC84FC84FC84841408F8484848FE009D +:2064E00020213820407BA020F82121212931270000FC081020FE20A040FC54545454FE0030 +:2065000000452810284B8808182949890909572000FC081020FE20A040FC54545454FE00E3 +:2065200008087E081C2AC8040708142201020C702020FC2070A82600F01020408000000075 +:20654000001F0001FF010105023F24242424FF0000E04080FE00000000F848484848FE0091 +:20656000000079484878484B78484849794A0000202024A4A82020FE70A8A824242220209B +:2065800000FE2928FEAAAAABAEC282FE8283FE82084A2AAC883E08989CAACA8888403E000E +:2065A000003F243F262D3421213F212F215F418180FE107C38541220203E203C203E20207F +:2065C00001003F222F262B322024223F214244980080FE107C3854928090A0FCC0A0988671 +:2065E000002211110007F01011121410102847004048485040FC40E0504844404000FE00B4 +:20660000004024220200E026222223222A3528001092525410FE1038549210101000FE002A +:2066200000F80809097A444041790A0A0C085020808080FE02042020282424222220A04080 +:206640000121110909017F030505091121C10101000808102000FC804040201008060000F0 +:20666000081CF01010FC103A36525490111214100040202808889094A2A2C288888878009B +:20668000017E120909001F101111111202041860F80010102000F010101010908082827E6B +:2066A00000201010814141151525E529212324080080402828081014222242880808F80078 +:2066C00002017F428928490E77013F213F017F000000FE0224489410F000F808F808FC0457 +:2066E00002017F408209284B1CE7012121213F000000FE022440881410F000080808F8081C +:20670000007F409F101F101F02FF093FD111110100FE02F410F010F000FE20F816502000F0 +:2067200010101111FD11313854539212121210102040FC04FC04FC2020FE22222A242020A5 +:2067400000017D45457D45457D4545457D45010100FC040404FC2020FE202010124A8602A4 +:206760001010212149F1112040FB42021AE240002040FC04FC04FC2020FE22222A24202025 +:206780007F405F405F040F103F51111F02041860FC04F404F400E020F80808F88082827EED +:2067A00008080F10207FA121213F2204081020C00000E02040F8080808F888808082827E79 +:2067C00020203E44887F4949497F14142524438020202020FC242424244444940A02FE0030 +:2067E00010101011FE25252525492810284481028080F80810FC242424FC50509092120E00 +:20680000101720204BF2122242FA42021AE2430200FE4080FC9494F49494F4949494FC0431 +:2068200000FF0202043F24242724242724243F2000FE000000F84848C84848C84848F80857 +:206840000808FF0808003F2121213F2121213F202020FE202000F8080808F8080808F808D8 +:2068600010101310FC1011151931D111111151218888FE888800FC242424FC242424FC04F5 +:2068800000007B484878494979494949794901018888FE888800FC242424FC242424FC04DD +:2068A00008FF080830CA2C30C81424CC1424D40920FE201020FC8484FC8484FC484A8A06F6 +:2068C000081CF01010FC11313A54549010101013202020A8A4A22220242428081020C00099 +:2068E00040202F89494F09292F49C94F4940400110101010145252921014040810204080B2 +:2069000001003F2020202F2828282F2848488F080080FE008080F8888888F8888888F80814 +:2069200010101010FC2425252648281028448003202020A8A4A22220242428081020C00020 +:2069400008FF08003F24243F003F20302824408320FE2000F84848F890FC80485024D40C5E +:2069600000FF01011111112142020404081020C000FE000008081020808040402010080682 +:20698000003F2020203F20203F2020202428302000F8080808F88080FC80404024140C0452 +:2069A00010131212FE1312161B32D2121212532200FC040404FC2020FE202010128A060257 +:2069C00000003F24242424242424242424FF00000000F848484848484848484848FE00004B +:2069E00040407F807E42524AFF42928AFF0214092020203E444444A4A8281010284884024D +:206A0000111012121A565352921212121312121200BE82024222FE925222528A0A020A046B +:206A200020170041414F4949494F4941415E484000FC040404E4242424E40424F414040CF7 +:206A400000007C4444447C4444447C440101020400FC848484FC848484FC848404041408A6 +:206A6000202322F8A9A9A9A9F9A0202B38E8410200FE0200FC04FC04FC4020FE00880402E6 +:206A8000000079494949494949497848030000002040FC044424240C00FE0202FA021408A9 +:206AA00010103C2142BC1010FC111210141810004040FC048850204080FC84848484FC840C +:206AC0000202070814620201061FE80808080F080000F0102040800000F808080808F808F6 +:206AE000010102040837C0003E2222223E2200000000804020D80600F8888888A890808005 +:206B0000004720240204E021262023202B30200700BC84A494A4508826C010648830C00012 +:206B200011111711FC1312171A33D017101152241010FC1000F808F808F840FCA0100806EA +:206B4000047F041F101F101F04FF1027C11F010340FC40F010F010F000FE508806F00000DB +:206B600008FF083F222F23262A203F444F94270420FEA0FE10BC18B45200FC00F808F808B0 +:206B800011111711FC13323B56539017101112141010FC1000F808F808F840FCA01008067A +:206BA00000784B48487949494979484B4848499A8888FE8800FC04FC04FC20FE5088040221 +:206BC000003F222F22272A222F2122274A52830280FE107C1038D410FC0000F80808F8089C +:206BE000003F243F262D3420272027202F40418080FE107C38541238C040F840FE40408078 +:206C0000003F243F262D352F282F282F21424CB080FE107C385412F888F888F850F88A7E1E +:206C200010101013FC1010151830D01111125020202020FE202020FC70A8A8242422202000 +:206C4000010101FF0101017F0305091121C10101000000FE000000FC8040201008060000B2 +:206C60000808FF08001F101F101F017F020418E02020FE2000F010F010F000FC8040300EBA +:206C8000003F29253F013F01FF2442013F0101FF00F82848F800F800FE482400F80000FE89 +:206CA00000FE92D6BA93FE10FE101EE002AAA9822028242420FE202020505050888804021C +:206CC000002010178040480B1010E12224282000404040FE404040FC40E050484640404093 +:206CE0000121171180434A0B1213E0272021220C1010FC1000F808F808F840FCA010080679 +:206D0000017F40843F041F101F101F027F0418E000FE0244F840F010F010F000FC40300E0C +:206D2000007D444848514949454545695141414100FE202040FC040404FC04040404FC0441 +:206D400002422F220203E22223202F2029322C000808FE0808F80808F840FEE05048464022 +:206D6000020408103F0001111F2101FF0101010100002010F8080000F80000FE000000003A +:206D80000808FF08080F08080F01FF050931C1012020FE2020E02020E000FE4020180600AB +:206DA00010111111FD1111171A32D2121310502000F80848280808FE08884808FE085020C3 +:206DC000080848487E4889080EF8480808080B08202020202020FC20202020202020FE00A9 +:206DE000020101FF00003F2121213F2121213F20000000FE0000F8080808F8080808F808CF +:206E000010101010FC242427254929112944840000FC84A4948484FE04442404FE042810C6 +:206E2000001F10121111FF202221213F0000000000F010101010FE10101010FC1010A040C3 +:206E4000047F041F101F101F04FF1021CF01013F40FC40F010F010F000FE1008E60000F88A +:206E6000047F041F101F101F04FF102FC80F080F40FC40F010F010F000FE10E826E020E076 +:206E8000047F041F101F101F04FF113FD111110140FC40F010F010F000FE10F816502000AF +:206EA000047F041F101F101F04FF1022DF04083040FC40F010F010F000FE1008F610502086 +:206EC000047F041F101F101F04FF1222CB122A0440FC40F010F010F000FE100826909000A4 +:206EE000010101017F030505091121418101010100000000FC8040402010080402000000C8 +:206F0000003F2020203F2020203F202020203F2000F8080808F8080808F808080808F808DD +:206F200000007948487B48497A484948784803002020FC2020FE88042220FC202020FE0084 +:206F4000080848487E498A080EF848080808090A40404080FE088888885050205088040243 +:206F6000081CF11111FD113835565093101110132040FC04FC04FC202432C018608C30C05C +:206F8000010618EF001F101F001F013F017F010300C030EE00F010F020C000F800FC000010 +:206FA000000F725252575252525F72520204050800DE525254D4585452D2525A545050907F +:206FC0000000784B4A4A4A4A4A4A7B4A02020202404040FC44444444A49414040404140825 +:206FE00010103C2141BD1111FD11111115191101202020FE22222222524A8A0202020A0464 +:20700000007E1212127E12127E121222224A8400007C4448485048484444446850404040F2 +:20702000202F2222F2575252529F52222254558800DE525254D4585452D2525A545050906E +:20704000101020204BF2122242FA42031AE2420220202020FE222222524A8A0202020A0480 +:2070600010103F204F803F003F111217202042810000FC00F000F010101010D04A4A8602FF +:20708000003F040404040404080808101020408000F0102020407C04040404040404281031 +:2070A00010101310FC24242424482911294682040000F8889090A0BC84840404040428103E +:2070C00000FF0808107F5555555555555555414308880808FE080808482828080808281048 +:2070E00002027F040830CF00007F0111112145020000FC402018E60000FC00100804040082 +:207100000101FF01017F48444F41415F414141400000FE0000FC2444E40404F404041408C8 +:20712000003F21213F21213F01017F02040830C000F80808F80808F80000FC040404281047 +:207140000000FC05054B2D291111292545810101A09080FE1010FC1010FC101010FE00003C +:20716000017F111F01FF921E043F04FF040C35C600FC10F000FE92F040F840FE8850300E56 +:2071800010101013FC1010131833D010111152248080BCC05024D40C00FE909012120E009A +:2071A0000078484F4878484A4A7A4A4A4A4A4B98402020FE00009054242454940404FC0405 +:2071C00010101017185450529212121212121310402020FE00009054242454940404FC04B1 +:2071E00020170042415F41414F4949494941414000FC040404F40404E42424A44404140887 +:207200000020101083424B0A1312E0272020200040407E40FC04FC04FC4440FE40404040CC +:2072200000037A4A4A4B4A4A4A4A7A4A0404081000FC040404FC00404448704042423E00A4 +:20724000202023384A5181202320212328302106083CC04424280040FE8808906050880423 +:207260000101017F414141424244485040404040000000FC04040484442414140404140829 +:2072800021212721F157555557915325295151810808C8101EE45454D414944848141422DE +:2072A000102442FF01007E42427E42427E424A44404448704042423E004448704042423ECA +:2072C00010111111FD252525254929112946820400FC040404FC00404448704042423E0020 +:2072E0003F017F419D011D0638203C203F0810E0F800FE0274007000F808F808F842423E4C +:2073000008080B1212333252931010101011121400409C04049C0404FC9090909012120E77 +:207320000023121282434A0A1212E2222424281000FC040404FC00404448704042423E0003 +:20734000001F1010101F1012121213122222418000FC040404FC00000C30C0020202FE004B +:2073600010101012FA12121A32D212121312502008884828280808080808109824244282D2 +:2073800008080811113234509111121214101010808080FE02042020282424222220A0407B +:2073A000007F40447F44417F444F546447407F0000FC0010FE1000FE00F80808F800FE00E0 +:2073C00000784F484B784B484B7A4A4A4A494A9C1814FE10D010F010E828A8A8AA4A2622C0 +:2073E0000241212F0000E4242427202122548F00080810FE4040444444FC84000000FE0079 +:2074000000271010874444171024E2222420250200BC8484BC2020BC84A49494A484281030 +:2074200008FF087F011111FF101F203F0049840020FE20FC00F800FE00F800FC0424940859 +:2074400010101010FC10141833D21212121253224040407E40404040FC0404040404FC04A4 +:2074600010101F2020401F101010FF00000000000000FC808080F8808080FE80808080808D +:207480000001FD1111213D6565A525253D26220400FE0202FE24247E2424FE52544864428C +:2074A00010101310FB10111A33D01113101750208888DE88DE885422FC8020FC20FE20204D +:2074C00010101010FD1211141830D01212125420202050884422F8085020A4828A8A7800D6 +:2074E000010102040A31C10F000001084848870000008040201806E0408000849212F000A3 +:2075000010101111FD25252525492911294585014020FC0404FC0404FC2022140844820099 +:2075200000FE2828FEAAAAAAAEC282FE8282FE822010FC8484FC8484FCA2A4989088C4821D +:2075400001021F1012111110101F00007F0000000000F0101010502000FC0404E404281053 +:20756000003F20203F2020202E2222244448920100F80808F8808088D0E0A0A09088840024 +:2075800010111111FD1111151830D1101010532000FC0404FC0404FC2020FC202020FE001A +:2075A000007F080F080F08FF003E0222140834C300FC20E020E03EE020F888885020D80612 +:2075C00008FF287D447C417C457C001F00FF010320FE20FC8850FE20FC2000E040FE000035 +:2075E0000000F29292929F909494F4940504070040407C404040FE004444A4941404FC0462 +:20760000202339214179A127F82720222932240800FC08F808F80EF808BCA4A42890A846AF +:2076200020203B22437AA322FB202720293224004080F808F808F808F840FEE05048464056 +:2076400000271414874444171020E72020202F0000FC0404FC0404FC4040FC404040FE00D1 +:207660000909113254991112141110025151900F0000FC044850484444408000041212F0ED +:2076800020202023FA2420706BA0A02020202020402020FE02040000FE2020202020A0406C +:2076A000004428132A4C88081B28488808085020402020FE02040000FE2020202020A040B0 +:2076C00004452624031014172A22EF2225242801007C04A8907C14945050DC5050B09E00C4 +:2076E0000201017F4080003F0101010101010502000000FE020400F80000000000000000FF +:2077000010101013FA14101833D0101010105020402020FE02040000FE2020202020A0403B +:2077200000201017844840101720E02020202100804040FC04080000FC404040404040804A +:20774000011111111F21410101FF01010101010100000000F800000000FE00000000000077 +:2077600010111010FC1010151830D0101010572000FC4444444444FC848484848484FE0076 +:2077800010113C2040BC1011FC1010101418130000F84848484848F8888888888888FE005E +:2077A0001011202444F8102140FC40001CE0470000FC4444444444FC848484848484FE00D6 +:2077C0000078484B4A7C4848497A4C4848484898202020FE4244A0A2A498908884A2C080A1 +:2077E00000201017844841111325E92121212101404040FC848840444830201008448200BC +:207800000101017F4282050508182848880A0C08000000FC0408000890A040201008060024 +:20782000007F01013F0101FF000808FF0810204000FC0000F80000FE002020FE2020202050 +:2078400010101110FC24242424482810284481020000FC8484848888505020205088040296 +:207860001010FE2244281028C502027F040810600000FC8488502058860000F80808502092 +:207880001010FE2244281028C5000108484887000000FC8488502058860000849212F000B1 +:2078A0000202020204FF040808101806010618600000000000FE20202040408080601008A6 +:2078C00000077A49484B78484F49497A4A0408033CC0442800FC8080FE00F8885020D806A7 +:2078E0000101013F21212F21202027243F44478000F800FC04608808F800F800FE00F80011 +:2079000000001F1090535212325F9212222340808040FE0000FC000000FE000000FC000003 +:2079200010171212FA17121A32DF12121214552800DE525254D4585452D2525A545050903D +:207940002027202F38ABA0A3A02F20272424242400FC40FE4258405800FE40FCA4A4A40C27 +:20796000101194575A11FC31385754911111111100FC20FE22AC20AC00FE20FC5454540CD5 +:20798000014127210100E72021232529293121010808FE084840FE8000FC04040404FC041F +:2079A0000001F791919F91919193FD910101050228A4242020FE2024A4282810122A4682B7 +:2079C000007E40446454494854546440407E01024040407C848820202050505088880402A1 +:2079E000007E40446454484854546440417E00002040FC84A484948880FE0202FA02140874 +:207A0000007E40446454494855546440407E000300F8888888860000FC84885020508806A1 +:207A200008FF0810117D117D11FC133A5692121220FE2000FC24FC24FC20FE222AFA0A06B7 +:207A400000037A4A4A4A4A4A4A4A7A4A0302030000FC000888505020205050880800FE003D +:207A600010171424276464A7202F28282B29282800FC4444FC4444FC40FE4252F2120A04E6 +:207A80000023121282424A0A1212E2222322230000FC000888505020205050880800FE005D +:207AA000020272525F525252535E725202020A041010207CC44444C47C44444444447C44C6 +:207AC000007C4545457D11115D5151525EE4081000202020202020202010101008080402CB +:207AE0000E7455555555555555555552525190100000FC242424FC00000202FE0000FE000E +:207B00001010107D555555555555555D11111111202040FC04040404FC0404040404FC0428 +:207B200010101011195551519111111111111111202040FC04040404FC0404040404FC0450 +:207B400000FE10107C1010FE003F21213F20201F00FE10107C1010FE00F80808F80202FE94 +:207B600010101011FD1111151931D11111115121202040FC04040404FC0404040404FC0434 +:207B800010101017F810101B30D01017101050209090909E9090909C9090909E909090908C +:207BA00008484949497D41417948494B484848884080FC2424FC2444FC9010FE10101010A4 +:207BC000080810274808103350901017101010109090909E9090909C9090909E909090905C +:207BE00001432E22028F4252122FE2222222240800BC10103C90103C10907E1010101010B5 +:207C000000201714844545151525E52525292911083CC0001CE020222428101008448200AE +:207C20002221FA2072A922FF0837C11F017F01038808BE089C2A88FE20D806F000FC00007C +:207C400000271211874142141322E2232222230278C04850FC504806F84848F84848F8089F +:207C600002041F1110FF101221403F242424FF000000F01090FE10105020F8484848FE00A6 +:207C8000083E222A7E222A4600FF081F28C80F0878488E00F84830CC00FE00F80808F80885 +:207CA0000000784849794A4D784848487949020410909088080404FA888888880808281069 +:207CC00000007D545454557C545457547C440000202024A4A820FC202020FE20202020207D +:207CE00004442425047F040404FF0408081020400484842424A4242424E42424040414082D +:207D000010109559117D1111FF11111121224284081CE00000FC4444442828101028448240 +:207D200000001F10101F10101010FF000000000020F0000000F880808080FE004020100828 +:207D400001003F2222222F2222222424484893200080FE201000FC404048506042C23E00F9 +:207D600002013F08047F42813F040407080810200000F82040FE0204F80000F01010502011 +:207D8000101013FD107B12FC103B3454901111124020FC0890FE024420FC80F888082810EF +:207DA000003C2524243C2524243C272424445488202024A4A820FC202020FE2020202020DC +:207DC00012121212FA17121A32D21212141458301010107C14949494A4A4D48A82827E00A2 +:207DE000000079494A4D494949497949010100008080FC0404F4141414F404281202FE00DC +:207E000010103F2141BD25253D21252220201F0004040424242424242424242484849408A2 +:207E2000101011155A55519111111129254540808080FC0404F4141414F404281202FE007F +:207E4000201001F90A15113559951511111110108080FC0404F4141414F404281202FE00D7 +:207E6000007C4545467D11115D5151515DE100008080FC0404F4141414F404281202FE0023 +:207E80000121111282474A121223E222222221000000FC0404E4242424E414080202FE0084 +:207EA00000037848484848494A4C78480000070000FC20204040D048444440404000FE0067 +:207EC000007B4848487848494A7C484848484F9800FC20204040D048444440404000FE005F +:207EE0001010111011FC10131010111DE14101014020FC00089000FE0000FC040404FC04A5 +:207F000004047C043C047C0601FF050C34C5060440407C4078407C4000FE008850300E003F +:207F2000007C45545554545754545511292545814020FC00089000FE0000FC040404FC04BC +:207F4000007C45484950484B44444569514141414020FC00089000FE0000FC040404FC04A8 +:207F600000FE2828FEAAAAAAAEC282FE8282FE820000F808080808F88880808082827E00A9 +:207F800010171424256464A5252525252524242800FC0404F44444F45454545474464642C1 +:207FA0000040202F008047541424E42424202000404040FE4040FC444444445448404040CD +:207FC000000178484B484849494979490100000320FC2088FE8800FC0424242424508804AE +:207FE0000408102FC404081060003F242424FF00402010E8262020A04000F8484848FE00E0 +:208000000001FC1011203C6467A424243C24200000FC202024A4A820FE2020202020202005 +:2080200010111010FD1010141B30D0101010502000FC202024A4A820FE2020202020202069 +:2080400001FF001F101F003F000101050248448400FE00F010F000F06080000000884444AC +:2080600001412F21018740571424E72422202F040404E81000C404C85042C24484E81020D3 +:208080000808FF08087F007F41417F002217F8400004840810220204081022020488106051 +:2080A00008FF080123151007701310111017284720FE2000F010E01C40F840F040FC40FE0B +:2080C00010131212FE13323A565392121212151800DE525252DE525252DE5252525252A678 +:2080E0000003FA2222437A4ACA4B4A4A7A4A050800DE525252DE525252DE5252525252A6F8 +:20810000203F4885231510077013101110172847407E9008F010E01C40F840F040FC40FE76 +:2081200000784F48487B484B4A7A4B4A49484F9A8282F48880E202E42820E02242748810A7 +:20814000003E2222223E2222223E222222424A85007C4444447C4444447C4444448494082A +:2081600000775555557755555577555555B5891310207C446454444C407E02027A020A04C8 +:2081800010101310FD1013141932D010131050202020FE20FC40FE882422F820FE202020CE +:2081A0000100F8232040784CCA4A484878480700089000FC90909292949890909090FE00D2 +:2081C0001013101010FE101112141618E040070000FC20204040D048444440404000FE0098 +:2081E0000001FD1111213D6565A525253D252100101010121214D8101010101252920E0041 +:208200003F017F419D011D007E427E407E62BE22F800FE0274007010FE4428FE107C101065 +:2082200010111111FD1111151931D11111115120101010121214D8101010101252920E0084 +:2082400010101011FD1111151931D11111125224101010FE121410FC4444282810284482AE +:20826000007C45447C437CA5243C007F040810604020FC8850FE20FC202000F808085020B8 +:2082800000FE10107C1010FE0020203E2020263800FE10107C1010FE00808498E084847C52 +:2082A00000017D555555557D555555557D450100101010121214D8101010101252920E00D4 +:2082C00000007B4A4A4B4A4A4B48794F000000004080FC2424FC2444FC9010FE1010101013 +:2082E00000784B4A4A7B4A4A4B78494F484848984080FC2424FC2444FC9010FE101010100B +:2083000000001F109057541437559514242849968040FE4040FC4440F80810A040A0180613 +:208320000000003F2020202F2424222120414698808080FC848880F0101020408040300E2F +:20834000007F4444444444444444484850407F0000FC4040404040404444443C0000FE005D +:2083600000001F109750501136509013222242838040FE00FC2040D0484400F8080808F8D6 +:2083800010101724246467A42427262A2A2B3220100888BE8094887E0888BE8888888808BF +:2083A000003F20203F202828282F282848498A0C00F80808F8004040444850604444443CFD +:2083C0003E223E207EA23E2201FF003F003F203F10FE4428FE10FC1000FE00F800F808F800 +:2083E000203F4885003F203F202F29292F494988407E900880FC04FC00FC2424FC24240C63 +:2084000010101724246764A427262A2B2A2A32228040FC0404FC0000FCA4A4FCA4A4A40C2C +:2084200000101010101F1010101F1010102020404040404040FC000000E020202020202002 +:2084400000F809494949497D05051EE6440428104020FE0202FE0000FEAAAAFEAAAAA286C0 +:2084600000FE28FEAAAAFE007C00FE105493512200F888888898D8A8A8A8D88A8A0A0602AC +:20848000004F2027048447501720EF202224290000FEA0FCA4A4FC00FC00FE40484442800C +:2084A00000FE28FEAAAAFE007C00FE1054935122081CE8A8A8A8A8A8A8A4A4A4A228342458 +:2084C000007F043F24243F003F00FF011121450200FC40F84848F800F800FE0010080400CD +:2084E00021212523F927252D35E725252525A444080848901ED464545454D448485464C2D0 +:2085000008492A7F495D6B49431F101F101F101F20203E4848A8102846F010F010F010F0F4 +:2085200011101010FD1010141833D0101111522404848800FE88888888FE888808080808AA +:208540001011505C5151FF0111555555840831C200FE2040FC0424242424244450880402E9 +:20856000040830DF040408103F10111111020C70402018E62020A040F01010101060180496 +:20858000001F101010101F00007C444444447C4400F010101010F000007C444444447C44A5 +:2085A00000FC4949794949784B484D79C80808082020FC24FC24FC00FE8000FC040428103B +:2085C00000001F10101F10101010FF000810204020F0000000F880808080FE000000000080 +:2085E0001011101011FC10101310101CE040000000FC202024A4A820FE20202020202020F4 +:208600000808FF08007F0111090901FF010101012020FE2000FC0010102000FE0000000004 +:208620000808FF0820179042490817E0202020002020FE2000FC40485040FE4040404040C2 +:20864000007F010111090901FF0101010101010100FC000010102000FE0000000000000035 +:20866000080B10305790101013000F08081020C038C04040FE404040F800E0202022221ECE +:208680004224007E24242424FE2424242444448400FC404040784848A8988888AACA8A06B4 +:2086A000002310100201F110171010141810000000F8404048485040FE40404040404040AA +:2086C000003F20203F24222F22223F224244840800F80808F81020F82020FC2020202020AC +:2086E0002020202322FA22232222223AE2440409202020FE222420FC848848502050880661 +:2087000000201212834048081111E1222224280340484440FE8080FC444448502050880648 +:208720000808087F494A487F41524A444A91210000FE10207C445454545454542824428235 +:20874000201392424B12E4242904FF081C030C7020FE2220FC844830CE00FE204080700862 +:208760000000FC1111213D6565A525253D262204101010FE121410FC444428281028448205 +:208780001010217D4545457D454444447C4501022040FC2424FC2424FC4068B2BE20221E9E +:2087A000002010130202F2131212121312284700404080F8080808F8080808F80800FE0085 +:2087C000101094555911FD313955559111111111202040FC04040404FC0404040404FC04A4 +:2087E00010087F002112FF00003F2121213F2100040484242424E4242424242404041408FA +:2088000010101010FE1010121C30D010101050208080808080A090888484808080808080EC +:2088200020203B20407BA222FB2222232A3222024844FE4040FC4444FC4444FC444454084A +:20884000080808101030305090101010101010104040404040504844444040404040404010 +:208860000808FF0901FF013F213F213F212121212020FE2010FE00F808F808F808082810B0 +:208880000404FF243F427F823F223F223F2222204040FE40FC24F404E424E424E424A44CE8 +:2088A0000808FF08013F0804FF00001F10101F102020FE2000F82040FE0000F01010F01024 +:2088C0000808FF0840272087445714E7242424042020FE2844FE40FC44FC44FC4444540825 +:2088E0002020272020FB22222322223BE24202024844FE4040FC4444FC4444FC44445408D6 +:2089000008080808FE08181C2A2A4888080808084040404040504844444040404040404099 +:20892000007F41415F414F494F494F4949407F4000FC4424F404E424E424E4246404FC04AA +:2089400008047F042414FF001F10101F10101F102040FC404850FE00F01010F01010F01052 +:2089600000402F20008744541724E427242424044844FE4040FC4444FC4444FC44445408A1 +:20898000024127200402EF20232222232A3223020810FCA0A4A8FE00F80808F80808F8081F +:2089A0000302F392939197F19F919295F0910200F808F808F810FC10FE104854E05048C0B1 +:2089C00003221312834147111F21E22520212200F808F808F810FC10FE104854E05048C091 +:2089E00022227F22223E22223E2222FF04224182007C4444447C4444447C444484841408CC +:208A00002222FF22223E22223E2222FF242242812020A07E42841010101028A8484484027D +:208A200010171010FC13323A565292131212131200FE909090FC949494949C040404FC043C +:208A40000000003F222322223F20222A32424A84282420FE20A02424E4282890522A4682E7 +:208A600001017F013F01FF013F02FF081C030C700000FC00F808FE08F800FE204080700801 +:208A800002020202020207FA020202020202010000000000003CC000000000040404FC00B8 +:208AA000004027200300171023E02721232021064040FC40F848FE48F880FE089060980404 +:208AC0000020171081464011122CE221222421004040FCE05844A010484648504844408075 +:208AE00020100047200810602101FF050931C10180809CE08084847C0000FE402018060049 +:208B0000002212128242531E1222E223222020010000FC242424A4242424A42444449408DA +:208B200008087F08080F08080F0808FF000810202020FC2020E02020E02020FE002010082F +:208B400011111311FD11313955519117101011120808FC0808F80808F80808FE0090080400 +:208B600001013F020408FF00001F10101F0000000000F8804020FE10109090909010502093 +:208B80000808080B484E48494848484E58E00106202020FE202020FC8488485020508806CA +:208BA00000007D545454577C545455547C4403002020FC202020FE002020FC202020FE0021 +:208BC00010101110545557545555555D650000002020FC508804FE08E82828E82808281099 +:208BE00000784B49487848484B7848484849499A4020FE04885020D80688888888080808E2 +:208C000002017F0804030C30C8080808081010200000FC2040806018262020202020202005 +:208C200021111102FC21203C24242424274454890000FE0088FC88F888F88888FE50880432 +:208C4000201011F9091111395595111111121214081CE0000000FE1010101010101010108F +:208C6000201010FC04081038549210101010101000FC8488889088888484C4A8908080806A +:208C800000F8094848494B7C05051DE5450428102020FC508804FE08E82828E82808281000 +:208CA0000808087E0808FE0828282E2828584F800000F8080808F888808084847C00FE0001 +:208CC000012121213F00003F0000003F2020201F00080808F80000F0101010F0000404FCD0 +:208CE00008081F1020409F000001060810100F000000FC000000E020408000040404FC0034 +:208D0000010102040831C101111111111111FF00000080402018060000F800000000FE00F7 +:208D200001001F1010101F1010101724244487040080FC040404FC000000FC040404FC04DA +:208D400008087F083E087F080901FF02040830C000007C24242444548800FE8040201806A4 +:208D60000001F9212141794FC94949497948000000007E121212D2121212529222224A8497 +:208D8000003E22223E0101FF020C30C03E22223E007C44447C2010FE806018067C44447C28 +:208DA00010103F204F803F0000000000000000000000FC00F000F010101010100A0A0602DE +:208DC000012111120401F01010111110102847000000FE0000F81060800404FC0000FE00A0 +:208DE00001003F0204081F0004047F04040810200080FC002010F8082020FE2020202020B5 +:208E000001211112844148081310E020202020000000FC0000F80000F80808080A0A060255 +:208E200000201010874040121221E12121202F0080404000FC000808081010102020FE00B2 +:208E4000002011110204F110101010151A120100808000FE0000F808106080000202FE0067 +:208E600010101010FD1210151931D1111111512140407C84080020CE0202CE020202FE0270 +:208E8000101010111A54535090131212121213124040A0100806F80000F808080808F80822 +:208EA00000201011824443101023E222222223024040A0100806F80000F808080808F8086A +:208EC00001013F0204087F41890F11017F0101010000F8804020FE0204F00000FC0000008F +:208EE00010101110FC1010171830D01010105020083CE020202020FE2020202020202020A4 +:208F000010103D2040BC1013FC10101014181000083CE020202020FE2020202020202020AB +:208F200010103C2040BC1112FC1111111519110100F888888888060000FC04040404FC04FD +:208F400000003F01010101FF010101010101010110F80000000000FE0000000000000000C1 +:208F6000002013100000F71010101010102847001078C0404040FE40404040404000FE0064 +:208F800010103F284582040837C0021109087F0040407E9008804020D80610102040FC000D +:208FA00008080B101030305790101010101010101078C040404040FE404040404040404079 +:208FC000024120270007E02F20272029322C0000081000FEA0FCA4FEA4FCA0B0A8A6A0A031 +:208FE000101010FE117E447C447C10FE11111010404080FE0000FC08102040800202FE00F0 +:2090000000FE92D6BA92FF12FE101EE002AAA880202020505088442220F808081010202037 +:2090200010103C2041BC1011FC101010141813005048405CE0405EE044483022528A0602D7 +:2090400010103C2043BC1010FC1010101418100088888888FE88888888F888888888F88837 +:20906000100808FF003E22223E22223E22222A24101020FE000848484848484808082810BF +:20908000014127210F8142541322E223222223021010BC10FE10A844FA0808F80808F80885 +:2090A000002312130007F013121312131213284740F848F840FE00F808F800F808F800FEDC +:2090C00000201010874040171020E02020212600A09080B8C080BCC088906044A4140C04F3 +:2090E000004422220001E02E222222222A32250810FE92FE10FE00FE82FE80FE82FE00FEA2 +:2091000010FE20487E080EF94A09013F0101FF000CF08080FE888808080800F80000FE00A0 +:209120000121213F002222FF22223E22223E2200000808F820203E429410101028284482A2 +:209140000808080F1011214101020204081020C0000000FC040810000080804020100806CE +:209160002214FF14147F15FF157F1436559414142020A07E428410901010282828C444822A +:2091800010101010FD12343955519111111110104040A0A0100806F0101050200404FC0027 +:2091A00000007848494A4C4949497949010100004040A0A0100806F0101050200404FC000F +:2091C0000078484B4A7C494A4879484848484F98402020FE0294080400FC20202020FE00C9 +:2091E0000804047F01013F0202FF0404081020C0202040FC0000F80000FE80808082827E28 +:209200002020272022F927202322223AE24203024040FC404850FE00F808E8A8E808F808C9 +:2092200008FF08013F1109FF003F20272427203F20FE2000F81020FE00F808C848C808F85A +:2092400000F9090909784043427A0B080808572000FC0404FC2020FE2222FE202422FE02C3 +:2092600010101010FD1214111931D111111150204040A0A0100806F0101050200404FC005A +:2092800010131013FC133834505791171117111138C078C078C43C00C638CE38CE384A86F2 +:2092A00020203B214179A321F92325212931210108C808082A2AAC480888541414242442F8 +:2092C0001008FF007E427E00FF81BDA5BD8185821010101E1010FC4444442828102844828E +:2092E000101110101855515191111111111111112024A4A820FC0404FC0404FC040414083E +:2093000020202320F82720716AA5A121212222241078C04040FEA0100816101010101010CC +:20932000000079494B7D494979494949794A0204A090FE1010FE1010FE1010FE00A4525224 +:2093400000003F01027F040830C808080810102010F8000000FC402018262020202020208E +:2093600008080B101037305192151111111212141078C04040FEA0100816101010101010F4 +:209380000003FC101010111110101EE04000000000FE4040808000FC040404040404281054 +:2093A0002828FE2838107C54547C10FE101010101092525410FE8282FE8282FE82828A8495 +:2093C00010131013FC1310141837D1171117512138C078C078C43C00C638CE38CE384A86C1 +:2093E0002021FE2429122AC601FC28292848478000DC444454CC44CC544444548A02FE000C +:2094000010111010545555555555555D650101012024A4A820FC0404FC0404FC040414081C +:20942000080A09111033325293121213121212124048485040F80808F80808F80808281077 +:2094400002017F489020007D101011101EE040000000FE22140800FE4080FC04040428105C +:2094600010101110101EF01010121418100102040000FC44444444444444448484042810B8 +:209480000808FF080010107E1212121222224A842020FE2000007C444444444444447C4447 +:2094A000001F1010101F1010101F10101010FF0000F0101010F0101010F010101010FE0042 +:2094C000101010101B545050971010101112171240404040FC404040FE4080801008FC0418 +:2094E00002017F489020212CF0202024283122040000FE221400FC4444444484840428104E +:2095000010103C2040BC1110FC101010141811024040407C84882020205050508888040299 +:20952000080B081110333057941311111010111600F808F808F800FC04F01010A040B00E7F +:2095400002013F000804FF01017F0109112145020000F8002040FE0000FC0020100804002C +:20956000017F013F02FF08102FC11F050911610100FC00F800FE20D00806F040201008002A +:2095800000FE10107C1010FE01061AE11F00000100FE10107C1010FE00C0300EE04080009B +:2095A0002222FF223E087F497F087F087F080FF22020A020FC24242424242444448428108A +:2095C0000808FF08001F10101F101010202040802020FE2038C00000FC40404040404040D4 +:2095E00020202122FD20222A33E027242525A44440A01048F6A048A8F840FC8424F4140C41 +:2096000001020C31CF0413141F017F42444F444000806018E6409050F000FC0444E4240CD2 +:20962000017F408013109150531037549311101700FE0204F808F808F800FC04F810E01C2D +:2096400000201010814141151525E529212120000080402020000004020202080808F800EE +:2096600001017F013F01FF001F101F101F1010100000FC00F800FE00F010F010F01050201A +:20968000202120FC405090FF10111CF05010131000FC08103048840200FC20202020FE0012 +:2096A000203F409F007F003F030C701F02027F0000FC00F000F010D010D030D20A0AF602E3 +:2096C00010101424246467A4242425262420202000FE10207C445454545454542028448294 +:2096E0000873424A4A4B4A4A4A5B6A4A1212234200DE525252D2525252D2129A54B010101A +:2097000000201710834047101322E322232222024040FC40F840FE00F808F808F80828101B +:2097200024FF247E827A4A7A041F013F017F010320207EC4281028C620C000F800FC000041 +:2097400000007B4849484B7849494949794901012020FE20FC20FE00FC04FC04FC04140876 +:20976000203F409F007F047F043F04FF203F202100FC00F000F010D0109010F28A8A868249 +:20978000101017101B54575093121312131212124040FC40F840FE00F808F808F80828102F +:2097A00000212020213D2121212529312000010200FE2040FC0424242424244450880402B1 +:2097C000004027200300E720232223222B3222024040FC40F840FE00F808F808F8082810C3 +:2097E00001003F202020202F20212122424488100080FE00808080FC804040202010080680 +:209800000000FB202021F92121202139E24400004020FE0000FC0404FC2028242222A04023 +:2098200002017F40881022027F020404081020400000FE0224100800F01010101010A0404D +:20984000081CF01011FD11323854549011111214404040404444485040A0A090100804028D +:2098600000001F101010101F101010101010FF0010788000000000FC404040404040FE0089 +:2098800000033C2020203F222222222227F84000003E22242428A42422222234A8202020A7 +:2098A0000000FC101310117C101010111EE0400028242420FE2020B2B468A8242220A040E3 +:2098C0000101017F012111090305091161010502201000FC000810A04020100806000000DD +:2098E000007F4041414141424244444850407F4000FC040404040484444424242404FC0476 +:20990000100808FF04047F444850607F40407F40101020FE4040FC44443C04FC0404FC0421 +:2099200000271414844444141424E4252624270400FC04444444444444A494140404FC0416 +:209940000808087E0908FE0828282E2928584F804040788810FC0404FC0404FC0000FE00D2 +:20996000007F4040444241404142444840407F0000FC001010204080402010100000FE0059 +:209980001010107C545454547C5010141CE4430000FC848484FC848484FC84848484FE007E +:2099A000040404047F444444447F444444447F4040404040FC44444444FC44444444FC04A2 +:2099C00010217D457D457D4545FD0D152545950800FE000444282810102828448400FE00D9 +:2099E000003F20203F202828282F203050509F0000F80808F880888888F880848484FC0437 +:209A000000F909494949497D05051DE54505291000FE000444282810102828448400FE0048 +:209A20002312834A0A13E2232101FF050931C101FC00F80808F800FC0000FE40201806006C +:209A400000FF22223E22223E222227FA420202020080FC44444444442828A8101028448280 +:209A6000007F223E223E23FE0204FF081C030C70007C44442810A8448200FE2040807008DE +:209A80001011505E5050FE009292AAC6828EF2020EF010FE9292FE10FE929A96FE828A8435 +:209AA0001013117D1111FD1111515D5370504F8000E05E42D24A4AC44464CA4A5240FE002E +:209AC0000101013F01010101FF02020408103F00000000F800000000FE0000002010F808BC +:209AE000007F49455F427F485764444443407F4000FC2444F404FC24D44CC424E404FC0400 +:209B00002222FF22775577123F64BF243F243F20007E90207C44545454545454202844824F +:209B200010131111FD103038545490101010111600FC04040488888850502020508804027E +:209B400000FE2828FEAAAAAAAEC282FE8282FE824444FE44102844827C10107C1010FE0049 +:209B600001021F10101F10101F017D091121C5020000F01010F01010F0048850201806009B +:209B80000101020408102FC101011F0101017F00000080402010E8060000F0000000FC0048 +:209BA00000001F109051521D3050931020204F808040FE40A01008F64040F8404040FE0012 +:209BC0000111093F027F08103FC11F013F010502001020F800FC20F00806E000F800000011 +:209BE0000101010101FF010102020404081020C00020101000FE000080804040201008065F +:209C00000111093F02027F08102FC40408081120001020F80000FC2010E826202020408095 +:209C2000000000FC05044828101028244581020440404040FC44444444848484040428109F +:209C400020203C519010FE10135454545C640502202020FC24242424FE20505088880402F3 +:209C600010101017585050901710102825414284404040F848484848FE40A0A01010080606 +:209C800000001F129752541538579415242445848040FE00BCA4A4BC40FCA45444A4140C3E +:209CA0000808087F080808FF10102442FF41000000007C44444444C44444445448404040B8 +:209CC000242424FF2424FF007E42427E42427E4210207C446454C44C407E02027A020A040A +:209CE00010101715FD13363A57529213121213128080FE2210FC2020FC2020FC2020FE001F +:209D00000000FC1011223C6464A424243C25210240407C8408FE9292FE9292FE92120A0414 +:209D20000111112140030C30DF101F101F101F1000100824C0008040FC80F880F880FC00C0 +:209D4000201100F80B101035589415121410101000FC4444FE4444FC8080FC848484FC8415 +:209D6000007E1212FF12127E20207E62A2223E22824428FE1010107C101010FE1010101056 +:209D800010101E22334AA414081021420048448420282420FE205050888804020088444433 +:209DA000111111165A5550921111122C244242841014D2507E5090A82844448208A452526F +:209DC0000101013F21213F212121FF2020202020000000F80808F8080808FE080808281058 +:209DE00020100340210912642901FF050931C1018080F0901012120E0000FE4020180600E8 +:209E000010FE00EEAAEE44FE44FE44FE50CB6542081CE8A8A8A8A8A8A8A4A4A4A22834241C +:209E200020272023F2232127212731EF41030D0140FC00B8A8B810FC10FC10FE2810488601 +:209E400020272023FA23212F31E7212F2123AD4140FC00B8A8B810FC10FC10FE28104886F1 +:209E60000007F093929391979197F19F01030D0140FC00B8A8B810FC10FC10FE28104886C1 +:209E8000002010100000F0101010101418100F004040404040407C40404040404040FE004D +:209EA0002020203B4850802320272020293122048080BCC05024D40C00FE909012120E00A5 +:209EC00010101010FC1110141830D010101151224050484840FE50505050909092120E00E5 +:209EE0001010202348F8102340FB400019E142048080BCC05024D40C00FE909012120E00B1 +:209F0000087F0802FF081F28C80F01084848870020FC2000FE00F01010F000849212F00019 +:209F2000101010FD10101C30D010512200484484404040F84848C848AAAA06020088444461 +:209F400000003F01010101FF0101010101013F0010F80000000000FE000000000000F8007C +:209F600008080813103030509010101017101010000000FC0000000000000000FE000000F5 +:209F80000101010101010202040408081020408000000000000080804040202010080402D1 +:209FA000003F021212240810600108484848870000F8080808080850200088841212F00088 +:209FC000202021FC2020F82021FC2424342821220000FC2424A4A4A4242424444484140804 +:209FE00008080B101030305F90101010101017101078C040404040FE404040404040FC009E +:20A00000002010100000F01010101015191204084040404040404040A0A0A0101008040276 +:20A02000003F020202222222420204040808106000F80808080808080808080808085020E1 +:20A0400010101110FC2424272448281028448500083CE020202020FE202020202020FC0061 +:20A060001010232048FA122244F8400119E244080000FC4444444444848484040404281023 +:20A0800010101310FC1010141830D111111252240000F8889090A0BC84840404040428103E +:20A0A00008080B101030305090101111111212140000F8889090A0BC84840404040428105E +:20A0C000001F10101010101F1010101010101F1000F01010101010F0101010101010F010D3 +:20A0E000000000FF000808087F08081010204003484440FE4040444444282812324A8602BB +:20A100000808FF08007F101F101F1010FF0000002020FE2000FC10F010F0103ED010101084 +:20A120000808FF0A017F40891224083FC8080F082020FE2000FE0224904820F82620E020A1 +:20A140000808FF08007F4081017F03050931C1012020FE2000FE020400FC804020180600C8 +:20A1600000FE007C447C00FE82AA92FE92929286202020FCA4A4A4A4FCA4202824FE420077 +:20A18000101013165850519010111228244440804020FE02508824508804FA888888F88820 +:20A1A0000020131284414A081112E521212121014020FE02940864900804FA080808F808A8 +:20A1C00002017F40881122040830DF1010101F100000FE02241088402018F6101010F0102E +:20A1E000101020204BF8112141FB41011AE2440028242420FE20242424A82810122A4682CE +:20A2000000007F4080000F0808080810102040800000FE020400C0404040404242423E0008 +:20A2200020212020FB20202932E023202021A64000FC4830FE5294103020FE70A824222089 +:20A24000001F02017F0418620101FF050931C10100F02040FC8488800000FE402018060089 +:20A260000101017F414244495141424244484040000000FC0484442404048444440414080A +:20A280000808FF081010FE1222226414081422C02020FE2000007C4444444444447C44008B +:20A2A000202120FBAAA9A8A9F8A3202939E9410100FC20FE22AC20AC00FE20FC5454540C80 +:20A2C0001017102F286360A3202F20272424242400FC40FE4258405800FE40FCA4A4A40CC6 +:20A2E00000FD040B1211141930D310111111512100FC20FE22AC20AC00FE20FC5454540C74 +:20A3000010101010FE22222242241408142242800000007C4444444444444444447C44007F +:20A32000003F202F203F28484A8C00FF0804040000FC00F800FE8850300E20FE2020A04095 +:20A34000020FF001914A00FE04080FF84808281020202020202020202020202222221E00A3 +:20A36000002010108F4141121226E1202021220C80808080FE0808081010A040A010080400 +:20A38000040201010102020204040808102040800000000000808080404020201010080638 +:20A3A000201302F21223226AB22A22232224242800FE00FC00FEA890C88608FE884808188E +:20A3C000101010FE2028497E08080EF84808090A4040407C84882020205050508888040219 +:20A3E000007D444848534848444444685141424400FC000000FE90909090909212120E004F +:20A400000808FF080801242443002412A0A41C002020FE2020008824E4002412A0A41C0057 +:20A420000002FA22232027F82023223AE242020220222222FE00FE2040FE52525252520655 +:20A4400022213940437AA222FB2020293122040808081020F8080808F8A0A02024241C00F0 +:20A4600020131040405F41414F4141415F40404000FC040404F40404E4040404F4041408FF +:20A4800002211514854444141524E42425242404007C0404F4444444F4444444F404140885 +:20A4A0000808FF080A02FF04081F284888080F082020FE202000FE0000F010101010F0108C +:20A4C000007E02027E40407E2212061A6202140800FC0404FC8080FC44240C34C404281006 +:20A4E00022222722FA27202F34E724272424A4448888C8909ED424D454D454C8485464C2F1 +:20A50000002F1010874444141424E5262424270400FEA0A0FCA4A4A4A4A41C040404FC047D +:20A520000404FF04007D444851494545554942444040FE4020FC8850FE000000000000000F +:20A5400000794949497949494878484A4A4C489800FC2424FC2424FC004024A28A887800C0 +:20A5600020217D45897D55557C54547D011DE24000FC2424FC2424FC20105442424A380039 +:20A5800002017F449F043F04FF081121DF01017F0000FE42F440F840FE201008F60000FCA2 +:20A5A000017F449F043F04FF081F29C9090A041800FE42F440F840FE20F0282620A0402082 +:20A5C00000007F000000003F0000000000FF00000000FC00000000F80000000000FE0000CC +:20A5E0000204081F027F081027C0000F00003F00004020F000FC2010C80600E00000F8003E +:20A60000010102040830C111090901FF010101010000804020180610102000FE00000000D6 +:20A6200024247E2424FF007E427E427E42424A442020203E444444A4282810102828448269 +:20A640001F06010E007C241866017F050931C101E040804000F84830CC00FC402018060091 +:20A660000301F093909794939490F79001020C00F010E01800BCA418A440FCE050484640FD +:20A6800001017F0111090901FF121110101418100000FC0010102000FE0010A040300E002E +:20A6A00020232121F820212E30E322222320A74000F84810A040B04E40F84848F844FC04FB +:20A6C00000F908484848487F04051DE545042B1000FCA4885020D82620FC2424FC22FE0233 +:20A6E00010101310FC1010151830D010101350200000FC04040404FC0404040404FC04000F +:20A7000010111111FD2525252449281028448003A02C2424AC2424FC20FC88502050880600 +:20A7200000FE10107C1010FE010848498E18E70000FE10107C1010FE10A044821210F000FA +:20A7400008081F2040BF2121213F202020201F000000E02040F8080808F800020202FE001E +:20A7600000231012824440111220E1212121270000FC44444484940820203C202020FE001E +:20A7800001017F050931C108087E081C2AC908080000FC402018062020FC3068A42220202F +:20A7A00009080813123232529310111111111111048800FE22AA7222FE00FC04FC04FC04B4 +:20A7C0000808FF080010084024050972101011062020FE20002020A8A422222810608000E9 +:20A7E0000000FC1010203D6566A424243C242003202020A8A4A22220242428081020C000AE +:20A800000018060106186101FF011111212145020810608060180400FE002010080404003C +:20A820000162140814224908FF082A29488828100404042424242424A424242484841408BC +:20A8400000201011814242141020E02020202106404040484442424848481010204080005F +:20A860001010202149FA122440F8400018E04106404040484442424848481010204080009F +:20A8800008080B121232335091121411121011164080FC946494FC900884FA0890609806C3 +:20A8A000000078494A4D48484F48784B020203024040A01008F64040FC4040F80808F8081B +:20A8C00020203C44887F02027E0202FE004844842020407E844444282810284482884444B5 +:20A8E000203F4885084B48484949494911112040407E900800FE2020FC242424342820200B +:20A9000000077848484B4A7A4A4A4A4B7A4A030200FE909090FC949494949C040404FC0485 +:20A9200000F724242424F42F24242434E445081000BCA4A4A4A4A4FEA4A4A4A4A4A45488EA +:20A940000808FF080901010101013F2020203F202020FE202000FE000000F8080808F80848 +:20A9600008080808FE08181C2A2A488808080808040408102044040810224204081020C039 +:20A98000010101012121212121212121213F000000000000080808080808080808F8080003 +:20A9A000007B4A4A4A4A4AFF4A4A4A4A4A5A850802C2424A4A4A4AEA4A4A4A4A42424A84C0 +:20A9C000101011155951519111111129254242842010FE0202FE00EE22AA662266AA226612 +:20A9E0001008007E0204081A2C4A0A0808080808040408102044040810224204081020C0F1 +:20AA00002017004041414141424244484040404000FC040404040404844424240404140863 +:20AA200000784857506251484F48685141424448404040FC40485040FEA0A0101008040215 +:20AA4000202F2027FC25252F30E322232223A04F40FE00FC04F414FC00F808F808F800FE27 +:20AA6000007C454755555555555555112926428480F808FE4492FE007C007C007C447C448B +:20AA800000784B4849784B49487B4849494949998850FE20FC20FE24A8FE00FC0404FC04B0 +:20AAA00008047F013F01FF1109FF003F20203F202040FC00F800FE1020FE00F80808F8084C +:20AAC00000201010844444141424E4242427200040404040444444444444444444FC040007 +:20AAE00002013F20203F20203F212925495185020000FC0404FC00007C042414244414084A +:20AB00001010232049F8132140FB400119E141018850FE20FC20FE24A8FE00FC0404FC04C7 +:20AB20002020232020FB22222322223AE24202024020FE8850FE528A06FA8A8AFA020A043C +:20AB400008080911123430539010101011111214808000FE004040FC4444848404042810B0 +:20AB600002017F08043F202428372424272020200000FC2040F8084828D84848C80828105A +:20AB800011093F204F080F001F10111111020C701020FC04E820E000F01010101060180432 +:20ABA0000000784B4A4A4A7A4A4A4A4A7A4A0202404080FC0404F494949494F4040414082A +:20ABC0000202020202020302020202020202FF00000000000000F800000000000000FE0063 +:20ABE00001211109013F202027242424272020200008102000F80808C8484848C808281097 +:20AC00000111097F409F101F01FF050C34C50604001020FE02F410F000FE008850300E0040 +:20AC200010111010FC11313955519111111111112024A4A820FC0404FC0404FC04041408F8 +:20AC400010111010FC1111151931D111111151212024A4A820FC0404FC0404FC04041408E8 +:20AC6000081DF01010FD113139555591111111112024A4A820FC0404FC0404FC04041408D0 +:20AC800020202023A8B0A0A320272020514942848080BCC05024D40C00FE909012120E008F +:20ACA0000404FF0410101F2040880402020000004040FE400000F8080808080808085020FC +:20ACC0000808101F204080040201010000000000000000F808080808080808080808502095 +:20ACE00020117C004428FE007D44447C44447C4400FC44444444948800FC84848484FC84C0 +:20AD000001010109091111214101000001020C7000000020100804141020408000000000DA +:20AD2000000178484849494949497949010101012024A4A820FC0404FC0404FC04041408FF +:20AD4000007F1111212542803F212121213F2100003E2224242824242222223428202020ED +:20AD60001013202048F9112244F9410119E1410100FC84848404140800FC04040404FC048D +:20AD800002027F040832DF02FF030F38CF080F080000FC402018D620FE00F010F010F01072 +:20ADA000007C445455565454575455112A2444802020508804FA0000FE2028242222A04065 +:20ADC0001010107D555654547C5010141EE24000201010FE0204808890A0C08282827E0003 +:20ADE00000003F0101FF0101011F101010101F1010F8000000FE000000F010101010F0104C +:20AE00000102040830CF01013F01011F10101F100080402018E60000F80000F01010F0108D +:20AE20000808087E0808FF141456559524245488202020407E844444442828101028448215 +:20AE400010131111FD1111171837D0121112542800FC08F808F80EF808BCA4A42890A846F3 +:20AE600008103E223E223E2222FE060A12224A0408080808FE0808084828280808082810CA +:20AE80002023212131A9A1A7A02720222122242800FC08F808F80EF808BCA4A42890A846BF +:20AEA00000201111814147101021E122242020072020203C2020FE00202424281020C0003E +:20AEC000201010F8081013385494101010101710202020202020FE20202020202020FE00EC +:20AEE000002111110102F413111110141810030C00F01010100E00F8081090A040A018061C +:20AF00000000FC1111213D6565A525253D242000202020FC242424FC242424FC24202020CB +:20AF20000101013F2121213F2121213F21010101000000F8080808F8080808F80800000047 +:20AF40000000784B4A4A4A4B4A4A7A4B02000000404040F8484848F8484848F8484040404A +:20AF600008080817143434579414141714101010404040FC444444FC444444FC4440404068 +:20AF800002041F101F101F10107F0000031CE0000000F010F010F21418F050901010502012 +:20AFA00000271414814240101720E021222C200000FC04A410084040FC40E05048464040D3 +:20AFC00020232222FA4A4A4B8A4A32122A4C840800FC0000F80000FCA0A4A8909088A4C20D +:20AFE0001010202545F9112141FD41011DE04000202020FC242424FC242424FC242020200F +:20B00000201010F9091111395595111111101010202020FC242424FC242424FC2420202096 +:20B0200000201017844840101020E12122222408404040FE444840A0A0A0202022221E00FF +:20B0400002017F41813F21213F21213F210101010000FE0204F80808F80808F80800000033 +:20B0600020202322F849494949915121314848804020FE2220FC2424FC2424FC2420202043 +:20B0800008087F08080F08080F0808FF1214101F2020FC2020E02020E02020FE201000F89D +:20B0A00004252424242427041F101F101F10101000F8885020D80600F010F010F0105020C1 +:20B0C0002020272033AAA3A2A32223222F2122244040FC40F808F808F808F808FE10080451 +:20B0E00000201113804741121C23E02023202007809008FC40FE1048861020C40830C0002D +:20B100000101FF017F003F21213F2020204040800000FE00FC00F80808F800000000000094 +:20B12000011111113F214181013F01010101FF0000000000FC00000000F800000000FE0084 +:20B14000111151517D5191107C1310101CE14204FC2424FC2424FC4040FE42828202140864 +:20B16000101051517D5192101CF150101010131020202020FC20202020FC20202020FE0077 +:20B1800001073C04040404FF040404080810204020A02020202020FE202020202020202072 +:20B1A0001011212149F8132242FB42021BE0400000F01010F040F84848F84848FA42423EEE +:20B1C0000111112140030C3FD01F101F10101F1000100824C00000F808F808F80808F8082C +:20B1E00000003F20203E22224A44813F2424FF009088FC8088485024548C04F84848FE0077 +:20B20000077808FF2A2AEB2A6AA91C2A4988080802020282129212929292121202820A045B +:20B220000078494949794A484879484848484B9820202020FC20202020FC20202020FE0076 +:20B24000003F080402010618E1011F0101017F0000F020408000C0300E00F0000000FC0045 +:20B26000080B484848494949494949091110204000FE202020FC24242424243428202020D9 +:20B28000011111113F214101FF020404081020C000000000F8000000FE80404020100806A3 +:20B2A0000189512555951515355595111212A44800FE10107C545454545454545C101010C8 +:20B2C00020101001FE21213D27252525254554888080FE2020202C74A424342A2202FE008E +:20B2E00000271414874444171121E92523212F0000F80808F80808F8202024283020FE0044 +:20B30000002010130000F7101017101215191000404040FC4040FE1010FE10101010502054 +:20B32000001F101010101F10101010102020408000F808080808F808000000000000000027 +:20B34000007F00037C043F2424243F040407782000F090D010109090909090128ACA46026C +:20B36000010101010101FF010101010101010101000000000000FE000000000000000000C1 +:20B3800000FF02020404080F1828488808080F0800FE0000000000F8080808080808F8082E +:20B3A00010101010FD1211141831D11111115121202050880402FC0000FC04040404FC0434 +:20B3C00000007C444544447C444444447C44000008080808FE0808088848480808082810F6 +:20B3E00008080810103037509010101010101010202020202020FE20202020202020202080 +:20B400000102040A31DF101F101F1011101214180080402018F610F010F00890601008043C +:20B420002020203D4549A1212121202028332100202020FC24242424FC24202824FE0200A9 +:20B4400002017F40880404100808FF01020418600000FE02848080808080FE40201008047E +:20B46000002011110101F11111111014181102040000FC0404040404FC04009088040202E1 +:20B480000101013F2121213F21011109060518E0000000F8080808F8080000000080700E7B +:20B4A0000808081F11214101FF010202040830C0000000F800000000FE008080402018066D +:20B4C00010101F20206764A4272022212021222C4040FE4040FC4444FC4040408040300E29 +:20B4E000003F20203F202422203F21222448508000FC0404FC8090A080FCC0A090888680A0 +:20B5000000F808494949497D05041CE444042912202020FC24242424FC20A06060900806F8 +:20B5200010101010FC2425242448281028448000202020404884FE8200FC84848484FC845A +:20B5400000000000FF00003E080808080F78200048444440FE40404040402022120A060233 +:20B56000003F00000000FF01011111214181050200F800000000FE00001008040202000069 +:20B58000010101010101FF010101010101013F00000000000000FE00000000000000F8006A +:20B5A0000212121212FF12121212131010101F002020202020FE20202020E0000000FC009E +:20B5C00010101013FC1031395555911111111010402000FE2020FC2424242424342820203A +:20B5E0000101FF013F213F013F01FF013F0105020000FE00F808F800F808FE08F80000002E +:20B6000010101010FB10141B31D111111117522028242420FE2020A020101010CA0A060258 +:20B62000087E080E780A197F003F003F003F203F0CF080FE888808FC00F800F800F808F8C2 +:20B64000024222220F02E2232E22222A24518F00081C6040C07EC848484848488800FE00F4 +:20B6600008087D080C1968082813027F040810604040F84848C84AAA860200F808085020A4 +:20B680001F10101F10101F00FF01111111294583F01010F01010F000FE0000F8000000FEE5 +:20B6A000000079484B4848494A4C7949010101014044F850FE40F8827E00FC04FC04FC0447 +:20B6C0000202F395989097909292F29508000F001010DE288400FC4048484854E240FE009B +:20B6E000002310100700F013121212131228470078C04040FE4040F8080808F80800FE00EF +:20B7000008080810103F305090101010101710104040404040FE40404040404040FC000031 +:20B7200008080813103037509017101211111010404040FC4040FE1010FE10101010502004 +:20B740000CF311543810FC13303954509310101000FC04885020D82620FC2020FE202020AE +:20B760002020203C454A80212121212529312000808080FE202020FC2424242434282020F5 +:20B7800000003F2020203F20202020202028302010F880808080FE8080404022120A0602C7 +:20B7A0000201007F0101013F2121212121210101000000FC000000F80808080828100000B1 +:20B7C0001010101B545057901017101211111010404040FC4040FE1010FE10101010502000 +:20B7E00002017F40803F04081F01013F0101FF000000FE0204F80020F01000F80000FE0049 +:20B80000201111F909111139559510101011121400FC040424242424245450909012120E8A +:20B82000002010100700F017111111151917020028242420FE2020E020101010CA0A060266 +:20B840000808484848494A48485868480808090A40404080FE088888885050205088040236 +:20B8600000003F01013F010101FF01010101050210F8000000F8000000FE0000000000003D +:20B880001008FF02043F20203F20203F20203F201020FE0000F80808F80808F80808F80869 +:20B8A00002017F40800000FF00001008080001000000FE02444040FE404040404040408024 +:20B8C00002027F023F04FF08081F1024428200000000FC00F800FE2020FC20202020A040EC +:20B8E00010131012FD1117141833D111101051261CE084444810FE0200F80810A040B00E3C +:20B9000009081F305F901F101F10001F10101F100080FC80F880F880FC0000F80808F8081C +:20B9200000017E22117F40803F100804030C30C008FC101020FE0204F01020408060180616 +:20B9400000001F1196545714375097122120438C8040FE405C445C44FC40FC0810E0180696 +:20B9600008043F213F213F00FF001F1010101F102040F808F808F800FE00F0101010F010C9 +:20B9800008FF08007D041851505C50505D71C20420FE2010FE2048FE02A8A8A82A2A2A069E +:20B9A00010131212FE12323A565292121312131000FC000888505020205050880800FE0096 +:20B9C00010101310FC11333855519111121214184020FC409008FC04505050505052520E9E +:20B9E0000001FD21213E44476494080911224080202020FC202020FE70A8A824242220201E +:20BA000010111010FC1013141830D0101010502000F808502010FE22242020202020A040B6 +:20BA2000202021FA25405392FA131AF25312121240A01008F600C45454D45454D44454C8B5 +:20BA400008080E080808FF0008084A49890828110000FC44444444282828101028488402AA +:20BA600010112844827C1310FE10107C44447C4400F808502010FE22242020202020A040F2 +:20BA800001211111814147101121E525292125020000DC141414D414141488484814142212 +:20BAA00000007D04081051505C5050505D71C2042010FE204884FE02A8A8A8A82A2A2A062E +:20BAC0000202023F02020202FF02020202020202201008E020202020FC0404040428100030 +:20BAE000007C45445457545454555413282440832020FC2020FE0294501090FE28448202E1 +:20BB00001008FF007E427E017E04080EF808291240404040F8484848C848685A8A8A06023E +:20BB200010FE007D447C007C08FE115220484484404040F84848C848AAAA060200884444E1 +:20BB400008FF083F243F021F02FF030F38CF080F20FE20F848F800D020FE00F010F010F08E +:20BB60001F101F101F021F02FF030F38CF080F08F010F010F000D020FE00F010F010F01010 +:20BB800000037A4A4B4849784B4848497A48000000FE5252FE24FC28FE20FC84FC84FC841E +:20BBA000003F24243F021F02FF030F38CF080F0800F84848F800D020FE00F010F010F010F7 +:20BBC000003F24243F101F225F92121F02037C2000F84848F800FC04C44444C424F41408C7 +:20BBE000003F017F091122C40931CB0519610502F80000FC20108844201826C030080000B5 +:20BC00000438203C20203F002925212925212931007808780808F800482808482A0A468219 +:20BC2000003F203F202F202F282F203F5057901000FC04FC00F880F888F880FC94F41408BF +:20BC4000010101017F030505091121418101010100201010FC8040402010080402000000DA +:20BC6000002010100700F011111214101028470040504840FCC0E050484444404000FE0064 +:20BC800020202720F824227269A1A2222428202004048484BE8484A41414848484041408C5 +:20BCA0000101FF01013F2121213F23050931C1010000FE0000F8080808F888402018060070 +:20BCC0000000003F202020302824242020404081504840FE4040444444282812324A86025C +:20BCE000084B4A494848484B0A013F000804FF0000F80810A040B00C0000F8002040FE00E4 +:20BD00007F497F497F087F080FF0013F0101FF007C0428107E121410502000F80000FE0073 +:20BD200001003F2022223F22222223204A4991000080FE002020FC202020E00048242400C9 +:20BD400008492A08FF2A498810FE2242641834C22020203E444444A42828101028284482EE +:20BD600001211711814745151721E325292121010808C8081ED26440C808884854142442C9 +:20BD80001010FE224434081422C001084848870000007C444444447C440000849212F00069 +:20BDA000003F20203F2222223F5252529312020202C24242D2121212D252525242820A0497 +:20BDC00000FF02043F2424242202FF081C030C7000FE0000F88888A81000FE2040807008D9 +:20BDE00010101310FC1211161830D013101050204020FE2048F22452F80820FE2020202044 +:20BE00000201FF001F10FF101F02040C34C506040000FE00F010FE10F080442810080600A8 +:20BE2000003F2121213F2121213F21212141418000F8080808F8080808F80808281202FEB8 +:20BE40000808484849494949494949091110204020202020FC2424242424243428202020A9 +:20BE600010101010FD1231385450911010101310202050880402FC202020FC202020FE00AE +:20BE800010101010FD1211141830D11010105320202050880402FC202020FC202020FE009E +:20BEA0003F017F419D011D00087E182C4A880808F800FE0274007000FC84FC84FC84FC843F +:20BEC0000000FD044444282810102828444481020000FC84848488885050202050880402B8 +:20BEE00001017F012911290129112A02040830C00000FC00281028002810A88040201806C0 +:20BF0000014121230206EB22222322222A332202402020FE2020FC2020FC202020FE000028 +:20BF200001010101017D05090911112141810502000000080890A04040201008060000005E +:20BF40000000F39090F79292F7929297F09007001078C04040FC4848FE4848FC4040FC0020 +:20BF6000091CF01011FD1131395454901011121404848810FC040404FC50509092120E008E +:20BF8000000079494A4F484949497949020204088080001008FC04202020202022221E0037 +:20BFA0000007F09291F7949AF293949AF19204083CC0442408FE020808BE88A83E08080840 +:20BFC0000445545455555555555555555454850600FE2040FC042424242424445088040261 +:20BFE000003F0110087F48081E22520C081020407C80088890FE1210FC109090FE1010106E +:20C00000022111100302F212131010151912040808081020F8080808F8A0A02022221E004A +:20C020000003FC1011213D6565A525253C24210200FE2040FC040424242424445088040430 +:20C04000422224FF08084949497F091010204182007C4444447C4444447C4444848414082B +:20C0600010101111555951911010102825464080081CE000202020FE2020A8A42222A04059 +:20C0800022227F22223E22223E2222FF042241810004784040407E4848484848488888082C +:20C0A0002424242FF427242734E42F202528B04080829CD090909E949494D41414A42444EB +:20C0C0000404E4AFA4A7A4A7A4A4EFA00508100080829CD090909E949494D41414A424444B +:20C0E000003F21213F21213F200108484848870000F80808F80808F8080088841212F00047 +:20C10000040E780808FF08181C2A2A4889080808202020202040404040488484FE8202009B +:20C12000003F00007F00001F101010101F10000000F80808E80808888888888888882810C3 +:20C140000808101022427C040810207E0000FF00101020204484F808102040FC0000FE0084 +:20C1600000FF1010101E2222528C04080810204000FC8080848890A0C080808484847C00CC +:20C18000003E20203D20203C2021FE202542FE422020FC24FE24FC2020FC2020FE2020200A +:20C1A0000101013F0101FF00007F080404000000000000F80000FE2020FC20202020A0401B +:20C1C000003E22223E007F5555557F5555555143007C0404F4040474545454547404140837 +:20C1E00000007F444444444448485060407F40000000FC4444444444443C040404FC040051 +:20C20000080B081017303053921212131010101000FC0404F40404E4242424E404041408C8 +:20C2200010111024246464A424242425262420210808884848080808101010282444820279 +:20C240002023203C4748A023222222232830200000FC0404F40404E4242424E40404140894 +:20C26000003F20202020203F2020202020201F0000F01010101010F0000000040404FC0089 +:20C2800010101010FC11313A545490101113111010909088882424224040888404FE02001F +:20C2A0000808142241007F101F101F1010FF0000202050880400FC10F010F0103ED01010A5 +:20C2C000080808081412222041820108484887002020202050508888040200849212F000A5 +:20C2E000002824244252901020204844FC44000300FE2040FC849494949494A43048840227 +:20C30000022111170000F0171010101112284700080810FC404040FE40A090080800FE00B1 +:20C3200002017F408101017F0305091121C101010000FE02040000FC804020100806000035 +:20C34000002111110102F214181011151A17020020202010104848448280100808FC04009A +:20C36000004720210007E424272424272C34240400F810A040FC4444FC4444FC4444540838 +:20C3800010111111FD1111151831D01010105023A02C2424AC2424FC20FC88502050880674 +:20C3A00010217D45655555FD446554544444548BA02C2424AC2424FC20FC885020508806D0 +:20C3C000222A2722FF22272A32EF24282522A54810901020BE44A4A428A890902828448295 +:20C3E0000101F791919795959791F395090101010808C8081ED26440C808884854142442C3 +:20C400000808FF080A027F0202222224440810202020FE202000F010141212121010A040CA +:20C4200000FE2828FEAAAAAAAEC282FE8282FE82041EF0101010FE1038345452901010101C +:20C4400009090A14103031529C131212121213121008044440A0100806F808080808F80857 +:20C46000013F011F01FF02041F01063F0111254200F800F000FE0020C08010F808201008EA +:20C48000002017100302F21310111214102847004040FC40F84848F8E05048444000FE004F +:20C4A0007F04043F24243F0011097F050931C101FC4040F84848F8001020FC4020180600EF +:20C4C00010171020276464A72221272021222C2000FCA0A0FCA4A4FC4850FCE05048464048 +:20C4E0002214FF0849497F081021413F0101FF00007C447C447C4444940800F80000FE001E +:20C5000004422220078145551527E12122222408405E9212D21E525252DE521212222A44B7 +:20C5200002017F40880F103053921213121213120000FE0204FC4080F80808F80808F8083F +:20C54000002011110101F1111111111519120204081CE0000000FE1010301814121010105C +:20C5600001013F01FF013F0121252525294141810000F808FE08F80008482828280808089F +:20C5800000FE2828FEAAAAAAAEC282FE8282FE8210102044FE2844A23C4444A810284482E3 +:20C5A0000808FF08007C0000FE101054529250202020FE20007C0000FE1010545292502082 +:20C5C000203E48803F203F203F203F08FF081020407E9000F808F808F808F820FE202020D6 +:20C5E000001F10101F01013F21213F0101017F2000F01010F00000F80808F82010F8040449 +:20C6000000784B505162554849496951414141414040FE80FC20FE00FC04FC04FC04140833 +:20C6200000784954526051484E4A6A52424245481010FE2040FC44447C447C44544800FE19 +:20C64000101023204AF9112043F8410318E04106083CC04424280040FE8808906050880417 +:20C66000007C457454FE827D447C447C4444554A107E20BCC8BE00BCA4BCA4BCA4AC403E53 +:20C680000000FD1010203D6664A427243C2420004020FE00888854220020FE202020202045 +:20C6A000012121213F0202070814220100031CE000080808F80000F010102040800000008E +:20C6C000081CF31011FD113935505390101212142020FE20FC24FC24FC22FE4224A28A7867 +:20C6E000012010170001F61011161011162847001090A0FC804468B02868A424A040FE00D0 +:20C70000007C4A505060564A4A4A6A5242424548884850FC20509438509834549020FE00DC +:20C720000111111F41417F003F00FF0111214502001010F00404FC00F800FE0010080400D8 +:20C74000007E020408080A0C39C90A08080828102020202020A8A4A4222222202020A0409D +:20C7600010101010FC1011151931D1111010502300F88888F800FC042424242450488404D8 +:20C7800010103F48853F0202FF02043F081020C040407E9008F01010FE1010F0100000002A +:20C7A00008FF08017F001F10FF101F040838CB0C20FE2000FC00F010FE10F0885020180624 +:20C7C00010101011FB103039565091121010111640408804FE02884442F88850205088062C +:20C7E000000078494B4848494A48794A0000010640408804FE02884442F888502050880610 +:20C800002020274451F122264AF2420232C202024020FE0200FE10207C44447C44447C4415 +:20C820000001FC101011117D111111111CE041022024A4A820FC0424242424245088040277 +:20C8400001013F01017F42841F01063F011125420000F80000FE0224C08010F808201008CE +:20C8600010113C2040BD1111FD111111141811022024A4A820FC042424242424508804026B +:20C8800002073820203E2222223E202041418204081CE0808080FE888888888808080808A3 +:20C8A0002023222322FB20202720243AE440020100F808F808F80000BC84A494A484940893 +:20C8C00008080A121232335E92121212121211104040405868C84848484858420202FE0046 +:20C8E00002017F4080080808090E0808080807000000FE0204000830C00000040404FC009C +:20C9000010101011FD2525272549291129458400202020202C3464A4243428222202FE0022 +:20C920002121272120F821222520203BE24203021010FC1040A01008F60000F80808F80827 +:20C9400002925F2262AF2A2A6FA2272A3222A24210109C2448BEA2AAAA2A2AAA88142242E9 +:20C9600010121111FC1013151931D1111112542010101010FE1010282444428200807E00CC +:20C98000007D4545457D1010135C5251525CE10000FC04FC04FC0000DE42524A52424A84F3 +:20C9A00000784B4848791210515D515159E101012022B4A8A824A240FC0404FC0404FC04A9 +:20C9C000003C2424243C2524243C242424445488202020404884FE8200FC84848484FC84C6 +:20C9E0000808FF080408103F00001F1010101F102020FE20002010F80800F0101010F01099 +:20CA000010101010FD1310141931D111111151212020408804FE0200FC0404040404FC04C6 +:20CA20000202040810207F20001F101010101F10000000201008FC0400F010101010F01021 +:20CA400001017F013F02FF040931CB05196105020000FC00F800FE40201826C030080000FD +:20CA600000FE2828FEABAAAAAEC282FE8282FF822020202020FE20202050505088C8240292 +:20CA80000101010101FF0101020204040A1121C00000000000FE00008080404020100806CC +:20CAA00001017F0102040A31C0010848484887000000FC0080402018060088841212F00071 +:20CAC00000201010874048081010E1212222240840404040FE4040A0A0A0101088484402D9 +:20CAE0001011111111FD11111711111DE142020400F8080848282808FE080808080828103E +:20CB000020202721F129252532E225252920A0402824407EC8487E48487E4848487E404026 +:20CB20000102040930CF00001F10111111020C700080402098E64080F0101010106018043C +:20CB400001003F2020BE722A2B64A42A2A5240800080FE5048FE9090FE9090FE9090FE8074 +:20CB600000402E2203924A5A1424EA2A32202000504880FE9090FC9090FC909090FE808032 +:20CB80001010111010FC13101010101CE14301000000FC000000FE202040408804FE02006E +:20CBA000202F2027FC25257768A3A2232223202F40FE00FC04F414FC00F808F808F800FE86 +:20CBC00000001F1092525411325C92122421428C8040FE404850A01008444850A0100806B0 +:20CBE00000271017844740131223E2232027200000FCA0FCA4FC00F808F808F840FC40403C +:20CC0000002310130203F011111111151813000000FE50FE52FE00FC04FC04FC20FE20205F +:20CC2000002212140001F610101212141811020C40444448A010084440484850A01008063C +:20CC40001010111111FD11111111111DE04003000000FC040404FC040404FC040000FE00E1 +:20CC6000103AE2242039E620203AE2242021221F40444448A010084440484850A2120AFE3B +:20CC8000201001FD0911113559951511101013100000FC040404FC040404FC040000FE00A1 +:20CCA0000001F9212140784BC849494A7A4C080020242424FC8080FE90105254A828448261 +:20CCC00020272424F922202837E02021222CA04000FC04A410084040FC40E0504846404026 +:20CCE00000077A4A4A494949484878480001020C00F8080808101010A0A04040A010080627 +:20CD00000121213F0808FF101014242941820C30000808F80000FE8088889040402018061E +:20CD200000231010804143111121E2222428210200F020408000FC24242424444484281056 +:20CD40002020272425FC27242524253DE54909114020FE20FC24FE24FC20FC040404FC0405 +:20CD600020202724FD24272C35E425252529A9514020FE20FC24FE24FC20FC040404FC0425 +:20CD80000111097F409F10101F01013F0101FF00001020FE02F41010F00000F80000FE006F +:20CDA0000111097F409F10101F01FF050931C101001020FE02F41010F000FE40201806000A +:20CDC0000079484B4A7848484878484948484B982024A8FE02F88888F82020FC2020FE00CB +:20CDE00001003F202F203F202F202F2848488F080080FE80F888FE88F880F8080808F808CC +:20CE0000101095555911FD3139555591111212142010FE107C14FE147C107C4444447C443F +:20CE200010121121206764A425252525252424244048485040FC0404F4141414F404140842 +:20CE400010217C447C457D4545FD0D15254595092024A4A820FC040474545454740414083A +:20CE600000221111804744141525E525252424044048485040FC0404F4141414F4041408F2 +:20CE80001011107C1111FD1111515D5171504F802024A4A8FC040474545474040C00FE00E3 +:20CEA000231080431121E22429200111220418E0F020C0FC2424448428100010A040300E89 +:20CEC00010101011FE1011141B30D111111050208080FE0282F24242FA425252F202140838 +:20CEE00000201710834047101121E222242820004040FC40F880FE9010FE109050105020EF +:20CF0000004F2024028241561424E724242427043EC084444810001C04041C040404FC0443 +:20CF2000101021234CF0112640FB40021AE441008080F8089060984640FC40484444408084 +:20CF400008FF08203F489F2202FF0222223F000020FE2000FC04E40404FC042424E4281046 +:20CF600010101012FD10303956549010111112149090909294989098949290901212120E47 +:20CF8000002014120100F1121411111214284700A0A0A4A8B0A0B0A8A42024241C00FE0022 +:20CFA00001211112854142101720E222232020000000FC0404E48484F484A4A4E4042810A6 +:20CFC00001794952556152484F486A52434040400000FC0404E48484F484A4A4E4042810C6 +:20CFE000002010100300F010111010101418100010101010FE101010109090101010502033 +:20D0000001017F02040F34C7040704FF04081F000000FC8040F018E600E000FE0010F808AE +:20D02000101050517C5093101CF1501010101010202020FC2020FE0808FE08884808281053 +:20D0400004FF04003D24253C27243D262444558A40FE402024A8FC40FE8824AA70A824627A +:20D060000279494F487F494A4D784949484B4898484850FC40FE1008F61010FC04E4140831 +:20D0800000001F119153561930539C10202340808040FE0000F81020C0300EC02000C02037 +:20D0A0001109097F02FF093FC01F001F001F101F101020FC00FE20F806F000F000F010F011 +:20D0C00011101011FC1031395551901011121410088890FC2424FC2020FE62A22A242020DB +:20D0E000003F21213F21213F103F4A9224481221040404242424242424A4A4A484849408B1 +:20D10000007C4444447C10105C5051525CE1000000FC8484FC8484FC40FE2A4A92224A8467 +:20D12000212038234078A322FA23202029322400088890FC2424FC2020FE62A22A242020CA +:20D1400010111111FD1111151833D0111111522400FC0404FC0404FC00FE20203C20A07ED8 +:20D16000003E223E223E00FF08082F2828584F8000FE10207C445454545428448200FE00D2 +:20D18000007C4544447C13125C5151515DE100004020FC008850FE2224FC242434282020C0 +:20D1A0000000794848484B4A4C494979490100004020FC008850FE2224FC24243428202090 +:20D1C0000808081017303050911112151810101040404040FC40E0E0505048F44240404075 +:20D1E00008087E08FE1422419F10101F10101F102020FC20FE508806F01010F01010F0109F +:20D200000007F097949B92939293F0970202050840FC40FE02FC48F848F800FC447840FE81 +:20D220001011111119555050911214101112101100FC04FC04FC8080FE4A4A922242940872 +:20D2400002211117804047141427E02122242800101020F84848F84040FCC444544840405E +:20D26000422224FF0909FF8888FF18284A890808040404242424242424A4A4A48404140870 +:20D28000003F20203F202424243F24244444840700F80808F890909090FC9090F00000FE60 +:20D2A000003F01010101FF0102020404081020C000F800000000FE00808040402010080673 +:20D2C00000231010874041121420E0222224210000FC4040FEA0100846404864525240808C +:20D2E0002020272023FA23222322233AEF4102044040FC40F808F808F808F808FE10080497 +:20D30000003F21212121213F21212121213F200000F80808080808F80808080808F80800A6 +:20D32000081C701011FC10107C444444447C440088888888FE88888888F888888888F888FA +:20D3400010101110185550509011111111111111083CE02020FE202020FC04040404FC04AA +:20D36000081D701011FC10107D464444447D440000FC2020FE505088242224B2AA2AA04059 +:20D3800000784849497949494979494B4848499A505050FC545454FC545454FE00880402FB +:20D3A00010101012FD1010151A34D010111152249090909294989098949290901212120E13 +:20D3C00004040F1864031DE1017F0109112145020000F0204080700E00FC00201008040030 +:20D3E000002310100001F211111111111028470000FC8484841408FC040404FC0000FE007D +:20D400000000784A497848497A4C4848794902049090909294989098949290901212120EBA +:20D42000007C4445447C1010105D5050505CE10250505052D4585058D45250509292120E4B +:20D44000007C4454545454545555551129254581202020203E202020FC0404040404FC0416 +:20D4600010103D2141BD1210FD1010101418110220202020FC202020FE20505088880402F2 +:20D480001010107C545454545555555D11111111202020203E202020FC0404040404FC04C2 +:20D4A000003F2020202F2020202020202040418000FE000000FE4040404040404040408001 +:20D4C00000007949494949494949794901020204081CE0000000FE10101010101010101077 +:20D4E0001011101054585093101110282444438000FC08103048840200FC20202020FE004C +:20D5000000201310804048081010E020202020000000FE2020202020202020202020A040FA +:20D520000000F9081010217808084833102C4380083CE0202020FC20202020FE0000FE00AB +:20D5400010101720236263A02F282320202021208040FC00F808F800FE02F84040404080A5 +:20D5600002017F001F101F007F409F01010105020000FC00F010F000FE02F4000000000093 +:20D5800001003F202E2224242E22222A444689100080FE000EF01010FE1010FE0000FE001E +:20D5A00020202721F922222F31E525222225A850000C701010107C101010107C0000FE00F9 +:20D5C00010207B48685949FB484A6A59494A4C980006B88888083E888888883E00807E0017 +:20D5E000004720210007E424272424272424548F00F810A040FC4444FC4444FC445408FE49 +:20D6000010131212FE12323A565292121212121200FC0404F40404F4949494F404041408EB +:20D6200000FE2828FEAAAAAAAEC282FE8282FE8200FE8282BA8282BAAAAAAABA82828A84E8 +:20D64000000178484B784949794949487948030020FC8850FE00FC24FC24FC20FC20FE0035 +:20D66000003F20202F202027242424272420202000FC0404F40404E4242424E42404140806 +:20D6800020233A22427AA222FA2222222A32220200FC0404F40404F4949494F404041408C3 +:20D6A000003F212129252521FF212121214145820004040810220204C8102202040810600A +:20D6C00002013F0804FF001F111F111F013F01FF0000F82040FE00F010F010F000F800FE02 +:20D6E00020272021F82724746FA4A4272424242400F810A040FC4444FC4444FC44445408AD +:20D7000020272021F827242C37E424272424A44400F810A040FC4444FC4444FC44445408AC +:20D7200010103F2845BF202F202724242720202040407E9008F808E808C84848C808281013 +:20D740001010202348F8112340F8400019E14204402020FE408804FE9290909012120E007E +:20D7600000001F109751501734579417242444848040FE00F810A0FC44FC44FC444454081F +:20D780000808091215303352921312121312121240A01008F600C45454D45454D44454C878 +:20D7A00010101010FC1112151830D0101010502300F88888880600FC84844850205088060A +:20D7C0000000080424101000FF010102040830C08080808080808080FE004020100804047C +:20D7E000002310170102F413111111121428470038C040FC504846F0103C04140800FE00A1 +:20D80000000F0808080808784040404040407F4000E020202020203C040404040404FC0446 +:20D82000001F01017F050931C00F08080810204070800000FC40201806C0404044443C0044 +:20D8400002017F4088112101017F0102040830C00000FE022410482000FC00804020180636 +:20D86000007F4242474C52414678434046417F4000FC0404E4448404C43C04840484FC0434 +:20D88000080811204808133050911111121214182020FC202020FE2020203C20A0603E00CD +:20D8A000002011120500F017101212141128470040A01008F64040FC404844444080FE0019 +:20D8C00000201011824540101720E222242821004040A01008F64040FC405048444440807E +:20D8E000003F203F202027203F2023265B42830200FC04FC8088F0A0FE80F808F808F80827 +:20D900000101010101013F01010101010101FF00000000000000F800000000000000FE00C6 +:20D920000000784848484F484848784800000F00404040404040FC40404040404040FE0067 +:20D9400008080F10207FA121213F2204081020C00000E02040F8080808F888A09092827E27 +:20D960000024141487404F101027E4242424240440444444FC00FE4080FCA4A4A4A4A40C84 +:20D98000007F4040405F40414244485042417F4000FC048484F48484848484848404FC046C +:20D9A00010101011FD1315111931D11111115121A09080FE1010FC1010FC101010FE00001C +:20D9C0000C7110FE11395593013929292A4C498200FE2040FC042424242424445088040289 +:20D9E000007A494948784F494979494949494A9C007C44447C44447C504A44546242807E9F +:20DA00001110107C555555557D5010141CE5420404848810FC040404FC50509092120E00C7 +:20DA2000201201F9081017355995151111111214007C44447C44447C504A44546242807EA2 +:20DA4000032212130202F3121212121312284700F80808F80808F844281088040400FE0097 +:20DA6000003F0101FF02040830DF101010101F1000F80000FE80402018F610101010F010B6 +:20DA8000010101FF01212121213F010101010000000000FE0008080808F800020202FE00A2 +:20DAA0007E427E547E547E94621F101F101F101078484886784830CE00F010F010F0103075 +:20DAC00010101011FE1111151B31D111111150208080FE0020202C74A42434282202FE00EC +:20DAE00010101310FC1010141B30D01010105020083CC0404040407EC040404242423E0032 +:20DB000001784848497949494978484848494A9C04848810FC040404FC50509092120E00DA +:20DB200010207C4454455448407E0202FA021408201010FE820440485060404242423E00A6 +:20DB4000007C4449495249494545456951414040402020FE020400081020C0040404FC00C1 +:20DB6000007C04242425243E02021AE24202150A2020202020FE20202050505088880402EF +:20DB800000F80849494A487C04041CE444042810201010FE0204808890A0C08282827E001D +:20DBA00020272425FD2625746CA4A625242424241090907E20207CA4A4BCA43C2424242CC8 +:20DBC000007F022111100202FF04081E01061860FC00080810200000FE2020408060180420 +:20DBE00010101310FC1010141932D410101050200000FE20204040FC848484848484FC84A1 +:20DC00000000F390909792929792F297000007001078C04040FC4848FE4848FC4040FC0023 +:20DC200010101312FC1112141830D010111150204020FE02880402F8102040800202FE00DA +:20DC40000000794848484B4848487948000003002020FC202020FE002020FC202020FE0058 +:20DC60001010117C545457547C5011141CE443002020FC202020FE002020FC202020FE003C +:20DC800000201310804047101020E320202027004040F8404040FC004040F8404040FC0028 +:20DCA00010101110FC24272424482910284483002020FC202020FE002020FC202020FE00F0 +:20DCC00000FF04040407080A09090810131C100000FE000000E020202020202222221E00B5 +:20DCE000201000FD081010355894141111121010202020FE202020FC70A8A8242422202022 +:20DD0000007F0103051961007F0111111111FF0000FC000060180400FC0000F80000FE00D4 +:20DD2000101010103E224242A41408081020408040404040406050484444404040404040C7 +:20DD400000FC03027D49494A7A038C485119E2044020FE020400DE5252529A941012120E20 +:20DD60000201FF04142444003F003F203F0000000000FE4050484400F010F000F8085020CA +:20DD800001201F11854940171027E427202020000080FC20282400F010F000F8080850201B +:20DDA0000000FD101010137C101010101DE142040000FC000000FE909090909012120E0027 +:20DDC000007C000000FE28282828282A4C48800300FE2040FC849494949494A4304884025C +:20DDE000020202027F02120A04040A091120408000000000E02020202020202222221E004E +:20DE0000101013165C51509013101028254142844020FE0204F80000FE90909012120E0069 +:20DE200002017F40801F00007F040404080810600000FE0204F00000FC4040404444443CBE +:20DE40000000FB222541794ACA4B4C48794902044020FE020400DE5252529A941012120E63 +:20DE600010101112FC1312161A33D010111152248080F80810FC444444FCA0A022221E00ED +:20DE80000000794A4C4B4A7A4A4B4848794902048080F80810FC444444FCA0A022221E0001 +:20DEA0001010237A4C4948487B48484849794A044020FE0204F80000FE90909012120E00E1 +:20DEC000101013121D55515292131410111112144020FE020400DE5252529A941012120E2F +:20DEE00002017F40901E122222528C04081020400000FE0204F8888888A8908282827E0032 +:20DF000020202322FD49494A8A4B3410294982044020FE020400DE5252529A941012120EEA +:20DF20000000FF040404070404080810102040800000FE000000F010101010101010A04079 +:20DF400000784B4A4D79494A4A7B4C4849494A9C4020FE020400DE5252529A941012120EE2 +:20DF600000271010804040131020E02020202F0000FC4040404040FC404040404040FE00F2 +:20DF8000007F01010101013F010101010101FF0000FC0000000000F8000000000000FE00C7 +:20DFA00002010100FF1010101010101010101F0000000000FE000000000000000000FC00B5 +:20DFC00010101310FC10303855509010101017100000FE2020202020FC2020202020FE00C6 +:20DFE000007F404042524A44444A4A526140404000FC04041494542424545494040414080D +:20E0000008081027480810305790101010101F10804000FC40404040FC4040404040FE00DD +:20E02000000778484848784B4848487848000F0000FC4040404040FC404040404040FE0069 +:20E040001008FF2020263820017F01013F0101FF007C447C447C449408FC0000F80000FE5B +:20E060000201FF101010101F00010848484887000000FE00000000F8000088841212F000C1 +:20E080000201FF10101F0202FF04081E010618600000FE0000F80000FE2020408060180423 +:20E0A0000000003F20203F22223F242825424598282420FE2020E42424A8A890122A4682D5 +:20E0C00001417F007C11FF395593FC24681029C60004FC2040FC24FC24FC245A5E90120E23 +:20E0E000111525459710206FA02724242424283008484850DE2414D4149494A8C894142263 +:20E1000004040F10205F101312121212222241800000F01020FC00F0101050200404FC0049 +:20E120000101017F01013F01017F010101010101000000FE0000F80000FC0404042810005F +:20E1400000402F200007E0202F20202020508F008080FC8080F88080FC8484948880FE0009 +:20E1600010101011FE11313955519111111212144040FC0408FE007C4444544842423E006C +:20E18000007F41415F414F415F41414141417F4000FC0404F404E404F41414542404FC046F +:20E1A00000007849494B4D494949794901010101A09080FE1010FC1010FC101010FE000008 +:20E1C00010101011195755519111111111111111A09080FE1010FC1010FC101010FE0000CC +:20E1E00001211111017F020202040408102040800000000000F808088848480808085020AD +:20E20000048444088B5E4404285EC84046584000504880FE9090FC9090FC909090FE808091 +:20E220001010202545FB152141FD41011DE14101A09080FE1010FC1010FC101010FE00002F +:20E240000808FF09017F01011F01017F010101012020FE2000FC0000F00000FC0404140816 +:20E2600008FF08001F017F0519E1047F081C037C20FE20708000FC40300E00FC20408078CF +:20E28000001F0101FF050931C202FF081C030C7070800000FE4020180600FE2040807008F7 +:20E2A00008080817103033509017101010101010404040FE4040FC4040FE42424A4440401B +:20E2C000080A09111037305090101011111214184040404040FC444484A494140404281067 +:20E2E000003F20203F20202F21212F21215F418000FC0404FC00F00000F00000F80202FE44 +:20E300001010202544F8102040FD40001CE04000202020FE2020FC2020FE22222A242020C9 +:20E320000101013F010101FF0305091121C10101000000F8000000FE80402010080600009F +:20E340000808FF08003F213F202E203F4455A40C2020FE2000080808FE0848282808A8103D +:20E360000000784B4848484F4849794A04080000404040FC404040FEE0505048444240400B +:20E38000001F11111F11111F00FF11101014181000F01010F01010F000FE10A040300E0034 +:20E3A000003F213F213F001F101F101F1010101000F808F808F800F010F010F01010502029 +:20E3C00000037A4A4B4A4A4B484F7A4A0202030200F84848F84848F800FE40442890080698 +:20E3E0000C7011FF3955930111FC2444281129C62040FC2424FC2424FC4068B2BE20221E76 +:20E4000008080810173030529211111111101F1080404000FC000808081010102020FE0074 +:20E4200000271417844740131223E2232222220200FC44FC44FC00F808F808F8080828100E +:20E44000004724270407E023222322232A32220200FC44FC44FC00F808F808F80808281056 +:20E46000003F20203F202F20203F222A4A528A0404848484BE04842414D40484444414088C +:20E480003F213F202F205F44952C01084848870008087E084828A808289000849212F00064 +:20E4A000007F020202020202020202020202FF0000F8080808080808281000000000FE0068 +:20E4C00001003F2027A467242760AF2929497F800080FE00F808F808F800FC242424FE00DA +:20E4E00000231212834242131027E42424242F0000F80808F80808F800FCA4A4A4A4FE0073 +:20E500001010107D545454547C5010141EE24001402020FE888888888850502020508806E9 +:20E52000020101FF1010080804020102040830C0000000FE10102020408000804020180687 +:20E54000201700405F4447444744445F4040404000FC0404F444C444C44474C44444540880 +:20E560001010202749F1112141F8400018E1420C804040FC1010101010A0A040A01008067E +:20E58000010179494A4C4849494A7C4801020400000000FCA4A4A4242444448404042810B6 +:20E5A000081CF11211FC1039345451901012121440F80810FC0404FC0404FC4024A28A78D1 +:20E5C00002017F080718E2041F01063F011125420000FC20C0300E20C08010F8082010080C +:20E5E0002017004040474444444444474440404000FC040404C44444444444C44404140836 +:20E600000000794A4C4948484B487A49020001009088044288FC0400DE42524A52424A84B5 +:20E6200004081224C81F00007E22120A12224A044020100826F01000FC4424142444940859 +:20E6400004081022C4081F00007F080F09101618402010084620F00000FC00E020A4241C06 +:20E6600024222220F82E222A32E222222225A84008080808FE084828280808281000FE0015 +:20E68000202121F9A9A9A8A8FBA2222A3BEA420200FC040404FC2020FE22528A0A020A04D1 +:20E6A00000231212824340101724E4252624240400F8080808F84040FC44A4141404140894 +:20E6C00002017F48902F08080F013F21222420200000FE2214E82020E000F808884808187F +:20E6E000040E780808FF08080A0C186808082B104050484840FE404444483022528A0602EC +:20E70000101010FE117C447C457C10FE10101010202050880412905010901EF01010101073 +:20E72000007F4848487F4141417F4848487F000020A02020203028242222202020A020204A +:20E7400020232222FB22232A32E322222524A85300FC0404FC00FC4088FC2420FC2020FEED +:20E7600000201710804040171020E021212224081078C040404040FE40A0A01010080402A7 +:20E7800000007F0101111111292945850101FF000000FC0000101010282844840000FE0066 +:20E7A000000079494949494949497848030000002040FC040404140800FE0202FA02140880 +:20E7C00010103C2040BC1010FC101010151810002040FC848484948880FE0202FA0214089A +:20E7E00001021F1010101010101F00007F0000000000F0101010502000FC0404E404281045 +:20E8000000231010804740101121E0202020200000F8000000FE808000F80808080850208E +:20E82000004720200202E2252428202830200F0000FC404048484854D26240404040FE0079 +:20E84000003F20203F202F21222720202F4040BF00FC0404FC00FC0010F88880FC8080FE8D +:20E86000003F020202027F04040408081020408000F000000000FC808080808084847C00D6 +:20E880000808FF08003F02027F020404081020C02020FE2000F00000FC80808084847C004F +:20E8A00010131010FD10303B545091111111111100FE4040FC8484FE0000FC040404FC048B +:20E8C000007F02023F040408FF001F1010101F1000FC0000F0101010FE00F0101010F010AF +:20E8E000001F10101F00003F0101FF02040830C000F01010F00000F80000FE804020180688 +:20E90000001F11111111FF212222223F0408102000F010101010FE10101010FC1010A04029 +:20E9200000003F0000FF0004042724242427F8404050484840FE404040402022128A06025B +:20E94000007F020202023F04040404080808FF0000FC00000000F010101010101010FE0070 +:20E9600010131010FD1010171830D1111111512100FE4040FC8484FE0000FC040404FC04DA +:20E980000808081F1121410101FF010101010101000000F80000000000FE000000000000D0 +:20E9A000103F4A0A7F0A0A7F10103E42140830C000FCA0A0FCA0A0FC1010FC1090FE1010A8 +:20E9C000080B081010303350901010111111171000FC40404040F888888888080808FE0015 +:20E9E000090909121531315197111212131010100000FC00F8084828FE084828FC085020BD +:20EA00001010111111FD11111111101CE34000002040FC040404140800FE0202FA02140875 +:20EA20000000003F20202020202020202040438C908880FE8080844448483022528A060244 +:20EA40003F017F419D011D040F14031CE20F0418F800FE0274007000E04080700EE020604E +:20EA6000000378484948487B484849497949010100FE4040FC8484FE0000FC040404FC0411 +:20EA8000101050507D5290101CF1521010101110808080FC5454549494242444448428106B +:20EAA0000808081F122242840408102142040810000000FC444444444484840404042810EE +:20EAC00004040F1824030C32C21F0204040810200000F020C000C0300EF010101010A040A1 +:20EAE0001013101019545053901011111111111100FE4040FC8484FE0000FC040404FC0435 +:20EB0000004322220300E02720202F202831220C00F80808F80000FC4040FE40A0100806D6 +:20EB200004043F0404FF00001F10101F10101F104040F84040FE0000F01010F01010F010C4 +:20EB4000007F44445F51515F44447F0024224280007C4444447C40404242BE0088444404A5 +:20EB600010101111FD1131395551911111121214081CE0000000FE101010101010101010B8 +:20EB800000FF0404043F24242424283020203F2000FE404040F84848484838080808F8087E +:20EBA0000003FC1011213D6565A525253D25210100FE5050FC54545454548C040404FC04C4 +:20EBC0000000FC1010203D6664A424243C2420034040407E828242241408081020408000C7 +:20EBE0000202F2929F9292F6979A9A92F2920202000C704040407E4848C8484848484888ED +:20EC00000007F09390939293919FF0930202030240FC40F800F808F810FE00F80808F808E4 +:20EC20000007794949494949494A7A4A0404080300F8081010203C0404888850205088069B +:20EC400010113D2141BD1111FC111210151A100100F80808F80808F880FC54942444940836 +:20EC6000101750507C5392121EF252131212131200FE909090FC949494949C040404FC04FA +:20EC8000091CF01013FC13383553559111111010846830C80440FEA020FC2424342820207F +:20ECA00001021F101F101F101F100108484887000000F010F010F010F01000849212F0005D +:20ECC000180601063A02FF04081F284888080000186080601800FE8080F88888A8908080FB +:20ECE000003F110901FF091121C0010848488700F800102000FE2010080600849212F00024 +:20ED000000784B48487B4848497A4948494A48982020FE70AC225088242224A82422A04042 +:20ED200002020202070408102442010001020C7000000000F80808101020408000000000BA +:20ED400010101013185457509111111111111111888888FE8888FE00FC0404FC0404FC04A9 +:20ED6000101011155951519111101028264244802040FC04FC04FC04FC4020A48A8A780050 +:20ED8000111010145B5053901113152925414080846830C80440FEA020FC24243428202052 +:20EDA00000271211804143101123E020272021063CC044288010E04088FC4440FCA0100E79 +:20EDC00000201010814142141020E02020202106808080FC040484482810102040800000CC +:20EDE000003F203F20282628242728205F40800000FC04FC0088B08C80F88080FE80808077 +:20EE000021222724FF24277269A7A223222425280808C850DE64D41414D414C8485454A298 +:20EE20000404FF0911214F8201FF050C34C506044020FE10608404FC00FE008850300E0045 +:20EE400001003F22223F222223202F28484888000080FE2020FC2020E080F88888A89080DF +:20EE6000007F00000804020200010E702000000000F80808080808086888080808085020BC +:20EE800020202121F9494949894830102A4A84002040FC04FC04FC04FC4020A48A8A780027 +:20EEA000017F013F003F203F08FF003F20203F2000FC00F800F808F820FE00F80808F808FD +:20EEC00010113D2141BE1013FC10101015191204202020FC202020FE909090901212120EE3 +:20EEE00000221213844840171121E12122222408404040FC404040FE2020202022221E00A8 +:20EF0000003F0408103F0106187F010911214502F80000204080001008FC0420100804000A +:20EF2000007C454A48514949454544685142404020A8242200FC04FC04FC20A82422A0405A +:20EF40000000007E02022514080814122240000120282424203EE02424282810324A8602E3 +:20EF60001010212545F9112141FD41011DE141010000FC2424242424FC2424242424FC049B +:20EF800000007B4A4C794849784B4849794901014020FE0224FC20FC20FE20FC0404FC0460 +:20EFA0001013107C545454547C5010141EE2400000FE404040405048444440404040404084 +:20EFC000007F40404F48484F48484F4840407F0000FC0000F88888F88888F8888080FE0054 +:20EFE0003F017F419D011D003E223E203E203E20F800FE0274007000F808F800F84830CCCC +:20F00000202023FE445190FD10131CF1511111114020FE0224FC20FC20FE20FC0404FC04DB +:20F020000007F494949794F497949497F494040400BC848484BC0000BC2424A810284482FA +:20F0400010101011545554545457545C64000102202020FC2024A4A820FE5050888804029C +:20F0600008080817103231509F10101111121418404040FC40485040FEA0A010100804023F +:20F080000044281128498808182B488808085122202020FC2024A4A820FE5050888804029C +:20F0A00000FF020202020202020202020202020200FE0000000040201008080000000000B7 +:20F0C0003F203F212724272427242722474A811EFE00FC00F808F808F808F800F808F00E27 +:20F0E0007F021F101F101F101F081F2844031CE0FC00F010F010F010F000F0204080700E17 +:20F100000007784848484848484878480000000000FE40404040504844444040404040401A +:20F1200020202724F424272535E525252529A9501090103E2244901010102828284444829F +:20F1400020203B22427AA322FA2222222A3424081050901E1224C888888888949494942209 +:20F160000111111F214101FF04040408081020C0000000F8000000FE4040404042423E0027 +:20F1800010101020246464A4242424242427202040404040444444444444444444FC040010 +:20F1A00010101E22247EAA2A3E2A2A3E000E7020824428FE1010107C101010FE1010101005 +:20F1C0001010212444F8102340FC40001CE04000083CE020202020FE202020202020202001 +:20F1E0000000003F20202F20202F29292F494081504840FE4040444444282812324A8602DF +:20F2000004252424242427041F10111111020C7000F8885020D80600F010101010601804B0 +:20F220001212234284172A62AF2222222223222000009C0000803E088808080888082810B8 +:20F2400010207C45645454FC4564545444455488201010FE20204484F810204482FE82004B +:20F260002017004141415F41434549514141404000FC04040404F4048444241404041408A8 +:20F2800000201711814242171125E52222252810081C701010505C505050507C0000FE0034 +:20F2A00000F8080B0878404143780808090B5120402020FE40408808F020408804FC040088 +:20F2C00010101013FC2524272449281029468400885000FE50FC54FE54FC50D854525050B5 +:20F2E000001F10101F10101F044424141404FF0000F01010F01010F0404444485040FE002C +:20F30000007848505162554848486A51414047404040A0A01008F600884848501020FE00D6 +:20F320000001FD111111117D111110101CE1420400FC040424242424245450909012120EDB +:20F340000808FF08087F4155495D497F4949454210149212107E10101010282828444482DA +:20F36000001F10101F10101F1010FF0408103F1000F01010F01010F01010FE002010F80808 +:20F380000078494949794948487B4849494A4C984080FC04FC04FC2032B4A8282424A24089 +:20F3A000202020394A548023222223222A3223028080F8081000409C04049C040404FC04CD +:20F3C00008047F013F01FF4020091224E020232C2040FC00F800FE8080FC044840A01806DC +:20F3E00002017F4081111F2101FF0404040830C00000FE020400F80000FE40404042423EF9 +:20F40000007848515264504B4A4A6B52424243428080F8081000409C04049C040404FC0494 +:20F42000007B4A525362524B4A4A6A524242434200F80808F80808F8444830201088060088 +:20F440001010202445F8102340FC40001CE043005048405CE0405EE044483022528A0602C9 +:20F4600008080808FE08181C2A2A48880808080800FC848484FC848484FC84848484FC8452 +:20F48000003F2222222F2226272A2A322242428200FE00007C44447C44C47C4444447C44ED +:20F4A00020273823427BA127F92721272933250140FC00B8A8B810FC10FC10FE28104886BB +:20F4C000001F0101FF050931DF10101F10101F1070800000FE402018F61010F01010F010D4 +:20F4E00010103F284588087E08181C2A2A48880840407E900800FC8484FC8484FC8484FC2C +:20F5000001FF003E223E047F043F04FF041CE50600FE00F888F840FC40F840FE44281806C7 +:20F52000024222220F824257162AF2222222220200007C4444447C44C4447C4444447C4445 +:20F5400002020408103F0102041F0000010618E0000020204080080810E040800000000067 +:20F56000442528FE11107C1010FE11102020418000DC444454CC44444CD4644444445488E7 +:20F58000211010F80B101039549013101010101004848800FE2020FC2020FE20202020205F +:20F5A000022111100700F013101017101418100008081000FC4040F84040FE404040404028 +:20F5C0000808087E08181C2A480801084848870000F88888F888F88888F800849212F0001F +:20F5E0000000784B4A4A4A4A4A4A7A4A02020202404080FC0404F494949494F40404140860 +:20F6000002017F001F101F001F0001FF010105020000FC00F010F000E04080FE0000000068 +:20F62000000100FC111111111111111DE040010200FE2040FC0424242424244450880402E2 +:20F6400004043F0404FF04081F28C80F080808074040F84040FE4020F02826E0200808F877 +:20F6600010101113FD113934505390131010131080F808FE1222FE40A2549834549250203A +:20F6800009090A171A323350911611161011161000F010FC2444FC8044A83068A824A24041 +:20F6A0000204087F404047444444444744404040000000FC0404C444444444C4440414089B +:20F6C000081F207FA1223F0619620C710618E20100E020F80808F80010A0C0A090888600B5 +:20F6E0000808FF08013F01FF013F0125252941812020FE2000F808FE08F800482828080839 +:20F700000001FC1010213D6565A525253D2521012024A4A820FC0404FC0404FC0404140859 +:20F720003F017F419D011D11093F203F203F2020F800FE027400701020F808F808F8081893 +:20F740000849292A087F41417F41417F4141454204040424242424242424242404041408FF +:20F7600000007B48484F48484B497A4D080000004044F44848FE2040F81020FE2020A04090 +:20F780003E223E00FF011F1011020C70003E223EF888F800FE00F01010C0300800F888F879 +:20F7A00010113C2040BD1111FD111111151911012024A4A820FC0404FC0404FC0404140865 +:20F7C0000022111180434A0A1312E223222222024048485040F80808F80808F8080828108C +:20F7E00002017F409109011F101F101F101010100000FE02142000F010F010F0101050203B +:20F80000022110138C404F111326EB22232222021020C0308880FE00F808F808F808281069 +:20F820000000784B4848487B484B4848794902048080BCC05024D40C00FE909012120E00A7 +:20F8400001010101011111112121418101010502000000000010080404020202000000003D +:20F8600002023F0202FF01023F10205F800002010008D02040FE0000E04080FC808080009C +:20F8800010101011FC10313A5450901010101013402020FE0088040288885050205088066F +:20F8A00001211109013F20203F20203F202020200008102000F80808F80808F808082810C6 +:20F8C00000007B484F484B484A4A7A4B020204084040F848FE48F8404848E85848484848A4 +:20F8E00010103F2845803F0101FF0102040830C040407E9008F0000000FE008040201806FB +:20F90000100800FF0024428124140814224280012020203E444444A428281010284884023C +:20F9200021212721FB21277169A0A7202021222C003CD4149414D4244C40FE40A0100806DE +:20F94000040424272424242FF040001F00007F0040404448704242423E0000F00000FC007F +:20F96000007E427E427E207F894955417D010A042020207E42841010101028282844448290 +:20F980001011117D555554557E5111151DE4400000FC04FC04FC80FE22225202FA02140805 +:20F9A0002828FE2838107D54547C10FE101011102020FC202020FE002020FC202020FE0065 +:20F9C00020202020FB202022222428202121222480808080F09090989492929010105020B4 +:20F9E00010101011FC1110141833D01010105122202020FC2024A4A820FE50508888040217 +:20FA000010101113FD1111151931D31010115224A090FE20FC20FC20FE00FC889E020A04F4 +:20FA2000007F02222222427F060A122242820A0400BE2224242824E422222234282020208E +:20FA40000808142241BE08087F082A294988281008482828084828280E7808080808080878 +:20FA6000007848484B78484A4A7C484849494A9C80808080F09090989492929010105020DB +:20FA8000022213120203F21013121213161A13022024A830A2225E80FC0404FC0404FC04C1 +:20FAA000007F4090101F10203F0000FF0000000000FE020400F80000F80808C8080850200E +:20FAC00010101010FB103139575191111212141010141210FE105054F45454484A5A2642F7 +:20FAE00020203F4888087F08082E28282FF0400000007C444444444444444454484040404B +:20FB0000203E44BE2A3E2A3E2A2A453F213F017F00FC24549850FC10FE1010F808F804FE7D +:20FB20002223242937ADA5A7A525272525252428009E8A0AD26640D45E64C4445E4444C465 +:20FB400000221212824F42121222E222222223004848484848FE4848484878000000FE009F +:20FB6000002714198141490A1310E0272020200000FE020400FC0000FC0404F4040428105A +:20FB8000014227240704E724242F212A3428020108088888BE8888C8A8A888888888A810E6 +:20FBA000003F20203F2024222F282F284F48880800F80808F88090A0F808F808F808281064 +:20FBC00008FF0810087F2214FF087F082A49A81120FE2000047840407E484848488888089F +:20FBE0000808FF080802010004242444840403002020FE2020000080080402021010F000AA +:20FC000010103D2040BC1310FC101110141810004020FC008850FE202020FC2020202020B1 +:20FC20000207382020203F2424242424244444812020207E428410101010282848448402BD +:20FC400002013F000804FF0101017F01010101010000F8002040FE000000FC00000000007E +:20FC600010087F002214FF08087F082A498828110004784040407E4848484848488888086B +:20FC800010101111195551519111111111121214081CE0000000FE10101010101010101073 +:20FCA000000201000004042424244444840403000000008080000804040202121010F00084 +:20FCC00008080B101031305091101011111111114020FE0000FC0000FC0000FC0404FC04D8 +:20FCE0000808107F555555555555555557FC0000101094545810FC101010FE109010101000 +:20FD0000001F101F101F01111F21411F01017F0000F010F010F00000F80000F00000FC005F +:20FD2000007B4A4B4A7B484A4B7C484B48484F9800F808F808F84040FC4040F84040FE0021 +:20FD4000008B522352931012335490131010A74000F808F808F84040FC4040F84040FE0001 +:20FD60001011111119555051911210111010131000FC04FC04FC2020FE2020FC2020FE0076 +:20FD800004022111080800FF000404080810204008080810102040FE004020100808040476 +:20FDA000007F1212121212FF121212122222428204840424242424E4242424240404140867 +:20FDC000007F121212FF12222241813F0101FF000484242424A42404140800F80000FE0045 +:20FDE000007F1212121212FF121212122222428200840408102202C408102202040810609B +:20FE0000007F1212121212FF121212122222428200BE2224242824E4222222342820202040 +:20FE20000809102048081330509010101010101000FC00000000FE20202020202020A040F4 +:20FE400000FE2828FEAAAAAAAEC282FE8282FE82007C447C447C10507C90107C1010FE00D2 +:20FE600001013F0101FF08043F0101FF010101010000F80000FE2040F80000FE00000000A4 +:20FE800001017F03050931C1001F101010101F100000FC804020180600F010101010F01026 +:20FEA0001010111119555250901110101010131020202020FC20202020FC20202020FE0076 +:20FEC00010101111FD252624244928102844830020202020FC20202020FC20202020FE006A +:20FEE000003F20202020203F04040408081020C000F80808080808F8404040404042423EBE +:20FF000000001008444241424448506040407F000010102044840484442414140404FC045D +:20FF2000017949494A7A4D484A7A4B4A4B484898000000FE020212A24AAA1A0AFA021408AA +:20FF40000808101F20408825222528203F000000000000F8088888282828A828E8085020CF +:20FF60000020111082424A0A1212E32222232000000808885252222252920A0A02FE020020 +:20FF80000808087E1112202848489014227E2200504880FE9090FC9090FC909090FE80806E +:20FFA0001024427E007E427E427E4246004844848098E084847C8098E084847C00884444AF +:20FFC0000808081017303050911112141810101040404040FE40E0E05050484442404040F6 +:20FFE000101011212A6CA92E282B28282B2021268080F80890609826C01020C810608000B7 +:020000040106F3 +:2000000008047F013F02FF040F1121CF02023F002040FC00F800FE00F01010F01010FE004D +:2000200010131010FC103139545090101010101000FE4040808000FC0404040404042810B9 +:2000400000007B4A4B4A4B4A4B48784F0001020C4080F808F808F808F85048FEA01008063C +:2000600010113C2043BC1112FD101010151912041CE02020FEA82422F88890BE020214085A +:20008000001F01017F050931CF0404040808106070800000FC402018E62040780808502084 +:2000A000201000FC09111135599515111111111120202020FC24242424FC24242424FC04C4 +:2000C000101320204FF9122443F941011AE2440838C04040FC504846F010207C040428104B +:2000E0002020202322FA23222222223BE4440900407C40FE4278C43C00505454D850FE0078 +:200100000000003F202020203E20202020404081504840FE4040444444282812324A8602D9 +:20012000003F017F419D011D00FF023F2424242000F800FE0274007000FE00F88888A8109E +:200140000101013F21212F212022322A2A425F8000F800FC04608808F84048485040FC00A6 +:200160000000784B4A4A4B4A4A4A7A4B04040900407C40FE4278C43C00505454D850FE0057 +:200180000809102041890911214585091020418200FE2040FC04242424242444508804021F +:2001A0001010204192152060A7202222242821204040A01008F64040FC4050484444408035 +:2001C000002010110102F0101310101014181000808080FC20202020FE2020202020202082 +:2001E00008FF0801FF081F030C3F003F213F213F20FE2000FE20C01008FC04F808F808F850 +:2002000000FE2828FEAAAAAAAEC282FE8282FE8200444428AAAA9292AAAAA6C68282FE0234 +:200220000808142241BE08087F082A29498828110000FC44444444282828101028488402EB +:2002400020202020FC242424242424242444438000F8888888F888888888F88A0202FE00CF +:2002600001003F20232020202F202020404081000080FE00F810A040FE42444040404080A1 +:2002800002017F04081F030C3F003F213F213F200000FC0020C01008FC04F808F808F80850 +:2002A000101010111B565252921212121212171040408000FC949494949494949494FE00A7 +:2002C000087F11320C32C2041F01063F01112542007C4444447C0020C08010F80820100806 +:2002E00010131011FD252624254929112945810100FE22203C20FE00FC04FC04FC04140800 +:200300001010232048F7102041FB450119E141014044F44850FE4080F80808F80808F8086F +:200320001010212444FB102040FD40031CE040032020FC2020FE0294501090FE284482023C +:20034000101010FE2028487E09080EF8480808080000FE1010101010FE101010101010102E +:2003600000007B4A4C49484949497949010003004020FE0204FC00FC04FC04FC0400FE00DC +:2003800002017F40803F001F101F101F1000FF000000FE0204F800F010F010F01000FE0056 +:2003A0001F101F101F10FF08103F100128284807F010F010F010FE2010F8080088A424E04C +:2003C00020101001FE21203C242424242445558A8080FE0000FC2424A0A0BCA0A0603E006D +:2003E000020101FF020408103F110204083F1000000000FE002020408000002010F80808F9 +:20040000002212130400F7111111121214284700404040F84040FC20202024241C00FE00CA +:2004200001003F2427A9722F2A6FAA2F20435C800080FE0044287E9090BC90907E901010A4 +:200440000000784B487848497B484848794B0100402020FE40408808F020408804FC040006 +:20046000101021214AF4132242FB42021BE04000808000FC0404E42424E42424E40428106F +:200480002828FE2838117E54547C10FE101010105050509292949890B0D0909092928E800B +:2004A0000808FF08107C45447C43407C45447C442020FE204020FC8850FE2020FC20202020 +:2004C000221111007F40801F0001FF010101050208081020FE0204E04080FE00000000008E +:2004E0000201017F408004040408081010204080000000FE0244404020202010100804024B +:200500003F017F419D011D003F00001F00003F00F800FE0274007000F80808F80808F80897 +:200520000101023F24242424242424242424FF00000000F848484848484848484848FE004B +:20054000003E22223E007F4149494949141221C220202020FC242424242424444484281056 +:20056000003F01FF013F29253F013F01FF484484F80000FE00F82848F800F800FE884444C3 +:200580001017244497142565A5252525292931213CE02020FE20FC0404FC04FC0404FC045D +:2005A00008080F10102F48880F08080F080000000000FC0404C44444C44444C444042810E7 +:2005C000002011110204F3121213121217181000808000FC0404E42424E42424E4042810CA +:2005E000003F00001F00003F0000FF080404000000F80808F80808F82020FE202020A040C9 +:2006000001F909494949497D05051DE545062A1404242424242424242424242424240404C1 +:20062000002111110202F41212111111102847000024242448489048482424240000FE0023 +:200640000000FD21223D454565950909112040808080FC0404E42424E42424E40404281016 +:2006600000271111814141171121E1212121210100F01010101010D0101010120A0A060211 +:20068000012111110101F111111111151912020404242424242424242424242424240404B9 +:2006A000002711110101F117111111111519110100F01010101010D0101010120A0A0602F5 +:2006C000004F20210202E322262A23222A24508F1090901010D8545492921210502000FE3B +:2006E000004F22220202EF222222222222508F0000E020202020A0202414140C0400FE004F +:20070000003F20202020202F2020202020405F8000FE0080808080FC808090888880FE00F4 +:2007200010111111FD1111151931D1101010502000FC242424FC242424FC242020202020F7 +:20074000007E04242424447F0C141424458414082040FC84A484948880FE0202FA021408ED +:2007600000FE929292FE929292FE9210111010102040FC84A484948880FE0202FA02140872 +:200780000003784949494A4B484878490204000000FC1010101010FE30509010101050201D +:2007A000002010080401010101010101010101010010204080000000000000000000000002 +:2007C0000808FF08003F0010203F01020C30C0002020FE2000FC202020FE20202020A0403D +:2007E000003F00001010203F010204081060010000FC4040404040FE404040404040408041 +:200800001011107C545455557C5010141DE6400000FE0888888808FE1828488808082810AA +:200820000121213F003F202F203F20204F409F00000808F800FC80F880FC0080F880FE00ED +:20084000101F22428F14246FA02027242424272400C01C008080BEC8080888888888A89067 +:2008600000271414854444171424E42524282B1000FE2020FC2020FE002020FC2020FE004B +:20088000007E04242526447F0C14142444841408504880FE9090FC9090FC909090FE80806C +:2008A0000003784848484C4A4A4A78480000070000FC909090929294949890909090FE0026 +:2008C000007F040404044424241414040404FF0000FC404040404444484850404040FE00A8 +:2008E000002310110101F213101010151A14000000FC1010101010FE305090101010502040 +:20090000007F01111111FF080F101F002924400000FC00F80000FE00F800FC042494281078 +:200920000007F494949497949494F4950604070400FC04444444FC4444A494140404FC046B +:20094000201700425F4449714F494F494F41404000FC0404F444241CE424E424E414F40801 +:20096000101312165A5253921212122A2742438200FE02222222FE2222524A8A0202FE023B +:2009800000201711824443121223E222232020004080FE104846F84848F84848F842423E32 +:2009A00008087F08080FF040003F24242424FF00202020282422202000F848484848FE0067 +:2009C000007F02120A023F20202020202040408000FC40485040FE00000000000000000067 +:2009E0000001FC1010203C6764A424243C25210200FC8888888888FE8888888888080808E1 +:200A0000202023F8A8A9A9ABF8A2222939EA4408040EB88888282EA8A8A8A83E00807E0076 +:200A2000012121213F00007F04040F1828C80F0800080808F80000FC0000F8080808F80842 +:200A40000000F9081011217909094931102C4380083CE02020203C20202020FC0000FE0015 +:200A60000201FF00003F00003F00003F20203F200000FE0000F80000F80000F80808F80822 +:200A800010087F22147F4448524448514244883000FE10207C44545454545454282442821B +:200AA000201702424748524C48484E48484F404000FC0404E42444E42424E42424E41408A9 +:200AC000011111210204186001111122040830C000081020C0300804001010A040201806A1 +:200AE00000211111814142141023E2222222230200F0101010100E0000F808080808F808A5 +:200B000002027F040931DF11111F11111F0101000000FC402018F61010F01010F40404FC1F +:200B200010101711FE1413161A33D212131050204080FE104846F84848F84848F842423E48 +:200B400000037A4A4B7A4A4B7A4A4A4A7A4A030200F80808F80808F84448302010880600D1 +:200B60001012214180142262A02127212121212000001C0000003E88880808080808281083 +:200B800000201714804340131223E223202122048040FC0400F840F848F848F800100804C7 +:200BA000101010FD1215117D111111FD111110108080F80810FC242424FC00000202FE006B +:200BC0002023222222FA22222223223AE242020300FE00FC84FC84FC20FE48C8304884FE42 +:200BE00004FF04041710F0171434D7100048448440FE4040D0121CD05052D20E008844445F +:200C0000003F20202020202F202121222244489000FE0080908880FC804040202010080694 +:200C20000001FD1111213D6565A524243C25220400FC040424242424245450909012120E4A +:200C4000003F20222224242D362424242444448400FE005048FE9090FE9090FE9090FE803C +:200C600000007B484849484849487849010101014020FE0000FC0000FC0000FC0404FC04E0 +:200C800002013F08043F2020212E20212E40439C0000F82040FC0020C0106088106080008E +:200CA0001010101459525091111111292545418140407C84080020CE0202CE020202FE028E +:200CC00002017F409F101F101F04FF081C030C300000FE02F410F010F000FE2040807008A5 +:200CE000002013100100F312121212161A1404094020FC000890FE1020C81024C81060804E +:200D000000F8084848494A7C04041DE444042B10202050508804FA00442424A88810FE0078 +:200D20000000FC21213D45456597080810204182202020FC2424242424FE20505088040253 +:200D40000101011F1111111111FF0202040830C0000000F01010101010FE80804020180661 +:200D6000011F1111FF021CE2041F12111F007F0000F01010FE80700E00E02060FC04D40806 +:200D8000081CF01111FD11313957549010101112202020FC2424242424FE205050880402CB +:200DA00010111010FC103138545491111214101100F810204080FE9292921222224294081C +:200DC00010111010FC1011141830D1111214502100F810204080FE92929212222242940810 +:200DE0000A09091017303053901017101010101008081000FC4040F84040FE4040404040A4 +:200E000000001F109350501133519112222448818040FE00F020C000FC2424244444A810F3 +:200E20000804047F0101013F010101FF01010101202040FC000000F8000000FE0000000069 +:200E400002211110874040131020E7202020200008081000FC4040F84040FE40404040404B +:200E6000007C45494951494945454569514141410000FC0404040404FC0404040404FC04D0 +:200E8000203F409F007F110A7F043F04FF04040400FC00F000F01010D0109012EA0A06022F +:200EA00008080B1212323252921212131210101000803C24242424242424B428202020201E +:200EC00000001F119057501033509017202040808040FE10A0FC4040F84040FC4040404013 +:200EE0000804007F013F02FF040834C404081020204000FC00F800FE402058464040404096 +:200F000011101010FB103039545093101010101004848800FE2020FC2020FE20202020206D +:200F200002211710834047101021E02721222D000810FC40F840FC4020C0446850484680F3 +:200F400002442F280F08EF223F2427283221508F001090909EA4C414D4088894A24200FEC4 +:200F6000007B48484B7A4A4B48784F484948489B00FE5050FE5252FE0040FE889060D80471 +:200F800010101110FC2425242448281028448102083CE0202020FE2020505050888804024C +:200FA0000000FB202221F92220232039E1410100083CC0044428FC2020FE20242424FC04BF +:200FC00010101310FA11111A30D3101111115120083CC0044428FC2020FE20242424FC04A7 +:200FE0000202027F0100073800FF0404040830C00000FC204084641C00FE40404042423E49 +:20100000002310120101F21013101111111128473CC0044428FC2020FE20242424FC00FE85 +:2010200002017F489020081F2101FF0121213F000000FE22140800F80000FE000808F8082A +:20104000002013100201F1121013101115191100083CC0044428FC2020FE20242424FC048A +:2010600020202022F94848498A4C3010294982049090909294989098949290901212120EEE +:201080000000F097909192949191F0900001020C804040FC001008041010A040A0100806FB +:2010A000007F022111100C3020203C2020203F20FC00080810200078080878080808F808A2 +:2010C0000404FF0410102045FA1020FC001CE0404040FE408080FC04048444440404281010 +:2010E000007F04043F24243F027F04081C03063800FC4040F84848F800FC204080807008E9 +:20110000101190555811FC2828292A282A4C488000DC4454CC540048FE90FC90FC90FE805B +:20112000202F2424F42724746FA4A4252E20202000DE929294949894929292DA94909090D1 +:2011400000037849484B4A49484979490100030020FE20FC00FE02FC00FC04FC0488FE0092 +:2011600000FF22223E22223E222227FA4202020200BE2224242824242222A2342820202085 +:2011800004081824030C30C01F020202020202024020508800C0300EF01010105020000015 +:2011A000007F49497F49497F08087F08080FF040007C042810087E1214101010101050208C +:2011C000004020210207101023E22222222223024040801008FC0400F80808080808F8087B +:2011E00001011111111739D11111111110100F0000000030D0101010105020020202FE0072 +:20120000007F02041F101111111111120204186000FC0000F01010101010109040201008E1 +:2012200010101711FD1212161A33D212121252238040FE20203C4464944848302050880631 +:201240000404040444242414141404040404FF004040404044444848506040404040FE00E1 +:201260000000784848484B484848784800000000202020202020FE2020202020202020205D +:201280000101013F21213F21213F000000010EF0000000F80808F80808F890A042A21A06CF +:2012A00000784F49497A4A4E4A7B4A4A4A4A4A9B8040FE20203C44649448483020508806BD +:2012C0000201FF080810113152951110101011160000FE8080F80848281010A040A018062F +:2012E00000201711814242161223E222222222038040FE20203C44649448483020508806B5 +:2013000000000000000000FF000000000000000000000000000000FE0000000000000000D0 +:2013200001017F011F007F409F001F101F0804FF0000FC00F000FE02F400F010F02040FE27 +:20134000007F44444F50405F4041424458407F0000FC0000F88080FC804020100800FE0044 +:2013600010111111FD1017151931D1111117502000F80808F800FE08F808F8083EC8080811 +:2013800010103C2340BC1010FD12141014181000402020FE4040A0A2A498908884A2C08049 +:2013A00008080817103031519315191111111111804040FE8080404448302010084482002E +:2013C000080B081010373050901310101111121400F8888888FE888888F8888000000000EA +:2013E000020101FF0202050508182848880A0C08000000FE0000000890A0402010080600F2 +:20140000007D4848495D5555555D4949487E010200FE2040FC04242424242444508804022E +:201420000101FF013F01013F21213F02040830C00000FE00F80808F80000FC844C201806A3 +:2014400000231213000FF01312121210112A470040F848F840FE00F8084848A01008FE006E +:20146000081CF01011FC1030395454911010101120207C8448302048903E42A4181060806C +:2014800008080A121231315190101010101112148048480808101010A0A04040A010080686 +:2014A00000784F484B784B4A4B78484848494A9C4040FC40F848F840FC4454A8A0100806CD +:2014C000404D7044443D407C9010FE102825458200FC085020FE2428A0B8A0A0E0201E0058 +:2014E00000201312824243121222E22222242408083CC0000000FE10101010101010101052 +:2015000002017F40801F10101F10101F1010FF000000FE0204F01010F01010F01010FE009B +:2015200020202720FB484B4A8B483010284982044040FC40F848F840FC4454A8A010080614 +:20154000080F101F00FF9254FE38549208FF081000E020C040FE247812FE549220FE202037 +:2015600020202320F92227706BA2A222232020204040FCA01008FE08C8484848C808281000 +:201580001010117D555454547C5010141CE44106402424040488888850502020508804022F +:2015A00008080B101132375093121212131010104040FCA01008FE08C8484848C808281048 +:2015C000003F00000020203F2020202020201F0000F01010101010F0000000040404FC0036 +:2015E000007F0000000102040810102020201F0000F0204080000000000000040404FC00E6 +:20160000020408103F08081F21017F02040830C000002010F80800F00000FC804020180685 +:2016200000042221212020202020242830210204101010101010102020204050880402020F +:201640000808FF0808003F000304081020201F002020FE202000E0C0000000000404FC008C +:2016600010101312FE1212161A32D2131210502000803C24242424242424B4282020202016 +:201680000F08080F08080F04081F224204081102F01010F01010F00000FC4444848428107B +:2016A000001F10101F003F2121213F2020201F0000F01010F000F8080808F8080202FE005A +:2016C00010101010555654545454545C65010000404080FE0000FC08102040800202FE00C5 +:2016E00008080B101030305090111112121211100000FC0810204080800000020202FE007E +:2017000008091121490A1433519110101010131C00F01010100E00F8081090A040A018062F +:2017200000784948487B484949794949484A4A9C4020FC8850FE00FC04FC04FC20948A7A9A +:2017400001412122040FE424272021212224508F0000F01020FC4444FCA0302A221E00FE63 +:20176000404C7044453C407C9011FE10292444802020FC24FE24FC2020FC2020FE202020D4 +:2017800000001F1093525214385792112020418E8040FE00F010100E00F80810A040B00E04 +:2017A000020101FF040424242444448808102140000000FE404050484844444440404080BF +:2017C0000201FF04083ACC083F242837242720200000FE8850201806F84828D848C8281004 +:2017E000013F0804FF001F101F101F025151900F00F82040FE00F010F010F000041212F080 +:2018000010087F2214FF1029CE1426CD1524D40900784848488600FC444428281028448230 +:20182000101013101854505090111112121211100000FC0810204080800000020202FE00D8 +:20184000020121201010080804020102040830C00010101020202040408000804020180681 +:20186000100800FF00081020403F24242424FF00102000FE0020100804F848484848FE008B +:2018800002211110874041121423E22222222F0008081000FC00100804F8A8A8A8A8FE006E +:2018A000012111110101F0101111111519110101000438C00202FE00FC0404FC0404FC0468 +:2018C000002012120201F111101010141811020C8048480808101010A0A04040A010080676 +:2018E000002013120401F11111111115191107004020FE0204F80808F80808F80808FE00A9 +:20190000002311100000F013101110141B10000000FC04885020D82620FC2020FE20202060 +:20192000003F20203F20201F000808FF0810204000F01010F00404FC002020FE2020202041 +:201940007E221A62023F213F213F043F04FF0810FC4434C404F808F808F840F840FE201032 +:20196000007E2212061A6201007F00100804FF0000FC44240C34C40080FC00102040FE0046 +:201980001013212048F8102340F940001BE0400000FC04885020D82620FC2020FE2020200C +:2019A0000404FF04003F21212F21222428203F204040FE4000F80808E80888482808F808A8 +:2019C0000404FF04007C444850484444544841424040FE4000FC8484FC8484FC84841408CF +:2019E000007F404141415F414242444850407F4000FC04040404F404844424141404FC044A +:201A00000638203E223E223E203E2222424A840100784848488600FC44442828102844820F +:201A200002013F000804FF001F10101F10101F100000F8002040FE00F01010F01010F01036 +:201A4000007D454949514949454545695242444800FC040404FC040404FC040404041408BF +:201A600010111111FD252525254929112945810100FC04242424FC2424544C8C0404FC043B +:201A800000007848494A4C48484B7848000000004040A0A01088464000F80810102020408E +:201AA00010113D2141BD1111FD1111111519110100F80808F80808F8444830201048860055 +:201AC00000201710844242101720E02F20202700083CC0844448103CC04040FE4040FC00E0 +:201AE00002017F409F011F11111F11111F0408100000FE02F400F01010F01010F040201053 +:201B00002020203E4448811010101012141811024040407C848820202050505088880402DB +:201B200000003F0404FF04043F040408081020400000F01010FE1010F01000000000000062 +:201B4000007F0101013F2020407F010101010A040808080808080808080808080808080833 +:201B60000078494A54536051484B4868514545488080F80810FC04FC04FC0440242A0AF8FC +:201B80000006784040407E404040404E700000000000FC8484848484848484A890808080F7 +:201BA0000808FF0801011F111111FF02040830C02020FE200000F0101010FE804020180643 +:201BC000202F282AFA2A257868AFA1222320212E00BEA2AAAAAA14A280FE1010A0609804E9 +:201BE000003E222A2A2A1462027F04081C03063800F888A8A8A8508800FC20408080700883 +:201C0000003F22242D3624242127242447409F0080FE50FC90FC90FC00F09020FC04D40880 +:201C200001003F20202128242422222240409F000080FE0000048484484810102040FE0076 +:201C4000202F284A5AFA252840F7410233C0010E00BEA2AAAAAA14A280FE1010A060980458 +:201C60000808FF08007F40803F01011F0101017F2020FE2000FE0204F80000F0004020FC86 +:201C80000808FF08007F41811F11111F01017F002020FE2000FE0204F01010F00008FC04A1 +:201CA0000808FF087F409F10101F003F20203F202020FE20FE02F41010F000F80808F80828 +:201CC0000808FF08007F408111112202040830C02020FE2000FE02041010A080402018064B +:201CE000202121F9A9A8ABAAFAA3222A3BE8400000F01010F040F84848F84848FA42423E8B +:201D0000002013120202F212121213121028470000803C242424242424B428202020FE00E0 +:201D200001FF203F003F203F00775475557552B400FE00F800F808F800DC54545C5696627A +:201D4000003F080F0812112244003F242424FF0000F010A0BC8404944800F8484848FE0064 +:201D6000007F417F417F08FF007F417F0849881800040408102202C40810220204089060ED +:201D8000404D7044453D010D7111FF113854911200FE2040FC04242424242444508804027D +:201DA0000001FC1011213D6565A525253C24200300FE2020FC2424FC2424FC20A040B00EEB +:201DC0000000784949497949494B487848000102202020FC2424242424FE205050880402F3 +:201DE0000202F294959F9292949FF490010E04002020203C444484241494040484042810FB +:201E000020272424FC27242C34E724242428A85000FC444444FC444444FC44444444540821 +:201E200010171424246764A4242724242428283000FC444444FC444444FC44444444540881 +:201E400000784F484A7A4C4F497A4C4F494A4C984020FE28247EC8487E48C87E48487E40AD +:201E600000001F109057541437549417242848908040FE0000FC4444FC4444FC44445408E4 +:201E8000003F202F203F202F202F282F484F880880FE80F888FE88F880F888F888F88898A5 +:201EA0000201FF101024457A10244478081020C00000FE5048FE9090FC9090FC9090FE80CB +:201EC000007D4444447D11115D5151515DE1010100F808D020FC2424FC2424FC2424240C9E +:201EE0001011107C545555557D5111151DE5410100F808D020FC2424FC2424FC2424240CBE +:201F00000000784948484B484848794902040000402010E02234B8B0A8A828242422A040B5 +:201F20000020101380404F111121E22428302100804020C04444485060605048444240802F +:201F400000271011804744141724E4272424240400F810A040FC4444FC4444FC4444540894 +:201F60000201001F01017D050509091121C1050200008000040890A0404020100806000030 +:201F80003F06013F213F213F2120010848488700F06080F808F808F8081800849212F0009B +:201FA0003F06013F213F213F2122027F04081060F06080F808F808F8080800F8080850204C +:201FC000003F2121213F2121213F21212141418000F8080808F8080808F8080808082810A9 +:201FE0000101090951557D4949557D4541417F00000020204454F4242454F4140404FC0488 +:202000000808081017303050901011111112121490888880FEA0A0A0A0A0202222221E00E4 +:2020200010102464A5242420202301084848870040407E8848502058860000849212F00054 +:20204000101010101B545050901011111112121490888880FEA0A0A0A0A0202222221E0044 +:2020600004040404FF040404040808101020408020101000FE8080808080808282827E00EF +:20208000010101013F212121213F212121213F2000000000F808080808F808080808F80827 +:2020A0000808087F494949497F494949497F4100007C44484850484844444468504040408E +:2020C00010103C2041BD1111FD1111111519110120202020FC24242424FC24242424FC045C +:2020E000004428102B48880818284989090A522490888880FEA0A0A0A0A0202222221E00E4 +:2021000000201010874444141427E4242424270440404040FC44444444FC44444444FC048E +:2021200002211117824243121222E22224242910101010BE2040BC848888BE888888A810D6 +:2021400000FF04047F4444485060407F40407F4000FE4040FC4444443C0404FC0404FC04ED +:202160000202FF04040F08182F48880F080808080000FE0000F01010F01010F01010502059 +:20218000020202FF04040F0A1211214081061860000000FE0000F01010204080402018062A +:2021A000020202FF040408081F28488808080F08000000FE00000000F80808080808F808A6 +:2021C0000808081017303051931519111111111140404040FE808000FC0404040404FC04EB +:2021E0000CF010543911FD11313955519111111120202020FC24242424FC24242424FC04BB +:20220000004720200F01E22C232121212A3224081CE04040FE504846F010207C04042810D7 +:20222000003F10101008080404020102040830C000F01010202020404080008040201806A8 +:20224000101020204544F80810102844FD45020440404040FC4444444484848404042810E9 +:20226000002310100000F710101010101128470000F840404040FC40404040404080FE0062 +:202280000241202F048444571424E42424282A11101010A828440290888880A0908888001C +:2022A000003F01010101FF01010101010101050200F800000000FE000000000000000000D8 +:2022C000003F0101FF01010502003F242424FF0000F80000FE0000000000F8484848FE0047 +:2022E00010101112FD10333A565392121312121240A01008F600C45454D45454D44454C881 +:202300000101013F212F21272427202F205F429C00F800FC04E008F810F000F880FC201C64 +:202320001F111F111F013F21212F242001484887F010F010F000F80848E82810008412F231 +:2023400011614742754741774141FF0008102040001CC4041CC404DC0404FE00201008042F +:202360000101020408102FC1013F011111214502000080402010E80600F80010080404008C +:202380000102040830CF003E223E223E22222A240080402018E60008484848484808281011 +:2023A000004021220D00E724272427242425508F40A01008F60084A4A4A4A484948800FE24 +:2023C00004040F10207FA1213F21213F0000FF000000E02040F80808F80808F80000FE0070 +:2023E000101011121D545352921312121312121240A01008F600C45454D45454D44454C868 +:2024000000201112854847141427E4242724250440A01008F600C45454D45454D4445488D0 +:2024200001412322048F54541724E42720202F000000F01020FC4444FC4444FC0000FE0003 +:202440000179494951516150484B4A6A52424242FC2424FC2424FC2020FE222AFA0A0206A4 +:20246000001F000201007F00000000000000020100F010204080FE828480808080808000D4 +:2024800020232222FB48484B884837102849820400F80808F80000F84040FE40A01008065D +:2024A00000FF0101017F4141494541494541414000FE000000FC0404442404442404140804 +:2024C0001010101F1020203F000000FF00000000000000FC000000F8080808C808085020CB +:2024E00010101010545454545454545D640000004040407E408080FC040404F404042810D5 +:2025000000003F011F11111F017F41415F48404010F80000F01010F000FC0424F414040CAE +:2025200002017F40803F010101FF0101010105020000FE0204F8000000FE00000000000013 +:20254000004720200300E027202023222A32230200FC4040F88888FE0000F8080808F80852 +:20256000007E0202221212020A1262220202140800FC0404442424041424C44404042810BD +:20258000007F01010101013F010101010101FF0000FC0000000000F8000020101000FE0041 +:2025A0002020202720F8232222222338E0470200141210FE1010D2525254D408EA1A264209 +:2025C0000808FF08003F010101FF0101010105022020FE2000F8000000FE00000000000044 +:2025E0000808FF10103F2161BF21213F21212522003E2224242824242222223428202020E8 +:20260000000178484848484B484878480000000000FC2020202020FE202020202020A0404C +:20262000002312130203F017141414151414284700F848F848F840FC44547494040C00FEFC +:202640000000794A4D484B4A4A4B7A4A0302020240A01008F600C45454D45454D44454C821 +:2026600010101010555454545556545C64000000005048842420508806F888888888F88834 +:202680001414274991112F61A1252525253E28200000DE121212D21212D2121AD4101010A9 +:2026A00001020C37C03E223E223E222601484887008060D80608484848480818008412F228 +:2026C0001412214908142241BE222222223E22012020207E428410101010282848448402FE +:2026E00000945222509E1212325292131210A142202824242020FC202050D0508888040200 +:202700000201FF08103F001F101F101F101010100000FE0010F808F010F010F01010502015 +:2027200022111100FF08112FC01F001F001F101F08081020FE2010E806F000F000F010F096 +:2027400001211214804041121423E222222223021008044440A0100806F808080808F80804 +:2027600002017F409F111F111F013F21212F24200000FE02F410F010F000F80848E8281047 +:20278000201000FC091010345994141010101010005048842420508806F888888888F88889 +:2027A00000F908502111FD25292121212020A14200FE2040FC042424242424445088040291 +:2027C00000F809532511FD24282320232020A34080F808FE1222FE40A25498345492502095 +:2027E000007C05242424243E02021AE24202150A0000FC84848488885050202050880402D1 +:20280000103E42A21418E21F1412101F007F000000F888AA927E00E0206000F8088828102B +:2028200004241615854447141424E52526282810444454546444FC44C4E4545444444444E1 +:20284000007F40880F10205F11111F020408106000FE0204E02040F80808F880A092827EDE +:20286000003F000000FF0404040408081020408000F8000000FE40404040404242423E00D0 +:202880001013101011FD11111111111DE040030000FE0000FC0404FC0404FC040000FE004E +:2028A00001013F01FF001F10101F050838CA0C080000F800FE00F01010F004885020180646 +:2028C000003F202127242427242427202448528100FE8000F01010F01010F080908884006A +:2028E00020272221F823202837E121222224A8433CC0442800FC8080FE00F8885020D8062F +:20290000202021FC435091FD11111CF0511610102020FC20FE00FC0404FC529488A4C280D6 +:20292000007F404F40405F444444484850407F4000FC04E40404F484848494947404FC04F3 +:20294000001F10101F003F2020212121020418E000F01010F000F80808080808C03008041D +:20296000007F404F484F405F5051515244487F4000FC04E424E404F4141414944424FC0468 +:20298000009053205790131232539011131DA1414040F840FE00F80808F8A4281048860090 +:2029A00000271414854545151525E424292A300000FE2040FC04FC04FC2420A82422A04073 +:2029C0001010212148FB102043F8400318E0430080FC04F808FE40A2345894345290502063 +:2029E000002310100007F111111111121214284700F8000000FC202020202424241C00FEB7 +:202A00000404FF04101E122222528C04081020404040FE4000F8888888A8908282827E0043 +:202A2000003F20272427242722242920204A4A9100FE80F808F808F850484480444212F04C +:202A400010103E42A214081020C001084848870000F88888A89084847C0000849212F0002C +:202A600000784B52546150484B486850414142444020FE0204F80000FE90909012120E0065 +:202A800000007F404040407F404040407F4000000000FC04040404E404040404FC04000079 +:202AA0001010202445FA102140FC40001CE04000404080FC0404040484444404040428102E +:202AC0001010107D1111FD1111515D5170504F80282420FC202424282810942C4400FE0048 +:202AE000007C4544447C13105C5050505CE00102083CE0202020FE2020505050888804029B +:202B000010103C2040BC1010FC1010101519120400FC848484FC848484FC84840404140875 +:202B2000001F10101F101010FF01012121213F0070800000F8808080FE0000080808F808E6 +:202B4000023F29252F2325293F00FF101F00000000F82848E8884828F800FE00F80850202B +:202B6000001F1010101F1010101F10102020408000F8080808F8080808F808080808281008 +:202B8000121111101B565252931010111112141808081020F8080808F8A0A02022221E00BF +:202BA0002017004442404F48484F42424448504000FC04448404E42424E4848484947408D2 +:202BC000101010FE107C11FE103834545091101000FC00000000FE202040488484FE82020F +:202BE000003F00000000FF0204040810207F200000F800000000FE000000402010F8080848 +:202C0000003E22223E007F4149494949141221C1003E2224242824242222223428202020CE +:202C200008080F10204884020000031C080000000000FC040404040424C404040404281010 +:202C4000007C444848504949454545695040404300F88888F800FC04242424245048840447 +:202C60000101020408103F0404040408081020C0000000402010F848404040404242423E31 +:202C8000002310100007F010111217121028470000F8000000FC40801008FC040000FE0055 +:202CA0000404FF0421214589F12043FA021AE7404040FE40F808F808F800FC949494FE00FC +:202CC00000FE2828FEAAAAAAAEC282FE8282FE8200007C000000FE101020204442FE420096 +:202CE0001F101F101F007F429F04091F017F0101F010F010F000FE02F40000F000FC000079 +:202D000020107C00452AFE007C44447C45447C44404080FC04048444441424448404281085 +:202D2000003F0808081017204001FF010101050200F010203C04C4548800FE0000000000AD +:202D4000007F4040404F48484848484840407F0000FC808080F888888888A8908080FE006C +:202D60000003FA2222427A4ACA4A4A4A7A4A030000FE101010FE929292929A941010FE00DD +:202D800002023F040408116101FF0109112145020000E02022221E0000FE0020100804004F +:202DA00008087F0808FF000808FF182C2A4988084048444440FE40444444282A122A46826F +:202DC0000808087F0808FF00003E2222223E2200404844444040FE404444282A122A46829D +:202DE00002017F408101111111210202040830C00000FE0204000808102080804020180679 +:202E000002017F42813F000804FF01017F0101010000FE0204F8002040FE0000FC00000049 +:202E200008087F08FF1010FF20487F080FF8080820282420FE20242424282810122A46825D +:202E400000FF01013F21213F2121FF202020202000FE0000F80808F80808FE080808281074 +:202E6000020204FF080810305790101010101F10000000FE00404040FC4040404040FE00AD +:202E8000000079494949494949494979490101012040FC040404FC040404FC040404FC0434 +:202EA00021252729F723252930E322222220A1460828BE48BE18AA4600F8084848B008044C +:202EC00010FE20487E080EF94A1F10101F10101F0CF08080FE88880808F81010F01010F0D6 +:202EE00008283E487E142546811F101111020C3010507C90FE28488A06F0101010C030088D +:202F0000007C4445555555555555551129264284201010FE001010107C1010101010FE00FB +:202F2000007848494979494949794949494A4A9C201010FE001010107C1010101010FE002F +:202F400008FF08FF103E422418E00808FF08102020FE20FE8098E084847C2020FE2020201A +:202F6000002F10170407F4171013121312132847A0FEA0FCA4FCA4FC00F808F808F800FE99 +:202F8000202027A87322FB227368A921212121219090FE90FC94FC94FC00F808F808F8087D +:202FA00004241404FF0004222F21212F21213F0040485040FE004088E80808E80808F808BD +:202FC00008FF082312138047541720EF21222C2020FE20F808F800BCA4BC40FE504846401C +:202FE0000101FF013F2123250930C601000E01000000FE00F808884820180680400080408C +:20300000001F10101F10101F0101FF010101010100F01010F01010F00000FE0000000000FF +:2030200003422223008744541720EF2122243800F80808F800BCA4A4BC40FE6050484640A6 +:20304000003F120904031CE11F11111F11017F2000F010204080700EF01010F00008FC049B +:20306000007C4444447D11115D5053505CE10200F88888F800DC5454DC20FE70A8242220DE +:203080000302F293909794949790FF9102041800F80808F800BCA4A4BC40FE605048464006 +:2030A000002213140007F01013121213122847004040F84040FC0000F80808F80800FE00FB +:2030C00001021F10101F10101F020203FE0202010000F01010F01010F00000FC000404FC36 +:2030E00010101010545851901010102824444380202020202020FC20202020202020FE00E6 +:2031000010101014585151911110132824414280F88888F800DC5454DC20FE70A824222061 +:2031200001017F013F01FF001F10111111020C700000FC00F800FE00F01010101060180450 +:2031400020272221F020212630E320202720A04000F80810A040B04E40F84040FC404040B2 +:20316000007F414149494949494949141221408004040424242424242424242404049488D4 +:2031800000271211804041161023E0202720200000F80810A040B04E40F84040FC404040D2 +:2031A000007C4445545454545754541028254182141210FE10909292F29494888A1A2642F5 +:2031C00008080F142447040407040108484887000000FC0000F00000F80000849212F00022 +:2031E0002221202724FD24242720233AE3420302081000FC4454E444FC00F808F808F8083E +:20320000111010131A5652529310111111111111048800FE22AA7222FE00FC04FC04FC0465 +:2032200008043F2129253F001F10101F10101F102040F8082848F800F01010F01010F01000 +:20324000007C4455555555555554541028244480884850FC24AC7424FC00F888F888F888E8 +:2032600010101010FE1010121C30D0101010502080808080808080808080808484847C009A +:203280000000F790919294939293F29302000F004040FCE0504846F808F808F80800FE006A +:2032A00000201710814244131223E22322202F004040FCE0504846F808F808F80800FE00CA +:2032C00008080808FE08181C2A2A48880808080880808080808080808080808484847C00C8 +:2032E000101010FE2028487E08080EF84808080840404040404040404040404242423E0058 +:2033000020233A22427AA222FA2222202931220402E2222AAAAAAAAAAAAAAA8242220A04E6 +:20332000201700404F49494F49494F494141414000FC0404E42424E42424E4240404140831 +:2033400000007B4848784B4878484848794A0400083CC0004020FC081020408000807E00EA +:2033600010111111FD11313B555191111112121400DC5454545454FE5454545454D4244C99 +:2033800010101312FD10303956509010101010104020FE8A0480FE40407C40407E404040C8 +:2033A000010179494A4A4C484848784800000000000000FE808080F8808080FC80808080DF +:2033C00008080F121222438202020302020202020000FE000000F8000000FC0000000000C0 +:2033E000111111155A5254901010102824444080000000FE808080F8808080FC8080808083 +:20340000012111110202F4101010101418100000000000FE808080F8808080FC8080808002 +:2034200020202721F827242D34E525252524A4448040FC10A0FC44F444F41414F4041408EC +:2034400002017F0804031CE01F02043F242424200000FC204080700EF00000F88888A810E5 +:2034600002017F408000033E0203FE02020201000000FE020420F00000FC00040404FC00A7 +:2034800002017F4890280F1424470404070404040000FE221408F80000F00000F8000000E5 +:2034A00008080F101330375093121212121011164040FC40F840FE00F808484848A010087F +:2034C000017F449F043F04FF08112FC10911250200FE42F440F840FE2010E80620100800F9 +:2034E00001017A4F4A7B4B4A7A4A4A4A7A4C040800F808FE8824FE00FC00FC00FC84FC84DD +:20350000081C7010101C7011111DF11111100F004040407C404040F8080808FA0A02FE00EA +:20352000080F103F65A83F20272027202744478400F020FE0884FE00F800F800F808F8086D +:20354000101094545810FC303955559111111111202020203E202020FC0404040404FC04E9 +:2035600000201010804048081312E222222223024040407E40404040FC0404040404FC041B +:203580000202037E03FE01031CE0003F242424FF4020F800FC106082621E00F8484848FE67 +:2035A000202021FD415191FD11111DF151121214081CE0000000FE10101010101010101042 +:2035C000202322FA435292FE12121FF25214141800FC0404FC4848FC4848FEA4A890C8865C +:2035E0000121213F1010FE20487E080EF849090A000808F8000CF08080FE88888808080829 +:20360000003F20203F22222F22223F242445468400FC0404FC2020F82020FE8850300E0013 +:2036200008FF0800FE10117C54546C447C457D4620FE205048FE90FC90FC90FE80542A2A62 +:2036400010101010FD10303954509010101013105048405CE0405EE044483022528A0602D9 +:2036600001010101010101013F20202020203F20000000FE00000000F80808080808F808E6 +:203680001010101E101011107E424242427E420120282424203EE02424282810324A8602DA +:2036A0001008087E000444442529290FF1410101202020203E202020FC0404040404FC04F8 +:2036C00001211711814149091117E222232223000808FE08F808F80808FE50880400FC0004 +:2036E000101023224CF8132040F941011AE244084020FE020400FE2020203C20A0603E00CF +:2037000010111010FB103139555191101310101020FC8850FE00FC04FC04FC20FE202020FD +:2037200002013F0804FF001F101F101F01FF01010000F82040FE00F010F010F000FE000079 +:2037400010087F2214FF007F417F417F08FF08080004040810A20204081022020488106087 +:20376000002711108F4043121322E3202F20200040FC10A0FE00F808F808F840FE40404056 +:2037800001F9090909794147417909090909512100080810204000FE4020201008448200E7 +:2037A00011093F204F080F003F013F017F0105021020FC04E820E0F00000F800FC00000027 +:2037C000004F2121018F4858182FE12121212A0440444448485040FE50504848444462402F +:2037E00010101010FD103039555490101010111610101010FE101010109090502050880697 +:20380000000000007F00101008040201020418E080808080FC808080808080008040300E02 +:203820001010107C545454575454545C101010108084848890A080FEA090908884A2C08085 +:20384000007C44545454545554545410282444808084848890A080FEA0A0909088A4C2805B +:203860000808081013303051911010101010111610101010FE101010109090502050880668 +:20388000003C2424243C2427243C2424244454888084848890A080FEA090908884A2C080A1 +:2038A000003F2027A16F202362A32223204F408080FE40FC10FE00F808F808F840FE404038 +:2038C000007D44484B504949454545685340404020FC8850FE00FC04FC04FC20FE202020FC +:2038E00010131010FC1111121C31D1111111512100FC84848404140800FC04040404FC04DE +:20390000000378484849497A4C4949497949010100FC84848404140800FC04040404FC04F1 +:2039200010101010FC1310141830D0101011522090888880BCC0808888906044A4140C0431 +:2039400000271010804141121423E2222222230200FC84848404140800FC04040404FC04B4 +:203960000808087E0808FE0828282E2828584F800004844428281010282844840000FE0054 +:20398000007D444444447D444444447C0048448400FC4444449408FC848484FC0088444489 +:2039A000007F447F0101013F203F203F01FF010100FC44FC00FC00F808F808F800FE000095 +:2039C000040444241414040C142444080810204040404448504060504844404242423E0027 +:2039E000083E223E20419F01FF011F013F01FF01407EA8106E00F010FE10F000F800FE00E8 +:203A0000007F040408081020409F101010101F1000F808080808502000F808080808F808F1 +:203A2000004027240404E7242424282A3224508F4020FE008888FE8888F800A4525200FE5F +:203A400010101111FD1111151931D11111125224081CE0000000FE10101010101010101099 +:203A600008087E080E78082912001F1010101F100CF08080FE8888080800F0101010F0102F +:203A80001010FB1019F01152251F11111F017F208080F0909094540C04F01010F008FC045A +:203AA000222127FA244F5097FC171CF7541414150808C8109ED46494949494888894A4C279 +:203AC00002023F0202FF01020F18284F88080F080008D02040FE0000F01010F01010F01002 +:203AE00020203920407BA020F8212220283020002022FA2428FE2040FC8484FC8484FC8471 +:203B00000808FF09003F22223F222223204A49912020FE2080FC2020FC2020E0004824245A +:203B2000002010170002F1101010111214284700804040FC101020A040A010080800FE009B +:203B4000024222220F824252132EE22222222A05081C6040C0407EC84848484848488808B6 +:203B60000000FC1011127C101110101CE14000032020508804122040881020448810608017 +:203B80002222FF223E223E2222FF405462407E0008482828084828280E7808080808080835 +:203BA00001017F011F101F101F101F10FF0810200000FC00F010F010F010F010FE2010085E +:203BC00000FE2828FEAAAAFE1010FE10101EF04000FC404040784848A8988888AACA8A06A3 +:203BE0000000FC1010203C6465A525253D252101202020203E202020FC0404040404FC04E3 +:203C000000F823405188FB2821FA202138E043002020FE20FC40FE8834E220FC70AC2220E6 +:203C200001010101013F202121212222040830C00000FC0000F8080808080808C03008045D +:203C400010101E20207C9310FE10101214181000202020202020FE2020202020202020207D +:203C60000808081010333252921212121011121440407E4040F8084848484848A0100804A4 +:203C800010101013FA1430385450901111121418404040FC44484040A0A0A02022221E00AD +:203CA00000001F109051521430539010232040878040FE40A0100826C01020C00810E000DD +:203CC000004020210204E02023202028332000074040A01008264080102040881020C00072 +:203CE0003F017F419D011D003F202F203F244486F800FE0274007000FC00F800FC48300EDC +:203D000010131212FE1212171A32D2121214542800FC0000F80000FCA0A4A8909088A4C267 +:203D200020203B404179A121F9212129372001022020FE20FC04FC04FC04FC04FE880402A4 +:203D4000007C444B485049494444446B50404040404040FE80A020FC202020FE202020200F +:203D60000808FF081F007D050931C5023F0024422020FE20C044885020180600F8008844A9 +:203D800010101112F813101837D01013101051208080F01020FC4444FE4444FC4440408088 +:203DA0000101794A4C7B48487B48484B784801000000F01020F84848FE4848F8484040805A +:203DC000080813204808113151911111111117100000FE20202020203C2020202020FE0049 +:203DE00000442912284B88081F28488B080851208080F01020FC4444FE4444FC444040803C +:203E000008081F2040BF01017F01013F010105020000E02040F80808FE0808F80800000033 +:203E2000101013101854515191111111111117100000FE20202020203C2020202020FE00AC +:203E40000808FF087F497F2A4988007F011111FF2020BE44A4242810284600FC00F800FEC6 +:203E600010111010FC1310141931D2141010572000FC081022B2B4A8282422A04000FE0077 +:203E8000007F010101011111111111111111FF0000FC0000000000F8000000000000FE0026 +:203EA0000000FF080808484E484848484FF000012020203E444444A4282810102848840281 +:203EC0001010107C545555555555555D1010101120203E2020FC04242424242450488404B4 +:203EE00000001F10905F50103252921222225F808040FE0000FC4040407C40404040FE0005 +:203F00002212147F080808FF0808141221418000003E2224242824A42222223428202020F1 +:203F2000002013100000F11111111115191107000000FE20202020203C2020202020FE004B +:203F40000808FF080A01017F0000030C304887002020FE20200000F830C000000000FE004D +:203F600010101013FC1030395454901010101116202020FE202020FC84884850205088069E +:203F80000101017F0101013F10080402010618E0000000FC000000F01020408000C0300E66 +:203FA0000000784B484848494848784800000106202020FE202020FC84884850205088066A +:203FC000212121FBAAACA8A8FBA0202939EA4408000000DE92929292F29292525E2020005E +:203FE0002020207E48880808FF0814142222428000007C4444444444444444447C4400002E +:20400000003C2425243C2425243C24242444558E202020FE202020FC848848502050880623 +:20402000013D2525253D2424253D252525455589000438C00202FE00FC0404FC0404FC0454 +:2040400000201010804047101020E02020202000404040404040FE404040404040404040BB +:20406000020101007F000000000102041824430000000000F8102040800000000000FE0051 +:204080001010212545F9112141FD40001CE142040000FC0404040404FC0400908804020259 +:2040A00000FF24243C24243C24242EF4440404050000FC8484848484FC840048448482029A +:2040C00001017F011F10101F101F101F1010FF000000FC00F01010F010F010F01010FE0069 +:2040E00010101310FC11313955559111111117102020FE2020FC04FC04FC04FC0404FE00F1 +:2041000000FC2320203D454565950909112147802020FE2020FC04FC04FC04FC0404FE00F4 +:2041200010101010FD1010141930D0101011522440404040F848484848C848A8AA0A0602C2 +:2041400008080F10103332539213121312121F104040FC4040F808F808F808F80808FE0049 +:2041600010171020216267A02020272020202F2000FE40801008FC444040FC404040FE00F8 +:204180001010101111FD11111111111DE14107002020202020203C20202020202020FE005B +:2041A00011111111FD1110141931D11111115121000438C00202FE00FC0404FC0404FC04C3 +:2041C0000101010111111111111111111111FF00000000000000F800000000000000FE003C +:2041E000007C4445457D11115D5151515DE107002020202020203C20202020202020FE0067 +:20420000001F1010101010101F1000080810204000F0101010101010F010002010080404E0 +:204220002020233C20201F001F10101F10101F10007080080808F800F01010F01010F010B3 +:20424000101023224AFA122342FA42021AE24302083CE020202020FE201010120A8A06022F +:20426000010101FF0101013F0001084848488700000000FE000000F8000088841212F0007C +:2042800010FB1019F01152241F013F017F01050280F0909094540CE40000F800FC00000030 +:2042A00024222220FF21212937E121212222A448405E9212D4141814F212121A94505010B8 +:2042C000007F020408103F0001013F010101FF0000FC00002010F8080000F8000000FE009D +:2042E00000FE10202845FE1210107C10101EF14240404080FE08888888505020508804028A +:204300007F447F017F011F101F101F101F10FF00FC44FC00FC00F010F010F010F010FE00E9 +:204320001010117D555555555555545C101112140000FC0404040404FC04009088040202AA +:2043400010101011545457545455545C64000000202020FC2020FE0808FE0888480828104C +:204360000424243F4404FF04043F242426250404040404A42424E42424A4A4A484041408D5 +:20438000203E4808FF1422401F10101F10101F10007C444444447C00F01010F01010F01025 +:2043A000081CF11111FD1230395454901010111220202020FC202020FE2050508888040223 +:2043C000081CF01111FF15313955559111111111A09090FE1010FE1010FE101010FE000082 +:2043E000003F20203F20202724242424244146987CC04040FE4040FC04444444B4080402FD +:2044000002040F126904030C71111122040830C00000F81020C00000001010A04020180622 +:2044200000001F10905750103F50901F222141808040FE4040FC4040FE1010FE101050205E +:2044400001211711814047141823E222222220005050FC505000FE4244F8484848584040EB +:2044600000201011824740101322E222222223024040801008FC0400F80808080808F80808 +:2044800002017F4890007F04081F01013F0101FF0000FE221400FC0020F01000F80000FE90 +:2044A000010101013F21212121213F210101010100000000F80808080808F8080000000090 +:2044C00001013F2121213F2101013F242424FF000000F8080808F8080000F8484848FE004E +:2044E00001013F2121213F2101010848484887000000F8080808F808000088841212F0001F +:2045000010103C2041BD1111FD1111101418100020202020FC24242424FC242020202020C8 +:204520000201FF013F21213F0102040C34C506040000FE00F80808F800804428100806009A +:20454000101020214BFC102043FC400018E140008080F80810A040A01806C020108060103D +:20456000081CF01011FD1131395555901010101020202020FC24242424FC24202020202048 +:20458000003C2424253D2525253D25242444548820202020FC24242424FC24202020202030 +:2045A00000003F01FF011F111F111F013F01FF0010F80000FE00F010F010F000F800FE0010 +:2045C0000808081017343454941417141010101040404040FC4444444444FC44404040403D +:2045E00001010204081028C8080808141222418200008040201028262020205050880402BC +:2046000002041F10121111FF10121111202040800000F010101010FE1010101010105020F0 +:20462000003F21212F21213F202724242740408000F80808E80808F808C84848C808281033 +:20464000101010101054525290101010202040800484848484A49494848484848484040452 +:2046600001211111814145151921E12121222204042424242424B46C24242424242404047D +:20468000002010110204F31010101110141813008080F8081020FC040404FC040404FC0410 +:2046A00001F9090D0B79414741790B0D09095121003C0444843C20E0203C844404042810E0 +:2046C000202020FC415191FD11111DF15111111120202020FC24242424FC24242424FC0412 +:2046E000003C2424253C2424243C24242444548808080808FE080808884848080808281003 +:20470000001F000F001F007F41811F111111110100F010F010F000FE0204F0101050200033 +:20472000007C4444447C00000F080808101020C000F8888888F80000C04040404042423E84 +:2047400020203E428408FE02027E020202FF0200101010FE929490FCA4A4A8A89028448290 +:2047600002017F4081013F2121213F2121213F200000FE020400F8080808F8080808F8082E +:20478000001F10101F1010202F488F080F007F0000F80808F8402010E826E020E000FC0085 +:2047A00007F2135253525778080F39CA08092E10E05CC454C868D4643CC04468D0484640BC +:2047C0000001FD1111127C131010101DE1420000202020FC202020FE70A8A8242422202084 +:2047E00010111111FD12303B5454901111121010202020FC202020FE70A8A824242220204C +:204800001011117D555654577C5010151DE64000202020FC202020FE70A8A824242220203B +:204820000111111F214101FF0305091121C10101000000F8000000FE8040201008060000DA +:204840000088532050971010315395111111A1414044F44850FE4080F80808F80808F8084A +:20486000004023200007E02021232521293121014044F44850FE4080F80808F80808F808CA +:20488000002111110102F0131010101519120000202020FC202020FE70A8A824242220203B +:2048A000002310100106F011161011161028470000FC40804468B02868A42420A040FE0073 +:2048C000101010103E28498A080808080808080840404040FE9010101010101010105020A1 +:2048E00010101011555951911111102824454080202020FC24242424FC24202824FE82006C +:2049000002023F02FF010F38CF08080F004844840008D020FE00F010F01010F00088444407 +:2049200010101013FC1010141930D01010105320402000FE20202020FC2020202020FE00D0 +:204940000007F49794F59495F5959497F6960A1200FC04FC00FC20FC24FC20FE2AFA0A0630 +:204960000007F497949594959595F49706060A1200FC04FC00FC20FC24FC20FE2AFA0A06F0 +:204980000201007F010101013F0101010101FF00000000FC00000000F80000000000FE005C +:2049A00008FF08023F0202FF030C3FC80F080F0820FE2008D02040FE0000F010F010F010EC +:2049C00010101013FC1030385554901010101310402000FE20202020FC2020202020FE001C +:2049E000007C4444447C44447C4444444EF0010220202020FC24242424242444448428104A +:204A00001010107D545454547D5010141CE44300402000FE20202020FC2020202020FE00ED +:204A2000007C445455555654545454102825448040202000FE0204000000000000FE00006F +:204A400010103D2040BC1110FC101011151A10002020FC20FC20FE4848FE88482808281014 +:204A600010103F4885007D111111111DE242040840407E900800F0101090501212120E0032 +:204A800008080817103030509710101010101F10804000FC40404040FC4040404040FE001B +:204AA00000201017804040101320E02020202F00804000FC40404040FC4040404040FE0007 +:204AC000201312FA0A121338549410111112141800FC04040404FC909090901212120E004C +:204AE00000F8084B4848487C05041CE444042B10402000FE20202020FC2020202020FE0013 +:204B000010101111FD1111151931D11111125224081CF050505050505048484844444200C4 +:204B200000001F1212121212121212222242428010F8202020202020201010100808040250 +:204B400010101111FD1111151930D010101053202020FC2424FC2424FC20241832CA0602FF +:204B60000101013F0202FF04080F000006010000000000F80000FE0000F010204080402098 +:204B80000000FC1110203D6464A524243C242000202020FC2040FE4080FC048850201010D4 +:204BA000202020FD405093FC10111CF050101010202020FC2040FE4080FC0488502010103A +:204BC00020272427FC24232831E721212F21A24400BCA4BC20A49C0010FC1010FE10080486 +:204BE000007C4455545554575455541029264480885000FE50FC54FE54FC50D854525050FA +:204C0000203E48880F101F00FF063B0419620C73407E9000E020C040FE0008B0C0A09806E8 +:204C200010101011FD1131395555911111121214201010FE001010107C1010101010FE00EE +:204C40000100003F202020202F20202020405F80008080FC00808080FC8080808080FE00D0 +:204C600008482B081828C90A01FF050C34C506042020FE202020FC0000FE008850300E00DC +:204C8000080808482B2808081829C8080808080B40404040FE88888888089050205088041B +:204CA00010111010FD1011151931D1101110532020FC8850FE00FC24FC24FC20FC20FE0059 +:204CC0000808084828280B182848880808080908202020202020FE20202020202020FC0046 +:204CE00008080848282F08081828C80809090A0C4048444440FE404040A0A09010080402B9 +:204D000010101011FD1335395555911111111111A09090FE1010FE1010FE101010FE00001C +:204D200010103C2041BE1010FC10101014181000504880FE9090FC9090FC909090FE808074 +:204D4000002013120203F21213121213122847002040FC0404FC0000FE0202FE0200FE00DA +:204D6000087F087E08FF101E22469F1011020C7020207E44A42810284482F01010C0300877 +:204D8000007C4448444455494245013F0101FF0040404040A0A01008040200F80000FE00C9 +:204DA0002027204251F2242840F7400231C2040800BC84940894A44000BCA4A42890A84645 +:204DC000002017100302F31013101017181001008040FC00F808F800F81020FC40404080F9 +:204DE0000141212302161B122223E22222232202402020FE2020FC2020FC202020FE0000E2 +:204E000010111111FD1110141931D1111212542800FC040404FC2020203C2020A0603E0033 +:204E200010101111FD11151830D0121212125320202024242424FC24202022222222FE0282 +:204E4000010101011F101F101F1101FF0101010100FC0000F010F010F01000FE00000000C2 +:204E6000010101011F101F101F01FF050931C1010000FC00F808F808F800FE402018060040 +:204E80000003F820212220FA21222038E142000000FE4080442468B030A868A42220A04098 +:204EA0000808FF08092121213F01014141417F002020FE2020080808F80800040404FC044A +:204EC00000FE2828FEAAAAAAAEC282FE8282FE822020207C44840444241414040404281098 +:204EE00000037848494A484A494A78480102000000FE4080442468B030A868A42220A04030 +:204F000008047F013F02FF040F182FC80F080F082040FC00F800FE00F010F010F010F01023 +:204F200010101010555A50911010102824444080404080FC040404048444440404042810C5 +:204F400000201017844444141724E020202F2400404040FC44444444FC44404844FE020064 +:204F6000080404FF101020244478081014227E02202040FE2020404888F010202844FC04DA +:204F80004020091224E020232C001F1010101F108080FC044840A0180600F0101010F0103F +:204FA0000141210A14E021261F10111111020C700000FC4448A0100CF01010101060180479 +:204FC0004020091224E020232C04FF081C030C708080FC044840A0180600FE2040807008A1 +:204FE00001201017814142121427E12222242700088890FE08081094A438081010A4BC84EE +:2050000001211214824141101724E427242427042424489048242400FC4444FC4444FC04C3 +:2050200000FC04081011161830D010101010512240404080FE0888888850502050880402EA +:2050400008282E282EF002041F01063F011125428088F084847C0020C08010F808201008A4 +:20506000080B081010303057901010101010111000F80810204040FE40404040404040804F +:20508000101194545810FC33385454901010101000FC0408102020FE202020202020A040CA +:2050A00000201714804341101720E023202020008040FC8440F810A0FC4040F8404040405B +:2050C000007F0000000101FF010101010101050200F81020408000FE00000000000000005D +:2050E0000102041F1010101F10101F1010101F10000000F0101010F01010F0101010F0104D +:2051000000201710834047101322E222222021064040FC40F840FE00F808484848A010080A +:2051200002017F40801F000001FF0101010105020000FE0204E0408000FE00000000000061 +:205140003F203E20FF227F017F401F007F1125420830C418620C7000FC04F000FC10080422 +:2051600010101312FC11303857549111121410104020FE0200FC0000FE2028242222A040F8 +:2051800000784B4A4C791010535C51515AE400004020FE0204F80000FE2028242222A040A4 +:2051A0000201017F40801F00007F011111214502000000FE0204F00000FC00100804040073 +:2051C0001010232248F9102043F841011AE440004020FE0200FC0000FE2028242222A04054 +:2051E000100804001F1010101F1001084848870010204000F0101010F01000849212F0004D +:205200001111212149F9112141FA42021CE44811101010101010101010A868284444840208 +:2052200020203E428408FE02027E020202FE0200007C444848504848444444685040404028 +:205240000101013F0101FF010111111111294780000000F80000FE000000F8000000FE00E9 +:2052600001017F013F02FF040837C11F01020C300000FC00F800FE4020D806F000C03008F2 +:2052800020202720FB20272932E520232020A1464040FC40F880FC1008F640F840A010082D +:2052A000081DF11111FD1131395555911111171000F8080808F8080808F808080808FE0084 +:2052C000001F101010101F01011111112925438000F010101010F0000000F8000000FE00F4 +:2052E00002017F08080814220101FF01010101010000FC20202050880000FE0000000000A6 +:2053000020101001FE20203C25242724244454898080FE008080FCA02020FE2050508806D3 +:20532000201111F909111139559511111111171000F8080808F8080808F808080808FE0043 +:20534000002111110101F111111111151911070000F8080808F8080808F808080808FE0057 +:20536000007D454949514949454545695141474000F8080808F8080808F808080808FE006F +:205380001011212149F9112141F9410119E1470000F8080808F8080808F808080808FE0043 +:2053A00010103C2040BC1010FD11111115191101202020203E202020FC0404040404FC04B7 +:2053C000203E48BF24223F02FF09122FC21F0913407E90F88848F800FE20508826F0482019 +:2053E0000002F29292979192979AF392030404089094D892D20EF010FC44FC44FC44540888 +:2054000000FE2928FEAAABAAAEC283FE8282FE824020FE00888854220020FE202020202029 +:205420001F101F101F00FF223E223E222FF24203F010F010F000FE00F8889050205088065C +:20544000007F44447F00047C04047C0404FC040400FC4444FC00407C40407C40407E404000 +:205460000804FF043F283027203F00FF080404002040FE40F84838C808F820FE2020A040D5 +:20548000014F20270405E6272427202F2120508F10FEA0FCA41C04FC04FC10FE10B000FE6F +:2054A000010179494A4A4C784848484878480000000000FE808080F8808080FC80808080FE +:2054C000020202FF040404080F10102040803F00000000FE00000000F88080808080FE00F1 +:2054E0000808081017303151911212141418131080808080FE800000FC2020202020FE008B +:2055000010101010FD1132385450901010101010808080FE4040407C4040407E4040404057 +:205520001212122F226262AF282828282F282020101010A03E4424A4A4A8A890A828448206 +:2055400009090911123234509010101010101010000000FE808080F8808080FC8080808065 +:20556000011111111129254581013F010101FF0000101010102824440000F8000000FE00CA +:2055800001003F202424242A31202F204040BF000080FE80909090A8C480F8808080FE0026 +:2055A0000000000000000000000000000000000000000000000000000000000000000000EB +:2055C0000000000000000000000000000000000000000000000000000000000000000000CB +:2055E0000000000000000000000000000000000000000000000000000000000000000000AB +:2056000000000000000000000000000000000000000000000000000000000000000000008A +:2056200000000000000000000000000000000000000000000000000000000000000000006A +:20564000003F00000000FF01010101010101050200F800000000FE00000000000000000008 +:2056600000FF080808080808080808101020408000FE202020202020202020202020202025 +:205680000000FF080808080808080810102040800000FE40404040404040404444443C00C5 +:2056A00000FF010121212121213F00000000000000FE000000FC000000FC040404042810C7 +:2056C0000808080808FF08080808080808080F081010101010FE1010101010101010F0107E +:2056E000101111111111FF111111111111212040101010101010FE10101010101010101071 +:20570000007F00010103050931C101010100FF0000FC800000402010080400000000FE000D +:20572000007F00001F10101F10101F100000FF0000FC0000F01010F01010F0100000FE0024 +:20574000003F0000007D0509091121418502FF0000F0204080048850201008060000FE0095 +:2057600000FF001F10101F007F48445F4141414000FE00F01010F000FC2444F404041408E5 +:205780007F00030D71011010FE222264140834C2FC806018040000FC040810FE1010502092 +:2057A000007F013D25253D017F013D25253D01FF00FC007848487800FC007848487800FE6A +:2057C0000101010101010101010101010101010100000000000000000000000000000000B9 +:2057E000003F21213F21213F017F41415F48404000F80808F80808F800FC0424E4241408EF +:2058000001010101010101010102020404081020000000000000000000000000000000003B +:20582000101010101010131C1010101010100F000000000830C00000000000040404FC006A +:2058400000033E0202020203FE0202020202010020F00000000000FC000000040404FC00DF +:2058600000003F01010101FF01020204081020C010F80000000000FE008080402010080661 +:20588000001806010618600008040201020C30C00810608060180420204080008040300EEC +:2058A000003F20203F20202724242424244443807C800000FE0000F0101050240404FC0086 +:2058C00000003F2020203F20202020202128302010F880808080FE8080404022128A4642E5 +:2058E0000202047F404844424142444840407F40000000FC04244484048444240404FC04E1 +:2059000001222427212227202724272427444484000848880848C808C848C848CA4A4AC68A +:2059200021202023FC252525252525252544438010A000FC80F808F808F808FA0A02FE0088 +:2059400040407D807C446554FE44A494FE0529122010FE204884FE02A8A8A8A8AA2A2600E5 +:2059600004087F447F013F01FF08043F01FF01010000FC44FC00F800FE2040F800FE0000C4 +:20598000241424087008FF087E007E427E241EE090A094847C1010FE10FC4448281028C6A6 +:2059A0000000000000040201000000000000000000000000000000008040400000000000E0 +:2059C000003F000001794949494979010502FF0000F02040803C0444281028440000FE0074 +:2059E0007F10102F488F084F484F407C04FC2444F8081EE22AE420E424E4047C407C444412 +:205A000000001010101738D01010101010100F0000000030D0101010105020020202FE0014 +:205A2000080808080F0808087F41414141417F4120202020A02020202020202222221E0037 +:205A4000003F000000FF0808080808101020408000F8000000FE20202020202020202020AA +:205A60000909F90909013F010101FF010101010120203E202000F8000000FE00000000000E +:205A800001013F01017F40800F0000FF010105020000F80000FE0204E04080FE00000000D3 +:205AA00001017F011109FF003F20272427203F200000FC001020FE00F808C848C808F808F1 +:205AC00010111111FD1111117D454545457D450100DC444444DC0000DC1414D4080814225D +:205AE000003F202020202020202121224244881000FE0000808080808040402020100806A9 +:205B0000003F2020202F2122242720204F40800000FE008080FC004040FC4040FE40404026 +:205B2000003F22222F22223F202724244744840700FE1010FC1010FE00F80808F80808F84B +:205B4000003F20203F2126382F282F284F48800000FEA090FE40300EF888F888F888808019 +:205B6000003F2028252F22222A2A2F224244840800FE009010BE22449090901028284482B7 +:205B8000003F29293F29292F292F29295F408A1100FE000CB020203E28282828A848880878 +:205BA0003F203F21263827202F2A2B2A4B4A8F08FC90FC40300CF080F828E828E828F808F3 +:205BC0003F22242D36242424242027244440831CFE50FE90FC90FC90FE00FC4444B00C028B +:205BE000007F4040404040404040404040407F0000FC000000000000000000000000FE00AD +:205C0000007F4040404744444444474440407F0000FC000000F010101010F0100000FE003A +:205C2000007F44445F48525F42435E4A42427F0000FC2020A07828A828A82A2A4680FE00C9 +:205C4000007F404F484F407F404F4849424C7F0000FC80F888F880FE00F888681008FE0043 +:205C6000007F404F484F484F59694F4949407F0000FC80F808F800FC2424FC242C00FE0084 +:205C8000007D4848485D5455555D4949497E000320FE20FC20FE00FC0424242424508804D7 +:205CA00008087F080808FF0008087F08080FF040202020202030A8242220202020202020C2 +:205CC00001010101013F20203F20203F20203F200000FE0000F80808888888880808F808AD +:205CE000000000000000000000000000000000000404044444444444444444040404140850 +:205D000000010121110A0A04040A0A112140800004040424242424242424242404041408B9 +:205D20002020203F549414242448881020408502040404A4A4A4A4A4A4A4A4A484841408C5 +:205D4000007F02040C1221C0007F0808080FF04004040424242424A42424242404041408F5 +:205D60000808FF142241BE00FF10207F01010A04040484242424A424A4242424040414082D +:205D8000084949497F10103F41A11214081020C004040424242424242424242404041408CE +:205DA000084949497F007F01013F2020232C3000040404242424242424242424040414088E +:205DC0000808FF08087F49497F081C2A4988080804048424242424242424242404041408F1 +:205DE00008087F142241FF017949494979010502040484242424E424242424240404140814 +:205E00000809494A881422498849498A142241800404042424242424242424240404148848 +:205E200008047F40203B2A2A2A5A4B8A12122342040484A424A4A4A4A4A4A4240484140812 +:205E40001111FF11007B4A4A7B4A4A7B4A4AAB140202E20A0ACA4A4ACA4A4ACA42424A8452 +:205E600000FF0A7F4A4A7F007F00FF042444940802E202C25252D212D212F21282422A04F7 +:205E8000007F40514A5F444455555F444448499202F2024A4A7A9A2A0A4A4A4AA2A22A04EB +:205EA00012113F2262BF22223F22223F20544A8A0202C20212D21212D21212D202824A4445 +:205EC000117F15123F64BF243F243F207F110E7102C20202D21292129212D21282020A84CA +:205EE000083F203F203F007F447F447F00FF112102828282929212D252D252D202E20A049D +:205F0000007F404040404040404040404040404000FC04040404040404040404040414083A +:205F2000007F4048445F41405F4444444740404000FC042444F40484F4040404E40414081C +:205F4000080808101030305090101010101010100000000000000000000000000000000059 +:205F600008080B101030305090101010101010100000FE2020202020202020202020A040F8 +:205F80000809091111313151911111111112121400F01010101010101010101212120E0041 +:205FA0000808081013303050901010101111121440404040FC444444448484840404281016 +:205FC00008080B101030305190101010101710100000FC00000000F80000000000FE0000DC +:205FE00008080911123431509010101112121110808000FE0000F808106080000202FE00BA +:206000000808081011313254901010111217121040408080001010202040800804FE0200D8 +:2060200008080B101032325294101011111214180000FC444444444484848404040428103B +:20604000080B0A1212323252921212121312131000FC000888505020205050880800FE009F +:20606000080A0A12123233529212121212131210202020222224A83020202022A2221E0016 +:20608000080B081111313253901010111214101000FC1010101010FE30509010101050200C +:2060A00008080F111131315191121212121213120000FC0000F01010905050101292120ECC +:2060C00011111123226264A0202F202020202020000000F84040404040FE4040404040401D +:2060E0000909091111313157911111111111111100080810204000FE4020201008448200C6 +:206100000808081112343B5292121212121211104040A0100804F210101050200404FC00A4 +:2061200008080813103031519111111111121214804040FC0000F0101010101212120E00F5 +:206140000808081013323450901010101013101040202000FE0204000000000000FE0000C9 +:20616000101310202F6060AF212226212020232C00F80000FE8080FE081010A0609008045D +:20618000080808101030305790101010101010104040407C404040FE4040504844404040FA +:2061A000080808101232529212121212121010112020203E444444A4282810102848840290 +:2061C00010101222236264A02F2020202122242840404040FC404040FE40A0A0100804026C +:2061E00011111223246863A22222222322202020000000FC0404E424242424E424042810F0 +:206200000808081113343050931C1010101110108080F80810A040A01806C02010806010F0 +:2062200008080813123431519111111111111010402020FE020400081020C0020202FE00E5 +:20624000080B0A1212333252921212121414181000FC040404FC00404448704042423E00EC +:20626000141414242F6464A424242424282832210000003CA4A4A4A4A4A4A4A4A4BCA40090 +:206280000808081F103037509013121212121312404040FE4040FC0000F808080808F8089E +:2062A000080B091111313151911111111710101000FE080808F80808F808081EE80808089E +:2062C00008080F101131335599111111111111114040FE8000FC0404FC0404FC040414088F +:2062E0001010172021626DA027202123202020204040FCA01008F600FC8000F8080850208E +:2063000010171424246760A2222222222224242800FC040404FC0048484848484A4A4A0627 +:20632000080A0A13143030579011111214181010404040FC404040FEE0505048444240400B +:2063400008090912143B325293121213121212121010080804FA0808F80808F808082810A6 +:20636000080808141230305192141010111112149090909294989098949290901212120E00 +:2063800008080F121130305196111111111212148040FE0810A040B00E1010101010101014 +:2063A00010101027206162A4212120202021222C804040FC001008041010A040A010080618 +:2063C00010101027246861A12325292121212121404040FC84884044483020100844820000 +:2063E0000808081113303151911210171010101040409008FC242020FC2020FE2020202073 +:2064000010101720236067A021212222242820204040FC40F880FE9010FE10905010502049 +:20642000080B081211303352921212121214141800FC90949890FE00000000000000000009 +:20644000101F1020276464A4262524242424242500FE0000BCA4A4A4B4ACA4A4A4A4A4AC40 +:206460000808081017303251911011121410111050484840FE40446468D050484442408005 +:2064800010171424276464A72020272020202F2000FC4444FC4444FC4040FC404040FE00B3 +:2064A000080B0A121330305790101F101011121400F80808F80000FC4040FE40A010080655 +:2064C00010101724276467A03F212223202020204040FC44FC44FC00FE0000FC0404281074 +:2064E00010171021206764A4272424272424242400F810A040FC4444FC4444FC44445408BF +:2065000010101122276161A324202F202021222C40801008FC0400F84040FE40A01008062E +:2065200008080F101330375192141110171010104040FC40F880FC104846F040FC40404099 +:2065400008080F101330375093121312131212124040FC40F840FE00F808F808F808281005 +:2065600011111721216067A021232529212121210808FE084840FE8000FC04040404FC04FB +:20658000080808171030305390101017101010109090909E9090909C9090909E90909090DA +:2065A0000808081013323352931210171010101040407E40FC04FC04FC4440FE4040404021 +:2065C000101011212A6CA92E28282B28282122248080F808906098465048FC40A01008046C +:2065E000080B0A1213323253901710111214101000F84848F84848F840FCE0504846404012 +:20660000080B081017313254901711121110101338C04040FC50488680FC1010A0609008AD +:2066200008080B121233325293101117101010104080FC2424FC2444FC9010FE1010101017 +:2066400010171424256464A7242525252524242800FC4444F44444FC04F41414F4041408EF +:2066600008080B121431315191111111111111114020FE0204F80808F80000FC0404FC04B6 +:2066800008080813123431529011101010101710402020FE0294080400FC20202020FE0064 +:2066A000080B0A1213323253921212121214141800FC0404FC2020FE2020FC848484FC8441 +:2066C00010101720226F62A0272424242420232C4040FC4048FE0800FC04444444B00C0216 +:2066E000080B0A1212323252921312121212121300FE00FC84FC84FC20FE48C8304884FE6F +:206700000A0A0B121233325093121213121213122024A830A2225E80FC0404FC0404FC04A8 +:20672000080B0A1312333153941212121310101000F808F808F800FC4444A404F4042810FF +:20674000080B0A1213323253901712121212131200F84848F84848F800FE404428900806DC +:20676000111113242B6162A421222021252528200000FC9494645484281040242A0AF800F0 +:20678000080908101330315290171011111011162024A820FEA8240240FE880890609804C8 +:2067A000080A091017343853921213101111121440485040FE0204F80808F8A02024241C89 +:2067C00010101724286362A22322222F202122248040FE0214E00000FC1010FE00100804C8 +:2067E00010101721216965A522222525292020202824407EC8487E48487E4848487E40401A +:2068000009090B121532315294101310111215100010DC54548808F40200FC4050484480BE +:2068200010171023206362A3212F20232222232240FC40F800F808F810FE00F80808F808D8 +:2068400012121722246764A827252527252022218888E8901EE4545454545448485494225C +:2068600010171125276365A9202322222322222300BC0828BC18AA4600F80808F80808F85A +:2068800011111322266B62A223222223222524284020FE2020FC2020FC2020FE0024929293 +:2068A00014121F20206F68A82F222B2A32222A24141292107E909090902828A8284A4A86CC +:2068C000080B091017303352931213101310171040F810A0FC00F848F848F840F840FE00DC +:2068E000080B0A12133037509312131011131D1100FC9494FC00FE00FC04FCA214084482E7 +:20690000121314272D7667A4252425242529293100F810FE4824FE00FC00FC00FC04FC04C7 +:2069200001010204081020C01F01010101017F000000804020100806F00000000000FC00CA +:206940000102040831C1013D0509091121C10502008040201806008488502010080600004F +:20696000010102040830CF00007F011111214502000080402018E60000FC00100804040004 +:206980000101020408102FC00211090908007F00000080402010E806101010202040FC00B2 +:2069A0001011112925459111111129254581070000F8080808F8080808F808080808FE00FD +:2069C00001020C30DF003B2A3B003F243F24242000806018F600B8A8B800F888F888A81031 +:2069E0000601020C31C1013D0509091121C1050200008060180600848850201008060000A9 +:206A00000601020418E11109057F05091121C10100008040300E102040FC402010080600E8 +:206A2000040408081020DF04080F000000000100404020201008F60000E020202020408025 +:206A4000007C447C40423E04043F0404FF08102000F888F880847C4040F84040FE2010088E +:206A600011087F449F047F011F111F111F0408100890FE42F440FC00F010F010F040201014 +:206A8000442428FD10207D45457D457C44477C44141210FE1010D2525254D408CA1A264263 +:206AA0004425297D55557D55557D1111FD12121400FE0202FE24247E2424FE525448644282 +:206AC00004FF1113525B52535AE3244F94031CE040FE00DC54D45CD052CE08E44280700E40 +:206AE00010103F204080000000000000000000000000FC04040404040404040404042810F7 +:206B000010101F2242BF023F223F223F222222200000FC4424F404E424E424E42424B448F6 +:206B200010101F2042BF001F001F001F101F10000000FC0404E404C404C404C444C45408B5 +:206B400010101F207F801F101F003F223F223F200000FC04E404C444C404E424E424F42884 +:206B600002043F202422203F001F1010102040800000E02020A040F80888A89082827E009A +:206B8000003F20202F222227242834222142448800F80808E80808C84848888A0A0A060285 +:206BA000003C2424242720203F240404081020C00078484848C80808F84840404042423E79 +:206BC000020101FF000000000000000000000000000000FE000000000000000000000000B4 +:206BE0000201FF08112244081F040408081020C00000FE2010084420F05040404042423E89 +:206C0000017F001F101F007F40803F02037E020100FC00F010F000FE02F40000F80202FEC8 +:206C20000201FF00081224481F02040C34C506040000FE0020104824F090442810080600F4 +:206C400001FF001F02017F04186203040C35C60400FE00F02040FC848880008850300E0017 +:206C600001FF00087D080C78082913040C35C60400FE0040F848C84AAA06028850300E0058 +:206C80000201FF041425413F22242921222420200000FE40504804F888482808884808185D +:206CA0000201FF0438203C203F02040C34C506040000FE0078087808F880442810080600C6 +:206CC00001FF003F20272427203F003F00FF112300FE00F808C848C808F800F800FE10082E +:206CE00001FF203F003F203F01794F7A4A794A9C00FE00F800F808F80038A8A8B82AAA4663 +:206D000001FF203F003F203F00715775577157B000FE00F800F808F8001CD454DC56D662CE +:206D200001FF203F003F203F04725771537157B100FE00F800F808F8409CD4149C16D622F0 +:206D4000004020200008081010E02020202020000000000000000000000000000000000003 +:206D600000472020000809111122E3202020270000FE808080F808080808F8101010FE0011 +:206D800000402F220203121426E52921222224080404C42424A4A4A4A4A4242404041408BE +:206DA000004222230400101721E1212122222408404040FC404040FE2020202022221E0011 +:206DC000024222220F02121627EA2A322222220208282828A444549210A0202844FC440053 +:206DE000007F408000000000000000000000000000FE020400000000000000000000000050 +:206E0000007F40807F0206196A041B620C30C20100FE0204FC000810A0C0A0988680800073 +:206E2000007F40801F101F101F1201FF0008102000FE0204F010F010F01000FE0020100812 +:206E4000002010100000F01010101010141810000000000000000000000000000000000076 +:206E6000002013100000F01017101010141810000000FC4040404040FE4040404040404052 +:206E8000002013100000F01010101014181007000000FE2020202020202020202020FE00E0 +:206EA000002010100101F111111111111519100020202020242424242424242424FC040048 +:206EC000002312120202F21212121212171A130000FC000888505020205050880800FE003D +:206EE000002312120203F21212121312161A130000FE000000FC04040404FC000000FE00B2 +:206F0000002010100302F21212121213161A120220202020FE222222524A8A0202020A047D +:206F2000002010100300F010111111111519110120202020FE202020FC0404040404FC049C +:206F4000002017100003F21212121312141810000000FE0808C848484848C8480808281010 +:206F6000002013120202F21312121212161A1302083CE020202020FE201010120A8A261276 +:206F8000002310100001F112141111111519110100FC84848404140800FC04040404FC046F +:206FA000002011110101F1101011111115191100202024242424FC20202424242424FC044A +:206FC000002010100103F01011111111151911012020408804FE0200FC0404040404FC04CD +:206FE000002312120302F21212121213161A130000FE0000FC2020F8202020FC0000FE0029 +:20700000004027200003E02027202129322408004040FC4040F84040FEE0505048444240F7 +:20702000002011100000F31010101110141813002020FC202020FE002020FC202020FE0058 +:20704000002010170000F3101011111115191101202020FE2020FE0000FC04040404FC04BB +:20706000002010170101F21214151A1014191204808080FE002020A4A428505088080402C9 +:20708000002111110102F0131010101015191204202020FC202020FE909090901212120EE5 +:2070A000004023220203E2222222222A34240800083CC00000FE000000FC84848484FC84C4 +:2070C000002010110204F31010101310141817004040A0100806F8404040F8404040FE0034 +:2070E000002011120003F01017101013141811008080F01020FC4444FE4444FC4440408059 +:20710000002312140003F010111110141B10000000FE024440FC80A020FC2020FE20202058 +:20712000004720200402E220212224202830220100BC8484A49494848C94A48484849408BE +:20714000002110100001F11111111111151911012024A4A820FC0404FC0404FC040414088F +:20716000002111110204F0131010111115191101202020FE202020FE0000FC040404FC047D +:20718000004422210204E02021222420283025020040BE08888888BE8888888888883E0092 +:2071A000004021220701E12324202F202831220C40801008FC0400F84040FE40A0100806DA +:2071C000004F24240407E424272424252E30200000C0BCA4A4A4A4A8A8A890D0A8A8C482F9 +:2071E000004F20210204EA21222428212A34200000FE80844468B030A868A4242220A04059 +:20720000004320200701E2242027212A3120000338C04040FC50488680FC1010A060900831 +:20722000004126240407E424272420202932240840405C44445C4444FC44A0A010080402B8 +:20724000004020210204E82320202029352509004040A010884600F010204024220A08F802 +:20726000004020210204E023222223222A3223028080F8081000409C04049C040404FC04DE +:20728000004027200101E22420202720283020008040FC001010A8440040FE40404040401A +:2072A000014127210101E121212722222B3223001010FC10F010F01010FE00900800FC0066 +:2072C00000402F200704E52424272029322400004040FE40FC4454E444FCE050484640406D +:2072E000002010130202F312121212161B140408407C40FE4278C0443C00FC80FE8080FC51 +:20730000004322230203E123242222222B30200000F808F808F800FC4444A404F404281083 +:20732000004724240700E3202F2122232830200000BCA4A4BC00F800FE0000F80808502079 +:20734000002011120500F31212131212171A120240A01008F600C45454D45454D44454C848 +:20736000004722210003E0202721212A322408033CC0442800FC8080FE00F8885020D8065C +:20738000004027200201EF20232222232A3223028040FC000810FE00F80808F80808F80867 +:2073A000002011100000F31214111111151910004020FC008850FE2224FC242434282020AA +:2073C000002211100106F212121111111519110140407C84082020508806F8080808F80824 +:2073E000004027240407E42427262A2B3A2A12028040FC0404FC0000FCA4A4FCA4A4A40CDD +:20740000014127210003E223222320272831220C1010FC1000F808F808F840FCA0100806A9 +:20742000004221200704E823222223202931220440485040FE0204F80808F8A02024241C6C +:20744000004724270407E122242122253020010E00FC44FC44FC100884F8080890609806F3 +:20746000024121200700E122242322222A322F0008081000FC00100804F8A8A8A8A8FE009A +:20748000004020220204E126202322222A322700402890A4C28A887800FC94949494FE0021 +:2074A000004027210007E425242525252D3424048040FC10A0FC44F444F41414F404140804 +:2074C000012017100302F312131212141B1001060890FE00C454D454D444CC00FC84140887 +:2074E000004721250703E529202322222B32220300BC0828BC18AA4600F80808F80808F826 +:2075000001412322060BE2222322222B322504084020FE2020FC2020FC2020FE002492927E +:20752000004720200700E126202724252E34240400F89060FCA428A040FCA414ECA4E40CD8 +:20754000014127210107E426252725272D3524040808CC0A08DE48C848C854D4545454E27B +:20756000024324270D16E7242524252C3529091100F810FE4824FE00FC00FC00FC04FC04D3 +:2075800004442A200F02EE222E222E2A322F0400484CAA08FE88E88AEA8CEC88EA1A264297 +:2075A0000000000000000000000000000000000000007C44444444444444445448404040D3 +:2075C0001F007D050931C5023F001F101010100FC044885020180600F800F010502404FCD6 +:2075E000007C44484850484844444468504040400000000000000000000000000000000017 +:20760000007C47484850484844444468514142440000FC90909090909090909212120E00AB +:20762000007C45484850484B4444446850404040083CE020202020FE202020202020202030 +:20764000007C44484B504848444744685041414288888888FE88888888FE888888080808C0 +:20766000007C4549495149494545456951424244081CE00000FC4444442828101028448259 +:20768000007C4448485048484545456951414141202020203E202020FC0404040404FC0440 +:2076A000007C444849514A484444446850404040808080FE4040407C4040407E404040405A +:2076C000007848535262524B4A4A6A5242444449202020FE222420FC848848502050880681 +:2076E000007D44484850484B444544685040434000FC08103048840200FC20202020FE0082 +:20770000007848575060514B4848695640404146402020FE408408F022448810205088047C +:20772000007849515161574848496952444040472020203C2020FE00202424281020C00035 +:20774000007D454949514949444445685040434000FC0404FC0404FC2020FC202020FE000C +:20776000007F4A525263524A4B4A6A524740404000E05E5252D25254D45448E85454624049 +:2077800000784950506351494F49695340404340083CE02020FE2424FE2424FE2020FE0008 +:2077A00000784B525263524A4B486957404040404080FC2424FC2444FC9010FE10101010CE +:2077C000007B4A4A53526253484F4A6A5242434200F84848F84848F800FE4044289008068C +:2077E000007C45494951494847444469504043402040FC04FC04FC00FE2020FC2020FE0035 +:2078000000784B4A525362524B484868514142442040FC2424FC2444FC40A8B43C22221E69 +:20782000007B4A4B525361524B494A6B5042424400FE02FE02FE08529C0852DE00A452520B +:20784000007F0808080808FF0808080808080808007C4448485048C844444468504040404E +:2078600000007F08080808080808080FF0400000007C444848504848444444685040404096 +:207880000804043F202020202020202020404080003E22A4242824242222223428202020BF +:2078A00010080800FF20202020202020203F0000003E2224A42824242222223428202020B0 +:2078C00010207E42424A44407F01011DE1410A04003E2224242824242222223428202020A0 +:2078E000100808FF10101F111111111121254280003E22A424282424222222342820202013 +:20790000007F0808087F4848545262404040424100BE222424A8A4A4A2A2A2B4A8A0A020BC +:2079200000FF080810143251901010000EF04000007C44484850484844444468504040402F +:207940001212121212F312121212123252931200003E222424A8242422222234A82020201D +:20796000141414149455555614141417F8400000003E22A4A4282424222222B428202020DE +:2079800001077C444444447F444444424252694400BE2224242824A422222234A8A0A0A04B +:2079A0000808102241FF00007F41414141417F41003E222424A8A424222222342820202087 +:2079C000080808FF0849292AFF08081412214180003E22A424282424A2222234282020209B +:2079E00000FF08102241FF0808087F08080FF84000BE22242428A4A42222223428A02020E6 +:207A00000848487F488808FF181C2A2949880808007C4448485048C844444468504040401C +:207A20000808142241BE0000FF10102241FF4100003E222424A82424A22222342820202005 +:207A400001320C126908FF102424488A113F1100003E22242428A424222222342820202020 +:207A600020207F41817949497949497941010A04003E22242428242422222234282020206C +:207A8000007F48087F1014247F040407FC44040400BEA224A4282424A22222B428202020C0 +:207AA000007F00007B4A4A4A6B5A4A4A4A4A4A5A00DE1212D454585452D2525A545050D0F3 +:207AC000007F4141417F007F08087F08080FF040007C444848504848444444685040404014 +:207AE0000848487F488808FF00007F4141417F41003E2224242824A42222223428202020DC +:207B0000300D061960087F14247FA42426250404803E2224A428E42422A2A2B4A820202056 +:207B2000020FF001914A00FE04080FF848082810003E222424282424222222342820202095 +:207B400010207F49497F49517F2444FF04040404003E222424282424222222B4282020201B +:207B60000809494A881422498849498A14224180003E22242428242422222234282020A005 +:207B8000007F405F505F505F447F49594649507F00DE12929494989412D2121A141090D03C +:207BA00000FF14147F55557F08087F08080FF040007C4448485048484444446850404040A4 +:207BC000007F042724FF203F407F00AAAA00050200BE222424A824A422A2A2B4A8A0202025 +:207BE0002222FF223E087F497F087F087F080FF0007CC4484850484844444468504040408A +:207C0000087F2214FF007F417F417F08FF080808003E2224A428242422222234A820202050 +:207C20000FF8492AFF2A49807F49497F49497F41003E2224A42824A42222223428202020BC +:207C40002214FF087F08FF492AFF007F41417F41003EA2242428A42422A222342820202074 +:207C6000FC4B784A794DFA0C07F8284D1A29C80800BEA2A42428A4A4A222A2342820A0206E +:207C8000007F04FF843504350000EEAAAAAAEEAA00CE0AEA2A8A0C8A0A0AEAAAACA8E8A854 +:207CA0002A7FAAFFAAFFAAFF00FF007F417F22FF003EA2A4A4A8A4A422A22234282020A087 +:207CC00004040F102040BF0000001F0000003F000000F0102040F8080808F8080808F80880 +:207CE00008080F10205F91111111FF02040830C00000E02040F010101010FE8040201806A9 +:207D00000000FF2020203E22222222224242940920202020FC242424242424244444A81043 +:207D20002020207E42827A4A4A4A7A4A0202150A20202020FC2424242424244444842810CA +:207D4000007E1212222A44803E222222223E220120202020FC242424242424244444A81092 +:207D6000100808FF0810227C091224C81422C00120202020FC242424242424244444A81078 +:207D800008087F1111254200FF001F10101F000000007C4444447C00FE10909090905020EC +:207DA000003E04087E080828107F55555557FD0220202020FC242424242424444484281047 +:207DC00000FF81BD81BD81007E427E427E427E4320202020FC242424242424244444A810EE +:207DE00010107E12222A448044FF5555555559B300FE9292FE9292FE1008282064AA281830 +:207E000001053921213D21213F013F0804031CE00000780808780808F800F0204080700E82 +:207E20002127206BB02320534A8B003F080407F808C8089A2C88089492A200F020C0807E46 +:207E40007C447C447C091F315F911F103F0807F8F888F888F800F800F000FC00F020C03E7E +:207E60000000F8081010207808084830102C43800000000000000000000000000000FE00C5 +:207E800000000000404040404040404040407F000000000004040404040404040404FC04BB +:207EA000010101015D4545494951614542407F000000001024448444241414040404FC04B5 +:207EC000092422292224293F1010111E10100F0020488828884828F80038C0040404FC00F6 +:207EE0000202020204040408081010207F200000000000000000000040201010F8080800F7 +:207F0000020408103F00080808FF08081010204000002010F808202020FE2020202020200F +:207F20000204081F027F08103FD1111F11111F10004020F000FC2010F81610F01010F01040 +:207F4000007C050810284582007C1010101DE1422010FE204884FE02A8A8A8A8AA2A2600F9 +:207F60000408102FC404081061013F010101FF00402010E8262020A04000F8000000FE009F +:207F8000007F0424141404FF0001013F0101FF0000FC4048485040FE000000F80000FE007D +:207FA0000808103057901010101116013F0101FFA09080FC80485024548C0400F80000FE30 +:207FC00010FE007D447C007C08FE1152213F01FF404040F84848C848AAAA060200F800FE67 +:207FE00008FF087F497F497F08FF497F013F01FF00784848860078482890284400F800FEEC +:208000000201FF10247910227C0830C0013F01FF0000FE48FE90FC90FC90FE8000F800FE6B +:20802000080F08FF807F4994227FA23E013F01FF00007CA4A42424A81028440200F800FE5D +:208040001011101010FC10131010101CE040000000FC2020202020FE202020202020A0400A +:208060002021202020FB202021212038E040000000FC000000FE808000FC0404040428102C +:208080001010101011FE10101010101CE1410000404080FE0000FC08102040800202FE000F +:2080A0001111111111FD11111111111DE142020404242424242424242424242424240404F3 +:2080C0001010101312FE121212121EE242040408402020FE00000000000000000000000035 +:2080E0001010111010FC10111111111DE14100000000F808080808F8080000000202FE0086 +:208100001011111111FD11111111111DE141000000FC0404040404FC000000000202FE006C +:208120002023222222FA22222222223AE444091200FE00202020FC242424444484842810E7 +:208140001010111111FD11111111111DE1420204081CE0000000FE101010101010101010A2 +:208160001010111111FD11111111111DE1420204081CE00000FC44444428281010284482EA +:208180001111111117FD11111111111DE141010108080808FE08080808F808080808F8089B +:2081A0001010101013FC10101010111DE142020490888880FEA0A0A4A4A8283222629E000F +:2081C0001010101010FC10101111111DE1410101202020203E202020FC0404040404FC0491 +:2081E0002020202020FB22222223223AE244040840407E4040FC040404FC04000000000047 +:208200001010111111FD11111111111DE1420204081CE0000000FE101030181412101010B3 +:208220001010131212FE12131212121EE2420302083CE020202020FE201010120A8A261287 +:208240001010101312FC11111111111DE1410000402020FE020400081020C0020202FE00B9 +:208260001011111111FD11111111111DE142020400FC040404FC00404448704042423E00D0 +:208280002021212121F921272222223AE340000000F80848280808FE08884808FE08502062 +:2082A0002021212222F4272122222437E040000120202020FCA424242424A4A4C444940880 +:2082C0002023202020F8242222222038E040070000FC909090929294949890909090FE002C +:2082E0002027202021FA272020202738E0400F0000FE40801008FC444040FC404040FE0077 +:208300002023222222FA22222222223AE242020200FE0202FA0202FA8A8A8AFA02020A040A +:208320001011111111FC11101011111DE141000020242424FC00FC0404FC00000202FE00D1 +:208340002020272121FA22272125253AE2450810081C701010505C505050507C0000FE0033 +:208360002020202322FA22222222223AE2420202404080FC0404F494949494F404041408F2 +:208380002020202720F820222222223AE2420300402020FE00009054242454940404FC049B +:2083A0002020202720F82123202039E640000106402020FE408408F0224488102050880400 +:2083C0001011111111FD11111111111DE141010100F80808F80808F84448302010488600F4 +:2083E0001011111111FD10101310101DE040030000FC040404FC0000FE2020FC2020FE001D +:208400002020272424FC24272424243CE744000008088888FE8888C8A8A8888888882810F5 +:208420002023222222FB20202724243DE644040400F8080808F84040FC44A41414041408C6 +:208440002023222223F820272424243CE441061800F80808F80000FC04444444B4080402BA +:208460001010131012FD11101310111CE0400000083CC04424280010FE10109090105020B7 +:208480001010131214FD10101310101CE14102044020FE0204F80000FE90909012120E00B3 +:2084A0002020272020FB22232223223BE2420F004040FC4040F808F808F808F80808FE00FE +:2084C0002020272122FC23222223223AE34000004080FE104846F84848F84848F842423EC7 +:2084E0001011111111FD10101112141CE142000100FC04FC04FC8080FE4A4A922242940874 +:208500002020232222FB2222232039E7400000004080FC2424FC2444FC9010FE1010101090 +:208520002020202021FA21202020203AE2420400202050884422F8085020A4828A8A7800FD +:208540002023222222FB22222223223AE242050800DE525252DE525252DE5252525252A69B +:2085600021212122FA272A2222232238E14204080000F01020FC444444FCA4B0282A221E71 +:208580002023202120FB20272428233AE242020000F808F808F800FE4244F8484848584042 +:2085A00020202320F827202023242239E24401004040F84848FE4848F844E85048464080B8 +:2085C0001013121213FE12121212121EE244040800FE0202FE10929292FE10929292FE020F +:2085E0002022222722FA222223202738E1420C00909090FE9090F000FC40FEE050484640C9 +:208600002027202027FC2424272038E740000F0000FCA0A0FCA4A4A4FC4040FC4040FE0099 +:208620002023222222FB202027202038E141020400FC949494FC8040FE80F88808082810D5 +:2086400021212122FA262A222222223AE242020200780808FE40407C9010FE10282844821B +:208660002023202121F921202322223BE242020200FE00FC0404FC00FE8A52FE22222A0409 +:208680002027242425FD252525253CE4490A100000FE2040FC04FC04FC2420A82422A040A6 +:2086A0002322232223F827242427203BE140030CF808F808F800FCA4A4FC00F810E01806B6 +:2086C00020272425F4272425242535E54509091120FE20FC24FE24FC20FC24FC24FC242CB3 +:2086E0002221242220F9222020272039E24C000078286CAA2A48984040FCE050484640404E +:208700002027242724FC242425243CE5440B081000FC04FC20A870A804A0FC2020FE202094 +:2087200008FF083E2A3E409F017F093FC80F080F78488678483048E400FC20F826E020E073 +:2087400008FF087F417F221FFF111F121F047F00107E107C44281028F610F010F040FC4077 +:2087600010FF107C00FE837C007C447C452FF1422020BE44509090A8A4C2201054424A3876 +:208780000808FF080800000000000000000000002020FE202000000000000000000000003C +:2087A0000808FF080804047F04040808102040802020FE20200000E02020202022221E00CB +:2087C0000404FF04003F040404040808102040804040FE4000F80810207C0404044428104D +:2087E0000808FF08090101013F0101010101FF002020FE2020000000F80000000000FE009F +:208800000404FF0400003F010101FF01010101014040FE4000F800000000FE000000000053 +:208820000404FF04003F08080C0A11102020438C4040FE4000F02040F80810A040A01806DC +:208840000808FF080802027F020A0406091020402020FE20200000E02020202022221E00A7 +:208860000404FF04003F00003F20203F000000004040FE4000F80808F80000FC04042810F6 +:208880000808FF08003F0000003F202020201F002020FE2000F0101010F000040404FC002E +:2088A0000808FF0A04081F00030C3F1000010E702020FE200010E0C00408F02040800000AD +:2088C0000808FF0809013F0101FF0102040830C02020FE202000F80000FE008040201806C6 +:2088E0000808FF08001F00007F040404080810602020FE2000F00000FC4040404444443C25 +:208900000808FF0808003F0000FF020408103F102020FE202000F80000FE00002010F808E9 +:208920000808FF080901FF01013F2121212121012020FE202000FE0000F80808082810006C +:208940000808FF09017F01013F080402010618E02020FE2000FC0000F020408000C0300E09 +:208960000808FF08003F21212F212122224448902020FE2000FC0000F808080808085020A4 +:208980000808FF08003F202027242424244444832020FE2000FC0000E02020A0440404FC1D +:2089A0000808FF08003F20203F20203F2020203F2020FE2000F80000F01010F0000000FC72 +:2089C0000808FF08082020203C202020242830002020FE202080808890A0C08484847C0002 +:2089E0000808FF0808010101111111111111FF002020FE202000000000F800000000FE007C +:208A00000808FF0809013F2121222428202020202020FE202000F808088848280808281000 +:208A20000808FF0808001F1011111112020418602020FE202000F010101010908082827EE5 +:208A40000404FF040808090E08FF0908080A0C084040FE400030C00000FE008040300E00FC +:208A60000808FF080800080808080814122241822020FE2020002020202020505088040258 +:208A80000808FF080902040A31C11F00000000012020FE20208040201806E0204040800018 +:208AA0000808FF0810101F2242840811224408102020FE200000F848488888080808502063 +:208AC0000404FF0408080F1021410102040830C04040FE400000FC04080000804020180637 +:208AE0000808FF08003F2020203F2020202830202020FE207880808080FE404024140C040D +:208B00000808FF08000F081060001F0804031CE02020FE2000E020201C00E0204080700EB5 +:208B20000808FF080A0101FF02020202020202022020FE20200000FE000040201000000017 +:208B40000808FF080A017F4080000000007F00002020FE202000FE020400000000FC0000B7 +:208B60000404FF04007F0204080FF848080828104040FE40004040404040404242423E0084 +:208B80000808FF080024222121202024283021062020FE2000101010101020205088040287 +:208BA0000808FF090101FF01017F03050931C1012020FE200000FE0000FC804020180600C1 +:208BC0000404FF041010FF1010101F1010101F104040FE401010FE101010F0101010F01091 +:208BE0000808FF08007F0001030519610101FF002020FE2000FC8000601008040000FE0007 +:208C00000808FF080800047F0404080810234C802020FE20204020FC808890A0C282827E45 +:208C20000404FF040202FF04040F0814224186384040FE401008FE0000F010204080700EA0 +:208C40000808FF08003F20203F20203F20203F202020FE2000F80808F80808F80808F808AB +:208C60000808FF08001F10101F10101F1010FF002020FE2000F01010F01010F01010FE0095 +:208C80000808FF0808013F21213F2121FF2020202020FE202000F80808F80808FE08281087 +:208CA0000404FF04003F202027242424272020204040FE4000F80808C8484848C8082810A2 +:208CC0000404FF040808101037509010101013104040FE4000404040FE4040404040FC0037 +:208CE0000404FF040808101330519010101010104040FE40101010FE101090901010502019 +:208D00000808FF0902040A31C11F00000C0300002020FE208040201806E02040800080402F +:208D20000808FF09021F121111101F007F0000002020FE2000F010105020FC04E40428101A +:208D40000808FF08067840407E4040404E7000002020FE2000FC8484848484948880808078 +:208D60000808FF08000C704044445C64480810602020FE200000FC84848484948880808012 +:208D80000808FF08007F4081013F01010101FF002020FE2000FE020400F800000000FE00E1 +:208DA0000808FF08007F40801F04043F040404042020FE2000FE0204E02020A020140C0481 +:208DC0000808FF083F20203F20203F20202428302020FE20F80808F88080FC4024140C04A1 +:208DE0000808FF08007F04081020DF1010101F102020FE2000F808085020F8080808F8087D +:208E00000404FF0400FF04043F24242830203F204040FE4000FE4040F84848483808F80896 +:208E20000808FF0801FF017F013F213F020418E02020FE2000FE00F808F800FC844C300E9F +:208E40000808FF0A027F01000738007F040810602020FE20FC204084641C00FC4042423E81 +:208E60000808FF0820203E2020263901FF0101012020FE208088B0C4847C0000FE000000E3 +:208E80000808FF080404242427242424242FF0402020FE20404044485060404242423E00F7 +:208EA0000808FF08001F10101F003F2020203F202020FE2000F01010F000F8080808F808D1 +:208EC0000808FF08003F202F20272424272020202020FE2000F808E808C84848C808281029 +:208EE0000404FF04003F20202724242720203F204040FE4000F80808C84848C80808F808BD +:208F00000404FF0511113F4101FF03050931C1014040FE400000F80000FE804020180600ED +:208F20000404FF04007B08102378082B102847804040FE4038C04040F84040FC0000FE001E +:208F40000808FF08003F02FF040834C4040408102020FE20F00000FE40205846404040404C +:208F60000808FF080008081037509010111112142020FE2000504840FE40A0A01010080669 +:208F80000404FF0408081330509F1010101017104040FE401078C04040FE40404040FC009D +:208FA0000404FF041021408813305090101010104040FE4000FC0000FE2020202020A04012 +:208FC0000808FF0902040830CF01011F01017F002020FE2080402018E60000F00000FC00A2 +:208FE0000808FF0902040837C0003F0204081F082020FE20804020D80600F8004020F0106C +:209000000404FF14101F205F901F101F100000004040FE4000F808C848C848C84808502033 +:209020000808FF080207083402010F18E8080F082020FE2000F810204080F8080808F8084D +:209040000808FF0A017F0804030C30C4040408102020FE2000FC2040806018464040404050 +:209060000808FF080A017F0810244402010618E02020FE202000FC201048448000C0300E1A +:209080000808FF0A01FF0408103F0404040810602020FE2000FE002010F848404044443CC8 +:2090A0000808FF080820179040480810E0202F202020FE202000FC40404040404040FE00A3 +:2090C0000808FF08007F4081111F2101FF0101012020FE2000FE020400F80000FE0000008D +:2090E0000808FF08007F4081017D05091121C5022020FE2000FE0204048850201008060018 +:209100000808FF083F001F003F00FF08040400002020FE20F010F010F020FE202020A040E0 +:209120000404FF04003F203F203F2221202428304040FE4000F010F010F00810A040300E64 +:209140000404FF041F10101F10101621204681004040FE40F01010F080402010880680406C +:209160000404FF04007F0402120809FF020418604040FE4000FC0488808000FE4020100803 +:209180000404FF04007C040810101DF1121050204040FE4000202020A8A424222220A040AA +:2091A0000808FF0810102144F81020FC401CE3402020FE200000FC20202020202020FE0038 +:2091C0000404FF0410102045F81020FC401CE0404040FE40080808FE088848480808281023 +:2091E0000404FF041010107D1210101CE041020C4040FE408080FC04484040A0A010080656 +:209200000808FF09013F017F409F0001FF0105022020FE2000F800FE02E44080FE00000097 +:209220000404FF04007C4445447D4444447C44004040FE40101010FE101090901010502015 +:209240000404FF041F10101F017F4142444840404040FE40F01010F000FC048444441408B0 +:209260000404FF041F017F050931CF04040810604040FE708000FC402018C640F01050205E +:209280000808FF08063808FF08080E78080828132020FE20405048FE40402428122AC6028D +:2092A0000404FF14103F409F1211FF22213F00004040FE4000FC00F01010FE1010FC10606D +:2092C0000808FF08001010242464A524242020232020FE200040407E888848502050880659 +:2092E0000808FF080808103350901211111017102020FE20804040FC000808101020FE0011 +:209300000808FF0902040837C1013F01112145022020FE20804020D80600F8001008040045 +:209320000808FF080902040837C0021109087F002020FE2020804020D80610102040FC00AD +:209340000808FF08007F22113F0000FF010105022020FE20F8001020E04080FE00000000D9 +:209360000808FF08007F221102FF04081C030C702020FE20F800102000FE20204080700880 +:209380000404FF044428102B48982849890A52244040FE40908888FEA0A0A0202022221EE3 +:2093A0000404FF044428102848992848880851224040FE402020A4A4A8202050508804024E +:2093C0000808FF0A013F000804FF01017F0101012020FE2000F8002040FE0000FC000000F5 +:2093E0000808FF0A013F20401F007F04040810602020FE2000FC0408E000FC404044443C10 +:209400000808FF0A011F101F101F1110101214182020FE2000F010F010F0048850201806DE +:209420000808FF087F429F101211101F00007F002020FE20FE02F410105020FC0404D40812 +:209440000404FF04101023447911217D001CE0404040FE402020FE20242424FC2222221E0E +:2094600008FF093F011F01FF001F101F101F101020FE20F800F000FE00F010F010F010308C +:209480000404FF0408087F080F080F08FF0810204040FE402020FC20E020E020FE20100875 +:2094A0000404FF04101011FD11313955519212144040FE40000CF00000FE10101010101082 +:2094C0000404FF04101010FD313A5450901113114040FE4010909008484442908808FC049C +:2094E0000808FF080F013F213F017F013F01FF002020FE20E000F808F800FC00F800FE00BE +:209500000808FF0A027F040837C03F01091125022020FE2000FC4020D806F8002010080065 +:2095200008FF097F013F01FF013F02FF081C037C20FE20FC00F808FE08F800FE2040C038EA +:209540000808FF081010FD10141830D1111254202020FE204844FE4040FCA428281028C6AD +:209560000404FF04080F0808FF00082A498928104040FE40007C444444282810102844821A +:209580000404FF041F101F101F003F203F203F204040FE40F010F010F000F808F808F80878 +:2095A0000404FF041010FE929292929A941010104040FE4020203E2020FC84848484FC84D4 +:2095C0000808FF08053921213D21213F020418E02020FE2000780808780808F88040300ED4 +:2095E0000808FF09081F10305F90101F10101F102020FE2080FC8080F88080F88080FC00B9 +:209600000808FF0A043F213F223F0810FF0000002020FE2000F808F808F88080FE80808042 +:209620000808FF083E22223E22223E2222224A842020FE20FC84948880FCA4A4A890A8C639 +:2096400004FF04080F10205F11111F020408106040FE4000E02040F80808F880A092827E2E +:209660000404FF04081F2044B820203C20203F204040FE4000E02040780808780808F80873 +:209680000808FF0A017F0808142201FF010101012020FE2000FC2020508800FE0000000077 +:2096A0000404FF0410087E10101F121222224A844040FE40202050508806601000C0300800 +:2096C0000404FF041009094121290911711117104040FE4000F80808F80808F80808FE003B +:2096E00008FF0A017F40803F04081F2848080F0820FE2000FE0204F00000F0101010F010CE +:209700000808FF08017F409F101F101F10101F102020FE2000FE02E420E000F01010F010D4 +:209720000808FF0A017F40901E222454080810602020FE2000FE0204F88888A89084847C62 +:209740000808FF08007F44881F030C3F011125422020FE2000FE0244802010F80820100837 +:209760000808FF08007D0911111D31D1111252242020FE201CF050505050484844545A68DE +:209780000404FF04001F40514943454955427F004040FE4000E0449424C444241404FC0400 +:2097A00004FF04087F083E087F0801FF020C30C040FE40007C242444548800FE80601806EA +:2097C0000404FF0408087F08FF08087F080FF0404040FE40000808FE08482828080828105E +:2097E0000404FF04087F080F080F08FF1214101F4040FE4020FC20E020E020FE402000F8FD +:209800000404FF0408087E08181C2A2A488808084040FE4000FC8484FC8484FC8484FC84F5 +:209820000404FF0400003F202F222F242D4245884040FE402824FE20A424A898122A4682AA +:209840000404FF04003F202F282A2A2A2A4549904040FE4824FE20A4A4A8A890922A4682CD +:209860000404FF04203C202C30041F101F101F104040FE408890E4847C00F010F010F010BA +:2098800008FF081F101F007F101F101F10FF000020FE20F010F000FC10F010F03ED0101027 +:2098A00008FF08011F111F01FF001F1011020C7020FE2000F010F000FE00F01010C0300857 +:2098C00008FF08003F21213F21213F025151900F20FE2000F80808F80808F800041212F097 +:2098E00008FF08003E223E003F00FF080F00000020FE2000F888F800F800FE00F010A040DA +:209900000404FF04080B12325390171011121C104040FE4000F80808F840FEE05048464092 +:209920000404FF0410217D4545457D4545457D444040FE4000FC24242424FC00000202FE4A +:2099400008FF097F001F101F007F409F0101050220FE20FC00F010F000FE02F400000000A5 +:209960000404FF0411097F05196104FF081E033C4040FE401020FC40300C00FE2040C038A0 +:209980000404FF04201392424A0A12E2222424284040FE401CE00EF0909092948888A4C267 +:2099A0000808FF0A017F409F001F101F101F00FF2020FE2000FE02F400F010F010F000FE73 +:2099C00008FF08007C44447C40417C40407C404320FE2000F80808F800F888502050880670 +:2099E00008FF08017F013F02FF081721DF05091120FE2000FC00F800FE20D008F6402010CB +:209A000008FF0A3F02FF020F34C3001F101F101F20FE20C080FE20C008F800F010F010F024 +:209A200008FF083F202F203F242426205F44820020FE20FC00F800FC48300E20FC20A040A7 +:209A400004FF041F101F10FF102FC0080F007F0040FE40F010F010FE10C84640F808A8107B +:209A600008FF08003F212F2224283F010848488720FE2000F808E8884828F800849212F04D +:209A80000808FF0810172062A12F2023222223222020FEA040FC000810FE00F80808F80832 +:209AA00008FF08040832C40F007E22120A122A4420FE2040201846E020FC442414245488D6 +:209AC00008FF0802FF001F101F007F404F484F4020FE2000FE00F010F000FC04E424E40C1F +:209AE00008FF09001F10925354103F509021224C20FE2080FC0000F84040FE40A010080602 +:209B00000808FF0900FF0413141F017F444F44402020FE2080FE409050F000FC44E4240C0D +:209B200008FF08013F08047F42813F040708102020FE2000F82040FE0204F800F010502004 +:209B400008FF081008FF043F04FF043F0C34C40420FE201020FE40F848FE48F860584640E6 +:209B60000808FF084122FF084949497F112040812020FE20007CC4447C44447C4444940892 +:209B80000808FF08201392434A0B12E2222223222020FEA040F808F808F842442890080672 +:209BA0000808FF08007F41820C30DF013F11097F2020FE2000FE02846018F600F81020FCE4 +:209BC00008FF08007D042811FD1511111110502320FE2000FC2040FC0424242424508804EE +:209BE00008FF080008FF087F49497F1C2A49880820FE200020A03E42941010102828448240 +:209C000008FF083F243F007F40BF080F0910161820FE20F848F800FE02F400E020A4241C69 +:209C20000808FF091267444744576004040810602020FE2000DC44C444DC00404042423EE9 +:209C40000404FF041021418917305091111112144040FE40203C2020FE0020203E20A07E7A +:209C60000404FF04080814225D8011094A27F8404040FE4020203E44A424282810A84482DD +:209C80000808FF082010FE21203C2524254454892020FE204040FE2040FC2020FE5088061F +:209CA00008FF08201705444F596F494F494F484020FE2000FC0484F404E404E404F41408AC +:209CC00008FF082312432A0B721311FF0519E10120FE20FC00F808F800FC00FE40300E0089 +:209CE00008FF0A017F40803E007E14141424244320FE2000FE02243820F80850245484FC8E +:209D000008FF08017F488B10335292131212131220FE2000FE02F480F80808F80808F8089C +:209D200008FF083C2414250618E30C310638073820FE20F8482848C0300E408030C0000024 +:209D400008FF093F011F111F111F017F0249488720FE20F800F010F010F008FC040824E45C +:209D600008FF087F043F243F101F101F01FF010120FE20FC40F848F810F010F000FE00009F +:209D800008FF08003F28252F222A2A2F2244448820FE2000FE9010BE22D49090282844825C +:209DA00008FF0800FF10294E9625CD1424C4140820FE2010507C90107C1010FE40300E009C +:209DC00008FF081F101F10FF223E223E222FF24220FE20F010F010FE00FC4444281028C6EC +:209DE00004FF043E223E00FF223E223E222FF24240FE4028242420FE20282810122A4682EA +:209E000008FF083F243F007F409F101F101F101F20FE20F848F800FE02F410F010F010F03C +:209E200008FF08003F1109FF0930DF111F111F1020FE20F8001020FE2018F610F010F01091 +:209E400008FF0822147F497F497F08FF0808080920FE200C704040407E4848484888880856 +:209E60000808FF08003E203C203C20FE2044FE432020FE20484848FC484848FE004884023C +:209E800008FF08007E11103C256494090810234020FE205050DC5050DC5050DC5050FE00E7 +:209EA00008FF087F447F007F40BF081F621418E020FE20FC44FC00FE02F440485062423E16 +:209EC0000404FF04224A8A1F206FA02F292929304040FE4020A0BEC4A424282810A84482C3 +:209EE00008FF08013F08FF001F101F101F49488720FE2000F820FE00F010F010F00492F2AB +:209F000008FF0A01FF1020457B11257D091121C120FE2000FEA090FE20FC20FC2020FE00B1 +:209F200004FF0400492AFF2A4910FE22641824C240FE400020203E44A4242828102844824D +:209F400008FF08003E22223E21203E52529E120020FE204020FC8850FE2020FC2020202033 +:209F600008FF082322FA4A4B4A925222534A840820FE20FE00FC00FEA498C608FE8848185F +:209F800008FF09FF013F001F107F489F013F01FF20FE20FE00F800F010FE22F400F800FE5F +:209FA00008FF083F017F419D011D007F023F242420FE20F800FE0274007000FC00F8485821 +:209FC00008FF083F01FF013F293F013F01FF244220FE20F800FE00F828F800F800FE482437 +:209FE0000808FF08203E44FF497F497F000FF0402020FE204428FE10107C1010FE10101028 +:20A0000008FF08017F080F007F484F017F0519E120FE2000FC20E000FC24EC00FC40300E45 +:20A0200008FF080638087E1C2A49021DE905091320FE20407C9424449408C0302E40201075 +:20A0400008FF083F017F419D081F305F901F101F20FE20F800FE027480FC80F880F880FC2E +:20A0600008FF0800402F280BE82B292A3122518F20FEA0F880FC84F088F840A870A860FE12 +:20A0800008FF08224788172567A527212F21222420FE2000DC80C07EC848C808E808A850FA +:20A0A00008FF283F40BE2AFF4A7F081F023F112320FE20203E48A8281028468010F81008D4 +:20A0C00004FF04207D447C417C457C017F0519E140FE4020FC8850FE20FC2000FC40300EF9 +:20A0E00008FF083F243F262D34213F212F415F8120FEA0FE107C385412203E203C203E2039 +:20A1000000000808080808FF080808081010204000002020202020FE2020202020202020DA +:20A1200002017F0424448910000808FF081020400000FC4050484480002020FE20202020BB +:20A1400001017F02040830C909090909111121400000FC80402018262020202020202020B6 +:20A1600002027F040830DF101211101112101F000000FC402018F600204080402000F8000A +:20A1800001017F0204083FC80F080F08097E00000000FC804020F826E020E020F820202022 +:20A1A00002017F04244489100101FF02040830C00000FC40504844800000FE804020180685 +:20A1C000007F2215081F030C3F01017F020418E0FC00081040802010F80800FC8040300ED7 +:20A1E0002424243D04FC24244501FF02040830C0202020FC202020F80000FE80402018067B +:20A200001010FE2845827C00FE20407C040428104040FC8404F49494F484948882827E0065 +:20A2200004040404FF040404040808101020408000000000FE8080808080808282827E00ED +:20A2400020202021FD2A28282828282828484780808080F808088848480808502202FE000D +:20A2600020202020FD2A2828282829292A4847802020508804028888888808080A02FE00B4 +:20A2800020222222FE2A282B2A2A2A2F284847809090BCD0888800F8A8A8A8FE0202FE002D +:20A2A00010101010F810141830D0101010105020000000000000000000000000000000007A +:20A2C00011101012FA12161A32D21212121252220080BC04040404040404040404041408BB +:20A2E00010101011FC1011141831D01010105020202020FC2040FE4080FC048850201010A1 +:20A3000010101013FA12161B32D2121312105020202020FE222222FE222222FE222020205A +:20A3200010101011FD1315111931D11111115121888888087E0808482828080808082810C8 +:20A3400010101010FD1310141833D010111152242020408804FE028888FE8888080808087C +:20A3600020212122FA24272932E224272020A04120202020FCA424242424A4A4C4449408CF +:20A3800010101013FC1011141831D11111115121202020FE2020FC0000FC04040404FC04E4 +:20A3A00020202320F827202932E521212122A2441078C04040FEA01008161010101010103C +:20A3C00011111211FD1010141931D2141010502324244824240080FC048448281020C00008 +:20A3E00010111111FD1013121A32D3121212512000F80808F800FC444444FC000202FE005C +:20A4000010101310FA11151833D0111010105020083CC04424280010FE10109090105020AB +:20A4200010111010FB10141930D011121410502000FC4444FE4444FC8080FC848484FC84DE +:20A4400020232020FB20212A34E020222224A14000FC4040FEA010084640486452524080CE +:20A46000202F2424F427242437E424252E20A04000DE929294949894929292DA9490909026 +:20A4800010131212FE1212171A32D2121214552800FE1010FE1010FE001010FE1010FE00F3 +:20A4A00010101310FC1112101833D011111250202020FE508804FA0000FE20242222A040F1 +:20A4C00010101310FD1217101B32D212131050204040FCA01008FE08C8484848C80828105D +:20A4E00020232222FB22222A32E222232222A34200FE0202FE2222FA22322AFE0202FE022C +:20A5000010101312FA13161A33D01117101050204080FC2424FC2444FC9010FE10101010BC +:20A5200011111112FC11141833D01011121050200000FC044454E444FC44E454444414080B +:20A5400010101110FD1010131830D111111151214020FC00089000FE0000FC040404FC04D2 +:20A5600010101312FA13161A32D312121214552A4020FC0404FC002824FE20505088040293 +:20A5800010101312FE1312121A32D212141458204020FC0404FC00FC84FC84FC84849488F1 +:20A5A00011111113FD1111141931D11111105023FC2424FE2424FC00FC0424242458840292 +:20A5C00010111113FD1111151930D31010115620484848FE48487800FE20FE70A8242220C7 +:20A5E00010101310FC1112111931D111111057202020FE70A82422FC04FC04FC0400FE008A +:20A6000010131212FA12161A32D312121212522300FE00FC84FC84FC20FE48C8304884FED3 +:20A6200022222223F424272A32EF22222223A240101010BE2244901010902828A844448206 +:20A6400020202122FD20232A32E322222322A24240A01008F600C45454D45454D44454C881 +:20A6600010101310FD1017101931D111111151214020FE000488FE00FC0404FC0404FC04B3 +:20A6800010101312FC11141931D11111111053204020FE0204FC00FC04FC04FC0400FE0025 +:20A6A00020232222FB22222A32E222232424A85100FC0404FC008448FC4848FE484888089A +:20A6C00010131012FD1011121830D3101010512210D458528C8804FA2020FE20508804026B +:20A6E00021212223F827202936E021262021A64000F808F010FE804468B02868A422A040D7 +:20A7000020202027F424272434E424242529A952407C40FE4270C4443C20105442424A382C +:20A7200020272424F724242534E720202525A94000FC4444FC44A41404FC4024220A08F88C +:20A7400010101312FE1212161A32D2121214552A041EF01E10FE9298F28E80B8A8AA4A8665 +:20A7600011101017F813101F30D310111214502010A000FEA0F8A8FEA8F8A0B0A8A6A0A033 +:20A7800024222220F721252535E721212222A448405E9212D21E525252DE521212222A4435 +:20A7A00020232222FB22222A32E223222224A44800FC0404FC4848FC4848FEA4A890C886DA +:20A7C00020272020F724242730E422222420A54200BC8484BC2020BC84A49494A4842810DD +:20A7E00023212023F827242B34E027202122AC40F010E01800BCA418A440FCE0504846408C +:20A8000010131213FE1310151B30D1131011522400FC44FC44FC8010E04884FE2228A4420E +:20A82000202F282AFA2A252830EF21222320A14E00BEA2AAAAAA14A280FE1010A060980424 +:20A8400020202322FA22232A32E222222525AA504020FE004848FE4848487800542A2A008A +:20A8600020272021FF24242734E72424272CA04008888810DE94A494949494C88894A4C274 +:20A8800020272024FA24202833E222232222A34200BC84A494A48440F80808F80808F80854 +:20A8A0002222222FF222272030E725252527A54000FE10A07C4454545454545428244282A0 +:20A8C0002123242FF427242730EF20232223A24300F010FC44FC44FC00FE00F808F808F87D +:20A8E00021202720FB22232A33E223202721A0400890FE90FC941C04FC04FC08FE08A8104E +:20A9000020202725FA24232A33E027242724A0408040FC144844F848F840FC44FC444040E3 +:20A920002121212FF127242734E7212F2121A141080814D422C05CC848C83EC8080808085F +:20A9400010131212FB10171833D2131011135D2100FC9494FC00FE00FC04FCA2140844820E +:20A9600020202724F424272434E7262A2A2BB240100888BE8094887E0888BE888888880849 +:20A9800020232223FA23202F34E72427202FA14280F808F808F800FC44FC44FC00FE101019 +:20A9A00020272024FA24212A37EA23222322A34200BC84A494A42010FC20FC20FC20FE0075 +:20A9C00027202724FB20272933E62B222322A342FC40FE425C405C20FC20FC20FC20FE0004 +:20A9E00022232520FB22222B30E722252823A14210DE2884FCA454FC80FEA8E452F850C8E1 +:20AA000020272223F02F2A2331E7212F2123AD4140FC48F840FEAAB810FC10FE2810488668 +:20AA20000202020202FF0202020101000000000020101000FE0000000000008042221A06C3 +:20AA400000000000FF0008041455505092120E0048444440FE4040404040A0A2920A0602FC +:20AA6000000000FF002222FF22223E22223E2200504840FE4040404040202012120A0602E2 +:20AA80000044281328441011FC10585494135120141210FE101010F090909088EA8A0602D2 +:20AAA00000007C444444444444447C4400000000404040404060504844444040404040403E +:20AAC00000007C444444444444447D4400000000404040424448506040C0404242423E00DB +:20AAE000000179494949494949497A4A0204040800F01010101010101010101212120E0043 +:20AB000000007C444444444444447C440000000000FC8484848484848484948880808080E5 +:20AB200000007D444444444444447C44000102040000FC4444444444444444848404281095 +:20AB4000000078484B484848484878480101020440404040FC4444444484848404042810E2 +:20AB600000007B48484848484B48784800000000083CC0404040407EC040404242423E00D9 +:20AB8000000279484848484848487848000000000002048850202020202020202020202044 +:20ABA000000078484848494B494878480001030120204040848408F8101020408804FE0287 +:20ABC0000000784B4848484F4848784901020408404040FC404040FE40A0A0101008040203 +:20ABE0000003784848484F48484878490102040800FC40404040FE40A0A0A02022221E006F +:20AC000000007B4848484B4848487849020201009090FE909000F810204080000202FE00D0 +:20AC2000000078484F484848484879490202040840404040FE4040A0A0A010108848440237 +:20AC400000037A4A4A4A4A4A4A4A7A4A0404091200FE00202020FC242424444484842810FC +:20AC600000037A4A4A4A4A4A4A4A7A4A0404081000FE0000F888888888A8908282827E001B +:20AC800000027A4A4A4A4B4A4A4A7A4A02030200202020222224A83020202022A2221E0062 +:20ACA0000001794949494949494979480000010600FC040424242424242424504884020233 +:20ACC000001F1010101F01017F4142444840404000F0101010F00000FC048444240414089A +:20ACE0000000F090909090929292F2940000000000402010908080848282828888887800CE +:20AD000000037848484949494A4B78480000010004E4242424E4040404E424242424448477 +:20AD200000037A4A4A4A4A4A4A4A7A4A0202030000FE101010FE929292929A941010FE0005 +:20AD4000000078484848484F48487848000000004040407C404040FE4040504844404040A6 +:20AD60000007F494949794949497F4900000000000FC444444FC444444FC44404040404032 +:20AD800000007B4A4A4A4A4A4A4A7A4A02040408083CD09090909090908888C8A4D4920006 +:20ADA00000007848494A4C484B487849000000004040A0A010482620F8081010A0402020BA +:20ADC000000078494B4C48484B4C7848000100008080F80810A040A01806C02010806010A5 +:20ADE0000000784B4A4C48484B48784800000000402020FE02040000FE2020202020A04015 +:20AE0000000079494949494848487A4A02020300202024242424FC24202022222222FE023A +:20AE20000202E2A2AFA4A4A4A4A9E5A20509100100007C24A4A4A4A8A828101028488402E2 +:20AE40000001715252545751525274470000000120202020FCA424242424A4A4C4449408E4 +:20AE600001017152525457515152745700000F000808081094A4BC08081020BC0000FE002C +:20AE800000037A4A4B4A4A4A4A4A7A4B0202030000FE0000FC2020F8202020FC0000FE00D6 +:20AEA0000000784B484849484849794901010101202020FE2020FC0000FC04040404FC04B1 +:20AEC00000077848484B4A4A4A4A7A4B0202030200FE909090FC949494949C040404FC0480 +:20AEE0000000784B4848484949497A4A04000001404040FE80909012525490282844840253 +:20AF00000002794948484B49494979490102040010101010FE1010282444428200807E003E +:20AF20000000EFA2A2A3A2A4A6A5E8A0010204080404C41414D454545454949404041408AF +:20AF40000000F790979093929497F0900001020C4040FE40FC44FC4040FE42AAA41008063E +:20AF60000000784B4848484B484B7848010102048080BCC05024D40C00FE909012120E0070 +:20AF8000010179494949494949487B4800000000101214D81012528E2020FE202020202087 +:20AFA0000000784A4A4A4A4A4A4A7A4A030E04009090909092D4989090909092D2120E0038 +:20AFC00000007A4949484F484848784801010204404444485040FE909090909212120E008C +:20AFE0000001794949484848494A78480000000320242424FC4040FC048448502040800013 +:20B0000000007849494B4D49494979490101010190909010FE101038385454921010101025 +:20B020000101F19292969A929292F29202020202007C242424FE2424247C24202020408075 +:20B040000000F794949595959595F59505090911083CC0001CE020222428101008448200BA +:20B06000000078494A4C4948484F7848010207024040A0100806F00000FC40801008FC0483 +:20B080000001794949494A4C4B4878490204000000F0101010104E40FC40E0504846404033 +:20B0A00000007B49484848484B487848000101024020FE04885020D80688888888080808E5 +:20B0C000010078484B48484948487B480000000004848800FE2020FC2020FE202020202010 +:20B0E00000007A4949484F484849794A04080000404048485040FE40E05050484442404059 +:20B100000000784B4A4C484B4848784F00000000402020FE020438C040407EC04042423EB0 +:20B120000000F097949891919395F99101010101404040FC848840444830201008448200C2 +:20B1400000037A4A4B4A4A4B4A4A7A4A0202030200F80808F80808F844483020108806001B +:20B16000000078494B484949494A784F0000000040409008FC242020FC2020FE202020205D +:20B180000000F790939097909091F3940000030C4040FC40F840FE80F80810A040A0180607 +:20B1A0000000794848484B484849794A000001022020FC202020FE48484C4A4A8888281002 +:20B1C00000007B48484B4A4C484B7848000102048888FE8800FE024440FC4484840428108B +:20B1E0000007F097949497949497F2910001020C00FE40FC4444FC4444FC40408040300EF1 +:20B200000007F090939090979090F3920202030200FC4040F88888FE0000F8080808F8081D +:20B22000020272525F525252535E725202020A05081C6040C0407EC848484848484888081F +:20B24000000178484849494949497949000001022024A4A820FC0424242424245088040271 +:20B26000000079494949494949487848070000002040FC0404FC0404FC40407EC042423EAC +:20B28000010078484B484B48494B7D4901010000846830C80440FEA020FC242434282020A5 +:20B2A0000000F292929598909097F09000000F00404048484854E24040FC40404040FE00FD +:20B2C0000007745454575454545774550405060000BCA4A4A4A4A4A4A4A43428A060202051 +:20B2E0000000F790939097919294F190070000004040FC40F880FC104846F040FC40404014 +:20B3000000007B4849484B4849497949010000032020FE20FC20FE00FC042424245088042E +:20B320000101F791919097909193F599010101010808FE084840FE8000FC04040404FC045D +:20B3400000007B484848494949497949010101018888FE888800FC242424FC242424FC04C2 +:20B360000101715157515153535575590101010110101010BC101038B854549210101010BD +:20B380000202725F525555575151715F05010101101010BC10107E90203CC4082810080485 +:20B3A0000007F494959494979495F5950504040800FC4444F44444FC04F41414F4041408B2 +:20B3C0000101794A4D494A484F487A4A030000000000FC0404E48484F484A4A4E404281052 +:20B3E0000101F394989192949192F091050508000000FC9494244484281040242A0AF800E7 +:20B400000000F790919192949090F790000000008040FC001010A8440040FE404040404070 +:20B4200000007B4849484F48484F7849000001068040FC000890FE4040FE880890609804D6 +:20B4400000007B48494B484949497949010101014020FE8004FE02FC04FC04FC04041408AA +:20B460000002F294909196909092F2940001020C40444448A010084440484850A01008065C +:20B48000000472525854545252547C5404050502101010FE929490FCA4A4A8A89028448216 +:20B4A00000007B4A4C484B4848497949020204084020FE020400FE2020203C20A0603E00E1 +:20B4C00001007B4A4A4B4A4A4B4A7A4A02030200009ED25254D45854D212925AD450101073 +:20B4E00000007B4A4A4B4A4A4A4B7A4A0204050A4020FC0404FC002824FE205050880402F8 +:20B5000000077454575454545756765A0A12000002E2222AEA8A8A8AEAAAAAAAA2E28A843E +:20B520000007705251525458505770520102040800BC84940894A44000BCA4A42890A8467D +:20B540000001794B4949494949487B4800010600484848FE48487800FE20FE70A82422202F +:20B560000101F791909091929590F093020203021010FC1040A01008F60000F80808F8082B +:20B580000000F790909795949594F495040404044040FC4040FC14A4F44444F4444454080E +:20B5A0000007F495959595959595F4940508081300FE00FC2424FC2424FC2020FC2020FED1 +:20B5C0000000F79091929D909097F0900300000F4040FCA01048F64040FC0040F84040FE3F +:20B5E00002027B4A4A4B4A484B4A7A4B020203022024A830A2225E80FC0404FC0404FC0432 +:20B600000101794949494948484B7A4A02020202FC2424FC2424FC2020FE222AFA0A0206CA +:20B6200000037A4B4A4B4849494979490101010100FE22FE22FE00FC04FC04FC0404140866 +:20B640000001775151515751535375550901010188C808082A2AAC4808885414142424421D +:20B660000106F494979494979097F2910000010E405C44445C4444FC40FC0810A040B00E36 +:20B6800000007B4849484F4849497949010101018040FC000890FE00F80808F80808F80805 +:20B6A000013F08047F419F111111013F20203F2000F82040FE02F410502000F80808F808F9 +:20B6C0000100784B4849484B4849794A04080300088890FC40F840FE8000FC202020FE00B3 +:20B6E000000178484B48494A484F7849010001062024A820FEA8240240FE880890609804D1 +:20B700002211007F41911F2101FF001F10101F10081020FE0204F00000FE00F01010F010BD +:20B7200000037A4A4B4A4B4A4A4B7A4A0504081300FC0404FC00FC4088FC2420FC2020FE5D +:20B740000101F293909790919690F1960001060000F808F010FE804468B02868A422A04056 +:20B760000000F790939097919295F093000106004040FC40F880FC1068C640F8E0584440E4 +:20B78000010171575157515F5253725202040408080808D01E9424D414D4544848D4244274 +:20B7A00000007B4849484B484849784B000102002020FE20FC20FE4088F024FE2224A240D1 +:20B7C0000202EFA2A2AFA1A2A7ACF4A704040704003E6264A4E82424A2A2A2B4A8A0A0A045 +:20B7E00000007948484B48494B487B4A020207002020FC2020FE8004FE02FC949494FE004D +:20B80000000379494949494F484F784A0102040800FC08F808F80EF808BCA4A42890A8461D +:20B820000101F791919292969A92F292020202021010FE1000FE0808E8A8A8E8A808281037 +:20B840000000F790939293929392F3920F0102044040FC40F808F808F808F808FE10080481 +:20B860000000F790979499939090F790020409004040FC40FC8418E04088FC445048488098 +:20B88000000FF093929293909795F4970404040400FE00F80808F800FC14A4FC4444540876 +:20B8A0000700F392939293929390F1930400010EFC80F808F808F808F880F810A040B00E5E +:20B8C0000007F494979494959497F0900505090000FC4444FC44A41404FC4024220A08F8BB +:20B8E0000000F392939293909791F2940B0000004080F808F808F880FC104844FA40404038 +:20B900000001F290919690939090F79003000007900894609846FC08B0D03EC2241860809F +:20B920000003784A494B4A484B487849010204010EF0442408FE4240FE80FC4428106886EE +:20B940000201F190979091929493F29202020F0008081000FC00100804F8A8A8A8A8FE008D +:20B9600004027250575155555557715102020408405E9212D21E525252DE521212222A4423 +:20B980000008E4A1AAA4A4A0A3A4EDA5050404008080FE00FC84A494FE842414FE042810F8 +:20B9A0000108E4A4A1A1BDA5A5A5E5A5050A1100FC085020FC2424FC24FC24242C00FE0018 +:20B9C00000017949484B48484949794900000301202424FC20FE0020FC2424FC2024FE0203 +:20B9E0002222478AF52741F90719E13F20203F200808D0223CC8103EC03E00F80808F808A3 +:20BA0000020277525351575555577157010101019090D090BC14D45454D414D424245488E5 +:20BA200000007750575457545750735203020302A0A0FEA0FCA4FCA4FC00F808F808F80859 +:20BA4000000FE0A7A4A4A7A0A7A0EFA00204090000FEA0FCA4A4FC00FC00FE404844428076 +:20BA60000000705754545454575474550A081100141210FE1090D292F29494C8AA9AA642D2 +:20BA8000000FE8AAAAAAA5A8A0AFE1A20300010E00BEA2AAAAAA14A280FE1010A060980432 +:20BAA00000047457505754545754745704040A11404444FC00BCA4A4BCA4A4BCA4A4B44803 +:20BAC0000402725F545457555555755505090B1020203E40A0203C501010FE102828448250 +:20BAE0000000F791909794959495F595050404048040FC10A0FC44F444F41414F404140896 +:20BB00000000F794989095959893F094040407008040FE029450244AFA0040444444FC0472 +:20BB200001017751515750575454775402000F040404E81000C404C85042C24484E81020A0 +:20BB4000000FE8AAA9ABA8A8AAAAEBA80809091200FE002848EE9284A0A8E8889414244255 +:20BB60000000F7909592979A9392F390020409004040FCA01408FC0AF808F8404844448069 +:20BB80000004F290979190979093F0970001020CA0A4A8A0FC10A0FC40F840FCA0100806B1 +:20BBA0000003F2939293909F9497F497040F000000F808F808F800FE80BC9494D48894A2F4 +:20BBC0000101F392969B92929392F293020504084020FE2020FC2020FC2020FE0024929270 +:20BBE0000001F794959497949594F0970001020C8000FC445444FCE4540440FEA01008061A +:20BC00000000F1929D9092929390F7940505040440A01048F6A048A8F840FC8424F4140CE2 +:20BC20000103F49F94979497909FF0930203020300F010FC44FC44FC00FE00F808F808F8E9 +:20BC40000201F097949594949790F39203020302081000FC4454E444FC00F808F808F80883 +:20BC60000007F092919295989392F29302010F0020A4A8921408F402F80808F80810FE0009 +:20BC80000107F190979091919190F7940505050408FE0820FE00F808F800FE02FA0AFA06EB +:20BCA0000101F791939599909390F790020409001010BC10B8541200F800FC404844428064 +:20BCC0000000784B4A4A4B4A4A4B7A4B02050409407C40FE4278C43C00FE40A458B452B066 +:20BCE00000007B49484F484B4A4B7A4B000505088040FC0890FE00FC04FC04FC40240AFA34 +:20BD00000000F7959B9197919791F295080007008040FE12FC10FC10FE1048F44240FC00D5 +:20BD200000007754545457545457765A0A0B1200100888BE8094887E0888BE888888880855 +:20BD40000007E0AFA8A3A0A3A0AFE0A70404040400FC40FE4258405800FE40FCA4A4A40C3B +:20BD6000000077545A53545A5552745B000204008040FE0224BCA4A810E804FA404844C0B3 +:20BD80000700F7949B9097919396FB9203020302FC40FE425C405C20FC20FC20FC20FE0018 +:20BDA00000077253505F5A535157714F01030D0140FC48F840FEAAB810FC10FE28104886A5 +:20BDC000007F4040404040404040404040407F4000FC040404040404040404040404FC04F9 +:20BDE000007F40404F4040415F41414145427F4000FC0404E4448404F40404040404FC0410 +:20BE0000007F4242427F44444846414244487F4000FC040404FC4444848404844424FC04F6 +:20BE2000007F4141424448546546444443407F4000FC04048444249C04042424E404FC04A6 +:20BE4000007F4444474949524244494244407F4000FC0404F4545454949414A44404FC0440 +:20BE6000007F414142444A516F40404241407F4000FC04048444241CE42444840484FC04CB +:20BE8000007F42425F444F546744474444447F4000FC0404F404E424E424E424A444FC04E0 +:20BEA000007F405F424F447F404F48484F407F4000FC04F404E424FC04E42424E404FC048F +:20BEC0007F414F414F417F404F484F484F48487FFC04E404E404FC04E424E424E42464FCEF +:20BEE000007F41414F415F44424F415F41417F4000FC0404E404F44484E404F40404FC0410 +:20BF00007F405F525F407F404F484F454C74467FFC04F494F404FC04E424E414A44424FC1B +:20BF20001010107D545454545455545C10101010202020FE2020FC2020FE22222A242020C1 +:20BF40001010117D555556545754545C1010111220202020FC202020FE2050508888040291 +:20BF60001010107D555555555555555D11121214101010FE121410FC4444282810284482E5 +:20BF80001010FE22641824C3013F2121212101010000FC442810284600F808082810000012 +:20BFA000202027F8ABA8AFA8A9A9AABA242820204040FC40F880FE9010FE109050105020F6 +:20BFC000202027F8ABA8AFA8ABAAAABA222021264040FC40F840FE00F808484848A0100894 +:20BFE000202322FAABAAAAAAAAAAAABB2222232200FE0202FE2222FA22322AFE0202FE0239 +:20C000001010107C555654545454545C10101010504880FE9090FC9090FC909090FE80808D +:20C02000202322FAABAAABAAAAABAABA2524283300FC0404FC00FC4088FC2420FC2020FE5C +:20C04000202121F9A9A9A8ABAAABA8B92020212600F808F808F800FC94FC00F89060980699 +:20C060001011107C575455555555555C1310101020FC8850FE00FC04FC04FC20FE202020B4 +:20C08000202221F8ABA8A8ABA8A9A8BB2020212650525450FE8850FE20FC20FE5088040232 +:20C0A000202722F9ABA9AAACABAAAABB2222232278C04850FC504806F84848F84848F808B7 +:20C0C0000121213F003F08080C0A11102020438C000808F800F02040F80810A040A0180643 +:20C0E00010101110545454555555555D650100000000F808080808F8080000000202FE00D2 +:20C1000010111010545454575454545C6401010200FC8888888888FE888888888808080869 +:20C1200010101013545454555454545C64000106202020FE202020FC84884850205088064C +:20C1400010111111555555555555555D6501010000FE000444282810102828448400FE00B9 +:20C1600010111010545455555454545C6502000000FE0888888808FE182848880808281071 +:20C1800010111111555555555555545C6401020400FC040424242424245450909012120E95 +:20C1A00000003F01027F040830C1012121213F0010F8000000FC4020180600080808F80884 +:20C1C0000121213F0102040A31C11F0000000001000808F8008040201806E02040408000B4 +:20C1E0000121213F001F10101412111224284080000808F800F01050509010924A4A0602B3 +:20C200000121213F003F2121213F202020201F00000808F800F8080808F800020202FE0008 +:20C2200010101010555454545555555D6501010120202020FE202020FC0404040404FC04BB +:20C240000121213F0000FF00001F10101F000000000808F80000FE10109090909010502019 +:20C260000121213F02027F0409113F0111214502000808F80000FC000000F80010080400CA +:20C2800010111111555555555555555C6400000000FC242424FC242424FC242020202020B8 +:20C2A00010101010555555555555555D6501010120202020FC24242424FC24242424FC048E +:20C2C00008081030579010101101212121213F009088809EE08044340C0008080808F808F8 +:20C2E00010101111565455555555555D64000000808000FC0404E4242424E424040428104C +:20C300000121213F000C704044445C6448081060000808F80000FC84848484948880808027 +:20C3200010111111555555555555555D6501010100FC040404FC2020FE202010124A86022C +:20C3400010131110545454575455545C6700000000FC04885020D82620FC2020FE202020D6 +:20C3600010111111555555555555555D6501010100FE02027A02027A4A4A4A7A02020A04FE +:20C3800010101110545754545556545C64010102083CE02020FE5088048A888888080808CE +:20C3A00010101111565555555555555D650000008080FC0404E42424E42424E404042810A5 +:20C3C00010101011565554545554545D640000008080F80810FC2424FE2424FC2420A04051 +:20C3E00020202320A8ABAAACA8ABA8B8C80102048888FE8800FE024440FC448484042810F1 +:20C4000020202027A8AAA9A9AFA8A9B9CA040800404040FC40484850FEE0505048444240FA +:20C420000121213F101010FD313A545090111311000808F810909008484442908808FC044B +:20C4400020202721AAACABAAAAABAABACB0000004080FE104846F84848F84848F842423EFF +:20C460000121213F003F21212F21272427203F20000808F800F80808E808C848C808F80898 +:20C4800021202020ABA8ABA8A8A9AAB8C8000000846830C82420FE40FC84FC84FC849488F8 +:20C4A00020202320A9A9A9A8A9A8A8BBC80000004020FE00FC04FC00FC0810FE2020A0404E +:20C4C00020202023AAACA9AAA8A9A8B8C8000700402020FE0294080400FC20202020FE0016 +:20C4E00020232222ABAAAAAAAAAAAABACA04040800FE0202FE10929292FE10929292FE02F0 +:20C5000020202320A8ABAAACA8ABA8B8C80102008888FE8800FE022420FE70A8A824222073 +:20C5200020232020ABAAAAABA8A8AFB8C900000300FE5050FE5252FE0040FE889060D8047B +:20C540000121213F00003F202F222F242D424588000808F82824FE20A424A898122A46829C +:20C560000121213F001F11111F11111F01484887000808F800F01010F01010F0008412F2E0 +:20C580000121213F02043F213F213F02040830C0000808F80000F808F808F890A8FA8A7EDC +:20C5A0000121213F020C37C03E223E223E222226000808F88060D80608484848480828105E +:20C5C00011101013545554575455555E64080300088890FC40F840FE8000FC202020FE008C +:20C5E00020212020ABA8A9AAA8AFA8B9C90001062024A820FEA8240240FE8808906098045A +:20C6000020202023A8A8A9A9AAABA8B9C9020300844448FE8484084A529C84080852DE4215 +:20C6200010111111555555555555555D6202040800FE1212FE007E42427E427E42427E42F3 +:20C6400020232027A9A9AFA9ABADA8B9CA04080038C040FC50545854544CE05048444240B5 +:20C6600001417F02FF001F101F007F404F484F400004FC00FE00F010F000FC04E424E40CDF +:20C6800020222122ACA9AEABAAABAABBCA02020240485048A41806F808F808F808082810BB +:20C6A00010111010575455555555555C6700000020FC8850FE00FC04FC04FC20FE202020B6 +:20C6C00020212023A8A9AAA9A9A9AABDC80102042024A8FEA824220404DE44549E040404AA +:20C6E00020272022A9AAADA8ABAAAABBCA010F0020A4A8921408F402F80808F80810FE004F +:20C7000001417D49516B4D596D4B596959417F000004F42444AC3464B42C64A46404FC0428 +:20C7200001417F00243A221E203E48087F1422410004FC007C042810FE12505E50B09E00E2 +:20C74000213F087E083E223E223E223E22FF244208F800FE10207C44545454545428448286 +:20C760000808102048081030509010101010101000000000000000000000000000000000A9 +:20C7800008081023480810305090101011111214402020FE808080FC848484840404281034 +:20C7A0000809112149091131519111111111171000F8080808F8080808F808080808FE001F +:20C7C000080811214A0C13325293121213101010808000FC0404E42424E42424E4042810B4 +:20C7E000090810204B081031509013101010101004848800FE2020FC2020FE2020202020F9 +:20C80000080810214B081033509011131410111620408810E04088FC8480F80890609806C4 +:20C820001010204790122161AF20212122242820404040FC40484850FEE050504844424046 +:20C84000080811214909173050911111121418102020203C2020FE0020203C20A0603E00F8 +:20C8600008091020480B123252921212121212122024A4A820FE0202FA8A8A8AFA020A043C +:20C88000080813224B0A133057901013101017104080F808F808F800FC4040F84040FC00C2 +:20C8A000080813204A0911325093101111111110083CC0044428FC2020FE20242424FC041E +:20C8C0001115254597102760A7212721212F202008484850DE14E414D414D40808D4244222 +:20C8E00012142F489F182F64A22F242724282A3110109090BEA4D41414D4148888949422AE +:20C900002E2A4E4A8E1A2E64AF34272427242724E0A0EEA0E0A0FE44F484E484E484F40815 +:20C92000040408102044040810204404081020400000000000000000000000000000000077 +:20C940000044281028488808182848880808502000000000000000000000000000000000CB +:20C96000004428102B488808182848880909522480808080F09090909090909212120E008C +:20C98000004528102848880B182848880808502000FC2020202020FE2020202020202020ED +:20C9A000004428112949890919294989090A5224201010FE0000000000000000000000001B +:20C9C00000472810294989091828488B0808502000F01010101010FC040404F404042810C5 +:20C9E000004528102848880B182848880808532000FC4444444444FC848484848484FE00C2 +:20CA000000442810294B880818284888090952244040808804FE02909090909012120E0070 +:20CA20000045291129498909192949880808502000FC242424FC242424FC24202020202050 +:20CA4000004429112A4D890919294989090950208080FC0404F4141414F404281202FE0053 +:20CA60000044281328488B0A1A2B488809095224909090FC9494FC9090FE92921A14101035 +:20CA8000004428102B488909192B49890A0A542028242420FE20242424A82810122A468279 +:20CAA0000088502152941110305790101112A7424040A0100806F00000FC40801008FC0441 +:20CAC0000088532254901013305190101010A0404020FE02141010FE1010909010105020CF +:20CAE000008857205192121332569A131212A246001090901010D854549292121010502058 +:20CB0000028A522352921213305093101010A740202428B02022A21E4040FC404040FE0089 +:20CB20000045291129488B0A1A2B4A8A0B0A522200F80808F800FC0404FC0404FC041408AA +:20CB40000089572151911F11335395151911A14184C404141414D4141494540404041408F2 +:20CB60000088502152951010375092121418A1404040A01008F64040FC40504844444080B3 +:20CB80000088502051921510305092111110A7404040A0A01008F600884848501020FE0006 +:20CBA00000442B102849880819284889090951214020FE0000FC0000FC0000FC0404FC0405 +:20CBC000004428112B4888091A28498A0808512640408804FE02884442F888502050880650 +:20CBE0000088532051921710335292121310A0404040FCA01008FE08C8484848C808281022 +:20CC0000008B522253921213305790111214A04000F84848F84848F840FCE050484640405B +:20CC2000008B522252931010305192101010A14600FE525252FE2040FC04885020408000BC +:20CC40000090532252931212335090101011A24400409C04049C0404FC9090909012120EA6 +:20CC60000088502152951010375090131212A3424040A01008F64040FC4040F80808F8084F +:20CC80000088572051911214305097101010A0408040FC001010A8440040FE404040404020 +:20CCA0000097512151971414345791111111A5422020203E42449010105452529210502047 +:20CCC0000189512751911117345494171410A040001E12D2121E12D2525E52D252222A4445 +:20CCE0000090572051921413325392131210A7404040FCE0504846F808F808F80800FE00B8 +:20CD0000008B522253921213305792121212A34200F84848F84848F800FE40442890080686 +:20CD20000097542754971013325392131212A24200FC44FC44FC00F808F808F808082810E5 +:20CD4000008B522253921212325292121212A44800FC2424FC00FC8484FC84FC8484FC844B +:20CD6000008B502057901112345097101112AC4000F89060FCA428206040FCE0504846400A +:20CD8000004528102B488909192949880B08502020FC8850FE00FC04FC04FC20FE2020200F +:20CDA0000088532150971013325392131111A24C8040F810A0FE00F808F808F82022221E53 +:20CDC000009F582A69AB28286AAA2B282829A95200FE002848EE9284A0A8E88894142442E3 +:20CDE000009057205592171A335293101214A9404040FCA01408FC0AF808F8404844448017 +:20CE00000293542967A5252765A527252525A448009E8A0AD26640D45E64C4445E4444C42A +:20CE20000097502F50971514375097101F10A5483CC040FE40FC54E4FC40FC40FE002492A8 +:20CE4000018F5127549711113352971A1312A34210FE10BCA4BC4020FE20FC20FC20FE008F +:20CE60001010101E122222528A0404080810204010101010FE1090909090FE1010101010CE +:20CE8000007E4A4A7E4A4A7E08FF182C2A4A880820207C44A81020D01E226494081020C0C9 +:20CEA0002020203C244546A4140808101020408020205048A4FA88F888F8A29488A4C48043 +:20CEC000020F34031D7F40BF013F213F213F102000F0608000FE02FC00F808F808F8100863 +:20CEE0000404040F0810304884020102040830C0000000F0101020204080008040201806F4 +:20CF00002020203E44488010101010121418100000000000000000000000000000000000D9 +:20CF20002021203C4448A120202021212A34200100F810204080FE92929212222242940836 +:20CF40002020203B485282222223202028302000404040FC4048484848F8484042423E009D +:20CF60002020203D4648802021202024283020008080FC0000F80000F80808080A0A0602C9 +:20CF80002020213C444880232020202428302100083CE020202020FE202020202020FC006A +:20CFA0002020213C444883202020202428302102083CE0202020FE202050505088880402DE +:20CFC000202021394A5480232020202029312204808000FE004040FC44448484040428102C +:20CFE0002020203C454B802021212125293121012020408804FE0200FC0404040404FC0445 +:20D000002020203B4A528222222222222A322202404080FC0404F494949494F404041408CD +:20D020002020233C444BA22421202023283020002020FE2020FE0204F81020FE2020A04038 +:20D040002020203C454AA020232021212A3420002020508804FA2020FE2028242222A040FE +:20D060002021213D4549A121202121212931210100FC0404FC0404FC0012D4181052920EBE +:20D080002020273849528423222322232A3027004040FCE0504846F808F808F80800FE006C +:20D0A0002023223E474AA2232023212028302007A02E2222AE2222FE20FE04885020D8067A +:20D0C000212127394853822322232023283122041010FC1000F808F808F840FCA010080649 +:20D0E000222127384B50872123242823293127000810FC40F880FC00F88888F80808FE0062 +:20D100002020233C4448A12121202320293023008888FE88F820FC24FC20FE20FC20FE0000 +:20D120002222273A4A578027242724272C3424048888C8909ED424D454D454C8485464C20C +:20D140002023223B4A528120202320202B30210200DE52DE1052CE0088FE8888FE88040291 +:20D160002027223B485F8A232127212F29332D0140FC48F840FEAAB810FC10FE2810488659 +:20D1800001003F202022222222232222224241800080FE0000000418608000020202FE007D +:20D1A00001003F20202F20203F212122424488100080FE0000FC8080FE40404042423E00C5 +:20D1C00001003F20203F20202F242221404186380080FE8080FC8080F010204080601806A3 +:20D1E00001003F222227283724242724244443800080FE0000F808C84848C8281202FE008F +:20D2000001003F202222242D34242425264444840080FE00202020FE70A8A8242220202004 +:20D2200001003F24223F20202F20203F204040800080FE1020FC8080F88080FE808080807B +:20D2400001003F22223F222320272427444488100080FE1010FE10F000F808F82010080642 +:20D2600001003F20202F2122242F3427244740800080FE0080FC201088F690F090F2827E39 +:20D2800001003F20222C28282E28282F41428C300080FE0080B88888B88888F840201806A0 +:20D2A00001003F2021272427242721223F4040800080FE8000FC44FC84FC2020FE20202056 +:20D2C000003F202F203F212F242F34244441820C80FE80F888FE08F810F816909060100821 +:20D2E00001003F222F222F223F24272444488A110080FE10901EA424D41494888894A4424B +:20D30000003F243F2427202F282F203F404F803F80FE10FE10F080F888F880FC80F880FED7 +:20D32000003F202F282F282F202F203F4853803F80FE00F888F888F880F880FE88E480FE53 +:20D34000003F242F31222F2A2F2A2F2A4A4A881180FE003C1424CC80A8BEC888BE88888866 +:20D36000003F202F2027242525272027404F820480FE40FE00FC04F414FC00FC00FE48C421 +:20D38000003F22242D362424202724274447840480FE50FC90FC90FC00F808F808F80818BE +:20D3A000101010101854505090101010101010100000000000000000000000000000000021 +:20D3C000101017101854505090101111121214180000FC8484848484848404040404281008 +:20D3E000101010101B545050911010101010101010101010FE10101010909010101050209F +:20D40000101013101854505790101010101010101078C040404040FE404040404040404070 +:20D420001013101854505790101010111112141800FC40404040FE40A0A0A02022221E00EA +:20D4400010101017185450579212111010101116404040FE404040F8080810A040A0180632 +:20D46000101312121A565252921212121312131000FC000888505020205050880800FE00A7 +:20D48000101010101B565252921213121010101020202020FE2222222222FE222020202066 +:20D4A00010101011195650509310101010101010808080FC20202020FE202020202020203F +:20D4C0001111111A5451509013101010101010100000FC0000F80000F80808080A0A0602D7 +:20D4E0001111111119555157911111111111111100080810204000FE4020201008448200EE +:20D50000101010185552549111111111111110104040A0A0100806F0101050200404FC004F +:20D520001011111955525294181011111217121020202010104848448280100808FC040008 +:20D54000101010101B545050901010101010101040202000FE4040605048444440404040FE +:20D560001013101018545057911111111111171000F88888888888F8080808080808FE0082 +:20D58000101010101B545050911111111111111120202020FE202020FC0404040404FC0446 +:20D5A000101010101B545050901011121410101020282420FE207070A8A824222020202075 +:20D5C000101310101A555150971010101010101000F8404048485040FE404040404040409B +:20D5E000101011111955515191111111101013100000FC040404FC040404FC040000FE00C4 +:20D60000101010131A5652529217101010111214404040F84848484848FE40A0A0100806E7 +:20D6200010101018555152901010101010101010808080FE4040407C4040407E40404040A2 +:20D640001011111119555151911111111112121400FC040404FC00404448704042423E0028 +:20D6600010101013185453529213101011111214909090FC9494FC9090FE92921A141010E9 +:20D680001013101018555152941111111111111100FC84848404140800FC04040404FC0478 +:20D6A0001017121118545156901310101710101000F80810A040B04E40F84040FC404040A1 +:20D6C00010101018545153901011111111111111202040408804FE0200FC04040404FC049B +:20D6E00020202730A8A0AFA2222425282F202021101090107E12D212122222A2C24294080B +:20D70000101312121A565352921212121414191200FE20282420FE202050505088880402C4 +:20D720002027242435ADA5A5A52525212222242804C44454545454545454540484441408FA +:20D740001011111119545150901111111111101020242424FC00FC0404FC00000202FE00E9 +:20D76000101011111A5453529213121213101010808000FC0404E42424E42424E4042810CC +:20D78000101010111B54505091121511111111118080F80810A040A01806F8080808F8086E +:20D7A0001013121C54535090111110101710101000FE024440FC80A020FC2020FE202020AE +:20D7C000101013185453529411101013101010102020FE2020FE0204F81020FE2020A04025 +:20D7E000101013101855515191101010111210102020FE2020FC2424FC2070A82422202057 +:20D80000101212121A565250901011101010131080FCA4A4A890A8C62020FC202020FE00A8 +:20D820002027242437ACA4A7A020272020202F2000FC4444FC4444FC4040FC404040FE0057 +:20D840002027242434AFA4A4A42526242424272400FC444444FC44C4E45444444404FC0494 +:20D860001011111119545352921213121212111000F80808F800FC444444FC000202FE007F +:20D8800011101013185453529213101011121410088890FC2424FC2020FE62A22A242020F7 +:20D8A000101010111B545051921011121010111640408804FE02884442F888502050880623 +:20D8C0002027242435ACA5A4A72424242425272000FE2020FC2024A8FE2050488404FE008A +:20D8E000101013101857505093101017101010102020FE2020FE8850FE2020FE20202020BC +:20D90000101010171854505390101017101010109090909E9090909C9090909E9090909082 +:20D92000101110101857525292121212121212122024A4A820FE0202FA8A8A8AFA020A042F +:20D94000101312121A575252931212121212121200FE028A52FE4222FE828282FA020A048E +:20D96000101312121A565253921212121212121400FE2222FA2222FE02FA8A8AFA020A04A1 +:20D98000101010111A54515290111010121214108080FC5454A42444940840A4AA8A780050 +:20D9A000101013185551529410101710101010108040FC001010A8440040FE4040404040C3 +:20D9C0001011111119555151901312121212171000F80808F80808F800FC94949494FE0090 +:20D9E000101011195550539011111111111010132020FC24FC20FE00FC042424245088040B +:20DA00002027242437A8A3A0A72122232020202000BCA4A4BC00F800FC0000F8080850209C +:20DA20001013121A56535090171010101111121400FC949494FC8040FE80F88808082810C5 +:20DA400020242434AFA0AFA0202724242424242440444444FC00FE4080FCA4A4A4A4A40C6B +:20DA600020212731A9A1A7A1232325252921212188C808082A2AAC48088854141424244221 +:20DA80001111111A5551519111101011121011160000FE00FC04FC04FC80FC08906098061A +:20DAA000101017101B54575091131017101215104040FC40F840FE8010E048FC4448448001 +:20DAC0002120202730ABA0A7A0232021222C202010A000FEA0F8A8FEA8F8A0B0A8A6A0A0A0 +:20DAE0002027242534AFA4A5A42525252529293120FE20FC24FE24FC20FC24FC24FC242C87 +:20DB00001013121B56535097101312131012141000F808F808F840FE00F808F8404844C0DD +:20DB20002121232236ABA2A2A3222223222524284020FE2020FC2020FC2020FE0024929240 +:20DB4000101110101B545151911111101110131020FC8850FE00FC24FC24FC20FC20FE0004 +:20DB600021212731ABA5A9A027202222222528301010BC10B8541200FC4440784040FE00C8 +:20DB8000202F2037ACA5A5A524272023202F222440FE00FC04F414F404FC00F800FE48C4E5 +:20DBA000111711131A575057941111111111111108FE08FC94FC00FE02F808F808F808F864 +:20DBC000003F0101FF02040931C111112141050200F80000FE804020180690482424000065 +:20DBE000007B48514A4D6850414619E11121450240FC80F820FC88F888C0300E90482400F6 +:20DC0000201700404040405F404040404040404000FC0404040404F4040404040404140836 +:20DC2000201700405F4040404F4040405F40404000FC0404F4040404E4040404F404140818 +:20DC4000201701415F41414F41415F414141414000FC0404F40404E40404F4141454240C6A +:20DC600020170242425F4444484951526742404000FC040404F4048484044424F41414080B +:20DC800020170042415F4044424142444840404000FC040404F4444484048444440414089E +:20DCA00020170042415F4040474444444850404000FC040404F40404C444445434041408A8 +:20DCC000201700484445405C4444454A5140404000FC044444F44444A4941404F404140810 +:20DCE0002017004047444447404F48484F40404000FC0404C44444C404E42424E404140821 +:20DD0000201700405F51515F51535559515F404000FC0404F41414F41494543414F4040C4E +:20DD2000201700444748516F494F494F4141404000FC0404C48404E424E424E41414F40C7B +:20DD4000201702414F484F484F49484A4C48404000FC0404E424E424E414A4442414040CA1 +:20DD600020170040405F404E4A4E40465841424000FC84A494F484A4A4A4C454B414040CBA +:20DD80002017004F484F484F405F505F505F404000FC04E424E424E404F414F414F4040C46 +:20DDA000201700424C484E484F4242444448504000FC0404E424E424E48484949474040CE1 +:20DDC000201700405F4A455F504740464142444800FC04E4042444F414C444840484442C77 +:20DDE000201700405F515F505C504F484F484F4800FC04648404F4845434E424E424E42CD0 +:20DE000020170048445E48494E4A4A4A4A52566000FC044444A4A4140C4424048444240C7E +:20DE20002017004F484F484F484F415F4142444800FC04E424E424E424E444F40484442CBC +:20DE4000201700405E424A444857614F4142445800FC048494A44C5424D40CE40484442C73 +:20DE60002013114F415F42444F404F4A4A5F404000FC04E404F40444E404E4A4A4F4140850 +:20DE80002017015F414F484F484F484F487F444800FC04F404E424E424E424E424FC442CBF +:20DEA000201700514A5F4455555F44484952404000FC044444749424444444A414041408E5 +:20DEC0002017005C447F525E525E537E4243404000FC04447C5494145424A45494041408D6 +:20DEE0000101011109090103050931010101010100000000000000000000000000000000B4 +:20DF0000000808080F0000007F0808081010204010101010F0101010F01010101010101003 +:20DF200004242424243C0504FC2424242444840520282424203EE02424282810324A860235 +:20DF400000201010804048081010E0202020200000000000000000000000000000000000F1 +:20DF600000201111824441101020E02122222100808000FE0000F808106080000202FE00C2 +:20DF80000023121282424A0B1212E2222222210000F80808080808F8000000020202FE0078 +:20DFA00000271212824149091010E0202021220C00F8088848501010A0A04040A0100806B4 +:20DFC00000201013804048091010E02720202000202020FE202020FC202020FE20202020CE +:20DFE00000201310804047111121E121222224080000F8000000FC202020202022221E002C +:20E0000000201010874048081111E2242820200040404040FE40E0E05050484442404040ED +:20E020000027101082424A0A1213E0202020200000FE4040407C444444FC040404042810B2 +:20E040000020101780424A0A1213E02020202000404040FC4048484848F8484042423E0080 +:20E060000023121282424A0B1212E2222223220000FC0404040404FC0404040404FC040091 +:20E0800000201714844444171424E424242724000000FC04040404F40404040404FC04004F +:20E0A00000201010874048081010E0202020200080404000FE8080C0A0908888808080808B +:20E0C00000201017814149091110E0202021220C804040FC1010101010A0A040A0100806CB +:20E0E00000201017804049091111E12122222408804040FC0000F0101010101212120E00C3 +:20E1000000221111804740101020E021212224084040404040FC444484A494140404281030 +:20E1200000472425058645541424E62524242404109090107E1212929292921222224A842A +:20E1400001211111874141111121E1212121210108080808FE08080808F808080808F80873 +:20E1600000201010874040101121E2242820200040504840FC40E0E0505048444240404066 +:20E1800001211111874149091112E2222424291020101000FE4040484850506242C23E00E7 +:20E1A0000020101080434A0A1213E2222224240840407E4040FC040404FC040000000000E7 +:20E1C0000020101382424A0A1217E02020212204404040F84848484848FE40A0A010080698 +:20E1E00000201714844444141425E526242427040000FCA4A4A4A4A4A4241C040404FC04DD +:20E200000121131284484212132EE222222221000000FC00404078C84848485A4202FE00BD +:20E2200000201010814244101320E021202020004040A0A010482620F8081010A040202055 +:20E2400000211614844444141425E6242121220400003CA4A4A4A4A4A4A4B4A82020202014 +:20E2600000201714844444171020E22224282100083CC000404040FE40404844424240807D +:20E2800000201017804041121720E02122272200804040FE40800810E040800804FE0200FF +:20E2A0000020121181404B081010E72020202000404048485040F8404040FC4040404040EC +:20E2C00000201017844842121222E32222222100804040FC04080010204080040404FC0039 +:20E2E00000271010804744141427E020202025020888888888880810109094A4A2BE020014 +:20E300000023121282434A0A1312E2222222230200FC040404FC2020FE202010128A0602D5 +:20E3200000271010804041161023E0202020270000F810206098040200FC40404040FE00C5 +:20E3400000271010834242131222E32220202F0000FC0000F80808F80808F8080000FE00AA +:20E3600000201710814143151921E121212121014040FE8000FC0404FC0404FC0404140876 +:20E3800000402F22028342541625E820212224080202C21212D252525252929202020A04E5 +:20E3A00000201017804251101F20E02121222408404040FC40485040FEA0A0101008040204 +:20E3C0000020101080434A0A1212E2222021220440407E4040F8084848484848A0100804B5 +:20E3E00000271414844447141424E4252624270400FC04444444FC4444A494140404FC0451 +:20E4000000271414844444141424E4242424270400FE0202F29292929292F2920202FE0284 +:20E4200000221213844040171021E12224282000404040FC404040FEE05050484442404092 +:20E440000020131282424B0A1212E322222223024080FC040404FC040404FC040404FC04F4 +:20E460000020101183424A0A1212E22222222F0040408000FC949494949494949494FE0079 +:20E4800000201011824441101027E020212227024040A0100806F00000FC40801008FC047F +:20E4A00000201014824040111224E020212122049090909294989098949290901212120E47 +:20E4C00000201111824443121223E22223202000808000FC0404E42424E42424E4042810C7 +:20E4E00001211113844051161023E024272020000000F810A040B04E40FC4040FE404040AD +:20E500000241212F008442521121E22224283000040404E49494949414149494444414086A +:20E520000044222200804E521222E222232220004040407C50901010FE101090101010106C +:20E5400000271010834040171020EF222121200000F80808F80808F81010FE1010105020F1 +:20E5600001211111874242121224E221222224080000001ED252525252929212925E5200E1 +:20E5800000402F20008744541720E021222C20004040FE4040FC4444FC40E050484640402B +:20E5A00000271010834040171020E3222222230200FC4040F88888FE0000F8080808F808CA +:20E5C00000201017804241111720E12122242800404040FC40484850FEE0505048444240D1 +:20E5E00000271414854444141524E4242424270400FC4444F444E444F45454744444FC047B +:20E6000000231212824243101022E2222225281000F808080808F84040407C404040FE00DD +:20E620000021111181404B0A1213E2222322220200F80808F800FC0404FC0404FC041408CB +:20E6400000221212834048091214E0232020200040484848F840A010884640F01020204049 +:20E6600000201312824342121222EF20212224081038C00000FC20202020FE0020100804CC +:20E680000221101182404F111227EA22222220000810E0100880FE4040FC444454484040BD +:20E6A0000121111282474A121223E220212224080000F01020FC444444FCA4A02022221EA0 +:20E6C00000201714884340101721E121222224088040FC0408F00000FC20202024241C00B2 +:20E6E00000201710804F40111326EA23222223028088E890A0FE8000F80808F80808F80856 +:20E7000001211711814149091111E127202021020808FE0808F80808F80808FE0090080446 +:20E72000024222220F824256172AEA3222222202000C704040407E4848C848484848488861 +:20E74000024222220F824256172AEA322222220208282828A444549210A0202844FC440079 +:20E7600000201310804740111022E127202021064040F84040FC0428A02020FC50880404C1 +:20E78000004F202102844A411224E8212224200000FE80844468B030A868A4242220A040AB +:20E7A00000271414874444171020EF222222240800FC4444FC4444FC0000FE080808080809 +:20E7C00000231212834047141427E4242720200000F80808F840FC4444FC4444FC42423E24 +:20E7E00000201011824441101023E02221212F004040A0100806F04040F840484850FE0057 +:20E8000000271414844744141427E42424282A1100BEAAAAAAAAAAAABEA0A0A0A2A2A21E60 +:20E8200000402724088340501720E222242821008040FE0204F00000FC40504844444080BA +:20E8400000201714804342121322E223222020008040FC4440F84848F84848F8484040406A +:20E8600000402724088342521322E223222223028040FE0204F80808F80000FC0404FC0483 +:20E8800000231010834040171024E2212224210000F80808F80808FE4044E8504846408065 +:20E8A00000472424078444541726E62A2A32200002E2222AEA8A8A8AEAAAAAAAA2E28A84AB +:20E8C00000221217824242121320E72021222C00909090FE9090F000FC40FEE05048464036 +:20E8E00000271010874444141720E02720202F0000FCA0A0FCA4A4A4FC4040FC4040FE00E7 +:20E9000000271010874444141424E4242424270400FE4080FE9292F29292F2929292FE023C +:20E92000432E2282424F0226274ACA52424242039010101252D4589010A8282848448402C9 +:20E9400000211614844744141720E7212020231C40405C44445C4444FC40F810A060980661 +:20E960000020131283424B081710E023202027004080F808F808F800FC4040F84040FC0001 +:20E9800042222584485702222F42CB4A52424A0400007CA424242428A8281090A828448285 +:20E9A00000211112854041121423E22222222F0010100804FA88082810F8A8A8A8A8FE00C9 +:20E9C0000241212F008744541724E42724242504080810FE00C45454D45454D45444548880 +:20E9E00000402724088340531223E223222027008040FC0408F800F808F808F80800FC000F +:20EA00000023121283424B0A1213E2222524281300FC0404FC00FC4088FC2420FC2020FEAA +:20EA20000023121283424A0A1212E2222424281000FC2424FC00FC8484FC84FC8484FC8486 +:20EA40000484441F8444441E2444C45F4444440420207848907C5454547C404042423E0080 +:20EA600000201710834047111225E023202126004040FC40F880FC1068C640F8E058444031 +:20EA800000201310804F40111320E72424242F004040FC4040FE8010F808FCA4A4A4FE00EE +:20EAA00000231111814141171027E0222122240800FC08F808F80EF808BCA4A42890A8469B +:20EAC00001211711804740111225E127212122041010FC1048FCA010081410FE10101010A3 +:20EAE00001211711804F48101720E02320202F001010FE1000FE0200FC4040F85048FE00C4 +:20EB000000402F20078447541724E02F222121005048FE40FC44FC44FC4408FE08082810AE +:20EB200000271010874444171020E72021222C0000FCA0A0FCA4A4FC4040FCE050484640CC +:20EB40000023121282434A0A1212E2232224240800FE00FC00FEA890C88608FE8848081846 +:20EB600000231213824340171024E2212620220100F808F808F800BC84A4948CB4849408C1 +:20EB800000271415844445141425E4242524270400FE02FA42C22A6AB22A6AAA2242FE0269 +:20EBA00002221315884047101027E0202F2020001010DE2884788080F88080F88484847C2A +:20EBC00000201312834243121320E0272021220C4080F808F808F808F85048FEA010080621 +:20EBE0000142252000834C531020E72022212F00100814A0E01806F84040FC404850FE00AE +:20EC000000201714854447141524E525252929114020FE20FC24FE24FC20FC040404FC04D6 +:20EC200000402722018F48501721E121212222048040FC1020FE8244FC0000F80808281094 +:20EC40000027141083424B0A1310E0272021220400FC0400F808F808F88040FC00100804EE +:20EC600001211711814F40171427E427202122041010FC1010FE40FC44FC44FC0010080464 +:20EC8000014F21200F8851431020E7202224290010FE1000FE8214E04088FC44504844801C +:20ECA00001412F210087405F1027E025252628101010FE1040FC44FE44FC4064545444441D +:20ECC0000141272103854940102FE1222120230C1010BC10B854128080FC101020C03008A9 +:20ECE00000201710874447141720E32223222302A0A0FEA0FCA4FCA4FC00F808F808F808E7 +:20ED000000201017844445141424E52427282810407C40FE4278C43C08F024A8FE20A0404D +:20ED200000271417844741121720E32F2022250800FC44FC44FC0010E0C804FE4248448225 +:20ED400000201312834047141720E020252528004040F848F840FC44FC4080484414F00023 +:20ED60004222258448570024324AC841435C4000101010A03E4424A4A4A8A810A8284482AB +:20ED800000492522068B4252162BE22222222A042020FA2428FE2040FC44447C44447C44DB +:20EDA00000492522068A4352162AE22222222A042020FC205088FE08E8A8A8E8A8082810A6 +:20EDC00000201714844744141724E525252929118040FCA0A0FCA4A4FC0024A83024A41CDC +:20EDE0000442222F048447551525E525292B30212020207E80007C1410505C505050BE0017 +:20EE0000004720210F8444571427E424272C200008888810DE94A494949494C88894A4C2AE +:20EE200001412F21018740571424E72422202F040404E4043EC404E45454C44484E414085B +:20EE40000444242F048744571424EF202528300080829CD090909E949494D41414A424443D +:20EE600004845F04955565002F48CF484F4848082020FC2068AA2600F808F808F808281017 +:20EE8000014E2222028F42531626EA222222220210105438107C4444FC44447C4444544825 +:20EEA0000023111087404B0A1312E3202320270040F810A0FC00F848F848F840F840FE008E +:20EEC00007241714854447141427E425292F3103FC04FC00F810FE20609C8408DE08081838 +:20EEE00002422F22028F4A5A1F22E72A3222220210109C2448BEA2AAAA2A2AAA88142242A4 +:20EF000000402F29098F49591F29E9292F2920002824407EC8487E48487E4848487E4040D1 +:20EF200000201714874447101720E3222321200FA0A0FCA4FCA4FC00FC00F808F810A0FE97 +:20EF4000024324270D9647541524E5242529291100F810FE4824FE00FC00FC00FC04FC04B1 +:20EF6000004F2027048545571023E2232223200F40FE00FC04F414FC00F808F808F800FEF2 +:20EF800000271514874445141724E52424292A1020FE0890FC50FC54FE54FC50D854525074 +:20EFA0000047202F08834053102FE0272424240400FC40FE4258405800FE40FCA4A4A40C49 +:20EFC000012111128246561A1222E2222222220228AA6C28FE4428FE107C10FE10284482AE +:20EFE00000231213824340171427E427202F210280F808F808F800FC44FC44FC00FE1010E3 +:20F0000000271011814140171423E1262126210E40FE00F808F800FE02F88044B868A660C3 +:20F020000027101482444112172AE3222322230200BC84A494A42010FC20FC20FC20FE001E +:20F040000484441F845F511F315FC45F44444404101028448200EE22AA662266AA22AA447F +:20F0600001412527048A41521720E32027202F0000BC24A890A846A0BCA0B8A0BCA0FE007D +:20F0800000BF480F804F480F205CD75D555C552E80FC00F800F808F8809CD4545C96562236 +:20F0A000402021824D400E2A2E40CF494F49490840A01008F600EEAAEE00FE22FE222A0437 +:20F0C00002211711864342131223E127212F22044850FC504CF848F848F810FC10FE080446 +:20F0E000402F288F484F023F204FC84F424A520600BE8890BEA222EA2AAAAAAA089452222E +:20F1000047202F8843450F252742CF4A4F425F02FC40FE425800BC24243CA4A4BC24A44C75 +:20F120000201017F408000000000000000000000000000FE02040000000000000000000088 +:20F140000201017F4082021F0202040408102040000000FE020400E02020202022221E00FF +:20F1600002017F4080007F0404081F28C8080F080000FE020400FC000000F8080808F80880 +:20F180000201017F40810008484848890E18E700000000FE02049090244282021010F00097 +:20F1A00002017F42827F040F182F488F080808080000FE0204F800F010F010F010105020BD +:20F1C00002017F40803F202F203F2424444586040000FE0204F800F000FC885020180600A7 +:20F1E00002017F41941423003F213F213F2121200000FE029428E800F808F808F808281044 +:20F20000017F449F043F04FF081F20C80F007F0000FE42F440F840FE20D04846F808A810C8 +:20F22000017F449F043F04FF081721DF017F010300FE42F440F840FE20D008F600F80000F2 +:20F2400002017F408524243C04057C24242444840000FE02FC20F84848FE00FC8484FC8404 +:20F26000017F40817F04281F28CF080F0111250200FE0204FC4028F028E620E000100800BE +:20F28000017F449F043F04FF0A112FC2041C650600FE42F440F840FE2010E88E5020180650 +:20F2A000017F40BF243F00FF001F101F0518EA0C00FE02FC48F800FE00F010F00890601CCE +:20F2C000017F449F043F04FF081F28CF0109152300FE42F440F840FE20F028E600F000FC71 +:20F2E000017F449F043F04FF091F20DF001F101F00FE42F440F840FE20F008F600F010F048 +:20F30000002010100000F01010101010102847000000000000000000000000000000FE00F0 +:20F32000002310110102F310101011161028470000FC10101010FE30509010502000FE00F5 +:20F34000002010110102F0101710101010284700808080FC20202020FE2020202020FE000B +:20F36000002312120202F212121212121228470000FC0404F4949494F49404140800FE001B +:20F38000012111130204F0101010101010284700000000FE8080F88080FC80808000FE00F2 +:20F3A00002221314040AF21712121212112847000000FC404058E84868504404FC00FE0025 +:20F3C000002011110204F0111112141010284700808000FE02242028242222A04000FE006C +:20F3E0000444242F0404E4242428283221508F0000003CA4A4A4A4A4A4A4BCA40000FE00A6 +:20F40000002310100001F613101010171028470000F81020508804F8404040FC0000FE0023 +:20F42000002011120702F013121212131228470080801008FC0400F8080808F80800FE008D +:20F44000002312120302F21212141418102847003CC00000FE0000FC848484FC8400FE008B +:20F46000002010110200F11610111012131028478080FC089060982620FC2020FE2020FE23 +:20F4800000402F200704E7242724242424508F004844FE40FC44FC44FC4444540800FE0009 +:20F4A000004F20200704E4262524242425508F0000FE0000BCA4A4B4ACA4A4A4AC00FE001B +:20F4C000002010170002F1101112141110284700405048FC404850E0504844408000FE00F5 +:20F4E000002211110003F2121312121312122A474048485040F80808F80808F8082810FE3C +:20F50000094522260A02E2262A32222A25508F001010105252549028244442820000FE008B +:20F52000002112170001F21511121510112E4700801008FC04100804F80890609008FE0071 +:20F54000002013100007F11214131010171028474040F84040FC104844F84040FC0000FE7F +:20F56000002310170102F4101F1113101116284738C040FC50484480FE089060980400FE31 +:20F58000002017140302F21312131212132847008040FC04F01010F000F80808F800FE008D +:20F5A00000472023000FE0242221222421508F0000F808F808FE4044E85048444080FE0021 +:20F5C000004424240700EF20272424242424508F40444444FC00FE80FCA4A4A4A40C00FEB3 +:20F5E000002013120302F31017101310172847004080F808F808F800FC40F840FC00FE00C8 +:20F6000002412F200704E4252624272427508F000810FEA0FCA4A4241C04FC04FC00FE0071 +:20F62000004724240704E4272424272424548F0000BC8484BC0000BC0404A8102844FE0025 +:20F6400002422F220702EF242724242A29508F001010901EA4449414888894A24200FE0074 +:20F66000012711130107F0131213121712122A4710FC10F810FC40F848F848FE082810FE34 +:20F68000002312130203F017101412141211284700F808F808F800BC84A494A4940800FE8C +:20F6A000004724250405E6202724272427508F00807C2424A4544880FC44FC44FC00FE0091 +:20F6C000074427240702E72C3724272427548F00F808F808F840FC40F840F840FC00FE00EA +:20F6E000002211170102F41213141A1111122A47404850FC5048441090BC90507E1010FE49 +:20F70000004020270405E4272427282B3023508F407C40FE42F844FCC022D418749220FE18 +:20F72000044F29320F0AEA2F2A2A2F2A2A31508F003C141494A8A8BCC888BE88888808FE52 +:20F7400001422D25020DE3252923252925528F0010207CC4447C44447C28282A4680FE00EB +:20F7600000402F2A1401E720212621262126508F8040FE120C20FC804468B068A4A440FE5E +:20F78000024422270504E527242624262426508F489048F828C828F890D090D48CC400FECE +:20F7A00000007F000000003F000000007F0000000000F808080808F808080808F8080000DC +:20F7C00010FE107C10FE10007F00003F00007F0010FE107C10FE1000F80808F80808F8086C +:20F7E000080F101F00FF020D71020C710618E20100F010E020FE000890A0C0A09886800090 +:20F80000080F101F00FF02424375414F4162440800F010E020FE0010D21418D012924E203A +:20F82000003F20203F21212F212122224444881000F80808F80000E02020202022221E0031 +:20F84000003E222222223E2A2828282424424180007C444444447C00282444428200807E5D +:20F86000003F203F2024293022252C344444840700FC04FC2020FE2020FC84885020D806C3 +:20F88000003F203F202E2A2A2C2A2A2A4A4E880800FC04FC00FC08E8A8A8A8E8A8082810A6 +:20F8A0003F203F2023203F20202F21235E428A04FC04FC00F020FE40C0BE04887E08281015 +:20F8C0003F203F2224283022252C342444458604FC04FC10109C9090FE10909C90503E00DE +:20F8E000003F203F202528312429382B4849880B00FC04FC0024A8FCA82440FE8890708C16 +:20F900003F203F222F2027203F2A3F245F44BF08FC04FC20F880F080FCA87C107C107E100D +:20F92000007D0404047C4043407D040404042B1000FC08103048840200FC20202020FE00AB +:20F94000087F11320C1261003F003F203F000000007C442810284600F010F000F8085020BB +:20F9600000FB090909794141417909090B08502000FE080808F80808F808081EE8080808E3 +:20F98000282828FE2A2AFEA8A8FF29292D4A488820207C44887C5454547C404042423E00F9 +:20F9A00000F0171112F7848484F714141417A440001EC20202DE505050DE424242C25408F8 +:20F9C0007115714773153100FF101F007F444F411C441CD09C440C00FE10F000FC44E40C49 +:20F9E000010121212121213F010101010101010100000808080808F80800000000000000F1 +:20FA000010101010FD2624252448281028448400404080FC0404040484444404040428104A +:20FA200010101110FC24242525492911294584000000F808080808F8080000000202FE0068 +:20FA400010131010FC242427244828102844810200FE8888888888FE888888888888080881 +:20FA600020232020F8484F4888483011294A840800FC40404040FE40A0A0A02022221E0080 +:20FA800010111111FD252525254929112945850000FE000444282810102828448400FE0050 +:20FAA00010111111FD2525252549291129458500101010121214D8101010101252920E0078 +:20FAC00010101010FC2526242449281028448400202050508844222000FC040808101020A8 +:20FAE00010101011FD252525244828112E44840020202EF0202020FE2262A22A242020202E +:20FB000010111010FC27242424482810284582042020A0A020FE222242524A8A82021408B8 +:20FB200010111010FC242425244828102844830000F84848484848F8888888888888FE0002 +:20FB400010111010FC242724244828102844840000F808502010FE22242020202020A04021 +:20FB600010101111FD25252525492911294484000848282828080808080848941422428278 +:20FB800010101010FC24242424482810284485000000FC848484FC848484FC840000FE009A +:20FBA00010101010FD252525254929112945850120202020FC24242424FC24242424FC0465 +:20FBC00010111111FD252527254929112946820400DC5454545454FE5454545454D4244C71 +:20FBE00002013F000804FF02027F04081C030C700000F8002040FE0000FC20408080700864 +:20FC000020232020F8484C4A8A4A30102848870000FC909090929294949890909090FE00B2 +:20FC200020202023F848484B884B3010294982048080BCC05024D40C00FE909012120E0043 +:20FC400020212121F94A484B48905021314A4880202020FC202020FE70A8A824242220209B +:20FC60000201FF0414142442027F04081C030C700000FE405048440400FC204080807008D6 +:20FC800010101011FC2425262448281028448003402020FE0088040288885050205088066B +:20FCA00011101010FD242424244B28102945820404848800FE88888888FE888808080808A3 +:20FCC00010101011FD2624252448281328448400402020FE020418E040407EC04044443CA2 +:20FCE00010111111FD252525244829102844870000FC2424FC2424FC2020FC202020FE009F +:20FD000010101111FD25252427482911284484002020FC24FC24FC00FE8000FC0404281067 +:20FD200020212121F94948484B925222334A4A8200FC040404FC2020FE22528A0A020A047A +:20FD400011101011FD252525254929112945850100BC04242424FC2474AC24242404140861 +:20FD60001008402409721017027F04081C030C702020A8A42A30C00000FC204080807008C3 +:20FD800011101011FC2425252549281029468400088890FC2424FC2020FE62A22A242020EE +:20FDA00020232222FB4A4A4A8A4A32132A4C840800FC0404FC0018E038E03CE022221E003A +:20FDC00020272525F55556555595552526545484007E04047454545454547454040414085D +:20FDE00010101310FD24272425492911294585012020FE20FC20FE00FC04FC04FC04140824 +:20FE000010101310FC252424274828112A4484002020FE2020FC2020FE40A4A89088C680FA +:20FE200020202320F9484B4889483111294A82042020FE20FC24FE24FC20203E20A07E0007 +:20FE400010101010FC2424242549291129458501FC8484FC8484FC00FE0202FE0202FE0256 +:20FE600010101111FD25252525482913284484004080FC2424FC2444FC9010FE10101010F9 +:20FE800011101011FD252525254928102B448400048850FC2424FC2424FC2020FE2020201D +:20FEA0001010FE22641824C2013F2224212224200000FC44281028C600F888480888481875 +:20FEC00020212121F9494949884B32122A4A870000F80808F80808F800FC94949494FE0067 +:20FEE00020272221F84B48484F915122324C48833CC0442800FC8080FE00F8885020D806D9 +:20FF000010101310FD252524274A2910284484004020FE00FC04FC00FE02FC202020A04003 +:20FF2000007E2418FF294A98027F04081C03063820207EA4281028C600FC204080807008B7 +:20FF400010101310FD242724254929112B4585018888FE88FC88FE20FC24FC24FE041408BE +:20FF600021212721F84B4A4B8A4B3017284982041010FC1000F808F808F840FCA0100806EE +:20FF800010101111FD25252524492911294585012040FC54245404FC0012D4181052920EF0 +:20FFA00020232022F94B4A484B905021314A4C810EF0442408FE4240FE80FC442810688680 +:20FFC00020202322FC49494949915127304849824020FE0214E00000FC1010FE0090080426 +:20FFE00020212121F84B48484991512130484B81202424FC20FE0020FC2424FC2024FE02F5 +:020000040107F2 +:20000000083E087F1C2A493F21213F222740438C207EA428102844FE0000FE1020C0300C5E +:2000200020272022FA4F49494A9350253548488000FC407840FE00FC00FC045454042810F3 +:2000400010101310FD24272425492911294585012020FE2024A8FE00FC0474547404FC04ED +:2000600010131011FD25252425482B102845820000FE50FC5454FC00FC00FE20A824A24084 +:2000800020212023FA48484848905121314949802024A8FE02F88888F820FC2424342820B1 +:2000A00010111111FD252424254828132845820000FC24FC24FC4088F02044FE22242260DE +:2000C00020212020FB484949499151203348488020FC8850FE00FC04FC04FC20FE202020D0 +:2000E00010131011FC252525244B28112945850120FE20FC00FC04FC88FE00FC0404FC04F5 +:2001000020232023FA4A4A4B489151213149488320FE00FC04F494FC00F808F808F800FE58 +:20012000007C45447C437CA5243C02FF081C033C4020FC8850FE20FC202000FE2040C03832 +:2001400000F9A9A9F9AFAAFA4244FA49494AAC10003E2A2A3EAAAABE9090BE121292AA448C +:2001600020202724F754555654945425245455884020FE88DE88DCAA884090204884FC84B2 +:2001800021202322F948494848935021324C4880FC20FE22AC20AC009EF29ED2BE929E9241 +:2001A000003F080808101021410909112141050200F010203C04041408201008040400001A +:2001C000010911210001FF020C30C10909112502002010080000FE80601806201008080026 +:2001E000007F221111001F000001FF0101010502F80010102000E0408000FE00000000003D +:200200001010FE22641824C2003F0001FF0105020000FC44281028C600E08000FE00000031 +:2002200008047F123C08143E003F0001FF0105022040FC48F02050F800E08000FE000000EA +:20024000007F000000010101031DE1410101050200F81020408418608000000000000000ED +:20026000007F000020110905030101010101050200F810204080000000008040300C0000CD +:2002800000FC05091215151931D11111111150208080FC0404F4141414F404281202FE00E3 +:2002A00000F808484848487C04041CE444042B1000F8888888F8888888F888888888FE00E1 +:2002C00000F909494949497D05051DE54505291000FC545454545454948C040404FC0400CC +:2002E00000F80849494B4D7D05051DE545052911888888087E0808482828080808082810A9 +:2003000000F808494A4C4B7C04041DE444042B108080F8081020FC040404FC040404FC046B +:2003200000FB09484848487F04051CE44704281000FC04885020D82620FC2020FE202020DE +:20034000087F11320C12611F0008080F007F0000007C4428102846E0202020FC04C4140811 +:2003600000F80848494B487C05051DE5450529112020408804FE0200FC0404040404FC0431 +:2003800000F8084B4848487F04071CE445052A148080BCC05024D40C00FE909012120E0008 +:2003A00000F809494B4D497D05041FE444042810909414181032520E2020FE202020202039 +:2003C00000F808484948487C04071CE44404281184444800FE48484848FE48484848880818 +:2003E00000F310505352527A0B0A3ACA0A0A2A1200FE0000DE5252525AD65252525252D65E +:2004000000F80B484848487C04041CE7440428118888FE8888F88888F88888FE0088840475 +:2004200000F909494949497D04071CE44506281000FC2424FC2424FC20FE70A8242220204B +:2004400000F80848494A487C04041CE444042810504880FE9090FC9090FC909090FE808079 +:2004600000F80849484B487D06051CE445042813404884FE20FE88244288106284186080C0 +:2004800000794953486B50431F00080F007F0000203C20FEA4287080E02020FC04C4140816 +:2004A0007E2418FF294A98001F00080F007F0000203E48A810284600E02020FC04C41408F7 +:2004C000087F087E08FF101E225F80080F007F0020207E44A428102844E22020FC04D408FB +:2004E00000F909494949497C05051DE54505291140BC149454A44C00FC2424FC2424FC045A +:2005000000F809494949497D05051DE545062A142010FE0202FE00EE22AA662266AA22669A +:2005200000FB08494949497C05041FE444052A1000FE50FC5454FC00FC00FE20A824A240D3 +:2005400000F809494949497D05051CE4450529122040FC247C8C542454FC201054424A38D2 +:2005600003F213525252537A0A0B3ACA0C0F2811FE02FE00FC08FE1030CE4284EE84848CED +:2005800000FB08494A49497D05051CE5440728119498928E80FC24FC24FC88FC88FE880489 +:2005A00000F310515151507B080B38CB08092A1020FE00DC54DC88FE88FE88FE9488A4C2DB +:2005C0001010202444F8102040FC40001CE040000000000000000000000000000000000093 +:2005E0001011202444F8102340FC40001CE0400000FC2020202020FE202020202020A04035 +:200600001010202445F8102040FC40001CE0400008080808FE0808088848480808082810B3 +:200620001010202445FA102040FC40001DE14000404080FE0000FC08102040800202FE0039 +:200640001010202445F8102041FC40001CE1420440404040F848484848C848A8AA0A06027D +:200660001010202545F9112141FD41011DE24204201010FE000000000000000000000000A2 +:200680001010212444F8132040FC40001DE341000000FC000000FE202040408804FE020083 +:2006A0001011212545F9112141FD41011DE14100101010121214D8101010101252920E0020 +:2006C0001011202444F8132040FC40001CE0400000F808502010FE22242020202020A0404A +:2006E0001111212547F9112141FD41011DE1410108080808FE08080808F808080808F8080A +:20070000101222224AF7122242FA42021AE243004848484848FE4848484878000000FE0043 +:20072000101020204BF8102041F941011AE2440150484840FE8080FC444428281028448239 +:20074000101020214AFC132040F8410018E043008080F8081020FC040404FC040404FC04CB +:200760001010202348F8132242FB400019E14204909090FC9494FC9090FE92921A14101084 +:200780001010212545F9112040FD41011DE14100202024242424FC20202424242424FC0406 +:2007A0001010202445FB102041FD41011DE141012020408804FE0200FC0404040404FC0489 +:2007C0001010272049FA1D2047F8410318E040004040FCA01008F600FC8000F80808502059 +:2007E000101021224CF0112345F9410119E1410180803C0080807E08080808080808281040 +:20080000101020214AF8112640F940021BE040008080FC089060982620FC2020FE202020DC +:200820001013202445F9112141FD41011CE0400300FE2020FC2424FC2424FC20A040B00EA2 +:200840001011202444F9112141FD41011DE141012024A4A820FC0404FC0404FC040414082C +:200860001110202348F8132242FB400019E24400088890FC2424FC2020FE62A22A242020B3 +:200880001010212048FB102142F8410218E041062020FC2020FE884442F888502050880671 +:2008A0001010212444F9132041FD41011DE040002020FC508804FE08E82828E82808281000 +:2008C0001010202748F8102340F8400718E040009090909E9090909C9090909E909090905F +:2008E0001011202048FB122242FA42021AE242022024A4A820FE0202FA8A8A8AFA020A040C +:200900001011212545F9112140FD41011DE1410100FC0404FC0404FC0012D4181052920E3D +:200920001010212048FB112147F9410318E04300083CE02020FE2424FE2424FE2020FE00F6 +:200940001013202249F9172440FB410118E041061CE084444810FE0200F80810A040B00E2F +:20096000101021214AF5102146F8410119E141018888EC2A2848887E0000FC040404FC0445 +:20098000101221204BF8172142FD490119E1410040485040F880FC1008F41210502404FC87 +:2009A000101023224CF9112141F9410119E141014020FE0204F80808F80000FC0404FC043B +:2009C000111122244AF9112043FA42031AE243022424489048242400FC4444FC4444FC04C0 +:2009E0001010232444F8112141FD40031CE040008888FE88F820FC2424FC20FE20202020D9 +:200A0000111121214FF1112343FD490119E1410100003E22A2223EA262223E2222223E22AC +:200A20001011212149F9112140FB400119E1420400FC0404FC0404FC00FE20203C20A07E67 +:200A40002020274555F7252547F5450735C00003101010101452529210140810204080002E +:200A60001010212545F8132041FD41011DE040032020FC24FC20FE00FC042424245088041E +:200A80001011212149F9112140F840021AE4400000FC2424FC2424FC004024A28A887800B3 +:200AA000111121224AF2162242FA42021AE2420200FE1010FE9292FE9292FE90502058865F +:200AC000111121224AF61A2242FA42021AE2420200780808FE40407C9010FE10282844822F +:200AE0001012212544F8132141FD41011DE2440010207C44447C40407C44447C44807E0069 +:200B0000101322234AFB122243F843021BE2430200FC04FC20FE108A0600FC04FC04FC0478 +:200B20001013202249F8172041F9410119E1410100FC90949890FE00F80808F80808F808CA +:200B4000101027204BFA132243FA43021FE142044040FC40F808F808F808F808FE10080416 +:200B6000101322224AFB122242FA42031AE4440800FE00FC00FEA890C88608FE8848081856 +:200B80001010232049F9112043FA42021AE242024020FE00FC04FC00FE02FA8AFA020A04D6 +:200BA0001010232049F9112140FB42021AE242024020FE00542454FC20FE4292FA0A02067B +:200BC000111020204BF8102142F9410119E1470004848800FE00880402FC54545454FE009C +:200BE0001010202544F9102340FD40001DE24000885000FE50FC54FE54FC50D85452505032 +:200C0000101023224CF9112141F9410718E041024020FE0214E00000FC1010FE0090080431 +:200C20001013202545F9112041FC43001CE1420000FE50FC5454FC00FC00FE20A824A24068 +:200C40001011212149F9102342FB400118E0410600F808F808F800FC94FC00F890609806F5 +:200C60001011212545F9102041FC40031CE1420000FC24FC24FC4088F02044FE22242260C2 +:200C8000101720244AF4102146F843001BE0400700BC84A494A4508826C010648830C000F1 +:200CA0001112212445F9112141FC43001CE1460024482400FC24FC24FC20FE70A824222031 +:200CC0002222224F52F2272040F7450535C7050000FE10A07C4454545454545428244282DC +:200CE000101023204AF9132541F9410019E244002020FE508A04FE04FC04FC202422A240FA +:200D0000111020234AFA122243F8410119E14101048800FE22AA7222FE00FC04FC04FC0456 +:200D20001013202545F9112340FD41011DE1400300FE00FC24FC24FE00FC24FC24FC00FEA3 +:200D40001014222248F9102E42FA42021AE2450810FE92FE10FE00FE82FE80FE82FE00FEBD +:200D60001111212148FB122243F8470018E14600FC0404FC00DE5252DE20FE70A8242220DB +:200D8000101322224BF8172043FA430019E34D0100FC9494FC00FE00FC04FCA2140844820A +:200DA0002125274957F3252940F3420232C001060828BE48BE18AA4600F8084848B008042D +:200DC0000202040810207F2001020408103F1000000000101020C0800000002010F8080016 +:200DE0001121457911257D0501FF007C547C547D1020447810247C2410FE808852225A8604 +:200E000000000808081111222211110808080000000088888810102020101088888800006A +:200E20000811221108003F2121213F2121213F20881020108800F8080808F8080808F8084B +:200E400008112211081F101F003F21213F20201F8810201088F010F000F80808F80202FE8F +:200E60000000FE1010107C101010101EF04000000000FE101010101010101010101050201C +:200E80000001FD111111117D111111111DE2420400F01010101010101010101212120E0046 +:200EA0000000FC131010117C101310101CE04000404040FE4040FC4040FE42424A444040AD +:200EC0000000FC101111127D101010101DE1420410909088080404FA8888888808082810A7 +:200EE0000000FC131010107C101010101CE04106402020FE888888888850502050880402F0 +:200F00000000FD101010107C111010101CE043000000FC2020202020FC2028242420FE0052 +:200F20000000FD101011117D111111111CE040000000FE0808E828282828E8280808281087 +:200F40000000FC101310107C101011111DE2420490888880FEA0A0A4A4A8283222629E0085 +:200F60000000FC101010107C111111111DE14101202020203E202020FC0404040404FC0407 +:200F80000000FC101011117E101010101CE0400050545292909EF090909090908A8A868287 +:200FA0000000FC111111117D111111111DE14101202040FC04040404FC0404040404FC0454 +:200FC0000001FD111111117D111111111DE1410100FC040404FC2020FE202010124A860258 +:200FE0000202FA22272222FA2222223AE44409100000001ED252525252525252525E5280DB +:201000000003FD1111117D111111111DE340000000FE080808F80808F808081EE808080858 +:201020000000FC101310107C101710101CE1420488888888FE88888888FE0088840402021B +:2010400000017C1011117D111111111DE040010200FE2040FC0424242424244450880402AC +:201060000007F824242427F82121223AE448020100DE92929494D8949292929A949090106F +:201080000000F922242021FB25212139E141010180803C0080807E080808080808082810E7 +:2010A0000000F822212020F92224202039E102049090909294989098949290901212120EF6 +:2010C0000000F821232420F82122252139E101018080F80810A040A01806F8080808F80835 +:2010E00008081F2141091125027F013F0101FF000000FC040820100800FC00F82010FE00FC +:201100000003FA24202320F821212038E340000000FE024440FC80A020FC2020FE2020203C +:201120000004FA2220202EFA2222233AE2450800202020FE405090FE1010FE101010FE008F +:201140000101FB21212121F92121213BE04001020808FC0808F80808F80808FE009008048E +:201160000000FB20202021F921212338E04001028888FE88A820FC242424FE205088040278 +:201180000000FB20212227F82322223AE34000004040FCA01008FE08C8484848C80828102C +:2011A0000000F820232222FB2222223AE444091240407C40FC4470C0443C00F09092120E74 +:2011C0000001FD111111117D101111111DE1410100FC0404FC0404FC0012D4181052920EC9 +:2011E0000001F922202023F82021212238E0010620222224508804222024242850880402E1 +:201200000000FB22202120F823202139E24400004020FE0200FC0000FE2028242222A040AB +:201220000000FB22252121FA22232438E14102044020FE020400DE5252529A941012120EBF +:201240000007FC24212220F827202039E24C000000FC04A410084040FC40E0504846404088 +:201260000003FA22232222FB2222223AE244040800FC0404FC2020FE2020FC848484FC8495 +:201280000001FD111111117C101010101CE0400000FE027A027A0200FC84FC84FC84FC841C +:2012A0000000F922252023FA2223223AE342020240A01008F600C45454D45454D44454C8DD +:2012C0000007FA21202320F82721213AE24408033CC0442800FC8080FE00F8885020D8068D +:2012E0000003FA22222322FA2322223BE242020200DE424242DE003ED21214D40814244296 +:201300000001FA21202020FB2222223AE242030292244824924080FE028A5222528AFE023F +:201320000003F822212322F823202039E14204010EF0442408FE4240FE80FC44281068869C +:201340000000FB22222223FA2222223AE24404082010FE20FC24FE24FC20FC848484FC8489 +:201360000000FB20202021F921202338E14003008888FE88F820FC24FC20FE20FC20FE0016 +:201380000000FD101013107D111111111CE041028888FC8888FE20FC24FC24FC0088040209 +:2013A000000FF82A2A2A25F8202F213AE340010E00BEA2AAAAAA14A280FE1010A060980461 +:2013C0000002FB20202123FD21212139E14101012022FE9088FE1010FE1010FE1010FE001F +:2013E0000000FB22222322FA22232038E54509004080FC44F414A444A4FC4024220A08F87F +:201400000201F927222223FA2222223AE4450810101010BE4000BE8A88A8AEA8A8A85E803D +:201420000001FC1013107D111111111CE340000020FC8850FE00FC04FC04FC20FE20202010 +:201440000002F920232020FB2021203BE040010650525450FE8850FE20FC20FE508804021E +:201460000000FA23242A23FC22212738E1420C0080DC84D4489424404850FCE0504846408B +:201480000000F823222223FA2223223BE2450409407C40FE4278C43C00FE40A458B452B056 +:2014A0000007FC24242721F92125253DE5450E001090BCA4C4A8102846C03C2424A43C248E +:2014C0003E223E207EA23E22007F013F0101FF0010FE4428FE10FC1000FC00F82010FE0058 +:2014E0000105FF29272325F92023223AE24001060828BE48BE18AA4600F8084848B0080446 +:201500002F484B684B6A4B48FF807F013F0101FFEC24A42CA4ACA424FE02FC00F82010FE00 +:20152000003E223E223E00FF08082F2828584F802020FC2020F82020FC2424342820FE0086 +:20154000202020FC2020F82020FD25253529232000F88888F88888F800FC54545454FE007D +:20156000202120FD2020F82121FD2525352921211EE02212948020CE0202CE020202FE02A0 +:2015800010101310FC10303854549010111112140000FC90909090909090909212120E00C4 +:2015A00010101010FD1230395454901010101010404080FC0404040484444404040428108F +:2015C00010101110FC10303955559111111110100000F808080808F8080000000202FE00AD +:2015E00010131111FD103038545490101010111600FC044424A888885050202050880402C4 +:2016000010131010FD113139545490131010101000F01010101010FC040404F40404281008 +:2016200020232222FA2222726AA2A2222424293200FE00202020FC24242444448484281072 +:2016400010111111FD1131395555911111111110101010121214D8101010101252920E00BC +:2016600010101010FC1031395654901010101013202020A8A4A22220242428081020C0002F +:2016800001017F03050931C11F10101F10101F100000FC8040201806F01010F01010F010FF +:2016A00010101011FD1131395555911111111111202020FE22222222524A8A0202020A04C1 +:2016C00010111111FD113139555590101011121400FC040424242424245450909012120E10 +:2016E00010101011FD1230385754901010101010808080FC20202020FE20202020202020CD +:2017000010101010FC10303B54549010101010108084848890A080FEA090908884A2C0801E +:2017200011111111FD1131395552921214141811101010101010101010A86828444484027B +:2017400001021F101211101F01017F030519E1010000F010105020FC0404F48840300E0003 +:2017600010101013FC1030385454901011111214402020FE808080FC8484848404042810D8 +:2017800010111111FD113139555591111111101000FC2424242424FC040000000202FE004E +:2017A00010111010FC103338545490101010101000F808502010FE22242020202020A040A5 +:2017C00001017F050931CF00007F0111112145020000FC402018E60000FC001008040400FA +:2017E00010101310FC10333854549010101010108888FE888800FE424242424A4440404035 +:2018000010101310FC10303855529410101010100000FE20204040FC848484848484FC8434 +:2018200010101010FB103038545191111212141890888880FEA0A0A4A428283222629E0014 +:2018400010131212FE12323A575292121312131000FC004040788890102050880400FE001A +:2018600010111010FD103038575490101010101000FC202024A4A820FE202020202020207D +:2018800010101010FC113139555591111112121420203E2020FC040404FC04000000000036 +:2018A00010111111FD113139555591101010101000FC242424FC242424FC24202020202052 +:2018C00010111111FD11303B545591101010101000F8080808F800FE8000F80808085020BC +:2018E00010101010FD113139555591111111111120202020FC24242424FC24242424FC0408 +:2019000010101111FD11313955559010101112140000FC0404040404FC040090880402024C +:2019200010101111FD1131395555911111121214081CE0000000FE10103018141210101098 +:2019400010111111FD11313955559111111212141CE00000FE00007C4444544842423E00DB +:2019600010101010FC11323855549010101010102020505088241210FC0408885020101059 +:2019800010101011FD1231395555911111101010808080FC0404E424242424E424042810C4 +:2019A00010101312FE12323B5652921212121312083CE020202020FE201010120A8A261210 +:2019C00010101312FE12323B5454911112141010083CC000202020FE202028242222A040A3 +:2019E00010101011FD1230385454901010101010201010FE0204808890A0C08282827E0067 +:201A000010111010FC103038575091101010131000FC8488502050882620FC202020FE0096 +:201A200010101110FC13303855529410101010104044F44850FE4080FE4080FC040428109B +:201A400010101011FC1033385455921410101010404044F44850FE40808498E082827E00B3 +:201A600010111010FC103239555590101010131000FE48484848484A4A4C48484848FE00BD +:201A800010101013FC10303B54539010111112148080BCC05024D40C00FE909012120E00DD +:201AA00010131010FC113338545493101010171000FE20408804FE222020FE202020FE0033 +:201AC00010101010FC113139555591111010101120203E2020FC0424242424245048840430 +:201AE00010101110FC1033385454901011111214202024A4A820FE909090909212120E00CC +:201B000010111111FD103138545591111111101020242424FC00FC0404FC00000202FE00F5 +:201B200020202721F922326F61A5A52222252830000C701010107C101010107C0000FE0013 +:201B400010101110FC1330385455911111111111083CE02020FE202020FC04040404FC0470 +:201B600010101111FD113139555591111111111000409C04040404DC0404040404FC040040 +:201B800010101111FB1531395550931010101010909414181032520E2020FE202020202031 +:201BA00010101112FC10313B555591111111111180803C0080807E080808080808082810B0 +:201BC00010101010FD1238345053901010111311202050880402F80000FE20408804FE02C2 +:201BE00010103E42A41408102041FF050931C1011010FC109090FE101010FE40201806001E +:201C00000201FF04141424440001FF050931C1010000FE40504844440000FE402018060053 +:201C20000111093F02027F081121DF0305196101001020F80000FC201008F600C0300800E1 +:201C400010101013FE14303B5454911010101013402020FE024440FE888808D02050880452 +:201C600010131010FE113138545192101010111000DE4242524A4A42C64A524242424A84A1 +:201C800008087E081C2AC8000F08080A091120402020FC2070A82600E02020202022221EA1 +:201CA00010111111FD12303B5454911111111111202020FC202020FE0000FC040404FC0417 +:201CC00010101110FD1030395450931010101010083CC00444A800F81020FE202020A0406C +:201CE00010101011FA15313955519111111212148080F80810FC2424FC2424FC24241408A1 +:201D000010101110FC10333854549110101010104020FC008850FE202020FC202020202054 +:201D200020222121F422227068A1A62222222220101010105452529010140408081020C030 +:201D400010131010FD10303B545191121011121400F80808F80808F840484850A010080653 +:201D600010101110FC13303854519210101010102022FA2428FE2040FC8484FC8484FC84B6 +:201D800008087E081C2AC80408102FC4040810602020FC2070A824402010E8262020A040DE +:201DA00010101110FC13303854559013101010132020FC2020FE0294501090FE28448202EE +:201DC00010FE20487E080EF94A01FF050931C1010CF08080FE8888080800FE40201806001F +:201DE00010101010FD113139555590131010101020203E20FC04FC04FC2420FE2020202042 +:201E000010131212FE133038545192101010111600FE525252FE2040FC048850204080006A +:201E200020202320F82722726FA2A227202027201078C04040FC4848FE4848FC4040FC00B1 +:201E400010101310FC11313955549111121410104020FE0000FC0404FC2028242222A04049 +:201E600010101310FD11313855549013101010104020FE00FC04FC00FC0810FE2020A04090 +:201E80002020202EFB2224746EA2A22B242629302020FC24FE24FC20FC2020FE2020FE0069 +:201EA00010101110FC13383451529110111210102020FC2424FE2424FC2274A82422A040B5 +:201EC00010131212FB12323B565292121214141800FC0404FC2020FE2020FC848484FC841D +:201EE00020202720FB2027716AA5A023202021264040FC40F880FC1008F640F840A01008E1 +:201F000011111711FD11393551579212131213101010FC10F010F01010FE00900800FC0099 +:201F200010101310FC13323A56529212121212122020FE2020FE8A52FA2222FA22222A044D +:201F400010101310FC11323955519111111013102020FE70A82422FC04FC04FC0400FE00A0 +:201F600010101310FD11313955559010101112102020FE20FC24AC7424FC2070A8242220BD +:201F800010121212FE103139555591111010111690909EA8C480FC04242424545090120E86 +:201FA00010111111FD103739555591111117101000F80808F800FE08F808F8083EC80808B1 +:201FC00010101010FC103038545392121212131200F888888888F88800DE52525252DE52CB +:201FE00020203E48887E14224001FF050931C10100FC80F888F880FC0000FE4020180600B2 +:2020000020212721F92127716BA3A5252921212188C808082A2AAC480888541414242442E3 +:2020200010111111FD113139555591111711111120DC141414D42600DC1414D408081422FF +:2020400010121111FC103339555591111112141010207C44447C40407C44447C44807E003F +:2020600010101110FC10333854559010111210104020FC008850FE2020FC20A82422A040C0 +:2020800011101212FE12323A565292121212121200BC8404F49494F404F49494F404140863 +:2020A00011101013FC11303B5455911214181310088890FC40F840FE8000FC202020FE005D +:2020C00010111010FB10313A545090131010101044248810FE882422F82020FE2020202040 +:2020E00010101312FC11303955559111111013104020FE0204FC00FC04FC04FC0400FE0037 +:2021000010131212FB12323A565292121212141800FC2424FC00FC8484FC84FC8484FC841B +:2021200010131111FD12323A545193121212171000F808101CE4A454A800FC949494FE00E4 +:2021400010101310FD103B3451529011101013102020FE20FC40FE8834E220FC70AC222089 +:2021600010131212FE12323A565292121212131000FE2828EE2828EE2828EE282828FE00DB +:2021800010111111FD113834535092111210111000FC04FC04FC0000DE42524A52424A84DF +:2021A00010101113FD1131395555901310101010A090FE20FC20FC20FE0020FE20202020B4 +:2021C00020212322FB22336A62A7A021222421208404C444DE44C46454D4C4444444548800 +:2021E00010101312FB123338575192141B1010104080F808F808F880FC104844FA404040FF +:2022000020202720FB222F726BA0A123252921218040FE00F808FE08F8A4281010488600A4 +:2022200010101310FD11313857529212121212124020FE00FC04FC00FE02FA8AFA020A0467 +:202240002214FF0849497F081021FF050931C101007C447C447C44449408FE40201806005B +:2022600010101312FC11313955519117101011124020FE0214E00000FC1010FE0090080407 +:2022800010101312FC10313854519210101010104020FE02508824508804FA888888F888B3 +:2022A00020242222F8212E726AA3A222222322202020FA2428FE2040FC44447CC4447C44D9 +:2022C00020232222FB2222726AA2A2222224242800FE0202FE109254FE82FE82FE828A84E0 +:2022E00010101710FC10313955509310111017108888FE88F820FC24FC20FE20FC20FE006F +:2023000010101310FD10333855559111111111112020FE2024A8FE00FC0474547404FC040A +:2023200020202027FC2424746FA4A4252A283120141210FE1090D292F29494C8AA9AA64299 +:2023400011101312FD1031385550931010101010FC20FE22AC20AC00FC00FE80FC042810D3 +:2023600010111013FE10303854549011101013102024A8FE02F88888F82020FC2020FE00B1 +:202380002811284B98294E882810017F0519E10122FC28FE40FC84FC84FC00FC40300E0048 +:2023A00022222724F92725756FA5A52725252428040484940CC46454C4467CC4444444C4DC +:2023C00020272021FF2424776CA7A424272C202008888810DE94A494949494C88894A4C271 +:2023E00021212127F9212F7169A5A52527252428141212907E50D4545448EA562200FE006F +:2024000024FF247E827A4A7A0401FF050931C10120203E44842810284400FE4020180600CC +:20242000017F111F01FF803F041F680F01FF097100FC10F000FE02F800F010F000FE201CFB +:20244000202F282AF92B28786AAAAB282829293200FE002848EE9284A0A8E888941424424C +:2024600010101111FB15313955519111111212149088FE1010FE1010FE1010FE00A4525257 +:2024800010101011FE103139555093121212121220508824FA502454FC20FE4292FA0A061B +:2024A00010101113FD113935505390111111111180F810FC24FC24FC00FE00FC04FC04FC16 +:2024C00010101310FD11313955559013111010108850FE50FC548C7404FC08FE0888A810EF +:2024E00020232223FA2222726AA2A2222225242800FE02FE1054385482507C9010FE101047 +:2025000010131010FB10303B545392121312121200FC4830FE52945020FE528A765272068C +:2025200022222425F92E227468AFA020232C2020203C447808FE20D21A2CCC1A2AC8281085 +:2025400010111013FA113039545191111111111100FC20FE22AC20AC00FC2424FC2424FC00 +:2025600011111217FA13333A565292121214141800F808FE8824FE00FC00FC00FC84FC8458 +:2025800010131011FD113139555590111013111220FE00FC0474547404FC00FC00FE246214 +:2025A000007C45447C437CA5243C017F0519E1014020FC8850FE20FC202000FC40300E004E +:2025C00020202724FA23346A65A2A42B202224208040FE0224BCA4A810E804FA404844C0EB +:2025E000221214FF14147F555563417F41417F411014129210FE1010102828284444840252 +:20260000087F087E08FF203E4287017F020418E020203E4484281028442210FC8040300EEB +:202620000000FC20203D4645649408081020408300F88888880600FC84844850205088066B +:202640000001FD21213D4545659509091121478000F8080808F8080808F808080808FE0038 +:202660000000FC21223C444465940809122440818080FE00F8102040FC9494242444A81088 +:202680000000FC20213E444465940808112040832020508804122040881020448810608038 +:2026A0000000FC20203C4545659509091020408300F88888F800FC04242424245048840469 +:2026C0000000FC20203D46446494090810204380202050508804FA00442424A88810FE00CB +:2026E0000000FD20213C444564940B0810204080083CC00444A800F81020FE202020A04082 +:202700000100FC21213D45456595080813204080048850FC2424FC2424FC2020FE202020B8 +:202720000003F820203B4A4A6A9A0B101020478000FC081020AEA2AAA4A4AA32A040FE0049 +:202740000000FB222439494969990917102041824020FE0214E00000FC1010FE009008044E +:202760000003F821203B4A49689909111120438020FE20FC00FE02FC00FC04FC0488FE0084 +:20278000101010FE2028487E08090EF84808090A0000FC2424A4A4A4A42424444484281023 +:2027A000202121FD415191FD11111DF15111121400FE0000784848484868504242423E0090 +:2027C000101010FE2128487E08080EF84808080820202020FE202020FC8484848484FC8458 +:2027E000202021FC405191FD11111DF1501010100000FE0808E828282828E82808082810BF +:20280000202020FC405191FD11111DF15112121420203E2020FC040404FC040000000000BE +:20282000202021FD415191FD11111CF0501112140000FC0404040404FC0400908804020235 +:20284000202021FD415192FC13101CF05010111220202020FC202020FE2050508888040298 +:20286000202020FC415290FC11101CF051101013202050880412204088102044881060802A +:20288000202023FC415090FC13101CF050101010083CE02024A4A820FE2020202020A040BB +:2028A000202021FD415191FD10101CF051121010081CE000202020FE2020A8A42222A040D9 +:2028C000101110FE2028487E09080EF84808080800FC44444444948800FC84848484FC8490 +:2028E000202020FC415090FD10101CF05013101010141210FE1010D090909088EA8A0602C7 +:20290000101010FE2028487E08080EF84808090800FE10204482FE121010FE101010FE00B4 +:20292000202020FC415291FC10101DF050101310202050880402FC202020FC202020FE0097 +:20294000101010FE2128487E09080EF848080808404078885020508806F888888888F8885D +:20296000202321FD415191FD11111DF15113101000FE202828E8282828E8282A3AEA2620B0 +:2029800008087E08FE142242BF05091F01FF01012020FC20FE508806F80000F000FE00001F +:2029A000202322FA425392FE13121EF25212121200FE028A52FE4222FE828282FA020A040A +:2029C000202320FD405192FC10131CF15011121400DE424A844A522000DE52529448542243 +:2029E000202021FA415090FC11111DF1511111119292244824929200FE2222FE2222FE024F +:202A0000202023FC415093FC11121CF1501010132020FE20FC40FE8804FA20FC205088044E +:202A2000202023FA425392FE13121EF2521414184020FE5050FE5252FE0092D49892D28EBF +:202A4000202120FB20415291F9111AF5501112142024A8FEA824220404DE44549E04040436 +:202A6000017F013F213F213F01FF013F20203F2000FC00F808F808F800FE00F80808F808FD +:202A8000020202027F020202FF020101010E7000402020FC0000003EC01020408444340C35 +:202AA000080814122140BE2222222A2421211F00282424202EF0202424282810122A468232 +:202AC0007F021F101F101F101F02037E01000738FC00F010F010F010F040F8204084641C7E +:202AE0000808FF087F417F417F4908FF080808092028A424203EE02424282890324A8602D5 +:202B00003F21213F00FF213F213F2127F94101012824242020FE2024242828D0122A468278 +:202B20002222FF223E223F2222FF405462407E0120282424203EE02424282810324A86021F +:202B4000007E427E427E09487F887E080FF0400120282424203EE02424282810324A8602DF +:202B6000007E22243F554955A2007F555557FC001014121016781212121414081AAA46827B +:202B8000007F12523312FF003F21213F21213F21109412901678D212121414081A2A4682A6 +:202BA00000005F5057751517F4545755952720402824FE20A02020A4A4A8A81012AA4682E8 +:202BC000007E40446454484854546440407E000000FC404040784848A8988888AACA8A0689 +:202BE0001010282442910808FE0244281008080000FC404040784848A8988888AACA8A06E2 +:202C000010087F002214FF00003E2222223E220000FC404040784848A8988888AACA8A06CC +:202C2000087F083E003E223E147F007F080F111C0408106408106408106000FC00E0249CC3 +:202C4000442428FE92D6BA92FE007C447C447C4400FC404040784848A8988888AACA8A06DC +:202C6000007C45447C437CA5243C007F080F111C4020FC8850FE20FC202000FC00E0249C22 +:202C8000010101010101013F10080402010618E0000000FC000000F01020408000C0300EF7 +:202CA00002023F040830C0001F10101F10101F100000E02022221E00F01010F01010F010A6 +:202CC000001F10101F10101F02027F040408106000F01010F01010F00000E0202022221EC2 +:202CE00000007C444444447D444444447C44000000FC2020202020FE202020202020202061 +:202D0000001F101F101F00003F0101FF020418E000F010F010F00000F80000FE8040300E14 +:202D2000001F101F101F003F0000FF0408103F1000F010F010F000F80000FE002010F80857 +:202D40001F10101F10101F01017F03050931C101F01010F01010F00000FC80402018060047 +:202D6000001F101F101F003F202021212244489000F010F010F000FC80804040201008062D +:202D800000007C444444447C444444447C450102040EF0808080FE8888888888880808088F +:202DA00000007C444546447C444444447D440000404080FC040484444414244484042810EB +:202DC000001F10101F10101F01111122040830C000F01010F01010F00008108040201806EF +:202DE000001F101F101F08081F215294101F000000F010F010F00000FC0484440484281079 +:202E000010103E2254081720DF10101F10101F10404050484440FE00F01010F01010F01078 +:202E2000001F101F101F000C7044445C6448106000F010F010F00000FC8484849488808005 +:202E40001F10101F10101F0201017F00100804FFF01010F01010F0000000FC00102040FEBD +:202E60000804023C04047516161525244484140800007C4444C47C4444447C8040300E0093 +:202E8000000179494949497949494949794A020400FC040404FC00404448704042423E00EC +:202EA000023F02FF020C3FC807001F101F101F1008D020FE00708404FC00F010F010F0103D +:202EC0001F101F101F003F20203E22222A444186F010F010F088FC808888505024548C0493 +:202EE000000079494B4D497949484B4878480000909414181032520E2020FE202020202002 +:202F0000001F10101F10101F24140C146408106000F01010F01010F0485060504842423E7E +:202F2000001F101F101F017F4202FF081C030C7000F010F010F000FC0400FE204080700868 +:202F400000037A4C484B4878494948487B48000000FE024440FC80A020FC2020FE20202016 +:202F600000007B48484B4A7A4B4A4A4B7A4A02024844FE4040FC4444FC4444FC4444540853 +:202F8000000078494A4C497848484B4A7A4A03024040A0108846F0102040F8080808F808BD +:202FA0001F101F101F081F22540837C01F10101FF010F010F04060504840FE00F01010F034 +:202FC00000007B4A4C49487949494949794803004020FE0204FC00FC04FC04FC0400FE0090 +:202FE0000003784A4948497A48484B487848010210D458528C8804FA2020FE2050880402F6 +:203000000003784A494B7A484B484879490204010EF0442408FE4240FE80FC44281068861F +:2030200000037A48494949794948484B7848010200FE0200FC04FC04FC4020FE00880402A8 +:203040000201F790979497F097909191F79105020808C8109E94A414949414C80814244204 +:203060000007F09F909795F497909790FF9005083CC040FE40FC54E4FC40FC40FE00249246 +:203080000007F094929491F2979A9392F392030200BC84A494A42010FC20FC20FC20FE007E +:2030A0000107F093909790F391979395F390020110FC40F840FC00D412FE50348C8A96026F +:2030C0001F101F101F01FF223E043F04FF041C67F010F010F000FE88F840F840FE90601C56 +:2030E000013F0108FF08001F101111111204186000F80020FE2000F01010101010C0300822 +:203100001212FF1213101F001F10111111020C702020FE20E000F800F01010101060180476 +:20312000007D454555555554545454102825428400FC04040404FC505050509292120E008A +:20314000007C4454545455545454541028244480202020404884FE8200FC84848484FC8476 +:203160001010FB1019F01152241F101111020C308080F0909094540C04F0101010C03008E5 +:2031800008082E28282EF0001F10111111020C70808890E084847C00F010101010601804FB +:2031A000007C4447545454555454541328244083201010FE204284F81022C4081028C40281 +:2031C000007C445454545454545555122824448000FC8484FC909088843208006018040089 +:2031E000007D454555555555555555112926428400FE00007C0000FE50525448484452605B +:2032000001017F1109FF050930DF101111020C300000FC1020FE402018F6101010C03008C7 +:20322000007C445455545554545454112A24448028242420FE2020B2B468A8242220A0407F +:20324000017F0909157F40801F10111111020C7000FC202050FE0204F0101010106018046C +:20326000007C444554545754545454112824418220A2A2245088042220A4A42850880402E6 +:20328000007C47545555555555555413282444802824FE20FC24FC24FC2408FE88484818A2 +:2032A0001011111F111111117D454444447D460400FC040424242424245450909012120E76 +:2032C000084949497F007F01013F2020232C3001007C44445454545454541028284A8A06D6 +:2032E00000007F08082A2A2A5D4988080FF04001007C44445454545454541028284A8A0615 +:2033000008087E0808FF012A184828FF14224181007C44445454545454541028284A4A86F0 +:20332000102844827D00F19595F59595F59195B2007C44445454545454541028284A4A8695 +:203340002424FF247E24FF087E4A7E4AFF424A44007C44445454545454541028284A4A8684 +:203360002222FF223E087F497F087F087F080FF0007CC4445454545454541028284A4A8650 +:20338000101E107F515C724E404A6A5B4A8F7800007C44445454545454549028284A4A866D +:2033A0000810305790101011091F2101FF010101A090BEC04024140C00F80000FE00000039 +:2033C0007C04047C417D05042B10111F21FF0101F888F820FC24FC28FC0400F800FE0000C7 +:2033E000080848487E4888080EF8480808080808808080848890A0C08080808484847C005D +:20340000080849487E4889080EF84B0808080808083CE020203CE020203EE0202222221EB9 +:20342000101050507D5090101DF151111111111120202020FE202020FC0404040404FC04BD +:20344000101350507D5090131CF051111111111100FE4040FC8484FE0000FC040404FC04FF +:20346000101151517D5290131CF0511111111111202020FC202020FE0000FC040404FC04A3 +:20348000101051507C5193101DF15111111010102020FC508804FE08E82828E828082810A4 +:2034A000101151517D5191111DF151171010111200F80808F808F808F80808FE0090080476 +:2034C000101057517D5292171DF555121215181010107C14FE147C107C10FE101000FE00EE +:2034E000101053527E5392121FF35315151519118040FC0404FC0000FC5454FC5454440C6C +:20350000101053507D5191101FF25212121212124020FE00FC04FC00FE02FA8AFA020A04D4 +:20352000087F083E087F08083F013F017F010502007C2424244454F80000F800FC000000B4 +:2035400020124420087320003F013F017F01050240484414608000F00000F800FC0000008F +:20356000103AE22424F8202722FA2224242A51800086B888485E288888BE8888888828105D +:203580001139E22224F8232020FB2222222342800006B888485E880808BE88888888A810FE +:2035A0003E223E207EA23E22001F013F017F010310FE4428FE10FC1020C000F800FC000082 +:2035C000023F02FF020F34C300013E033E037E0120C080FE20C008F800F000F000FA02FE87 +:2035E0001038E0212338E121213AE7202020201F40409008FC2420FC2020FE20222222FE2E +:20360000013E033E037E010018711C711C711418F000F000FA02FE0030C078C078C4443C1B +:203620001038E721223AE7212139E6222528201F10107C14FE147C107C10FE1012FE02FEF0 +:203640000810247E10FF24428930C40832C438C0081CE020203CE020203CE02222221E0088 +:2036600008142241BE00784A4A7A4A4A7A484A59040E7010901CF090909EF0909292920E5E +:2036800008492A7F415D555D423F013F017F010020203E48A8281028F600F000F80202FEF0 +:2036A000113BE42B223BE227203BE2232223201F00F010F848F848FC00F808F80AFA02FEED +:2036C0001138E3202239E0272039E1212121201F0890FC90949890FE00F808F80AFA02FE86 +:2036E00077557755775577227FA43F243F243F20040E7010101C7010901E70101212920E55 +:2037000010103F204F803F0004040404080810200000FC00F000F010101010100A0A060284 +:2037200010103F204F803F0000111111212141810000FC00F000F010101010100A0A06027D +:2037400010103F204F803F0004044444447F00000000FC00F000F010101050504ACA460281 +:2037600010103F204F803F0024242424244444800000FC00F000F010909090908A8A8682B8 +:20378000203F409F007F101F20510E31CC031C0300FC00F000F01090901010926A0A060265 +:2037A000203F409F007F007F121292535212FF0000FC00F000F01090105090120A0AC60207 +:2037C000203F409F007F007F44445F444A517F4000FC00F000F010D0505050524A4AC6428E +:2037E000203F409F007F047F043F203F0A12224100FC00F000F010D0109090920A4A46C28E +:20380000203F409F007F003F203F203F007F4AFF00FC00F000F01090909090920ACA46E26C +:203820000404040F0810304884020102040830C0000000FE1010202040800080402018063C +:203840000808FF08087F49497F081C2A498808092020A03E444444A4282810102848840295 +:2038600008107E427E427E1008FF203E22424A852020203E444444A4282810102848840216 +:2038800008484848487D404078484849484848892020FC2020FE0294509050FE2844820223 +:2038A0000849494B497D414179484B4848494E88484848FE48487800FE20FE70A8242220A8 +:2038C00008484B4A4B7E43427A4A4A4A4A4A4C884020FE02FE14FE10FE92FE92FE9292969D +:2038E00000017E22113F02027F040F142241863808FC101020F80000FC00E0204080601C98 +:20390000041EE02292544004FF0444242405150A101E10FE929CF0928E80B8A8A82A2A460A +:20392000003F2121213F2121213F2121214145820404042424242424242424240404140825 +:20394000003C2424243D2424243C24242444548800FC000000FE404080FC04040404281010 +:20396000003E2222223E2222223E222222424A84040408102044040810224204081020C04B +:203980000201FF10101F001F101F101F101010100000FE0000F800F010F010F010105020B3 +:2039A000007848484B7848484F7848484849499A88888888FE888888FE88888888080808F5 +:2039C0000078494848784B48487848484849499A0000FC000000FE90909090909212120E39 +:2039E000003C2424243D2424243C24242444558A2020202020FE20202050505088C8240247 +:203A0000007848484B7848484879494A4A4C499840404040FE408090902020484484FE82D2 +:203A20000078484B487A4A4A4A7B484848484898404040FC4048484848F8484042423E0002 +:203A4000003C2425253D2525253D252525455589202020FE22222222524A8A0202020A0421 +:203A6000180601063A02FF040F182F488F080808186080601800FE00F808F808F8082810F7 +:203A8000003C2424243C2524243C24242444558A4040407C8488202020505050888804025C +:203AA000007848484B78484848784949494A4A9C90888880FEA0A0A4A4A8283222629E0016 +:203AC0000078484F4879494A4B7849494A4C4898404040FE80202020FC2028242222A0408E +:203AE000003C2424243C2427243C2424244454884040407C404040FE404050484440404095 +:203B0000003C2424243C2424243C24242445558A20203C2020FC848484FC848080000000C5 +:203B2000003D2525253D2525253D25242444548800FC242424FC242424FC242020202020D3 +:203B4000003C2425253D2525253D252525445488202020FC242424FC242424FC2420202093 +:203B600001013F213F213F001F101F101F1010100000F808F808F800F010F010F01050202F +:203B8000003C2424253D2624243C242424445488808080FE4040407C4040407E4040404011 +:203BA000007849494979494949794949494A4A9C081CF050505050505048486854745200D4 +:203BC000003C2424253E2424253C24242544548B20205088041220408810204488106080C3 +:203BE000003C2525263C2525253D252524445488808000FC0404E4242424E4240404281007 +:203C0000003C2525253D2525253D252525455589041EF010101010FE101010080A4AA612EA +:203C2000007948484878484B4879484848484B9800FC08103048840200FC20202020FE00D8 +:203C400000784A4949784F484878484849494A9C404444485040FE909090909212120E0097 +:203C6000007B4A4A4A7A4A4A4A7A4A4A4A4A4A9A00FC0404F40404F4949494F40404140845 +:203C8000003D2525253D2525253D25252545558900FC04242424FC2424544C8C0404FC0419 +:203CA00000784848497A4848487B484848494B99202050880402F80000FE20408804FE02E1 +:203CC00000794848487849484B784848494A48980488502050882420FE20A8A42222A0401E +:203CE00000784B484878494B487848494A48489B4020FE40909024E44448881030488404B5 +:203D0000003C2424243C2424253C242424445489844800FC48484848FE484848488888086B +:203D2000003C2424253C2424273C24242444558A88485000FC202020FE2050508888040214 +:203D4000003C2524243C2427243C242525465488202024A4A82020FE70A8A82424222020EB +:203D6000007B4848497A4848497A4848494A489800FE4080442468B0302868A42220A0405B +:203D800000794949497948484B7A4A4A4B4A4A9A00FC040404FC2020FE22528A0A020A049A +:203DA000003C2424243D2624243D2424244457882020A8A8A874222020FC20202020FE005C +:203DC00000784B484A79484B48784F4848484898083CC004442800F81020FE202020A040E1 +:203DE00000784B4A4C7948484B78484849494A9C4020FE0204F80000FE90909012120E005A +:203E0000007B4A4A4B7A4A4A4B7A4A4A4D4D4A9800FC0404FC002022B2B4A8A82424A24043 +:203E200000784B4849784B4849794949494949992020FE20FC20FE00FC04FC04FC041408C7 +:203E400000784B494A7C4B4A4A7B4A4A4B4848984080FC104846F84848F84848F842423E0B +:203E60000078484F4878484B4878484F484848989090909E9090909C9090909E90909090F1 +:203E8000003C2425253D2525253D25242444558A2020A02C2424AC2424FC24505088040269 +:203EA00000784B4A487948484B7849494A4C48984020FE0200FC0000FE2028242222A040EF +:203EC00000784B4A4C784B48487949494A4A4C984020FE020400FE2020203C20A0603E0057 +:203EE0000078484B49794A4A4F79494D4A4B4C9810107C14FE147C107C10FE101000FE0094 +:203F000000784B4849784B48497A48494848489B2020FE20FC40FE8804FA20FC2050880445 +:203F200000784B48487B4A4A4A7A4A4A4A4A4A9A2020FE2020FE8A52FA2222FA22222A044D +:203F4000003D2424253D2525253D25252545558900FE2040FC545474545474545454FC04AE +:203F6000003C2424243C2424243D25252545578800F88888F88888F800FC54545454FE00CF +:203F8000003D2525253C2524253C24242444548800DC5454DC00FC00FE80FC0404042810E9 +:203FA0000078494A4D784B4A4A7B4A4A4B4A4A9A40A01008F600C45454D45454D44454C8C0 +:203FC0000079484849784B48497A4C4948484B982024A820FC40FE88242220FC2020FE004B +:203FE0000079484849784B48497A4D48494848992024A820FC40FE884442FC88D0304884F6 +:20400000007B4849497949484B7A4A4B4A4A4A9A00FE00FC0404FC00FE8A52FE22222A0427 +:2040200020FE213C244454881F101F101F10101040FE001CE094A8C6F010F010F010502068 +:2040400000784B4A4C7949494979494F4848499A4020FE0214E00000FC1010FE0090080425 +:204060000079484948784B48497A4D48494A48982024A8FC2040FE88242224A82422A04012 +:2040800000784B4A497B48484978484948484B984020FE8A04FE4088FC2420FC2020FE00CE +:2040A00000784948487B4A4C49794948494949994020FC8850FE2224FC242C20FC04FC04F3 +:2040C00000784F48487B484B4A7A4B4A49484F9A8888C8BE88C81CD45454D44888D414227C +:2040E000007B484B4A79484B48784B484B484B9888FE88FE02FC00FE40A254B85492502047 +:20410000003C2424243D2525253C272424455688F88888F800DC5454DC20FE70A824222081 +:20412000007B484B4A7A4A4B487949494949489B20FE00FC04F494FC00F808F808F800FEB8 +:20414000007B4A4A4B7A4A4A4B7A4A4A4A4D4E9820FE8850FE50FC54FE54FC50D854525021 +:204160000079484B48794A4949794A4D48494A9C2024A8FEA824220404DE44549E0404040F +:204180002020203F2040407E02021AE2420214092020207E428410101010282848448402BB +:2041A000422418245210FF20287EAA2A2A2E08092020207E428410101010282848448402B3 +:2041C00008087F142241FF027A4A4A7A4A020A042020203E22445090101010282844448288 +:2041E000020F780808FF284B49496B49497F41012020207E4284101010102828484484021E +:204200001008FF004224FF007E42427E42427E432020207E42841010101028284844840217 +:204220000814225D803E223E00771155335511332020203EA244509010101028284444822E +:20424000007C4445464C6C5454546C44444241804040FC04F494F484948A827E0002FE00CA +:20426000201312FE030A8A8A4A4A52531CE4481000F8080828A8A84848A8A82A0A0A0602A3 +:20428000007C4444444C6C5454556C444442418000F888F888F888F888FC00508802FE0056 +:2042A000007D4545454D6C5554546C4445424180A02C24AC24FC20FC04C830488402FE0064 +:2042C000001410FE284482243624FF24544B891200F888888898D8A8A8A8D88A8A0A0602FD +:2042E000007C4445444C6D5456556C454642418020A4A42850880488AADC88542202FE004B +:20430000000F0808081020C03F100804030C30C000E0202020201E00F01020408060180650 +:2043200010FE107C00FE827C007C047C407C040D00784848488600FC444428281028448276 +:2043400010FE107C00FE82107C20507C10FE101100784848488600FC4444282810284482F4 +:2043600008FF087F00FFA03E42FF497F497F498B00B8282828C6807C2424282810284482A5 +:20438000047C04043C04047C0401FF0804031CE0407C40407840407C4000FE204080700E7A +:2043A00002017F0804031CE22E222E222E225F800000FC204080708EE888E888E888F80875 +:2043C00002412504FD1415159555252554558404007C0444F444F45474D454F4E454444C35 +:2043E000201000FE20203D2624242424445488002020205050880402601000C02010080046 +:2044000020101001FE21203C25252525254554888080FE2020FE2020FC2424243428202086 +:2044200020101001FE21203C25242427244454888080FE001CE0203CE0203EE02022221EF2 +:2044400020101001FE20203C242425242445558A8080FE0000FC84A49484FE848404140868 +:2044600020101001FE20203C25242424244455888080FE101090FE901010FE101010FE0023 +:2044800020101001FE20203C242424242445558A8080FE0000FC8484FC80A4A8B022221EAD +:2044A00021111102FC21203C252424242444558A0000FE4020FE4084FE02A8A8A8AA2A2654 +:2044C00021111102FC21203C27242525254454880000FE0020FC5088FE08E828E808281014 +:2044E0001011101458505190101011292644408100F810204080FE92929212222242940899 +:2045000010101013545851901013102824444080404040FE4040FC4040FE42424A444040FE +:2045200010101011545951911111102824444080202020FE2024242424FC242022221E0079 +:20454000101010145952549111111129254540804040A0A0100806F0101050200404FC009F +:20456000101013105458509011121428244440800000FE20204040FC848484848484FC8493 +:2045800010101310555850901310102824444080083CE02024A4A820FE2020202020A04076 +:2045A00010101015585050901110102824404380402000FE20202020FC2020202020FE0036 +:2045C00010101015585050901110102824454080201010FE20204484F810204482FE8200D8 +:2045E000020408103F001F10101F0111220418E000002010F808F01010F00010A040300E72 +:20460000101011155B5551911110132824444080909414181032520E2020FE20202020206E +:20462000111010145B505091101013282444408004848800FE2020FC2020FE2020202020FE +:204640001013101055585093101011292545418100FE4040FC8484FE0000FC040404FC0479 +:2046600010101014595250901010112925454181202050884422F8081020FC040404FC042F +:20468000111012165A5252921213122A2642428200BE820222125242CA56523202020A04F4 +:2046A00010101014595151911111102B2444408020203E20FC04FC04FC2420FE2020202049 +:2046C000011111220418E0080A2A2C48142242800008089040300E10105454981028448275 +:2046E00011111117595151931212122A27444080003C24A4243C24A4A4BCA4A4A4445488BF +:204700001011111559515190101310292440478000FC04FC04FC044020FE00048800FE0058 +:204720001011111155595191101311292545418100FC2424FC2424FC00FE20221448840277 +:204740001011111155595191111111292745418120DC141414D42600DC1414D408081422AC +:20476000080B12335097111214100111220418E000F808F840FC504844400010A040300E05 +:20478000101013125459509111111129254443804020FE0204FC00FC04FC04FC0400FE0060 +:2047A00010101111555951911111122A244440804020FE0202FE0000FEAAAAFEAAAAA28675 +:2047C00020242222A8B0AEA222222222524A458800F88888F88888F8A29488A8C48400FE04 +:2047E000101312165A5253901312122B2642438240BE129252AA2440FE2222FE2222FE02CA +:204800001011111155595093121310292444418600F808F808F800FC94FC00F8906098062D +:2048200010101314585352921312122A264242824020FE8850FE528A06FA8A8AFA020A04E7 +:204840003F213F202F205F44952C0111220418E008087E084828A80828900010A040300E1A +:2048600010131012555A5090111111292545418100DE42524A524220FC0404FC0404FC0464 +:2048800020212724ADB4A7A4252420275049428C8000FC445444FCE4540440FEA01008065D +:2048A000101311105558519211111129254541813CE024A8FEA82402FC2424FC2424FC0460 +:2048C000101211145850539111111129254142844424287E10284A1C284C1A2A4810FE00C3 +:2048E000FE20509A2C489C2AC8180111220418E0FE20509A2C489C2AC8180010A040300E16 +:20490000101311145B5253901312132A274242831EE02294FE52FE04C47EC454CC84D44863 +:204920002F486B486B4AFF887E2C4AFF1129C618EC24AC24ACA4FE22FC68A4FE1028C63082 +:2049400000000000000000000000000024224280000000000000000000000000884444043B +:2049600002027F023F04FF081F204482020024420000FC00F800FE20FC202020A0408844E1 +:204980000179494A4C79494949487800242242800000FC0404E42424E4042810884444043E +:2049A000017F013F003F203F08FF003F203F244200FC00F800F808F820FE00F808F88844C0 +:2049C00002013F20203F2020202F2121424488100000FC0404FC80A090FC404020100806BD +:2049E00002013F20203F2022212422205F4080000000FC0404FC00202020207EA020202010 +:204A000002013F20203F20202F282929494988080000FC0404FC0000FC04E42424E414089E +:204A200001003F203F20272427202F284F4888070080FC04FC00F010F000F888F80202FEC2 +:204A400001003F203F21213F21212F21415F81010080FC04FC20203E20203C20203E20204E +:204A6000201010F80810103854941010101010100000000000000000000000000000000056 +:204A8000201011F90911113955951111111110100000FC04040404FC040000020202FE001A +:204AA000201011F80810103B54941010101011120000FC20202020FE20205050888804029F +:204AC000201010F90911113955951111111117102020202020203C20202020202020FE000A +:204AE000201010F90810103B5494101010111010202020FC202020FE2020404884FE82004B +:204B0000201010F80B101038559511111111111120202020FE202020FC0404040404FC04BC +:204B2000201010F80B101038559511111212141150484840FE8080FC444428281028448295 +:204B4000201010F8091112385494101010101010808080FE4040407C4040407E4040404079 +:204B6000201010F8091112385494111112101010808080FE02042020A8A424222220A040D5 +:204B8000402023FA121222336AAA222222222322083CE020202020FE201010120A8A26127E +:204BA000201110F80B101039559511111010101000FC0404F40404E4242424E404041408B4 +:204BC000201010F808111139559511111010101120203E2020FC042424242424504884045B +:204BE000201010FA0910183552941010111112149090909294989098949290901212120EA7 +:204C0000211113F90911113955951117101011120808FC0808F80808F80808FE00900804D7 +:204C2000211010F9091111395595101013101010048850FC2424FC2424FC2020FE2020208B +:204C4000412127F91311273169A827202021222C003CD4149414D4244C40FE40A010080623 +:204C6000211010F80B101835509013101212141004848800FE2020FC2020FE00A452520078 +:204C8000402720FB1013223369AF20232222232240FC40F800F808F810FE00F80808F808B4 +:204CA000201310F909111837509310171011161020FE00DC54DC88FE88FE88FE9488A4C2C0 +:204CC00000FF020202020202000108484848870000FE004020100800000088841212F000CB +:204CE00002020203020202FF0001084848488700000000F8000000FE000088841212F00028 +:204D000000007E02241408142240010848488700080808FE08482808281000849212F00057 +:204D200008087F083E087F08080108484848870000007C2424244454880088841212F00077 +:204D4000013F0101FF00013F0101FF025151900F00F80000FE0000F80000FE00041212F08A +:204D600000FF02043F242424242001084848870000FE0000F8888888A81000849212F000C1 +:204D8000080B103057901010130108484848870038C04040FC404040F80088841212F000F2 +:204DA00008047F01013F0101FF010848484887002040FC0000F80000FE0088841212F0004C +:204DC0004020091224E020232C010848484887008080FC044840A018060088841212F00017 +:204DE000017F013F007F408F081020C12828480700FC00F800FE02E42022221E88A424E083 +:204E0000122148942162AE222222210848488700003C00007E080808281000849212F0008A +:204E2000007F417F487F4845536101084848870020203E44A4242810284600849212F000C3 +:204E40003F242F253F22272A33203F025151900FFC20F820FC00F010F000FC00041212F0E0 +:204E60001C7010FE107C44447C440108484887001020FC84FC84FC84FC0000849212F000E0 +:204E8000087F003E233E003E047F08291148488740407E884848505020508804008412F298 +:204EA0002720FA21776BA52925220108484887008888BE08D85C2A48080800849212F000D5 +:204EC000014F212780475414E52624240148488710FE10FCA0FCA4A46454840C008412F2D2 +:204EE00010FE29FE017C447D447C10FE1148488740F84830CEF820FC88A8A850888412F27F +:204F000001013F01FF013F0101010101010101010000F808FE08F808000000000000000001 +:204F200001013F01FF013F01013F0101FF0101010000F808FE08F80000F80000FE000000B7 +:204F400001017D050931C5021F10101F10101F10000810A060180600F01010F01010F010C9 +:204F6000221111007F408001017D05091121C50208081020FE0204000488502010080600CA +:204F800001017D050931C502080A6A2C2A4AA910000810A0601806001014D45854945220D7 +:204FA0000001F921214179C9494949497A42040800F01010101010101010101212120E0082 +:204FC0000001FC1010203C6764A424243C24200000FC2020202020FE202020202020202087 +:204FE0000001FC1010203D6464A425253E24200100F810204080FE9292921222224294082E +:2050000001017F013F017F017F04083FC8080F080000FC00F800FC00FC0000F01010F010A1 +:205020000000FC1310203D6564A424273C242000404040FE80A020FC202020FE20202020E4 +:205040000000FC1310213D6565A524243C242000202020FE2024242424FC242022221E00EC +:205060000003F82121417ACB484848497A44000000FC1010101010FE305090101010502094 +:205080000000FC1010203C6464A424243D252204081CE0808080FE88888888880808080812 +:2050A0000000FD1010203D6464A424243C252200041EE0002010FE040810204080403E0095 +:2050C0000003FA2223427ACA4A4A4A4B7C44081000F8080828A8A84848A8A82A0A0A060261 +:2050E0000000FC1110203C6564A424243C252000202020FC202020FE2020404884FE82007B +:205100000101FB2121407ACA494948487841020C1010FC10100008081010A040A0100806D9 +:205120000001FD1111213D6565A525253D22020400FE000000FE20203C24242424445488AB +:205140000404FF0911214F8000FF081F28C80F084020FC10608404FC00FE00F80808F808BB +:205160000000FC1011213E6464A424243C242000808080FE4040407C4040407E4040404087 +:205180000000FC1010213E6465A424243C2423002020505088040200FC2020202020FE0054 +:2051A0000000FD1111213D6565A525253D252101041EF010101010FE101010080A4AA612A1 +:2051C0000000FC1011203C6464A424243C24230040202000FE000484844848485010FE005F +:2051E0000000FC1111223C6464A424243C242000201010FE0204808890A0C08282827E00BF +:205200000000F82320407B4ACA4B484879490204909090FC9494FC9090FE92921A14101081 +:205220000007FA2222427A4FCA4A4A4A7A4C040802E2424A4A4A4AEA4A4A4A4A42424A4432 +:205240000000FD1010203C6564A424243C2420004848FE48482010FE808080808080FC0058 +:205260000000FC1110213C6464A724243C242102202020FC2024A4A820FE505088880402BA +:205280000000F8232040784BC84B4848794902048080BCC05024D40C00FE909012120E0045 +:2052A00008082E28282EF0007F04083FC8080F08808890E084847C00FC0000F01010F01089 +:2052C0000001FD1111213D6565A525253D25210100FE02027A02027A4A4A4A7A02020A04AF +:2052E0000000FC1111213D6565A525253D252101202040FC04049454242454940404FC0451 +:205300000000FC1011203C6465A424243C242000404078885020508806F888888888F88879 +:205320000000FB2020437848C8484B487848020110D8949490FE909494D89890AACA860277 +:205340000000FB2021407B48C9494949794800032020FE20FC20FE00FC04242424508804E6 +:205360000000FC1011223C6464A424243C242000504880FE9090FC9090FC909090FE808082 +:205380000000FD1011203C6764A425253D2521014020FC00089000FE0000FC040404FC045C +:2053A0000000FB2224407B48C84949497A4A04084020FE020400FE2020203C20A0603E00DA +:2053C0000000F9232047794ACC4B48487B480007809008FC40FE1048861020C40830C000FA +:2053E0000001FC1010213C6464A425243D25200020FE20FC20FE00FCA494FEA414FE0418A0 +:205400000001FD1111213C6566A525253D24200000FC04FC04FC80FE22225202FA021408AA +:205420000000F92020407B4ACC494949794900004020FC008850FE2224FC2424342820206D +:205440000000FB2224417849C9494949794803004020FE0204FC00FC04FC04FC0400FE0043 +:205460000000FB2222437ACA4B4B4B4D7D4509018040FC0404FC0000FC5454FC5454440C14 +:205480000202F3242A4172D458575051725C00000808BE88A83E084848FCE0504846404014 +:2054A0000000FB2021427849C84848497A4C00004020FE88244290F80844A89088A4C28080 +:2054C0000301F023204774D35450575071520C00F010E01800BCA418A440FCE0504846409F +:2054E000087F083E003E2A3E40FF081F28C80F08007848488678483048FE00F80808F80800 +:205500000201F8242240794ECA484B4878490200007E407C44FC407E2020FE70A8242220E7 +:205520000201F720274477D057505151775105020808C8109E94A414949414C8081424422F +:205540000007F022214275D85352525372510F0020A4A8921408F402F80808F80810FE0040 +:205560000003FC1111213D6764A525253D25200300FE00FC24FC24FE00FC24FC24FC00FEF7 +:205580000000FB2021417A4DCA494A49784902008888FE8810DE5254887402FC2024226074 +:2055A0000003F8232241784BC8484B487B48030088FE88FE02FC00FE40A254B854925020F2 +:2055C0000003F024224074D2525051527652020288FE8812FE10FE92FE92FE9204FE442CAB +:2055E000010618EF001F101F0404FF0911214F8000C030EE00F010F04020FE10608404FC1E +:2056000004241404FF0111093F2125252921212140485040FE001020F808482828082810DC +:2056200014553614FF492A7F49495D6B4949494B282424207E20203C345454548888142246 +:2056400014553614FF492A7F49495D6B4949494B14127E10107E52527E52527E5252524664 +:2056600000017C44447C44477C4444447C44000000FC2020202020FE202020202020A040DC +:2056800000037C44457D45457D4544447C44000000FE2020203E222222FE020202021408CD +:2056A00000017D45457D45457D4545457D45010000FE000444282810102828448400FE0000 +:2056C0000000784B487949497949484878480000202020FE2024242424FC242022221E00F2 +:2056E00000007849497A4A4C784848487848010640404048444242484848101020408000D1 +:205700000000784B4A7C484878484849794A0408404040FC44484040A0A0A02022221E0026 +:2057200001111F215F01FF001F101F101F101F100000F800F000FE00F010F010F010F01016 +:20574000101E2262940830C01F101F101F101F1000F888A892827E00F010F010F010F01095 +:2057600000007C44447C45447C4444447C440000202020404884FE8200FC84848484FC84A0 +:2057800000007D44447C47447C4445447C4403002020FC202020FE002020FC202020FE00BD +:2057A0000000784A4A7A4A4A7A4A4A4A7A4F02009090909092D4989090909092D2120E00AA +:2057C00000007C44457C44447D4444457C44000120207C8448302048903E42A418106080D9 +:2057E000000078494B784949794A484F7848000040409008FC242020FC2020FE2020202047 +:205800000000784B487948487B484848794A0400202020FE2024A4A8FE70A8A82422202028 +:2058200000007848497A4D4878484A49794807004040A0A01008F600884848501020FE00D1 +:205840000100784B48784B4A7A4B4848794A0400088890FC2424FC2020FE62A22A242020E3 +:20586000000078494B7848497A48494A7848010640408804FE02884442F88850205088060F +:2058800000037A4A4A7A4A4B7A4A4A4A7A4C050800FE1010FE1010FE001010FE1010FE0047 +:2058A00000007B4A4A7B4A4A7B4848487849020400409C04049C0404FC9090909012120EBA +:2058C00000007849497B4D497949494979490101A09080FE1010FC1010FC101010FE000081 +:2058E00000007B4A4A7B4A4A7B48494F784800004080FC2424FC2444FC9010FE101010102D +:205900000101017F409F09320C3FD01F101F101F00F800FE02F4209060F816F010F010F059 +:205920000106F49497F49497F0979291F090010E405C44445C4444FC40FC0810A040B00EF3 +:205940000003784A4978494A78484B487848010210D458528C8804FA2020FE20508804023C +:205960007E2418FF294A98001F101F101F101F10203E48A810284600F010F010F010F010DB +:2059800000007948487B48497B484B4A7A4A07002020FC2020FE8004FE02FC949494FE001B +:2059A00000037A48497949497948484B7848010200FE0200FC04FC04FC4020FE00880402CF +:2059C000000378494979494879484B487849020000FE50FC5454FC00FC00FE20A824A240E3 +:2059E0000001784B4A78484878484849784803002024A8FE02F88888F82020FC2020FE0017 +:205A00000007F0919FF49497F4979494F79C000008888810DE94A494949494C88894A4C222 +:205A20000002F19791F29492F293949AF1920408404850FC5048440808BE88A83E080808ED +:205A400008FF087E427E24FE001F101F101F101F107E107C442818E600F010F010F010F0B7 +:205A600000007D545454547C545454547C4400000000FE10101010101010101010105020AF +:205A8000001F11111F11111F0000FF080808102000F01010F01010F00000FE202020202070 +:205AA00000007C545455547C545454547C4401022028242420FE2020205050508888040276 +:205AC00000007C545455567C545454547C44010240404080FE0888888850502050880402EC +:205AE00000007D555555557D555555557D460204081CE00000FC4444442828101028448211 +:205B000000007C545556547C555454547D4400032020508804122040881020448810608023 +:205B200001020C37C03F091125023F213F213F20008060D806F820100800F808F808F808D2 +:205B40000000FBAAADA9F9AAAAABACF8890102044020FE020400DE5252529A941012120E76 +:205B600000017C545754557D555555547D44030020FC8850FE00FC24FC24FC20FC20FE0058 +:205B8000003F24243F00007F0103050931C1010100F84848F80000FC0000700C02000000C0 +:205BA000007F44447F00007F011111111111FF0000FC4444FC0000FC0000F8000000FE0019 +:205BC000007F44447F0101FF01011F1010101F1000FC4444FC0000FE0000F0101010F01020 +:205BE000003F24243F01FF003F003F003F203F2000F84848F800FE00F800F800F808F80835 +:205C00003F24243F027F04093FD11F111F010100F84848F800FC4020F816F010F40404FCED +:205C20003F24243F01013F01FF04081F00484484F84848F80000F800FE0020F0108844447C +:205C40007F44447F01FF013F24222F213F212120FC4444FC00FE00F84888E808F8082810D9 +:205C6000007F44447F101019555395111111111100FC4444FCA090FE20FC20FC2020FE00AF +:205C8000007F447F227F223E087F497F08FF080800FC44FC00780848487C0404F404140877 +:205CA0003F24243F08043F29253F001F101F101FF84848F82040F82848F800F010F010F099 +:205CC00001013F0101FF04081F003F242424FF000000F80000FE0020F010F8484848FE00C9 +:205CE00011614D457549497542003F242424FF00001C44449C84445C0400F8484848FE0002 +:205D000044242800FE0028458200FEAAAAAAAFF800FEAAAAFE40FE22FAAAAAFA22FA0A0441 +:205D200010101E20207C9010FE10101214181000000000000000000000000000000000005D +:205D400010101E20207C9010FE1010121418100080808080808080808080808484847C00B5 +:205D600010103D2040BC1010FC101111151910000000FC0810204040808000040404FC0062 +:205D800010101E20207C9010FE1010121418100040404040406050484444404040404040BD +:205DA00010101E20207C9010FE101012141810000404044444444444444444040404140889 +:205DC00010111E20207C9010FE1010121418100000FC040810202020202020202020A040A4 +:205DE00010103C2040BC1110FC10101014181300202020202020FC20202020202020FE0005 +:205E000011113D2141BD1111FD111111151A1204042424242424242424242424242404048D +:205E200010101E20207C9010FE101012141810030808102040880810204484081020C00059 +:205E400010103C2141BD1111FD1111111519110180405E02020202020202020202020A04F3 +:205E600010133D2141BC1010FC1010101418110600FC044424A88888505020205088040237 +:205E800010103C2043BC1010FC1110101418100340404040FE8888888808905020508804F9 +:205EA00010103D2040BC1010FC111210141810000000FE1010202068A42222202020202090 +:205EC00010101E20207D9010FE101012141811022020202020FE20202050505088C8240254 +:205EE00010113D2141BD1111FD1111111519110000FE000000FC04040404FC000000FE0090 +:205F000010103D2141BD1111FD111111151A1204081CE00000FC4444442828101028448244 +:205F200010103C2040BD1210FC11101014181000202050508844222000FC0408081010201F +:205F400010103C2340BC1010FC10101015191204402020FE808080FC8484848404042810EC +:205F600010103C2140BC1010FC10101014191102402000FC0000F0909090909292120E004C +:205F800010113C2040BD1010FC101310141810001010909010109090101EF010101010100E +:205FA00010101E20207C9011FE1010121418110220202024A4A4A82020505050888804021D +:205FC00010113D2141BD1111FD1111111519100000FC2424242424FC040000000202FE0002 +:205FE00010103D2040BC1010FD101010141813000000FC2020202020FC2028242420FE0056 +:2060000010103D2040BC1010FC101010141813000000FE10101090909E9090909090FE00C2 +:2060200010103C2043BC1010FD1111111519110120202020FE202020FC0404040404FC0467 +:2060400010103D2040BD1111FD111111141810000000FE0808E828282828E828080828104A +:2060600010113D2141BD1111FD1111111519110000FE00007C44444444447C440000FE0086 +:20608000202038234078A121FB25212129312000404040FE80A020FC2424242434282020E9 +:2060A00010103C2043BC1010FD111111161A140150484840FE8080FC4444282810284482E0 +:2060C00020203820437AA222FA2222222B32200028242420FE20242424282890122A4682CC +:2060E00010113D2141BD1111FD1111111519110100FC040404FC040404FC04040404FC0475 +:2061000010103D2141BD1111FD111111141813000000FC040404FC040404FC040000FE0064 +:2061200010103D2141BD1111FD111111151911010000FC2424242424FC2424242424FC04F1 +:2061400020203B22427AA223F82021212A342000083CC000202020FE202028242222A04037 +:2061600010103C2340BC1111FD11111115191000402000FE2020FC2424242424342820202A +:2061800010103C2140BC1010FD10101014191000201010FE20204484F810204482FE820048 +:2061A00010103C2141BE1010FC10101014181000201010FE0204808890A0C08282827E009B +:2061C00010103C2040BC1011FD11121014191200402028080848545252606044C4443C0097 +:2061E00010113D2141BD1111FD111111151A120400FC040404FC00404448704042423E0049 +:2062000010103C2141BD1111FD111111151A1204101010FE121410FC444428281028448236 +:2062200010133D2040BC1013FC1110101718100000FC04885020D82620FC2020FE202020A3 +:2062400010103D2040BD1010FD121410141810004044F44850FE4080FE4080FC040428106D +:2062600010103C2140BC1310FC11121014181000404044F44850FE40808498E082827E008B +:2062800010113C2040BC1010FC1010101518100000FE888888F88888F888889EE8080808B8 +:2062A00010103D2040BC1011FE101010141810002020FE4040FC8484FC8484FC84849488F4 +:2062C00020203820437AA222FB2222222A35240828242420FE202424A4A8A89092AA46823B +:2062E00010103C2140BD1010FC13101014181102202020FC2024A4A820FE505088880402D6 +:20630000202038234078A023F8232020293122048080BCC05024D40C00FE909012120E006C +:2063200020273844447CA720F921222A3428020100DE92929494D8949292929A94909010A4 +:2063400010113C2040BC1310FC101110141813002024A4A4A820FC040404FC040404FC04D1 +:20636000202139214178A023FA2222222A32200000FC0404FC2020FE222222222A242020D6 +:2063800020233A22427AA322FA2222222B32230200FE02222222FE2222524A8A0202FE0229 +:2063A00010113D2141BC1110FC1111111519100020242424FC00FC0404FC00000202FE0049 +:2063C00020213921417AA023F820202129322000202020FC202020FE70A8A82424222020AC +:2063E00020203B204079A123F8222221293224080006B88888083E888888883E00807E0031 +:2064000010103D2040BD1010FC13101014191301083CE02020FC202020FE20408804FE02C8 +:2064200010103D2143BD1111FD10131014181000909414181032520E2020FE202020202080 +:2064400020203821427CA320F8202320283027004040A0100806F8404040F8404040FE009C +:2064600020203821427CA320F82322222A3223024040A0100806F80000F808080808F808D4 +:2064800010113C2040BC1110FF101010151A10000488502050882420FE20A8A42222A0404E +:2064A00010103C2140BC1010FC1112101418110250505052D4585058D45250509292120EB5 +:2064C00020203922407BA020FB202023283020008080F80810FC2424FE2424FC2420A04016 +:2064E00010103C2142BD1111FD111111151910008080F80810FC242424FC00000202FE001A +:2065000010103C2340BC1113FC10101015191204402020FE408804FE9290909012120E00B0 +:2065200022213924427AA021F92226222A332200007C040810207E2A2A2A4A5292224A848A +:2065400020203823427CA023F820212028302003402020FE024440FE888808D02050880465 +:2065600021213921477AA222FA2422212A3224080000001ED252525252929212925E520061 +:2065800020203B20407BA224F8232020283122048888FE8800FE024440FC44848404281067 +:2065A000202038234079A020FB20202029322400202020FE2024A4A8FE70A8A824222020BB +:2065C000202038204378A020F82020222A32240010141210FE109050480888A89AAA66026E +:2065E00020223A22427AA220F82021202830230080FCA4A4A890A8C62020FC202020FE00A7 +:2066000010113D2141BD1010FD1010111418130000FC040404FC0000FE2020FC2020FE00F4 +:2066200010113D2141BD1111FC1011101418130000FC2424FC2424FC2020FC202020FE0031 +:2066400020213921417AA023F820212129312101202020FC202020FE0000FC040404FC0489 +:2066600020203B20407BA020F82023202830220110D8949490FE909494D89890AACA8602DC +:2066800010103D2141BD1214FC10111014181300202024242424AA722020FC202020FE0066 +:2066A00010103D2041BC1010FD10101014181000041EE02212948008FE0888484808281027 +:2066C00020203B204079A320F92121212A3224084020FC409008FC04505050505052520E49 +:2066E00021203A22427AA222FB2222222B32220200BE8202FA525252FE52529212020A0413 +:2067000021203A22427AA222FA2222222A32220200BE820202FA8A8AFA8A8AFA02020A0410 +:2067200010103D2141BD1111FD111111151911014020FC0404FC0404FC20221408448200C3 +:2067400010113C2040BD1013FE1110101418100300FC04FC04FC00FE02F888885020D806DC +:2067600020233A42437AA223FA22222A3424080000F80808F80000FC04F49494F4042810C4 +:2067800020273D25457DA625FD2525252E342404007E040474545454545474540404140843 +:2067A00020203B204178A320F9212121293121012020FE20FC20FE00FC04FC04FC04140856 +:2067C00020203B204078A320F8202122283020008888FE88A820FE4080FC84848484FC8428 +:2067E00020203B204079A220F8202320283021022020FE50A824FA20A888FE888888080863 +:2068000010113D2141BD1011FC1310111418100000FC04FC04FC00FE08FE08088808281096 +:2068200010113D2141BD1111FC131010151A100000FC2424FC2424FC20FE70A8242220200B +:2068400010113D2141BD1111FC1111111519110100FC0404FC0404FC0012D4181052920E26 +:2068600010113D2141BD1111FD1111111519110100FC042424FC2424745454740404FC04E5 +:20688000202038214278A122F82120202A3224008080FC5454A42444940840A4AA8A78002D +:2068A00010103D2041BC1013FC101111151911014020FC00089000FE0000FC040404FC04D3 +:2068C00010113C2041BC1310FD121410141810002024A820FC40FE8804FA8888A892827E96 +:2068E00020223A244079A620F82222242831220C40444448A010084440484850A0100806A8 +:2069000010103D2241BC1010FD111111151911019292244824929200FE2222FE2222FE020F +:2069200021213B214379A721F92027202831220C003CD4149414D4244C40FE40A010080602 +:2069400011113D2141BD1110FD111111151911011012D41852922E40FC0404FC0404FC04C0 +:20696000202139214179A121F82020222A34200000FC2424FC2424FC004024A28A88780014 +:2069800020233A224378A120FB2021212830200000DE5252DE00FC00FE8000FC04042810F1 +:2069A00010103D2040BD1010FD11111115191101083CE02020FE20A02C2424AC2424FC0443 +:2069C00010113D2141BD1111FC11101014181003A02C2424AC2424FC20FC885020508806B6 +:2069E00010133C2140BD1010FD101011151A10011EE0442488FC4040FE80FC44281068863E +:206A000020203B204179A121F92020212A3420004020FE00FC040404FC52948888A4C28049 +:206A200010113C2043BC1112FC131011151811062024A820FEA8240240FE88089060980411 +:206A400010103C2241BC1010FD1214101418100090909EA2D48894A4FE84A494948494884A +:206A600020273823427BA122FD2121212930200390FC94FC90FE1216FC04242424508804FE +:206A800020233A42437AA222FA22222A3424081000FC2424FC00FC8484FC84FC8484FC8496 +:206AA00020203B204079A121F9212023283021028888FE8800FC04FC04FC20FE508804025A +:206AC000202338214179A120FB2222232A32220200FE00FC0404FC00FE8A52FE22222A0475 +:206AE000202039234579A121F921232028312204A090FE20FC20FC20FE00FC889E020A04E8 +:206B000010103C2142BC1010FC111011141B10002050887402F888F80CF020FC20FE2060D1 +:206B200020233A22427AA320FB2222232A32230240BE129252AA2440FE2222FE2222FE02CE +:206B4000212038204378A021FA2121212931270004848800FE00880402FC54545454FE005C +:206B600020203B224079A020FB202023283023004020FE0200FC40A2345894345290502042 +:206B800020203B224479A121F9212127283021024020FE0214E00000FC1010FE00900804F2 +:206BA00010133C2141BD1110FD1013101419120000FE50FC5454FC00FC00FE20A824A24011 +:206BC000202138234278A020F8202021283023002024A8FE02F88888F82020FC2020FE0065 +:206BE000202139214179A023FA2320212830210600F808F808F800FC94FC00F89060980696 +:206C000010113D2141BD1010FD1010131419120000FC24FC24FC4088F02044FE222422604A +:206C200020273C254477A425FC2525252D39291120FE20FC24FE24FC20FC24FC24FC242CF5 +:206C400022213947427AA322FA22222A34250810202020BE4020BCD09090FE90A8A8448249 +:206C600022213947427AA322FA22222A34250810101010BE4000BE8A88A8AEA8A8A85E80CD +:206C800020203B20407BA222FA2222222A3222024020FE8850FE22FA22FA8A8AFA020A0470 +:206CA00020233823427BA021F92121212833200000FE50FE52FE00FC04FC04FC20FE2020EB +:206CC000202F384A497BA828FA2A2B283829091200FE002848EE9284A0A8E8889414244224 +:206CE00020243A204779A027F82320272831220CA0A4A8A0FC10A0FC40F840FCA010080620 +:206D0000202039234579A121F82320212931210180F810FC24FC24FC00FE00FC04FC04FCC1 +:206D200021203B20437AA320FB2020202B3022010888C810DE64D414D45494E88894942256 +:206D400022213D24457CA525FD2525252C352404007C0444F444F45474D454F4E454444C73 +:206D600021203B204279A027F8212121293121010890FC90949890FE00F80808F80808F838 +:206D800020203B22417AA121F92023222B3220004020FE8A2422FC24FC20FE22FE22202014 +:206DA00020233820407BA222FA2320202830250200BEA2A2BE88083E2AAAAABE888A7E0281 +:206DC00020273822417AA528FB2222232A312F0020A4A8921408F402F80808F80810FE0078 +:206DE00020233820417BA121F92121212B30200388FEA890FE20FC20FC20FE00FC88708E0C +:206E000020233A224379A324FB2222232837200000F8A8A8F800FC84E4A4A4E494F41408FB +:206E200020203920407BA021F9212121283222044020FC8850FE00FC04FC04FC20948A7A7B +:206E4000202037444A73A42AF5222423283224008040FE0224BCA4A810E804F8404844C0A4 +:206E600020203B22437AA322FA2222222A34250A4020FE50FE52FE0094D890D28E00542A30 +:206E800010103D2043BC1111FD11111015181300083CE020FE20FC24FC24FC20FC20FE000D +:206EA00020213C50901111FF111110282444418004E4242424E4040404E424242424448451 +:206EC0002020217D519112FC1010112824444380202024242424AA722020FC202020FE00DA +:206EE0002020207D519315FD1111112925454181A09080FE1010FC1010FC101010FE000023 +:206F0000081DF11111FD11313955559111111110101010121214D8101010101252920E00BF +:206F2000081CF01111FD1139345450911610101020202EF0202020FE2262A22A2420202095 +:206F4000081CF01310FC10313854549111121010202020FE202020FC70A8A82424222020E5 +:206F6000081CF01017FC1038355152941810101040504840FC40E0E050504844424040409C +:206F8000081CF01010FC1038345551911111111100FC84848484FC0000FE02020202FE02BC +:206FA000081CF01310FC10383554509111111110484440FE505092920E2020242424FC0461 +:206FC000081CF11011FC10393450539010101010041EE002229400FC0810FE101010502023 +:206FE000081CF11111FD113139555591111111114020FC0404FC0404FC20221408448200DB +:20700000081DF11111FD1131385754901112101000FC2424FC2424FC20FE70A82422202003 +:20702000081CF01011FE11383454509212121410202050884422F8085020A4828A8A780082 +:20704000081CF31011FD113935555191171011122020FE20FC04FC04FC04FC04FE88040211 +:20706000081DF11111FD10313A5451921010111600FC24FC24FC884442F8885020508806CA +:20708000081CF31011FC133039555591111111112020FE2024A8FE00FC0474547404FC0459 +:2070A0000C7010FE385490285591553955935121202020203E202020FC0404040404FC0406 +:2070C000047810FE113A54907C44447C45447C454040FE80FC84FC84FC407CC4281068868D +:2070E00010E7202322FB21376967A12F21232D2140FC00B8A8B810FC10FC10FE281048862F +:207100001010207C444444447C444444457D4600040EF08080FCA4A4A4A8A890102844828B +:207120001010207B4848494A7848484848784906402020FE008804028888502050880402A8 +:207140001011217D454644477C444545457D4501202020FC202020FE0000FC040404FC0446 +:2071600008087E182C2A488809041F101F101F100CF08080FE8888880800F010F010F0100F +:20718000101321784B48494A79494949497949013CE024A8FEA82402FC2424FC2424FC0471 +:2071A0000207382A2A2B2A2A2A292928284A4D891010507C9010FE102824428240300E00A7 +:2071C0001010FE2844827C00FE20407C04052912081CE8A8A8A8A8A8A8A4A4A4A2283424FF +:2071E000003F0006013F21213F21213F2121212000F0204080F80808F80808F80808281065 +:2072000020202020FC24242424242526454080002040FC84A484948880FE0202FA02140830 +:20722000040402FF0000021F1412101F007F000020103EC0804232EE206000F80888281000 +:207240004048506044443C101010FE10111010102040FC84A484948880FE0202FA021408F5 +:207260000808087F49080814141414252644800010207C446454444C407E02027A020A043B +:2072800010101010FE1010107C444444457C44002040FC84A484948880FE0202FA02140875 +:2072A000101010FF202848487E082C2A4989281010207C446454444C407E02027A020A045D +:2072C00010101E10107C4444447C4440414080002040FC84A484948880FE0202FA02140849 +:2072E0002020407E82027A4A4A4A7A4A030214082040FC84A484948880FE0202FA02140811 +:2073000001077C444444447F444444424252694410A07C446454444C407E0202FA828A8407 +:20732000102478107E00FF02041F12111F007F002048F020FC00FE0000E02060FC04D40880 +:20734000007F0808107F5555555555555551454210207C446454444C407E02027A020A0460 +:207360001010FB1019F01152241F12111F007F008080F0909094540C04E02060FC04D4082E +:20738000040E380808FF08083E222222233E22002040FC84A484948880FE0202FA0214089F +:2073A000121212222F62A6272A2A32222222222208103E22B22A2226A0BE02027A020A045F +:2073C0000201FF041424421F1412101F007F00000000FE40504804E0206000F80888281040 +:2073E0001010FE1010FE82047808101EF11050202040FC84A484948880FE0202FA021408EE +:2074000000FF0000F7949494D6B59494949494B508903E22B2AAA2A6A0BE8282FA828A840E +:207420000848487F880808FF00007E4242427E4210207C446454444C407E02027A020A0416 +:2074400028244292102844827C444444457C44002040FC84A484948880FE0202FA02140803 +:20746000402F014949497F495D6B49494941454210207C446454444C407E02027A020A040A +:20748000442428FC1414FC9090FE3232539610102040FC84A484948880FE0202FA021408F3 +:2074A0000406750504FF0414145C5454555DE34110207C446454444C407E02027A020A04BB +:2074C0002222FF2222007F4949497F4949497F410810BE22322A2226203E02027A020A0429 +:2074E0000808FF142249887F497F497F080A0C080810BE22322AA226203E02027A020A0439 +:2075000010207F49497F49517F2444FF0404040410207C446454444C407E02827A020A0417 +:207520001008FF007E427E007E04080FF808281010207C446454444C407E02027A020A04A1 +:20754000202724FC242724745457545474080A110890BEA2B2AAA2A6A0BE8282FA828A04EF +:207560000077555577007F00FF203F0101010A0410207C446454444CC07E02027A020A0481 +:20758000211112FF2121425294E721424294F71008103EE2322A22A6A03E02027A828A84CF +:2075A000007F49497F405F51515F515F51519F1110207C446454444C407E02027A020A0415 +:2075C000007E2418FF294A9A041F12111F007F0020207EA4281028C600E02060FC04D4083D +:2075E0000EF0229244203C5010FE1054555C64002040FC84A484948880FE0202FA021408A4 +:207600002214007F147F15FF157F14365594141410207CC4645444CC407E02027A820A041B +:20762000007755555555225508FF1222340C32C110207C446454444C407E02027A020A0416 +:2076400010087F4052527F52525E40555555800010207C446454444C407E02027A020A04EB +:207660000077115533550C33C418620C710618E010207C446454444CC07E02827A020A0429 +:2076800008087F08552241BE223E223E082A491810207C44645444CC407E02027A020A0486 +:2076A00028247EC8487E48487E48487E41AAAA002040FC84A484948880FE0202FA02140803 +:2076C000087F003E223E499A041F12111F007F002824FE205050528E00E02060FC04D40898 +:2076E0007E1408FF294AA8107F55635D555D414310207C446454444C407E02027A020A0478 +:2077000010217C446455444C407C0404F504140944FE5448FE90FE90FE90FE80FE4438C60F +:20772000003E233E092E287E041F12111F007F0040FC4830CE78487800E02060FC04D408F3 +:2077400022FF22F794F728247F48FF487F487F4008903EA2B2AA2226A03E02027A028A047C +:2077600000001F109050501030509010202040808040FE00000000000000000000000000BC +:2077800000001F109057501030509010202041808040FE0000FC40404040404040404080D8 +:2077A00000001F109057501030509010202040808040FE0000FC848484849488808080804D +:2077C00000001F109057511131519112222448908040FE0000FC0000F808080808085020A4 +:2077E00000001F109050501434549414242740808040FE00404040444444444444FC0400C5 +:2078000000001F109352521232529212222444898040FE00FE002020FC2424444484A810B1 +:2078200000001F109050501730519111222244888040FE00908880FEA02020202222221EC7 +:2078400000001F1092525F1232529312222243828040FE000808FE080808F8080808F8087E +:2078600000001F109057501033529213222040808040FE0000FE0808C84848C848082810F2 +:2078800001003F2020A764242764A42720405F800080FE0000F80808F80808F80000FE0020 +:2078A00000001F129253551931519111212141818040FE0000FE0000F80000FC000000006C +:2078C00000001F129253541B32529312222242818040FE0000FC04E42424E414080202FE07 +:2078E00000001F10905057103050931020204F808040FE804000FC404040F8404040FE00F0 +:2079000000001F10905F501132579010212247828040FE8040FE800810E040801008FC04E7 +:2079200001003F2424A46F242464A424284852A10080FE000000BCA4A4A4A4A4A4BCA40063 +:2079400000001F109053501034529210202047808040FE0000FC9090929294989090FE003E +:2079600000001F109F505F10375497102021428C8040FE40FE40FC44FC40FE42AA14080675 +:2079800000001F109050571030539010212545888040FE004040FC4040FC0040242A0AF8F5 +:2079A00000001F1191575110375490172021428C8040FE0808FE0800FE0240FC840428103D +:2079C00000001F1097505310315F9013222243828040FE00FC80F88808FE00F80808F8082A +:2079E00000001F1090525215385090172020408F8040FE4040484854E24040FC404040FE93 +:207A000000001F109251541435549415262444848040FE00007C0444F444E45444445408D2 +:207A200000001F109251511432529116222242808040FE101010545292101404081020C058 +:207A400001003F202FA163242D62A529224459800080FE00FC0008885060E050504844808D +:207A600000001F109050571030539010272040808040FE0090909E90909C90909E909090C0 +:207A800000001F109754541734559515252447848040FE00FC4444FC44F41414F404FC0484 +:207AA00000001F1097505F11325C901F2123408F8040FE38C040FE50484680FE0810E01C8C +:207AC00001003F2022AC68282E68A82F21424CB00080FE0080B88888B88888F84020180618 +:207AE00001003F2024A26F242467A424284852A10080FE001010A82844928888A090880803 +:207B000000001F1291575417345794102F2040808040FE0810FC44FC44FC4440FE4040400F +:207B200000001F119157511735579113252941818040FE0004C414D454D414945444140893 +:207B400001003F202FA4623F2162AC302F40409F0080FE80F890A0FE40209886F88080FC0E +:207B600001003F2022A2642D3464A524254444850080FE00F80808FE80F82020FE508806A5 +:207B800000001F119057501330579113242847808040FE10A0FC40F880FC00F84040FE0099 +:207BA00000001F12915F511234509F11232041868040FE4850FE50484480FE0890609804C1 +:207BC00000001F109754541734549714242744848040FE00BC8484BC007CA4242890284632 +:207BE00000001F1097525110335C9312232047808040FE00FC4810E01846F848F844FC0402 +:207C000000001F119751531137519110202545888040FE00BC149414A44C004024220AF8FF +:207C200000001F1197515312335293102F20438C8040FE10FC10F808F808F840FEA01806B3 +:207C400001003F242FA96D2B3F69A92D2B4949930080FE00784848860078484828102846C8 +:207C600000001F1492545112375A9312232242828040FE4448A41008FC0AF808F808281005 +:207C800001003F222FA27F202F68AF282F4244880080FE20F820FC80F888F888F820100805 +:207CA000003F203FA16F292F60A7202F2244498080FE00FE20FC24FC00F800FC484442803F +:207CC000003F2027A467242761A227202F44499080FE00FC44FC44FC0008F0C4FE48448270 +:207CE000003F202FA86A2A2A65A83F222740439C80FE00BEA2AAAAAA14A2FE0810E01C0236 +:207D000001003F2223A46A252265A827224449800080FE20BCA4A81008F600FC504844801A +:207D2000003F202FA96A2C2A69A92D2A2848488880FE203C44A810284638507E907C10FE3F +:207D4000003F202EAA6B2C2A6AAA2B2E2849498A80FE40788810FC04FC04FC2014524A38A8 +:207D6000003F202FA965292166B8232C214E418E80FE007C2414A460188620408830C000C6 +:207D800001003F202EA46524256EA424244659820080FE804E44F42424AE4444A4A40E0030 +:207DA000003F222FA2622F2A6AAF22272A52428280FE109C2448BEA2AAAA2A2AAA942242F4 +:207DC00000001F1097515F1033529312232545888040FE40FC10FE00F808F808F8442AFA76 +:207DE00001003F202FA86F2A2A6FAA2F285254A80080FE00DC54D4A280DC94D4088854629D +:207E000001003F2027A464272464AF2C344744800080FE1088BE80A2943E8888BE8888085C +:207E2000003F243FA46F292F69AF292F297F499080FE00BE08103E222A2A2A2A2A9412A276 +:207E4000001F141794571437519312172A23428380FEA4BCA4BCA4BC20FE20FC20FC20FE71 +:207E6000201310FC02098988484952501CE0410000DE4242524A4A42C64A524242424A84B7 +:207E8000201013FC00098989494850501DE240002020FE2020FC2424FC2070A8242220209C +:207EA00002017F40881022040F10680402031CE00000FE0224100800F0102040800000009A +:207EC00002017F48902F00001F10203F000000000000FE2214F81010F00000F808085020D7 +:207EE00002017F489121FF012121213F010101000000FE221408FE00080808F80A0202FE0B +:207F000002017F4890013E02017F00010E3048870000FE2214F0000000F86080000000FE3E +:207F200002017F4890080812227C0814227E21020000FE22144040F8484848488888281034 +:207F400002017F4890044424240C34C8081020400000FE2214404850604060524A423E008F +:207F600002017F48912F017F041209FF020418600000FE2214E800FC848800FE60100804BD +:207F800002017F48903F111F111F01FF050931C10000FE2214F810F010F000FE4020180640 +:207FA00002017F49920C37C03E223E223E2222260000FE229460D80608484848480828109F +:207FC00002017F4A913F0804FF001F101F101F100000FE2214F82040FE00F010F010F010E3 +:207FE00002017F4891097F05196104FF081E033C0000FE221420FC40300C00FE2040C03895 +:2080000002017F48900638282C2A2A2A28555D820000FE22141CE8A8A8A8A8A8A45474129C +:20802000201000FC0810103458941410101010100000000000000000000000000000000068 +:20804000201301F909101034589414101010111600FC044424A88888505020205088040261 +:20806000201000FD091111355995151111111111202020FE22222222524A8A0202020A04FB +:20808000201001FC081010355894141010101110083CE020202020FE202020202020FC00A7 +:2080A000201000FC081112345895141010101010202050508844222000FC040808101020A6 +:2080C000201000F9081014385590101010101112202020FC24242424FE205050888804020B +:2080E000201001F8081015385490131010101010202024A4A820FC202020FE2020202020E1 +:20810000201100FC0810133458941510101013102024A4A4A820FC040404FC040404FC041B +:20812000201000F8091211345895151111111111202050880402FC0000FC04040404FC043A +:20814000201000F90B14103459961511111111118080F80810A040A01806F8080808F8087C +:20816000201101F909111135599515111111111100F80808F80808F844483020104886005A +:20818000201201F90810173559951511111214101010107E2028487E0808FE0808887E0014 +:2081A000201101F909111034599414111010131000FC040404FC0000FE2020FC2020FE0065 +:2081C000201000F8091211345894111010101310202050880402FC00442424A88810FE00E3 +:2081E000211002F21222226AB22A22222222222200BE820202FA8A8AFA8A8AFA02020A0486 +:20820000201003F8081110345B941411121410102020FE2020FC2020FE40A4A89088C680DA +:20822000201001F80813143854911210101010102022FA2428FE2040FC8484FC8484FC84F9 +:20824000201101F909111539549112141112101100F80808F80808F880FC549424449408CC +:20826000201003FA0A13163A57901117101010104080FC2424FC2444FC9010FE10101010D3 +:20828000201302F21322226BB22A22222224242800FC0404FC2020FE2020FC848484FC84BD +:2082A000201700F211222468B02F20222122242800BC84940894A44000BCA4A42890A84628 +:2082C000201003F80810143956901011111111118888FE8820508804FA0000FC0404FC0433 +:2082E000201003F80813103559951511111111115052DC50D24E00FC04FC04FC040414088D +:20830000211101F212262A6AB22A222222232222007C4444447C1010FE385454941210103B +:20832000201100F01320216AB02B2021212021262024A820FEA8240240FE88089060980488 +:20834000201003F21223226AB32B2325252529218040FC0404FC0000FC5454FC5454440C25 +:20836000201101F909111134589515111111171048484E506844444000FC54545454FE006F +:20838000201003F21222226AB22A22222224252A041EF01E10FE9298F28E80B8A8AA4A8601 +:2083A000201300FA09121034599515111111111100DE42524A524220FC0404FC0404FC0461 +:2083C000201300F01023226AB22B20202020252200BEA2A2BE88083E2AAAAABE888A7E02BB +:2083E000201100FB0A111439549310111111111100FC20FE22AC20AC00FE20FC5454540CC7 +:20840000221207F2172A226FB22D282320272020A848BEA85CAA88FE18E442F840FC40C058 +:2084200000007F010101111111111111292543800000FC0408000000F80000000000FE0045 +:208440007F011111112947801F101F101F101010FC0400F80000FE00F010F010F010502066 +:2084600000FF9110FE2028487E08080EF849090A101010FE929490FCA4A4A8A890284482E8 +:2084800010102044FE2844A23C4444A810294582101010FE929490FCA4A4A8A890284482EA +:2084A000007E02241809FE0A1819284888082810202050508844222000FC04080810102048 +:2084C00001017F01013F0101FF03050931C101010000FC0000F80000FE80402018060000E4 +:2084E000101010FC107810FD103834549010101000FC0408081010FE10101010101050202D +:20850000101010FC107811FD1238345490101013202020A8A4A22220242428081020C0000C +:20852000101111FD117911FD113935559111111100F808080808F80000FC04040404FC04C0 +:20854000101010FC117A11FC1039355591111111202050880402FC0000FC04040404FC049A +:20856000101013FC107B12FC103B3454901112148888FE8800FE024440FC448484042810FB +:20858000101110FC107B12FE123A3652529212122024A4A820FE0202FA8A8A8AFA020A04E3 +:2085A000111111FD117911FC103B365252921212FC2424FC2424FC2020FE222AFA0A0206FF +:2085C000101110FC137811FE103B3451519011162024A820FEA8240240FE880890609804CA +:2085E000101013FC117813FC11393551539111118888FE88FC88FE20FC24FC24FE04140848 +:20860000101111FD117911FD113935515192121400FE007E00FE5448644208FE4828081868 +:20862000101013FE137A12FF123B3652529314184020FE48FE48EC5A48FE207CC4447C44A9 +:20864000023F02FF020F34C3007F081F011F017F20C080FE20C008F800FC20F000F000FC54 +:2086600000FF22223E22223E222227FA4202020200807E080808080808088808080828103C +:2086800000FF24253D25253D25252FF545050505202020FC2424FC242424FE0404041408DA +:2086A00000FF24243C25263C25242EF4440404042020505088241210FC0408885020101027 +:2086C00000FC484B7A4C48784B484C78C8080808402020FE02040000FE2020202020A0404C +:2086E00000FF24243C25243C24242EF444040404081CE02020FE202020FC84848484FC848A +:2087000000FC494979484B7849494D79C908080B2020FC24FC20FE00FC0424242450880449 +:20872000087F087E08FF101E227F880F08FF000020207E44A428102844FE20E03EE0202012 +:20874000FF043F243F001F101F101F01FF010101FE40F848F800F010F010F000FE00000090 +:2087600000791010111111FD111111111010111200FE2040FC042424242424445088040275 +:20878000081C604040407E48484848484848880B00FE2040FC849494949494A43048840228 +:2087A000100808FF00003C24242424254644800300FE2040FC849494949494A43048840238 +:2087C000101010FE10107C00007C4444447C440300FE2040FC849494949494A43048840260 +:2087E0001010282442807C00007C4444447C440300FE2040FC849494949494A43048840260 +:2088000020243822221E00080AEC282C4A4AA81300FE2040FC849494949494A43048840275 +:20882000100808FF0810227C091224C81422C00300FE2040FC849494949494A430488402FF +:208840000808142251887E0204087E42427E420000FE10207C4454545454545428244282B5 +:2088600000EEAAAAEE00FE00FF407E020202140800FE10207C4454545454545428244282F5 +:20888000084949497F00FF08107F555555555543007E10207C44D454545454542028448200 +:2088A000007F223E223E23FE02F7115522558910007E10207C44D4545454545420284482F5 +:2088C0002424FF2400FF2424FFA5A5DB9181858200FE10207C4454545454545428244282B3 +:2088E000007E221C2277552255087F1C2A49880800FE10207C4454545454545428244282BB +:20890000007F417F417F08FF007F417F08498818007E10207C4454D4545454542028C482AD +:20892000007F08FF886B086B00FF087F55555543007E10A0FC44545454D45454202844828F +:20894000082E28FF2A4C32C43F213F223F08FF0000FE207C54542844F808F808F880FE80A3 +:2089600001010101013F20212121212F214140800000F80000FC04080018E0000404FC00C2 +:208980000101013F21212F2021202F222140438C00F800FE02F004FC0080F8204080601C86 +:2089A0000808087F494949497F48080A0FF1400040404040404040404040404444443C001B +:2089C0001010107C545454547C5010141CE541020000F090909090909090909292120E00B3 +:2089E00000FF0407081020413F21213F01017F2000FE00F01010A040F80808F80008FC049D +:208A00000000FE25252525252424242524444380202020FC242424FC202028FC0402FE00B7 +:208A20001010107C555654547C5010141DE54000404080FE0000FC08102040800202FE0011 +:208A40001010107C555454547C5010141EE2400020101000FE808080808080808080FC002F +:208A60001010107C555454547D5010141EE2410220202020FC202020FE2050508888040215 +:208A80001011117D555555557D5111151DE54100101010121214D8101010101252920E0018 +:208AA0001010107D555555557D5111151DE54101202020FE22222222524A8A0202020A045D +:208AC0001011117D555555557D5110141CE5420400FC040424242424245450909012120EAC +:208AE0001010117C545455547C5013141EE24000083CE020203CE020203EE0202222221EC3 +:208B00001010107C545556547C5010141CE54102202050508804028888888888880808086C +:208B20001010107C545454557C5010141CE54000084848484484A4222040404884FE8200AD +:208B40001011107C545554547C5013141EE240001010909010109090101EF01010101010F6 +:208B60001011107C545555557D5110141CE4410004E4242424E4040404E424242424448442 +:208B80000121213F01FF00013F21213F01017F20000808F800FE0000F80808F80008FC04E3 +:208BA0001010107C555454547C5010141EE2400088888888FE88888888F888888888F888B2 +:208BC0001010107C555454547D5111151DE5410120202020FE202020FC0404040404FC0472 +:208BE0001010137C545555557D5111151CE440000000FE0808E828282828E8280808281051 +:208C00001011117D555555557D5111151DE6420400FE000000FE20203C24242424445488EC +:208C20001010107C555555557D5111151DE5410120202020FC24242424FC24242424FC0464 +:208C40001010107D555555557D5117151DE54101202020FC2424FC242424FE0404041408A3 +:208C60001010107C555556547C5010141EE24000808080FE4040407C4040407E40404040CC +:208C80001010107C545454547C5010141CE44300040EF080808080FE888888888888FE0077 +:208CA0001010107C545556547D5010141EE240002020505088241210FC04088850201010B6 +:208CC0001011107C545454547F5011141CE4430000FC8488502050882620FC202020FE0070 +:208CE000202020F9A9AAABA8F9A1222B38E84000109090107E529292121252D262224A8460 +:208D0000007D1111111DE2451F11111F11017F2000F0109052120E00F01010F00008FC0444 +:208D20001010107D545554547C5310141EE24102202020FC2024A4A820FE5050888804023F +:208D4000202020FBA8A8A8ABF8A3202839E942048080BCC05024D40C00FE909012120E00AA +:208D60001011107C545555547C5011141CE4430000FE20408804FE222020FE202020FE001A +:208D8000202020FAAAAAAAAAFAA2222839E9420480BE8888BEAAAAAAAAAAAAAA2E0808088B +:208DA0001010107C555555557D5111151DE5410150505050FC54545454FC54545454FC04A3 +:208DC000202023F8A8A9A9ABF8A2222939EA44080006B88888083E888888883E00807E00CF +:208DE0001010117C545754547C5111151DE54101083CE02020FE202020FC04040404FC046E +:208E00001010137C545454547D5010141CE541024020FE88502050880688888888080808B2 +:208E20001010107D545455567C5010141CE44003402020FE00880402888850502050880645 +:208E40001110107C575454557C5013141EE2400004848800FE2020FC2020FE2020202020B6 +:208E60001010107C555454547C5110171CE4400020204884FE129090FE1010FE1010101029 +:208E80003F202F203F242426202F28484F801F08FC00F800FC48300E80F88888F884FE0248 +:208EA00008087E080E78082912013F213F017F000CF08080FE8888080800F808F808FC0419 +:208EC0001011107C545555557D5111151DE541012024A4A820FC0404FC0404FC0404140882 +:208EE0001011117D555454557C5013141CE4410200FC0404FC0000FC2020FE205088040203 +:208F0000202127F9A9A9AFA9FBA3252D39E9410184C404141414D41414945404040414085E +:208F20001010107C555654547C5310151DE64000202050880402F82020FE20242222A0403F +:208F40001010117C555454557C5013141EE24000083CC00444A800F81020FE202020A04085 +:208F60001010107D545455547C5310141CE44102884850FC2020FC2020FE50509092120E45 +:208F80001010137C555457547D5111151DE541012020FE20FC20FE00FC04FC04FC04140802 +:208FA0001010117C545454547C5010151CE441028888FC8888F88888F88888FE00880402C8 +:208FC000212121F9AFA9A9ABFBA5252939E9410100063820A0203E24A464242424242444B7 +:208FE000202020FBA8A8ABAAFAA2232838EB4100141210FE1010D2525254D40C6A8A1622FC +:2090000004047C043C047C04011F11111F017F2040407C4078407C4000F01010F008FC044F +:209020001011117D555555557C5310141DE6400000FC2424FC2424FC20FE70A824222020B7 +:20904000202322FAABAAAAAAFAA2222B3AEA430200FE0202FE2222FA22322AFE0202FE02F8 +:209060001010107C545454547C5011141CE5400000FC8484FC8484FC40FE2A4A92224A848A +:209080001010117D555555557D5011171CE440004080FC2424FC2444FC9010FE1010101057 +:2090A0001011117D555555557D5111151DE6420400FC24247424FC047454547404041408E0 +:2090C0001011107C555457547D5214141CE440002024A820FC40FE8804FA8888A892827E42 +:2090E000202023FAADA9A9AAFAA3242839E942044020FE020400DE5252529A941012120E71 +:20910000212023FAAAABAAAAFBA2222A3AEB4200009ED25254D45854D212925AD45010104E +:209120001011107C545754547C5111151DE5430000FC081020FE20A040FC54545454FE007B +:209140001010137C555457547D5210141CE440002020FE20FC40FE8804FA8888F88888F8AB +:20916000202023F8A8ABAAACF8A3202838E942008888FE8800FE022420FE70A8A8242220A7 +:20918000202023F8A8ABAAAAFAA2222A3AEA42022020FE2020FE8A52FA2222FA22222A047B +:2091A0001011107C545454547D5111151DE5410100FE00FC8484FC00FE2222FE2222FE02F8 +:2091C0001010137C545755547C5310141DE440032020FE508826FC2020FE0020FC2020FE85 +:2091E000202721F9A9AFA9A9FBA3252D39E94101C40424141484241494463C040404040416 +:209200001010107C555654547C5010141DE440014040FE80FC84FC84FC407CC4281068867D +:209220001011117D555555557C5110141EE24003A02C2424AC2424FC20FC88502050880601 +:20924000202021FAADA8ABAAFAA3222A3BEA420240A01008F600C45454D45454D44454C8AD +:20926000212020FBA9A9A9A9F9A121293AEA4408088888DE1020DE4244445E444444D408C6 +:20928000202120F8ABA8A9AAF8A7202939E841062024A820FEA8240240FE8808906098044D +:2092A0001010107D545455557D5111151DE54101884850FE5050FC54548C04FC0404FC0481 +:2092C0001010117D555555557D5112141CE440002010FE0202FE0000FEAAAAFEAAAAAA8654 +:2092E000007E2418FF294A98011F11111F017F2020207EA4281028C600F01010F008FC0419 +:20930000202027F8ABA8AFA9FAA5202B38E946004040FC40F880FC1068C640F8E058444090 +:20932000087F087E08FF101E2246813F213F017F20207E44A4281028448200F808F804FE1D +:209340001010117C545554547D5111151DE541014848FE4800FE4848FE4A4AB622020A04F9 +:20936000202023F8A8ABA8A8F9A2202B38E841028888FE8824FE5088048A88FE88880808E2 +:209380001010137C545555557D5110171CE441028888FE8800FC04FC04FC20FE5088040205 +:2093A0001011117D555555557D5111151FE2420400FE10207C447C447C101054529250207D +:2093C000202021F9A9A9A9A9F9A020283AEA44002040FC04FC04FC04FC4020A48A8A78005A +:2093E000202023F8A9A9A9A9F8A3222A3AEA42024020FE00542454FC20FE4292FA0A0206FB +:209400001010117D555555557D5111151DE642042010FE107C14FE147C107C4444447C4499 +:20942000202023F9A8ABAAACF8A3202838E941024020FC0890FE024420FC80F8880828104C +:20944000087F08FF1456A54C811F11111F017F2020203E44A810284600F01010F008FC04B2 +:209460001010117C545754557D5111151CE441028888FC8888FE20FC24FC24FC00880402B0 +:20948000202027F8ABAAABAAFBA0212939E941019090FE90FC94FC94FC00F808F808F808B0 +:2094A0001013107D555555547D5013141CE5420000FE50FC5454FC00FC00FE20A824A240BC +:2094C000202120FBAAA8A8A8F8A0202938E843002024A8FE02F88888F82020FC2020FE00E4 +:2094E000202120F9A8ABA8A8F9A220283AEA44001CE02024A8FE70A824224024A28A887850 +:20950000202021FBADA9A9A8F8A3202B38E8430080F808FE1222FE40A254983454925020F7 +:20952000081F280718E10C03107E527E1014FE0200F020C0308E4000A0FCA4FC2024FE02FD +:209540001011107C575455557D5111141FE4400020FC8850FE00FC04FC04FC20FE20202067 +:20956000202023F8A8AAA9AAF8A0202B38E840004020FE2048F22452F80820FE20202020DC +:209580001F02017F04186201107E527E1014FE02F02040FC8488800020FCA4FC2024FE0251 +:2095A000202027F8A8ABA8ABFAA2232A39E847028282F48880E202E42820E02242748810F3 +:2095C000202023F8A9A9A9A9F9A0232838EA42042020FE20FC24FC24FC22FE4224A28A787C +:2095E000202321F8ABA8A9AAF9A1212939E941013CE024A8FEA82402FC2424FC2424FC04E5 +:209600001010137C555457557C5310151DE541018850FE20FC20FE24A8FE00FC0404FC0430 +:209620001013107C555755557D5111151FE4400388FEA890FE20FC20FC20FE00FC88708E57 +:20964000202320FBAAA9A8ABF8A023283BE8430088FE88FE02FC00FE40A254B85492502071 +:209660001010117F555555557D5111151DE5410280F808FE4492FE007C007C007C447C44E3 +:20968000202322FAABAAAAAAFBA2222A3AED460820FE8850FE50FC54FE54FC50D854525064 +:2096A0001011107C555555557C5111151DE5410248FE4800FE4A4AFE14FE10924C4A1622D1 +:2096C0000F101F00FF0C730D720CF37C547C12FEE020C040FE1020C0B08E20F8A8F824FCF0 +:2096E000017F111F01FF881F680F107C547C12FE00FC10F000FE02F010F020F8A8F824FC6C +:20970000232223FAABA8A9ABFDA1212839E84007DE52DE52DEA0FE20FC20FE00FC88708E59 +:209720000808101F21410101FF01212121213F00000000F800000000FE0008080808F808AD +:209740003E222A2A2A1422491F2101FF01213F00F888A8A8A8508804F80000FE0008F808B9 +:20976000087F083E003E2A3E40901F21FF01213F00784848867848304886F000FE0008F8CC +:2097800020203C519111FF11115555555E660400203E20FE203CE21E04789254FE105020BA +:2097A000081C711111FD11117D454545457D4501041EF010101010FE101010080A4A86021B +:2097C00010101F28244580003F0000000000FF0040407E9088080000F80000000000FE00E7 +:2097E00010103F2845803F0101FF01010101050240407E900800F80000FE00000000000046 +:2098000010103F2845803F08080C0A121120438C40407E900800E0204078081020C0300E01 +:2098200010103F2845BF0010101F00007F00000040407E9008F0101010FC0404E404281005 +:2098400010103F4885007F080808FF080810204040407E900800FC202020FE202020202036 +:2098600010103F2845801F1011111112140830C040407E900800F010101010909082827EB4 +:2098800010103F284580001F121212122222428240407E900810F8202020201010080402C1 +:2098A00010103F2845811F11213F03050931C10140407E900870800000FC04040428100001 +:2098C00010103F4895101F22428408112244081040407E900800F8484888880808085020E8 +:2098E00010103F2845807E08080808080EF0400040407E900800FC848890888484A89080C2 +:2099000010103F2845803F20202724242720203F40407E900800FC0000F80808F80000FED7 +:2099200010103F2845801F10101F10101F00FF0040407E900800F01010F01010F000FE009B +:2099400010103F284591113F4181013F010101FF40407E90080000FC000000F8000000FECE +:2099600010103F284588081F244487040407040440407E90080000FC0000F00000F80000EC +:2099800010103F4895101F20409F10101F00000040407E900800F8080888888888085020E8 +:2099A00010101F2824458201017F0010080400FF40407E908808000000FC0010204000FE31 +:2099C00010103F2845803F007F001F10101F100040407E900800F808E80888888888A810B1 +:2099E000203F4885007F04081020DF1010101F10407E900800F808085020F8080808F80864 +:209A000010103F488510107E1212121222224A8440407E9008007C444444444444447C4474 +:209A200010103F4885201017007011111214284740407E90088080F888880808281000FEA8 +:209A400010103F488508103F00001F1010101F1040407E90082010F80800F0101010F0101F +:209A600010103F284588087E08080E780808281040407E90080000FC8484848484FC840088 +:209A8000203F488520203E2020263901FF010101407E90088088B0C4847C0000FE000000AA +:209AA00010103F488511113F4101FF04081020C040407E90080000F80000FE404042423E0E +:209AC000203F4885007B0810227A0A2B10284780407E900818E04040784040FC0000FE0037 +:209AE00010103F284582040830CF01011F01017F40407E900880402018E60000F00000FC0B +:209B000010103F2845881F205F01FF011F01050240407E900800F020F808FE08F80800007F +:209B200010103F284590107D1210101CE041000040407E900880FC040484542444842810B7 +:209B400010103F4885007F0111111129458501FF40407E900800FC0010101028448400FE83 +:209B6000203F48857F013F213F213F211A061960407E9008FC00F808F808F8000000C03E38 +:209B800010103F48851011FD11111DF11111512040407E900800FC242424FC00000202FEBC +:209BA00010103F488511091F101F101F1010101040407E90081020F010F010F0101050205C +:209BC00010103F48851010242464A5242420202340407E900840407E888848502050880603 +:209BE000203F49BF011F01FF001F101F101F1010407E90F800F000FE00F010F010F01030DD +:209C0000203F48853F011F017F001F1011020C70407E9008F800F000FC00F01010C0300839 +:209C2000203F4885003F20202F24222F2122243F407E900800FC8080F890A0FC402010FE4B +:209C400010103F2845821F02FF030F38CF080F0840407E900800D020FE00F010F010F010DA +:209C6000203F4885087F0802FF04081F28C80F08407E900820FC2000FE0000F01010F01056 +:209C800010103F48851010FB10101CF01010502040407E90088888FE8888F8888888F888FD +:209CA000203F4885101110FC13101D30D3105020407E900800FC88708E20FC20FE20202016 +:209CC00010103F48853F213F213F00FF0808102040407E9008F808F808F800FE202020200E +:209CE000203F488508043F213F213F01FF010101407E90082040F808F808F800FE0000007E +:209D0000203F4885017F408810201F0101017F00407E900800FE02241008F0000000FC0080 +:209D200020207E518A017F40901E2224540810604040FE100800FE0204F888A89084847C34 +:209D4000203F4885013F01FF013F012525294181407E900800F808FE08F800482828080825 +:209D600010103F2845803F202F202F28284F408040407E902824FE20A424A89892AA468257 +:209D8000203F48851F111F01FF001F1011020C70407E9008F010F000FE00F01010C030083E +:209DA00020207E518A1F101F101F007F013F01FF4040FE1008F010F010F000FC00F800FE56 +:209DC000203F4885090810375191121017101112407E9008F01010FC00F84040FCA0100C1F +:209DE000203F48857F043F04FF111F11FF101010407E9048FC40F840FE10F010FE1050206C +:209E0000203F48853F22223E222E223E22223F00407E9008FC404078407040784040FC00F4 +:209E200010103F48857F043F243F017F0519E10140407E9008FC40F848F800FC40300E00CD +:209E4000203E48823F2423243F00203E20202638407E9000F8488848F8008498E084847C1F +:209E6000203F48853F20202F28282B2848519224407E907C80F880FC84F0887800E0241CC4 +:209E8000203F488508FF087F49497F1C2A498808407E900820A03E42941010102828448268 +:209EA000203F48853F24243F003F203028244083407E9008F84848F890FC80485024D40C94 +:209EC000203F4885126744474457600404081060407E900800DC44C444DC00404042423E3B +:209EE000203F4885003F223F223F28282F484B8C407E900880FE20FC24FC40487044443CCB +:209F0000203F488504554E445F444E55447F0001407E90080C7040407E4848484888880818 +:209F2000203F48851F101F101F1014183F2424FF407E9008F010F010F488700EF84848FEE0 +:209F4000203E48FF043F243F101F101F01FF0101407E90FC40F848F810F010F000FE000096 +:209F6000203F48853E08487E1424463F203F203F407E90087C1090FE284A86F808F808F8CE +:209F8000203F4885007E04281720DF101F08047F407E900890A04428D008F610F02040FCFF +:209FA000203F48852424FE243C243C24FE294582407E90081010FE9290FCA4A4A81028465D +:209FC000203F4885087F083E2A2A3E081C2A4808407E9008203C44887C4454545428448230 +:209FE000203F48852027F4253620E7242724A744407E9008807CA4A45488FC44FC44FC0448 +:20A0000001053921213D2121213F2102040830C0000078080878080808F8088040201806AB +:20A02000063820203E20203F0808FF080810204000F80808F80808F82020FE202020202070 +:20A0400001017F013F02FF040834D8101C101F100000FC00F800FE40201876107010F0104B +:20A06000063820203E20203F103F40892424400000F80808F80808F800FC04249494281079 +:20A0800002041F101F101F101F01FF050931C1010000F010F010F010F000FE4020180600A1 +:20A0A0000808107F555555555555555557FC010000FC2424242424FC44444444C444FE0043 +:20A0C00008103E22322A2AFE22322A2A22424A8400007C1010101010101010101010FE0080 +:20A0E00010207C44655555FD456555554545548820202020242424242424242424FC0400E6 +:20A1000010207D45655454FC446454544444558A40242404048888885050202050880402A7 +:20A1200010217D45655555FD4565555545455588101010121214D8101010101252920E00E1 +:20A1400010207C44655555FD456555544444548820202020FC24242424FC24202020202080 +:20A1600010207C44645454FC4464545445455688040EF08080FCA4A4A4A8A8901028448267 +:20A1800010207C45645454FC446454544444558A402020FE4040407C444444448484281005 +:20A1A00010207D44645555FD45655555444454880000FE0808E828282828E82808082810FD +:20A1C00010207C44645454FC446454544445558A20203C2020FC848484FC8480800000000B +:20A1E00010207C44655555FD456555554545558920202020FC24242424FC24242424FC040F +:20A2000010207C44655556FC4464545444445488808080FE4040407C4040407E4040404096 +:20A2200010237C44655555FD456555554545558900FE5050FC54545454548C040404FC048D +:20A2400010217C44645555FD45655555454555892024A4A820FC0404FC0404FC040414086E +:20A2600010217D45655555FD456555554545558A00FC0404FC001C701C701EF01012120EBA +:20A2800010217C44645754FC446555554545578800FC081020FE20A040FC54545454FE008A +:20A2A00010207D44645454FC44645454444454888448FE2040FC8484FC8484FC8484FC843B +:20A2C00010207D44655555FD45645454444454885050FE50FC54FC54FC00F888F888F888C2 +:20A2E00010217C44675455FD456555544544578820FC8850FE00FC24FC24FC20FC20FE003D +:20A300001023784B6A5948FB48486B584B484B9888FE88FE02FC00FE40A254B8549250202C +:20A320000102040930CF000201FF050C34C506040080402098E6408000FE008850300E00C6 +:20A34000041F1412101F000201FF050C34C5060400E020A040FC041408FE008850300E005F +:20A3600008087F091111254201FF050C34C5060400007C4444447C0000FE008850300E00D0 +:20A3800001017F110905196201FF050C34C506042010FC10A040300800FE008850300E0026 +:20A3A00010084024097210100701FF040C34C5062020A8A4222830C00000FE885020180696 +:20A3C000007C45447C437CA5243E01FF061CE5064020FC8850FE20FC202000FE8048300E97 +:20A3E000442429FD11117D1111FD111121214181041EF010101010FE101010080A4AA61257 +:20A40000442528FC10107C1310FD10102020438000FC08103048840200FC20202020FE0044 +:20A42000442428FD13107C1112FC11122020418640408804FE02884442F8885020508806BF +:20A44000442529FD11117C1112FD11112120408000FC04FC04FC80FE22225202FA02140862 +:20A46000442529FD11107C1310FD11122224488020242424FC8080FE90105254A8284482FD +:20A48000047F013F01FF003E08FF2A7D901E020C40FC00F800FE282424FE2024A8122A4643 +:20A4A000101094545911FD31395555911111101020202020242424242424242424FC040082 +:20A4C000101094545811FE30385454901010111240404080FE0888888850502050880402AE +:20A4E000101095555911FD3139555591111110100000FC2424242424FC0000000202FE0056 +:20A50000101195555911FD31395555911112121400FE000000FE20203C24242424445488B3 +:20A520000111111F41417F0011097F050931C101001010F00404FC001020FC402018060080 +:20A54000101394545911FD31395555911111111100FE5050FC54545454548C040404FC04CA +:20A560000141210A14E0212611097F050931C1010000FC4448A010081020FC4020180600AF +:20A58000080F283F61920C31C011097F050931C1007C044428106884001020FC4020180622 +:20A5A00008492A08FF2A49884277925A2F2242820012121224244890484824249212120080 +:20A5C000202023AA7021F8207368A921222420204020FE0200FC0000FE2028242222A040B0 +:20A5E000101094555813FC313A55549011101013404884FE20FE8824428810628418608077 +:20A60000101094555913FD31395555911111111180BC8408FE20207C9010FE102828448299 +:20A62000202021A97225F8217669A921212121218888EC2A2848887E00FC0404FC0404FC93 +:20A64000212020AF7121FA22746FA92222242720088890FE08081094A438081010A4BC8447 +:20A66000202320A97121FA247169A9212121212100FE22203C20FE00FC04FC04FC04140840 +:20A68000202120A87320F8217268AB202021262000FC4830FE5294103020FE70A8242220A5 +:20A6A000202023AA7322FB227368A8272021222C4080F808F808F808F85048FEA010080696 +:20A6C000202320A87023FA22726BA8202020252200BEA2A2BE88083E2AAAAABE888A7E0238 +:20A6E000003F20203F20203F222221202428302000F01010F01010F0000810A040201806B6 +:20A700007D447D457C4854651F101F101F00FF00FC2020FE5052920EF010F010F000FE0053 +:20A72000007E2212061A620204047F040408102000FC44240C34C4042020FE2020202020D2 +:20A740001011282443900800FC0409502010110000DC444454CC44444CD4644444445488DF +:20A76000010618EF001F101F007E22120A126A0400C030EE00F010F000FC44241424D408FB +:20A78000011F017F020F38CF080F007E221A620608D020FC00F010F010F000FC4434C40CA0 +:20A7A000047C043C047C0404007E22120A126A04407C4078407C404000FC44241424D408ED +:20A7C00008FF003E223E223E2226007E221A620620FE000848484848081800FC4434C40C60 +:20A7E00010087E42427E42407F55557FD555554300EE2222AA662222266AB2222222AA44B9 +:20A8000000FE007C447C00FE82AA92FE9292928600EE2222AA662222266AB2222222AA44EC +:20A82000007F485F645F444A517F007E221A62060078484C80784848304C00FC4434C40C5B +:20A84000020408103F0106187F010909112145020000204080001008FC0420100804040039 +:20A8600010FB1019F01152241F01063F0111254280F0909094540C24C08010F8082010081F +:20A88000087F080F080F08FF1428DF023F01152220FC20E020E020FE50880610F808201010 +:20A8A00010083E22233E204184081F023F01152240407E885020588640800010F808201066 +:20A8C000000EF0229244203C5010FE1054555C64000CF02044F81024FE12505492125020FB +:20A8E00001FF011F12FF101F003E222A2AFF2A5900FE00F010FE90F01CE024F824FE54B206 +:20A900001010FE107D10FE203D4448A81028418220202020FC202020FE2050508888040242 +:20A920001010FE5556BA103855A23C44A91028C08080FE0222AA7222FE2272AA22220A0446 +:20A940000808087E0808FF0828282E2828584F80040444444444444C546404040400FE00EB +:20A960000808087E0808FF0828282E2928584F8000F88888F88888F8888888FE0000FE0098 +:20A980001013107C1011FD1112505C505172508F02F2828A8AEA2A2AAA4A4A820A0400FE95 +:20A9A0001012117D1010FC1013515D515170508F2020203E4284909010102824428200FE57 +:20A9C000111517791713FD1913525A525071528F0828BE48BE18AA46F8084848A01008FE8C +:20A9E0000808087E0808FF14145655942424548800FC8484948880FCA4A4A8A890A8C48275 +:20AA00000808087E0808FF1414565595242454882024F42828FE10207CC4447C44447C4407 +:20AA200000FE01007C4444447C0044282EF043000000FC2020202020202020202020FE002C +:20AA400000FE00017C4444457C0044282EF04106202020FE202020FC848848502050880605 +:20AA600000FF14147F5555555761417F41417F4100807E1010101010101010101010502059 +:20AA800000FE2828FEAAAAAAAEC282FE8282FE82007C1010101010FE1010101010101010AE +:20AAA00000FE2828FEAAAAAAAEC282FE8282FE8208080808FE0808084828280808082810BA +:20AAC00000FE2828FEAAAAABAEC282FE8282FE82202020A0ACB4E4A4A4B4A8A2A2827E008B +:20AAE00000FE2828FEAAAAAAAEC282FE8282FE8210101010FE1010107C44444444447C449A +:20AB000000FE2828FEAAABAAAEC282FE8282FE824040407EA0A0203C2020203E202020207E +:20AB200000FE2828FEAAAAAAAEC282FE8282FE82201010FE828440444850604242423E0093 +:20AB400000FE2828FEAAAAAAAEC282FE8282FE831050507C901010FE282828284A4A8600A2 +:20AB600000FE2828FFAAAAAAAEC283FE8282FE8220207E824428102040FE424242427E4233 +:20AB800000FE2828FEAAAAAAAEC282FE8282FE8280828CF082827E00FC8484FC8484FC846F +:20ABA00000FE2828FEAAAAAAAEC282FE8283FF8200FE28AA6C28FE80808080808000000073 +:20ABC00000FB2020FBAAAAAADB8A8AFA8A8AFA8A00FE0000DE5252525AD65252525252D64E +:20ABE00000FE2828FEAAAAAAAEC282FE8282FE82007C4444447C0000FE10107C1010FE001B +:20AC000000FE2828FEAAAAAAAEC282FE8283FE821010282844BA1010FE1058549212502019 +:20AC200000FE2828FEAAAAAAAFC282FE8282FE82041EE02292544008FE08884848082810A5 +:20AC400000FE2828FEAAAAAAAEC282FE8282FE8200FC8484FC8484FC009092F49892D28E92 +:20AC600000FE2828FEAAAAAAAEC282FE8282FE822010FC00844800FE0000FC848484FC8418 +:20AC800001F92127F9A9A9ABDA8A8AFA8B88F888003C24E4243C24A4A4BCA4A4A444548829 +:20ACA00000FE2828FEAAAAABAEC282FE8282FE83007C447C447C00FE10105E5050B09E006E +:20ACC00000FE2828FEAAAAAAAEC282FE8282FE8200FC14505C507E807C447C447C44444CDC +:20ACE00000F82320F8A9AAACD88889F98989FB882020FC4080F88888F800FC545454FE00B9 +:20AD000000FE2828FEAAAAAAAEC282FE8282FE832010FE90BC94FE94BC90BCA4A4A4BC2400 +:20AD200000FE2828FEAAAAAAAEC382FE8282FE8200EE22AA66AA1028449220C832C418E0A6 +:20AD400000FE2828FEAAAAAAAEC282FE8282FE8228AA6C28FE4428FE107C10FE10284482CF +:20AD600000FE2828FEABAAAAAEC282FE8282FE832824407EC8487E48487E48487E40AA2A4B +:20AD800000F82320F8A9A8A8D98A89F98989FB884020FE4084FEA8AA2600FC545454FE007F +:20ADA00000F82023FAAAABAADA8B8AFB8A8DFC89407C40FE4278C43C00FE40A458B452B035 +:20ADC00000FE2828FEAAAAAAAEC282FE8282FE8228FEAAFEAAFE00FE00FE82FE4428FE0059 +:20ADE00000F92023F8A9A9A9D98889F88B88F98A1CE020FE20FCAC74FC20FC20FE00542AA2 +:20AE0000007F020609116204081162040830C20100FC00000890A0C0C0A0908886808000BF +:20AE200020203C2120FC8495D4A4D49586FC8500844448FE20FC20FE4080FE101010FE0024 +:20AE400000FF0407081060001F101F011111294700FE00F010A04000F010F000F80000FECB +:20AE6000007D1111111DE2441F101F011111294700F0109052120E00F010F000F80000FE16 +:20AE800008087E080E780829121F101F011131CF0CF08080FE88880808F010F000F800FEF3 +:20AEA000003F2223223F2B52469F101F011131CF24FE20A424A8109A26F210F000F800FEA0 +:20AEC000492A7F495D6B49411F101F0111112947203E4848A8102846F010F000F80000FE0A +:20AEE000007C4444447D10115C5050505CE00000404040FC84040404844444040404281048 +:20AF0000007B484848781010515D51515AE2040100FC848888909C8444442828102844829F +:20AF2000007D4444447C10135C5050505CE0010200FE4848484848FE4848484888880808FA +:20AF4000007C4444457C10105D5050505CE0010220202020FC202020FE20505088880402D0 +:20AF6000007C4444447D12105C5050505CE0000020205050880402F88888A89082827E0032 +:20AF8000007C4544447C1010105D5250505CE0000000FE20204040FC848484848484FC84DF +:20AFA00000784849497B1511515D515159E10101888888087E0808482828080808082810F4 +:20AFC000007D4545457D11135D5151515DE2020400DC5454545454FE5454545454D4244C89 +:20AFE000007C4545457D11115C5050505DE20000081CE000202020FE2020A8A42222A040CA +:20B00000007C4445457E10105C5050505CE00000201010FE0204808890A0C08282827E0080 +:20B02000017949494B791111515D515159E203040000001CD454545454545454545C5480CC +:20B04000007C4445457D11115D5151515DE20204101010FE121410FC44442828102844823C +:20B06000007C4444447D1310105D5151515DE101202040408804FE0200FC04040404FC04F1 +:20B08000007C4544447C13105C5051505CE003002020FC202020FE002020FC202020FE0008 +:20B0A000007C4447447C10135C5350505DE102048080BCC05024D40C00FE909012120E00F3 +:20B0C000017D4545457D1111115C5350505CE000101214D81012528E2020FE2020202020FA +:20B0E00000794949497A1013505C505059E10204202020FC202020FE909090901212120E95 +:20B10000007A494948781017515D515159E20400000C70101010FE101010101010807E00A5 +:20B12000007C4544447C1010115C5050505DE1024020FE8850205088068888888808080821 +:20B14000007C4445447C1112105C5050505CE003402020FE008804028888505020508806B2 +:20B16000007C4545457D1111115D5151515DE1014020FC0404FC0404FC20221408448200BD +:20B18000007D4444457D11115C5050505EE2040000F80808F8000404FC4020A48A8A7800A2 +:20B1A000007C4444457D11115D5150535CE0000020203E20FC04FC04FC2420FE20202020BE +:20B1C000007D4545457D1111105D5050515EE00000FC2424FC2424FC20FE70A824222020A8 +:20B1E0000179494B4A7C1010535C505159E20408000000DE92929292F29292525E20200098 +:20B20000007D4545457D11115D5151515DE202041CE01010FE10107C445454545428448276 +:20B22000007C4545457D11115D5151515DE202042010FE0020203C20207C444444447C4459 +:20B24000007C4544457C1013105C5151515DE1014020FC00089000FE0000FC040404FC046D +:20B2600004F2929097F12121A7B9A1A1BAE20408405E9212D4141814F212121A94505010D8 +:20B2800000784F49497A1217515D55525AE5080010107C14FE147C107C10FE101000FE0020 +:20B2A000007D4547457D11115D5053505CE10600484848FE48487800FE20FE70A824222096 +:20B2C000007D4545457C13105C5151515DE1010120242424FC00FE2040FC54545454540C62 +:20B2E000007C4544477C11115D5151505DE00300083CE020FE20FC24FC24FC20FC20FE00FD +:20B30000007C4744457D11115C5352525EE20202041EE020FC2424FC20FE222AFA020A04D5 +:20B32000007C4545457D11115D5151515DE202044020FE4848FE487800FC4448281028C634 +:20B34000007C4445447C10115C5050515EE40100844448FE20FC20FE4080FE101010FE0043 +:20B36000007C4545457D11115D5151525EE204004020FE0202FE0000FEAAAAFEAAAAA28622 +:20B38000007D4444477C10115E5053505CE1060000FC4830FE5294103020FE70A8242220FC +:20B3A000007D4444447C10135C5350515CE1020400FE84FC84FC86FC04DE525294485422BA +:20B3C000007C4544447D10105D5151515DE101014848FE4800FE4848FE4A4AB622020A0419 +:20B3E000007B494848781110505D50505BE000031EE022944088F020C4FE2220FE50880669 +:20B40000007B4A4A4B7A1212525E52525AE2050000FE0004F404EEA4A4EC04A44474940887 +:20B4200000F7949695F72424A6BEA7A4BCE5091200FE002848EE9284A0A8E8889414244274 +:20B44000007A49484B781013505D505358E0010650525450FE8850FE20FC20FE508804023A +:20B46000007D4544457C11125D5151515DE101013CE024A8FEA82402FC2424FC2424FC0416 +:20B4800002F19F9090F72424A7B9A5A5A9B1C5021412D2107E9090909028A868284A4A86B0 +:20B4A000007D4545457C1112115D5151505DE00000FC5454FC80FC44F45454F444F41408C0 +:20B4C000007D4445447C1111115D5151515DE10148FE4800BE82527ED27E527E527E42060E +:20B4E00000F7949595F52525A4BDA4A7BDEA081320FE00FC24FC24FC20FC20FE24FA20FE1A +:20B50000017A49484B7A1212135E5352535EE20324482400FC946494FC4868486A4A466222 +:20B5200001F5979997F32529A0BBA2A2BAE001060828BE48BE18AA4600F8084848B0080485 +:20B5400002F293969AF22222A5B8A0A3B9E0030C48E808EA1CE808E8B4E200F810E0180604 +:20B5600000077A1108077800030C70010618E000E0000C30C08040A0305090101010A040D8 +:20B580000C31C2144830C81425CC1424C404281000FC44444444948800FC84848484FC8467 +:20B5A0000C30C2144830C81424CC1424C404281000FE202040FC848484FC84848484FC846B +:20B5C0001020D4095123D51929C91929C909512190909010FE1010383854549210101010BC +:20B5E0000C30C3144831C91525CD1425C40429128888FE8800FC04FC04FC20FE5088040225 +:20B600000C30C3154931C91525CC1525C50529112040FC0454245404FC0012D41852920E73 +:20B6200010103C2448BE2A2A3E2A2A3E2A4A42860888484808884848080EF80808080808AE +:20B6400020207849907C54547D54547C5454458E202020FC24242424FE2050508888040259 +:20B6600010103C2449BE2A2A3E2A2A3E2B4A428640407E807C081020FE4A4A92122254887C +:20B6800020207949917D55557D55557D5556468C081CF050505050505048486854745200C9 +:20B6A00008282E282EF0080F103F511F111F11218088F084847C00C080F808F808F80818DA +:20B6C00020207948907C55547C54547C5555468C202024A4A820FE909090909212120E00C6 +:20B6E00020207948907D55557D54547C5556448C2020FE2020FC2424FC2070A824222020FA +:20B7000021207849917D55557D55547C5754448C048850FC2424FC2424FC2020FE20202054 +:20B7200008282E282EF0017F003F003F003F203F8088F084847C00FC00F800F800F808F869 +:20B7400008FF083E2A3E41FF003F003F003F203F78488678483048FC00F800F800F808F876 +:20B760001010FE107C10FE007C447C447C44544900FC8484A4A4A4A4A4A450505092920E36 +:20B780003F017F419D011D003F00FF040F000000F800FE0274007000F800FE00F010A040EB +:20B7A0003F017F419D011D003F20212F21424498F800FE0274007000FC0000F80808502090 +:20B7C0003F017F419D011D02017F0804030418E0F800FE027400700000FC20408040300EEB +:20B7E0003F017F419D011D007C09103D442B106FF800FE02740070083CE020FC20FE00FE96 +:20B800003F017F419D011D007F080718E4040810F800FE0274007080FC20C0304E40404051 +:20B82000003F017F419D011D2017402B0A72121000F800FE0274007040FC40F84848584095 +:20B84000003F017F419D011D047C043C047C040400F800FE02740070407C4078407C404059 +:20B860003F017F419D011D023F087F02FF080778F800FE0274007000F820FC00FE20C038B7 +:20B880003F017F419D011D201782411720EF2027F800FE027400703CC04428FC40FE40FCCC +:20B8A0003F017F498423120372131113141A1300F800FE2214F808F808F800FC44A4F40CD2 +:20B8C0003F017F419D00123F127F003F213F2123F800FE02740020203E44A424281028466A +:20B8E0003F017F419D30CB2D31C915640D34C518F800FE027400FC24FC24FC20FC20FE0010 +:20B900000808282F2828FF00494955634147790120202022222428302060A02222221E0061 +:20B920000808282F2828FF004949556341477901007C4444447C4444447C44444444FE00EB +:20B940001010505E5051FE009292AAC6828EF20240407C8484F4949494F484A892827E007C +:20B960000808282F2828FF00494955634147790100FE222222224A44807E424242427E42EB +:20B980001010505E5050FE009292AAC6828EF20308282828A8AABCA8A8A8A8A8AABAEA86F8 +:20B9A0001010505E5050FE009292AAC6828EF20200FC8484FC8484FCA2A4989088A4C280A3 +:20B9C0001011505E5050FE019292AAC6828EF20200FC2020FC4444FE0000FC848484FC849B +:20B9E0000808282F2828FF004949556341477901007C444444447C1010505E5050709E00C1 +:20BA00001010505E5050FE009292AAC6828EF30200FE8282FE80FE90A4FE9290FC9010FEB5 +:20BA20001F10101F013F21213F21213F21010100F01010F000F80808F80808F80A0202FE2F +:20BA40001F00FF0830DF101F013F213F213F0100F000FE443CF010F000F808F808FA02FE29 +:20BA6000003E223F111F11FF013F213F213F010000F888F810F010FE00F808F808FA02FE66 +:20BA80000908081F10305F90101F1010101F1010008080FC8080F88080F8808080FC000039 +:20BAA00009081F305F901F101F1101FF010101010080FC80F880F880FC0000FE00000000EE +:20BAC00009081F305F901F101F103F04040830C00080FC80F880F880FC00E0207C041408F6 +:20BAE000007C4444457E44447C4444444EF00000504880FE9090FC9090FC909090FE808075 +:20BB000020203C44C52A102844827C4444447C44504880FE9090FC9090FC909090FE808074 +:20BB20003E223E223E223E081F305F901F101F10F888F888F888F880FC80F880F880FC00A3 +:20BB4000302A417DD0537D51517D5151517D40401814203E68283E28283E2868A83E202082 +:20BB6000007D1111111DE2450618EF013F1109FF00F0109052120E00C030EE00F81020FE65 +:20BB80000201FF04142444010618EF013F1109FF0000FE4050484400C030EE00F81020FE9E +:20BBA000100940240B7010110618EF013F1109FF1CE02020FE508804C030EE00F81020FEEC +:20BBC00010FF287F080FF8090618EF013F1109FF0478407E48488808C030EE00F81020FED3 +:20BBE000007E2418FF294A990618EF013F1109FF20207E8428102844C030EE00F81020FE30 +:20BC0000087F087E08FF203E438618EF013F09FF20203E448428102844C230EE00F820FEBA +:20BC20002017804913E12224010618EF013F09FF40FE9008FC50524E00C030EE00F820FEBE +:20BC40003E223E207EA23E230618EF013F1109FF10FE4428FE10FC10C030EE00F81020FEA7 +:20BC6000010618EF011F093F10287C927C1054FE00C030EE00F020F810287C927C1054FE20 +:20BC800020207C44887D54547C54547C001DE1424050484840FE50505050909092120E00A7 +:20BCA00010101E23247EAA2A3E2A2A3E000E7122201010FE4040407C444444448484281072 +:20BCC00020207C44897C54547C54547D011EE04050484840FE40407CA4A4A82810284482A7 +:20BCE00020207D44887D54547C57547C001CE0400000FC202024A4A820FE2020202020202D +:20BD000010101E22247EAA2A3E2A2A3E000E7020101010101E101010FC8484848484FC8441 +:20BD200010101E22247EAA2A3E2A2A3E000F712210101E1010FE828282FE82808000000059 +:20BD400020207D44887C55547C54547C011CE040083CE0202020FE207068A8A42220202010 +:20BD600020207C44887D56547C54547C001CE04044444484BE8484A494948484848494882A +:20BD80002211007F44840F103F511F111F00FF00081020FC0408C040F010F010F000FE00FE +:20BDA00010101E22247EAB2A3E2A2A3E000E7020202020404884FE8200FC84848484FC84C6 +:20BDC00020207D44887C57547C54557C001CE3402020FC202020FE002020FC202020FE009F +:20BDE00020207C47887C55547C55557D011DE141202020FE2020FC0000FC04040404FC040A +:20BE000020207D44887C54557E54547C001CE0402020FE4040FC8484FC8484FC84849488B0 +:20BE200020217C44887D55557D55557D011DE14100FE202040FC5454545454545454040C44 +:20BE400020207D44887C54547D54547C001DE1424020FE88502050880688888888080808E8 +:20BE600020207C45887C55567C54547C001CE043402020FE00880402888850502050880679 +:20BE800011097F02FF0834CF103F511F111F00FF1020FC00FE2018C640F010F010F000FEB9 +:20BEA00020217C44887C54557C54557C001CE04000FC0404FC0404FC0808FE8848480818AD +:20BEC00020217C44897D55557D55557D001CE04300FE2020FC2424FC2424FC20A040B00E4E +:20BEE0004043788813FAAAAAFBAAAAFA021AE24200FE0000DE5252525AD65252525252D663 +:20BF00004042798910F8AFA9F9A9A9F9011AE4401010107E2028487E0808FE0808887E00DA +:20BF200020217D45897D55547C54547C001CE140407E5252544854621010FE101010FE0072 +:20BF400040407B8A12FAAAABFAAAAAFA031AE0400404C4447E4444E454544444C444140828 +:20BF600020207C44897C54577C55547D011EE0404040F8885020D82620FC20282424A04036 +:20BF800020217C44887D54547D54547C011EE0400CF0204488F02044FE2220A82422A040C9 +:20BFA000201244200873280F103F511F111F00FF40484414608000C040F010F010F000FE9D +:20BFC00020207D458A7C54547D54547C001CE1422010FE0204F80000FE50505092920E0085 +:20BFE00040437A8A12FBAAAAFAABAAFA021AE34000DE525252D2525252D21A9450B0101095 +:20C0000020207D44887C55547C54547C001CE0402020FE20FC20FE00FC84FC84FC84948882 +:20C0200020207C44887D54547D54547D001CE0412020FC2020FE4884227888485020508C78 +:20C0400020237D45897D55557D55557D031CE04000E05C5454D45454D4544868C85454623E +:20C0600020207C47887C54557C54547C031CE040505050DE505050DC50505050DE50505089 +:20C0800020217D45897D55557C55557D011DE14100FC0404FC0404FC0012D4181052920E06 +:20C0A00020207C44887C54547D55557D011DE141FC8484FC8484FC00FE0202FE0202FE02E8 +:20C0C00020217D45897D55557D55557D011DE14100FC042424FC2424745454740404FC04A5 +:20C0E00020207D45897D55557D54547C001CE14200409C0404DC0404FC5050509092120EB8 +:20C100004040788811FAA9A8F8A8A8FA021AE440202050884422F8085020A4828A8A780021 +:20C1200020217D45897D55557D55557D011EE24400FC24247424FC047454547404041408D3 +:20C1400020217C44897C54557D55557C001CE14000FC0434C44444F45454F444547696029A +:20C1600020207D46897C54547D55557D011DE1419292244824929200FE2222FE2222FE02CF +:20C1800020217C448B7C54557D55557D011CE04320FC2088FE8800FC042424242450880454 +:20C1A0004041798B11F9A9A9F9A8ABF80019E640484848FE48487800FE20FE70A8242220A3 +:20C1C00020217D45897C55547D54547C001CE04000DC5454DC00FC00FE80FC0404042810B7 +:20C1E00040407B8911F9ABA9F9ABADF90119E14108C808082A2AAC48088854141424244219 +:20C2000020207C44897E54547C54547C011CE0414040FE80FC84FC84FC407CC428106886F1 +:20C2200020207D45897D55547F54547D001CE3402040FC04FC04FC00FE2020FC2020FE0096 +:20C2400020207D45897D55557D55567C001CE0402010FE0202FE0000FEAAAAFEAAAAAA8648 +:20C2600020217C44887C54577C55557D011CE34000FCA4885020D82620FC2424FC22FE0213 +:20C28000087E08FE101E224F903F511F111F00FF20207EC4281028C640F010F010F000FE2F +:20C2A00020207D448B7C54557E54557D011DE1414044F850FE40F8827E00FC04FC04FC04E7 +:20C2C00020207C44887C54547D54557C011CE14000FC84FC84FC0000DC4454CC5444548822 +:20C2E00020217D45897D54547C55547C001DE04000FC545454FC20A8A42420A8A42420205B +:20C3000020207D44897C54557C55547C001CE040041EE0022294FE1010FE10929292FE02F5 +:20C3200041417B8911F8ABAAFAABA8FB0018E0404848E848DE8AEAAAAAEA8AEA9292AAC443 +:20C3400020237C45897D55547D54577C001DE24000FE50FC5454FC00FC00FE20A824A24091 +:20C3600020217C478A7D54557C55547D001CE14000FC20FE22AC20AC00FC04FC0404FC0472 +:20C380004041798911F9A8ABFAABA8F90018E14600F808F808F800FC94FC00F8906098062E +:20C3A000203F40BE2AFF4A7F103F511F111F00FF20207EA8281028C640F010F010F000FE86 +:20C3C00020217D45897D55557D55557D011EE24410FE107C14FE147C107C547C547C544CB9 +:20C3E00040437A8B12FBAAAAFBABABFA021AE44900FE0014A4F64A425054F4444A8A922026 +:20C4000040407B8811F8ABA9F8ABA8F90119E1418850FE20FC20FE24A8FE00FC0404FC04DE +:20C4200020207D44897D55557D55557C011CE0408850FE50FC549C04FC04FC08FE8848186B +:20C4400020217D45897D54557C55557D001CE34050FC54FC54FC00FC00FC04FC8850FE008E +:20C460002828FE2838107C54547C10FE101011100000FC848484FC848484FC840000FE0081 +:20C480002828FE2939117D55557F10FE10101112202020FC2424242424FE20505088040288 +:20C4A0002829FC2838107D54547C10FC10111210101090907E10909098A8A4C480403E003B +:20C4C0002828FE2838117C54557E10FE10101011081CE02020FE5088048A88888888880853 +:20C4E0002828FC293A117D55557D10FC101011128080F80810FC242424FC50509092120E33 +:20C500002828FD2838117C54547D12FC101010104848FE4820FE4040BC8488BE8888A8902C +:20C520002828FC293A117C55547D10FD111110108080FE0242FA02F202F202F212F2140812 +:20C540002829FC283B107C55567C13FC1011161000FC4830FE5294103020FE70A8242220EE +:20C560005050FB507120FBA8A9F921F9232121218888FE88FC88FE20FC24FC24FE041408C4 +:20C580005050FB507027F8A9ABFD21F9212121218888FE8888FE80FC24FC24FC2424240CE2 +:20C5A000007C447454FE837C447C447C4444544920202050508806484848484848888808FB +:20C5C000007C447454FF827D447C447C4444544B00F88888880600FC8484485020508806FE +:20C5E000007C447455FE827C447C447C4444544820202020FE202020FC8484848484FC8424 +:20C60000007C447454FE827C447C447C454454482040FC84A494948C80FE0202FA0214081F +:20C62000007C447454FE827C447C447C44445448041EF090909090FE909090888AAAD68AB6 +:20C64000007C447454FE827C447C447C4445554A081CE08080FE8080BCA4A4A4A43C240000 +:20C66000007C447455FE827C457C447C44445448404078885020508806F888888888F8882A +:20C68000007C447454FE827C447D447C4445544800F8A8A8F8A8A8F820FC2070A82620202E +:20C6A000007C447454FE827C447C447D444454482040FE9292FE92A2FE4888FE08080808B1 +:20C6C000007D447455FE827D447D447C444454492024A820FE68A40220FE4888D0304C8259 +:20C6E000007C457554FE827D447C477C444454484020FC044078885020D806F88888F88896 +:20C70000007C457554FE827C447C447C4444544B2010FE0248FC4800FC84A4A4A450920ED4 +:20C72000007C457554FE827C447C447D4444554A4020FE0218E080FC909090FE00880402BB +:20C74000007C447454FE827D447C447C4444544800FEAAAAFE40FE22FAAAAAFA22FA0A048E +:20C7600008107F49497F49497F101A2C2F4848871010107C1010FE1038549290901002FE3C +:20C7800010207C55547C54547C102A2D4F488700282420FE20207C44548894244002FE00E1 +:20C7A0003F203F212638212F282F282F41428C30FC90FC40308C00F888F888F850FA8A7E51 +:20C7C00010217C54557D55557D112B2D4F48870000FC5050FC545454AC0404140802FE0074 +:20C7E00008107F49497F49497F101A2C2F484887105438107C44447C44447CC4C44C02FEE0 +:20C8000010217D55557D55557D112B2D4F48870000FC048C54FC4424FC4474040C02FE008D +:20C8200010207D54557D55547D112B2D4F4887004020FC502454FC20FC4454740C02FE0024 +:20C840001010102424790A10247C04080810204020205048A4FA88F888F8A29488A4C4808D +:20C86000003F213F2428332C372427242744458600FE08FC10886498F610F010F46818047E +:20C880007F101E2354091061061FE80F080F080C205088469024489060F816F010F4681C03 +:20C8A0007C44FE207C042811061FE80F080F080C1C10FE92F894BCAA66F816F010F4681C00 +:20C8C00001FF10257B157911E61FE80F080F080C00FEA0FE20FC20FE60F816F010F4681C26 +:20C8E0003F20203E20203E2020FF102442FF4100040408102044040810224204081020C008 +:20C900003E203E203E20FF227F007F04040830C004186004186204186000FC404042423E2A +:20C920003E203E203E20FF227F013E033E037E01041860041862041860F000F000FA02FEEB +:20C940003F203E20FF227F013F213F21FF2020200830C418620C7000F808F808FE0828102A +:20C960003E203E203E20FF227F007F08103FD01F04186004186204186000F80830F808F89A +:20C980003F203E20FF227F01FF013F003F203F200830C418620C7000FE00F800F808F80854 +:20C9A0003E203E203E20FF227F08082E28282EF0041860041862041860808890E084847C9F +:20C9C0003E203E203E20FF227F081037D0131C100418600418620418604040FCE05846408F +:20C9E0003F20FF227F11097F04FF102FC80808070418620C701020FC00FE10E826A048F85C +:20CA00003E203E203E20FF227F007C10FE385492041860041862041860001052942844825A +:20CA20003F20FF227F02017F409F101F10FF10200418620C700000FE22C400F880FE2010A4 +:20CA40003F203E20FF227F013F24FF101F0C34C60830C418620C7000F848FE10F088700EAB +:20CA60003F20FF227F1021103F2423243F2925310418620C70840884F8488848F84A26820A +:20CA800001003F22222F23262A212224494287000080FE1010BC18B4520040801008FC04A7 +:20CAA00001003F222F262B32202F202F205F40800080FE107C3854927880F880FC82827E6F +:20CAC00001003F222F262B32212720232F4045880080FE107C38549208F06084FE4248846B +:20CAE00001003F223F223F282F282F20234244980080FE20FC24FC4078423E00F010120E13 +:20CB0000003F223F223F242724272023204F418E80FE20FC24FC20BC229E08F040FE504ED3 +:20CB2000003F223F223F24272427202F2047409F80FE20FC24FC20BC229E80FE40FC40FE7B +:20CB4000003F223F223F2427242722212F41428C80FE20FC24FC20BC229E4850FE504846F3 +:20CB6000087F55547F55557F54545E55545C56804444FE44447C44447C4444FE00284482FA +:20CB8000003F223F223F24272427232D2047428F80FE20FC24FC20BC62BE18F640FC48FE30 +:20CBA000003F223F223F2427242F292F295F459B80FE20FC24FC20BC229E087E48280818AA +:20CBC000087F54547F55557F54545E54555C5681105438FE1038569084EEA4B45E448404E0 +:20CBE000081030D71010003F29253F017F01FF4490887EC0221A06F82848F800FC00FE4430 +:20CC000000FE92D6BA92FE10FE101EE002AAA880101092929292FE10109292929292FE0214 +:20CC200000FE92D6BA93FF10FE111FE102AAA88010505090FC54D494941454D45424344893 +:20CC400000FE92D7BA92FE10FE101EE002AAA880202020FE2020FC0000FC84848484FC840D +:20CC600000FE92D6BB92FE10FE101EE002AAA88020207C8448302048903E42A4181020C037 +:20CC800000FE92D6BA92FE10FE101EE002AAA88010102044FE2844A23C4444A810284482FA +:20CCA00000FE92D6BA93FE10FE101EE102AAA8811010FC1010FE0254309050FE2844820243 +:20CCC0000638087E1C2A483F29253F017F01FF44407C9424449408F82848F800FC00FE4480 +:20CCE00000FE92D6BA92FE10FE101EE002AAA8802010FE00007C44447C105452921050201E +:20CD000000FE92D6BA93FE11FE101EE002AAA881202844FE20FE881422481022C4186080D4 +:20CD200000FE92D6BA92FE10FE101EE002AAA8802010FE004428FE007C44447C44447C44F3 +:20CD400020CE82EE8282FE019292DA92DA9293D9082828284444827C242424244444940850 +:20CD600020CE82EE8282FE009292DA92DA9293D910101010FE92929292FE92929292FE829F +:20CD800020CE82EE8282FE009292DA92DA9293D900FE10107C2424FE00007C4444447C44E3 +:20CDA00020CE82EE8282FE009292DA92DA9293D9007C447C447C10FE8210FE246810284409 +:20CDC00020CE82EE8282FE009292DA92DA9293D90EF02292442044F81024FE10FE2844820B +:20CDE000103E223E223E007F497F497F00FF224220202020F82828282828282A2ACA468067 +:20CE0000103E223E223E007F497F497F00FF224200007C1010101010FE10101010901010D8 +:20CE2000103E223E223E007F497F497F00FF22421010FE385492007C447C447C4480FE0078 +:20CE4000000000000000000000000000000000000000001010101010101000001818000032 +:20CE600000123624480000000000000000000000000000242424FE484848FE4848480000E6 +:20CE80000000103854545030181414545438101000000044A4A8A8A8541A2A2A2A440000D2 +:20CEA00000000030484848506EA494888976000000606020C000000000000000000000004D +:20CEC000000204080810101010101008080402000040201010080808080808101020400096 +:20CEE000000000001010D63838D61010000000000000000010101010FE1010101000000058 +:20CF0000000000000000000000000000606020C000000000000000007F00000000000000F2 +:20CF2000000000000000000000000000606000000000010202040408081010202040400034 +:20CF400000000018244242424242424224180000000000107010101010101010107C00000F +:20CF60000000003C4242420404081020427E00000000003C4242041804020242443800000D +:20CF8000000000040C14242444447E04041E00000000007E4040405864020242443800003D +:20CFA0000000001C2440405864424242241800000000007E4444080810101010101000007D +:20CFC0000000003C4242422418244242423C00000000001824424242261A0202243800004B +:20CFE000000000000000181800000000181800000000000000000010000000000010102081 +:20D0000000000002040810204020100804020000000000000000FE000000FE000000000058 +:20D02000000000402010080402040810204000000000003C4242620204080800181800008E +:20D0400000000038445AAAAAAAAAB442443800000000001010182828243C444242E7000049 +:20D06000000000F8444444784442424244F800000000003E4242808080808042443800002E +:20D08000000000F8444242424242424244F80000000000FC424848784848404242FC0000B4 +:20D0A000000000FC424848784848404040E000000000003C44448080808E844444380000E4 +:20D0C000000000E7424242427E42424242E700000000007C1010101010101010107C00006C +:20D0E0000000003E0808080808080808080888F0000000EE444850705048484444EE00009A +:20D10000000000E0404040404040404042FE0000000000EE6C6C6C6C5454545454D60000D7 +:20D12000000000C7626252524A4A4A4646E2000000000038448282828282828244380000EE +:20D14000000000FC424242427C40404040E0000000000038448282828282B2CA4C38060063 +:20D16000000000FC4242427C4848444442E300000000003E4242402018040242427C0000F4 +:20D18000000000FE921010101010101010380000000000E74242424242424242423C0000D2 +:20D1A000000000E7424244242428281810100000000000D692929292AAAA6C444444000046 +:20D1C000000000E7422424181818242442E70000000000EE444428281010101010380000D7 +:20D1E0000000007E840408081020204242FC0000001E1010101010101010101010101E004D +:20D200000000404020201010100808040404020200780808080808080808080808087800AE +:20D22000001C2200000000000000000000000000000000000000000000000000000000FFB1 +:20D2400000601000000000000000000000000000000000000000003C421E2242423F0000DD +:20D26000000000C0404040586442424264580000000000000000001C22404040221C0000B4 +:20D28000000000060202021E22424242261B0000000000000000003C427E4040423C000041 +:20D2A0000000000F1110107E10101010107C0000000000000000003E444438403C42423CAA +:20D2C000000000C04040405C6242424242E70000000000303000007010101010107C000085 +:20D2E0000000000C0C00001C0404040404044478000000C04040404E4850684844EE0000DE +:20D30000000000701010101010101010107C000000000000000000FE4949494949ED000039 +:20D3200000000000000000DC6242424242E70000000000000000003C42424242423C0000FE +:20D3400000000000000000D864424242447840E0000000000000001E22424242221E0207A0 +:20D3600000000000000000EE3220202020F80000000000000000003E42403C02427C000059 +:20D38000000000000010107C10101010100C000000000000000000C642424242463B000046 +:20D3A00000000000000000E7422424281010000000000000000000D79292AAAA44440000DD +:20D3C000000000000000006E241818182476000000000000000000E742242428181010E028 +:20D3E000000000000000007E44081010227E00000808080808080808080808080808080823 +:1CD40000304C430000000000000000000000000000000000000000000000000051 +:00000001FF diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_animation_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_animation_config.c new file mode 100644 index 0000000..1c2f233 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_animation_config.c @@ -0,0 +1,106 @@ +/** + ***************************************************************************************** + * + * @file gui_animation_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "gui_config.h" +#include "gui_animation.h" + +#if ANIMATION_EN==1 + +#include "grx_sys.h" +#define ANIMATION_TIMER_INTERVAL 150 + +#ifdef ENV_USE_RTOS +#include "FreeRTOS.h" +#include "timers.h" +static TimerHandle_t timer_handle = NULL; + +#else +#include "app_timer.h" +static p_app_timer_id_t animation_timer_id; +#endif + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void gui_animation_timerout_handler(void *p_arg) +{ + gui_animation_timer_task(); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void gui_animation_timer_start(void) +{ + #ifndef ENV_USE_FREERTOS + if (NULL != animation_timer_id) + { + gui_animation_overlap(); + + } + app_timer_create(animation_timer_id, ATIMER_REPEAT, gui_animation_timerout_handler); + app_timer_start(*animation_timer_id, ANIMATION_TIMER_INTERVAL, NULL); + #else + if (NULL != timer_handle) + { + gui_animation_overlap(); + + } + timer_handle = xTimerCreate(NULL, (ANIMATION_TIMER_INTERVAL), pdTRUE, NULL, gui_animation_timerout_handler); + xTimerStart(timer_handle, 0); + #endif +} + +void gui_animation_timer_stop(void) +{ + #ifndef ENV_USE_FREERTOS + app_timer_delete(animation_timer_id); + #else + xTimerDelete(timer_handle, 0); + timer_handle = NULL; + #endif +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_config.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_config.h new file mode 100644 index 0000000..72bd1c9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_config.h @@ -0,0 +1,198 @@ +/** + ***************************************************************************************** + * + * @file gui_config.c + * + * @brief Gui config + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef GUI_LCM_DRV_H +#define GUI_LCM_DRV_H +#include +#include + +/**@brief GUI module enable define. */ +#define FONT8x8_EN 0 +#define FONT5x7_EN 1 +#define FONT_OTHER_EN 1 +#define FONT_GB2312_EN 0 +#define CONVERT_COLOR_EN 0 +#define ANIMATION_EN 1 + +/**@brief DISPLAY param config. */ +#define T_COLOR uint16_t +#define GUI_DISPLAY_X_MAX 128 +#define GUI_DISPLAY_Y_MAX 128 + +/**** display driver config ****/ + +/** + ***************************************************************************************** + * @brief gui display init. + ***************************************************************************************** + */ +void gui_init(void); + +/** + ***************************************************************************************** + * @brief Fill Data to gui display memory. + * + * @param[in] color: Fill color. + ***************************************************************************************** + */ +void gui_fill_mem(T_COLOR color); + +/** + ***************************************************************************************** + * @brief Fill Data to gui display rectangle memory. + * + * @param[in] x0: X0 coordinate. + * @param[in] y0: Y0 coordinate. + * @param[in] x1: X1 coordinate. + * @param[in] y1: Y1 coordinate. + * @param[in] color: Fill color. + ***************************************************************************************** + */ +void gui_rectangle_fill_mem(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Draw a point to display memory. + * + * @param[in] x: X coordinate. + * @param[in] y: Y coordinate. + * @param[in] color: The color of the point. + ***************************************************************************************** + */ +void gui_point(uint16_t x, uint16_t y, T_COLOR color); + +/** + ***************************************************************************************** + * @brief Read a point from display memory. + * + * @param[in] x: X coordinate. + * @param[in] y: Y coordinate. + * + * @return The color of the read point.(Return 0xff:error) + ***************************************************************************************** + */ +T_COLOR gui_read_point(uint16_t x, uint16_t y); + +/** + ***************************************************************************************** + * @brief Set refresh flag to true. + ***************************************************************************************** + */ +void gui_refresh(void); + +/** + ***************************************************************************************** + * @brief Check if the refresh flag is true, if flag is true, refresh the gram memory data to display. + * + * @note This function should be called in main while or in timer handler + ***************************************************************************************** + */ +void gui_refresh_schedule(void); + +/** + ***************************************************************************************** + * @brief Refresh the rectangle gram memory data to display. + * + * @param[in] x0: X0 coordinate. + * @param[in] y0: Y0 coordinate. + * @param[in] x1: X1 coordinate. + * @param[in] y1: Y1 coordinate. + ***************************************************************************************** + */ +void gui_rectangle_refresh(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/** + ***************************************************************************************** + * @brief If refresh gram memory to the display area + * + * @param[in] gram_enable: true -- gram memory false -- buffer memory + ***************************************************************************************** + */ +void gui_set_refresh_mem(bool gram_enable); +/*------------------------*/ + +/**** animation config ****/ +#if ANIMATION_EN==1 + +/**@brief Animation param config. */ +#define GUI_X_MOVE_PIXEL 32 +#define GUI_Y_MOVE_PIXEL 32 +#define GUI_X_MOVE_FRAME (GUI_DISPLAY_X_MAX / GUI_X_MOVE_PIXEL) +#define GUI_Y_MOVE_FRAME (GUI_DISPLAY_Y_MAX / GUI_Y_MOVE_PIXEL) + +/** + ***************************************************************************************** + * @brief start animation timer + ***************************************************************************************** + */ +void gui_animation_timer_start(void); + +/** + ***************************************************************************************** + * @brief stop animation timer + ***************************************************************************************** + */ +void gui_animation_timer_stop(void); + +#endif +/*------------------------*/ + +/**** Font GB2312 config ****/ +#if FONT_GB2312_EN==1 + +/** + ***************************************************************************************** + * @brief Reads gb2312 font data based on offset + * + * @param[in] offset: font offset + * @param[out] read_buf: Read datas + ***************************************************************************************** + */ +void gui_read_gb2312(uint32_t offset, uint8_t* read_buf); + +/** + ***************************************************************************************** + * @brief Reads ascii font data based on offset + * + * @param[in] offset: font offset + * @param[out] read_buf: Read datas + ***************************************************************************************** + */ +void gui_read_ascii(uint32_t offset, uint8_t* read_buf); +#endif + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_gb2312_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_gb2312_config.c new file mode 100644 index 0000000..ac4a222 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_gb2312_config.c @@ -0,0 +1,72 @@ +/** + ***************************************************************************************** + * + * @file gui_lcm_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_config.h" + +#if FONT_GB2312_EN==1 +#include "hal_flash.h" + +/* + * DEFINES + ***************************************************************************************** + */ +//You can convert bin files in the GUI config folder into hex files that specify flash addresses +#define GB2312_FLASH_START_ADDR (0x0103d000) /**< Flash address of gb2312 font code. */ +#define ASCII_FLASH_ADDR (0x0103d000 + 0x3FE40) /**< Flash address of ascii font code. */ + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void gui_read_gb2312(uint32_t offset, uint8_t* read_buf) +{ + hal_flash_read(GB2312_FLASH_START_ADDR + offset, read_buf, 32); +} + + +void gui_read_ascii(uint32_t offset, uint8_t* read_buf) +{ + hal_flash_read(ASCII_FLASH_ADDR + offset, read_buf, 16); +} + +#endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcd_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcd_config.c new file mode 100644 index 0000000..2a8c548 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcd_config.c @@ -0,0 +1,102 @@ +/** + ***************************************************************************************** + * + * @file gui_lcm_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "gui_config.h" +#include "st7735.h" +#include "gui_animation.h" + +static bool gui_refresh_flag = false; +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ + +void gui_init(void) +{ + lcd_init(); + gui_animation_init(g_lcd_gram, g_lcd_buffer); +} + +void gui_fill_mem(T_COLOR color) +{ + lcd_fill_mem(color); +} + +void gui_rectangle_fill_mem(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, T_COLOR color) +{ + lcd_rectangle_fill_mem(x0, y0, x1, y1, color); +} + +void gui_point(uint16_t x, uint16_t y, T_COLOR color) +{ + lcd_draw_point(x, y, color); +} + +T_COLOR gui_read_point(uint16_t x, uint16_t y) +{ + return lcd_read_point(x, y); +} + +void gui_refresh(void) +{ + gui_refresh_flag = true; +} + +void gui_rectangle_refresh(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + lcd_rectangle_refresh(x0, y0, x1, y1); +} + +void gui_set_refresh_mem(bool gram_set) +{ + lcd_set_memory(gram_set); +} + +void gui_refresh_schedule(void) +{ + if(gui_refresh_flag) + { + lcd_refresh(); + gui_refresh_flag = false; + } +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_cfg.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_cfg.c new file mode 100644 index 0000000..81dae52 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_cfg.c @@ -0,0 +1,104 @@ +/** + ***************************************************************************************** + * + * @file gui_lcm_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "gui_config.h" +#include "lcm.h" +#include "gui_animation.h" + + +extern lcm_def_t st7735_lcm_opt; +const lcm_def_t *p_lcm_opt = &st7735_lcm_opt; +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ + +void gui_init(void) +{ + p_lcm_opt->lcm_init(); + gui_animation_init(p_lcm_opt->lcm_freambuffer_draw, p_lcm_opt->lcm_freambuffer_map); +} + +void gui_fill(T_COLOR dat) +{ + p_lcm_opt->lcm_fill_color(dat); +} + +void gui_point(uint16_t x, uint16_t y, T_COLOR color) +{ + if (x >= p_lcm_opt->lcm_var.lcm_width) + return; + if (y >= p_lcm_opt->lcm_var.lcm_height) + return; + p_lcm_opt->lcm_draw_point(x, y, color); +} + +T_COLOR gui_read_point(uint16_t x, uint16_t y) +{ + if (x >= p_lcm_opt->lcm_var.lcm_width) + return 0x0; + if (y >= p_lcm_opt->lcm_var.lcm_height) + return 0x0; + return (T_COLOR)p_lcm_opt->lcm_read_point(x, y); +} + +void lcm_set_memory(lcm_memory_type_t type) +{ + //p_lcm_opt->lcm_set_buffer(type); +} + + +void gui_refresh(void) +{ + p_lcm_opt->lcm_refresh(); +} + +void gui_render(uint8_t *p_map) +{ + p_lcm_opt->lcm_render(p_map); +} + + +void lcm_load_16x32(uint8_t x,uint8_t y_page, const uint8_t(*code16_32)[16],uint8_t index) +{ + //fill it +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_config.c new file mode 100644 index 0000000..fac85a5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_lcm_config.c @@ -0,0 +1,83 @@ +/** + ***************************************************************************************** + * + * @file gui_lcm_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "gui_config.h" +#include "uc1701.h" +#include "gui_animation.h" + + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void gui_init(void) +{ + lcm_init(); + gui_animation_init(s_lcm_gram, s_lcm_buffer); +} + + +void gui_fill(T_COLOR dat) +{ + lcm_fill(dat); +} + + +void gui_point(uint16_t x, uint16_t y, T_COLOR color) +{ + lcm_draw_point(x, y, color); +} + + +T_COLOR gui_read_point(uint16_t x, uint16_t y) +{ + return lcm_read_point(x, y); +} + + +void gui_refresh(void) +{ + lcm_set_memory(MEM_GRAM); + lcm_refresh(); +} + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_oled_config.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_oled_config.c new file mode 100644 index 0000000..10953e3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_config/gui_oled_config.c @@ -0,0 +1,82 @@ +/** + ***************************************************************************************** + * + * @file gui_oled_config.c + * + * @brief Users should implement the timer-related interface themselves + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "gui_config.h" +#include "ssd1316.h" +#include "gui_animation.h" + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void gui_init(void) +{ + oled_init(); + gui_animation_init(s_oled_gram, s_oled_buffer); +} + + +void gui_fill(T_COLOR dat) +{ + oled_fill(dat); +} + + +void gui_point(uint16_t x, uint8_t y, T_COLOR color) +{ + oled_draw_point(x, y, color); +} + + +T_COLOR gui_read_point(uint16_t x, uint8_t y) +{ + return oled_read_point(x, y); +} + + +void gui_refresh(void) +{ + oled_set_memory(MEM_GRAM); + oled_refresh(); +} + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.c new file mode 100644 index 0000000..642495d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.c @@ -0,0 +1,179 @@ +/** + **************************************************************************************** + * + * @file gui_convert_color.c + * + * @brief Function of convert color + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_convert_color.h" +#include "gui_config.h" + +#if CONVERT_COLOR_EN==1 + +uint16_t gui_color_to_index_565(uint32_t color_rgb) +{ uint8_t r, g, b; + + b = ( color_rgb>>(0+3) ) & 0x1f; + g = ( color_rgb>>(8+2) ) & 0x3f; + r = ( color_rgb>>(16+3)) & 0x1f; + + return( (r<<11) + (g<<5) + (b<<0) ); +} + +uint32_t gui_index_to_color_565(uint16_t index) +{ uint32_t r, g, b; + + b = (index>>0) & 0x1f; + g = (index>>5) & 0x3f; + r = (index>>11) & 0x1f; + r = r * 255 / 31; + g = g * 255 / 63; + b = b * 255 / 31; + + return( (r<<16) + (g<<8) + (b<<0) ); +} + +uint16_t gui_color_to_index_555(uint32_t color_rgb) +{ uint8_t r, g, b; + + b = ( color_rgb>>(0+3) ) & 0x1f; + g = ( color_rgb>>(8+3) ) & 0x1f; + r = ( color_rgb>>(16+3)) & 0x1f; + + return( (r<<10) + (g<<5) + (b<<0) ); +} + +uint32_t gui_index_to_color_555(uint16_t index) +{ uint32_t r, g, b; + + b = (index>>0) & 0x1f; + g = (index>>5) & 0x1f; + r = (index>>10) & 0x1f; + r = r * 255 / 31; + g = g * 255 / 31; + b = b * 255 / 31; + + return( (r<<16) + (g<<8) + (b<<0) ); +} + +uint16_t gui_color_to_index_444(uint32_t color_rgb) +{ uint8_t r,g,b; + + b = ( color_rgb>>(0+4) ) & 0x0f; + g = ( color_rgb>>(8+4) ) & 0x0f; + r = ( color_rgb>>(16+4)) & 0x0f; + + return ( (r<<8) + (g << 4) + (b<<0) ); +} + +uint32_t gui_index_to_color_444(uint16_t index) +{ uint8_t r,g,b; + + b = (index >> 0) & 0x0f; + g = (index >> 4) & 0x0f; + r = (index >> 8) & 0x0f; + + r = r * 17; + g = g * 17; + b = b * 17; + + return ( (r<<16) + (g<<8) + (b<<0) ); +} + +uint8_t gui_color_to_index_332(uint32_t color_rgb) +{ uint32_t r, g, b; + + b = (color_rgb>>0) & 0xff; + g = (color_rgb>>8) & 0xff; + r = (color_rgb>>16) & 0xff; + r = (r * 7 + 127) / 255; + g = (g * 7 + 127) / 255; + b = (b + 42) / 85; + + return( (r<<5) + (g << 2) + (b<<0) ); +} + +uint32_t gui_index_to_color_332(uint8_t index) +{ uint32_t r, g, b; + + r = (index >> 5) * 255 / 7; + g = ((index >> 3) & 7) * 255 / 7; + b = (index & 3) * 85; + + return( (r<<16) + (g << 8) + (b<<0) ); +} + +uint8_t gui_color_to_index_222(uint32_t color_rgb) +{ uint32_t r, g, b; + + b = (((color_rgb>>0) &255)+0x2a)/0x55; + g = (((color_rgb>>8) &255)+0x2a)/0x55; + r = (((color_rgb>>16)&255)+0x2a)/0x55; + + return( (r<<4) + (g<<2) + (b<<0) ); +} + +uint32_t gui_index_to_color_222(uint8_t index) +{ uint8_t r, g, b; + + b = ((index>>0)&3) * 0x55; + g = ((index>>2)&3) * 0x55; + r = ((index>>4)&3) * 0x55; + + return( (r<<16) + (g<<8) + (b<<0) ); +} + +uint8_t gui_color_to_index_111(uint32_t color_rgb) +{ uint8_t r, g, b; + + b = (color_rgb>>(0+7)) &1; + g = (color_rgb>>(8+7)) &1; + r = (color_rgb>>(16+7)) &1; + + return( (r<<2) + (g<<1) + (b<<0) ); +} + +uint32_t gui_index_to_color_111(uint8_t index) +{ + uint8_t r, g, b; + b = ((index>>0)&1) * 0xff; + g = ((index>>1)&1) * 0xff; + r = ((index>>2)&1) * 0xff; + + return( (r<<16) + (g<<8) + (b<<0) ); +} +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.h new file mode 100644 index 0000000..028ae0c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_convert_color.h @@ -0,0 +1,194 @@ +/** + ***************************************************************************************** + * + * @file gui_convert_color.h + * + * @brief Convert color API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +#ifndef GUI_CONVERT_COLOR_H +#define GUI_CONVERT_COLOR_H + +#include "gui_config.h" + +#if CONVERT_COLOR_EN==1 + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 16-bit index value. + * @note The convert value applies to a 64K color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 16-bit index value(64K color, d15-d11 for R value, d10-d5 for G value, d4-d0 for B value) + ***************************************************************************************** + */ +uint16_t gui_color_to_index_565(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 16-bit index value to a RGB value. + * @note The convert value applies to a 64K color LCD screen. + * + * @param[in] index: 16 bit index value. + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_565(uint16_t index); + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 15-bit index value. + * @note The convert value applies to a 32K color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 15-bit index value. + ***************************************************************************************** + */ +uint16_t gui_color_to_index_555(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 15-bit index value to a RGB value. + * @note The convert value applies to a 32K color LCD screen. + * + * @param[in] index: 15 bit index value. + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_555(uint16_t index); + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 12-bit index value. + * @note The convert value applies to a 4096 color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 12-bit index value.(RRRRGGGGBBBB) + ***************************************************************************************** + */ +uint16_t gui_color_to_index_444(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 12-bit index value to a RGB value. + * @note The convert value applies to a 4096 color LCD screen. + * + * @param[in] index: 12 bit index value.(RRRRGGGGBBBB) + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_444(uint16_t index); + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 8-bit index value. + * @note The convert value applies to a 256 color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 8-bit index value.(RRRGGGBB) + ***************************************************************************************** + */ +uint8_t gui_color_to_index_332(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 8-bit index value to a RGB value. + * @note The convert value applies to a 256 color LCD screen. + * + * @param[in] index: 8 bit index value.(RRRGGGBB) + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_332(uint8_t index); + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 6-bit index value. + * @note The convert value applies to a 256 color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 6-bit index value.(RRGGBB) + ***************************************************************************************** + */ +uint8_t gui_color_to_index_222(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 6-bit index value to a RGB value. + * @note The convert value applies to a 64K color LCD screen. + * + * @param[in] index: 6 bit index value.(RRGGBB) + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_222(uint8_t index); + +/** + ***************************************************************************************** + * @brief Convert the RGB value to a 3-bit index value. + * @note The convert value applies to a 64 color LCD screen. + * + * @param[in] color_rgb: RGB value. + * + * @return 3-bit index value.(RGB) + ***************************************************************************************** + */ +uint8_t gui_color_to_index_111(uint32_t color_rgb); + +/** + ***************************************************************************************** + * @brief Convert the 3-bit index value to a RGB value. + * @note The convert value applies to a 64 color LCD screen. + * + * @param[in] index: 3 bit index value.(RGB) + * + * @return RGB value + ***************************************************************************************** + */ +uint32_t gui_index_to_color_111(uint8_t index); +#endif + +#endif + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font5_7.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font5_7.c new file mode 100644 index 0000000..0759388 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font5_7.c @@ -0,0 +1,1163 @@ +/** + **************************************************************************************** + * + * @file gui_font5_7.c + * + * @brief Function of show 5*7 ascii + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_font5_7.h" +#include "gui_font_macro.h" +#include "gui_color.h" +#include "gui_basic.h" + +#if FONT5x7_EN==1 + +/**@brief 5*7 ascii define. */ +const uint8_t s_ascii_font5_7[][8] = { +/* space */ + { + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________} + +/* ! */ + ,{ + X_______, + X_______, + X_______, + X_______, + X_______, + ________, + X_______, + ________} + + +/* " */ + ,{ + X_X_____, + X_X_____, + X_X_____, + ________, + ________, + ________, + ________, + ________} + +/* # */ + ,{ + _X_X____, + _X_X____, + XXXXX___, + _X_X____, + XXXXX___, + _X_X____, + _X_X____, + ________} + +/* $ */ + ,{ + __X_____, + _XXXX___, + X_X_____, + _XXX____, + __X_X___, + XXXX____, + __X_____} + +/* % */ + ,{ + XX______, + XX__X___, + ___X____, + __X_____, + _X______, + X__XX___, + ___XX___, + ________} + +/* & */ + ,{ + _XX_____, + X__X____, + X_X_____, + _X______, + X_X_X___, + X__X____, + _XX_X___, + ________} + +/* ' */ + ,{ + XX______, + _X______, + X_______, + ________, + ________, + ________, + ________, + ________} + +/* ( */ + ,{ + __X_____, + _X______, + X_______, + X_______, + X_______, + _X______, + __X_____, + ________} + +/* ) */ + ,{ + X_______, + _X______, + __X_____, + __X_____, + __X_____, + _X______, + X_______, + ________} + +/* * */ + ,{ + ________, + _X_X____, + __X_____, + XXXXX___, + __X_____, + _X_X____, + ________, + ________} + + ,{ + ________, + __X_____, + __X_____, + XXXXX___, + __X_____, + __X_____, + ________, + ________} + + ,{ + ________, + ________, + ________, + ________, + ________, + XX______, + _X______, + X_______} + + ,{ + ________, + ________, + ________, + XXXXX___, + ________, + ________, + ________, + ________} + + ,{ + ________, + ________, + ________, + ________, + ________, + XX______, + XX______, + ________} + + ,{ + ________, + ____X___, + ___X____, + __X_____, + _X______, + X_______, + ________, + ________} + +/* 0 */ + ,{ + _XXX____, + X___X___, + X__XX___, + X_X_X___, + XX__X___, + X___X___, + _XXX____, + ________} + +/* 1 */ + ,{ + __X_____, + _XX_____, + __X_____, + __X_____, + __X_____, + __X_____, + _XXX____, + ________} + +/* 2 */ + ,{ + _XXX____, + X___X___, + ____X___, + __XX____, + _X______, + X_______, + XXXXX___, + ________} + +/* 3 */ + ,{ + _XXX____, + X___X___, + ____X___, + __XX____, + ____X___, + X___X___, + _XXX____, + ________} + +/* 4 */ + ,{ + ___X____, + __XX____, + _X_X____, + X__X____, + XXXXX___, + ___X____, + ___X____, + ________} + +/* 5 */ + ,{ + XXXXX___, + X_______, + XXXX____, + ____X___, + ____X___, + X___X___, + _XXX____, + ________} + +/* 6 */ + ,{ + __XX____, + _X______, + X_______, + XXXX____, + X___X___, + X___X___, + _XXX____, + ________} + +/* 7 */ + ,{ + XXXXX___, + ____X___, + ___X____, + __X_____, + _X______, + _X______, + _X______, + ________} + +/* 8 */ + ,{ + _XXX____, + X___X___, + X___X___, + _XXX____, + X___X___, + X___X___, + _XXX____, + ________} + +/* 9 */ + ,{ + _XXX____, + X___X___, + X___X___, + _XXXX___, + ____X___, + ___X____, + _XX_____, + ________} + +/* ':' 3a */ + ,{ + ________, + XX______, + XX______, + ________, + XX______, + XX______, + ________, + ________} + +/* ';' 3b */ + ,{ + ________, + ________, + XX______, + XX______, + ________, + XX______, + _X______, + X_______} + + +/* '<' 3c */ + ,{ + ___X____, + __X_____, + _X______, + X_______, + _X______, + __X_____, + ___X____, + ________} + +/* '=' 3d */ + ,{ + ________, + ________, + XXXXX___, + ________, + XXXXX___, + ________, + ________, + ________} + +/* '>' */ + ,{ + X_______, + _X______, + __X_____, + ___X____, + __X_____, + _X______, + X_______, + ________} + +/* '?' */ + ,{ + _XXX____, + X___X___, + ____X___, + ___X____, + __X_____, + ________, + __X_____, + ________} + +/* @ */ + ,{ + _XXX____, + X___X___, + ____X___, + _XX_X___, + X_X_X___, + X_X_X___, + _XXX____, + ________} + +/* A */ + ,{ + _XXX____, + X___X___, + X___X___, + XXXXX___, + X___X___, + X___X___, + X___X___, + ________} + +/* B */ + ,{ + XXXX____, + X___X___, + X___X___, + XXXX____, + X___X___, + X___X___, + XXXX____, + ________} + +/* C */ + ,{ + _XXX____, + X___X___, + X_______, + X_______, + X_______, + X___X___, + _XXX____, + ________} + +/* D */ + ,{ + XXX_____, + X__X____, + X___X___, + X___X___, + X___X___, + X__X____, + XXX_____, + ________} + +/* E */ + ,{ + XXXXX___, + X_______, + X_______, + XXXX____, + X_______, + X_______, + XXXXX___, + ________} + +/* F */ + ,{ + XXXXX___, + X_______, + X_______, + XXXX____, + X_______, + X_______, + X_______, + ________} + +/* G */ + ,{ + _XXX____, + X___X___, + X_______, + X_______, + X__XX___, + X___X___, + _XXXX___, + ________} + +/* H */ + ,{ + X___X___, + X___X___, + X___X___, + XXXXX___, + X___X___, + X___X___, + X___X___, + ________} + +/* I */ + ,{ + XXX_____, + _X______, + _X______, + _X______, + _X______, + _X______, + XXX_____, + ________} + +/* J */ + ,{ + __XXX___, + ___X____, + ___X____, + ___X____, + ___X____, + X__X____, + _XX_____, + ________} + +/* K */ + ,{ + X___X___, + X__X____, + X_X_____, + XX______, + X_X_____, + X__X____, + X___X___, + ________} + +/* L */ + ,{ + X_______, + X_______, + X_______, + X_______, + X_______, + X_______, + XXXXX___, + ________} + +/* M */ + ,{ + X___X___, + XX_XX___, + X_X_X___, + X_X_X___, + X___X___, + X___X___, + X___X___, + ________} + +/* N */ + ,{ + X___X___, + X___X___, + XX__X___, + X_X_X___, + X__XX___, + X___X___, + X___X___, + ________} + +/* O */ + ,{ + _XXX____, + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + _XXX____, + ________} + +/* P */ + ,{ + XXXX____, + X___X___, + X___X___, + XXXX____, + X_______, + X_______, + X_______, + ________} + +/* Q */ + ,{ + _XXX____, + X___X___, + X___X___, + X___X___, + X_X_X___, + X__X____, + _XX_X___, + ________} + +/* R */ + ,{ + XXXX____, + X___X___, + X___X___, + XXXX____, + X_X_____, + X__X____, + X___X___, + ________} + +/* S */ + ,{ + _XXX____, + X___X___, + X_______, + _XXX____, + ____X___, + X___X___, + _XXX____, + ________} + +/* T */ + ,{ + XXXXX___, + __X_____, + __X_____, + __X_____, + __X_____, + __X_____, + __X_____, + ________} + +/* U */ + ,{ + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + _XXX____, + ________} + +/* V */ + ,{ + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + _X_X____, + __X_____, + ________} + +/* W */ + ,{ + X___X___, + X___X___, + X___X___, + X_X_X___, + X_X_X___, + X_X_X___, + _X_X____, + ________} + +/* X */ + ,{ + X___X___, + X___X___, + _X_X____, + __X_____, + _X_X____, + X___X___, + X___X___, + ________} + +/* Y */ + ,{ + X___X___, + X___X___, + _X_X____, + __X_____, + __X_____, + __X_____, + __X_____, + ________} + +/* Z */ + ,{ + XXXXX___, + ____X___, + ___X____, + __X_____, + _X______, + X_______, + XXXXX___, + ________} + +/* 5b */ + ,{ + XXX_____, + X_______, + X_______, + X_______, + X_______, + X_______, + XXX_____, + ________} + +/* 5c */ + ,{ + ________, + X_______, + _X______, + __X_____, + ___X____, + ____X___, + ________, + ________} + +/* 5d */ + ,{ + XXX_____, + __X_____, + __X_____, + __X_____, + __X_____, + __X_____, + XXX_____, + ________} + +/* 5e */ + ,{ + __X_____, + _X_X____, + X___X___, + ________, + ________, + ________, + ________, + ________} + +/* 5f */ + ,{ + ________, + ________, + ________, + ________, + ________, + ________, + ________, + XXXXX___} + +/* 60 */ + ,{ + X_______, + _X______, + __X_____, + ________, + ________, + ________, + ________, + ________} + +/* a */ + ,{ + ________, + ________, + _XXX____, + ____X___, + _XXXX___, + X___X___, + _XXXX___, + ________} + +/* b */ + ,{ + X_______, + X_______, + X_XX____, + XX__X___, + X___X___, + X___X___, + XXXX____, + ________} + +/* c */ + ,{ + ________, + ________, + _XX_____, + X__X____, + X_______, + X__X____, + _XX_____, + ________} + +/* d */ + ,{ + ____X___, + ____X___, + _XX_X___, + X__XX___, + X___X___, + X___X___, + _XXXX___, + ________} + +/* e */ + ,{ + ________, + ________, + _XXX____, + X___X___, + XXXXX___, + X_______, + _XXX____, + ________} + +/* f */ + ,{ + __X_____, + _X_X____, + _X______, + XXX_____, + _X______, + _X______, + _X______, + ________} + +/* g */ + ,{ + ________, + ________, + _XXXX___, + X___X___, + X___X___, + _XXXX___, + ____X___, + _XXX____} + +/* h */ + ,{ + X_______, + X_______, + X_XX____, + XX__X___, + X___X___, + X___X___, + X___X___, + ________} + +/* i */ + ,{ + _X______, + ________, + _X______, + _X______, + _X______, + _X______, + _X______, + ________} + +/* j */ + ,{ + __X_____, + ________, + _XX_____, + __X_____, + __X_____, + __X_____, + __X_____, + XX______} + +/* k */ + ,{ + X_______, + X_______, + X__X____, + X_X_____, + XX______, + X_X_____, + X__X____, + ________} + +/* l */ + ,{ + XX______, + _X______, + _X______, + _X______, + _X______, + _X______, + XXX_____, + ________} + +/* m */ + ,{ + ________, + ________, + XX_X____, + X_X_X___, + X_X_X___, + X___X___, + X___X___, + ________} + +/* n */ + ,{ + ________, + ________, + X_XX____, + XX_X____, + X__X____, + X__X____, + X__X____, + ________} + +/* o */ + ,{ + ________, + ________, + _XX_____, + X__X____, + X__X____, + X__X____, + _XX_____, + ________} + +/* p */ + ,{ + ________, + ________, + XXX_____, + X__X____, + X__X____, + XXX_____, + X_______, + X_______} + +/* q */ + ,{ + ________, + ________, + _XXX____, + X__X____, + X__X____, + _XXX____, + ___X____, + ___X____} + +/* r */ + ,{ + ________, + ________, + _X_X____, + _XX_____, + _X______, + _X______, + _X______, + ________} + +/* s */ + ,{ + ________, + ________, + _XXX____, + X_______, + _XX_____, + ___X____, + XXX_____, + ________} + +/* t */ + ,{ + _X______, + _X______, + XXX_____, + _X______, + _X______, + _X______, + _XX_____, + ________} + +/* u */ + ,{ + ________, + ________, + X__X____, + X__X____, + X__X____, + X__X____, + _XXX____, + ________} + +/* v */ + ,{ + ________, + ________, + X___X___, + X___X___, + X___X___, + _X_X____, + __X_____, + ________} + +/* w */ + ,{ + ________, + ________, + X___X___, + X___X___, + X_X_X___, + X_X_X___, + _X_X____, + ________} + +/* X */ + ,{ + ________, + ________, + X___X___, + _X_X____, + __X_____, + _X_X____, + X___X___, + ________} + +/* y */ + ,{ + ________, + ________, + X__X____, + X__X____, + X__X____, + _XXX____, + ___X____, + _XX_____} + +/* z */ + ,{ + ________, + ________, + XXXXX___, + ___X____, + __X_____, + _X______, + XXXXX___, + ________} + +/* 0x7b */ + ,{ + __X_____, + _X______, + _X______, + X_______, + _X______, + _X______, + __X_____, + ________} + +/* 0x7c */ + ,{ + _X______, + _X______, + _X______, + _X______, + _X______, + _X______, + _X______, + ________} + +/* 0x7d */ + ,{ + X_______, + _X______, + _X______, + __X_____, + _X______, + _X______, + X_______, + ________} + +/* 0x7e */ + ,{ + _XX_X___, + X__X____, + ________, + ________, + ________, + ________, + ________, + ________} + +/* 0x7f */ + ,{ + XXXXX___, + XXXXX___, + XXXXX___, + XXXXX___, + XXXXX___, + XXXXX___, + XXXXX___, + ________} + +}; + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +uint8_t gui_put_char5_7(uint16_t x, uint16_t y, uint8_t ch) +{ + uint8_t i; + if( x>(GUI_DISPLAY_X_MAX-8) ) + return(0); + if( y>(GUI_DISPLAY_Y_MAX-8) ) + return(0); + if( (ch<0x20) || (ch>0x7f) ) + ch = 0x20; + + ch -= 0x20; + for(i=0; i<8; i++) + { + gui_point_color(x, y, s_ascii_font5_7[ch][i], 6); + y++; + } + + return(1); +} + + + +void gui_put_string5_7(uint16_t x, uint16_t y, char *p_str) +{ + while(1) + { + if( (*p_str)=='\0' ) break; + if( gui_put_char5_7(x, y, *p_str++)==0 ) break; + x += 6; + } +} + +void gui_put_num5_7(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t mode) +{ + uint8_t t,temp; + uint8_t enshow = 0; + for(t=0; t */ + ,{ + _XX_____, + __XX____, + ___XX___, + ____XX__, + ___XX___, + __XX____, + _XX_____, + ________} + +/* ? */ + ,{ + _XXXXX__, + XX___XX_, + ____XX__, + ___XX___, + ___XX___, + ________, + ___XX___, + ________} + +/* @ */ + ,{ + _XXXXX__, + XX___XX_, + XX_XXXX_, + XX_XXXX_, + XX_XXXX_, + XX______, + _XXXX___, + ________} + +/* A */ + ,{ + __XXX___, + _XX_XX__, + XX___XX_, + XXXXXXX_, + XX___XX_, + XX___XX_, + XX___XX_, + ________} + +/* B */ + ,{ + XXXXXX__, + _XX__XX_, + _XX__XX_, + _XXXXX__, + _XX__XX_, + _XX__XX_, + XXXXXX__, + ________} + +/* C */ + ,{ + __XXXX__, + _XX__XX_, + XX______, + XX______, + XX______, + _XX__XX_, + __XXXX__, + ________} + +/* D */ + ,{ + XXXXX___, + _XX_XX__, + _XX__XX_, + _XX__XX_, + _XX__XX_, + _XX_XX__, + XXXXX___, + ________} + +/* E */ + ,{ + XXXXXXX_, + _XX___X_, + _XX_X___, + _XXXX___, + _XX_X___, + _XX___X_, + XXXXXXX_, + ________} + +/* F */ + ,{ + XXXXXXX_, + _XX___X_, + _XX_X___, + _XXXX___, + _XX_X___, + _XX_____, + XXXX____, + ________} + +/* G */ + ,{ + __XXXX__, + _XX__XX_, + XX______, + XX______, + XX__XXX_, + _XX__XX_, + __XXX_X_, + ________} + +/* H */ + ,{ + XX___XX_, + XX___XX_, + XX___XX_, + XXXXXXX_, + XX___XX_, + XX___XX_, + XX___XX_, + ________} + +/* I */ + ,{ + __XXXX__, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + __XXXX__, + ________} + +/* J */ + ,{ + ___XXXX_, + ____XX__, + ____XX__, + ____XX__, + XX__XX__, + XX__XX__, + _XXXX___, + ________} + +/* K */ + ,{ + XXX__XX_, + _XX__XX_, + _XX_XX__, + _XXXX___, + _XX_XX__, + _XX__XX_, + XXX__XX_, + ________} + +/* L */ + ,{ + XXXX____, + _XX_____, + _XX_____, + _XX_____, + _XX___X_, + _XX__XX_, + XXXXXXX_, + ________} + +/* M */ + ,{ + XX___XX_, + XXX_XXX_, + XXXXXXX_, + XXXXXXX_, + XX_X_XX_, + XX___XX_, + XX___XX_, + ________} + +/* N */ + ,{ + XX___XX_, + XXX__XX_, + XXXX_XX_, + XX_XXXX_, + XX__XXX_, + XX___XX_, + XX___XX_, + ________} + +/* O */ + ,{ + _XXXXX__, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + _XXXXX__, + ________} + +/* P */ + ,{ + XXXXXX__, + _XX__XX_, + _XX__XX_, + _XXXXX__, + _XX_____, + _XX_____, + XXXX____, + ________} + +/* Q */ + ,{ + _XXXXX__, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + XX__XXX_, + _XXXXX__, + ____XXX_} + +/* R */ + ,{ + XXXXXX__, + _XX__XX_, + _XX__XX_, + _XXXXX__, + _XX_XX__, + _XX__XX_, + XXX__XX_, + ________} + +/* S */ + ,{ + __XXXX__, + _XX__XX_, + __XX____, + ___XX___, + ____XX__, + _XX__XX_, + __XXXX__, + ________} + +/* T */ + ,{ + _XXXXXX_, + _XXXXXX_, + _X_XX_X_, + ___XX___, + ___XX___, + ___XX___, + __XXXX__, + ________} + +/* U */ + ,{ + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + _XXXXX__, + ________} + +/* V */ + ,{ + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + XX___XX_, + _XX_XX__, + __XXX___, + ________} + +/* W */ + ,{ + XX___XX_, + XX___XX_, + XX___XX_, + XX_X_XX_, + XX_X_XX_, + XXXXXXX_, + _XX_XX__, + ________} + +/* X */ + ,{ + XX___XX_, + XX___XX_, + _XX_XX__, + __XXX___, + _XX_XX__, + XX___XX_, + XX___XX_, + ________} + +/* Y */ + ,{ + _XX__XX_, + _XX__XX_, + _XX__XX_, + __XXXX__, + ___XX___, + ___XX___, + __XXXX__, + ________} + +/* Z */ + ,{ + XXXXXXX_, + XX___XX_, + X___XX__, + ___XX___, + __XX__X_, + _XX__XX_, + XXXXXXX_, + ________} + +/* [ */ + ,{ + __XXXX__, + __XX____, + __XX____, + __XX____, + __XX____, + __XX____, + __XXXX__, + ________} + +/* \ */ + ,{ + XX______, + _XX_____, + __XX____, + ___XX___, + ____XX__, + _____XX_, + ______X_, + ________} + +/* ] */ + ,{ + __XXXX__, + ____XX__, + ____XX__, + ____XX__, + ____XX__, + ____XX__, + __XXXX__, + ________} + +/* ^ */ + ,{ + ___X____, + __XXX___, + _XX_XX__, + XX___XX_, + ________, + ________, + ________, + ________} + +/* _ */ + ,{ + ________, + ________, + ________, + ________, + ________, + ________, + ________, + XXXXXXXX} + +/* ` */ + ,{ + __XX____, + ___XX___, + ____XX__, + ________, + ________, + ________, + ________, + ________} + +/* a */ + ,{ + ________, + ________, + _XXXX___, + ____XX__, + _XXXXX__, + XX__XX__, + _XXX_XX_, + ________} + +/* b */ + ,{ + XXX_____, + _XX_____, + _XXXXX__, + _XX__XX_, + _XX__XX_, + _XX__XX_, + XX_XXX__, + ________} + +/* c */ + ,{ + ________, + ________, + _XXXXX__, + XX___XX_, + XX______, + XX___XX_, + _XXXXX__, + ________} + +/* d */ + ,{ + ___XXX__, + ____XX__, + _XXXXX__, + XX__XX__, + XX__XX__, + XX__XX__, + _XXX_XX_, + ________} + +/* e */ + ,{ + ________, + ________, + _XXXXX__, + XX___XX_, + XXXXXXX_, + XX______, + _XXXXX__, + ________} + +/* f */ + ,{ + __XXXX__, + _XX__XX_, + _XX_____, + XXXXX___, + _XX_____, + _XX_____, + XXXX____, + ________} + +/* g */ + ,{ + ________, + ________, + _XXX_XX_, + XX__XX__, + XX__XX__, + _XXXXX__, + ____XX__, + XXXXX___} + +/* h */ + ,{ + XXX_____, + _XX_____, + _XX_XX__, + _XXX_XX_, + _XX__XX_, + _XX__XX_, + XXX__XX_, + ________} + +/* i */ + ,{ + ___XX___, + ________, + __XXX___, + ___XX___, + ___XX___, + ___XX___, + __XXXX__, + ________} + +/* j */ + ,{ + _____XX_, + ________, + _____XX_, + _____XX_, + _____XX_, + _XX__XX_, + _XX__XX_, + __XXXX__} + +/* k */ + ,{ + XXX_____, + _XX_____, + _XX__XX_, + _XX_XX__, + _XXXX___, + _XX_XX__, + XXX__XX_, + ________} + +/* l */ + ,{ + __XXX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + __XXXX__, + ________} + +/* m */ + ,{ + ________, + ________, + XXX_XX__, + XXXXXXX_, + XX_X_XX_, + XX_X_XX_, + XX_X_XX_, + ________} + +/* n */ + ,{ + ________, + ________, + XX_XXX__, + _XX__XX_, + _XX__XX_, + _XX__XX_, + _XX__XX_, + ________} + +/* o */ + ,{ + ________, + ________, + _XXXXX__, + XX___XX_, + XX___XX_, + XX___XX_, + _XXXXX__, + ________} + +/* p */ + ,{ + ________, + ________, + XX_XXX__, + _XX__XX_, + _XX__XX_, + _XXXXX__, + _XX_____, + XXXX____} + +/* q */ + ,{ + ________, + ________, + _XXX_XX_, + XX__XX__, + XX__XX__, + _XXXXX__, + ____XX__, + ___XXXX_} + +/* r */ + ,{ + ________, + ________, + XX_XXX__, + _XXX_XX_, + _XX_____, + _XX_____, + XXXX____, + ________} + +/* s */ + ,{ + ________, + ________, + _XXXXXX_, + XX______, + _XXXXX__, + _____XX_, + XXXXXX__, + ________} + +/* t */ + ,{ + __XX____, + __XX____, + XXXXXX__, + __XX____, + __XX____, + __XX_XX_, + ___XXX__, + ________} + +/* u */ + ,{ + ________, + ________, + XX__XX__, + XX__XX__, + XX__XX__, + XX__XX__, + _XXX_XX_, + ________} + +/* v */ + ,{ + ________, + ________, + XX___XX_, + XX___XX_, + XX___XX_, + _XX_XX__, + __XXX___, + ________} + +/* w */ + ,{ + ________, + ________, + XX___XX_, + XX_X_XX_, + XX_X_XX_, + XXXXXXX_, + _XX_XX__, + ________} + +/* x */ + ,{ + ________, + ________, + XX___XX_, + _XX_XX__, + __XXX___, + _XX_XX__, + XX___XX_, + ________} + +/* y */ + ,{ + ________, + ________, + XX___XX_, + XX___XX_, + XX___XX_, + _XXXXXX_, + _____XX_, + XXXXXX__} + +/* z */ + ,{ + ________, + ________, + _XXXXXX_, + _X__XX__, + ___XX___, + __XX__X_, + _XXXXXX_, + ________} + +/* { */ + ,{ + ____XXX_, + ___XX___, + ___XX___, + _XXX____, + ___XX___, + ___XX___, + ____XXX_, + ________} + +/* | */ + ,{ + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ___XX___, + ________} + +/* } */ + ,{ + _XXX____, + ___XX___, + ___XX___, + ____XXX_, + ___XX___, + ___XX___, + _XXX____, + ________} + +/* ~ */ + ,{ + _XXX_XX_, + XX_XXX__, + ________, + ________, + ________, + ________, + ________, + ________} + +/* 0x7f */ + ,{ + XXXXXX__, + XXXXXX__, + XXXXXX__, + XXXXXX__, + XXXXXX__, + XXXXXX__, + XXXXXX__, + ________} + +}; + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +uint8_t gui_put_char8_8(uint16_t x, uint16_t y, uint8_t ch) +{ + uint8_t i; + + if( x>(GUI_DISPLAY_X_MAX-8) ) return(0); + if( y>(GUI_DISPLAY_Y_MAX-8) ) return(0); + if( (ch<0x20) || (ch>0x7f) ) ch = 0x20; + + ch -= 0x20; + for(i=0; i<8; i++) + { + gui_point_color(x, y, s_ascii_font8_8[ch][i], 8); + y++; + } + + return(1); +} + + +void gui_put_string8_8(uint16_t x, uint16_t y, char *p_str) +{ while(1) + { if( (*p_str)=='\0' ) break; + if( gui_put_char8_8(x, y, *p_str++)==0 ) break; + x += 6; + } +} + +void gui_put_num8_8(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t mode) +{ + uint8_t t,temp; + uint8_t enshow = 0; + for(t=0; t (GUI_DISPLAY_X_MAX-16) ) + return(0); + if( y_coord > (GUI_DISPLAY_Y_MAX-16) ) + return(0); + offset = (((str1-0xa1)*94) + (str2 - 0xa1)) * 32; + gui_read_gb2312(offset, gb2312_buf); + for(i=0; i<16; i++) + { + gui_point_color(x_coord, y_coord, gb2312_buf[i], 8); + gui_point_color(x_coord+8, y_coord, gb2312_buf[16+i], 8); + y_coord++; + } + + return(1); +} + +/** + ***************************************************************************************** +* @brief Display one 8*16 ascii. +* @note Display value between 0x20 to 0x7f, others show ' '. +* +* @return 0x01--success, 0x00--fail(the coordinate value is out of range) +***************************************************************************************** + */ +static uint8_t gui_put_ascii_char(uint16_t x, uint16_t y, char show_char) +{ + uint8_t i; + uint32_t offset; + uint8_t ascii_buf[16]; + uint16_t x_coord = x; + uint16_t y_coord = y; + + if( x_coord > (GUI_DISPLAY_X_MAX-8) ) + return(0); + if( y_coord > (GUI_DISPLAY_Y_MAX-16) ) + return(0); + offset = (show_char-0x20)*16; + gui_read_ascii(offset, ascii_buf); + for(i=0; i<16; i++) + { + gui_point_color(x_coord, y_coord, ascii_buf[i], 8); + y_coord++; + } + return (1); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +void gui_put_string(uint16_t x, uint16_t y, char *p_str) +{ + uint16_t i=0; + uint16_t x_coord = x; + uint16_t y_coord = y; + while(p_str[i] > 0x00) + { + if((p_str[i]>=0x20) &&(p_str[i]<=0x7e))//assic + { + if(gui_put_ascii_char(x_coord, y_coord, p_str[i])) + { + x_coord += 8; + if( x_coord > (GUI_DISPLAY_X_MAX-8) ) + { + x_coord = 0; + y_coord += 16; + } + } + + i++; + } + else + { + if(gui_put_one_gb2312(x_coord, y_coord, p_str[i], p_str[i+1])) + { + i+=2; + x_coord += 16; + if( x_coord > (GUI_DISPLAY_X_MAX-16) ) + { + x_coord = 0; + y_coord += 16; + } + } + else + { + i++; + } + } + } +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_gb2312.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_gb2312.h new file mode 100644 index 0000000..7580ecf --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_gb2312.h @@ -0,0 +1,59 @@ +/** + ***************************************************************************************** + * + * @file gui_font_gb2312.h + * + * @brief Show gb2312 string API + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef _GUI_FONT_GB2312_H_ +#define _GUI_FONT_GB2312_H_ + +#include "gui_config.h" + +#if FONT_GB2312_EN==1 + +/** + ***************************************************************************************** + * @brief Display gb2312 string and 8*16 ascii char. + * @note No line feed. + * + * @param[in] x: X coordinate. + * @param[in] y: Y coordinate. + * @param[in] p_str: Display string. + ***************************************************************************************** + */ +void gui_put_string(uint16_t x, uint16_t y, char *p_str); + +#endif + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_macro.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_macro.h new file mode 100644 index 0000000..23d48b1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_macro.h @@ -0,0 +1,261 @@ +#ifndef FONT_MACRO_H +#define FONT_MACRO_H + +#define ________ 0x00 +#define _______X 0x01 +#define ______X_ 0x02 +#define ______XX 0x03 +#define _____X__ 0x04 +#define _____X_X 0x05 +#define _____XX_ 0x06 +#define _____XXX 0x07 +#define ____X___ 0x08 +#define ____X__X 0x09 +#define ____X_X_ 0x0a +#define ____X_XX 0x0b +#define ____XX__ 0x0c +#define ____XX_X 0x0d +#define ____XXX_ 0x0e +#define ____XXXX 0x0f +#define ___X____ 0x10 +#define ___X___X 0x11 +#define ___X__X_ 0x12 +#define ___X__XX 0x13 +#define ___X_X__ 0x14 +#define ___X_X_X 0x15 +#define ___X_XX_ 0x16 +#define ___X_XXX 0x17 +#define ___XX___ 0x18 +#define ___XX__X 0x19 +#define ___XX_X_ 0x1a +#define ___XX_XX 0x1b +#define ___XXX__ 0x1c +#define ___XXX_X 0x1d +#define ___XXXX_ 0x1e +#define ___XXXXX 0x1f +#define __X_____ 0x20 +#define __X____X 0x21 +#define __X___X_ 0x22 +#define __X___XX 0x23 +#define __X__X__ 0x24 +#define __X__X_X 0x25 +#define __X__XX_ 0x26 +#define __X__XXX 0x27 +#define __X_X___ 0x28 +#define __X_X__X 0x29 +#define __X_X_X_ 0x2a +#define __X_X_XX 0x2b +#define __X_XX__ 0x2c +#define __X_XX_X 0x2d +#define __X_XXX_ 0x2e +#define __X_XXXX 0x2f +#define __XX____ 0x30 +#define __XX___X 0x31 +#define __XX__X_ 0x32 +#define __XX__XX 0x33 +#define __XX_X__ 0x34 +#define __XX_X_X 0x35 +#define __XX_XX_ 0x36 +#define __XX_XXX 0x37 +#define __XXX___ 0x38 +#define __XXX__X 0x39 +#define __XXX_X_ 0x3a +#define __XXX_XX 0x3b +#define __XXXX__ 0x3c +#define __XXXX_X 0x3d +#define __XXXXX_ 0x3e +#define __XXXXXX 0x3f +#define _X______ 0x40 +#define _X_____X 0x41 +#define _X____X_ 0x42 +#define _X____XX 0x43 +#define _X___X__ 0x44 +#define _X___X_X 0x45 +#define _X___XX_ 0x46 +#define _X___XXX 0x47 +#define _X__X___ 0x48 +#define _X__X__X 0x49 +#define _X__X_X_ 0x4a +#define _X__X_XX 0x4b +#define _X__XX__ 0x4c +#define _X__XX_X 0x4d +#define _X__XXX_ 0x4e +#define _X__XXXX 0x4f +#define _X_X____ 0x50 +#define _X_X___X 0x51 +#define _X_X__X_ 0x52 +#define _X_X__XX 0x53 +#define _X_X_X__ 0x54 +#define _X_X_X_X 0x55 +#define _X_X_XX_ 0x56 +#define _X_X_XXX 0x57 +#define _X_XX___ 0x58 +#define _X_XX__X 0x59 +#define _X_XX_X_ 0x5a +#define _X_XX_XX 0x5b +#define _X_XXX__ 0x5c +#define _X_XXX_X 0x5d +#define _X_XXXX_ 0x5e +#define _X_XXXXX 0x5f +#define _XX_____ 0x60 +#define _XX____X 0x61 +#define _XX___X_ 0x62 +#define _XX___XX 0x63 +#define _XX__X__ 0x64 +#define _XX__X_X 0x65 +#define _XX__XX_ 0x66 +#define _XX__XXX 0x67 +#define _XX_X___ 0x68 +#define _XX_X__X 0x69 +#define _XX_X_X_ 0x6a +#define _XX_X_XX 0x6b +#define _XX_XX__ 0x6c +#define _XX_XX_X 0x6d +#define _XX_XXX_ 0x6e +#define _XX_XXXX 0x6f +#define _XXX____ 0x70 +#define _XXX___X 0x71 +#define _XXX__X_ 0x72 +#define _XXX__XX 0x73 +#define _XXX_X__ 0x74 +#define _XXX_X_X 0x75 +#define _XXX_XX_ 0x76 +#define _XXX_XXX 0x77 +#define _XXXX___ 0x78 +#define _XXXX__X 0x79 +#define _XXXX_X_ 0x7a +#define _XXXX_XX 0x7b +#define _XXXXX__ 0x7c +#define _XXXXX_X 0x7d +#define _XXXXXX_ 0x7e +#define _XXXXXXX 0x7f +#define X_______ 0x80 +#define X______X 0x81 +#define X_____X_ 0x82 +#define X_____XX 0x83 +#define X____X__ 0x84 +#define X____X_X 0x85 +#define X____XX_ 0x86 +#define X____XXX 0x87 +#define X___X___ 0x88 +#define X___X__X 0x89 +#define X___X_X_ 0x8a +#define X___X_XX 0x8b +#define X___XX__ 0x8c +#define X___XX_X 0x8d +#define X___XXX_ 0x8e +#define X___XXXX 0x8f +#define X__X____ 0x90 +#define X__X___X 0x91 +#define X__X__X_ 0x92 +#define X__X__XX 0x93 +#define X__X_X__ 0x94 +#define X__X_X_X 0x95 +#define X__X_XX_ 0x96 +#define X__X_XXX 0x97 +#define X__XX___ 0x98 +#define X__XX__X 0x99 +#define X__XX_X_ 0x9a +#define X__XX_XX 0x9b +#define X__XXX__ 0x9c +#define X__XXX_X 0x9d +#define X__XXXX_ 0x9e +#define X__XXXXX 0x9f +#define X_X_____ 0xa0 +#define X_X____X 0xa1 +#define X_X___X_ 0xa2 +#define X_X___XX 0xa3 +#define X_X__X__ 0xa4 +#define X_X__X_X 0xa5 +#define X_X__XX_ 0xa6 +#define X_X__XXX 0xa7 +#define X_X_X___ 0xa8 +#define X_X_X__X 0xa9 +#define X_X_X_X_ 0xaa +#define X_X_X_XX 0xab +#define X_X_XX__ 0xac +#define X_X_XX_X 0xad +#define X_X_XXX_ 0xae +#define X_X_XXXX 0xaf +#define X_XX____ 0xb0 +#define X_XX___X 0xb1 +#define X_XX__X_ 0xb2 +#define X_XX__XX 0xb3 +#define X_XX_X__ 0xb4 +#define X_XX_X_X 0xb5 +#define X_XX_XX_ 0xb6 +#define X_XX_XXX 0xb7 +#define X_XXX___ 0xb8 +#define X_XXX__X 0xb9 +#define X_XXX_X_ 0xba +#define X_XXX_XX 0xbb +#define X_XXXX__ 0xbc +#define X_XXXX_X 0xbd +#define X_XXXXX_ 0xbe +#define X_XXXXXX 0xbf +#define XX______ 0xc0 +#define XX_____X 0xc1 +#define XX____X_ 0xc2 +#define XX____XX 0xc3 +#define XX___X__ 0xc4 +#define XX___X_X 0xc5 +#define XX___XX_ 0xc6 +#define XX___XXX 0xc7 +#define XX__X___ 0xc8 +#define XX__X__X 0xc9 +#define XX__X_X_ 0xca +#define XX__X_XX 0xcb +#define XX__XX__ 0xcc +#define XX__XX_X 0xcd +#define XX__XXX_ 0xce +#define XX__XXXX 0xcf +#define XX_X____ 0xd0 +#define XX_X___X 0xd1 +#define XX_X__X_ 0xd2 +#define XX_X__XX 0xd3 +#define XX_X_X__ 0xd4 +#define XX_X_X_X 0xd5 +#define XX_X_XX_ 0xd6 +#define XX_X_XXX 0xd7 +#define XX_XX___ 0xd8 +#define XX_XX__X 0xd9 +#define XX_XX_X_ 0xda +#define XX_XX_XX 0xdb +#define XX_XXX__ 0xdc +#define XX_XXX_X 0xdd +#define XX_XXXX_ 0xde +#define XX_XXXXX 0xdf +#define XXX_____ 0xe0 +#define XXX____X 0xe1 +#define XXX___X_ 0xe2 +#define XXX___XX 0xe3 +#define XXX__X__ 0xe4 +#define XXX__X_X 0xe5 +#define XXX__XX_ 0xe6 +#define XXX__XXX 0xe7 +#define XXX_X___ 0xe8 +#define XXX_X__X 0xe9 +#define XXX_X_X_ 0xea +#define XXX_X_XX 0xeb +#define XXX_XX__ 0xec +#define XXX_XX_X 0xed +#define XXX_XXX_ 0xee +#define XXX_XXXX 0xef +#define XXXX____ 0xf0 +#define XXXX___X 0xf1 +#define XXXX__X_ 0xf2 +#define XXXX__XX 0xf3 +#define XXXX_X__ 0xf4 +#define XXXX_X_X 0xf5 +#define XXXX_XX_ 0xf6 +#define XXXX_XXX 0xf7 +#define XXXXX___ 0xf8 +#define XXXXX__X 0xf9 +#define XXXXX_X_ 0xfa +#define XXXXX_XX 0xfb +#define XXXXXX__ 0xfc +#define XXXXXX_X 0xfd +#define XXXXXXX_ 0xfe +#define XXXXXXXX 0xff + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_other.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_other.c new file mode 100644 index 0000000..51a2d6b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/gui/gui_font_other.c @@ -0,0 +1,138 @@ +/** + ***************************************************************************************** + * + * @file gui_font_other.c + * + * @brief Function of show other modulus font + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "gui_font_other.h" + +#if FONT_OTHER_EN==1 + +#include "gui_color.h" +#include "gui_basic.h" + + +/* + * GLOBAL FUNCTION DEFINITIONS + ******************************************************************************* + */ +uint8_t gui_put_char16_32(uint16_t x, uint16_t y, const uint8_t(*code16_32)[16], uint16_t index) +{ + uint8_t i,j; + + if( x>(GUI_DISPLAY_X_MAX-16) ) return(0); + if( y>(GUI_DISPLAY_Y_MAX-32) ) return(0); + for(i=0; i<16; i++) + { + for(j=0; j<2; j++) + { + gui_point_color(x+j*8, y+i, code16_32[(index*4)+(j*2)][i], 8); + gui_point_color(x+j*8, y+16+i, code16_32[(index*4)+(j*2+1)][i], 8); + } + } + return (1); +} + +void gui_put_string16_32(uint16_t x, uint16_t y, const uint8_t(*code16_32)[16], uint16_t num) +{ + uint16_t i; + + for(i=0; i(GUI_DISPLAY_X_MAX-32) ) return(0); + if( y>(GUI_DISPLAY_Y_MAX-64) ) return(0); + for(i=0; i<16; i++) + { + for(j=0; j<4; j++) + { + gui_point_color(x+j*8, y+i, code32_64[(index*16)+(j*4)][i], 8); + gui_point_color(x+j*8, y+16+i, code32_64[(index*16)+(j*4+1)][i], 8); + gui_point_color(x+j*8, y+32+i, code32_64[(index*16)+(j*4+2)][i], 8); + gui_point_color(x+j*8, y+48+i, code32_64[(index*16)+(j*4+3)][i], 8); + } + } + return (1); +} + +void gui_put_string32_64(uint16_t x, uint16_t y, const uint8_t(*code32_64)[16], uint16_t num) +{ + uint16_t i; + + for(i=0; ip_xqspi, &command, &tmp, 1000); + *p_status_register |= tmp; + + command.inst = 0x35; + tmp = 0; + hal_xqspi_command_receive(p_exflash->p_xqspi, &command, &tmp, 1000); + *p_status_register |= (tmp << 8); + + return status; +} + +SECTION_RAM_CODE static hal_status_t exflash_write_status_register(exflash_handle_t *p_exflash, uint16_t data) +{ + hal_status_t status = HAL_OK; + + uint8_t w_sr_cmd[3]; + w_sr_cmd[0] = 0x01; //Write Status Register + w_sr_cmd[1] = data & 0xFF; + w_sr_cmd[2] = (data >> 8) & 0xFF; + + do { + status = exflash_enable_write(p_exflash); + if (HAL_OK != status) + break; + + status = hal_xqspi_transmit(p_exflash->p_xqspi, w_sr_cmd, sizeof(w_sr_cmd), 1000); + if (HAL_OK != status) + break; + + status = exflash_wait_busy(p_exflash, HAL_EXFLASH_RETRY_DEFAULT_VALUE); + } while(0); + + return status; +} + +SECTION_RAM_CODE hal_status_t enable_quad(exflash_handle_t *p_exflash) +{ + hal_status_t status = HAL_OK; + uint16_t status_reg_value = 0; + + do { + exflash_read_status_register(p_exflash, &status_reg_value); + if (((status_reg_value & (1<> FLASH_QE_BIT_POS) == ENABLE) + break; + + status_reg_value |= (uint16_t)(1<< FLASH_QE_BIT_POS); + + status = exflash_write_status_register(p_exflash, status_reg_value); + if (HAL_OK != status) + break; + + status_reg_value = 0; + exflash_read_status_register(p_exflash, &status_reg_value); + if (((status_reg_value & (1<> FLASH_QE_BIT_POS) == ENABLE) + break; + } while(1); + return status; +} + +SECTION_RAM_CODE hal_status_t platform_exflash_enable_quad(exflash_handle_t *p_exflash) +{ + hal_status_t status = HAL_OK; + + if (ll_xqspi_get_xip_flag(p_exflash->p_xqspi->p_instance)) + { + /* Disable global interrupt, aviod call function in flash */ + GLOBAL_EXCEPTION_DISABLE(); + + /* Configure XQSPI initial paraments */ + p_exflash->p_xqspi->init.work_mode = XQSPI_WORK_MODE_QSPI; + hal_xqspi_init_ext(p_exflash->p_xqspi); + /* Update EXFALSH state */ + p_exflash->state = HAL_EXFLASH_STATE_BUSY; + GLOBAL_EXCEPTION_ENABLE(); + } + else + { + /* EXFLASH in QSPI mode */ + exflash_wakeup(p_exflash); + status = (hal_status_t)exflash_check_id(p_exflash); + if (HAL_OK != status) + { + p_exflash->error_code = HAL_EXFLASH_ERROR_ID; + } else { + /* Update EXFALSH state */ + p_exflash->state = HAL_EXFLASH_STATE_BUSY; + } + } + status = enable_quad(p_exflash); + if (XQSPI_WORK_MODE_XIP == p_exflash->fw_mode) + { + /* Disable global interrupt, aviod call function in flash */ + GLOBAL_EXCEPTION_DISABLE(); + p_exflash->p_xqspi->init.work_mode = XQSPI_WORK_MODE_XIP; + hal_xqspi_init_ext(p_exflash->p_xqspi); + p_exflash->state = HAL_EXFLASH_STATE_READY; + GLOBAL_EXCEPTION_ENABLE(); + } + else + { + exflash_deepsleep(p_exflash); + p_exflash->state = HAL_EXFLASH_STATE_READY; + } + + return status; +} +#endif /* ENABLE_USER_QUAD_FUNC */ + +/* NOTE : Here is a function demo if user want to realize XIP Flash operations + Please refer hal_flash_read_identification_id() + */ static uint32_t s_identification_id; static SECTION_RAM_CODE hal_status_t exflash_read_identification_id(exflash_handle_t *p_exflash) { @@ -23,14 +162,18 @@ static SECTION_RAM_CODE hal_status_t exflash_read_identification_id(exflash_hand command.length = 3; status = hal_xqspi_command_receive_patch(p_exflash->p_xqspi, &command, id, 1000); - if (HAL_OK != status) { + if (HAL_OK != status) + { return status; } - if ((FLASH_MANU_ID_INVALID0 != id[0]) && (FLASH_MANU_ID_INVALID1 != id[0])) { + if ((FLASH_MANU_ID_INVALID0 != id[0]) && (FLASH_MANU_ID_INVALID1 != id[0])) + { s_identification_id = id[2] + (id[1] << 8) + (id[0] << 16); return HAL_OK; - } else { + } + else + { return HAL_ERROR; } } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.h old mode 100755 new mode 100644 index 5e6bb10..37222b9 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_exflash_user_operation.h @@ -34,10 +34,7 @@ #define SPI_FLASH_CMD_DP 0xB9 #define SPI_FLASH_CMD_RDP 0xAB -extern exflash_handle_t g_exflash_handle; -extern hal_status_t hal_xqspi_command_receive_patch(xqspi_handle_t *p_xqspi, xqspi_command_t *p_cmd, \ - uint8_t *p_data, uint32_t retry); - uint32_t hal_flash_read_identification_id(void); +hal_status_t platform_exflash_enable_quad(exflash_handle_t *p_exflash); #endif /* __HAL_EXFLASH_USER_OPERATION_H_ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.c old mode 100755 new mode 100644 index c56194a..c92d909 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.c @@ -49,46 +49,28 @@ * with the macro *FLASH_ENABLE. ******************************************************************************/ +#include "gr55xx_hal.h" +#include "hal_flash.h" #include #include #include -#include "gr55xx_hal.h" -#include "hal_flash.h" #ifndef EXFLASH_ENABLE #define EXFLASH_ENABLE /** EXFLASH_SIZE_PAGE_BYTES ? - EXFLASH_SIZE_PAGE_BYTES : size; + if (HAL_OK == status) + { + /* It's possible that the data is not written to flash memory. + * So we must read the data from flash memory, and check it. */ + uint8_t rd_buf[EXFLASH_SIZE_PAGE_BYTES]; + uint32_t offset = 0; + uint32_t unrd_bytes = size; + uint32_t rd_bytes = size > EXFLASH_SIZE_PAGE_BYTES ? + EXFLASH_SIZE_PAGE_BYTES : size; - do { - status = hal_exflash_read(&g_exflash_handle, addr + offset, - rd_buf, rd_bytes); - if ((HAL_OK == status) && (memcmp(buf + offset, rd_buf, rd_bytes) == 0)) { - unrd_bytes -= rd_bytes; - if (unrd_bytes == 0) { - return size; + do + { + status = hal_exflash_read(&g_exflash_handle, addr + offset, + rd_buf, rd_bytes); + if ((HAL_OK == status) && (memcmp(buf + offset, rd_buf, rd_bytes) == 0)) + { + unrd_bytes -= rd_bytes; + if (0 == unrd_bytes) + { + return size; + } + else + { + offset += rd_bytes; + rd_bytes = unrd_bytes > EXFLASH_SIZE_PAGE_BYTES ? + EXFLASH_SIZE_PAGE_BYTES : unrd_bytes; + if ((offset >= size) || ((offset + rd_bytes) > size)) + { + break; + } + } } - offset += rd_bytes; - rd_bytes = unrd_bytes > EXFLASH_SIZE_PAGE_BYTES ? - EXFLASH_SIZE_PAGE_BYTES : unrd_bytes; - if ((offset >= size) || ((offset + rd_bytes) > size)) { + else + { break; } - } else { - break; - } - } while (1); + } while(1); + } return 0; } @@ -154,17 +145,18 @@ bool hal_flash_get_security(void) bool hal_flash_erase(const uint32_t addr, const uint32_t size) { - return (HAL_OK == hal_exflash_erase(&g_exflash_handle, 0, addr, size)) ? true : false; + return (HAL_OK == hal_exflash_erase(&g_exflash_handle, 0, addr, size)) ? true : false; } bool hal_flash_erase_chip(void) { - return (HAL_OK == hal_exflash_erase(&g_exflash_handle, 1, 0, 0)) ? true : false; + return (HAL_OK == hal_exflash_erase(&g_exflash_handle, 1, 0, 0)) ? true : false; } void hal_flash_get_info(uint32_t *id, uint32_t *size) { - if (id == NULL || size == NULL) { + if (NULL == id || NULL == size) + { return; } @@ -204,17 +196,18 @@ uint32_t hal_flash_write(const uint32_t addr, const uint8_t *buf, bool hal_flash_erase(const uint32_t addr, const uint32_t size) { - return vflash_erase(addr, size); + return vflash_erase(addr, size); } bool hal_flash_erase_chip(void) { - return false; + return false; } void hal_flash_get_info(uint32_t *id, uint32_t *size) { - if (id == NULL || size == NULL) { + if (NULL == id || NULL == size) + { return; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.h old mode 100755 new mode 100644 index 39a95f9..cfb9bff --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/hal_flash.h @@ -59,15 +59,6 @@ #include #include -#include "gr55xx_hal.h" - -#if defined(GR5515_C) -exflash_handle_t g_exflash_handle; -#else -extern exflash_handle_t g_exflash_handle; -#endif - -extern uint32_t sys_security_enable_status_check(void); /** @addtogroup HAL_FLASH_DRIVER_FUNCTIONS Functions * @{ */ @@ -80,7 +71,7 @@ extern uint32_t sys_security_enable_status_check(void); * @retval false If failure. ******************************************************************************* */ -bool hal_flash_init(void); +bool hal_flash_init( void ); /** ******************************************************************************* @@ -95,9 +86,6 @@ bool hal_flash_init(void); */ uint32_t hal_flash_read(const uint32_t addr, uint8_t *buf, const uint32_t size); - -#if defined(GR5515_D) - /** ******************************************************************************* * @brief [High speed]Read flash Memory. @@ -114,8 +102,6 @@ uint32_t hal_flash_read(const uint32_t addr, uint8_t *buf, const uint32_t size); */ uint32_t hal_flash_read_align_word(const uint32_t addr, uint8_t *buf, const uint32_t size); -#endif - /** ******************************************************************************* * @brief Write flash Memory. @@ -131,7 +117,7 @@ uint32_t hal_flash_write(const uint32_t addr, const uint8_t *buf, const uint32_t /** ******************************************************************************* - * @brief Write flash Memory reliably. + * @brief Write flash Memory reliably. * * @note It's possible that the data was not written into Flash Memory * successfully. This function reads the data from Flash Memory to check @@ -220,7 +206,7 @@ bool hal_flash_erase_chip(void); */ uint32_t hal_flash_sector_size(void); -#if defined(GR5515_D) && defined(ENCRYPT_ENABLE) +#if defined(ENCRYPT_ENABLE) /** **************************************************************************************** diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.c new file mode 100644 index 0000000..e768680 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.c @@ -0,0 +1,67 @@ +#include "custom_config.h" +#include +#include +#include + +#define VFLASH_SECTOR_SIZE 0x1000 +#define VFLASH_SIZE (VFLASH_SECTOR_SIZE * NVDS_NUM_SECTOR) + +extern uint32_t nvds_get_start_addr(void); + +/* ***************************************************************************** + * Local variables + */ +static uint8_t vflash_ram[VFLASH_SIZE]; + +/* ***************************************************************************** + * Local functions + */ +static uint32_t addr_translate(uint32_t addr); + +/* ***************************************************************************** + * Function definitions + */ +bool vflash_init(void) +{ + memset(vflash_ram, 0xFF, VFLASH_SIZE); + + return true; +} + +uint32_t vflash_sector_size(void) +{ + return VFLASH_SECTOR_SIZE; +} + +uint32_t vflash_read(uint32_t addr, uint8_t *buf, uint32_t size) +{ + uint32_t v_addr = addr_translate(addr); + + memcpy(buf, (uint8_t *)v_addr, size); + + return size; +} + +uint32_t vflash_write(uint32_t addr, const uint8_t *buf, uint32_t size) +{ + uint32_t v_addr = addr_translate(addr); + + memcpy((uint8_t *)v_addr, buf, size); + + return size; +} + +bool vflash_erase(uint32_t addr, uint32_t size) +{ + uint32_t v_addr = addr_translate(addr); + + memset((uint8_t *)v_addr, 0xFF, size); + + return true; +} + +uint32_t addr_translate(uint32_t addr) +{ + return ((uint32_t)(addr - nvds_get_start_addr() + vflash_ram)); +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.h new file mode 100644 index 0000000..641e12a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hal_flash/vflash/vflash.h @@ -0,0 +1,18 @@ +#ifndef __VFLASH_H__ +#define __VFLASH_H__ + +#include +#include + +bool vflash_init(void); + +uint32_t vflash_read(uint32_t addr, uint8_t *buf, uint32_t size); + +uint32_t vflash_write(uint32_t addr, const uint8_t *buf, uint32_t size); + +bool vflash_erase(uint32_t addr, uint32_t size); + +uint32_t vflash_sector_size(void); + +#endif // __VFLASH_H__ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/BUILD.gn new file mode 100644 index 0000000..906e48b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hci_uart") { + sources = [ "hci_uart.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.c new file mode 100644 index 0000000..1bb4ab8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.c @@ -0,0 +1,354 @@ +/** + **************************************************************************************** + * @file hci_uart.c + * @author BLE SDK Team + * @brief H4TL UART driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard definition +#include "board_SK.h" +#include "custom_config.h" +#include "gr55xx_hal.h" +#include "gr55xx_sys.h" +#include "app_uart.h" +#include "hci_uart.h" // uart definition +/* + * STRUCT DEFINITIONS + ***************************************************************************************** + */ + +static hci_uart_call_t hci_uart_api = +{ +#if (HCI_UART_GRP_ID == 0) + hci_uart0_init, + hci_uart0_flow_on, + hci_uart0_flow_off, + hci_uart0_finish_transfers, + hci_uart0_read, + hci_uart0_write, +#elif (HCI_UART_GRP_ID == 1) + hci_uart1_init, + hci_uart1_flow_on, + hci_uart1_flow_off, + hci_uart1_finish_transfers, + hci_uart1_read, + hci_uart1_write, +#endif +}; + + /* TX and RX channel class holding data used for asynchronous read and write data + * transactions + */ +/// UART TX RX Channel +typedef struct +{ + /// call back function pointer + void (*callback) (void*, uint8_t); + /// dummy data pointer returned to callback when operation is over. + void *p_dummy; +} uart_txrxchannel_t; + +/// UART environment structure +typedef struct +{ + /// tx channel + uart_txrxchannel_t tx; + /// rx channel + uart_txrxchannel_t rx; + /// error detect + uint8_t errordetect; + /// external wakeup + bool ext_wakeup; +} uart_env_tag_t; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +/// uart environment structure +static uart_env_tag_t uart_env; +static app_uart_params_t s_params; +static app_uart_tx_buf_t s_hci_uart_buffer; +static uint8_t s_hci_buffer[256] = {0}; +/* + * PRIVATED FUNCTION DEFINITIONS + **************************************************************************************** + */ +static void hci_uart_callback(app_uart_id_t id, app_uart_evt_t *p_evt) +{ + void *data = NULL; + void (*callback) (void*, uint8_t) = NULL; + + if (APP_UART_EVT_TX_CPLT == p_evt->type) + { + // Retrieve callback pointer + callback = uart_env.tx.callback; + data = uart_env.tx.p_dummy; + + if(callback != NULL) + { + // Clear callback pointer + uart_env.tx.callback = NULL; + uart_env.tx.p_dummy = NULL; + + // Call handler + callback(data, 0); + } + } + else if (APP_UART_EVT_RX_DATA == p_evt->type) + { + // Retrieve callback pointer + callback = uart_env.rx.callback; + data = uart_env.rx.p_dummy; + + if(callback != NULL) + { + // Clear callback pointer + uart_env.rx.callback = NULL; + uart_env.rx.p_dummy = NULL; + + // Call handler + callback(data, 0); + } + } + else if (APP_UART_EVT_ERROR == p_evt->type) + { + uint8_t tmp; + uart_handle_t *p_uart = app_uart_get_handle(id); + + /* dummy read to clear RLS interrupt */ + tmp = ll_uart_receive_data8(p_uart->p_instance); + (void) tmp; + + /* Flush RX_FIFO */ + ll_uart_flush_rx_fifo(p_uart->p_instance); + + /* If Overrun error occurs. */ + if(p_evt->data.error_code & HAL_UART_ERROR_OE) + { + p_evt->type = APP_UART_EVT_RX_DATA; + hci_uart_callback(id, p_evt); + } + } +} + +static void hci_uart0_callback(app_uart_evt_t *p_evt) +{ + hci_uart_callback(APP_UART_ID_0, p_evt); +} + +static void hci_uart1_callback(app_uart_evt_t *p_evt) +{ + hci_uart_callback(APP_UART_ID_1, p_evt); +} + +static void hci_uart_init(app_uart_id_t id, void (*callback)(app_uart_evt_t*)) +{ + s_params.id = id; + + s_params.pin_cfg.tx.type = APP_HCI_UART_TRN_PORT; + s_params.pin_cfg.tx.mux = APP_HCI_UART_TX_PINMUX; + s_params.pin_cfg.tx.pin = APP_HCI_UART_TX_PIN; + s_params.pin_cfg.rx.type = APP_HCI_UART_TRN_PORT; + s_params.pin_cfg.rx.mux = APP_HCI_UART_RX_PINMUX; + s_params.pin_cfg.rx.pin = APP_HCI_UART_RX_PIN; + #if HCI_UART_FLOW_ON == 1 + params.pin_cfg.cts.type = APP_HCI_UART_FLOW_PORT; + params.pin_cfg.cts.mux = APP_HCI_UART_CTS_PINMUX; + params.pin_cfg.cts.pin = APP_HCI_UART_CTS_PIN; + params.pin_cfg.rts.type = APP_HCI_UART_FLOW_PORT; + params.pin_cfg.rts.mux = APP_HCI_UART_RTS_PINMUX; + params.pin_cfg.rts.pin = APP_HCI_UART_RTS_PIN; + #endif //HCI_UART_FLOW_ON + + s_params.init.baud_rate = APP_HCI_UART_BAUDRATE; + s_params.init.data_bits = UART_DATABITS_8; + s_params.init.stop_bits = UART_STOPBITS_1; + s_params.init.parity = UART_PARITY_NONE; + #if HCI_UART_FLOW_ON == 1 + params.init.hw_flow_ctrl = UART_HWCONTROL_RTS_CTS; + #else + s_params.init.hw_flow_ctrl = UART_HWCONTROL_NONE; + #endif //HCI_UART_FLOW_ON + s_params.init.rx_timeout_mode = UART_RECEIVER_TIMEOUT_DISABLE; + app_uart_init(&s_params, callback, &s_hci_uart_buffer); + return; +} + +static void hci_uart_write(app_uart_id_t id, uint8_t *p_buffer, uint32_t size, void (*callback) (void*, uint8_t), void* p_dummy) +{ + if(NULL == uart_env.tx.callback) + { + uart_env.tx.callback = callback; + uart_env.tx.p_dummy = p_dummy; + } + app_uart_transmit_async(id, p_buffer, (uint16_t)size); + return; +} + +static void hci_uart_read(app_uart_id_t id, uint8_t *p_buffer, uint32_t size, void (*callback) (void*, uint8_t), void* p_dummy) +{ + if(NULL == uart_env.rx.callback) + { + uart_env.rx.callback = callback; + uart_env.rx.p_dummy = p_dummy; + } + + app_uart_receive_async(id, p_buffer, (uint16_t)size); + return; +} + +static void hci_uart_flow_on(app_uart_id_t id) +{ + //Define HCI_UART_FLOW_ON to Open UART Flow Control + #if HCI_UART_FLOW_ON == 1 //To define macro this way for auto test script to locate and modify, don't change this line + uart_handle_t *p_uart = app_uart_get_handle(id); + /* Disable flow control default for .bit version < R02_27a_B0228a_k7 because CTS issue */ + ll_uart_set_hw_flow_ctrl(p_uart->p_instance, LL_UART_HWCONTROL_RTS_CTS); + #endif //HCI_UART_FLOW_ON + return; +} + +static bool hci_uart_flow_off(app_uart_id_t id) +{ + bool flow_off = true; + uart_handle_t *p_uart = app_uart_get_handle(id); + hal_uart_state_t state = hal_uart_get_state(p_uart); + + do { + /* Check if sleep is allowed by Host and if no transmission is ongoing */ + if ((state == HAL_UART_STATE_BUSY_TX) || (state == HAL_UART_STATE_BUSY_RX)) + { + flow_off = false; + break; + } + + /* Force RTS to 'flow off' */ + ll_uart_set_hw_flow_ctrl(p_uart->p_instance, LL_UART_HWCONTROL_NONE); + + state = hal_uart_get_state(p_uart); + /* Check if data has been received during wait time */ + if (state == HAL_UART_STATE_BUSY_RX) + { + /* Re-enable UART flow */ + hci_uart_flow_on(id); + + flow_off = false; + } + } while(0); + return flow_off; +} + +static void hci_uart_finish_transfers(app_uart_id_t id) +{ + return; +} + +/* + * EXPORTED FUNCTION DEFINITIONS + **************************************************************************************** + */ +void hci_uart0_init(void) +{ + hci_uart_init(APP_UART_ID_0, hci_uart0_callback); +} + +void hci_uart1_init(void) +{ + hci_uart_init(APP_UART_ID_1, hci_uart1_callback); +} + +void hci_uart0_flow_on(void) +{ + hci_uart_flow_on(APP_UART_ID_0); +} + +void hci_uart1_flow_on(void) +{ + hci_uart_flow_on(APP_UART_ID_1); +} + +bool hci_uart0_flow_off(void) +{ + return hci_uart_flow_off(APP_UART_ID_0); +} + +bool hci_uart1_flow_off(void) +{ + return hci_uart_flow_off(APP_UART_ID_1); +} + +void hci_uart0_finish_transfers(void) +{ + hci_uart_finish_transfers(APP_UART_ID_0); +} + +void hci_uart1_finish_transfers(void) +{ + hci_uart_finish_transfers(APP_UART_ID_1); +} + +void hci_uart0_read(uint8_t *p_buffer, uint32_t size, void (*callback)(void*, uint8_t), void *p_dummy) +{ + hci_uart_read(APP_UART_ID_0, p_buffer, size, callback, p_dummy); +} + +void hci_uart1_read(uint8_t *p_buffer, uint32_t size, void (*callback)(void*, uint8_t), void *p_dummy) +{ + hci_uart_read(APP_UART_ID_1, p_buffer, size, callback, p_dummy); +} + +void hci_uart0_write(uint8_t *p_buffer, uint32_t size, void (*callback)(void*, uint8_t), void *p_dummy) +{ + hci_uart_write(APP_UART_ID_0, p_buffer, size, callback, p_dummy); +} + +void hci_uart1_write(uint8_t *p_buffer, uint32_t size, void (*callback)(void*, uint8_t), void *p_dummy) +{ + hci_uart_write(APP_UART_ID_1, p_buffer, size, callback, p_dummy); +} + +void ble_hci_uart_init(void) +{ + s_hci_uart_buffer.tx_buf = s_hci_buffer; + s_hci_uart_buffer.tx_buf_size = sizeof(s_hci_buffer); + ble_hci_uart_register(0, &hci_uart_api); +} + +void ble_hci_stack_init_handle(void) +{ + +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.h new file mode 100644 index 0000000..f52c07a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/hci_uart/hci_uart.h @@ -0,0 +1,261 @@ +/** + **************************************************************************************** + * @file hci_uart.h + * @author BLE SDK Team + * @brief UART Driver for HCI over UART operation. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup LIBRARIES Libraries + * @{ + */ + +/** + @addtogroup LIBRARIES_HCI_UART HCI HCI UART Driver. + @{ + @brief Definitions and prototypes for HCI UART Driver. + */ + +#ifndef HCI_UART_H_ +#define HCI_UART_H_ + +#include +#include + +#include "gr55xx_hal.h" + +/** @addtogroup HCI_UART_DRIVER_FUNCTIONS Functions + * @{ */ + +/** + **************************************************************************************** + * @brief Initializes the UART0 to default values. + **************************************************************************************** + */ +void hci_uart0_init(void); + +/** + **************************************************************************************** + * @brief Initializes the UART1 to default values. + **************************************************************************************** + */ +void hci_uart1_init(void); + +#ifndef CFG_ROM +/** + **************************************************************************************** + * @brief Enable UART0 flow. + ***************************************************************************************** + */ +void hci_uart0_flow_on(void); + +/** + **************************************************************************************** + * @brief Enable UART1 flow. + ***************************************************************************************** + */ +void hci_uart1_flow_on(void); + +/** + **************************************************************************************** + * @brief Disable UART0 flow. + * + * @retval true if successful. + * @retval false if failure. + ***************************************************************************************** + */ +bool hci_uart0_flow_off(void); + +/** + **************************************************************************************** + * @brief Disable UART1 flow. + * + * @retval true if successful. + * @retval false if failure. + ***************************************************************************************** + */ +bool hci_uart1_flow_off(void); +#endif //CFG_ROM + +/** + **************************************************************************************** + * @brief Finish current UART0 transfers + ***************************************************************************************** + */ +void hci_uart0_finish_transfers(void); + +/** + **************************************************************************************** + * @brief Finish current UART1 transfers + ***************************************************************************************** + */ +void hci_uart1_finish_transfers(void); + +/** + **************************************************************************************** + * @brief Starts a data reception of UART0. + * + * @param[out] bufptr Pointer to the RX buffer + * @param[in] size Size of the expected reception + * @param[in] callback Pointer to the function called back when transfer finished + * @param[in] dummy Dummy data pointer returned to callback when reception is finished + ***************************************************************************************** + */ +void hci_uart0_read(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); + +/** + **************************************************************************************** + * @brief Starts a data reception of UART1. + * + * @param[out] bufptr Pointer to the RX buffer + * @param[in] size Size of the expected reception + * @param[in] callback Pointer to the function called back when transfer finished + * @param[in] dummy Dummy data pointer returned to callback when reception is finished + ***************************************************************************************** + */ +void hci_uart1_read(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); + +/** + **************************************************************************************** + * @brief Starts a data transmission of UART0. + * + * @param[in] bufptr Pointer to the TX buffer + * @param[in] size Size of the transmission + * @param[in] callback Pointer to the function called back when transfer finished + * @param[in] dummy Dummy data pointer returned to callback when transmission is finished + ***************************************************************************************** + */ +void hci_uart0_write(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); + +/** + **************************************************************************************** + * @brief Starts a data transmission of UART1. + * + * @param[in] bufptr Pointer to the TX buffer + * @param[in] size Size of the transmission + * @param[in] callback Pointer to the function called back when transfer finished + * @param[in] dummy Dummy data pointer returned to callback when transmission is finished + ***************************************************************************************** + */ +void hci_uart1_write(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); + +#if defined(CFG_ROM) +/** + **************************************************************************************** + * @brief Poll UART0 on reception and transmission. + * + * This function is used to poll UART0 for reception and transmission. + * It is used when IRQ are not used to detect incoming bytes. + ***************************************************************************************** + */ +void hci_uart0_poll(void); + +/** + **************************************************************************************** + * @brief Poll UART1 on reception and transmission. + * + * This function is used to poll UART1 for reception and transmission. + * It is used when IRQ are not used to detect incoming bytes. + ***************************************************************************************** + */ +void hci_uart1_poll(void); +#endif //CFG_ROM + +/** + **************************************************************************************** + * @brief Handle UART0 interrupt request. + * + * This function is used to handle UART0 interrupt request. + * It must to be called in UART0_IRQHandler(). + ***************************************************************************************** + */ +void hci_uart0_irq_handler(void); + +/** + **************************************************************************************** + * @brief Handle UART1 interrupt request. + * + * This function is used to handle UART1 interrupt request. + * It must to be called in UART1_IRQHandler(). + ***************************************************************************************** + */ +void hci_uart1_irq_handler(void); + +/** + **************************************************************************************** + * @brief HCI UART Tx Transfer completed callback. + * + * It must to be called in hal_uart_tx_cplt_callback(). + ***************************************************************************************** + */ +void hci_uart_tx_cplt_callback(uart_handle_t *huart); + +/** + **************************************************************************************** + * @brief HCI UART Rx Transfer completed callback. + * + * It must to be called in hal_uart_rx_cplt_callback(). + ***************************************************************************************** + */ +void hci_uart_rx_cplt_callback(uart_handle_t *huart); + +/** + **************************************************************************************** + * @brief HCI UART Error callback. + * + * It must to be called in hal_uart_error_callback(). + ***************************************************************************************** + */ +void hci_uart_error_callback(uart_handle_t *huart); + +/** + **************************************************************************************** + * @brief BLE HCI uart init. + * + * If users want to support dtm test, this function should be called. + ***************************************************************************************** + */ +void ble_hci_uart_init(void); + +/** + **************************************************************************************** + * @brief BLE stack init handler function. + * + * BLE Stack init complete, this function should be called. + ***************************************************************************************** + */ +void ble_hci_stack_init_handle(void); + +/** @} */ + +#endif /* HCI_UART_H_ */ + +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/BUILD.gn new file mode 100644 index 0000000..75662c3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("pmu_calibration") { + sources = [ "pmu_calibration.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.c old mode 100755 new mode 100644 index be5f2ad..0426ad9 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.c @@ -41,31 +41,187 @@ */ #include "pmu_calibration.h" #include "platform_sdk.h" +#include "gr55xx_sys.h" +#include "app_timer.h" -#define INTERVAL_MIN 2000 -#define STACKDEPTH 512 /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -#ifdef ENV_USE_FREERTOS -static TimerHandle_t timer_handle = NULL; -static void system_pmu_calibration_task(void *p_arg); -#else -static app_timer_id_t s_pmu_calibration_timer_id = 0; -#endif +static app_timer_id_t s_pmu_calibration_timer_id = {0}; + +extern uint32_t g_debug_temperature; +extern uint32_t g_debug_lpclk; +static uint32_t s_pre_temperature = 0; #if CFG_LPCLK_INTERNAL_EN -#error "INTERNAL LPCLK is not supported by OHOS" +#define LFRC32K_FAST_INTERVAL_ALLOW_PPM (100) +#define LFRC32K_MIDDLE_INTERVAL_ALLOW_PPM (300) +#define LFRC32K_SLOW_INTERVAL_ALLOW_PPM (300) +#define LFRC32K_CHECK_STATUS_CNT (3) +#define LFRC32K_ALLOW_PPM_WITHIN_THE_RANGE_CNT (20) +#define LFRC32K_ALLOW_PPM_WITHIN_MID_THE_RANGE_CNT (LFRC32K_ALLOW_PPM_WITHIN_THE_RANGE_CNT*100) +#define PMU_SMALL_INTERVAL_MS (10*1000) +static uint32_t pmu_interval_init = 30 * 1000; +static uint32_t pmu_interval_prev = 0; +uint32_t lfrc32k_fast_check_interval = 500; +uint32_t lfrc32k_middle_check_interval = 500*10; +const uint32_t lfrc32k_check_interval_table[LFRC32K_CHECK_STATUS_CNT]={500,500*10,30*1000}; //500ms, 5s, 30s +const uint32_t lfrc32k_check_cnt[LFRC32K_CHECK_STATUS_CNT]={20,20*100,0xFFFFFFFF}; //20 times, 2000 times, forever +const uint16_t lfrc32k_allow_ppm[LFRC32K_CHECK_STATUS_CNT]={100,300,300}; // 100ppm , 300ppm, , 300ppm + +uint32_t pmu_interval_get(uint32_t is_init) +{ + uint32_t interval = 0; + + if (g_debug_temperature > 44) + { + interval = PMU_SMALL_INTERVAL_MS; + } + else if (g_debug_temperature >= 40 && g_debug_temperature <= 44 && is_init) + { + interval = PMU_SMALL_INTERVAL_MS; + } + else if (g_debug_temperature < 40) + { + interval = pmu_interval_init; + } + + return interval; +} + + +uint32_t lfrc32k_interval_get(uint32_t use_interval,uint16_t ppm,uint32_t original_interval) +{ + static uint32_t fast_check_index = 0; + uint8_t current_check_status=0xFF; + fast_check_index++; + uint32_t new_use_interval = original_interval; + + for(uint8_t i=0;i lfrc32k_allow_ppm[current_check_status]) + { + new_use_interval = lfrc32k_fast_check_interval; + fast_check_index = 0; + } + else + { + if(fast_check_index < lfrc32k_check_cnt[current_check_status]) + { + new_use_interval = lfrc32k_check_interval_table[current_check_status]; + } + } + } + else + { + if(ppm > lfrc32k_allow_ppm[2]) + { + new_use_interval = lfrc32k_check_interval_table[1]; + fast_check_index = 0; + } + } + return new_use_interval; +} + +uint32_t get_lfrc32k_calibration_interval(uint32_t original_interval) +{ + static uint32_t prev_debug_lpclk=0; + static uint32_t use_interval=0; + if(prev_debug_lpclk == 0) + { + prev_debug_lpclk = g_debug_lpclk; + use_interval = lfrc32k_fast_check_interval; + return use_interval; + } + else + { + uint16_t ppm=0; + if(prev_debug_lpclk >= g_debug_lpclk) + { + ppm = ((prev_debug_lpclk - g_debug_lpclk)*100*10000)/prev_debug_lpclk; + } + else + { + ppm = ((g_debug_lpclk - prev_debug_lpclk)*100*10000)/g_debug_lpclk; + } + + prev_debug_lpclk = g_debug_lpclk; + use_interval = lfrc32k_interval_get(use_interval,ppm,original_interval); + return use_interval; + } +} + +void pmu_timer_handler(void* p_arg) +{ + static uint32_t pmu_calbration_mod=1; + static uint32_t pmu_calbration_index=0; + //is timer interval is 500ms,make sure 30s interval to do pmu calibration + if(pmu_calbration_index%pmu_calbration_mod == 0) + { + pmu_calibration_handler(p_arg); + if (s_pre_temperature != g_debug_temperature) + { + s_pre_temperature = g_debug_temperature; + rng_calibration(); + } + } + pmu_calbration_index++; + lfrc32k_calibration(); + + uint32_t interval_plan; + uint32_t interval_new; + uint32_t interval_diff; + + interval_plan = pmu_interval_get(0); + + if (interval_plan == 0) + { + interval_new = get_lfrc32k_calibration_interval(interval_plan); + return; + } + interval_new = get_lfrc32k_calibration_interval(interval_plan); + pmu_calbration_mod = interval_plan/ interval_new; + + interval_diff = interval_new > pmu_interval_prev ? + interval_new - pmu_interval_prev: pmu_interval_prev - interval_new; + + if (interval_diff > 2000) + { + app_timer_delete(&s_pmu_calibration_timer_id); + app_timer_create(&s_pmu_calibration_timer_id, ATIMER_REPEAT, pmu_timer_handler); + app_timer_start(s_pmu_calibration_timer_id, interval_new, NULL); + } +} #endif /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ + +void pmu_calibration(void* p_arg) +{ + pmu_calibration_handler(p_arg); + if (s_pre_temperature != g_debug_temperature) + { + s_pre_temperature = g_debug_temperature; + rng_calibration(); + } +} + void system_pmu_calibration_init(uint32_t interval) { - if (interval) { + if (interval) + { uint32_t interval_new; #if CFG_LPCLK_INTERNAL_EN pmu_interval_init = interval; @@ -74,28 +230,15 @@ void system_pmu_calibration_init(uint32_t interval) interval_new = interval; #endif -#ifdef ENV_USE_FREERTOS - timer_handle = xTimerCreate(NULL, interval_new, pdTRUE, NULL, -#if CFG_LPCLK_INTERNAL_EN - pmu_timer_handler -#else - pmu_calibration_handler -#endif // CFG_LPCLK_INTERNAL_EN - ); - - xTaskCreate(system_pmu_calibration_task, "pmu_calibration_task", - STACKDEPTH, NULL, configMAX_PRIORITIES - 1, NULL); -#else app_timer_delete(&s_pmu_calibration_timer_id); - app_timer_create(&s_pmu_calibration_timer_id, ATIMER_REPEAT, + app_timer_create(&s_pmu_calibration_timer_id, ATIMER_REPEAT, #if CFG_LPCLK_INTERNAL_EN pmu_timer_handler #else - pmu_calibration_handler -#endif // CFG_LPCLK_INTERNAL_EN - ); + pmu_calibration +#endif //CFG_LPCLK_INTERNAL_EN + ); app_timer_start(s_pmu_calibration_timer_id, interval_new, NULL); -#endif // ENV_USE_FREERTOS #if CFG_LPCLK_INTERNAL_EN pmu_interval_prev = interval_new; @@ -104,35 +247,9 @@ void system_pmu_calibration_init(uint32_t interval) return; } -#ifdef ENV_USE_FREERTOS -void system_pmu_calibration_start(void) -{ - if (timer_handle != NULL) { - if (xTimerIsTimerActive(timer_handle) == pdFALSE) { - xTimerStart(timer_handle, 0); - } - } - - return; -} - -static void system_pmu_calibration_task(void *p_arg) -{ - system_pmu_calibration_start(); - vTaskDelete(NULL); -} -#endif void system_pmu_calibration_stop(void) { -#ifdef ENV_USE_FREERTOS - if (timer_handle != NULL) { - xTimerDelete(timer_handle, 0); - timer_handle = NULL; - } -#else app_timer_delete(&s_pmu_calibration_timer_id); -#endif return; } - diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.h old mode 100755 new mode 100644 index ae8e208..1f94582 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/pmu_calibration/pmu_calibration.h @@ -1,5 +1,5 @@ -#ifndef _PMU_CALIBRATION_H -#define _PMU_CALIBRATION_H +#ifndef _PMU_CALIB_H +#define _PMU_CALIB_H #include #include diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/BUILD.gn new file mode 100644 index 0000000..92eaa3d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ring_buffer") { + sources = [ "ring_buffer.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.c old mode 100755 new mode 100644 index fb2e312..244d0a5 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.c @@ -39,16 +39,18 @@ * INCLUDE FILES ***************************************************************************************** */ -#include -#include "gr55xx_hal.h" -#include "utility.h" #include "ring_buffer.h" +#include "grx_hal.h" +#include "utility.h" +#include + /* * DEFINES ***************************************************************************************** */ -#define RING_BUFFER_LOCK() GLOBAL_EXCEPTION_DISABLE() -#define RING_BUFFER_UNLOCK() GLOBAL_EXCEPTION_ENABLE() +#define RING_BUFFER_LOCK() GLOBAL_EXCEPTION_DISABLE() +#define RING_BUFFER_UNLOCK() GLOBAL_EXCEPTION_ENABLE() +#define RING_BUFFER_SIZE_MIN (1) /* * GLOBAL FUNCTION DEFINITIONS @@ -56,13 +58,18 @@ */ bool ring_buffer_init(ring_buffer_t *p_ring_buff, uint8_t *p_buff, uint32_t buff_size) { - if (p_buff == NULL || p_ring_buff == NULL) { + if ((NULL == p_buff) || (NULL == p_ring_buff) || (buff_size < RING_BUFFER_SIZE_MIN)) + { return false; - } else { - p_ring_buff->buffer_size = buff_size; - p_ring_buff->p_buffer = p_buff; - p_ring_buff->write_index = 0; - p_ring_buff->read_index = 0; + } + else + { + RING_BUFFER_LOCK(); + p_ring_buff->buffer_size = buff_size; + p_ring_buff->p_buffer = p_buff; + p_ring_buff->write_index = 0; + p_ring_buff->read_index = 0; + RING_BUFFER_UNLOCK(); return true; } @@ -70,139 +77,193 @@ bool ring_buffer_init(ring_buffer_t *p_ring_buff, uint8_t *p_buff, uint32_t buff uint32_t ring_buffer_write(ring_buffer_t *p_ring_buff, uint8_t const *p_wr_data, uint32_t length) { - uint32_t surplus_space = 0; - uint32_t over_flow = 0; - uint32_t wr_idx = p_ring_buff->write_index; - uint32_t rd_idx = p_ring_buff->read_index; - uint32_t ret = 0; - uint32_t len = length; + uint32_t surplus_space = 0; + uint32_t over_flow = 0; RING_BUFFER_LOCK(); - if (rd_idx > wr_idx) { - surplus_space = rd_idx - wr_idx - 1; - len = (len > surplus_space ? surplus_space : len); - } else { - surplus_space = p_ring_buff->buffer_size - wr_idx + rd_idx - 1; - len = (len > surplus_space ? surplus_space : len); + uint32_t wr_idx = p_ring_buff->write_index; + uint32_t rd_idx = p_ring_buff->read_index; - if (wr_idx + len >= p_ring_buff->buffer_size) { - over_flow = wr_idx + len - p_ring_buff->buffer_size; + if ((NULL != p_ring_buff) && + (NULL != p_ring_buff->p_buffer) && + (NULL != p_wr_data)) + { + if (rd_idx > wr_idx) + { + surplus_space = rd_idx - wr_idx - 1; + length = (length > surplus_space ? surplus_space : length); } - } + else + { + surplus_space = p_ring_buff->buffer_size - wr_idx + rd_idx - 1; + length = (length > surplus_space ? surplus_space : length); - ret = memcpy_s(p_ring_buff->p_buffer + wr_idx, len - over_flow, p_wr_data, len - over_flow); - if (ret < 0) { - return ret; - } - ret = memcpy_s(p_ring_buff->p_buffer, over_flow, p_wr_data + len - over_flow, over_flow); - if (ret < 0) { - return ret; - } - wr_idx += len; + if (wr_idx + length >= p_ring_buff->buffer_size) + { + over_flow = wr_idx + length - p_ring_buff->buffer_size; + } + } - if (wr_idx >= p_ring_buff->buffer_size) { - wr_idx -= p_ring_buff->buffer_size; - } + memcpy(p_ring_buff->p_buffer + wr_idx, p_wr_data, length - over_flow); + memcpy(p_ring_buff->p_buffer, p_wr_data + length - over_flow, over_flow); + wr_idx += length; - p_ring_buff->write_index = wr_idx; + if (wr_idx >= p_ring_buff->buffer_size) + { + wr_idx -= p_ring_buff->buffer_size; + } + + p_ring_buff->write_index = wr_idx; + } + else + { + length = 0; + } RING_BUFFER_UNLOCK(); - return len; + return length; } uint32_t ring_buffer_read(ring_buffer_t *p_ring_buff, uint8_t *p_rd_data, uint32_t length) { uint32_t items_avail = 0; uint32_t over_flow = 0; - uint32_t wr_idx = p_ring_buff->write_index; - uint32_t rd_idx = p_ring_buff->read_index; - uint32_t len = length; RING_BUFFER_LOCK(); - if (wr_idx >= rd_idx) { - items_avail = wr_idx - rd_idx; - len = (len > items_avail ? items_avail : len); - } else { - items_avail = p_ring_buff->buffer_size - rd_idx + wr_idx; - len = (len > items_avail ? items_avail : len); + uint32_t wr_idx = p_ring_buff->write_index; + uint32_t rd_idx = p_ring_buff->read_index; - if (rd_idx + len >= p_ring_buff->buffer_size) { - over_flow = len + rd_idx - p_ring_buff->buffer_size; + if ((NULL != p_ring_buff) && + (NULL != p_ring_buff->p_buffer) && + (NULL != p_rd_data)) + { + if (wr_idx >= rd_idx) + { + items_avail = wr_idx - rd_idx; + length = (length > items_avail ? items_avail : length); } + else + { + items_avail = p_ring_buff->buffer_size - rd_idx + wr_idx; + length = (length > items_avail ? items_avail : length); + + if (rd_idx + length >= p_ring_buff->buffer_size) + { + over_flow = length + rd_idx - p_ring_buff->buffer_size; + } + } + + memcpy(p_rd_data, p_ring_buff->p_buffer + rd_idx, length - over_flow); + memcpy(p_rd_data + length - over_flow, p_ring_buff->p_buffer, over_flow); + rd_idx += length; + + if (rd_idx >= p_ring_buff->buffer_size && rd_idx > wr_idx) + { + rd_idx -= p_ring_buff->buffer_size; + } + + p_ring_buff->read_index = rd_idx; } - - memcpy_s(p_rd_data, len - over_flow, p_ring_buff->p_buffer + rd_idx, len - over_flow); - memcpy_s(p_rd_data + len - over_flow, over_flow, p_ring_buff->p_buffer, over_flow); - rd_idx += len; - - if (rd_idx >= p_ring_buff->buffer_size && rd_idx > wr_idx) { - rd_idx -= p_ring_buff->buffer_size; + else + { + length = 0; } - p_ring_buff->read_index = rd_idx; - RING_BUFFER_UNLOCK(); - return len; + return length; } uint32_t ring_buffer_pick(ring_buffer_t *p_ring_buff, uint8_t *p_rd_data, uint32_t length) { uint32_t items_avail = 0; uint32_t over_flow = 0; - uint32_t wr_idx = p_ring_buff->write_index; - uint32_t rd_idx = p_ring_buff->read_index; - uint32_t len = length; RING_BUFFER_LOCK(); - if (wr_idx >= rd_idx) { - items_avail = wr_idx - rd_idx; - len = (len > items_avail ? items_avail : len); - } else { - items_avail = p_ring_buff->buffer_size - rd_idx + wr_idx; - len = (len > items_avail ? items_avail : len); + uint32_t wr_idx = p_ring_buff->write_index; + uint32_t rd_idx = p_ring_buff->read_index; - if (rd_idx + len >= p_ring_buff->buffer_size) { - over_flow = len + rd_idx - p_ring_buff->buffer_size; + if ((NULL != p_ring_buff) && + (NULL != p_ring_buff->p_buffer) && + (NULL != p_rd_data)) + { + if (wr_idx >= rd_idx) + { + items_avail = wr_idx - rd_idx; + length = (length > items_avail ? items_avail : length); } - } + else + { + items_avail = p_ring_buff->buffer_size - rd_idx + wr_idx; + length = (length > items_avail ? items_avail : length); - memcpy_s(p_rd_data, len - over_flow, p_ring_buff->p_buffer + rd_idx, len - over_flow); - memcpy_s(p_rd_data + len - over_flow, over_flow, p_ring_buff->p_buffer, over_flow); + if (rd_idx + length >= p_ring_buff->buffer_size) + { + over_flow = length + rd_idx - p_ring_buff->buffer_size; + } + } + + memcpy(p_rd_data, p_ring_buff->p_buffer + rd_idx, length - over_flow); + memcpy(p_rd_data + length - over_flow, p_ring_buff->p_buffer, over_flow); + } + else + { + length = 0; + } RING_BUFFER_UNLOCK(); - return len; + return length; } uint32_t ring_buffer_items_count_get(ring_buffer_t *p_ring_buff) { + uint32_t count = 0; + if (NULL == p_ring_buff) + return 0; + + RING_BUFFER_LOCK(); + uint32_t wr_idx = p_ring_buff->write_index; uint32_t rd_idx = p_ring_buff->read_index; - if (rd_idx <= wr_idx) { - return wr_idx - rd_idx; - } else { - return p_ring_buff->buffer_size - rd_idx + wr_idx; + if (rd_idx <= wr_idx) + { + count = wr_idx - rd_idx; } + else + { + count = p_ring_buff->buffer_size - rd_idx + wr_idx; + } + + RING_BUFFER_UNLOCK(); + + return count; } uint32_t ring_buffer_surplus_space_get(ring_buffer_t *p_ring_buff) { - uint32_t surplus_space; - uint32_t wr_idx = p_ring_buff->write_index; - uint32_t rd_idx = p_ring_buff->read_index; + uint32_t surplus_space = 0; RING_BUFFER_LOCK(); - if (rd_idx > wr_idx) { - surplus_space = rd_idx - wr_idx - 1; - } else { - surplus_space = p_ring_buff->buffer_size - wr_idx + rd_idx - 1; + uint32_t wr_idx = p_ring_buff->write_index; + uint32_t rd_idx = p_ring_buff->read_index; + + if (NULL != p_ring_buff) + { + if (rd_idx > wr_idx) + { + surplus_space = rd_idx - wr_idx - 1; + } + else + { + surplus_space = p_ring_buff->buffer_size - wr_idx + rd_idx - 1; + } } RING_BUFFER_UNLOCK(); @@ -215,9 +276,13 @@ bool ring_buffer_is_reach_left_threshold(ring_buffer_t *p_ring_buff, uint32_t le uint32_t surplus_space; surplus_space = ring_buffer_surplus_space_get(p_ring_buff); - if (letf_threshold >= surplus_space) { + + if (letf_threshold >= surplus_space) + { return true; - } else { + } + else + { return false; } } @@ -226,8 +291,11 @@ void ring_buffer_clean(ring_buffer_t *p_ring_buff) { RING_BUFFER_LOCK(); - p_ring_buff->write_index = 0; - p_ring_buff->read_index = 0; + if (NULL != p_ring_buff) + { + p_ring_buff->write_index = 0; + p_ring_buff->read_index = 0; + } RING_BUFFER_UNLOCK(); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.h old mode 100755 new mode 100644 index 9d87d32..7e5e966 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/ring_buffer/ring_buffer.h @@ -48,7 +48,8 @@ * @defgroup RING_BUFFER_STRUCT Structures * @{ */ -typedef struct { +typedef struct +{ uint32_t buffer_size; /**< Size of ring buffer. */ uint8_t *p_buffer; /**< Pointer to buffer saved data. */ uint32_t write_index; /**< Index of write. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/BUILD.gn new file mode 100644 index 0000000..47dc7b6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("sensorsim") { + sources = [ "sensorsim.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.c new file mode 100644 index 0000000..da49de8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.c @@ -0,0 +1,103 @@ +/** + ***************************************************************************************** + * + * @file sensorsim.c + * + * @brief sensor simulator function Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "sensorsim.h" + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ + +void sensorsim_init(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg) +{ + if (p_cfg->start_at_max) + { + p_state->current_val = p_cfg->max; + p_state->is_increasing = false; + } + else + { + p_state->current_val = p_cfg->min; + p_state->is_increasing = true; + } +} + +int16_t sensorsim_measure(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg) +{ + if (p_state->is_increasing) + { + sensorsim_increment(p_state, p_cfg); + } + else + { + sensorsim_decrement(p_state, p_cfg); + } + + return p_state->current_val; +} + + +void sensorsim_increment(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg) +{ + if (p_cfg->max - p_state->current_val > p_cfg->incr) + { + p_state->current_val += p_cfg->incr; + } + else + { + p_state->current_val = p_cfg->max; + p_state->is_increasing = false; + } +} + +void sensorsim_decrement(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg) +{ + if (p_state->current_val - p_cfg->min > p_cfg->incr) + { + p_state->current_val -= p_cfg->incr; + } + else + { + p_state->current_val = p_cfg->min; + p_state->is_increasing = true; + } +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.h new file mode 100644 index 0000000..92648af --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/sensorsim/sensorsim.h @@ -0,0 +1,118 @@ +/** + ***************************************************************************************** + * + * @file sensorsim.h + * + * @brief Header file - sensor simulator + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef _SENSORSIM_H__ +#define _SENSORSIM_H__ + +#include +#include + +/** + * @defgroup SENSORSIM_STRUCT Structures + * @{ + */ +/**@brief Triangular waveform sensor simulator configuration. */ +typedef struct +{ + int16_t min; /**< Minimum simulated value. */ + int16_t max; /**< Maximum simulated value. */ + int16_t incr; /**< Increment between each measurement. */ + bool start_at_max; /**< TRUE is measurement is to start at the maximum value, FALSE if it is to start at the minimum. */ +} sensorsim_cfg_t; + +/**@brief Triangular waveform sensor simulator state. */ +typedef struct +{ + int16_t current_val; /**< Current sensor value. */ + bool is_increasing; /**< TRUE if the simulator is in increasing state, FALSE otherwise. */ +} sensorsim_state_t; +/** @} */ + + +/** + * @defgroup SENSORSIM_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Function for initializing a triangular waveform sensor simulator. + * + * @param[out] p_state: Current state of simulator. + * @param[in] p_cfg: Simulator configuration. + ***************************************************************************************** + */ +void sensorsim_init(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg); + +/** + ***************************************************************************************** + * @brief Function for generating a simulated sensor measurement using a triangular waveform generator. + * + * @param[in,out] p_state: Current state of simulator. + * @param[in] p_cfg: Simulator configuration. + * + * @retval ::Simulator output. + ***************************************************************************************** + */ +int16_t sensorsim_measure(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg); + +/** + ***************************************************************************************** + * @brief Function for incrementing a simulated sensor measurement value. + * + * @param[in,out] p_state: Current state of simulator. + * @param[in] p_cfg: Simulator configuration. + * + * @retval Simulator output. + ***************************************************************************************** + */ +void sensorsim_increment(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg); + +/** + ***************************************************************************************** + * @brief Function for decrementing a simulated sensor measurement value. + * + * @param[in,out] p_state: Current state of simulator. + * @param[in] p_cfg: Simulator configuration. + * + * @retval Simulator output. + ***************************************************************************************** + */ +void sensorsim_decrement(sensorsim_state_t *p_state, const sensorsim_cfg_t *p_cfg); +/** @} */ + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/BUILD.gn new file mode 100644 index 0000000..c81a661 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("user_efuse") { + sources = [ "user_efuse.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.c new file mode 100644 index 0000000..138e319 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.c @@ -0,0 +1,125 @@ +/** + ***************************************************************************************** + * + * @file user_efuse.c + * + * @brief efuse access function Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "user_efuse.h" +#include "string.h" +#include "grx_sys.h" +#include "grx_hal.h" + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint32_t user_efuse_write(uint8_t word_offset, uint32_t * efuse_value, uint8_t size_word) +{ + uint32_t ret = USER_EFUSE_ERROR_NONE; + efuse_handle_t efuse_handle = {0}; + + /* + * Reserved For Furture : Because the macro USER_EFUSE_BASE_OFFSET equal zero now, it will cause compiler warning. + * But in the furture, maybe USER_EFUSE_BASE_OFFSET will be another value. + */ + if( /*(word_offset < USER_EFUSE_BASE_OFFSET) || */(word_offset > (USER_EFUSE_BASE_OFFSET + USER_EFUSE_SIZE)) || (efuse_value == NULL)) + { + return USER_EFUSE_ERROR_INVALID_PARAM; + } + + if((word_offset + size_word * 4) > (USER_EFUSE_BASE_OFFSET + USER_EFUSE_SIZE)) + { + return USER_EFUSE_ERROR_INVALID_PARAM; + } + + do { + efuse_handle.p_instance = EFUSE; + efuse_handle.init.info_mode = DISABLE; + if(hal_efuse_init(&efuse_handle) != HAL_OK) + { + ret = USER_EFUSE_INIT_ERROR; + break; + } + + if(HAL_OK != hal_efuse_write(&efuse_handle, word_offset, efuse_value, size_word)) + { + ret = USER_EFUSE_WRITE_ERROR; + break; + } + } while(0); + hal_efuse_deinit(&efuse_handle); + return ret; +} + +uint32_t user_efuse_read(uint8_t word_offset, uint32_t *data, uint8_t size_word) +{ + uint32_t ret = USER_EFUSE_ERROR_NONE; + efuse_handle_t efuse_handle = {0}; + + /* + * Reserved For Furture : Because the macro USER_EFUSE_BASE_OFFSET equal zero now, it will cause compiler warning. + * But in the furture, maybe USER_EFUSE_BASE_OFFSET will be another value. + */ + if( /*(word_offset < USER_EFUSE_BASE_OFFSET) || */(word_offset > (USER_EFUSE_BASE_OFFSET + USER_EFUSE_SIZE)) || (data == NULL)) + { + return USER_EFUSE_ERROR_INVALID_PARAM; + } + + if((word_offset + size_word * 4) > (USER_EFUSE_BASE_OFFSET + USER_EFUSE_SIZE)) + { + return USER_EFUSE_ERROR_INVALID_PARAM; + } + + do { + efuse_handle.p_instance = EFUSE; + efuse_handle.init.info_mode = DISABLE; + if(hal_efuse_init(&efuse_handle) != HAL_OK) + { + ret = USER_EFUSE_INIT_ERROR; + break; + } + + if(HAL_OK != hal_efuse_read(&efuse_handle, word_offset, data, size_word)) + { + return USER_EFUSE_READ_ERROR; + } + }while(0); + hal_efuse_deinit(&efuse_handle); + return ret; +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.h new file mode 100644 index 0000000..0b55272 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/user_efuse/user_efuse.h @@ -0,0 +1,89 @@ +/** + ***************************************************************************************** + * + * @file user_efuse.h + * + * @brief efuse access API. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __USER_EFUSE_H__ +#define __USER_EFUSE_H__ + +#include +#include + +/** + * @defgroup USER_EFUSE_MAROC Defines + * @{ + */ +#define USER_EFUSE_BASE_OFFSET EFUSE_OFFSET_USER_DSVD /**< User eFuse offset */ +#define USER_EFUSE_SIZE (0x0020UL) /**< User eFuse size */ + +#define USER_EFUSE_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define USER_EFUSE_INIT_ERROR ((uint32_t)0x00000001) /**< INIT error */ +#define USER_EFUSE_WRITE_ERROR ((uint32_t)0x00000002) /**< WRITE error */ +#define USER_EFUSE_READ_ERROR ((uint32_t)0x00000004) /**< READ error */ +#define USER_EFUSE_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +/** @} */ + +/** + * @defgroup USER_EFUSE_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief efuse write + * + * @param[in] offset: Offset + * @param[in] efuse_value: Pointer to data + * @param[in] size_word: Write data size + * + * @return the error code of this funciton + ***************************************************************************************** + */ +uint32_t user_efuse_write(uint8_t offset, uint32_t *efuse_value, uint8_t size_word); + +/** + ***************************************************************************************** + * @brief efuse read + * + * @param[in] word_offset: Offset + * @param[in] data: Pointer to data + * @param[in] size_word: Read data size + * + * @return the error code of this funciton + ***************************************************************************************** + */ +uint32_t user_efuse_read(uint8_t word_offset, uint32_t *data, uint8_t size_word); +/** @} */ + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/BUILD.gn new file mode 100644 index 0000000..1c4ef62 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("utility") { + sources = [ "utility.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.c b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.c old mode 100755 new mode 100644 index 07a9139..6c4e958 --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.c @@ -41,176 +41,148 @@ */ #include "utility.h" -/* - * DEFINES - ***************************************************************************************** - */ - -#define ITEM_0 0 -#define ITEM_1 1 -#define ITEM_2 2 -#define ITEM_3 3 -#define ITEM_4 4 -#define ITEM_5 5 -#define ITEM_6 6 -#define ITEM_7 7 - -#define BIT_8 8 -#define BIT_16 16 -#define BIT_24 24 -#define BIT_32 32 -#define BIT_40 40 -#define BIT_48 48 -#define BIT_56 56 - -#define OFFSET_0 0 -#define OFFSET_1 1 -#define OFFSET_2 2 -#define OFFSET_3 3 -#define OFFSET_4 4 - /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ -void htole16(uint8_t *p_buf, uint16_t x) +void htole16(void *buf, uint16_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t) x; - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_8); + u8ptr = buf; + u8ptr[0] = (uint8_t) x; + u8ptr[1] = (uint8_t)(x >> 8); } -void htole32(uint8_t *p_buf, uint32_t x) +void htole32(void *buf, uint32_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t) x; - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_2] = (uint8_t)(x >> BIT_16); - u8ptr[ITEM_3] = (uint8_t)(x >> BIT_24); + u8ptr = buf; + u8ptr[0] = (uint8_t) x; + u8ptr[1] = (uint8_t)(x >> 8); + u8ptr[2] = (uint8_t)(x >> 16); + u8ptr[3] = (uint8_t)(x >> 24); } -void htole64(uint8_t *p_buf, uint64_t x) +void htole64(void *buf, uint64_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t) x; - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_2] = (uint8_t)(x >> BIT_16); - u8ptr[ITEM_3] = (uint8_t)(x >> BIT_24); - u8ptr[ITEM_4] = (uint8_t)(x >> BIT_32); - u8ptr[ITEM_5] = (uint8_t)(x >> BIT_40); - u8ptr[ITEM_6] = (uint8_t)(x >> BIT_48); - u8ptr[ITEM_7] = (uint8_t)(x >> BIT_56); + u8ptr = buf; + u8ptr[0] = (uint8_t) x; + u8ptr[1] = (uint8_t)(x >> 8); + u8ptr[2] = (uint8_t)(x >> 16); + u8ptr[3] = (uint8_t)(x >> 24); + u8ptr[4] = (uint8_t)(x >> 32); + u8ptr[5] = (uint8_t)(x >> 40); + u8ptr[6] = (uint8_t)(x >> 48); + u8ptr[7] = (uint8_t)(x >> 56); } -uint16_t le16toh(const uint8_t *p_buf) +uint16_t le16toh(const void *buf) { const uint8_t *u8ptr; uint16_t x; - u8ptr = p_buf; - x = u8ptr[ITEM_0]; - x |= (uint16_t) u8ptr[ITEM_1] << BIT_8; + u8ptr = buf; + x = u8ptr[0]; + x |= (uint16_t) u8ptr[1] << 8; return x; } -uint32_t le32toh(const uint8_t *p_buf) +uint32_t le32toh(const void *buf) { const uint8_t *u8ptr; uint32_t x; - u8ptr = p_buf; - x = u8ptr[ITEM_0]; - x |= (uint32_t) u8ptr[ITEM_1] << BIT_8; - x |= (uint32_t) u8ptr[ITEM_2] << BIT_16; - x |= (uint32_t) u8ptr[ITEM_3] << BIT_24; + u8ptr = buf; + x = u8ptr[0]; + x |= (uint32_t) u8ptr[1] << 8; + x |= (uint32_t) u8ptr[2] << 16; + x |= (uint32_t) u8ptr[3] << 24; return x; } -uint64_t le64toh(const uint8_t *p_buf) +uint64_t le64toh(const void *buf) { const uint8_t *u8ptr; uint64_t x; - u8ptr = p_buf; - x = u8ptr[ITEM_0]; - x |= (uint64_t) u8ptr[ITEM_1] << BIT_8; - x |= (uint64_t) u8ptr[ITEM_2] << BIT_16; - x |= (uint64_t) u8ptr[ITEM_3] << BIT_24; - x |= (uint64_t) u8ptr[ITEM_4] << BIT_32; - x |= (uint64_t) u8ptr[ITEM_5] << BIT_40; - x |= (uint64_t) u8ptr[ITEM_6] << BIT_48; - x |= (uint64_t) u8ptr[ITEM_7] << BIT_56; + u8ptr = buf; + x = u8ptr[0]; + x |= (uint64_t) u8ptr[1] << 8; + x |= (uint64_t) u8ptr[2] << 16; + x |= (uint64_t) u8ptr[3] << 24; + x |= (uint64_t) u8ptr[4] << 32; + x |= (uint64_t) u8ptr[5] << 40; + x |= (uint64_t) u8ptr[6] << 48; + x |= (uint64_t) u8ptr[7] << 56; return x; } -void htobe16(uint8_t *p_buf, uint16_t x) +void htobe16(void *buf, uint16_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_1] = (uint8_t) x; + u8ptr = buf; + u8ptr[0] = (uint8_t)(x >> 8); + u8ptr[1] = (uint8_t) x; } -void htobe32(uint8_t *p_buf, uint32_t x) +void htobe32(void *buf, uint32_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t)(x >> BIT_24); - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_16); - u8ptr[ITEM_2] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_3] = (uint8_t) x; + u8ptr = buf; + u8ptr[0] = (uint8_t)(x >> 24); + u8ptr[1] = (uint8_t)(x >> 16); + u8ptr[2] = (uint8_t)(x >> 8); + u8ptr[3] = (uint8_t) x; } -void htobe64(uint8_t *p_buf, uint64_t x) +void htobe64(void *buf, uint64_t x) { uint8_t *u8ptr; - u8ptr = p_buf; - u8ptr[ITEM_0] = (uint8_t)(x >> BIT_56); - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_48); - u8ptr[ITEM_2] = (uint8_t)(x >> BIT_40); - u8ptr[ITEM_3] = (uint8_t)(x >> BIT_32); - u8ptr[ITEM_4] = (uint8_t)(x >> BIT_24); - u8ptr[ITEM_5] = (uint8_t)(x >> BIT_16); - u8ptr[ITEM_6] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_7] = (uint8_t) x; + u8ptr = buf; + u8ptr[0] = (uint8_t)(x >> 56); + u8ptr[1] = (uint8_t)(x >> 48); + u8ptr[2] = (uint8_t)(x >> 40); + u8ptr[3] = (uint8_t)(x >> 32); + u8ptr[4] = (uint8_t)(x >> 24); + u8ptr[5] = (uint8_t)(x >> 16); + u8ptr[6] = (uint8_t)(x >> 8); + u8ptr[7] = (uint8_t) x; } -uint16_t be16toh(const uint8_t *p_buf) +uint16_t be16toh(const void *buf) { const uint8_t *u8ptr; uint16_t x; - u8ptr = p_buf; - x = (uint16_t) u8ptr[ITEM_0] << BIT_8; - x |= u8ptr[ITEM_1]; + u8ptr = buf; + x = (uint16_t) u8ptr[0] << 8; + x |= u8ptr[1]; return x; } -uint32_t be32toh(const uint8_t *p_buf) +uint32_t be32toh(const void *buf) { const uint8_t *u8ptr; uint32_t x; - u8ptr = p_buf; - x = (uint32_t) u8ptr[ITEM_0] << BIT_24; - x |= (uint32_t) u8ptr[ITEM_1] << BIT_16; - x |= (uint32_t) u8ptr[ITEM_2] << BIT_8; - x |= u8ptr[ITEM_3]; + u8ptr = buf; + x = (uint32_t) u8ptr[0] << 24; + x |= (uint32_t) u8ptr[1] << 16; + x |= (uint32_t) u8ptr[2] << 8; + x |= u8ptr[3]; return x; } -uint64_t be64toh(const uint8_t *p_buf) +uint64_t be64toh(const void *buf) { const uint8_t *u8ptr; uint64_t x; - u8ptr = p_buf; - x = (uint64_t) u8ptr[ITEM_0] << BIT_56; - x |= (uint64_t) u8ptr[ITEM_1] << BIT_48; - x |= (uint64_t) u8ptr[ITEM_2] << BIT_40; - x |= (uint64_t) u8ptr[ITEM_3] << BIT_32; - x |= (uint64_t) u8ptr[ITEM_4] << BIT_24; - x |= (uint64_t) u8ptr[ITEM_5] << BIT_16; - x |= (uint64_t) u8ptr[ITEM_6] << BIT_8; - x |= u8ptr[ITEM_7]; + u8ptr = buf; + x = (uint64_t) u8ptr[0] << 56; + x |= (uint64_t) u8ptr[1] << 48; + x |= (uint64_t) u8ptr[2] << 40; + x |= (uint64_t) u8ptr[3] << 32; + x |= (uint64_t) u8ptr[4] << 24; + x |= (uint64_t) u8ptr[5] << 16; + x |= (uint64_t) u8ptr[6] << 8; + x |= u8ptr[7]; return x; } @@ -219,8 +191,8 @@ uint8_t get_u8_inc(const uint8_t **pp_buf) const uint8_t *u8ptr; uint8_t x; u8ptr = *pp_buf; - x = u8ptr[ITEM_0]; - *pp_buf += OFFSET_1; + x = u8ptr[0]; + *pp_buf += 1; return x; } @@ -229,9 +201,9 @@ uint16_t get_u16_inc(const uint8_t **pp_buf) const uint8_t *u8ptr; uint16_t x; u8ptr = *pp_buf; - x = u8ptr[ITEM_0]; - x |= (uint16_t) u8ptr[ITEM_1] << BIT_8; - *pp_buf += OFFSET_2; + x = u8ptr[0]; + x |= (uint16_t) u8ptr[1] << 8; + *pp_buf += 2; return x; } @@ -240,11 +212,11 @@ uint32_t get_u32_inc(const uint8_t **pp_buf) const uint8_t *u8ptr; uint32_t x; u8ptr = *pp_buf; - x = u8ptr[ITEM_0]; - x |= (uint32_t) u8ptr[ITEM_1] << BIT_8; - x |= (uint32_t) u8ptr[ITEM_2] << BIT_16; - x |= (uint32_t) u8ptr[ITEM_3] << BIT_24; - *pp_buf += OFFSET_4; + x = u8ptr[0]; + x |= (uint32_t) u8ptr[1] << 8; + x |= (uint32_t) u8ptr[2] << 16; + x |= (uint32_t) u8ptr[3] << 24; + *pp_buf += 4; return x; } @@ -252,27 +224,27 @@ void put_u8_inc(uint8_t **pp_buf, uint8_t x) { uint8_t *u8ptr; u8ptr = *pp_buf; - u8ptr[ITEM_0] = x; - *pp_buf += OFFSET_1; + u8ptr[0] = x; + *pp_buf += 1; } void put_u16_inc(uint8_t **pp_buf, uint16_t x) { uint8_t *u8ptr; u8ptr = *pp_buf; - u8ptr[ITEM_0] = (uint8_t) x; - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_8); - *pp_buf += OFFSET_2; + u8ptr[0] = (uint8_t) x; + u8ptr[1] = (uint8_t)(x >> 8); + *pp_buf += 2; } void put_u32_inc(uint8_t **pp_buf, uint32_t x) { uint8_t *u8ptr; u8ptr = *pp_buf; - u8ptr[ITEM_0] = (uint8_t) x; - u8ptr[ITEM_1] = (uint8_t)(x >> BIT_8); - u8ptr[ITEM_2] = (uint8_t)(x >> BIT_16); - u8ptr[ITEM_3] = (uint8_t)(x >> BIT_24); - *pp_buf += OFFSET_4; + u8ptr[0] = (uint8_t) x; + u8ptr[1] = (uint8_t)(x >> 8); + u8ptr[2] = (uint8_t)(x >> 16); + u8ptr[3] = (uint8_t)(x >> 24); + *pp_buf += 4; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.h old mode 100755 new mode 100644 index cd7ad9c..fbad73e --- a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/utility/utility.h @@ -71,54 +71,39 @@ extern "C" { #define B_FAIL ((uint8_t)0xFF) #ifndef BV -static inline uint8_t BV(uint32_t n) -{ - return (uint8_t)(1 << n); -} +#define BV(n) (uint8_t)(1 << (n)) #endif #ifndef BF -static inline uint8_t BF(uint32_t x, uint32_t b, uint32_t s) -{ - return ((uint8_t)((x) & (b)) >> (s)); -} +#define BF(x, b, s) ((uint8_t)((x) & (b)) >> (s)) #endif #ifndef MIN -static inline uint32_t MIN(uint32_t n, uint32_t m) -{ - return (((n) < (m)) ? (n) : (m)); -} +#define MIN(n, m) (((n) < (m)) ? (n) : (m)) #endif #ifndef MAX -static inline uint32_t MAX(uint32_t n, uint32_t m) -{ - return (((n) < (m)) ? (m) : (n)); -} +#define MAX(n, m) (((n) < (m)) ? (m) : (n)) #endif #ifndef ABS -static inline uint32_t ABS(int32_t n) -{ - return (((n) < 0) ? -(n) : (n)); -} +#define ABS(n) (((n) < 0) ? -(n) : (n)) #endif #ifndef ALIGN_NUM #define ALIGN_NUM(align, num) (((num) - 1) + (align) - (((num) - 1) % (align))) #endif -#define BIT_MASK(n) (uint8_t)(((1) << (n)) - 1) +#define BIT_MASK(n) (uint8_t)(((1) << n) - 1) -/* takes a byte out of a uint32:var -uint32, ByteNum - byte tao take out(0-3) */ +/*takes a byte out of a uint32:var -uint32, ByteNum - byte tao take out(0-3)*/ #define BREAK_U32(var, ByteNum) (uint8_t)((uint32_t)(((var) >> ((uint8_t)((ByteNum) * 8))) & 0x00FF)) #define BUILD_U32(Byte0, Byte1, Byte2, Byte3) \ - ((uint32_t)((uint32_t)((Byte0) & 0x00FF) + \ - ((uint32_t)((Byte1) & 0x00FF) << 8) + \ - ((uint32_t)((Byte2) & 0x00FF) << 16) + \ - ((uint32_t)((Byte3) & 0x00FF) << 24))) + ((uint32_t)((uint32_t)((Byte0) & 0x00FF) + \ + ((uint32_t)((Byte1) & 0x00FF) << 8) + \ + ((uint32_t)((Byte2) & 0x00FF) << 16) + \ + ((uint32_t)((Byte3) & 0x00FF) << 24))) #define HI_UINT32_T(a) (((a) >> 24) & 0xFF) #define L3_UINT32_T(a) (((a) >> 16) & 0xFF) @@ -153,16 +138,16 @@ static inline uint32_t ABS(int32_t n) #endif #ifndef GET_BITFIELD -#define GET_BITFIELD(var, MSB, LSB) ((uint8_t)((var) << (7 - (MSB))) >> ((7 - (MSB)) + (LSB))) +#define GET_BITFIELD(var, MSB, LSB) ((uint8_t)((var) << (7 - MSB)) >> ((7 - MSB) + LSB)) #endif #ifndef SET_BITFIELD #define SET_BITFIELD(var, MSB, LSB, value) ((uint8_t)(var) = \ - (uint8_t)(((var) & (~(BIT_MASK(((MSB) - (LSB)))<<(LSB)))) | (((value) & BIT_MASK(((MSB) - (LSB)))) << (LSB)))) + (uint8_t)((var & (~(BIT_MASK((MSB - LSB))< +#include "user_periph_setup.h" +#include "uart_simu_key_init.h" +#include "grx_sys.h" +#include "custom_config.h" +#include "app_assert.h" +#include "app_log.h" +#include "app_error.h" +#include "board_SK.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define UART_TX_BUFFER_SIZE 0x400 +#define UART_RX_BUFFER_SIZE 244 + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +static app_uart_tx_buf_t s_uart_buffer; +static app_uart_params_t s_uart_param; + +static uint8_t s_uart_tx_buffer[UART_TX_BUFFER_SIZE] = {0}; +static uint8_t s_uart_rx_buffer[UART_RX_BUFFER_SIZE] = {0}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_uart_rx_handler(app_uart_evt_t *p_evt) +{ + if (APP_UART_EVT_RX_DATA == p_evt->type) + { + uint8_t key_id = 0xFF; + app_key_click_type_t key_click_type; + uint8_t rx_buf_offset = 0; + + if (!memcmp(s_uart_rx_buffer, VIR_KEY_UP_CMD, strlen(VIR_KEY_UP_CMD))) + { + rx_buf_offset += strlen(VIR_KEY_UP_CMD); + key_id = VIR_KEY_UP_ID; + } + else if (!memcmp(s_uart_rx_buffer, VIR_KEY_DOWN_CMD, strlen(VIR_KEY_DOWN_CMD))) + { + rx_buf_offset += strlen(VIR_KEY_DOWN_CMD); + key_id = VIR_KEY_DOWN_ID; + } + else if (!memcmp(s_uart_rx_buffer, VIR_KEY_LEFT_CMD, strlen(VIR_KEY_LEFT_CMD))) + { + rx_buf_offset += strlen(VIR_KEY_LEFT_CMD); + key_id = VIR_KEY_LEFT_ID; + } + else if (!memcmp(s_uart_rx_buffer, VIR_KEY_RIGHT_CMD, strlen(VIR_KEY_RIGHT_CMD))) + { + rx_buf_offset += strlen(VIR_KEY_RIGHT_CMD); + key_id = VIR_KEY_RIGHT_ID; + } + else if (!memcmp(s_uart_rx_buffer, VIR_KEY_OK_CMD, strlen(VIR_KEY_OK_CMD))) + { + rx_buf_offset += strlen(VIR_KEY_OK_CMD); + key_id = VIR_KEY_OK_ID; + } + + /* Determine the click type. */ + if (!memcmp(&(s_uart_rx_buffer[rx_buf_offset]), VIR_KEY_DOUBLE_PRESS, strlen(VIR_KEY_DOUBLE_PRESS))) + { + if (!memcmp(&(s_uart_rx_buffer[rx_buf_offset]), VIR_KEY_LONG_PRESS, strlen(VIR_KEY_LONG_PRESS))) + { + key_click_type = APP_KEY_LONG_CLICK; + } + else + { + key_click_type = APP_KEY_DOUBLE_CLICK; + } + } + else if (!memcmp(&(s_uart_rx_buffer[rx_buf_offset]), VIR_KEY_CONTINUE_PRESS, strlen(VIR_KEY_CONTINUE_PRESS))) + { + if (!memcmp(&(s_uart_rx_buffer[rx_buf_offset]), VIR_KEY_CONTINUE_RELEASE, strlen(VIR_KEY_CONTINUE_RELEASE))) + { + key_click_type = APP_KEY_CONTINUE_CLICK; + } + else + { + key_click_type = APP_KEY_CONTINUE_RELEASE; + } + } + else + { + key_click_type = APP_KEY_SINGLE_CLICK; + } + + memset(s_uart_rx_buffer,0,UART_RX_BUFFER_SIZE); + app_key_evt_handler(key_id, key_click_type); + } +} + +static void uart_evt_handler(app_uart_evt_t *p_evt) +{ + if (APP_UART_EVT_RX_DATA == p_evt->type) + { + app_uart_rx_handler(p_evt); + app_uart_receive_async(APP_UART_ID, s_uart_rx_buffer, UART_RX_BUFFER_SIZE); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +void uart_simu_key_init(void) +{ + s_uart_buffer.tx_buf = s_uart_tx_buffer; + s_uart_buffer.tx_buf_size = UART_TX_BUFFER_SIZE; + + s_uart_param.id = APP_UART_ID; + s_uart_param.init.baud_rate = APP_UART_BAUDRATE; + s_uart_param.init.data_bits = UART_DATABITS_8; + s_uart_param.init.stop_bits = UART_STOPBITS_1; + s_uart_param.init.parity = UART_PARITY_NONE; + s_uart_param.init.hw_flow_ctrl = UART_HWCONTROL_NONE; + s_uart_param.init.rx_timeout_mode = UART_RECEIVER_TIMEOUT_ENABLE; + s_uart_param.pin_cfg.rx.type = APP_UART_RX_IO_TYPE; + s_uart_param.pin_cfg.rx.pin = APP_UART_RX_PIN; + s_uart_param.pin_cfg.rx.mux = APP_UART_RX_PINMUX; + s_uart_param.pin_cfg.rx.pull = APP_UART_RX_PULL; + s_uart_param.pin_cfg.tx.type = APP_UART_TX_IO_TYPE; + s_uart_param.pin_cfg.tx.pin = APP_UART_TX_PIN; + s_uart_param.pin_cfg.tx.mux = APP_UART_TX_PINMUX; + s_uart_param.pin_cfg.tx.pull = APP_UART_TX_PULL; + s_uart_param.dma_cfg.tx_dma_instance = DMA0; + s_uart_param.dma_cfg.rx_dma_instance = DMA0; + s_uart_param.dma_cfg.tx_dma_channel = DMA_Channel2; + s_uart_param.dma_cfg.rx_dma_channel = DMA_Channel3; + + app_uart_init(&s_uart_param, uart_evt_handler, &s_uart_buffer); + app_uart_receive_async(APP_UART_ID, s_uart_rx_buffer, UART_RX_BUFFER_SIZE); +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/uart_simu_key_init.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/uart_simu_key_init.h new file mode 100644 index 0000000..3e1675c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/virt_key/uart_simu_key_init.h @@ -0,0 +1,75 @@ +/** + ***************************************************************************************** + * + * @file user_simu_key_init.h + * + * @brief Header file - User Function + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef _UART_SIMU_KEY_INIT_H_ +#define _UART_SIMU_KEY_INIT_H_ + +/* + * DEFINES + ***************************************************************************************** + */ +#define VIR_KEY_UP_ID 0x00 /**< ID for Virtual UP KEY. */ +#define VIR_KEY_DOWN_ID 0x01 /**< ID for Virtual DOWN KEY. */ +#define VIR_KEY_LEFT_ID 0x02 /**< ID for Virtual LEFT KEY. */ +#define VIR_KEY_RIGHT_ID 0x03 /**< ID for Virtual RIGHT KEY. */ +#define VIR_KEY_OK_ID 0x04 /**< ID for Virtual OK KEY. */ + +#define VIR_KEY_UP_CMD "up" /**< Command for Virtual UP KEY. */ +#define VIR_KEY_DOWN_CMD "down" /**< Command for Virtual DOWN KEY. */ +#define VIR_KEY_LEFT_CMD "left" /**< Command for Virtual LEFT KEY. */ +#define VIR_KEY_RIGHT_CMD "right" /**< Command for Virtual RIGHT KEY. */ +#define VIR_KEY_OK_CMD "ok" /**< Command for Virtual OK KEY. */ +#define VIR_KEY_DOUBLE_PRESS "+" /**< Double press click type. */ +#define VIR_KEY_LONG_PRESS "++" /**< Long press click type. */ +#define VIR_KEY_CONTINUE_PRESS "-" /**< Continue press click type. */ +#define VIR_KEY_CONTINUE_RELEASE "--" /**< Continue release click type. */ + +/* + * GLOBAL FUNCTION DECLARATION + ***************************************************************************************** + */ +/** + ***************************************************************************************** + * @brief Function for ble stack init complete + ***************************************************************************************** + */ +void uart_simu_key_init(void); + +/** @} */ + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/BUILD.gn new file mode 100644 index 0000000..c81e063 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/BUILD.gn @@ -0,0 +1,73 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +module_group("profiles") { + modules = [ + # "wss", + "hts", + "common", + "sample", + "cts_c", + "ths_c", + "gus_c", + + # "cts", + "otas", + "otas_c", + "hrrcps", + "tps", + "ans_c", + + # "mlmr", + "bas", + "ans", + "cscs", + "bas_c", + "lms", + "lns", + "dis_c", + "lls", + "dss", + + # "uds", + "hrs_c", + "tps_c", + "rscs_c", + "gus", + "ias", + "rtus", + "ths", + "dis", + "ias_c", + + # "mlmr_c", + "lls_c", + "ndcs", + "rscs", + + # "ags", + "pass", + "gls", + "ancs_c", + + # "bcs", + "pcs", + "pass_c", + "hrs", + "hids", + "bps", + "ams_c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/BUILD.gn new file mode 100644 index 0000000..663c137 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ags") { + sources = [ "ags.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.c index 85c228d..3902cde 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.c @@ -46,15 +46,12 @@ #include "utility.h" #include "app_log.h" #include "app_error.h" -#define MAX_PACKET_SIZE_OFFSET 3 -#define INDEX_0 0 -#define INDEX_1 1 -#define INDEX_2 2 + /* * DEFINES ***************************************************************************************** */ -/**@brief The UUIDs of AGS characteristics. +/**@brief The UUIDs of AGS characteristics. * The Tx channel transmits data from an Echo device to a gadget. * The Rx channel reansmits data from a gadget to an Echo device. */ @@ -72,7 +69,8 @@ ***************************************************************************************** */ /**@brief Alexa Gadget Service Attributes Indexes. */ -enum { +enum +{ AGS_IDX_SVC, AGS_IDX_TX_CHAR, @@ -90,17 +88,18 @@ enum { ***************************************************************************************** */ /**@brief Alexa Gadget Service environment variable. */ -struct ags_env_t { - ags_init_t ags_init; /**< Alexa Gadget Service initialization variables. */ - uint16_t start_hdl; /**< Alexa Gadget Service start handle. */ - ags_stream_env_t ags_stream_env[3]; /**< The environment variable of gadget stream. */ - uint16_t - rx_ntf_cfg[AGS_CONNECTION_MAX]; /**< The configuration of Rx Notification \ - which is configured by the peer devices. */ +struct ags_env_t +{ + ags_init_t ags_init; /**< Alexa Gadget Service initialization variables. */ + uint16_t start_hdl; /**< Alexa Gadget Service start handle. */ + ags_stream_env_t ags_stream_env[3]; /**< The environment variable of gadget stream. */ + uint16_t rx_ntf_cfg[AGS_CONNECTION_MAX]; /**< The configuration of Rx Notification which is configured by the peer devices. */ + ble_gatts_create_db_t ags_gatts_db; /**< Alexa Gadget Service attributs database. */ }; /**@brief Alexa Gadget stream payload. */ -typedef struct { +typedef struct +{ uint8_t p_data[USER_GADGET_TRANSACTION_BUF_SIZE]; /**< Gadget stream payload. */ uint16_t length; /**< Length of data. */ uint16_t offset; /**< Offset of data. */ @@ -110,126 +109,56 @@ typedef struct { * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t ags_init(void); -static void ags_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void ags_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void ags_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void ags_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - static sdk_err_t ags_echo_rx_val_chunk(uint8_t conn_idx); static sdk_err_t ags_stream_ack_send(uint8_t conn_idx, uint8_t stream_env_id, bool ack_flag); -static void ags_echo_tx_val_decode(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); -static void ags_encode_ack(ags_ack_packet_t *p_ack_packet, uint8_t stream_id, uint8_t trxn_id, bool ack_flag); -static void ags_encode_header(uint8_t *header, uint8_t stream_id, uint8_t trxn_type, uint8_t payload_length, - uint16_t trxn_length); +static void ags_echo_tx_val_decode(uint8_t conn_idx, const uint8_t *buf, uint16_t length); +static void ags_encode_ack(ags_ack_packet_t *ack_packet, uint8_t stream_id, uint8_t trxn_id, bool ack_flag); +static void ags_encode_header(void *header, uint8_t stream_id, uint8_t trxn_type, uint8_t payload_length, uint16_t trxn_length); static void ags_reset_stream(uint8_t stream_env_id, uint16_t total_length); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct ags_env_t s_ags_env; -static uint8_t s_gadget_tx_buffer[244]; -static uint8_t s_trxn_counter; -static uint8_t s_tx_sequ_num; +static struct ags_env_t s_ags_env; +static uint8_t s_gadget_tx_buffer[244]; +static uint8_t s_trxn_counter; +static uint8_t s_tx_sequ_num; static ags_stream_payload_t s_ags_stream_payload; +static const uint8_t s_ags_svc_uuid[] = {AGS_SERVICE_UUID}; /**@brief Full AGS Database Description - Used to add attributes into the database. */ -static const attm_desc_128_t ags_attr_tab[AGS_IDX_NB] = { +static const ble_gatts_attm_desc_128_t ags_attr_tab[AGS_IDX_NB] = +{ // Alexa Gadget Service Declaration - [AGS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [AGS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // AGS Tx Characteristic - Declaration - [AGS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [AGS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // AGS Tx Characteristic - Value - [AGS_IDX_TX_VAL] = { - AGS_TX_UUID, - WRITE_REQ_PERM(UNAUTH) | WRITE_CMD_PERM(UNAUTH), - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - AGS_TX_VAL_LEN_MAX - }, - + [AGS_IDX_TX_VAL] = {AGS_TX_UUID, + BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_UNAUTH), + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + AGS_TX_VAL_LEN_MAX}, + // AGS Tx Characteristic - Declaration - [AGS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [AGS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // AGS Tx Characteristic - Value - [AGS_IDX_RX_VAL] = { - AGS_RX_UUID, - NOTIFY_PERM(UNAUTH), - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - AGS_RX_VAL_LEN_MAX - }, + [AGS_IDX_RX_VAL] = {AGS_RX_UUID, + BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH), + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + AGS_RX_VAL_LEN_MAX}, // AGS Tx Characteristic - Client Characteristic Configuration Descriptor - [AGS_IDX_RX_NTF_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - 0, - 0 - }, -}; - -/**@brief AGS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t ags_task_cbs = { - (prf_init_func_t) ags_init, - NULL, - NULL, -}; - -/**@brief AGS Task Callbacks. */ -static gatts_prf_cbs_t ags_cb_func = { - ags_read_att_cb, - ags_write_att_cb, - NULL, - ags_ntf_ind_cb, - ags_cccd_set_cb -}; - -/**@brief AGS Information. */ -static const prf_server_info_t ags_prf_info = { - .max_connection_nb = AGS_CONNECTION_MAX, - .manager_cbs = &ags_task_cbs, - .gatts_prf_cbs = &ags_cb_func, + [AGS_IDX_RX_NTF_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Alexa Gadget service create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t ags_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t ags_svc_uuid[] = {AGS_SERVICE_UUID}; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = ags_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_ags_env.ags_init.char_mask); - gatts_db.max_nb_attr = AGS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = ags_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_ags_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -238,18 +167,19 @@ static sdk_err_t ags_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void ags_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void ags_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_ags_env.start_hdl, - AGS_IDX_NB, - (uint8_t *)&s_ags_env.ags_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_ags_env.start_hdl, + AGS_IDX_NB, + (uint8_t *)&s_ags_env.ags_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case AGS_IDX_RX_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_ags_env.rx_ntf_cfg[conn_idx]; @@ -272,13 +202,13 @@ static void ags_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void ags_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void ags_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t tab_index = 0; - uint16_t cccd_value = 0; - ags_evt_t event; - gatts_write_cfm_t cfm; + uint16_t handle = p_param->handle; + uint16_t tab_index = 0; + uint16_t cccd_value = 0; + ags_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_ags_env.start_hdl, @@ -288,18 +218,19 @@ static void ags_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par cfm.status = BLE_SUCCESS; event.evt_type = AGS_EVT_INVALID; event.conn_idx = conn_idx; - - switch (tab_index) { + + switch (tab_index) + { case AGS_IDX_TX_VAL: ags_echo_tx_val_decode(conn_idx, p_param->value, p_param->length); event.evt_type = AGS_EVT_ECHO_TX_DATA_RECEIVED; break; - + case AGS_IDX_RX_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - AGS_EVT_ECHO_RX_NOTI_ENABLE :\ - AGS_EVT_ECHO_RX_NOTI_DISABLE); + AGS_EVT_ECHO_RX_NOTI_ENABLE :\ + AGS_EVT_ECHO_RX_NOTI_DISABLE); s_ags_env.rx_ntf_cfg[conn_idx] = cccd_value; break; @@ -310,8 +241,8 @@ static void ags_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && - AGS_EVT_INVALID != event.evt_type && s_ags_env.ags_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && AGS_EVT_INVALID != event.evt_type && s_ags_env.ags_init.evt_handler) + { s_ags_env.ags_init.evt_handler(&event); } } @@ -325,12 +256,13 @@ static void ags_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void ags_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void ags_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; ags_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -342,11 +274,12 @@ static void ags_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = AGS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case AGS_IDX_RX_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - AGS_EVT_ECHO_RX_NOTI_ENABLE :\ - AGS_EVT_ECHO_RX_NOTI_DISABLE); + AGS_EVT_ECHO_RX_NOTI_ENABLE :\ + AGS_EVT_ECHO_RX_NOTI_DISABLE); s_ags_env.rx_ntf_cfg[conn_idx] = cccd_value; break; @@ -354,7 +287,8 @@ static void ags_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (AGS_EVT_INVALID != event.evt_type && s_ags_env.ags_init.evt_handler) { + if (AGS_EVT_INVALID != event.evt_type && s_ags_env.ags_init.evt_handler) + { s_ags_env.ags_init.evt_handler(&event); } } @@ -364,14 +298,16 @@ static void ags_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @brief Handles reception of the complete event. * * @param[in] conn_idx: Connection index. - * @param[in] status: The status of the complete event. + * @param[in] status: The status of the complete event. * @param[in] p_ntf_id: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void ags_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void ags_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_ags_env.ags_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (s_ags_env.ags_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { ags_echo_rx_val_chunk(conn_idx); } } @@ -410,43 +346,55 @@ static void ags_echo_tx_val_decode(uint8_t conn_idx, const uint8_t *p_data, uint uint16_t payload_length; uint16_t payload_offset; - if (p_data == NULL || (length < sizeof(ags_header_base_t))) { + if (NULL == p_data || (length < sizeof(ags_header_base_t))) + { APP_LOG_DEBUG("Unexcepted length: %d", length); return; } ags_header_base_t *p_header_base = (ags_header_base_t *)p_data; - for (uint8_t i = 0; i < ARRAY_SIZE(s_ags_env.ags_stream_env); i++) { - if (s_ags_env.ags_stream_env[i].stream_id == p_header_base->stream_id) { + for (uint8_t i=0; i < ARRAY_SIZE(s_ags_env.ags_stream_env); i++) + { + if (s_ags_env.ags_stream_env[i].stream_id == p_header_base->stream_id) + { stream_env_id = i; } } - if (s_ags_env.ags_stream_env[stream_env_id].is_active) { - if (p_header_base->length_ext) { + if (s_ags_env.ags_stream_env[stream_env_id].is_active) + { + if (p_header_base->length_ext) + { ags_header_subs_ext_t *p_header_subs_ext = (ags_header_subs_ext_t *)p_data; - + payload_length = be16toh(p_header_subs_ext->payload_length); payload_offset = sizeof(ags_header_subs_ext_t); - } else { + } + else + { ags_header_subs_t *p_header_subs = (ags_header_subs_t *)p_data; - + payload_length = p_header_subs->payload_length; payload_offset = sizeof(ags_header_subs_t); } - } else { + } + else + { uint16_t total_length; - if (p_header_base->length_ext) { + if (p_header_base->length_ext) + { ags_header_first_ext_t *p_header_first_ext = (ags_header_first_ext_t *)p_data; - + total_length = be16toh(p_header_first_ext->total_trxn_length); payload_length = be16toh(p_header_first_ext->payload_length); payload_offset = sizeof(ags_header_first_ext_t); - } else { + } + else + { ags_header_first_t *p_header_first = (ags_header_first_t *)p_data; - + total_length = be16toh(p_header_first->total_trxn_length); payload_length = p_header_first->payload_length; payload_offset = sizeof(ags_header_first_t); @@ -455,34 +403,37 @@ static void ags_echo_tx_val_decode(uint8_t conn_idx, const uint8_t *p_data, uint ags_reset_stream(stream_env_id, total_length); } - if (p_header_base->ack_flag) { + if (p_header_base->ack_flag) + { s_ags_env.ags_stream_env[stream_env_id].ack_flag = p_header_base->ack_flag; s_ags_env.ags_stream_env[stream_env_id].trxn_id = p_header_base->trxn_id; } s_ags_env.ags_stream_env[stream_env_id].received_length += payload_length; - if (s_ags_env.ags_stream_env[stream_env_id].received_length == \ - s_ags_env.ags_stream_env[stream_env_id].total_length) { + if (s_ags_env.ags_stream_env[stream_env_id].received_length == s_ags_env.ags_stream_env[stream_env_id].total_length) + { s_ags_env.ags_stream_env[stream_env_id].is_active = 0; - } else if (s_ags_env.ags_stream_env[stream_env_id].received_length > - s_ags_env.ags_stream_env[stream_env_id].total_length) { + } + else if (s_ags_env.ags_stream_env[stream_env_id].received_length > s_ags_env.ags_stream_env[stream_env_id].total_length) + { s_ags_env.ags_stream_env[stream_env_id].is_active = 0; - APP_LOG_DEBUG("Stream Overrun: %d %d.", s_ags_env.ags_stream_env[stream_env_id].received_length, - s_ags_env.ags_stream_env[stream_env_id].total_length); + APP_LOG_DEBUG("Stream Overrun: %d %d.", s_ags_env.ags_stream_env[stream_env_id].received_length, + s_ags_env.ags_stream_env[stream_env_id].total_length); } bool ack_flag = false; - switch (p_header_base->stream_id) { + switch (p_header_base->stream_id) + { case AGS_CONTROL_STREAM_ID: - ack_flag = s_ags_env.ags_init.ags_control_stream_cb(conn_idx, &((uint8_t *)p_data)[payload_offset], \ - payload_length, s_ags_env.ags_stream_env[stream_env_id].is_active); + ack_flag = s_ags_env.ags_init.ags_control_stream_cb(conn_idx, &((uint8_t *)p_data)[payload_offset], payload_length, \ + s_ags_env.ags_stream_env[stream_env_id].is_active); break; case AGS_ALEXA_STREAM_ID: - ack_flag = s_ags_env.ags_init.ags_alexa_stream_cb(conn_idx, &((uint8_t *)p_data)[payload_offset], \ - payload_length, s_ags_env.ags_stream_env[stream_env_id].is_active); + ack_flag = s_ags_env.ags_init.ags_alexa_stream_cb(conn_idx, &((uint8_t *)p_data)[payload_offset], payload_length, \ + s_ags_env.ags_stream_env[stream_env_id].is_active); break; default: @@ -498,7 +449,7 @@ static void ags_echo_tx_val_decode(uint8_t conn_idx, const uint8_t *p_data, uint /** ***************************************************************************************** * @brief Send ACK packet. - * If the Echo device request the ACK packet, the gadget must send the Echo device + * If the Echo device request the ACK packet, the gadget must send the Echo device * an ACK packet in response to the last packet of the transaction. * @param[in] conn_idx: Connection index. * @param[in] stream_env_id: The environment ID of gadget stream which is active. @@ -512,23 +463,24 @@ static sdk_err_t ags_stream_ack_send(uint8_t conn_idx, uint8_t stream_env_id, bo sdk_err_t error_code = SDK_SUCCESS; ags_evt_t ags_evt; - if (!s_ags_env.ags_stream_env[stream_env_id].is_active && (s_ags_env.ags_stream_env[stream_env_id].ack_flag)) { + if (!s_ags_env.ags_stream_env[stream_env_id].is_active && (s_ags_env.ags_stream_env[stream_env_id].ack_flag)) + { ags_ack_packet_t ack_packet; - + ags_encode_ack(&ack_packet, s_ags_env.ags_stream_env[stream_env_id].stream_id, \ s_ags_env.ags_stream_env[stream_env_id].trxn_id, ack_flag); - - gatts_noti_ind_t ags_rx_val_noti; - + + ble_gatts_noti_ind_t ags_rx_val_noti; + ags_rx_val_noti.type = BLE_GATT_NOTIFICATION; ags_rx_val_noti.handle = prf_find_handle_by_idx(AGS_IDX_RX_VAL, s_ags_env.start_hdl, (uint8_t *)&s_ags_env.ags_init.char_mask); ags_rx_val_noti.length = sizeof(ack_packet); ags_rx_val_noti.value = (uint8_t *)&ack_packet; - + error_code = ble_gatts_noti_ind(conn_idx, &ags_rx_val_noti); - + ags_evt.evt_type = AGS_EVT_ECHO_RX_DATA_SENT; ags_evt.conn_idx = conn_idx; ags_evt.p_data = (uint8_t *)&ack_packet; @@ -552,59 +504,65 @@ static sdk_err_t ags_echo_rx_val_chunk(uint8_t conn_idx) sdk_err_t error_code; ags_evt_t ags_evt; - if (s_ags_stream_payload.length) { + if (s_ags_stream_payload.length) + { uint8_t header_size = sizeof(ags_header_subs_t); uint16_t max_packet_size; uint16_t payload_size; uint8_t stream_id; uint8_t trxn_type; - gatts_noti_ind_t ags_rx_val_noti; - + ble_gatts_noti_ind_t ags_rx_val_noti; + ble_gatt_mtu_get(conn_idx, &max_packet_size); - max_packet_size -= MAX_PACKET_SIZE_OFFSET; - - if (max_packet_size < (header_size + s_ags_stream_payload.length)) { + max_packet_size -= 3; + + if (max_packet_size < (header_size + s_ags_stream_payload.length)) + { payload_size = max_packet_size - header_size; s_ags_stream_payload.length -= payload_size; - } else { + } + else + { payload_size = s_ags_stream_payload.length; s_ags_stream_payload.length = 0; } - + // Get stream ID from prededing transmit. stream_id = ((ags_header_base_t *)s_gadget_tx_buffer)->stream_id; - if (s_ags_stream_payload.length) { + if (s_ags_stream_payload.length) + { trxn_type = AGS_TRANSACTION_TYPE_CONT; - } else { + } + else + { trxn_type = AGS_TRANSACTION_TYPE_LAST; } - + ags_encode_header(&s_gadget_tx_buffer[0], stream_id, trxn_type, payload_size, 0); - error_code = memcpy_s(&s_gadget_tx_buffer[header_size], payload_size, - &s_ags_stream_payload.p_data[s_ags_stream_payload.offset], payload_size); + memcpy(&s_gadget_tx_buffer[header_size], &s_ags_stream_payload.p_data[s_ags_stream_payload.offset], payload_size); + s_ags_stream_payload.offset += payload_size; - + ags_rx_val_noti.type = BLE_GATT_NOTIFICATION; ags_rx_val_noti.handle = prf_find_handle_by_idx(AGS_IDX_RX_VAL, s_ags_env.start_hdl, (uint8_t *)&s_ags_env.ags_init.char_mask); ags_rx_val_noti.length = header_size + payload_size; ags_rx_val_noti.value = s_gadget_tx_buffer; - + error_code = ble_gatts_noti_ind(conn_idx, &ags_rx_val_noti); - } else { - error_code = memset_s(&s_ags_stream_payload, sizeof(ags_stream_payload_t), 0, sizeof(ags_stream_payload_t)); - if (error_code < 0) { - return error_code; - } + } + else + { + memset(&s_ags_stream_payload, 0, sizeof(ags_stream_payload_t)); s_ags_stream_payload.length = 0; s_ags_stream_payload.offset = 0; - + ags_evt.evt_type = AGS_EVT_ECHO_RX_DATA_SENT; ags_evt.conn_idx = conn_idx; ags_evt.p_data = s_ags_stream_payload.p_data; s_ags_env.ags_init.evt_handler(&ags_evt); - + error_code = SDK_SUCCESS; } return error_code; @@ -630,7 +588,7 @@ static void ags_encode_ack(ags_ack_packet_t *p_ack_packet, uint8_t stream_id, ui p_ack_packet->header_base.length_ext = AGS_LEN_EXT_NO_EXT; p_ack_packet->reserved_1 = AGS_HEADER_ACK_RES_1; p_ack_packet->payload_length = AGS_HEADER_ACK_PAYLOAD_LEN; - p_ack_packet->reserved_2 = AGS_HEADER_ACK_RES_2; + p_ack_packet->reserved_2 = AGS_HEADER_ACK_RES_2; p_ack_packet->result_code = ack_flag ? AGS_RES_CODE_SUCCESS : AGS_RES_CODE_UNSUPPORTED; } @@ -645,108 +603,130 @@ static void ags_encode_ack(ags_ack_packet_t *p_ack_packet, uint8_t stream_id, ui * @param[in] trxn_length: Total transaction length. ***************************************************************************************** */ -static void ags_encode_header(uint8_t *header, uint8_t stream_id, uint8_t trxn_type, uint8_t payload_length, - uint16_t trxn_length) +static void ags_encode_header(void *p_header, uint8_t stream_id, uint8_t trxn_type, uint8_t payload_length, uint16_t trxn_length) { - ags_header_base_t *p_header_base = header; - + ags_header_base_t *p_header_base = p_header; + p_header_base->stream_id = stream_id; p_header_base->sequ_num = s_tx_sequ_num++; p_header_base->trxn_type = trxn_type; p_header_base->ack_flag = AGS_ACK_NACK; p_header_base->length_ext = AGS_LEN_EXT_NO_EXT; - - if (AGS_TRANSACTION_TYPE_FIRST == trxn_type) { - ags_header_first_t *p_header_first = header; - + + if (AGS_TRANSACTION_TYPE_FIRST == trxn_type) + { + ags_header_first_t *p_header_first = p_header; + s_trxn_counter++; p_header_base->trxn_id = s_trxn_counter; p_header_first->reserved = AGS_HEADER_FIRST_RES; p_header_first->payload_length = payload_length; - + htobe16(&(p_header_first->total_trxn_length), trxn_length); - } else { - ags_header_subs_t *p_header_subs = header; - - p_header_base->trxn_id = s_trxn_counter; + } + else + { + ags_header_subs_t *p_header_subs = p_header; + + p_header_base->trxn_id = s_trxn_counter; p_header_subs->payload_length = payload_length; } } +static void ags_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + ags_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + ags_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + ags_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + ags_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ -sdk_err_t ags_stream_send(uint8_t conn_idx, uint8_t stream_id, uint8_t *p_data, uint16_t length) +sdk_err_t ags_stream_send(uint8_t conn_idx, uint8_t stream_id, void *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; uint16_t max_packet_size; uint16_t payload_size; uint16_t header_size; - gatts_noti_ind_t ags_rx_val_noti; - - error_code = memset_s(&s_ags_stream_payload, sizeof(s_ags_stream_payload), - 0, sizeof(s_ags_stream_payload)); - if (error_code < 0) { - return error_code; - } + ble_gatts_noti_ind_t ags_rx_val_noti; + + memset(&s_ags_stream_payload, 0, sizeof(s_ags_stream_payload)); s_tx_sequ_num = 0; s_ags_stream_payload.length = 0; - + ble_gatt_mtu_get(conn_idx, &max_packet_size); - max_packet_size -= MAX_PACKET_SIZE_OFFSET; - - error_code = memcpy_s(s_ags_stream_payload.p_data, length, (uint8_t *)p_data, length); - if (error_code < 0) { - return error_code; - } + max_packet_size -= 3; + memcpy(s_ags_stream_payload.p_data, (uint8_t *)p_data, length); + header_size = sizeof(ags_header_first_t); - - if (max_packet_size < (header_size + length)) { + + if (max_packet_size < (header_size + length)) + { s_ags_stream_payload.length = header_size + length - max_packet_size; - } else { + } + else + { s_ags_stream_payload.length = 0; } - + payload_size = length - s_ags_stream_payload.length; s_ags_stream_payload.offset = payload_size; - + ags_encode_header(&s_gadget_tx_buffer[0], stream_id, AGS_TRANSACTION_TYPE_FIRST, payload_size, length); - error_code = memcpy_s(&s_gadget_tx_buffer[header_size], payload_size, p_data, payload_size); - if (error_code < 0) { - return error_code; - } - + memcpy(&s_gadget_tx_buffer[header_size], p_data, payload_size); + ags_rx_val_noti.type = BLE_GATT_NOTIFICATION; ags_rx_val_noti.handle = prf_find_handle_by_idx(AGS_IDX_RX_VAL, s_ags_env.start_hdl, (uint8_t *)&s_ags_env.ags_init.char_mask); ags_rx_val_noti.length = header_size + payload_size; ags_rx_val_noti.value = s_gadget_tx_buffer; - + error_code = ble_gatts_noti_ind(conn_idx, &ags_rx_val_noti); return error_code; } -sdk_err_t ags_non_stream_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) +sdk_err_t ags_non_stream_send(uint8_t conn_idx, void *p_data, uint16_t length) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t ags_rx_val_noti; - ags_evt_t ags_evt; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t ags_rx_val_noti; + ags_evt_t ags_evt; ags_rx_val_noti.type = BLE_GATT_NOTIFICATION; ags_rx_val_noti.handle = prf_find_handle_by_idx(AGS_IDX_RX_VAL, s_ags_env.start_hdl, (uint8_t *)&s_ags_env.ags_init.char_mask); ags_rx_val_noti.length = length; - ags_rx_val_noti.value = (uint8_t *)p_data; - + ags_rx_val_noti.value = (uint8_t *)p_data; + error_code = ble_gatts_noti_ind(conn_idx, &ags_rx_val_noti); - + ags_evt.evt_type = AGS_EVT_ECHO_RX_DATA_SENT; ags_evt.conn_idx = conn_idx; - ags_evt.p_data = (uint8_t *)p_data; + ags_evt.p_data = (uint8_t *)p_data; ags_evt.length = length; s_ags_env.ags_init.evt_handler(&ags_evt); @@ -755,21 +735,27 @@ sdk_err_t ags_non_stream_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length sdk_err_t ags_service_init(ags_init_t *p_ags_init) { - sdk_err_t ret; - if (p_ags_init == NULL) { + if (NULL == p_ags_init) + { return SDK_ERR_POINTER_NULL; } + + s_ags_env.ags_stream_env[0].stream_id = AGS_CONTROL_STREAM_ID; + s_ags_env.ags_stream_env[0].is_active = false; + s_ags_env.ags_stream_env[1].stream_id = AGS_ALEXA_STREAM_ID; + s_ags_env.ags_stream_env[1].is_active = false; + s_ags_env.ags_stream_env[2].stream_id = AGS_OTA_STREAM_ID; + s_ags_env.ags_stream_env[2].is_active = false; - s_ags_env.ags_stream_env[INDEX_0].stream_id = AGS_CONTROL_STREAM_ID; - s_ags_env.ags_stream_env[INDEX_0].is_active = false; - s_ags_env.ags_stream_env[INDEX_1].stream_id = AGS_ALEXA_STREAM_ID; - s_ags_env.ags_stream_env[INDEX_1].is_active = false; - s_ags_env.ags_stream_env[INDEX_2].stream_id = AGS_OTA_STREAM_ID; - s_ags_env.ags_stream_env[INDEX_2].is_active = false; + memcpy(&s_ags_env.ags_init, p_ags_init, sizeof(ags_init_t)); - ret = memcpy_s(&s_ags_env.ags_init, sizeof(ags_init_t), p_ags_init, sizeof(ags_init_t)); - if (ret < 0) { - return ret; - } - return ble_server_prf_add(&ags_prf_info); + s_ags_env.ags_gatts_db.shdl = &s_ags_env.start_hdl; + s_ags_env.ags_gatts_db.uuid = s_ags_svc_uuid; + s_ags_env.ags_gatts_db.attr_tab_cfg = (uint8_t *)&(s_ags_env.ags_init.char_mask); + s_ags_env.ags_gatts_db.max_nb_attr = AGS_IDX_NB; + s_ags_env.ags_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_ags_env.ags_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_ags_env.ags_gatts_db.attr_tab.attr_tab_128 = ags_attr_tab; + + return ble_gatts_prf_add(&s_ags_env.ags_gatts_db, ags_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.h index feed9ac..4de22d3 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ags/ags.h @@ -46,7 +46,7 @@ * @{ * @brief Definitions and prototypes for the AGS interface. * - * @details The Alexa Gadget (AG) Service is defined by Amazon. It can connect a Alexa gadget with an Echo + * @details The Alexa Gadget (AG) Service is defined by Amazon. It can connect a Alexa gadget with an Echo * device. This module implements the Alexa Gadget Service with TX and RX characteristics. * * After \ref ags_init_t variable is initialized, the application must call \ref ags_service_init() @@ -57,27 +57,26 @@ #ifndef __AGS_H__ #define __AGS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup AGS_MACRO Defines * @{ */ -/**< The UUID of Alexa Gadget Service for setting advertising data. */ -#define AGS_SERVICE_UUID 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, \ - 0x03, 0xFE, 0x00, 0x00 +#define AGS_SERVICE_UUID 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,\ + 0x00, 0x10, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00 /**< The UUID of Alexa Gadget Service for setting advertising data. */ -#define AGS_HEADER_FIRST_RES 0x00 /**< Reserved value of header in the first packet. */ +#define AGS_HEADER_FIRST_RES 0x00 /**< Reserved value of header in the first packet. */ -#define AGS_HEADER_ACK_RES_1 0x00 /**< The first reserved value of header in the ACK packet. */ -#define AGS_HEADER_ACK_PAYLOAD_LEN 0x02 /**< Length of the ACK packet, in bytes. */ -#define AGS_HEADER_ACK_RES_2 0x01 /**< The second reserved value of header in the ACK packet. */ +#define AGS_HEADER_ACK_RES_1 0x00 /**< The first reserved value of header in the ACK packet. */ +#define AGS_HEADER_ACK_PAYLOAD_LEN 0x02 /**< Length of the ACK packet, in bytes. */ +#define AGS_HEADER_ACK_RES_2 0x01 /**< The second reserved value of header in the ACK packet. */ -#define AGS_TX_VAL_LEN_MAX 244 /**< Maximum length of TX Characteristic value. */ -#define AGS_RX_VAL_LEN_MAX 244 /**< Maximum length of RX Characteristic value. */ +#define AGS_TX_VAL_LEN_MAX 244 /**< Maximum length of TX Characteristic value. */ +#define AGS_RX_VAL_LEN_MAX 244 /**< Maximum length of RX Characteristic value. */ /** * @defgroup AGS_ADV_TYPE Advertising type @@ -91,8 +90,7 @@ #define AGS_RECONNECT_ADV_FLAG 0x00 /**< The reconnecting advertisiment flag. */ /** @} */ -#define AGS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of AGS connections. */ +#define AGS_CONNECTION_MAX 10 /**< Maximum number of AGS connections. */ /** * @defgroup AGS_CHAR_MASK Characteristics Mask @@ -108,62 +106,67 @@ * @defgroup AGS_ENUM Enumerations * @{ */ -/**@brief Alexa Gadget Service Stream ID. +/**@brief Alexa Gadget Service Stream ID. * At any time, there is only one control stream, one Alexa stream, and one OTA stream. * Each packet belongs to one of these streams, which is specified in the stream ID field of the packet's header. * See Gadgets documentation for details: * https://developer.amazon.com/en-US/docs/alexa/alexa-gadgets-toolkit/packet-ble.html#streams */ -typedef enum { +typedef enum +{ AGS_CONTROL_STREAM_ID, /**< Control stream ID, used to communicate. */ AGS_ALEXA_STREAM_ID = 0x06, /**< Alexa stream ID, used to send directives and events. */ AGS_OTA_STREAM_ID = 0x02, /**< OTA stream ID, used to update the gadget's firmware. */ } ags_header_stream_id_t; -/**@brief Alexa Gadget Service transaction type. +/**@brief Alexa Gadget Service transaction type. * It indicate where the packet is within the transaction. The transaction type and * protocol of a single transaction are defined by the first packet of the transaction. */ -typedef enum { - AGS_TRANSACTION_TYPE_FIRST, /**< First packet of a transaction, - or the only packet in a single-packet transaction. */ +typedef enum +{ + AGS_TRANSACTION_TYPE_FIRST, /**< First packet of a transaction, or the only packet in a single-packet transaction. */ AGS_TRANSACTION_TYPE_CONT, /**< Continuation packet of a transaction. */ AGS_TRANSACTION_TYPE_LAST, /**< Last packet of a transaction. */ - AGS_TRANSACTION_TYPE_CTRL, /**< Control packet. Currently, \ - the only type of control packet is the ACK packet. */ + AGS_TRANSACTION_TYPE_CTRL, /**< Control packet. Currently, the only type of control packet is the ACK packet. */ } ags_header_trxn_type_t; /**@brief Alexa Gadget Service ACK Flag. */ -typedef enum { - AGS_ACK_NACK, /**< The gadget doesn't need to send an ACK packet in response to the last packet of the +typedef enum +{ + AGS_ACK_NACK, /**< The gadget doesn't need to send an ACK packet in response to the last packet of the transaction unless another packet in the transaction has this bit set to 1. */ AGS_ACK_ACK, /**< The gadget must send an ACK packet in response to the last packet of the transaction. */ } ags_header_ack_flag_t; /**@brief Alexa Gadget Service Length extender. */ -typedef enum { +typedef enum +{ AGS_LEN_EXT_NO_EXT, /**< The packet's payload is 8 bits. */ AGS_LEN_EXT_EXT, /**< The packet's payload is 16 bits. */ + } ags_header_length_ext_t; /**@brief Alexa Gadget Service result code. */ -typedef enum { +typedef enum +{ AGS_RES_CODE_SUCCESS, /**< The message was valid and acted on (if applicable) successfully. */ AGS_RES_CODE_UNKNOWN, /**< The message was valid but rusulted in a failure or error. */ AGS_RES_CODE_UNSUPPORTED = 0x03, /**< The message was invalid because it contained a command or other field that - was not supported by the receiver. */ + was not supported by the receiver. */ } ags_header_result_code_t; /**@brief Alexa Gadget Service event type.*/ -typedef enum { - AGS_EVT_INVALID, /**< Indicate that invalid event. */ - AGS_EVT_ECHO_RX_DATA_SENT, /**< Indicate that the gadget has been sent the data to an Echo device. */ - AGS_EVT_ECHO_TX_DATA_RECEIVED, /**< Indicate that the gadget has been received the data from an Echo device. */ - AGS_EVT_ECHO_RX_NOTI_ENABLE, /**< Indicate that the Rx notification has been enabled. */ - AGS_EVT_ECHO_RX_NOTI_DISABLE, /**< Indicate that the Rx notification has been disabled. */ +typedef enum +{ + AGS_EVT_INVALID, /**< Indicate that invalid event. */ + AGS_EVT_ECHO_RX_DATA_SENT, /**< Indicate that the gadget has been sent the data to an Echo device. */ + AGS_EVT_ECHO_TX_DATA_RECEIVED, /**< Indicate that the gadget has been received the data from an Echo device. */ + AGS_EVT_ECHO_RX_NOTI_ENABLE, /**< Indicate that the Rx notification has been enabled. */ + AGS_EVT_ECHO_RX_NOTI_DISABLE, /**< Indicate that the Rx notification has been disabled. */ } ags_evt_type_t; /** @} */ @@ -172,60 +175,63 @@ typedef enum { * @{ */ /**@brief Alexa Gadget Service base part of data packet header. */ -typedef struct { - uint8_t trxn_id : 4; /**< The transaction ID. */ - uint8_t stream_id : 4; /**< The stream ID. @ref ags_header_stream_id_t */ - uint8_t length_ext : 1; /**< Length extender. It indicates the length of the payload field. \ - @ref ags_header_length_ext_t */ - uint8_t ack_flag : 1; /**< Acknowledgement(ACK) flag. @ref ags_header_ack_flag_t */ - uint8_t trxn_type : 2; /**< Transaction type. @ref ags_header_trxn_type_t */ - uint8_t sequ_num : 4; /**< Sequence number. Since this is four bits long, it supports - inplace sequencing of up to 16 packet at a given point in time. - Sequence numbers can rool over. */ +typedef struct +{ + uint8_t trxn_id :4; /**< The transaction ID. */ + uint8_t stream_id :4; /**< The stream ID. @ref ags_header_stream_id_t */ + uint8_t length_ext :1; /**< Length extender. It indicates the length of the payload field. @ref ags_header_length_ext_t */ + uint8_t ack_flag :1; /**< Acknowledgement(ACK) flag. @ref ags_header_ack_flag_t */ + uint8_t trxn_type :2; /**< Transaction type. @ref ags_header_trxn_type_t */ + uint8_t sequ_num :4; /**< Sequence number. Since this is four bits long, it supports + inplace sequencing of up to 16 packet at a given point in time. + Sequence numbers can rool over.*/ } ags_header_base_t; /**@brief Alexa Gadget Service header in first packet. */ -typedef struct { - ags_header_base_t header_base; /**< Header base. */ - uint8_t reserved; /**< Reserved. This is only present in the first packet of the transaction. */ - uint8_t - total_trxn_length[2]; /**< Total transaction length. This is only present in the first packet of the transaction. */ - uint8_t payload_length; /**< Payload Length. */ +typedef struct +{ + ags_header_base_t header_base; /**< Header base. */ + uint8_t reserved; /**< Reserved. This is only present in the first packet of the transaction. */ + uint8_t total_trxn_length[2]; /**< Total transaction length. This is only present in the first packet of the transaction. */ + uint8_t payload_length; /**< Payload Length. */ } ags_header_first_t; /**@brief Alexa Gadget Service extended version of header in first packet. */ -typedef struct { - ags_header_base_t header_base; /**< Header base. */ - uint8_t reserved; /**< Reserved. This is only present in the first packet of the transaction. */ - uint8_t - total_trxn_length[2]; /**< Total transaction length. This is only present in the first packet of the transaction. */ +typedef struct +{ + ags_header_base_t header_base; /**< Header base. */ + uint8_t reserved; /**< Reserved. This is only present in the first packet of the transaction. */ + uint8_t total_trxn_length[2]; /**< Total transaction length. This is only present in the first packet of the transaction. */ uint8_t payload_length[2]; /**< Payload Length. */ } ags_header_first_ext_t; /**@brief Alexa Gadget Service header in subsequent packets. */ -typedef struct { +typedef struct +{ ags_header_base_t header_base; /**< Header base. */ uint8_t payload_length; /**< Payload Length. */ } ags_header_subs_t; /**@brief Alexa Gadget Service extended version of header in subsequent packets. */ -typedef struct { +typedef struct +{ ags_header_base_t header_base; /**< Header base. */ uint8_t payload_length[2]; /**< Payload Length. */ } ags_header_subs_ext_t; /**@brief Alexa Gadget Service ACK packet. */ -typedef struct { +typedef struct +{ ags_header_base_t header_base; /**< Header base. */ uint8_t reserved_1; /**< Reserved. */ uint8_t payload_length; /**< Length of the ACK packet. */ uint8_t reserved_2; /**< Reserved. */ - uint8_t - result_code; /**< A result code, which depends on whether this is an ACK or a NACK. @ref ags_header_ack_flag_t */ + uint8_t result_code; /**< A result code, which depends on whether this is an ACK or a NACK. @ref ags_header_ack_flag_t */ } ags_ack_packet_t; /**@brief Alexa Gadget Service gadget stream enviorenment variable. */ -typedef struct { +typedef struct +{ ags_header_stream_id_t stream_id; /**< The stream ID. */ uint8_t is_active; /**< Whether the stream is active. */ uint8_t ack_flag; /**< Whether need to return ACK packet. */ @@ -235,7 +241,8 @@ typedef struct { } ags_stream_env_t; /**@brief Alexa Gadget Service event. */ -typedef struct { +typedef struct +{ ags_evt_type_t evt_type; /**< The AGS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -251,22 +258,20 @@ typedef struct { typedef void (*ags_evt_handler_t)(ags_evt_t *p_evt); /**@brief Alexa Gadget Service stream callback.*/ -typedef bool (*ags_stream_cb_t)(uint8_t conn_idx, const uint8_t *const p_data, uint16_t length, - uint8_t still_receiving); +typedef bool (*ags_stream_cb_t)(uint8_t conn_idx, const uint8_t *const p_data, uint16_t length, uint8_t still_receiving); /** @} */ /** * @defgroup AGS_STRUCT Structures * @{ */ -/**@brief Alexa Gadget Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Alexa Gadget Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ ags_evt_handler_t evt_handler; /**< Alexa Gadget Service event handler. */ ags_stream_cb_t ags_control_stream_cb; /**< Callback for incoming control streams. */ - ags_stream_cb_t ags_alexa_stream_cb; /**< Callback for incoming Alexa streams. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref AGS_CHAR_MASK. */ + ags_stream_cb_t ags_alexa_stream_cb; /**< Callback for incoming Alexa streams. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref AGS_CHAR_MASK. */ } ags_init_t; /** @} */ @@ -297,7 +302,7 @@ sdk_err_t ags_service_init(ags_init_t *p_ags_init); * @return Result of sending data. ***************************************************************************************** */ -sdk_err_t ags_stream_send(uint8_t conn_idx, uint8_t stream_id, uint8_t *p_data, uint16_t length); +sdk_err_t ags_stream_send(uint8_t conn_idx, uint8_t stream_id, void *p_data, uint16_t length); /** ***************************************************************************************** @@ -310,7 +315,7 @@ sdk_err_t ags_stream_send(uint8_t conn_idx, uint8_t stream_id, uint8_t *p_data, * @return Result of sending data. ***************************************************************************************** */ -sdk_err_t ags_non_stream_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); +sdk_err_t ags_non_stream_send(uint8_t conn_idx, void *p_data, uint16_t length); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/BUILD.gn new file mode 100644 index 0000000..f3a5595 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ams_c") { + sources = [ "ams_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.c index 0775e5f..3a0aa17 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.c @@ -40,13 +40,7 @@ **************************************************************************************** */ #include "ams_c.h" -#define ATTR_VALUE_LEN 2 -#define INDEX_0 0 -#define INDEX_1 1 -#define INDEX_2 2 -#define INDEX_3 3 -#define LEN_3 3 -#define OFFSET_2 2 + /* * STRUCT DEFINE ***************************************************************************************** @@ -57,58 +51,26 @@ static const uint8_t ams_cmd_uuid[] = {AMS_CMD_UUID}; static const uint8_t ams_attr_update_uuid[] = {AMS_ATTR_UPDATE_UUID}; static const uint8_t ams_attr_display_uuid[] = {AMS_ATTR_DISPLAY_UUID}; +static ble_uuid_t s_ams_service_uuid = +{ + .uuid_len = BLE_ATT_UUID_128_LEN, + .uuid = (uint8_t *)ams_service_uuid, +}; + /**@brief Apple Media Service Client environment variable. */ -struct ams_c_env_t { +struct ams_c_env_t +{ ams_c_handles_t handles; /**< Handles of AMS characteristics which will be got for peer. */ ams_c_evt_handler_t evt_handler; /**< Handler of AMS Client event handler. */ - uint8_t prf_id; /**< AMS Client profile id. */ uint16_t cmd_enable_flag; /**< The flag bits of the available status for the commands. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void ams_c_att_read_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_read_rsp_t *p_read_rsp); -static void ams_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void ams_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void ams_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct ams_c_env_t s_ams_c_env; /**< Apple Media Service Client environment variable. */ -/**@brief Apple Media Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t ams_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Apple Media Service GATT Client Callbacks. */ -static gattc_prf_cbs_t ams_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - ams_c_att_read_cb, - ams_c_att_write_cb, - ams_c_att_ntf_ind_cb, - ams_c_srvc_browse_cb, - NULL, -}; - -/**@brief Apple Media Service Client Information. */ -static const prf_client_info_t ams_c_prf_info = { - .max_connection_nb = AMS_C_CONNECTION_MAX, - .manager_cbs = &ams_c_mgr_cbs, - .gattc_prf_cbs = &ams_c_gattc_cbs -}; - /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -122,7 +84,8 @@ static const prf_client_info_t ams_c_prf_info = { */ static void ams_c_evt_handler_excute(ams_c_evt_t *p_evt) { - if (s_ams_c_env.evt_handler != NULL && AMS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_ams_c_env.evt_handler && AMS_C_EVT_INVALID != p_evt->evt_type) + { s_ams_c_env.evt_handler(p_evt); } } @@ -139,11 +102,11 @@ static void ams_c_evt_handler_excute(ams_c_evt_t *p_evt) static void ams_c_attr_info_decode(uint8_t *p_data, uint16_t length, ams_c_attr_info_t *p_attr_info) { - p_attr_info->ett_id = (ams_c_ett_id_t)(p_data[INDEX_0]); - p_attr_info->attr_id = p_data[INDEX_1]; - p_attr_info->flag = p_data[INDEX_2]; - p_attr_info->p_data = &(p_data[INDEX_3]); - p_attr_info->length = length - LEN_3; + p_attr_info->ett_id = (ams_c_ett_id_t)(p_data[0]); + p_attr_info->attr_id = p_data[1]; + p_attr_info->flag = p_data[2]; + p_attr_info->p_data = &(p_data[3]); + p_attr_info->length = length - 3; } /** @@ -155,23 +118,24 @@ static void ams_c_attr_info_decode(uint8_t *p_data, uint16_t length, * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void ams_c_att_read_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_read_rsp_t *p_read_rsp) +static void ams_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { ams_c_evt_t ams_c_evt; ams_c_evt.conn_idx = conn_idx; ams_c_evt.evt_type = AMS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_ams_c_env.handles.ams_attr_display_handle) { + if (p_read_rsp->value[0].handle == s_ams_c_env.handles.ams_attr_display_handle) + { ams_c_evt.conn_idx = conn_idx; ams_c_evt.evt_type = AMS_C_EVT_CPLT_ATTR_READ_RSP; - ams_c_evt.param.cplt_attr_data.p_data = p_read_rsp->vals[0].p_value; - ams_c_evt.param.cplt_attr_data.length = p_read_rsp->vals[0].length; + ams_c_evt.param.cplt_attr_data.p_data = p_read_rsp->value[0].p_value; + ams_c_evt.param.cplt_attr_data.length = p_read_rsp->value[0].length; } ams_c_evt_handler_excute(&ams_c_evt); @@ -186,33 +150,42 @@ static void ams_c_att_read_cb(uint8_t conn_idx, uint8_t status, * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void ams_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void ams_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { ams_c_evt_t ams_c_evt; ams_c_evt.conn_idx = conn_idx; ams_c_evt.evt_type = AMS_C_EVT_INVALID; - if (handle == s_ams_c_env.handles.ams_cmd_handle) { + if (handle == s_ams_c_env.handles.ams_cmd_handle) + { ams_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - AMS_C_EVT_CMD_SEND_SUCCESS : - AMS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ams_c_env.handles.ams_cmd_cccd_handle) { + AMS_C_EVT_CMD_SEND_SUCCESS : + AMS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ams_c_env.handles.ams_cmd_cccd_handle) + { ams_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - AMS_C_EVT_CMD_UPDATE_NTF_SET_SUCCESS : - AMS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ams_c_env.handles.ams_attr_update_handle) { + AMS_C_EVT_CMD_UPDATE_NTF_SET_SUCCESS : + AMS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ams_c_env.handles.ams_attr_update_handle) + { ams_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - AMS_C_EVT_ATTR_FOCUS_SET_SUCCESS : - AMS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ams_c_env.handles.ams_attr_update_cccd_handle) { + AMS_C_EVT_ATTR_FOCUS_SET_SUCCESS : + AMS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ams_c_env.handles.ams_attr_update_cccd_handle) + { ams_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - AMS_C_EVT_ATTR_UPDATE_NTF_SET_SUCCESS : - AMS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ams_c_env.handles.ams_attr_display_handle) { + AMS_C_EVT_ATTR_UPDATE_NTF_SET_SUCCESS : + AMS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ams_c_env.handles.ams_attr_display_handle) + { ams_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - AMS_C_EVT_CPLT_ATTR_DISPLAY_SET_SUCCESS : - AMS_C_EVT_WRITE_OP_ERR; + AMS_C_EVT_CPLT_ATTR_DISPLAY_SET_SUCCESS : + AMS_C_EVT_WRITE_OP_ERR; } ams_c_evt_handler_excute(&ams_c_evt); @@ -227,27 +200,31 @@ static void ams_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void ams_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void ams_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { ams_c_evt_t ams_c_evt; ams_c_evt.conn_idx = conn_idx; ams_c_evt.evt_type = AMS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_ams_c_env.handles.ams_cmd_handle) { + if (p_ntf_ind->handle == s_ams_c_env.handles.ams_cmd_handle) + { ams_c_evt.evt_type = AMS_C_EVT_CMD_UPDATE_RECEIVE; - + ams_c_evt.param.cmd_list.p_cmd = (ams_c_cmd_id_t *)(p_ntf_ind->p_value); ams_c_evt.param.cmd_list.length = p_ntf_ind->length; - + s_ams_c_env.cmd_enable_flag = 0; - for (uint16_t i = 0; i < p_ntf_ind->length; i++) { + for (uint16_t i = 0; i < p_ntf_ind->length; i++) + { s_ams_c_env.cmd_enable_flag |= (0x01 << p_ntf_ind->p_value[i]); } - } else if (p_ntf_ind->handle == s_ams_c_env.handles.ams_attr_update_handle) { + } + else if (p_ntf_ind->handle == s_ams_c_env.handles.ams_attr_update_handle) + { ams_c_evt.evt_type = AMS_C_EVT_ATTR_UPDATE_RECEIVE; - ams_c_attr_info_decode(p_ntf_ind->p_value, p_ntf_ind->length, - &ams_c_evt.param.attr_info); + ams_c_attr_info_decode(p_ntf_ind->p_value, p_ntf_ind->length, + &ams_c_evt.param.attr_info); } ams_c_evt_handler_excute(&ams_c_evt); @@ -262,8 +239,8 @@ static void ams_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ ***************************************************************************************** */ -static void ams_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_browse_srvc_t *p_browse_srvc) +static void ams_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, + const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { ams_c_evt_t ams_c_evt; uint16_t handle_disc; @@ -271,161 +248,173 @@ static void ams_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, ams_c_evt.conn_idx = conn_idx; ams_c_evt.evt_type = AMS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - - if (memcmp(p_browse_srvc->uuid, ams_service_uuid, BLE_ATT_UUID_128_LEN) != 0) { - return; - } - s_ams_c_env.handles.ams_srvc_start_handle = p_browse_srvc->start_hdl; - s_ams_c_env.handles.ams_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_SUCCESS == status) + { + if (0 == memcmp(p_browse_srvc->uuid, ams_service_uuid, BLE_ATT_UUID_128_LEN)) + { + s_ams_c_env.handles.ams_srvc_start_handle = p_browse_srvc->start_hdl; + s_ams_c_env.handles.ams_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) { - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) + { + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, ams_cmd_uuid, - BLE_ATT_UUID_128_LEN)) { - s_ams_c_env.handles.ams_cmd_handle = handle_disc; - s_ams_c_env.handles.ams_cmd_cccd_handle = handle_disc + OFFSET_2; - } else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, - ams_attr_update_uuid, BLE_ATT_UUID_128_LEN)) { - s_ams_c_env.handles.ams_attr_update_handle = handle_disc; - s_ams_c_env.handles.ams_attr_update_cccd_handle = handle_disc + OFFSET_2; - } else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, - ams_attr_display_uuid, BLE_ATT_UUID_128_LEN)) { - s_ams_c_env.handles.ams_attr_display_handle = handle_disc; + if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, ams_cmd_uuid, + BLE_ATT_UUID_128_LEN)) + { + s_ams_c_env.handles.ams_cmd_handle = handle_disc; + s_ams_c_env.handles.ams_cmd_cccd_handle = handle_disc + 2; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, + ams_attr_update_uuid, BLE_ATT_UUID_128_LEN)) + { + s_ams_c_env.handles.ams_attr_update_handle = handle_disc; + s_ams_c_env.handles.ams_attr_update_cccd_handle = handle_disc + 2; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, + ams_attr_display_uuid, BLE_ATT_UUID_128_LEN)) + { + s_ams_c_env.handles.ams_attr_display_handle = handle_disc; + } + } + + else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; + } } - } else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; + ams_c_evt.evt_type = AMS_C_EVT_DISCOVERY_CPLT; } } - ams_c_evt.evt_type = AMS_C_EVT_DISCOVERY_CPLT; ams_c_evt_handler_excute(&ams_c_evt); } +static void ams_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + ams_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + ams_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + ams_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + ams_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ams_c_client_init(ams_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_ams_c_env, sizeof(s_ams_c_env), 0, sizeof(s_ams_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_ams_c_env, 0, sizeof(s_ams_c_env)); s_ams_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&ams_c_prf_info, &s_ams_c_env.prf_id); + return ble_gattc_prf_add(&s_ams_service_uuid, ams_c_ble_evt_handler); } sdk_err_t ams_c_disc_srvc_start(uint8_t conn_idx) { - ble_uuid_t ble_ams_uuid = { - .uuid_len = BLE_ATT_UUID_128_LEN, - .uuid = (uint8_t *)ams_service_uuid, - }; - return ble_gattc_prf_services_browse(s_ams_c_env.prf_id, conn_idx, &ble_ams_uuid); + return ble_gattc_services_browse(conn_idx, &s_ams_service_uuid); } sdk_err_t ams_c_cmd_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_cmd_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_cmd_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ams_c_env.handles.ams_cmd_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - return ble_gattc_prf_write(s_ams_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ams_c_env.handles.ams_cmd_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ams_c_attr_update_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_update_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_update_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ams_c_env.handles.ams_attr_update_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - return ble_gattc_prf_write(s_ams_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ams_c_env.handles.ams_attr_update_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ams_c_cplt_attr_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_display_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_display_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_ams_c_env.prf_id, conn_idx, + return ble_gattc_read(conn_idx, s_ams_c_env.handles.ams_attr_display_handle, 0); } sdk_err_t ams_c_cmd_send(uint8_t conn_idx, uint8_t cmd_id) { - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_cmd_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_cmd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - gattc_write_attr_value_t write_attr_value; - write_attr_value.handle = s_ams_c_env.handles.ams_cmd_handle; - write_attr_value.offset = 0; - write_attr_value.length = 1; - write_attr_value.p_value = (uint8_t *)& cmd_id; - return ble_gattc_prf_write(s_ams_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ams_c_env.handles.ams_cmd_handle, 0, 1, (uint8_t *)& cmd_id); } sdk_err_t ams_c_attr_focus_set(uint8_t conn_idx, const ams_c_ett_attr_id_t *p_ett_attr_id) { - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_update_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_update_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - gattc_write_attr_value_t write_attr_value; - write_attr_value.handle = s_ams_c_env.handles.ams_attr_update_handle; - write_attr_value.offset = 0; - write_attr_value.length = p_ett_attr_id->attr_count + 1; - write_attr_value.p_value = (uint8_t *)&(p_ett_attr_id->ett_id); - return ble_gattc_prf_write(s_ams_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ams_c_env.handles.ams_attr_update_handle, + 0, p_ett_attr_id->attr_count + 1, (uint8_t *)&(p_ett_attr_id->ett_id)); } sdk_err_t ams_c_attr_display_set(uint8_t conn_idx, const ams_c_attr_info_t *p_attr_info) { - if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_display_handle) { + if (BLE_ATT_INVALID_HDL == s_ams_c_env.handles.ams_attr_display_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - - gattc_write_attr_value_t write_attr_value; - write_attr_value.handle = s_ams_c_env.handles.ams_attr_display_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&(p_attr_info->ett_id); - - return ble_gattc_prf_write(s_ams_c_env.prf_id, conn_idx, &write_attr_value); + + return ble_gattc_write(conn_idx, s_ams_c_env.handles.ams_attr_display_handle, 0, 2, (uint8_t *)&(p_attr_info->ett_id)); } bool ams_c_cmd_enable_check(ams_c_cmd_id_t cmd_id) { - if ((0x01 << cmd_id) & s_ams_c_env.cmd_enable_flag) { + if ((0x01 << cmd_id) & s_ams_c_env.cmd_enable_flag) + { return true; } return false; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.h index 2e97a5f..10b0e23 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ams_c/ams_c.h @@ -1,7 +1,7 @@ /** **************************************************************************************** * - * @file AMS_c.h + * @file ams_c.h * * @brief Apple Media Service Client API. * @@ -47,19 +47,17 @@ * @details The Apple Media Service Client contains the APIs and types, which can be used * by the application to discover Apple Media Service of peer and interact with it. * - * The application must provide an event handler to be registered, - * then call \ref ams_c_client_init() to initialize the client. + * The application must provide an event handler to be registered, then call \ref ams_c_client_init() to initialize the client. * After the application discovers peer Apple Media Service by calling \ref ams_c_disc_srvc_start(), * application can call \ref ams_c_cmd_send() to send romote command to peer and \ref ams_c_attr_focus_set to - * set the attribute focus. + * set the attribute focus. * * Secondly, use \ref ams_c_cmd_notify_set() and \ref ams_c_attr_update_notify_set() to enable the notification * for CMD update and attribute update. * * When the available CMDs or concerned attributes change, the module will receive notification from peer * if notifications of them are enabled. If the notification containing the information of changed attribute - * is truncated, application can call \ref ams_c_attr_display_set to set the attribute - * that needs to be completely + * is truncated, application can call \ref ams_c_attr_display_set to set the attribute that needs to be completely * displayed and \ref ams_c_cplt_attr_read to get the completely information of the attribute. */ @@ -67,7 +65,7 @@ #ifndef __AMS_C_H__ #define __AMS_C_H__ -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" @@ -75,18 +73,17 @@ * @defgroup AMS_C_MACRO Defines * @{ */ -#define AMS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections.*/ -#define AMS_C_ATTR_COUNT_MAX 256 /**< The buffer size of command.*/ -#define AMS_C_TRUNCATED_FLAG (0x01<<0) /**< Bit of truncated.*/ -#define AMS_SRVC_UUID 0xdc, 0xf8, 0x55, 0xad, 0x02, 0xc5, 0xf4, 0x8e, \ - 0x3a, 0x43, 0x36, 0x0f, 0x2b, 0x50, 0xd3, 0x89 /**< UUID of Apple media service.*/ -#define AMS_CMD_UUID 0xc2, 0x51, 0xca, 0xf7, 0x56, 0x0e, 0xdf, 0xb8, \ - 0x8a, 0x4a, 0xb1, 0x57, 0xd8, 0x81, 0x3c, 0x9b /**< UUID of remote command.*/ -#define AMS_ATTR_UPDATE_UUID 0x02, 0xC1, 0x96, 0xBA, 0x92, 0xBB, 0x0C, 0x9A, \ - 0x1F, 0x41, 0x8D, 0x80, 0xCE, 0xAB, 0x7C, 0x2F /**< UUID of attribute update.*/ -#define AMS_ATTR_DISPLAY_UUID 0xd7, 0xd5, 0xbb, 0x70, 0xa8, 0xa3, 0xab, 0xa6, \ - 0xd8, 0x46, 0xab, 0x23, 0x8c, 0xf3, 0xb2, 0xc6 /**< UUID of attribute display.*/ +#define AMS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ +#define AMS_C_ATTR_COUNT_MAX 256 /**< The buffer size of command. */ +#define AMS_C_TRUNCATED_FLAG (0x01<<0) /**< Bit of truncated. */ +#define AMS_SRVC_UUID 0xdc, 0xf8, 0x55, 0xad, 0x02, 0xc5, 0xf4, 0x8e,\ + 0x3a, 0x43, 0x36, 0x0f, 0x2b, 0x50, 0xd3, 0x89 /**< UUID of Apple media service. */ +#define AMS_CMD_UUID 0xc2, 0x51, 0xca, 0xf7, 0x56, 0x0e, 0xdf, 0xb8,\ + 0x8a, 0x4a, 0xb1, 0x57, 0xd8, 0x81, 0x3c, 0x9b /**< UUID of remote command. */ +#define AMS_ATTR_UPDATE_UUID 0x02, 0xC1, 0x96, 0xBA, 0x92, 0xBB, 0x0C, 0x9A,\ + 0x1F, 0x41, 0x8D, 0x80, 0xCE, 0xAB, 0x7C, 0x2F /**< UUID of attribute update. */ +#define AMS_ATTR_DISPLAY_UUID 0xd7, 0xd5, 0xbb, 0x70, 0xa8, 0xa3, 0xab, 0xa6,\ + 0xd8, 0x46, 0xab, 0x23, 0x8c, 0xf3, 0xb2, 0xc6 /**< UUID of attribute display. */ /** @} */ /** @@ -95,7 +92,8 @@ */ /**@brief Apple Media Service Command ID. */ -typedef enum { +typedef enum +{ AMS_CMD_ID_PLAY, /**< Command index of play. */ AMS_CMD_ID_PAUSE, /**< Command index of pause. */ AMS_CMD_ID_TOGGLE_PLAY_PAUSE, /**< Command index of toggle. */ @@ -109,25 +107,28 @@ typedef enum { AMS_CMD_ID_SKIP_BACKWARD, /**< Command index of skip backward. */ AMS_CMD_ID_LIKE_TRACK, /**< Command index of like track. */ AMS_CMD_ID_DISLIKE_TRACK, /**< Command index of dislike track. */ - AMS_CMD_ID_BOOK_MARK_TRACK, /**< ComMand index of book mark. */ + AMS_CMD_ID_BOOK_MARK_TRACK, /**< ComMand index of book mark. */ } ams_c_cmd_id_t; /**@brief Apple Media Service entities index. */ -typedef enum { +typedef enum +{ AMS_ETT_ID_PLAYER, /**< Entity index of player. */ AMS_ETT_ID_QUEUE, /**< Entity index of queue. */ AMS_ETT_ID_TRACK, /**< Entity index of track. */ } ams_c_ett_id_t; /**@brief Apple Media Service player attribute index. */ -enum { +enum +{ AMS_PLAYER_ATTR_ID_NAME, /**< Player attribute index of name. */ AMS_PLAYER_ATTR_ID_PLAYBACK_INFO, /**< Player attribute index of playback information. */ AMS_PLAYER_ATTR_ID_VOLUME, /**< Player attribute index of volume. */ }; /**@brief Apple Media Service queue attribute index. */ -enum { +enum +{ AMS_QUEUE_ATTR_ID_INDEX, /**< Queue attribute index of index. */ AMS_QUEUE_ATTR_ID_COUNT, /**< Queue attribute index of count. */ AMS_QUEUE_ATTR_ID_SHUFFLE_MODE, /**< Queue attribute index of shuffle mode. */ @@ -135,7 +136,8 @@ enum { }; /**@brief Apple Media Service track attribute index. */ -enum { +enum +{ AMS_TRACK_ATTR_ID_ARTIST, /**< Track attribute index of artist. */ AMS_TRACK_ATTR_ID_ALBUM, /**< Track attribute index of album. */ AMS_TRACK_ATTR_ID_TITTLE, /**< Track attribute index of tittle. */ @@ -143,21 +145,20 @@ enum { }; /**@brief Apple Media Service Client Event type. */ -typedef enum { - AMS_C_EVT_INVALID, /**< AMS Client invalid event type. */ - AMS_C_EVT_DISCOVERY_CPLT, /**< AMS Client has found AMS service and its characteristics. */ - AMS_C_EVT_DISCOVERY_FAIL, /**< AMS Client found AMS service failed - because of invalid operation or no found at the peer. */ - AMS_C_EVT_CMD_SEND_SUCCESS, /**< AMS Client has sent command. */ - AMS_C_EVT_CMD_UPDATE_RECEIVE, /**< AMS Client has recieved updated command list. */ - AMS_C_EVT_CMD_UPDATE_NTF_SET_SUCCESS, /**< AMS Client has set command update notification. */ - AMS_C_EVT_ATTR_FOCUS_SET_SUCCESS, /**< AMS Client has set focus attribute */ - AMS_C_EVT_ATTR_UPDATE_RECEIVE, /**< AMS Client has received updated attribution data. */ - AMS_C_EVT_ATTR_UPDATE_NTF_SET_SUCCESS, /**< AMS Client has set focus attribute notification. */ - AMS_C_EVT_CPLT_ATTR_DISPLAY_SET_SUCCESS, /**< AMS Client has set the attribute - which needs to be completely displayed. */ - AMS_C_EVT_CPLT_ATTR_READ_RSP, /**< AMS Client has received a read response. */ - AMS_C_EVT_WRITE_OP_ERR, /**< Write error. */ +typedef enum +{ + AMS_C_EVT_INVALID, /**< AMS Client invalid event type. */ + AMS_C_EVT_DISCOVERY_CPLT, /**< AMS Client has found AMS service and its characteristics. */ + AMS_C_EVT_DISCOVERY_FAIL, /**< AMS Client found AMS service failed because of invalid operation or no found at the peer. */ + AMS_C_EVT_CMD_SEND_SUCCESS, /**< AMS Client has sent command. */ + AMS_C_EVT_CMD_UPDATE_RECEIVE, /**< AMS Client has recieved updated command list. */ + AMS_C_EVT_CMD_UPDATE_NTF_SET_SUCCESS, /**< AMS Client has set command update notification. */ + AMS_C_EVT_ATTR_FOCUS_SET_SUCCESS, /**< AMS Client has set focus attribute */ + AMS_C_EVT_ATTR_UPDATE_RECEIVE, /**< AMS Client has received updated attribution data. */ + AMS_C_EVT_ATTR_UPDATE_NTF_SET_SUCCESS, /**< AMS Client has set focus attribute notification. */ + AMS_C_EVT_CPLT_ATTR_DISPLAY_SET_SUCCESS, /**< AMS Client has set the attribute which needs to be completely displayed. */ + AMS_C_EVT_CPLT_ATTR_READ_RSP, /**< AMS Client has received a read response. */ + AMS_C_EVT_WRITE_OP_ERR, /**< Write error. */ } ams_c_evt_type_t; /** @} */ @@ -167,20 +168,23 @@ typedef enum { */ /**@brief Structure that stores the attribute to be concerned or to display completely. */ -typedef struct { +typedef struct +{ ams_c_ett_id_t ett_id; /**< Entity index. */ uint8_t attr_id[AMS_C_ATTR_COUNT_MAX]; /**< Attribute indexs. */ uint16_t attr_count; /**< Count of attribute. */ } ams_c_ett_attr_id_t; /**@brief Structure that stores new command list. */ -typedef struct { +typedef struct +{ ams_c_cmd_id_t *p_cmd; /**< Command list. */ uint16_t length; /**< Count of Command. */ } ams_c_cmd_list_t; /**@brief Structure that stores attribute information. */ -typedef struct { +typedef struct +{ ams_c_ett_id_t ett_id; /**< Entity index. */ uint8_t attr_id; /**< Attribute index. */ uint8_t flag; /**< Flag about attribute. */ @@ -189,13 +193,15 @@ typedef struct { } ams_c_attr_info_t; /**@brief Complete attribution's value . */ -typedef struct { +typedef struct +{ uint8_t *p_data; /**< complete attribute data. */ uint16_t length; /**< Length of complete attribute data. */ } ams_c_cplt_attr_data_t; /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t ams_srvc_start_handle; /**< AMS Service start handle. */ uint16_t ams_srvc_end_handle; /**< AMS Service end handle. */ uint16_t ams_cmd_handle; /**< AMS Service remote command handle. */ @@ -206,10 +212,12 @@ typedef struct { } ams_c_handles_t; /**@brief Apple Media Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ ams_c_evt_type_t evt_type; /**< The AMS event type. */ - union { + union + { ams_c_cmd_list_t cmd_list; /**< Command list. */ ams_c_attr_info_t attr_info; /**< Attribute information. */ ams_c_cplt_attr_data_t cplt_attr_data; /**< Complete attribute data. */ @@ -292,7 +300,7 @@ sdk_err_t ams_c_cplt_attr_read(uint8_t conn_idx); * @brief Send command to peer device. * * @param[in] conn_idx: Index of connection. - * @param[in] cmd_id: Index of command. + * @param[in] cmd_id: Index of command. * * @return Operation result. ***************************************************************************************** diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/BUILD.gn new file mode 100644 index 0000000..d094c30 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ancs_c") { + sources = [ + "ancs_c.c", + "ancs_protocol.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.c index 285d819..d0d746b 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.c @@ -38,81 +38,51 @@ #include "ancs_c.h" #include "ancs_protocol.h" #include "string.h" -#define ATTR_VALUE_LEN 2 + /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Apple notification center client environment variable. */ -struct ancs_c_env_t { +struct ancs_c_env_t +{ ancs_c_att_handles_t handles; /**< Handles of ANCS characteristics which will be got for peer. */ ancs_c_evt_handler_t evt_handler; /**< Handler of ANCS Client event handler. */ - uint8_t prf_id; /**< ANCS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void ancs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void ancs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void ancs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_browse_srvc_t *p_browse_srvc); - - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static const uint8_t ancs_service_uuid[] = {ANCS_SRVC_UUID}; static const uint8_t ancs_notification_source_uuid[] = {ANCS_NTF_SOURCE_UUID}; -static const uint8_t ancs_control_point_uuid[] = {ANCS_CONTROL_POINT_UUID}; -static const uint8_t ancs_data_source_uuid[] = {ANCS_DATA_SOURCE_UUID}; +static const uint8_t ancs_control_point_uuid[] ={ANCS_CONTROL_POINT_UUID}; +static const uint8_t ancs_data_source_uuid[] ={ANCS_DATA_SOURCE_UUID}; static struct ancs_c_env_t s_ancs_c_env; /**< Apple notification center client environment variable. */ -/**@brief ANCS Client interface required by profile manager. */ -static ble_prf_manager_cbs_t ancs_c_mgr_cbs = { - NULL, - NULL, - NULL +static ble_uuid_t s_ancs_service_uuid = +{ + .uuid_len = BLE_ATT_UUID_128_LEN, + .uuid = (uint8_t *)ancs_service_uuid, }; -/**@brief ANCS GATT Client Callbacks. */ -static gattc_prf_cbs_t ancs_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - ancs_c_att_write_cb, - ancs_c_att_ntf_ind_cb, - ancs_c_srvc_browse_cb, - NULL, -}; + /* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ -/**@brief ANCS Client Information. */ -static const prf_client_info_t ancs_c_prf_info = { - .max_connection_nb = ANCS_C_CONNECTION_MAX, - .manager_cbs = &ancs_c_mgr_cbs, - .gattc_prf_cbs = &ancs_c_gattc_cbs -}; - -/* -* LOCAL FUNCTION DEFINITIONS -***************************************************************************************** -*/ - -/** -***************************************************************************************** -* @brief Excute ANCS client event handler. -* -* @param[in] p_evt: Pointer to ANCS client event structure. -***************************************************************************************** -*/ + /** + ***************************************************************************************** + * @brief Excute ANCS client event handler. + * + * @param[in] p_evt: Pointer to ANCS client event structure. + ***************************************************************************************** + */ static void ancs_c_evt_handler_excute(ancs_c_evt_t *p_evt) { - if (s_ancs_c_env.evt_handler != NULL && BLE_ANCS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_ancs_c_env.evt_handler && BLE_ANCS_C_EVT_INVALID != p_evt->evt_type) + { s_ancs_c_env.evt_handler(p_evt); } } @@ -126,18 +96,21 @@ static void ancs_c_evt_handler_excute(ancs_c_evt_t *p_evt) * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void ancs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void ancs_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { ancs_c_evt_t ancs_c_evt; ancs_c_evt.conn_idx = conn_idx; ancs_c_evt.evt_type = BLE_ANCS_C_EVT_INVALID; - if (handle == s_ancs_c_env.handles.ancs_ntf_source_cccd_handle) { + if (handle == s_ancs_c_env.handles.ancs_ntf_source_cccd_handle) + { ancs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ BLE_ANCS_C_EVT_NTF_SOURCE_NTF_ENABLED : BLE_ANCS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ancs_c_env.handles.ancs_data_source_cccd_handle) { + } + else if (handle == s_ancs_c_env.handles.ancs_data_source_cccd_handle) + { ancs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ BLE_ANCS_C_EVT_DATA_SOURCE_NTF_ENABLED : BLE_ANCS_C_EVT_WRITE_OP_ERR; @@ -155,17 +128,20 @@ static void ancs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handl * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void ancs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void ancs_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { ancs_c_evt_t ancs_c_evt; ancs_c_evt.conn_idx = conn_idx; ancs_c_evt.evt_type = BLE_ANCS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_ancs_c_env.handles.ancs_ntf_source_handle) { + if (p_ntf_ind->handle == s_ancs_c_env.handles.ancs_ntf_source_handle) + { ancs_c_evt.evt_type = BLE_ANCS_C_EVT_NTF_SOURCE_RECEIVE; ancs_decode_notification_source(p_ntf_ind->p_value, p_ntf_ind->length); - } else if (p_ntf_ind->handle == s_ancs_c_env.handles.ancs_data_source_handle) { + } + else if (p_ntf_ind->handle == s_ancs_c_env.handles.ancs_data_source_handle) + { ancs_c_evt.evt_type = BLE_ANCS_C_EVT_DATA_SOURCE_RECEIVE; ancs_decode_data_source(p_ntf_ind->p_value, p_ntf_ind->length); } @@ -173,24 +149,107 @@ static void ancs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p ancs_c_evt_handler_excute(&ancs_c_evt); } +/** + ***************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] conn_idx: Connection index. + * @param[in] p_browse_srvc: Pointer to the parameters of the browse services. + ***************************************************************************************** + */ +static void ancs_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, + const ble_gattc_evt_browse_srvc_t *p_browse_srvc) +{ + uint16_t handle_disc; + + ancs_c_evt_t ancs_c_evt; + ancs_c_evt.conn_idx = conn_idx; + ancs_c_evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED; + if(p_browse_srvc->uuid_len == BLE_ATT_UUID_128_LEN) + { + if(memcmp(p_browse_srvc->uuid, ancs_service_uuid, BLE_ATT_UUID_128_LEN) == 0)//find ancs service + { + s_ancs_c_env.handles.ancs_service_handle = p_browse_srvc->start_hdl; + + for(uint16_t i=0; i<(p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++)//find characteristic + { + handle_disc = p_browse_srvc->start_hdl + i + 1; + if(p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) + { + if(memcmp(p_browse_srvc->info[i].attr.uuid, ancs_notification_source_uuid, BLE_ATT_UUID_128_LEN) == 0)//find ancs notification source characteristic + { + s_ancs_c_env.handles.ancs_ntf_source_handle = handle_disc; + } + else if(memcmp(p_browse_srvc->info[i].attr.uuid, ancs_control_point_uuid, BLE_ATT_UUID_128_LEN) == 0)//find ancs control point characteristic + { + s_ancs_c_env.handles.ancs_control_point_handle = handle_disc; + } + else if(memcmp(p_browse_srvc->info[i].attr.uuid, ancs_data_source_uuid, BLE_ATT_UUID_128_LEN) == 0)//find ancs data source characteristic + { + s_ancs_c_env.handles.ancs_data_source_handle = handle_disc; + } + } + else if((p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_DESC) && //find cccd + ((*(uint16_t *)(p_browse_srvc->info[i].attr.uuid)) == BLE_ATT_DESC_CLIENT_CHAR_CFG)) + { + if(handle_disc == (s_ancs_c_env.handles.ancs_ntf_source_handle + 1))// find notification source cccd + { + s_ancs_c_env.handles.ancs_ntf_source_cccd_handle = handle_disc; + } + else if(handle_disc == (s_ancs_c_env.handles.ancs_data_source_handle + 1))// find data source cccd + { + s_ancs_c_env.handles.ancs_data_source_cccd_handle = handle_disc; + } + } + else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; + } + } + ancs_c_evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_CPLT; + } + } + ancs_c_evt_handler_excute(&ancs_c_evt); +} + +static void ancs_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + ancs_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + ancs_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + ancs_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ancs_c_client_init(ancs_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_ancs_c_env, sizeof(s_ancs_c_env), 0, sizeof(s_ancs_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_ancs_c_env, 0, sizeof(s_ancs_c_env)); s_ancs_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&ancs_c_prf_info, &s_ancs_c_env.prf_id); + return ble_gattc_prf_add(&s_ancs_service_uuid, ancs_c_ble_evt_handler); } /** @@ -202,109 +261,34 @@ sdk_err_t ancs_c_client_init(ancs_c_evt_handler_t evt_handler) */ sdk_err_t ancs_c_discovery_service(uint8_t conn_idx) { - ble_uuid_t ble_ancs_uuid = { - .uuid_len = BLE_ATT_UUID_128_LEN, - .uuid = (uint8_t*)ancs_service_uuid, - }; - return ble_gattc_prf_services_browse(s_ancs_c_env.prf_id, conn_idx, &ble_ancs_uuid); -} - -/** - ***************************************************************************************** - * @brief Handles reception of the attribute info request message. - * - * @param[in] conn_idx: Connection index. - * @param[in] p_browse_srvc: Pointer to the parameters of the browse services. - ***************************************************************************************** - */ -static void ancs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, - const ble_gattc_browse_srvc_t *p_browse_srvc) -{ - uint16_t handle_disc; - - ancs_c_evt_t ancs_c_evt; - ancs_c_evt.conn_idx = conn_idx; - ancs_c_evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED; - if (p_browse_srvc->uuid_len != BLE_ATT_UUID_128_LEN) { - return; - } - if (memcmp(p_browse_srvc->uuid, ancs_service_uuid, BLE_ATT_UUID_128_LEN) != 0) { - return; - } - // find ancs service - s_ancs_c_env.handles.ancs_service_handle = p_browse_srvc->start_hdl; - - for (uint16_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { // find characteristic - handle_disc = p_browse_srvc->start_hdl + i + 1; - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) { - if (memcmp(p_browse_srvc->info[i].attr.uuid, ancs_notification_source_uuid, - BLE_ATT_UUID_128_LEN) == 0) { // find ancs notification source characteristic - s_ancs_c_env.handles.ancs_ntf_source_handle = handle_disc; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, ancs_control_point_uuid, - BLE_ATT_UUID_128_LEN) == 0) { // find ancs control point characteristic - s_ancs_c_env.handles.ancs_control_point_handle = handle_disc; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, ancs_data_source_uuid, - BLE_ATT_UUID_128_LEN) == 0) { // find ancs data source characteristic - s_ancs_c_env.handles.ancs_data_source_handle = handle_disc; - } - } else if ((p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_DESC) && // find cccd - ((*(uint16_t *)(p_browse_srvc->info[i].attr.uuid)) == BLE_ATT_DESC_CLIENT_CHAR_CFG)) { - if (handle_disc == (s_ancs_c_env.handles.ancs_ntf_source_handle + 1)) { - // find notification source cccd - s_ancs_c_env.handles.ancs_ntf_source_cccd_handle = handle_disc; - } else if (handle_disc == (s_ancs_c_env.handles.ancs_data_source_handle + 1)) { - // find data source cccd - s_ancs_c_env.handles.ancs_data_source_cccd_handle = handle_disc; - } - } else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; - } - } - ancs_c_evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_CPLT; - - ancs_c_evt_handler_excute(&ancs_c_evt); + return ble_gattc_services_browse(conn_idx, &s_ancs_service_uuid); } sdk_err_t ancs_c_write_control_point(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - gattc_write_attr_value_t write_attr_value; - - write_attr_value.handle = s_ancs_c_env.handles.ancs_control_point_handle; - write_attr_value.offset = 0; - write_attr_value.length = length; - write_attr_value.p_value = (uint8_t *)p_data; - - return ble_gattc_prf_write(s_ancs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ancs_c_env.handles.ancs_control_point_handle, 0, length, (uint8_t *)p_data); } sdk_err_t ancs_c_ntf_source_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ancs_c_env.handles.ancs_ntf_source_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ancs_c_env.handles.ancs_ntf_source_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ancs_c_env.handles.ancs_ntf_source_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - return ble_gattc_prf_write(s_ancs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ancs_c_env.handles.ancs_ntf_source_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ancs_c_data_source_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ancs_c_env.handles.ancs_data_source_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ancs_c_env.handles.ancs_data_source_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ancs_c_env.handles.ancs_data_source_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - return ble_gattc_prf_write(s_ancs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ancs_c_env.handles.ancs_data_source_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.h index 4a8bb25..9c699e7 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_c.h @@ -3,7 +3,7 @@ * * @file ancs_c.h * - * @brief ANCS Service API. + * @brief Apple Notification Center Service API. * ***************************************************************************************** * @attention @@ -45,49 +45,48 @@ * @defgroup BLE_SDK_ANCS Apple Notification Center Service (ANCS) * @{ * @brief Definitions and prototypes for the ANCS interface. - - * @details ANCS provides a way for BLE devices to receive IOS mobile phone notifications. - * The service consists of three eigenvalues, including notification source, + + * @details ANCS provides a way for BLE devices to receive IOS mobile phone notifications. + * The service consists of three eigenvalues, including notification source, * data source, control point. - * - * The application needs to call \ref ancs_c_client_init() to initialize, and then - * use \ref ancs_c_discovery_service() to discover ANCS-related services on IOS devices. - * After discovery, ancs_c_on_browse_svc_evt function is called to parse and save + * + * The application needs to call \ref ancs_c_client_init() to initialize, and then + * use \ref ancs_c_discovery_service() to discover ANCS-related services on IOS devices. + * After discovery, ancs_c_on_browse_svc_evt function is called to parse and save * the handle corresponding to each service. These handles are used for data * transmission. - * + * * Secondly, use \ref ancs_c_ntf_source_notify_set() and \ref ancs_c_data_source_notify_set() - * to enable notification source & data source's CCD. The IOS notification is then sent to the + * to enable notification source & data source's CCD. The IOS notification is then sent to the * BLE device side immediately. - * + * * Finally, the application can use \ref ancs_decode_notification_source() and - * \ref ancs_decode_data_source() to parse the ANCS message and \ref ancs_c_write_control_point() + * \ref ancs_decode_data_source() to parse the ANCS message and \ref ancs_c_write_control_point() * to command the control point. For specific commands, please refer to the ANCS protocol specification. * */ -#ifndef ANCS_H -#define ANCS_H +#ifndef _ANCS_H_ +#define _ANCS_H_ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include /** * @defgroup ANCS_C_MACRO Defines * @{ */ -#define ANCS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of ANCS Client connections. */ -#define ANCS_SRVC_UUID 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, 0x99, 0x4e, 0xce, 0xb5, \ - 0x31, 0xf4, 0x05, 0x79 /**< UUID of Apple notification center service. */ -#define ANCS_NTF_SOURCE_UUID 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, \ - 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f /**< UUID of notification source. */ -#define ANCS_CONTROL_POINT_UUID 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, \ - 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 /**< UUID of control point. */ -#define ANCS_DATA_SOURCE_UUID 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe, \ - 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 /**< UUID of data source. */ +#define ANCS_C_CONNECTION_MAX 10 /**< Maximum number of ANCS Client connections. */ +#define ANCS_SRVC_UUID 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,\ + 0x99,0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79 /**< UUID of Apple notification center service. */ +#define ANCS_NTF_SOURCE_UUID 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,\ + 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f /**< UUID of notification source. */ +#define ANCS_CONTROL_POINT_UUID 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,\ + 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 /**< UUID of control point. */ +#define ANCS_DATA_SOURCE_UUID 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,\ + 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 /**< UUID of data source. */ /** @} */ @@ -96,15 +95,15 @@ * @{ */ /**@brief Event types that are passed from client to application on an event. */ -typedef enum { - BLE_ANCS_C_EVT_INVALID, /**< ANCS Client invalid event type. */ - BLE_ANCS_C_EVT_DISCOVERY_CPLT, /**< ANCS Client has found ANCS service and its characteristics. */ - BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< ANCS Client found ANCS service failed \ - because of invalid operation or no found at the peer. */ - BLE_ANCS_C_EVT_NTF_SOURCE_NTF_ENABLED, /**< ANCS Client has enable notification for notification source. */ - BLE_ANCS_C_EVT_DATA_SOURCE_NTF_ENABLED, /**< ANCS Client has enable notification for data source. */ - BLE_ANCS_C_EVT_NTF_SOURCE_RECEIVE, /**< ANCS Client has receive notification from notification source. */ - BLE_ANCS_C_EVT_DATA_SOURCE_RECEIVE, /**< ANCS Client has receive notification from data source. */ +typedef enum +{ + BLE_ANCS_C_EVT_INVALID, /**< ANCS Client invalid event type. */ + BLE_ANCS_C_EVT_DISCOVERY_CPLT, /**< ANCS Client has found ANCS service and its characteristics. */ + BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< ANCS Client found ANCS service failed because of invalid operation or no found at the peer. */ + BLE_ANCS_C_EVT_NTF_SOURCE_NTF_ENABLED, /**< ANCS Client has enable notification for notification source. */ + BLE_ANCS_C_EVT_DATA_SOURCE_NTF_ENABLED, /**< ANCS Client has enable notification for data source. */ + BLE_ANCS_C_EVT_NTF_SOURCE_RECEIVE, /**< ANCS Client has receive notification from notification source. */ + BLE_ANCS_C_EVT_DATA_SOURCE_RECEIVE, /**< ANCS Client has receive notification from data source. */ BLE_ANCS_C_EVT_WRITE_OP_ERR, } ble_ancs_c_evt_type_t; /** @} */ @@ -114,22 +113,22 @@ typedef enum { * @{ */ /**@brief ancs handle structure. */ -typedef struct { - uint16_t ancs_service_handle; /**< Handle of ancs service as provided by a discovery. */ - uint16_t ancs_ntf_source_handle; /**< Handle of ancs notification source characteristic \ - as provided by a discovery. */ - uint16_t ancs_ntf_source_cccd_handle; /**< Handle of CCCD of ancs control point characteristic \ - as provided by a discovery. */ - uint16_t ancs_control_point_handle; /**< Handle of ancs control point characteristic as provided by a discovery. */ - uint16_t ancs_data_source_handle; /**< Handle of ancs data source characteristic as provided by a discovery. */ - uint16_t ancs_data_source_cccd_handle; /**< Handle of CCCD of ancs data source characteristic \ - as provided by a discovery. */ -} ancs_c_att_handles_t; +typedef struct +{ + uint16_t ancs_service_handle; /**< Handle of ancs service as provided by a discovery. */ + uint16_t ancs_ntf_source_handle; /**< Handle of ancs notification source characteristic as provided by a discovery. */ + uint16_t ancs_ntf_source_cccd_handle; /**< Handle of CCCD of ancs control point characteristic as provided by a discovery. */ + uint16_t ancs_control_point_handle; /**< Handle of ancs control point characteristic as provided by a discovery. */ + uint16_t ancs_data_source_handle; /**< Handle of ancs data source characteristic as provided by a discovery. */ + uint16_t ancs_data_source_cccd_handle; /**< Handle of CCCD of ancs data source characteristic as provided by a discovery. */ +}ancs_c_att_handles_t; /**@brief ANCS Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ ble_ancs_c_evt_type_t evt_type; /**< The ANCS event type. */ + } ancs_c_evt_t; /** @} */ @@ -166,7 +165,7 @@ sdk_err_t ancs_c_discovery_service(uint8_t conn_idx); * @brief enable ancs notification source CCCD. * * @param[in] conn_idx: Connection index. - * @param[in] is_enable: Start or stop the notification. + * @param[in] is_enable: Start or stop the notification. * @return success or not. ***************************************************************************************** */ @@ -177,7 +176,7 @@ sdk_err_t ancs_c_ntf_source_notify_set(uint8_t conn_idx, bool is_enable); * @brief enable ancs data source CCCD. * * @param[in] conn_idx: Connection index. - * @param[in] is_enable: Start or stop the notification. + * @param[in] is_enable: Start or stop the notification. * @return success or not. ***************************************************************************************** */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.c index 2b01ad0..e13d24e 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.c @@ -35,22 +35,12 @@ ***************************************************************************************** */ + +#include "ancs_protocol.h" +#include "ancs_c.h" #include #include #include "app_log.h" -#include "ancs_c.h" -#include "ancs_protocol.h" - -#define LEN_2 2 -#define LEN_4 4 -#define LEN_6 6 -#define LEN_8 8 -#define INDEX_5 5 -#define INDEX_6 6 -#define INDEX_7 7 -#define INDEX_8 8 -#define OFFSET_8 8 - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** @@ -58,7 +48,8 @@ static uint32_t s_uid; /**@brief String literals for the iOS notification Category id types. Used then printing to UART. */ -static char const * lit_catid[] = { +static char const * lit_catid[] = +{ "Other", "Incoming Call", "Missed Call", @@ -74,14 +65,16 @@ static char const * lit_catid[] = { }; /**@brief String literals for the iOS notification event types. Used then printing to UART. */ -static char const * lit_eventid[] = { +static char const * lit_eventid[] = +{ "Added", "Modified", "Removed" }; /**@brief String literals for the iOS notification attribute types. Used when printing to UART. */ -static char const * lit_attrid[] = { +static char const * lit_attrid[] = +{ "App Identifier", "Title", "Subtitle", @@ -108,25 +101,23 @@ static void ancs_notify_attr_print(void) uint16_t UID; uint8_t attr_id; uint16_t attr_size = 0; - uint8_t ret; - ret = memcpy_s(&UID, LEN_4, &s_attr_buf[1], LEN_4); - if (ret < 0) { - return; - } - ret = memcpy_s(&attr_size, LEN_2, &s_attr_buf[INDEX_6], LEN_2); - if (ret < 0) { - return; - } + memcpy(&UID, &s_attr_buf[1], 4); + memcpy(&attr_size, &s_attr_buf[6], 2); - if (commd_id == CTRL_POINT_GET_NTF_ATTRIBUTE) { - attr_id = s_attr_buf[INDEX_5]; + if (commd_id == CTRL_POINT_GET_NTF_ATTRIBUTE) + { + attr_id = s_attr_buf[5]; APP_LOG_INFO("UID=%d, ATTR_ID: %s, ATTR_SIZE=%d", UID, lit_attrid[attr_id], attr_size); - for (uint16_t idx = 0; idx < attr_size; idx++) { - printf("%c", s_attr_buf[INDEX_8 + idx]); + for (uint16_t idx = 0; idx < attr_size; idx++) + { + printf("%c", s_attr_buf[8 + idx]); } printf("\r\n"); - } else if (commd_id == CTRL_POINT_GET_APP_ATTRIBUTE) { - for (uint16_t idx = 0; idx < attr_size; idx++) { + } + else if (commd_id == CTRL_POINT_GET_APP_ATTRIBUTE) + { + for (uint16_t idx = 0; idx < attr_size; idx++) + { printf("%c", s_attr_buf[idx]); } printf("\r\n"); @@ -143,34 +134,37 @@ static void ancs_notify_attr_print(void) */ void ancs_decode_data_source(uint8_t *p_data, uint16_t length) { - uint8_t ret; - // It's the begginning of a attr info. - if (s_buf_index == 0) { - ret = memcpy_s(&s_attr_size, LEN_2, &p_data[INDEX_6], LEN_2); - if (ret < 0) { - return; - } - ret = memcpy_s(&s_attr_size, length, p_data, length); - if (ret < 0) { - return; - } - // It's the end of the attr info, a complete attr info is already stored in the buffer. - if (s_attr_size == length - LEN_8) { + //It's the begginning of a attr info. + if (0 == s_buf_index) + { + memcpy(&s_attr_size, &p_data[6], 2); + memcpy(s_attr_buf, p_data, length); + //It's the end of the attr info, a complete attr info is already stored in the buffer. + if (s_attr_size == length - 8) + { ancs_notify_attr_print(); s_buf_index = 0; - } else { // It's not the end of the attr info. + } + //It's not the end of the attr info. + else + { s_buf_index = length; } - } else { // It isn't the begginning of a attr info. - ret = memcpy_s(&s_attr_buf[s_buf_index], length, p_data, length); - if (ret < 0) { - return; - } - // It's the end of the attr info, print the buffer. - if (s_attr_size == (s_buf_index - INDEX_8) + length) { + } + + //It isn't the begginning of a attr info. + else + { + memcpy(&s_attr_buf[s_buf_index], p_data, length); + //It's the end of the attr info, print the buffer. + if (s_attr_size == (s_buf_index - 8) + length) + { ancs_notify_attr_print(); s_buf_index = 0; - } else { // It's not the end of the attr info. + } + //It's not the end of the attr info. + else + { s_buf_index = s_buf_index + length; } } @@ -181,52 +175,47 @@ void ancs_decode_data_source(uint8_t *p_data, uint16_t length) * @brief Get notification attribute * * @param[in] uid: The uid of notify message - * @param[in] noti_attr: The notification attribute + * @param[in] noti_attr: The notification attribute * ***************************************************************************************** */ void ancs_notify_attr_get(int uid, char noti_attr) { - int len = 0; + int len = 0; uint8_t buf[8]; - uint8_t ret; buf[0] = CTRL_POINT_GET_NTF_ATTRIBUTE; - ret = memcpy_s(&buf[1], LEN_4, &uid, LEN_4); - if (ret < 0) { - return; - } - buf[INDEX_5] = noti_attr; + memcpy(&buf[1], &uid, 4); + buf[5] = noti_attr; if (ANCS_NOTIF_ATTR_ID_TITLE == noti_attr || ANCS_NOTIF_ATTR_ID_SUBTITLE== noti_attr - || ANCS_NOTIF_ATTR_ID_MESSAGE== noti_attr) { + || ANCS_NOTIF_ATTR_ID_MESSAGE== noti_attr) + { len = CFG_ANCS_ATTRIBUTE_MAXLEN; - buf[INDEX_6] = (len & 0xff); - buf[INDEX_7] = (len >> OFFSET_8) & 0xff; - ancs_c_write_control_point(0, buf, LEN_8); - } else { - ancs_c_write_control_point(0, buf, LEN_6); + buf[6] = (len & 0xff); + buf[7] = (len>>8) & 0xff; + ancs_c_write_control_point(0, buf, 8); + } + else + { + ancs_c_write_control_point(0, buf, 6); } } /** ***************************************************************************************** - * @brief ancs perform action + * @brief ancs perform action * * @param[in] uid: The uid of notify message - * @param[in] action: The action status defined by specification + * @param[in] action: The action status defined by specification ***************************************************************************************** */ void ancs_action_perform(int uid, int action) { uint8_t buf[6]; - uint8_t ret; buf[0] = CTRL_POINT_PERFORM_NTF_ACTION; - ret = memcpy_s(&buf[1], LEN_4, &uid, LEN_4); - if (ret < 0) { - return; - } - buf[INDEX_5] = action; - ancs_c_write_control_point(0, buf, LEN_6); -} + memcpy(&buf[1], &uid, 4); + buf[5] = action; + ancs_c_write_control_point(0, buf, 6); +} /** ***************************************************************************************** @@ -243,19 +232,24 @@ static void notification_content_print(ntf_source_pdu_t *p_notif) APP_LOG_INFO("Category Cnt:%u", (unsigned int) p_notif->category_count); APP_LOG_INFO("UID: %u", (unsigned int) p_notif->notification_uid); APP_LOG_INFO("Flags: "); - if (p_notif->event_flags.silent == 1) { + if (p_notif->event_flags.silent == 1) + { APP_LOG_INFO(" Silent"); } - if (p_notif->event_flags.important == 1) { + if (p_notif->event_flags.important == 1) + { APP_LOG_INFO(" Important"); } - if (p_notif->event_flags.pre_existing == 1) { + if (p_notif->event_flags.pre_existing == 1) + { APP_LOG_INFO(" Pre-existing"); } - if (p_notif->event_flags.positive_action == 1) { + if (p_notif->event_flags.positive_action == 1) + { APP_LOG_INFO(" Positive Action"); } - if (p_notif->event_flags.negative_action == 1) { + if (p_notif->event_flags.negative_action == 1) + { APP_LOG_INFO(" Negative Action"); } } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.h index 82c721d..08d65da 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ancs_c/ancs_protocol.h @@ -3,7 +3,7 @@ * * @file ancs_protocol.h * - * @brief ANCS Protocol API. + * @brief Apple Notification Center Service Protocol API. * ******************************************************************************* * @attention @@ -37,8 +37,8 @@ #ifndef _ANCS_PROTOCOL_H_ #define _ANCS_PROTOCOL_H_ +#include "gr_includes.h" #include -#include "gr55xx_sys.h" /** Maximum allowed value for attribute length */ #ifndef CFG_ANCS_ATTRIBUTE_MAXLEN @@ -46,10 +46,10 @@ #endif /** Attribute ID element without maximum length */ -#define ANCS_ATTR(ID) ((uint32_t)0x80000000 | ((uint8_t)(ID))) +#define ANCS_ATTR(ID) ((uint32_t) 0x80000000 | ((uint8_t) ID)) /** Attribute ID element with maximum length */ -#define ANCS_ATTR_MAXLEN(ID, LEN) ((uint32_t)0x80000000 | ((uint8_t)(ID)) | ((uint16_t)(LEN) << 8)) +#define ANCS_ATTR_MAXLEN(ID, LEN) ((uint32_t) 0x80000000 | ((uint8_t) ID) | ((uint16_t) LEN << 8)) /** * @defgroup ANCS_ENUM Enumerations @@ -57,21 +57,21 @@ */ /**@brief IDs for iOS notification attributes. */ -typedef enum { +typedef enum +{ ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER = 0, /**< Identify that the attribute data is of an "App Identifier" type. */ ANCS_NOTIF_ATTR_ID_TITLE, /**< Identify that the attribute data is a "Title". */ ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identify that the attribute data is a "Subtitle". */ ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identify that the attribute data is a "Message". */ ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identify that the attribute data is a "Message Size". */ ANCS_NOTIF_ATTR_ID_DATE, /**< Identify that the attribute data is a "Date". */ - ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" \ - that can be executed associated with it. */ - ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" \ - that can be executed associated with it. */ + ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */ + ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */ } ancs_notification_attr_t; /**@brief Category IDs for iOS notifications. */ -typedef enum { +typedef enum +{ ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */ ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */ ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */ @@ -80,33 +80,33 @@ typedef enum { ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */ ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */ ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */ - ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */ - ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */ + ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */ + ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */ ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */ ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */ } ancs_category_id_t; /**@brief Event IDs for iOS notifications. */ -typedef enum { +typedef enum +{ ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */ ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */ ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */ } ancs_evt_id_t; /**@brief ID for actions that can be performed for iOS notifications. */ -typedef enum { +typedef enum +{ ACTION_ID_POSITIVE = 0, /**< Positive action. */ ACTION_ID_NEGATIVE /**< Negative action. */ } ancs_c_action_id_t; /**@brief ctrl point command that can be performed for iOS notifications. */ -typedef enum { - CTRL_POINT_GET_NTF_ATTRIBUTE = 0, /**< Request attributes to be sent from \ - the NP to the NC for a given notification. */ - CTRL_POINT_GET_APP_ATTRIBUTE, /**< Request attributes to be sent from the NP to \ - the NC for a given iOS app. */ - CTRL_POINT_PERFORM_NTF_ACTION, /**< Request an action to be performed on \ - a given notification, for example, dismiss an alarm. */ +typedef enum +{ + CTRL_POINT_GET_NTF_ATTRIBUTE = 0, /**< Request attributes to be sent from the NP to the NC for a given notification. */ + CTRL_POINT_GET_APP_ATTRIBUTE, /**< Request attributes to be sent from the NP to the NC for a given iOS app. */ + CTRL_POINT_PERFORM_NTF_ACTION, /**< Request an action to be performed on a given notification, for example, dismiss an alarm. */ } ancs_c_ctrl_point_t; /** @} */ @@ -117,22 +117,21 @@ typedef enum { */ /**@brief notification flags that can be performed for iOS notifications. */ -typedef struct { +typedef struct +{ uint8_t silent : 1; /**< If this flag is set, the notification has a low priority. */ uint8_t important : 1; /**< If this flag is set, the notification has a high priority. */ uint8_t pre_existing : 1; /**< If this flag is set, the notification is pre-existing. */ -uint8_t positive_action : - 1; /**< If this flag is set, the notification has a positive action that can be taken. */ -uint8_t negative_action : - 1; /**< If this flag is set, the notification has a negative action that can be taken. */ + uint8_t positive_action : 1; /**< If this flag is set, the notification has a positive action that can be taken. */ + uint8_t negative_action : 1; /**< If this flag is set, the notification has a negative action that can be taken. */ } ancs_ntf_flags_t; /**@brief iOS notification structure. */ -typedef struct { +typedef struct +{ ancs_evt_id_t event_id; /**< Whether the notification was added, removed, or modified. */ ancs_ntf_flags_t event_flags; /**< Whether the notification was added, removed, or modified. */ - ancs_category_id_t - category_id; /**< Classification of the notification type, for example, email or location. */ + ancs_category_id_t category_id; /**< Classification of the notification type, for example, email or location. */ uint8_t category_count; /**< Current number of active notifications for this category ID. */ uint32_t notification_uid; /**< Notification UID. */ } ntf_source_pdu_t; @@ -148,7 +147,7 @@ typedef struct { * @brief Get notification attribute * * @param[in] uid: The UID of notify message - * @param[in] noti_attr: The notification attribute + * @param[in] noti_attr: The notification attribute * ***************************************************************************************** */ @@ -156,10 +155,10 @@ void ancs_notify_attr_get(int uid, char noti_attr); /** ***************************************************************************************** - * @brief ancs perform action + * @brief ancs perform action * * @param[in] uid: The UID of notify message - * @param[in] action: The action status defined by specification + * @param[in] action: The action status defined by specification * ***************************************************************************************** */ @@ -195,3 +194,5 @@ void ancs_decode_notification_source(uint8_t *p_data, uint16_t length); void ancs_decode_data_source(uint8_t *p_data, uint16_t length); /** @} */ #endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/BUILD.gn new file mode 100644 index 0000000..a6f0d8b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ans") { + sources = [ "ans.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.c index 7d33181..feafbbb 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.c @@ -42,7 +42,7 @@ #include "ans.h" #include "ble_prf_types.h" #include "ble_prf_utils.h" -#include "gr55xx_sys.h" +#include "grx_sys.h" #include "utility.h" /* @@ -50,7 +50,8 @@ **************************************************************************************** */ /**@brief Alert Notification Service Attributes Indexes. */ -enum { +enum +{ // Alert Notification Service ANS_IDX_SVC, @@ -84,171 +85,95 @@ enum { ***************************************************************************************** */ /**@brief Alert Notification Service environment variable. */ -struct ans_env_t { - ans_init_t ans_init; /**< Alert Notification Service initialization variables. */ - uint16_t start_hdl; /**< Alert Notification Service start handle. */ - uint16_t - new_alert_ntf_cfg[ANS_CONNECTION_MAX]; /**< The configuration of New Alert Notification \ - which is configured by the peer devices. */ - uint16_t - unread_alert_sta_ntf_cfg[ANS_CONNECTION_MAX]; /**< The configuration of Unread Alert Status Notification \ - which is configured by the peer devices. */ - uint16_t ntf_new_alert_cfg; /**< New Alert category notification configuration. */ - uint16_t - ntf_unread_alert_cfg; /**< Unread Alert Status category notification configuration. */ +struct ans_env_t +{ + ans_init_t ans_init; /**< Alert Notification Service initialization variables. */ + uint16_t start_hdl; /**< Alert Notification Service start handle. */ + uint16_t new_alert_ntf_cfg[ANS_CONNECTION_MAX]; /**< The configuration of New Alert Notification which is configured by the peer devices. */ + uint16_t unread_alert_sta_ntf_cfg[ANS_CONNECTION_MAX]; /**< The configuration of Unread Alert Status Notification which is configured by the peer devices. */ + uint16_t ntf_new_alert_cfg; /**< New Alert category notification configuration. */ + uint16_t ntf_unread_alert_cfg; /**< Unread Alert Status category notification configuration. */ + ble_gatts_create_db_t ans_gatts_db; /**< Alert Notification Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t ans_init(void); -static void ans_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void ans_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void ans_connected_cb(uint8_t conn_idx); -static bool ans_ctrl_pt_sup_check(ans_ctrl_pt_t *p_ctrl_pt); -static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt); +static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt); +static bool ans_ctrl_pt_sup_check(ans_ctrl_pt_t *p_ctrl_pt); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct ans_env_t s_ans_env; +static uint8_t s_ans_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_ALERT_NTF); static uint16_t s_ans_char_mask = 0x1fff; /**@brief Full ANS Database Description - Used to add attributes into the database. */ -static const attm_desc_t pass_attr_tab[ANS_IDX_NB] = { + +static const ble_gatts_attm_desc_t ans_attr_tab[ANS_IDX_NB] = +{ // Alert Notification Service - [ANS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Status Characteristic - Declaration - [ANS_IDX_SUP_NEW_ALET_CAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_SUP_NEW_ALET_CAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Status Characteristic - Value - [ANS_IDX_SUP_NEW_ALET_CAT_VAL] = { - BLE_ATT_CHAR_SUP_NEW_ALERT_CAT, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - ANS_SUP_NEW_ALERT_CAT_VAL_LEN - }, + [ANS_IDX_SUP_NEW_ALET_CAT_VAL] = {BLE_ATT_CHAR_SUP_NEW_ALERT_CAT, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + ANS_SUP_NEW_ALERT_CAT_VAL_LEN}, // New Alert Characteristic - Declaration - [ANS_IDX_NEWS_ALERT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_NEWS_ALERT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // New Alert Characteristic - Value - [ANS_IDX_NEWS_ALERT_VAL] = { - BLE_ATT_CHAR_NEW_ALERT, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - ANS_NEWS_ALERT_VAL_LEN - }, + [ANS_IDX_NEWS_ALERT_VAL] = {BLE_ATT_CHAR_NEW_ALERT, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + ANS_NEWS_ALERT_VAL_LEN}, // New Alert Characteristic - Client Characteristic Configuration Descriptor - [ANS_IDX_NEWS_ALERT_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [ANS_IDX_NEWS_ALERT_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Supported Unread AlertCategory Characteristic - Declaration - [ANS_IDX_SUP_UNREAD_ALERT_CAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_SUP_UNREAD_ALERT_CAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Supported Unread Alert Category Characteristic - Value - [ANS_IDX_SUP_UNREAD_ALERT_CAT_VAL] = { - BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - ANS_SUP_UNREAD_ALERT_CAT_VAL_LEN - }, + [ANS_IDX_SUP_UNREAD_ALERT_CAT_VAL] = {BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + ANS_SUP_UNREAD_ALERT_CAT_VAL_LEN}, // Unread Alert Status Characteristic - Declaration - [ANS_IDX_UNREAD_ALERT_STA_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_UNREAD_ALERT_STA_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Unread Alert Status Characteristic - Value - [ANS_IDX_UNREAD_ALERT_STA_VAL] = { - BLE_ATT_CHAR_UNREAD_ALERT_STATUS, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - ANS_UNREAD_ALERT_STA_VAL_LEN - }, + [ANS_IDX_UNREAD_ALERT_STA_VAL] = {BLE_ATT_CHAR_UNREAD_ALERT_STATUS, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + ANS_UNREAD_ALERT_STA_VAL_LEN}, // Unread Alert Status Characteristic - Client Characteristic Configuration Descriptor - [ANS_IDX_UNREAD_ALERT_STA_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [ANS_IDX_UNREAD_ALERT_STA_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // Alert Notification Control Point Characteristic - Declaration - [ANS_IDX_ALERT_NTF_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [ANS_IDX_ALERT_NTF_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Notification Control Point Characteristic - Value - [ANS_IDX_ALERT_NTF_CTRL_PT_VAL] = { - BLE_ATT_CHAR_ALERT_NTF_CTNL_PT, + [ANS_IDX_ALERT_NTF_CTRL_PT_VAL] = {BLE_ATT_CHAR_ALERT_NTF_CTNL_PT, #if defined(PTS_AUTO_TEST) - WRITE_REQ_PERM_UNSEC, + BLE_GATTS_WRITE_REQ_PERM_UNSEC, #else - WRITE_CMD_PERM_UNSEC, + BLE_GATTS_WRITE_CMD_PERM_UNSEC, #endif - ATT_VAL_LOC_USER, - ANS_ALERT_NTF_CTRL_PT_VAL_LEN - }, -}; - -/**@brief ANS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t ans_task_cbs = { - (prf_init_func_t) ans_init, - ans_connected_cb, - NULL, -}; - -/**@brief ANS Task Callbacks. */ -static gatts_prf_cbs_t ans_cb_func = { - ans_read_att_cb, - ans_write_att_cb, - NULL, - NULL, - ans_cccd_set_cb -}; - -/**@brief ANS Information. */ -static const prf_server_info_t ans_prf_info = { - .max_connection_nb = ANS_CONNECTION_MAX, - .manager_cbs = &ans_task_cbs, - .gatts_prf_cbs = &ans_cb_func, + BLE_GATTS_ATT_VAL_LOC_USER, + ANS_ALERT_NTF_CTRL_PT_VAL_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Alert Notify Service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t ans_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t pass_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_ALERT_NTF); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = pass_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_ans_char_mask; - gatts_db.max_nb_attr = ANS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = pass_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_ans_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -257,18 +182,19 @@ static sdk_err_t ans_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void ans_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void ans_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, - s_ans_env.start_hdl, - ANS_IDX_NB, - (uint8_t *)&s_ans_char_mask); + s_ans_env.start_hdl, + ANS_IDX_NB, + (uint8_t *)&s_ans_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case ANS_IDX_SUP_NEW_ALET_CAT_VAL: cfm.length = ANS_SUP_NEW_ALERT_CAT_VAL_LEN; cfm.value = (uint8_t *)&s_ans_env.ans_init.sup_new_alert_cat; @@ -306,7 +232,7 @@ static void ans_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void ans_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; @@ -314,7 +240,7 @@ static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p bool is_ctrl_pt_rec = false; ans_ctrl_pt_t ctrl_pt; ans_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_ans_env.start_hdl, @@ -325,7 +251,8 @@ static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p event.evt_type = ANS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case ANS_IDX_NEWS_ALERT_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ @@ -346,9 +273,12 @@ static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p ctrl_pt.cmd_id = (ans_ctrl_pt_id_t)p_param->value[0]; ctrl_pt.cat_id = (ans_alert_cat_id_t)p_param->value[1]; - if (ans_ctrl_pt_sup_check(&ctrl_pt)) { + if (ans_ctrl_pt_sup_check(&ctrl_pt)) + { is_ctrl_pt_rec = true; - } else { + } + else + { cfm.status = ANS_ERROR_CMD_NOT_SUP; } @@ -361,14 +291,16 @@ static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p ble_gatts_write_cfm(conn_idx, &cfm); - if (is_ctrl_pt_rec) { + if (is_ctrl_pt_rec) + { is_ctrl_pt_rec = false; ans_ctrl_pt_handler(conn_idx, &ctrl_pt); } if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && \ - ANS_EVT_INVALID != event.evt_type && \ - s_ans_env.ans_init.evt_handler) { + ANS_EVT_INVALID != event.evt_type && \ + s_ans_env.ans_init.evt_handler) + { s_ans_env.ans_init.evt_handler(&event); } } @@ -382,12 +314,13 @@ static void ans_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void ans_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void ans_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; ans_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -399,7 +332,8 @@ static void ans_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = ANS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case ANS_IDX_NEWS_ALERT_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ ANS_EVT_NEW_ALERT_NTF_ENABLE : \ @@ -419,7 +353,8 @@ static void ans_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val } if (ANS_EVT_INVALID != event.evt_type && \ - s_ans_env.ans_init.evt_handler) { + s_ans_env.ans_init.evt_handler) + { s_ans_env.ans_init.evt_handler(&event); } } @@ -431,7 +366,7 @@ static void ans_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in]: conn_idx: Connection index ***************************************************************************************** */ -static void ans_connected_cb(uint8_t conn_idx) +static void ans_connected_evt_handler(uint8_t conn_idx) { s_ans_env.ntf_new_alert_cfg = 0; s_ans_env.ntf_unread_alert_cfg = 0; @@ -448,30 +383,43 @@ static void ans_connected_cb(uint8_t conn_idx) */ static bool ans_ctrl_pt_sup_check(ans_ctrl_pt_t *p_ctrl_pt) { - if (ANS_CTRL_PT_NTF_UNREAD_CAT_STA_IMME < p_ctrl_pt->cmd_id) { + if (ANS_CTRL_PT_NTF_UNREAD_CAT_STA_IMME < p_ctrl_pt->cmd_id) + { return false; } - if (ANS_CAT_ID_INSTANT_MES < p_ctrl_pt->cat_id && ANS_CAT_ID_ALL != p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_INSTANT_MES < p_ctrl_pt->cat_id && ANS_CAT_ID_ALL != p_ctrl_pt->cat_id) + { return false; } if ((ANS_CTRL_PT_EN_NEW_INC_ALERT_NTF == p_ctrl_pt->cmd_id) && \ (ANS_CTRL_PT_DIS_NEW_INC_ALERT_NTF == p_ctrl_pt->cmd_id) && \ - (ANS_CTRL_PT_NTF_NEW_INC_ALERT_IMME == p_ctrl_pt->cmd_id)) { - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { - if (s_ans_env.ans_init.sup_new_alert_cat == 0) { + (ANS_CTRL_PT_NTF_NEW_INC_ALERT_IMME == p_ctrl_pt->cmd_id)) + { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { + if ( 0 == s_ans_env.ans_init.sup_new_alert_cat) + { return false; } - } else if (!(s_ans_env.ans_init.sup_new_alert_cat & (1 << p_ctrl_pt->cat_id))) { + } + else if (!(s_ans_env.ans_init.sup_new_alert_cat & (1 << p_ctrl_pt->cat_id))) + { return false; } - } else { - if (p_ctrl_pt->cat_id == ANS_CAT_ID_ALL) { - if (s_ans_env.ans_init.sup_new_alert_cat == 0) { + } + else + { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { + if ( 0 == s_ans_env.ans_init.sup_new_alert_cat) + { return false; } - } else if (!(s_ans_env.ans_init.sup_unread_alert_sta & (1 << p_ctrl_pt->cat_id))) { + } + else if (!(s_ans_env.ans_init.sup_unread_alert_sta & ( 1 << p_ctrl_pt->cat_id))) + { return false; } } @@ -493,47 +441,63 @@ static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt) event.evt_type = ANS_EVT_INVALID; event.conn_idx = conn_idx; - switch (p_ctrl_pt->cmd_id) { + switch (p_ctrl_pt->cmd_id) + { case ANS_CTRL_PT_EN_NEW_INC_ALERT_NTF: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { s_ans_env.ntf_new_alert_cfg |= s_ans_env.ans_init.sup_new_alert_cat; - } else { + } + else + { s_ans_env.ntf_new_alert_cfg |= 1 << p_ctrl_pt->cat_id; } break; case ANS_CTRL_PT_EN_UNREAD_CAT_STA_NTF: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { s_ans_env.ntf_unread_alert_cfg |= s_ans_env.ans_init.sup_new_alert_cat; - } else { + } + else + { s_ans_env.ntf_unread_alert_cfg |= 1 << p_ctrl_pt->cat_id; } break; case ANS_CTRL_PT_DIS_NEW_INC_ALERT_NTF: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { s_ans_env.ntf_new_alert_cfg &= ~s_ans_env.ans_init.sup_new_alert_cat; - } else { + } + else + { s_ans_env.ntf_new_alert_cfg &= ~(1 << p_ctrl_pt->cat_id); } break; case ANS_CTRL_PT_DIS_UNREAD_CAT_STA_NTF: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { s_ans_env.ntf_unread_alert_cfg &= ~s_ans_env.ans_init.sup_unread_alert_sta; - } else { + } + else + { s_ans_env.ntf_unread_alert_cfg &= ~(1 << p_ctrl_pt->cat_id); } break; case ANS_CTRL_PT_NTF_NEW_INC_ALERT_IMME: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { event.cat_ids = s_ans_env.ntf_new_alert_cfg; - } else { + } + else + { event.cat_ids = 1 << p_ctrl_pt->cat_id; } @@ -541,9 +505,12 @@ static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt) break; case ANS_CTRL_PT_NTF_UNREAD_CAT_STA_IMME: - if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) { + if (ANS_CAT_ID_ALL == p_ctrl_pt->cat_id) + { event.cat_ids = s_ans_env.ntf_unread_alert_cfg; - } else { + } + else + { event.cat_ids = 1 << p_ctrl_pt->cat_id; } @@ -554,7 +521,8 @@ static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt) break; } - if (ANS_EVT_INVALID != event.evt_type && s_ans_env.ans_init.evt_handler) { + if (ANS_EVT_INVALID != event.evt_type && s_ans_env.ans_init.evt_handler) + { s_ans_env.ans_init.evt_handler(&event); } } @@ -572,56 +540,86 @@ static void ans_ctrl_pt_handler(uint8_t conn_idx, ans_ctrl_pt_t *p_ctrl_pt) static uint16_t ans_new_alert_encode(ans_new_alert_t *p_new_alert, uint8_t *p_buff) { uint16_t length = 0; - uint16_t ret; p_buff[length++] = p_new_alert->cat_id; p_buff[length++] = p_new_alert->alert_num; - if (0 < p_new_alert->length) { - ret = memcpy_s(&p_buff[length], p_new_alert->length, p_new_alert->str_info, p_new_alert->length); - if (ret < 0) { - return ret; - } + if (0 < p_new_alert->length) + { + memcpy(&p_buff[length], p_new_alert->str_info, p_new_alert->length); } return (length + p_new_alert->length); } +static void ans_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GAPC_EVT_CONNECTED: + ans_connected_evt_handler(p_evt->evt.gapc_evt.index); + break; + + case BLE_GATTS_EVT_READ_REQUEST: + ans_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + ans_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + ans_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ans_new_alert_send(uint8_t conn_idx, ans_new_alert_t *p_new_alert) { - uint8_t encoded_new_alert[ANS_NEWS_ALERT_VAL_LEN]; - gatts_noti_ind_t new_alert_ntf; - uint16_t length; + uint8_t encoded_new_alert[ANS_NEWS_ALERT_VAL_LEN]; + ble_gatts_noti_ind_t new_alert_ntf; + uint16_t length; length = ans_new_alert_encode(p_new_alert, encoded_new_alert); - if (ANS_UTF_8_STR_LEN_MAX < p_new_alert->length) { + + if (ANS_UTF_8_STR_LEN_MAX < p_new_alert->length) + { return SDK_ERR_INVALID_PARAM; } - if (ANS_CAT_ID_INSTANT_MES < p_new_alert->cat_id) { + if (ANS_CAT_ID_INSTANT_MES < p_new_alert->cat_id) + { return SDK_ERR_INVALID_PARAM; } - if (!(s_ans_env.ans_init.sup_new_alert_cat & (1 << p_new_alert->cat_id))) { + if (!(s_ans_env.ans_init.sup_new_alert_cat & (1 << p_new_alert->cat_id))) + { return SDK_ERR_INVALID_PARAM; } - if (PRF_CLI_START_NTF != s_ans_env.new_alert_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF != s_ans_env.new_alert_ntf_cfg[conn_idx]) + { return SDK_ERR_NTF_DISABLED; } - if (!(s_ans_env.ntf_new_alert_cfg & (1 << p_new_alert->cat_id))) { + if (!(s_ans_env.ntf_new_alert_cfg & (1 << p_new_alert->cat_id))) + { return SDK_ERR_NTF_DISABLED; } new_alert_ntf.type = BLE_GATT_NOTIFICATION; new_alert_ntf.handle = prf_find_handle_by_idx(ANS_IDX_NEWS_ALERT_VAL, - s_ans_env.start_hdl, - (uint8_t *)&s_ans_char_mask); + s_ans_env.start_hdl, + (uint8_t *)&s_ans_char_mask); new_alert_ntf.length = length; new_alert_ntf.value = encoded_new_alert; @@ -630,32 +628,37 @@ sdk_err_t ans_new_alert_send(uint8_t conn_idx, ans_new_alert_t *p_new_alert) sdk_err_t ans_unread_alert_send(uint8_t conn_idx, ans_unread_alert_t *p_unread_alert) { - uint8_t encoded_unread_alert[ANS_UNREAD_ALERT_STA_VAL_LEN]; - gatts_noti_ind_t unread_alert_ntf; + uint8_t encoded_unread_alert[ANS_UNREAD_ALERT_STA_VAL_LEN]; + ble_gatts_noti_ind_t unread_alert_ntf; encoded_unread_alert[0] = p_unread_alert->cat_id; encoded_unread_alert[1] = p_unread_alert->unread_num; - if (ANS_CAT_ID_INSTANT_MES < p_unread_alert->cat_id) { + + if (ANS_CAT_ID_INSTANT_MES < p_unread_alert->cat_id) + { return SDK_ERR_INVALID_PARAM; } - if (!(s_ans_env.ans_init.sup_unread_alert_sta & (1 << p_unread_alert->cat_id))) { + if (!(s_ans_env.ans_init.sup_unread_alert_sta & (1 << p_unread_alert->cat_id))) + { return SDK_ERR_INVALID_PARAM; } - if (PRF_CLI_START_NTF != s_ans_env.unread_alert_sta_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF != s_ans_env.unread_alert_sta_ntf_cfg[conn_idx]) + { return SDK_ERR_NTF_DISABLED; } - if (!(s_ans_env.ntf_unread_alert_cfg & (1 << p_unread_alert->cat_id))) { + if (!(s_ans_env.ntf_unread_alert_cfg & (1 << p_unread_alert->cat_id))) + { return SDK_ERR_NTF_DISABLED; } unread_alert_ntf.type = BLE_GATT_NOTIFICATION; unread_alert_ntf.handle = prf_find_handle_by_idx(ANS_IDX_UNREAD_ALERT_STA_VAL, - s_ans_env.start_hdl, - (uint8_t *)&s_ans_char_mask); + s_ans_env.start_hdl, + (uint8_t *)&s_ans_char_mask); unread_alert_ntf.length = ANS_UNREAD_ALERT_STA_VAL_LEN; unread_alert_ntf.value = encoded_unread_alert; @@ -664,16 +667,23 @@ sdk_err_t ans_unread_alert_send(uint8_t conn_idx, ans_unread_alert_t *p_unread_a sdk_err_t ans_service_init(ans_init_t *p_ans_init) { - sdk_err_t ret; - if (p_ans_init == NULL) { + if (NULL == p_ans_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_ans_env.ans_init, sizeof(ans_init_t), p_ans_init, sizeof(ans_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_ans_env.ans_init, p_ans_init, sizeof(ans_init_t)); - return ble_server_prf_add(&ans_prf_info); + s_ans_env.start_hdl = PRF_INVALID_HANDLE; + + s_ans_env.ans_gatts_db.shdl = &s_ans_env.start_hdl; + s_ans_env.ans_gatts_db.uuid = s_ans_svc_uuid; + s_ans_env.ans_gatts_db.attr_tab_cfg = (uint8_t *)&s_ans_char_mask; + s_ans_env.ans_gatts_db.max_nb_attr = ANS_IDX_NB; + s_ans_env.ans_gatts_db.srvc_perm = 0; + s_ans_env.ans_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_ans_env.ans_gatts_db.attr_tab.attr_tab_16 = ans_attr_tab; + + return ble_gatts_prf_add(&s_ans_env.ans_gatts_db, ans_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.h index 4b11f1e..924e352 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans/ans.h @@ -46,7 +46,7 @@ * @brief Alert Notification Service module. * * @details The Alert Notification Service exposes alert information in a device. This information - * includes the following:Type of alert occurring in a device, Additional text information + * includes the following: Type of alert occurring in a device, Additional text information * such as caller ID or sender ID, Count of new alerts and Count of unread alert items. * * After \ref ans_init_t variable is intialized, the application must call \ref ans_service_init() @@ -58,24 +58,23 @@ #ifndef __ANS_H__ #define __ANS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup ANS_MACRO Defines * @{ */ -#define ANS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Alert Notification Service connections. */ -#define ANS_ERROR_CMD_NOT_SUP 0xa0 /**< Command not supported. */ -#define ANS_UTF_8_STR_LEN_MAX 18 /**< Maximum length of “UTF-8 stringâ€. */ -#define ANS_SUP_NEW_ALERT_CAT_VAL_LEN 2 /**< Length of Supported New Alert Category value. */ -#define ANS_NEWS_ALERT_VAL_LEN (ANS_UTF_8_STR_LEN_MAX + 2) /**< Length of New Alert value. */ -#define ANS_SUP_UNREAD_ALERT_CAT_VAL_LEN 2 /**< Length of Supported Unread Alert Category value. */ -#define ANS_UNREAD_ALERT_STA_VAL_LEN 2 /**< Length of Unread Alert Status value. */ -#define ANS_ALERT_NTF_CTRL_PT_VAL_LEN 2 /**< Length of Alert Notification Control Point value. */ +#define ANS_CONNECTION_MAX 10 /**< Maximum number of Alert Notification Service connections. */ +#define ANS_ERROR_CMD_NOT_SUP 0xa0 /**< Command not supported. */ +#define ANS_UTF_8_STR_LEN_MAX 18 /**< Maximum length of “UTF-8 stringâ€. */ +#define ANS_SUP_NEW_ALERT_CAT_VAL_LEN 2 /**< Length of Supported New Alert Category value. */ +#define ANS_NEWS_ALERT_VAL_LEN (ANS_UTF_8_STR_LEN_MAX + 2) /**< Length of New Alert value. */ +#define ANS_SUP_UNREAD_ALERT_CAT_VAL_LEN 2 /**< Length of Supported Unread Alert Category value. */ +#define ANS_UNREAD_ALERT_STA_VAL_LEN 2 /**< Length of Unread Alert Status value. */ +#define ANS_ALERT_NTF_CTRL_PT_VAL_LEN 2 /**< Length of Alert Notification Control Point value. */ /** * @defgroup ANS_CAT_ID_BIT_MASK Category ID Bit Masks @@ -101,7 +100,8 @@ * @{ */ /**@brief Alert Notification Service Categories of alerts/messages. */ -typedef enum { +typedef enum +{ ANS_CAT_ID_SMPL_ALERT, /**< Simple Alert: General text alert or non-text alert. */ ANS_CAT_ID_EMAIL, /**< Email: Alert when Email messages arrive. */ ANS_CAT_ID_NEWS, /**< News: News feeds such as RSS, Atom. */ @@ -117,7 +117,8 @@ typedef enum { } ans_alert_cat_id_t; /**@brief Alert Notification Service Control point. */ -typedef enum { +typedef enum +{ ANS_CTRL_PT_EN_NEW_INC_ALERT_NTF, /**< Enable New Incoming Alert Notification. */ ANS_CTRL_PT_EN_UNREAD_CAT_STA_NTF, /**< Enable Unread Category Status Notification. */ ANS_CTRL_PT_DIS_NEW_INC_ALERT_NTF, /**< Disable New Incoming Alert Notification. */ @@ -127,16 +128,15 @@ typedef enum { } ans_ctrl_pt_id_t; /**@brief Alert Notification Service Event type. */ -typedef enum { +typedef enum +{ ANS_EVT_INVALID, /**< Invalid ANS event type. */ ANS_EVT_NEW_ALERT_NTF_ENABLE, /**< NEW Alert notification is enabled. */ ANS_EVT_NEW_ALERT_NTF_DISABLE, /**< NEW Alert notification is disabled. */ ANS_EVT_UNREAD_ALERT_STA_NTF_ENABLE, /**< Unread Alert Status notification is enabled. */ ANS_EVT_UNREAD_ALERT_STA_NTF_DISABLE, /**< Unread Alert Status notification is disabled. */ - ANS_EVT_NEW_ALERT_IMME_NTF_REQ, /**< Request: notify the New Alert characteristic \ - to the client immediately. */ - ANS_EVT_Unread_ALERT_IMME_NTF_REQ, /**< Request: notify the Unread Alert Status characteristic \ - to the client immediately. */ + ANS_EVT_NEW_ALERT_IMME_NTF_REQ, /**< Request: notify the New Alert characteristic to the client immediately. */ + ANS_EVT_Unread_ALERT_IMME_NTF_REQ, /**< Request: notify the Unread Alert Status characteristic to the client immediately. */ } ans_evt_type_t; /** @} */ @@ -145,7 +145,8 @@ typedef enum { * @{ */ /**@brief Alert Notification Service New Alert value. */ -typedef struct { +typedef struct +{ ans_alert_cat_id_t cat_id; /**< Category ID. */ uint8_t alert_num; /**< Number of new alert. */ uint8_t str_info[ANS_UTF_8_STR_LEN_MAX]; /**< Text String Information. */ @@ -153,19 +154,22 @@ typedef struct { } ans_new_alert_t; /**@brief Alert Notification Service Unread Alert Status value. */ -typedef struct { +typedef struct +{ ans_alert_cat_id_t cat_id; /**< Category ID. */ uint8_t unread_num; /**< Number of unread alert. */ } ans_unread_alert_t; /**@brief Alert Notification Service Control Point value. */ -typedef struct { +typedef struct +{ ans_ctrl_pt_id_t cmd_id; /**< Command ID. */ ans_alert_cat_id_t cat_id; /**< Category ID. */ } ans_ctrl_pt_t; /**@brief Alert Notification Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ ans_evt_type_t evt_type; /**< The ANS event type. */ uint16_t cat_ids; /**< Category IDs. */ @@ -184,9 +188,9 @@ typedef void (*ans_evt_handler_t)(ans_evt_t *p_evt); * @defgroup ANS_STRUCT Structures * @{ */ -/**@brief Alert Notification Service init stucture. \ - * This contains all options and data needed for initialization of the service. */ -typedef struct { +/**@brief Alert Notification Service init stucture. This contains all options and data needed for initialization of the service. */ +typedef struct +{ ans_evt_handler_t evt_handler; /**< Phone Alert Status Service event handler. */ uint16_t sup_new_alert_cat; /**< Initial mask of Supported New Alert Category. */ uint16_t sup_unread_alert_sta; /**< Initial mask of Unread Alert Status. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/BUILD.gn new file mode 100644 index 0000000..8dba5b5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ans_c") { + sources = [ "ans_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.c index 683343c..d9140ae 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.c @@ -39,65 +39,31 @@ * INCLUDE FILES **************************************************************************************** */ -#include -#include "utility.h" #include "ans_c.h" +#include "utility.h" +#include -#define INDEX_2 2 -#define LEN_2 2 -#define ATTR_VALUE_LEN 2 -#define UUID_OFFSET_8 8 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Alert Notification Service Client environment variable. */ -struct ans_c_env_t { +struct ans_c_env_t +{ ans_c_handles_t handles; /**< Handles of ANS characteristics which will be got for peer. */ ans_c_evt_handler_t evt_handler; /**< Handler of ANS Client event handler. */ - uint8_t prf_id; /**< ANS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void ans_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void ans_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void ans_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void ans_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct ans_c_env_t s_ans_c_env; /**< Alert Notification Service Client environment variable. */ - -/**@brief Alert Notification Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t ans_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Alert Notification Service GATT Client Callbacks. */ -static gattc_prf_cbs_t ans_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - ans_c_att_read_cb, - ans_c_att_write_cb, - ans_c_att_ntf_ind_cb, - ans_c_srvc_browse_cb, - NULL, -}; - -/**@brief Alert Notification Service Client Information. */ -static const prf_client_info_t ans_c_prf_info = { - .max_connection_nb = ANS_C_CONNECTION_MAX, - .manager_cbs = &ans_c_mgr_cbs, - .gattc_prf_cbs = &ans_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_ALERT_NTF), HI_U16(BLE_ATT_SVC_ALERT_NTF)}; +static ble_uuid_t s_ans_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -113,7 +79,8 @@ static const prf_client_info_t ans_c_prf_info = { */ static void ans_c_evt_handler_excute(ans_c_evt_t *p_evt) { - if (s_ans_c_env.evt_handler != NULL && ANS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_ans_c_env.evt_handler && ANS_C_EVT_INVALID != p_evt->evt_type) + { s_ans_c_env.evt_handler(p_evt); } } @@ -128,24 +95,19 @@ static void ans_c_evt_handler_excute(ans_c_evt_t *p_evt) */ static void ans_c_new_alert_decode(const uint8_t *p_data, uint16_t length, ans_c_new_alert_t *p_new_alert) { - uint8_t ret; - if (length < LEN_2) { + if (2 > length) + { return; } - ret = memset_s(p_new_alert, sizeof(ans_c_new_alert_t), 0, sizeof(ans_c_new_alert_t)); - if (ret < 0) { - return; - } + memset(p_new_alert, 0, sizeof(ans_c_new_alert_t)); p_new_alert->cat_id = (ans_c_alert_cat_id_t)p_data[0]; p_new_alert->alert_num = p_data[1]; - p_new_alert->length = length - LEN_2; + p_new_alert->length = length - 2; - if (length > LEN_2) { - ret = memcpy_s(p_new_alert->str_info, length - LEN_2, &p_data[INDEX_2], length - LEN_2); - if (ret < 0) { - return; - } + if (2 < length) + { + memcpy(p_new_alert->str_info, & p_data[2], length - 2); } } @@ -159,7 +121,8 @@ static void ans_c_new_alert_decode(const uint8_t *p_data, uint16_t length, ans_c */ static void ans_c_unread_decode(const uint8_t *p_data, uint16_t length, ans_c_unread_alert_t *p_unread_alert) { - if (length != 2) { + if (2 != length) + { return; } @@ -176,24 +139,26 @@ static void ans_c_unread_decode(const uint8_t *p_data, uint16_t length, ans_c_un * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void ans_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void ans_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { ans_c_evt_t ans_c_evt; ans_c_evt.conn_idx = conn_idx; ans_c_evt.evt_type = ANS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_ans_c_env.handles.ans_sup_new_alert_cat_handle) { + if (p_read_rsp->value[0].handle == s_ans_c_env.handles.ans_sup_new_alert_cat_handle) + { ans_c_evt.evt_type = ANS_C_EVT_SUP_NEW_ALERT_CAT_RECEIV; - ans_c_evt.value.sup_new_alert_cat_ids = BUILD_U16(p_read_rsp->vals[0].p_value[0], - p_read_rsp->vals[0].p_value[1]); - } else if (p_read_rsp->vals[0].handle == s_ans_c_env.handles.ans_sup_unread_alert_cat_handle) { + ans_c_evt.value.sup_new_alert_cat_ids = BUILD_U16(p_read_rsp->value[0].p_value[0], p_read_rsp->value[0].p_value[1]); + } + else if (p_read_rsp->value[0].handle == s_ans_c_env.handles.ans_sup_unread_alert_cat_handle) + { ans_c_evt.evt_type = ANS_C_EVT_SUP_UNREAD_ALERT_CAT_REC; - ans_c_evt.value.sup_unread_alert_cat_ids = BUILD_U16(p_read_rsp->vals[0].p_value[0], - p_read_rsp->vals[0].p_value[1]); + ans_c_evt.value.sup_unread_alert_cat_ids = BUILD_U16(p_read_rsp->value[0].p_value[0], p_read_rsp->value[0].p_value[1]); } ans_c_evt_handler_excute(&ans_c_evt); @@ -208,22 +173,27 @@ static void ans_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void ans_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void ans_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { ans_c_evt_t ans_c_evt; ans_c_evt.conn_idx = conn_idx; ans_c_evt.evt_type = ANS_C_EVT_INVALID; - if (handle == s_ans_c_env.handles.ans_new_alert_cccd_handle) { + if (handle == s_ans_c_env.handles.ans_new_alert_cccd_handle) + { ans_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - ANS_C_EVT_NEW_ALERT_NTF_SET_SUCCESS : - ANS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ans_c_env.handles.ans_unread_alert_cccd_handle) { + ANS_C_EVT_NEW_ALERT_NTF_SET_SUCCESS : + ANS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ans_c_env.handles.ans_unread_alert_cccd_handle) + { ans_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - ANS_C_EVT_UNREAD_ALERT_STA_NTF_SET_SUCCESS : - ANS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ans_c_env.handles.ans_ctrl_pt_handle) { + ANS_C_EVT_UNREAD_ALERT_STA_NTF_SET_SUCCESS : + ANS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ans_c_env.handles.ans_ctrl_pt_handle) + { ans_c_evt.evt_type = (BLE_SUCCESS == status) ? ANS_C_EVT_CTRL_POINT_SET_SUCCESS : \ ANS_C_EVT_WRITE_OP_ERR; @@ -241,17 +211,20 @@ static void ans_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void ans_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void ans_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { ans_c_evt_t ans_c_evt; ans_c_evt.conn_idx = conn_idx; ans_c_evt.evt_type = ANS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_ans_c_env.handles.ans_new_alert_handle) { + if (p_ntf_ind->handle == s_ans_c_env.handles.ans_new_alert_handle) + { ans_c_evt.evt_type = ANS_C_EVT_NEW_ALERT_RECEIVE; ans_c_new_alert_decode(p_ntf_ind->p_value, p_ntf_ind->length, &ans_c_evt.value.new_alert); - } else if (p_ntf_ind->handle == s_ans_c_env.handles.ans_unread_alert_handle) { + } + else if (p_ntf_ind->handle == s_ans_c_env.handles.ans_unread_alert_handle) + { ans_c_evt.evt_type = ANS_C_EVT_UNREAD_ALERT_RECEIVE; ans_c_unread_decode(p_ntf_ind->p_value, p_ntf_ind->length, &ans_c_evt.value.unread_alert); } @@ -268,7 +241,7 @@ static void ans_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void ans_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void ans_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { ans_c_evt_t ans_c_evt; uint16_t uuid_disc; @@ -277,154 +250,171 @@ static void ans_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat ans_c_evt.conn_idx = conn_idx; ans_c_evt.evt_type = ANS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << UUID_OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (uuid_disc != BLE_ATT_SVC_ALERT_NTF) { - return; - } + if (BLE_ATT_SVC_ALERT_NTF == uuid_disc) + { + s_ans_c_env.handles.ans_srvc_start_handle = p_browse_srvc->start_hdl; + s_ans_c_env.handles.ans_srvc_end_handle = p_browse_srvc->end_hdl; - s_ans_c_env.handles.ans_srvc_start_handle = p_browse_srvc->start_hdl; - s_ans_c_env.handles.ans_srvc_end_handle = p_browse_srvc->end_hdl; + for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) + { + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) { - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | \ - p_browse_srvc->info[i].attr.uuid[1] << UUID_OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; - - if (BLE_ATT_CHAR_SUP_NEW_ALERT_CAT == uuid_disc) { - s_ans_c_env.handles.ans_sup_new_alert_cat_handle = handle_disc; - } else if (BLE_ATT_CHAR_NEW_ALERT == uuid_disc) { - s_ans_c_env.handles.ans_new_alert_handle = handle_disc; - s_ans_c_env.handles.ans_new_alert_cccd_handle = handle_disc + 1; - } else if (BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT == uuid_disc) { - s_ans_c_env.handles.ans_sup_unread_alert_cat_handle = handle_disc; - } else if (BLE_ATT_CHAR_UNREAD_ALERT_STATUS == uuid_disc) { - s_ans_c_env.handles.ans_unread_alert_handle = handle_disc; - s_ans_c_env.handles.ans_unread_alert_cccd_handle = handle_disc + 1; - } else if (BLE_ATT_CHAR_ALERT_NTF_CTNL_PT == uuid_disc) { - s_ans_c_env.handles.ans_ctrl_pt_handle = handle_disc; + if (BLE_ATT_CHAR_SUP_NEW_ALERT_CAT == uuid_disc) + { + s_ans_c_env.handles.ans_sup_new_alert_cat_handle = handle_disc; + } + else if (BLE_ATT_CHAR_NEW_ALERT == uuid_disc) + { + s_ans_c_env.handles.ans_new_alert_handle = handle_disc; + s_ans_c_env.handles.ans_new_alert_cccd_handle = handle_disc + 1; + } + else if (BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT == uuid_disc) + { + s_ans_c_env.handles.ans_sup_unread_alert_cat_handle = handle_disc; + } + else if (BLE_ATT_CHAR_UNREAD_ALERT_STATUS == uuid_disc) + { + s_ans_c_env.handles.ans_unread_alert_handle = handle_disc; + s_ans_c_env.handles.ans_unread_alert_cccd_handle = handle_disc + 1; + } + else if (BLE_ATT_CHAR_ALERT_NTF_CTNL_PT == uuid_disc) + { + s_ans_c_env.handles.ans_ctrl_pt_handle = handle_disc; + } + } + else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; + } } - } else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; + + ans_c_evt.evt_type = ANS_C_EVT_DISCOVERY_COMPLETE; } } - ans_c_evt.evt_type = ANS_C_EVT_DISCOVERY_COMPLETE; - ans_c_evt_handler_excute(&ans_c_evt); } +static void ans_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + ans_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + ans_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + ans_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + ans_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ans_client_init(ans_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_ans_c_env, sizeof(s_ans_c_env), 0, sizeof(s_ans_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_ans_c_env, 0, sizeof(s_ans_c_env)); s_ans_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&ans_c_prf_info, &s_ans_c_env.prf_id); + return ble_gattc_prf_add(&s_ans_service_uuid, ans_c_ble_evt_handler); } sdk_err_t ans_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - target_uuid[0] = LO_U16(BLE_ATT_SVC_ALERT_NTF); - target_uuid[1] = HI_U16(BLE_ATT_SVC_ALERT_NTF); - - const ble_uuid_t ans_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_ans_c_env.prf_id, conn_idx, &ans_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_ans_service_uuid); } - sdk_err_t ans_c_new_alert_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_new_alert_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_new_alert_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ans_c_env.handles.ans_new_alert_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_ans_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ans_c_env.handles.ans_new_alert_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ans_c_unread_alert_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_unread_alert_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_unread_alert_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ans_c_env.handles.ans_unread_alert_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_ans_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ans_c_env.handles.ans_unread_alert_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ans_c_sup_new_alert_cat_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_sup_new_alert_cat_handle) { + if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_sup_new_alert_cat_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_ans_c_env.prf_id, conn_idx, s_ans_c_env.handles.ans_sup_new_alert_cat_handle, 0); + return ble_gattc_read(conn_idx, s_ans_c_env.handles.ans_sup_new_alert_cat_handle, 0); } sdk_err_t ans_c_sup_unread_alert_cat_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_sup_unread_alert_cat_handle) { + if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_sup_unread_alert_cat_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_ans_c_env.prf_id, conn_idx, s_ans_c_env.handles.ans_sup_unread_alert_cat_handle, 0); + return ble_gattc_read(conn_idx, s_ans_c_env.handles.ans_sup_unread_alert_cat_handle, 0); } sdk_err_t ans_c_ctrl_point_set(uint8_t conn_idx, ans_c_ctrl_pt_t *p_ctrl_pt) { - gattc_write_no_resp_t write_attr_value; uint8_t ctrl_pt_val[ANS_C_ALERT_NTF_CTRL_PT_VAL_LEN]; ctrl_pt_val[0] = p_ctrl_pt->cmd_id; ctrl_pt_val[1] = p_ctrl_pt->cat_id; - if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_ctrl_pt_handle) { + if (BLE_ATT_INVALID_HDL == s_ans_c_env.handles.ans_ctrl_pt_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_ans_c_env.handles.ans_ctrl_pt_handle; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = ctrl_pt_val; - - return ble_gattc_prf_write_no_resp(s_ans_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_ans_c_env.handles.ans_ctrl_pt_handle, 2, ctrl_pt_val); } + + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.h index 6235ef5..ca64b06 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ans_c/ans_c.h @@ -57,38 +57,37 @@ #ifndef __ANS_C_H__ #define __ANS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup ANS_C_MACRO Defines * @{ */ -#define ANS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections. */ -#define ANS_C_ERROR_CMD_NOT_SUP 0xa0 /**< Command not supported. */ -#define ANS_C_UTF_8_STR_LEN_MAX 18 /**< Maximum length of “UTF-8 stringâ€. */ -#define ANS_C_ALERT_NTF_CTRL_PT_VAL_LEN 2 /**< Length of Alert Notification Control Point value. */ +#define ANS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ +#define ANS_C_ERROR_CMD_NOT_SUP 0xa0 /**< Command not supported. */ +#define ANS_C_UTF_8_STR_LEN_MAX 18 /**< Maximum length of “UTF-8 stringâ€. */ +#define ANS_C_ALERT_NTF_CTRL_PT_VAL_LEN 2 /**< Length of Alert Notification Control Point value. */ /** * @defgroup ANS_C_CAT_ID_BIT_MASK Category ID Bit Masks * @{ * @brief Category ID Bit Masks. */ -#define ANS_SMPL_ALERT_SUP (0x01 << 0) /**< Bit for Simple Alert Supported. */ -#define ANS_EMAIL_SUP (0x01 << 1) /**< Bit for Email Supported. */ -#define ANS_NEWS_SUP (0x01 << 2) /**< Bit for News Supported. */ -#define ANS_CALL_SUP (0x01 << 3) /**< Bit for Call Supported. */ -#define ANS_MISSED_CALL_SUP (0x01 << 4) /**< Bit for Missed Call Supported. */ -#define ANS_SMS_MMS_SUP (0x01 << 5) /**< Bit for SMS/MMS Supported. */ -#define ANS_VOICE_MAIL_SUP (0x01 << 6) /**< Bit for Voice Mail Supported. */ -#define ANS_SCHEDULE_SUP (0x01 << 7) /**< Bit for Schedule Supported. */ -#define ANS_HG_PRIO_ALERT_SUP (0x01 << 8) /**< Bit for High Prioritized Alert Supported. */ -#define ANS_INSTANT_MES (0x01 << 9) /**< Bit for Instant Message Supported. */ -#define ANS_ALL_CAT_SUP (0x03ff) /**< Bit for All Category Supported. */ +#define ANS_C_SMPL_ALERT_SUP (0x01 << 0) /**< Bit for Simple Alert Supported. */ +#define ANS_C_EMAIL_SUP (0x01 << 1) /**< Bit for Email Supported. */ +#define ANS_C_NEWS_SUP (0x01 << 2) /**< Bit for News Supported. */ +#define ANS_C_CALL_SUP (0x01 << 3) /**< Bit for Call Supported. */ +#define ANS_C_MISSED_CALL_SUP (0x01 << 4) /**< Bit for Missed Call Supported. */ +#define ANS_C_SMS_MMS_SUP (0x01 << 5) /**< Bit for SMS/MMS Supported. */ +#define ANS_C_VOICE_MAIL_SUP (0x01 << 6) /**< Bit for Voice Mail Supported. */ +#define ANS_C_SCHEDULE_SUP (0x01 << 7) /**< Bit for Schedule Supported. */ +#define ANS_C_HG_PRIO_ALERT_SUP (0x01 << 8) /**< Bit for High Prioritized Alert Supported. */ +#define ANS_C_INSTANT_MES (0x01 << 9) /**< Bit for Instant Message Supported. */ +#define ANS_C_ALL_CAT_SUP (0x03ff) /**< Bit for All Category Supported. */ /** @} */ /** @} */ @@ -97,7 +96,8 @@ * @{ */ /**@brief Alert Notification Service Categories of alerts/messages. */ -typedef enum { +typedef enum +{ ANS_C_CAT_ID_SMPL_ALERT, /**< Simple Alert: General text alert or non-text alert. */ ANS_C_CAT_ID_EMAIL, /**< Email: Alert when Email messages arrives. */ ANS_C_CAT_ID_NEWS, /**< News: News feeds such as RSS, Atom. */ @@ -113,7 +113,8 @@ typedef enum { } ans_c_alert_cat_id_t; /**@brief Alert Notification Service Client Control point ID. */ -typedef enum { +typedef enum +{ ANS_C_CTRL_PT_EN_NEW_INC_ALERT_NTF, /**< Enable New Incoming Alert Notification. */ ANS_C_CTRL_PT_EN_UNREAD_CAT_STA_NTF, /**< Enable Unread Category Status Notification. */ ANS_C_CTRL_PT_DIS_NEW_INC_ALERT_NTF, /**< Disable New Incoming Alert Notification. */ @@ -123,21 +124,19 @@ typedef enum { } ans_c_ctrl_pt_id_t; /**@brief Alert Notification Service Client Event type. */ -typedef enum { +typedef enum +{ ANS_C_EVT_INVALID, /**< ANS Client invalid event type. */ ANS_C_EVT_DISCOVERY_COMPLETE, /**< ANS Client has found ANS service and its characteristics. */ - ANS_C_EVT_DISCOVERY_FAIL, /**< ANS Client found ANS service failed \ - because of invalid operation or no found at the peer. */ + ANS_C_EVT_DISCOVERY_FAIL , /**< ANS Client found ANS service failed because of invalid operation or no found at the peer. */ ANS_C_EVT_NEW_ALERT_NTF_SET_SUCCESS, /**< ANS Client has set NEW Alert notification. */ ANS_C_EVT_UNREAD_ALERT_STA_NTF_SET_SUCCESS, /**< ANS Client has set Unread Alert Status notification. */ - ANS_C_EVT_SUP_NEW_ALERT_CAT_RECEIV, /**< ANS Client has received Supported New Alert Category value \ - (Read from peer). */ - ANS_C_EVT_SUP_UNREAD_ALERT_CAT_REC, /**< ANS Client has received Supported Unread Alert Category value \ - (Read from peer). */ - ANS_C_EVT_NEW_ALERT_RECEIVE, /**< ANS Client has received New Alert value (Notification from peer). */ - ANS_C_EVT_UNREAD_ALERT_RECEIVE, /**< ANS Client has received Unread Alert Status value (Notification from peer). */ - ANS_C_EVT_CTRL_POINT_SET_SUCCESS, /**< ANS Client has written Control Point completely. */ - ANS_C_EVT_WRITE_OP_ERR, /**< Error occured when ANS Client wrote to peer. */ + ANS_C_EVT_SUP_NEW_ALERT_CAT_RECEIV, /**< ANS Client has received Supported New Alert Category value (Read from peer). */ + ANS_C_EVT_SUP_UNREAD_ALERT_CAT_REC, /**< ANS Client has received Supported Unread Alert Category value (Read from peer). */ + ANS_C_EVT_NEW_ALERT_RECEIVE, /**< ANS Client has received New Alert value (Notification from peer). */ + ANS_C_EVT_UNREAD_ALERT_RECEIVE, /**< ANS Client has received Unread Alert Status value (Notification from peer). */ + ANS_C_EVT_CTRL_POINT_SET_SUCCESS, /**< ANS Client has written Control Point completely. */ + ANS_C_EVT_WRITE_OP_ERR, /**< Error occured when ANS Client wrote to peer. */ } ans_c_evt_type_t; /** @} */ @@ -146,7 +145,8 @@ typedef enum { * @{ */ /**@brief Alert Notification Service Client decoded New Alert value. */ -typedef struct { +typedef struct +{ ans_c_alert_cat_id_t cat_id; /**< Category ID. */ uint8_t alert_num; /**< Number of new alert. */ uint8_t str_info[ANS_C_UTF_8_STR_LEN_MAX]; /**< Text String Information. */ @@ -154,42 +154,40 @@ typedef struct { } ans_c_new_alert_t; /**@brief Alert Notification Service Client decoded Unread Alert Status value. */ -typedef struct { +typedef struct +{ ans_c_alert_cat_id_t cat_id; /**< Category ID. */ uint8_t unread_num; /**< Number of unread alert. */ } ans_c_unread_alert_t; /**@brief Alert Notification Service Client Control Point value. */ -typedef struct { +typedef struct +{ ans_c_ctrl_pt_id_t cmd_id; /**< Command ID. */ ans_c_alert_cat_id_t cat_id; /**< Category ID. */ } ans_c_ctrl_pt_t; /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t ans_srvc_start_handle; /**< ANS Service start handle. */ uint16_t ans_srvc_end_handle; /**< ANS Service end handle. */ - uint16_t ans_sup_new_alert_cat_handle; /**< ANS Supported New Alert Category characteristic Value handle \ - which has been got from peer. */ - uint16_t ans_new_alert_handle; /**< ANS New Alert characteristic Value handle \ - which has been got from peer. */ - uint16_t ans_new_alert_cccd_handle; /**< ANS CCCD handle of New Alert characteristic \ - which has been got from peer. */ - uint16_t ans_sup_unread_alert_cat_handle; /**< ANS Supported Unread Alert Category characteristic Value handle \ - which has been got from peer. */ - uint16_t ans_unread_alert_handle; /**< ANS Unread Alert characteristic Value handle \ - which has been got from peer. */ - uint16_t ans_unread_alert_cccd_handle; /**< ANS CCCD handle of Unread Alert characteristic \ - which has been got from peer. */ - uint16_t ans_ctrl_pt_handle; /**< ANS Control Point characteristic Value handle \ - which has been got from peer. */ + uint16_t ans_sup_new_alert_cat_handle; /**< ANS Supported New Alert Category characteristic Value handle which has been got from peer. */ + uint16_t ans_new_alert_handle; /**< ANS New Alert characteristic Value handle which has been got from peer. */ + uint16_t ans_new_alert_cccd_handle; /**< ANS CCCD handle of New Alert characteristic which has been got from peer. */ + uint16_t ans_sup_unread_alert_cat_handle; /**< ANS Supported Unread Alert Category characteristic Value handle which has been got from peer. */ + uint16_t ans_unread_alert_handle; /**< ANS Unread Alert characteristic Value handle which has been got from peer. */ + uint16_t ans_unread_alert_cccd_handle; /**< ANS CCCD handle of Unread Alert characteristic which has been got from peer. */ + uint16_t ans_ctrl_pt_handle; /**< ANS Control Point characteristic Value handle which has been got from peer. */ } ans_c_handles_t; /**@brief Alert Notification Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ ans_c_evt_type_t evt_type; /**< The ANS event type. */ - union { + union + { uint16_t sup_new_alert_cat_ids; /**< Alert status received. */ uint16_t sup_unread_alert_cat_ids; /**< Ringer setting received. */ ans_c_new_alert_t new_alert; /**< New Alert value. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/BUILD.gn new file mode 100644 index 0000000..fe6a833 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("bas") { + sources = [ "bas.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.c index f660996..df4f8fd 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.c @@ -49,7 +49,8 @@ ***************************************************************************************** */ /**@brief Battery Service Attributes Indexes. */ -enum bas_attr_idx_t { +enum bas_attr_idx_t +{ BAS_IDX_SVC, BAS_IDX_BATT_LVL_CHAR, @@ -65,125 +66,49 @@ enum bas_attr_idx_t { ***************************************************************************************** */ /**@brief Battery Service environment variable. */ -struct bas_env_t { - bas_init_t bas_init; /**< Battery Service initialization variables. */ - uint16_t start_hdl; /**< Battery Service start handle. */ - uint16_t - ntf_cfg[BAS_CONNECTION_MAX]; /**< The configuration of Battery Level Notification \ - which is configured by the peer devices. */ - prf_char_pres_fmt_t - batt_level_pres_format; /**< Battery Level Characteristic Presentation Format \ - which should not change during connection. */ +struct bas_env_t +{ + bas_init_t bas_init; /**< Battery Service initialization variables. */ + uint16_t start_hdl; /**< Battery Service start handle. */ + uint16_t ntf_cfg[BAS_CONNECTION_MAX]; /**< The configuration of Battery Level Notification which is configured by the peer devices. */ + prf_char_pres_fmt_t batt_level_pres_format; /**< Battery Level Characteristic Presentation Format which should not change during connection. */ + ble_gatts_create_db_t bas_gatts_db; /**< Battery Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t bas_init(void); -static void bas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void bas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void bas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct bas_env_t s_bas_env[BAS_INSTANCE_MAX]; /**< Battery service instance. */ static uint8_t s_bas_ins_cnt = 0; /**< Number of Battery Server task instances. */ +static const uint8_t s_bas_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BATTERY_SERVICE); /**@brief Full BAS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_t bas_attr_tab[BAS_IDX_NB] = { +static const ble_gatts_attm_desc_t bas_attr_tab[BAS_IDX_NB] = +{ // Battery Service Declaration - [BAS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [BAS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Battery Level Characteristic - Declaration - [BAS_IDX_BATT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BAS_IDX_BATT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Battery Level Characteristic - Value - [BAS_IDX_BATT_LVL_VAL] = { - BLE_ATT_CHAR_BATTERY_LEVEL, - READ_PERM_UNSEC | NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - BAS_LVL_MAX_LEN - }, + [BAS_IDX_BATT_LVL_VAL] = {BLE_ATT_CHAR_BATTERY_LEVEL, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + BAS_LVL_MAX_LEN}, // Battery Level Characteristic - Client Characteristic Configuration Descriptor - [BAS_IDX_BATT_LVL_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - 0 - }, + [BAS_IDX_BATT_LVL_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + 0}, // Battery Level Characteristic - Characteristic Presentation Format Descriptor - [BAS_IDX_BATT_LVL_PRES_FMT] = {BLE_ATT_DESC_CHAR_PRES_FORMAT, READ_PERM_UNSEC, ATT_VAL_LOC_USER, 0}, -}; - -/**@brief Battery Service interface required by profile manager. */ -static ble_prf_manager_cbs_t bas_mgr_cbs = { - (prf_init_func_t)bas_init, - NULL, - NULL -}; - -/**@brief Battery GATT Server Callbacks. */ -static gatts_prf_cbs_t bas_gatts_cbs = { - bas_read_att_cb, - bas_write_att_cb, - NULL, - NULL, - bas_cccd_set_cb -}; - -/**@brief Battery Service Information. */ -static const prf_server_info_t bas_prf_info = { - .max_connection_nb = BAS_CONNECTION_MAX, - .manager_cbs = &bas_mgr_cbs, - .gatts_prf_cbs = &bas_gatts_cbs + [BAS_IDX_BATT_LVL_PRES_FMT] = {BLE_ATT_DESC_CHAR_PRES_FORMAT, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Battery service and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t bas_init(void) -{ - const uint8_t bas_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BATTERY_SERVICE); - sdk_err_t error_code = SDK_SUCCESS; - uint16_t start_hdl; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - for (uint8_t i = 0; i < s_bas_ins_cnt; i++) { - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - start_hdl = PRF_INVALID_HANDLE; - gatts_db.shdl = &start_hdl; - gatts_db.uuid = bas_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_bas_env[i].bas_init.char_mask; - gatts_db.max_nb_attr = BAS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = bas_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_bas_env[i].start_hdl = *(gatts_db.shdl); - } else { - return error_code; - } - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -192,28 +117,32 @@ static sdk_err_t bas_init(void) * @param[in] p_param: Point to the parameters of the read request. ***************************************************************************************** */ -static void bas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void bas_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - uint8_t handle = p_param->handle; - uint8_t tab_index; - uint8_t char_pres_value[PRF_CHAR_PRES_FMT_SIZE]; - uint8_t i; - gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index; + uint8_t char_pres_value[PRF_CHAR_PRES_FMT_SIZE]; + uint8_t i; + ble_gatts_read_cfm_t cfm; cfm.handle = handle; cfm.status = BLE_SUCCESS; - for (i = 0; i < s_bas_ins_cnt; i++) { + for (i = 0; i < s_bas_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_bas_env[i].start_hdl, BAS_IDX_NB, &s_bas_env[i].bas_init.char_mask); - if (tab_index > 0) { + + if (tab_index > 0) + { break; } } - switch (tab_index) { + switch (tab_index) + { case BAS_IDX_BATT_LVL_VAL: cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)(&s_bas_env[i].bas_init.batt_lvl); @@ -247,35 +176,39 @@ static void bas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in] p_param Point to the parameters of the write request. ***************************************************************************************** */ -static void bas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void bas_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t cccd_value = 0; - uint8_t tab_index = 0; - uint8_t i = 0; - bas_evt_t bas_evt; - gatts_write_cfm_t cfm; + uint16_t handle = p_param->handle; + uint16_t cccd_value = 0; + uint8_t tab_index = 0; + uint8_t i = 0; + bas_evt_t bas_evt; + ble_gatts_write_cfm_t cfm; cfm.handle = handle; cfm.status = BLE_SUCCESS; - for (i = 0; i < s_bas_ins_cnt; i++) { + for (i = 0; i < s_bas_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_bas_env[i].start_hdl, BAS_IDX_NB, &s_bas_env[i].bas_init.char_mask); - if (tab_index > 0) { + + if (tab_index > 0) + { break; } } - switch (tab_index) { + switch (tab_index) + { case BAS_IDX_BATT_LVL_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); s_bas_env[i].ntf_cfg[conn_idx] = cccd_value; bas_evt.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ - BAS_EVT_NOTIFICATION_ENABLED : \ - BAS_EVT_NOTIFICATION_DISABLED); + BAS_EVT_NOTIFICATION_ENABLED : \ + BAS_EVT_NOTIFICATION_DISABLED); break; default: @@ -284,8 +217,9 @@ static void bas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par } if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && \ - BAS_EVT_INVALID != bas_evt.evt_type && \ - s_bas_env[i].bas_init.evt_handler) { + BAS_EVT_INVALID != bas_evt.evt_type && \ + s_bas_env[i].bas_init.evt_handler) + { bas_evt.conn_idx = conn_idx; s_bas_env[i].bas_init.evt_handler(&bas_evt); } @@ -302,32 +236,37 @@ static void bas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void bas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void bas_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; uint8_t i = 0; bas_evt_t bas_evt; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } - for (i = 0; i < s_bas_ins_cnt; i++) { + for (i = 0; i < s_bas_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_bas_env[i].start_hdl, BAS_IDX_NB, &s_bas_env[i].bas_init.char_mask); - if (tab_index > 0) { + + if (tab_index > 0) + { break; } } - switch (tab_index) { + switch (tab_index) + { case BAS_IDX_BATT_LVL_NTF_CFG: s_bas_env[i].ntf_cfg[conn_idx] = cccd_value; bas_evt.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ - BAS_EVT_NOTIFICATION_ENABLED : \ - BAS_EVT_NOTIFICATION_DISABLED); + BAS_EVT_NOTIFICATION_ENABLED : \ + BAS_EVT_NOTIFICATION_DISABLED); break; default: @@ -335,25 +274,51 @@ static void bas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (BAS_EVT_INVALID != bas_evt.evt_type && s_bas_env[i].bas_init.evt_handler) { + if (BAS_EVT_INVALID != bas_evt.evt_type && s_bas_env[i].bas_init.evt_handler) + { bas_evt.conn_idx = conn_idx; s_bas_env[i].bas_init.evt_handler(&bas_evt); } } +static void bas_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + bas_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + bas_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + bas_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ******************************************************************************* */ sdk_err_t bas_batt_lvl_update(uint8_t conn_idx, uint8_t ins_idx, uint8_t batt_lvl) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_cmd; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t send_cmd; - if (ins_idx <= s_bas_ins_cnt) { + if (ins_idx <= s_bas_ins_cnt) + { s_bas_env[ins_idx].bas_init.batt_lvl = batt_lvl; - if (PRF_CLI_START_NTF == s_bas_env[ins_idx].ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_bas_env[ins_idx].ntf_cfg[conn_idx]) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; send_cmd.handle = prf_find_handle_by_idx(BAS_IDX_BATT_LVL_VAL, @@ -373,24 +338,42 @@ sdk_err_t bas_batt_lvl_update(uint8_t conn_idx, uint8_t ins_idx, uint8_t batt_lv sdk_err_t bas_service_init(bas_init_t *p_bas_init, uint8_t ins_num) { - sdk_err_t ret; - if (p_bas_init == NULL) { + sdk_err_t error_code = SDK_SUCCESS; + + if (NULL == p_bas_init) + { return SDK_ERR_POINTER_NULL; } - if (ins_num > BAS_INSTANCE_MAX) { + if (ins_num > BAS_INSTANCE_MAX) + { return SDK_ERR_INVALID_PARAM; } - for (uint8_t i = 0; i < ins_num; i++) { - ret = memcpy_s(&s_bas_env[i].bas_init, sizeof(bas_init_t), &p_bas_init[i], sizeof(bas_init_t)); - if (ret < 0) { - return ret; + for (uint8_t i = 0; i < ins_num; i++) + { + memcpy(&s_bas_env[i].bas_init, &p_bas_init[i], sizeof(bas_init_t)); + s_bas_env[i].start_hdl = PRF_INVALID_HANDLE; + s_bas_env[i].bas_gatts_db.shdl = &s_bas_env[i].start_hdl; + s_bas_env[i].bas_gatts_db.uuid = s_bas_svc_uuid; + s_bas_env[i].bas_gatts_db.attr_tab_cfg = (uint8_t *)&s_bas_env[i].bas_init.char_mask; + s_bas_env[i].bas_gatts_db.max_nb_attr = BAS_IDX_NB; + s_bas_env[i].bas_gatts_db.srvc_perm = 0; + s_bas_env[i].bas_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_bas_env[i].bas_gatts_db.attr_tab.attr_tab_16 = bas_attr_tab; + error_code = ble_gatts_prf_add(&s_bas_env[i].bas_gatts_db, bas_ble_evt_handler); + if(error_code) + { + return error_code; } } s_bas_ins_cnt = ins_num; - return ble_server_prf_add(&bas_prf_info); + return error_code; } +uint16_t bas_service_start_handle_get(void) +{ + return s_bas_env[0].start_hdl; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.h index b21252f..3b810df 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas/bas.h @@ -69,20 +69,16 @@ #ifndef __BAS_H__ #define __BAS_H__ +#include "gr_includes.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup BAS_MACRO Defines * @{ */ -#define BAS_INSTANCE_MAX 1 /**< Maximum number of Battery Service instances. \ - The value is configurable. */ -#define BAS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of BAS connections. - The value is configurable. */ +#define BAS_INSTANCE_MAX 1 /**< Maximum number of Battery Service instances. The value is configurable. */ +#define BAS_CONNECTION_MAX 10 /**< Maximum number of BAS connections.The value is configurable. */ #define BAS_LVL_MAX_LEN 1 /**< Maximun length of battery level value. */ /** @@ -102,7 +98,8 @@ * @{ */ /**@brief Battery Service event types. */ -typedef enum { +typedef enum +{ BAS_EVT_INVALID, /**< Indicate that it's an invalid event. */ BAS_EVT_NOTIFICATION_ENABLED, /**< Indicate that notification has been enabled. */ BAS_EVT_NOTIFICATION_DISABLED, /**< Indicate that notification has been disabled. */ @@ -114,7 +111,8 @@ typedef enum { * @{ */ /**@brief Battery Service event. */ -typedef struct { +typedef struct +{ bas_evt_type_t evt_type; /**< The BAS event type. */ uint8_t conn_idx; /**< The index of the connection. */ } bas_evt_t; @@ -132,12 +130,11 @@ typedef void (*bas_evt_handler_t)(bas_evt_t *p_evt); * @defgroup BAS_STRUCT Structures * @{ */ -/**@brief Battery Service init structure. - * This contains all options and data needed for initialization of the service. */ -typedef struct { +/**@brief Battery Service init structure. This contains all options and data needed for initialization of the service. */ +typedef struct +{ bas_evt_handler_t evt_handler; /**< Battery Service event handler. */ - uint8_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref BAS_CHAR_MASK */ + uint8_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref BAS_CHAR_MASK */ uint8_t batt_lvl; /**< Initial value of Battery Level characteristic. */ } bas_init_t; /** @} */ @@ -156,7 +153,7 @@ typedef struct { * @return Result of service initialization. ***************************************************************************************** */ -sdk_err_t bas_service_init(bas_init_t bas_init[], uint8_t ins_num); +sdk_err_t bas_service_init(bas_init_t bas_init[],uint8_t ins_num); /** ***************************************************************************************** @@ -170,6 +167,16 @@ sdk_err_t bas_service_init(bas_init_t bas_init[], uint8_t ins_num); ***************************************************************************************** */ sdk_err_t bas_batt_lvl_update(uint8_t conn_idx, uint8_t ins_idx, uint8_t batt_lvl); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the bas service start handle . + * + * @return The bas service start handle. + ***************************************************************************************** + */ +uint16_t bas_service_start_handle_get(void); + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/BUILD.gn new file mode 100644 index 0000000..2f9fe2e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("bas_c") { + sources = [ "bas_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.c index e035df7..53df13b 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.c @@ -39,66 +39,33 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "bas_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "bas_c.h" +#include -#define UUID_OFFSET_8 8 -#define ATTR_VALUE_LEN 2 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Battery Service environment variable. */ -struct bas_c_env_t { +struct bas_c_env_t +{ bas_c_handles_t handles; /**< Handles of BAS characteristics which will be got for peer. */ bas_c_evt_handler_t evt_handler; /**< Handler of BAS Client event */ - uint8_t prf_id; /**< BAS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void bas_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void bas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void bas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void bas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct bas_c_env_t s_bas_c_env; /**< Battery Service Client environment variable. */ - -/**@brief Battery Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t bas_c_mgr_cbs = { - NULL, - NULL, - NULL +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_BATTERY_SERVICE), HI_U16(BLE_ATT_SVC_BATTERY_SERVICE)}; +static ble_uuid_t s_bas_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; - -/**@brief Battery Service GATT Client Callbacks. */ -static gattc_prf_cbs_t bas_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - bas_c_att_read_cb, - bas_c_att_write_cb, - bas_c_att_ntf_ind_cb, - bas_c_srvc_browse_cb, - NULL, -}; - -/**@brief Battery Service Client Information. */ -static const prf_client_info_t bas_c_prf_info = { - .max_connection_nb = BAS_C_CONNECTION_MAX, - .manager_cbs = &bas_c_mgr_cbs, - .gattc_prf_cbs = &bas_c_gattc_cbs -}; - /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -112,7 +79,8 @@ static const prf_client_info_t bas_c_prf_info = { */ void bas_c_evt_handler_excute(bas_c_evt_t *p_evt) { - if (s_bas_c_env.evt_handler != NULL && BAS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_bas_c_env.evt_handler && BAS_C_EVT_INVALID != p_evt->evt_type) + { s_bas_c_env.evt_handler(p_evt); } } @@ -126,20 +94,22 @@ void bas_c_evt_handler_excute(bas_c_evt_t *p_evt) * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void bas_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void bas_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { bas_c_evt_t bas_c_evt; bas_c_evt.conn_idx = conn_idx; bas_c_evt.evt_type = BAS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_bas_c_env.handles.bas_bat_level_handle) { + if (p_read_rsp->value[0].handle == s_bas_c_env.handles.bas_bat_level_handle) + { bas_c_evt.evt_type = BAS_C_EVT_BAT_LEVE_RECEIVE; - bas_c_evt.bat_level = p_read_rsp->vals[0].p_value[0]; + bas_c_evt.bat_level = p_read_rsp->value[0].p_value[0]; bas_c_evt_handler_excute(&bas_c_evt); } } @@ -153,14 +123,15 @@ static void bas_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void bas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void bas_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { bas_c_evt_t bas_c_evt; bas_c_evt.conn_idx = conn_idx; bas_c_evt.evt_type = BAS_C_EVT_INVALID; - if (handle == s_bas_c_env.handles.bas_bat_level_cccd_handle) { + if (handle == s_bas_c_env.handles.bas_bat_level_cccd_handle) + { bas_c_evt.evt_type = (BLE_SUCCESS == status) ?\ BAS_C_EVT_BAT_LEVEL_NTF_SET_SUCCESS :\ BAS_C_EVT_BAT_LEVEL_NTF_SET_ERR; @@ -178,14 +149,15 @@ static void bas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void bas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void bas_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { bas_c_evt_t bas_c_evt; bas_c_evt.conn_idx = conn_idx; bas_c_evt.evt_type = BAS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_bas_c_env.handles.bas_bat_level_handle) { + if (p_ntf_ind->handle == s_bas_c_env.handles.bas_bat_level_handle) + { bas_c_evt.evt_type = BAS_C_EVT_BAT_LEVE_RECEIVE; bas_c_evt.bat_level = p_ntf_ind->p_value[0]; bas_c_evt_handler_excute(&bas_c_evt); @@ -201,7 +173,7 @@ static void bas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void bas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void bas_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { bas_c_evt_t bas_c_evt; uint16_t uuid_disc; @@ -210,102 +182,123 @@ static void bas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat bas_c_evt.conn_idx = conn_idx; bas_c_evt.evt_type = BAS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << UUID_OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_BATTERY_SERVICE == uuid_disc) { - s_bas_c_env.handles.bas_srvc_start_handle = p_browse_srvc->start_hdl; - s_bas_c_env.handles.bas_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_BATTERY_SERVICE == uuid_disc) + { + s_bas_c_env.handles.bas_srvc_start_handle = p_browse_srvc->start_hdl; + s_bas_c_env.handles.bas_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | - p_browse_srvc->info[i].attr.uuid[1] << UUID_OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_BATTERY_LEVEL == uuid_disc) { - s_bas_c_env.handles.bas_bat_level_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_BATTERY_LEVEL == uuid_disc) + { + s_bas_c_env.handles.bas_bat_level_handle = handle_disc; + } } - } else if (BLE_GATTC_BROWSE_ATTR_DESC == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_DESC_CLIENT_CHAR_CFG == uuid_disc) { - s_bas_c_env.handles.bas_bat_level_cccd_handle = handle_disc; - } else if (BLE_ATT_DESC_CHAR_PRES_FORMAT == uuid_disc) { - s_bas_c_env.handles.bas_bat_level_pres_handle = handle_disc; + else if (BLE_GATTC_BROWSE_ATTR_DESC == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_DESC_CLIENT_CHAR_CFG == uuid_disc) + { + s_bas_c_env.handles.bas_bat_level_cccd_handle = handle_disc; + } + else if (BLE_ATT_DESC_CHAR_PRES_FORMAT == uuid_disc) + { + s_bas_c_env.handles.bas_bat_level_pres_handle = handle_disc; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; } - } - bas_c_evt.evt_type = BAS_C_EVT_DISCOVERY_COMPLETE; + bas_c_evt.evt_type = BAS_C_EVT_DISCOVERY_COMPLETE; + } } bas_c_evt_handler_excute(&bas_c_evt); } +static void bas_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + bas_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + bas_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + bas_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + bas_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t bas_client_init(bas_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_bas_c_env, sizeof(s_bas_c_env), 0, sizeof(s_bas_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_bas_c_env, 0, sizeof(s_bas_c_env)); s_bas_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&bas_c_prf_info, &s_bas_c_env.prf_id); + return ble_gattc_prf_add(&s_bas_service_uuid, bas_c_ble_evt_handler); } sdk_err_t bas_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - - target_uuid[0] = LO_U16(BLE_ATT_SVC_BATTERY_SERVICE); - target_uuid[1] = HI_U16(BLE_ATT_SVC_BATTERY_SERVICE); - - const ble_uuid_t bas_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_bas_c_env.prf_id, conn_idx, &bas_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_bas_service_uuid); } sdk_err_t bas_c_bat_level_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_bas_c_env.handles.bas_bat_level_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_bas_c_env.handles.bas_bat_level_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_bas_c_env.handles.bas_bat_level_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_bas_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_bas_c_env.handles.bas_bat_level_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t bas_c_bat_level_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_bas_c_env.handles.bas_bat_level_handle) { + if (BLE_ATT_INVALID_HDL == s_bas_c_env.handles.bas_bat_level_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_bas_c_env.prf_id, conn_idx, s_bas_c_env.handles.bas_bat_level_handle, 0); + return ble_gattc_read(conn_idx, s_bas_c_env.handles.bas_bat_level_handle, 0); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.h index 0d173c6..6d2977e 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bas_c/bas_c.h @@ -57,18 +57,17 @@ #ifndef __BAS_C_H__ #define __BAS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup BAS_C_MACRO Defines * @{ */ -#define BAS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of BAS Client connections. */ +#define BAS_C_CONNECTION_MAX 10 /**< Maximum number of BAS Client connections. */ /** @} */ /** @@ -76,16 +75,14 @@ * @{ */ /**@brief Battery Service Client event type. */ -typedef enum { - BAS_C_EVT_INVALID, /**< BAS Client invalid event. */ - BAS_C_EVT_DISCOVERY_COMPLETE, /**< BAS Client has found BAS service and its characteristics. */ - BAS_C_EVT_DISCOVERY_FAIL, /**< BAS Client found BAS service failed because of invalid operation \ - or no found at the peer. */ - BAS_C_EVT_BAT_LEVEL_NTF_SET_SUCCESS, /**< BAS Client has enabled Notification of Battery Level characteristics. */ - BAS_C_EVT_BAT_LEVEL_NTF_SET_ERR, /**< Error occured when BAS Client set Notification \ - of Battery Level characteristics. */ - BAS_C_EVT_BAT_LEVE_RECEIVE, /**< BAS Client has received Battery Level value \ - (Read or Notification from peer). */ +typedef enum +{ + BAS_C_EVT_INVALID, /**< BAS Client invalid event. */ + BAS_C_EVT_DISCOVERY_COMPLETE, /**< BAS Client has found BAS service and its characteristics. */ + BAS_C_EVT_DISCOVERY_FAIL, /**< BAS Client found BAS service failed because of invalid operation or no found at the peer. */ + BAS_C_EVT_BAT_LEVEL_NTF_SET_SUCCESS, /**< BAS Client has enabled Notification of Battery Level characteristics. */ + BAS_C_EVT_BAT_LEVEL_NTF_SET_ERR, /**< Error occured when BAS Client set Notification of Battery Level characteristics. */ + BAS_C_EVT_BAT_LEVE_RECEIVE, /**< BAS Client has received Battery Level value (Read or Notification from peer). */ } bas_c_evt_type_t; /** @} */ @@ -94,19 +91,18 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t bas_srvc_start_handle; /**< BAS Service start handle. */ uint16_t bas_srvc_end_handle; /**< BAS Service end handle. */ - uint16_t bas_bat_level_handle; /**< BAS Battery Level characteristic Value handle \ - which has been got from peer. */ - uint16_t bas_bat_level_cccd_handle; /**< BAS CCCD handle of Battery Level characteristic \ - which has been got from peer. */ - uint16_t bas_bat_level_pres_handle; /**< BAS Presentation Format Descriptor handle of \ - Battery Level characteristic which has been got from peer. */ + uint16_t bas_bat_level_handle; /**< BAS Battery Level characteristic Value handle which has been got from peer. */ + uint16_t bas_bat_level_cccd_handle; /**< BAS CCCD handle of Battery Level characteristic which has been got from peer. */ + uint16_t bas_bat_level_pres_handle; /**< BAS Presentation Format Descriptor handle of Battery Level characteristic which has been got from peer. */ } bas_c_handles_t; /**@brief Battery Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ bas_c_evt_type_t evt_type; /**< BAS Client event type. */ uint8_t bat_level; /**< Battery level. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/BUILD.gn new file mode 100644 index 0000000..08575ef --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("bcs") { + sources = [ "bcs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.c index ed9d50b..cc77057 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.c @@ -35,7 +35,7 @@ ***************************************************************************************** */ -/* +/* * INCLUDE FILES ***************************************************************************************** */ @@ -45,16 +45,14 @@ #include "ble_prf_utils.h" #include "utility.h" #include "app_log.h" -#define PACKET_ADD_2 2 -#define FIELD_SIZE 2 -#define LOAD_LEN 2 /* * ENUMERATIONS ***************************************************************************************** */ /** Body Composition Service Attributes Indexes. */ -enum { +enum +{ BCS_IDX_SVC, BCS_IDX_BC_FEAT_CHAR, @@ -72,37 +70,33 @@ enum { ***************************************************************************************** */ /**@brief Body Composition Service Measurement packet. */ -typedef struct { +typedef struct +{ uint16_t size; /**< Measurement packet size. */ uint8_t value[BCS_MEAS_VAL_LEN_MAX]; /**< Measurement packet Value. */ } meas_packet_t; /**@brief Body Composition Service Measurement data stream. */ -typedef struct { +typedef struct +{ meas_packet_t meas_packets[BCS_CACHE_MEAS_NUM_MAX * NUM_PACKETS]; /**< BCS Measurement packet Value. */ uint8_t packet_num; /**< BCS Measurement packet number. */ - uint8_t packet_to_be_send_num; /**< Number of BCS Measurement packet to be send. */ + uint8_t packet_to_be_send_num; /**< Number of BCS Measurement packet to be send. */ } bcs_meas_data_stream_t; /**@brief Body Composition Service environment variable. */ -struct bcs_env_t { - bcs_init_t bcs_init; /**< Body Composition Service Init Value. */ - uint16_t start_hdl; /**< Body Composition Service start handle. */ - uint16_t - meas_ind_cfg[BCS_CONNECTION_MAX]; /**< The configuration of BC Measurement Indication - which is configured by the peer devices. */ - uint16_t *p_start_handle; +struct bcs_env_t +{ + bcs_init_t bcs_init; /**< Body Composition Service Init Value. */ + uint16_t start_hdl; /**< Body Composition Service start handle. */ + uint16_t meas_ind_cfg[BCS_CONNECTION_MAX]; /**< The configuration of BC Measurement Indication which is configured by the peer devices. */ + ble_gatts_create_db_t bcs_gatts_db; /**< Body Composition Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATIONS ***************************************************************************************** */ -static sdk_err_t bcs_init(void); -static void bcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void bcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void bcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void bcs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ptf_ind); static uint16_t bcs_indicate_meas_value_chunk(uint8_t conn_idx); static void bcs_meas_value_encoded(const bcs_meas_val_t *p_meas, uint16_t max_payload, uint8_t cache_num); static uint16_t packet_field_add(uint16_t flag, uint16_t value, uint16_t *p_flags, uint8_t **pp_field); @@ -112,104 +106,42 @@ static bool subsequent_packet_switched(uint16_t max_payload, uint8_t field * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct bcs_env_t s_bcs_env; +static struct bcs_env_t s_bcs_env; static bcs_meas_data_stream_t s_meas_packets; +static const uint8_t s_bcs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BODY_COMPOSITION); -/**@brief Full BCS attributes descriptor which is used to add attributes into the ATT database.*/ -static const attm_desc_t bcs_attr_tab[BCS_IDX_NB] = { +/**@brief Full BCS attributes descriptor which is used to add attributes into the ATT database.*/ +static const ble_gatts_attm_desc_t bcs_attr_tab[BCS_IDX_NB] = +{ // Body Composition Service Declaration - [BCS_IDX_SVC] = {BLE_ATT_DECL_SECONDARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [BCS_IDX_SVC] = {BLE_ATT_DECL_SECONDARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // BC Feature Characteristic - Declaration - [BCS_IDX_BC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BCS_IDX_BC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // BC Feature Characteristic - Value - [BCS_IDX_BC_FEAT_VAL] = { - BLE_ATT_CHAR_BODY_COMPOSITION_FEATURE, - READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, - BCS_FEAT_VAL_LEN_MAX - }, + [BCS_IDX_BC_FEAT_VAL] = {BLE_ATT_CHAR_BODY_COMPOSITION_FEATURE, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + BCS_FEAT_VAL_LEN_MAX}, // BC Measurement Characteristic - Declaration - [BCS_IDX_BC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BCS_IDX_BC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // BC Measurement Characteristic - Value - [BCS_IDX_BC_MEAS_VAL] = { - BLE_ATT_CHAR_BODY_COMPOSITION_MEASUREMENT, - INDICATE_PERM(UNAUTH), - ATT_VAL_LOC_USER, - BCS_MEAS_VAL_LEN_MAX - }, + [BCS_IDX_BC_MEAS_VAL] = {BLE_ATT_CHAR_BODY_COMPOSITION_MEASUREMENT, + BLE_GATTS_INDICATE_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + BCS_MEAS_VAL_LEN_MAX}, // BC Measurement Characteristic - Client Characteristic Configuration Descriptor - [BCS_IDX_BC_MEAS_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - 0, - 0 - }, -}; - -/**@brief BCS Callbacks required by profile manager. */ -static ble_prf_manager_cbs_t bcs_mgr_cbs = { - (prf_init_func_t) bcs_init, - NULL, - NULL -}; - -/**@brief BCS Callbacks for GATT server. */ -static gatts_prf_cbs_t bcs_cb_func = { - bcs_read_att_cb, - bcs_write_att_cb, - NULL, - bcs_ntf_ind_cb, - bcs_cccd_set_cb, -}; - -/**@brief Information for registering BC service. */ -static const prf_server_info_t bcs_prf_info = { - .max_connection_nb = BCS_CONNECTION_MAX, - .manager_cbs = &bcs_mgr_cbs, - .gatts_prf_cbs = &bcs_cb_func + [BCS_IDX_BC_MEAS_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Body Composition service create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t bcs_init(void) -{ - *s_bcs_env.p_start_handle = PRF_INVALID_HANDLE; - const uint8_t bcs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BODY_COMPOSITION); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = s_bcs_env.p_start_handle; - gatts_db.uuid = bcs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_bcs_env.bcs_init.char_mask); - gatts_db.max_nb_attr = BCS_IDX_NB; - gatts_db.srvc_perm = SRVC_SECONDARY_SET; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = bcs_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_bcs_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the read request. @@ -220,18 +152,19 @@ static sdk_err_t bcs_init(void) * @return If the request was consumed or not. ***************************************************************************************** */ -static void bcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void bcs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, - s_bcs_env.start_hdl, - BCS_IDX_NB, - (uint8_t *)&(s_bcs_env.bcs_init.char_mask)); + s_bcs_env.start_hdl, + BCS_IDX_NB, + (uint8_t *)&(s_bcs_env.bcs_init.char_mask)); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case BCS_IDX_BC_FEAT_VAL: cfm.length = sizeof(uint32_t); cfm.value = (uint8_t *)&s_bcs_env.bcs_init.feature; @@ -261,13 +194,13 @@ static void bcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @return If the request was consumed or not. ***************************************************************************************** */ -static void bcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void bcs_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t tab_index = 0; - uint16_t cccd_value = 0; - bcs_evt_t event; - gatts_write_cfm_t cfm; + uint16_t handle = p_param->handle; + uint16_t tab_index = 0; + uint16_t cccd_value = 0; + bcs_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_bcs_env.start_hdl, @@ -278,12 +211,13 @@ static void bcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par event.evt_type = BCS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case BCS_IDX_BC_MEAS_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - BCS_EVT_MEAS_INDICATION_ENABLE :\ - BCS_EVT_MEAS_INDICATION_DISABLE); + BCS_EVT_MEAS_INDICATION_ENABLE :\ + BCS_EVT_MEAS_INDICATION_DISABLE); s_bcs_env.meas_ind_cfg[conn_idx] = cccd_value; break; @@ -294,8 +228,8 @@ static void bcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && - BCS_EVT_INVALID != event.evt_type && s_bcs_env.bcs_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && BCS_EVT_INVALID != event.evt_type && s_bcs_env.bcs_init.evt_handler) + { s_bcs_env.bcs_init.evt_handler(&event); } } @@ -309,12 +243,13 @@ static void bcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void bcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void bcs_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; bcs_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -326,11 +261,12 @@ static void bcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = BCS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case BCS_IDX_BC_MEAS_IND_CFG: event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - BCS_EVT_MEAS_INDICATION_ENABLE :\ - BCS_EVT_MEAS_INDICATION_DISABLE); + BCS_EVT_MEAS_INDICATION_ENABLE :\ + BCS_EVT_MEAS_INDICATION_DISABLE); s_bcs_env.meas_ind_cfg[conn_idx] = cccd_value; break; @@ -338,7 +274,8 @@ static void bcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (BCS_EVT_INVALID != event.evt_type && s_bcs_env.bcs_init.evt_handler) { + if (BCS_EVT_INVALID != event.evt_type && s_bcs_env.bcs_init.evt_handler) + { s_bcs_env.bcs_init.evt_handler(&event); } } @@ -352,15 +289,17 @@ static void bcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void bcs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void bcs_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { bcs_evt_t event; event.evt_type = BCS_EVT_INVALID; event.conn_idx = conn_idx; - if (s_bcs_env.bcs_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_INDICATION == p_ntf_ind->type) { + if (s_bcs_env.bcs_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_INDICATION == p_ntf_ind->type) + { bcs_indicate_meas_value_chunk(conn_idx); event.evt_type = BCS_EVT_MEAS_INDICATION_CPLT; } @@ -389,7 +328,7 @@ static uint16_t meas_packet_init(const bcs_meas_val_t *p_meas, meas_packet_t *p_ uint16_t *p_flags = *pp_flags; *p_flags |= (s_bcs_env.bcs_init.bcs_unit == BCS_UNIT_SI) ? - BCS_MEAS_FLAG_UNIT_SI : BCS_MEAS_FLAG_UNIT_IMPERIAL; + BCS_MEAS_FLAG_UNIT_SI : BCS_MEAS_FLAG_UNIT_IMPERIAL; uint16_t *p_field = (uint16_t *)*pp_field; *p_field = p_meas->body_fat_percentage; @@ -440,13 +379,15 @@ static uint16_t packet_field_add(uint16_t flag, uint16_t value, static bool subsequent_packet_switched(uint16_t max_payload, uint8_t field_size, meas_packet_t *p_packets) { - if (p_packets[MEAS_PACKET_SUB].size) { + if (p_packets[MEAS_PACKET_SUB].size) + { return false; } meas_packet_t *p_first_pkt = &p_packets[MEAS_PACKET_FIRST]; - if (p_first_pkt->size + field_size > max_payload) { + if (p_first_pkt->size + field_size > max_payload) + { // The Multiple packet bit is setting for the first packet. uint16_t *p_flags = (uint16_t *)p_first_pkt->value; *p_flags |= BCS_MEAS_FLAG_MUTI_PACKET; @@ -458,7 +399,9 @@ static bool subsequent_packet_switched(uint16_t max_payload, uint8_t field_size, *p_flags |= BCS_MEAS_FLAG_MUTI_PACKET; return true; - } else { + } + else + { return false; } } @@ -474,35 +417,32 @@ static bool subsequent_packet_switched(uint16_t max_payload, uint8_t field_size, */ static uint16_t bcs_indicate_meas_value_chunk(uint8_t conn_idx) { - gatts_noti_ind_t bcs_meas_ind; - sdk_err_t error_code; + ble_gatts_noti_ind_t bcs_meas_ind; + sdk_err_t error_code; - if (s_meas_packets.packet_to_be_send_num == 0) { + if (0 == s_meas_packets.packet_to_be_send_num) + { s_meas_packets.packet_num = 0; s_meas_packets.packet_to_be_send_num = 0; - error_code = memset_s(s_meas_packets.meas_packets, sizeof(s_meas_packets.meas_packets), - 0x00, sizeof(s_meas_packets.meas_packets)); - if (error_code < 0) { - return error_code; - } + memset(s_meas_packets.meas_packets, 0x00, sizeof(s_meas_packets.meas_packets)); return SDK_SUCCESS; } - if (PRF_CLI_START_IND == s_bcs_env.meas_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_bcs_env.meas_ind_cfg[conn_idx]) + { bcs_meas_ind.type = BLE_GATT_INDICATION; bcs_meas_ind.handle = prf_find_handle_by_idx(BCS_IDX_BC_MEAS_VAL, - s_bcs_env.start_hdl, - (uint8_t *)&s_bcs_env.bcs_init.char_mask); - bcs_meas_ind.length = s_meas_packets.meas_packets[s_meas_packets.packet_num - - s_meas_packets.packet_to_be_send_num].size; - bcs_meas_ind.value = s_meas_packets.meas_packets[s_meas_packets.packet_num - - s_meas_packets.packet_to_be_send_num].value; + s_bcs_env.start_hdl, + (uint8_t *)&s_bcs_env.bcs_init.char_mask); + bcs_meas_ind.length = s_meas_packets.meas_packets[s_meas_packets.packet_num - s_meas_packets.packet_to_be_send_num].size; + bcs_meas_ind.value = s_meas_packets.meas_packets[s_meas_packets.packet_num - s_meas_packets.packet_to_be_send_num].value; error_code = ble_gatts_noti_ind(conn_idx, &bcs_meas_ind); } - if (SDK_SUCCESS == error_code) { + if (SDK_SUCCESS == error_code) + { s_meas_packets.packet_to_be_send_num--; } return error_code; @@ -522,7 +462,8 @@ static void bcs_meas_value_encoded(const bcs_meas_val_t *p_meas, uint16_t max_pa { uint8_t packet_num = 0; - for (uint8_t i = 0; i < cache_num; i++) { + for (uint8_t i = 0; i < cache_num; i++) + { meas_packet_t *p_pkt = &s_meas_packets.meas_packets[packet_num]; uint16_t *p_flags; uint8_t *p_field; @@ -533,40 +474,47 @@ static void bcs_meas_value_encoded(const bcs_meas_val_t *p_meas, uint16_t max_pa /** The following are the optional fields. */ // Time Stamp Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_TIME_STAMP) && \ - s_bcs_env.bcs_init.bcs_meas_flags.time_stamp_present) { + s_bcs_env.bcs_init.bcs_meas_flags.time_stamp_present) + { *p_flags |= BCS_MEAS_FLAG_DATE_TIME_PRESENT; p_field += prf_pack_date_time(p_field, &p_meas[i].time_stamp); } // User ID Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_MULTI_USER) && \ - s_bcs_env.bcs_init.bcs_meas_flags.user_id_present) { + s_bcs_env.bcs_init.bcs_meas_flags.user_id_present) + { *p_flags |= BCS_MEAS_FLAG_USER_ID_PRESENT; *p_field++ = p_meas[i].user_id; } - if (BCS_MEAS_UNSUCCESS != p_meas[i].body_fat_percentage) { + if (BCS_MEAS_UNSUCCESS != p_meas[i].body_fat_percentage) + { // Basal Metabolism Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_BASAL_METABOLISM) && \ - s_bcs_env.bcs_init.bcs_meas_flags.basal_metabolism_present) { + s_bcs_env.bcs_init.bcs_meas_flags.basal_metabolism_present) + { packet_field_add(BCS_MEAS_FLAG_BASAL_METABOLISM, p_meas[i].basal_metabolism, p_flags, &p_field); } // Muscle Percentage Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_MUSCLE_PERCENTAGE) && \ - s_bcs_env.bcs_init.bcs_meas_flags.muscle_percentage_present) { + s_bcs_env.bcs_init.bcs_meas_flags.muscle_percentage_present) + { packet_field_add(BCS_MEAS_FLAG_MUSCLE_PERCENTAGE, p_meas[i].muscle_percentage, p_flags, &p_field); } // Muscle Mass Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_MUSCLE_MASS) && \ - s_bcs_env.bcs_init.bcs_meas_flags.muscle_mass_present) { + s_bcs_env.bcs_init.bcs_meas_flags.muscle_mass_present) + { packet_field_add(BCS_MEAS_FLAG_MUSCLE_MASS, p_meas[i].muscle_mass, p_flags, &p_field); } // Fat Free Mass Field. if ((s_bcs_env.bcs_init.feature & BCS_FEAT_FAT_FREE_MASS) && \ - s_bcs_env.bcs_init.bcs_meas_flags.fat_free_mass_present) { + s_bcs_env.bcs_init.bcs_meas_flags.fat_free_mass_present) + { packet_field_add(BCS_MEAS_FLAG_FAT_FREE_MASS, p_meas[i].fat_free_mass, p_flags, &p_field); } @@ -577,94 +525,122 @@ static void bcs_meas_value_encoded(const bcs_meas_val_t *p_meas, uint16_t max_pa * size shall be checked and the subsequent packet shall be used if needed. */ // Soft Lean Mass Field. - if (!(s_bcs_env.bcs_init.feature & BCS_FEAT_SOFT_LEAN_MASS) || \ - !s_bcs_env.bcs_init.bcs_meas_flags.soft_lean_mass_present) { - return; + if ((s_bcs_env.bcs_init.feature & BCS_FEAT_SOFT_LEAN_MASS) && \ + s_bcs_env.bcs_init.bcs_meas_flags.soft_lean_mass_present) + { + if (subsequent_packet_switched(max_payload, 2, &s_meas_packets.meas_packets[packet_num]) == true) + { + p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; + p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + } + + p_pkt->size += packet_field_add(BCS_MEAS_FLAG_SOFT_LEAN_MASS, p_meas[i].soft_lean_mass, p_flags, &p_field); } - if (subsequent_packet_switched(max_payload, FIELD_SIZE, &s_meas_packets.meas_packets[packet_num]) == true) { - p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; - p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); - } - - p_pkt->size += packet_field_add(BCS_MEAS_FLAG_SOFT_LEAN_MASS, - p_meas[i].soft_lean_mass, p_flags, &p_field); // Body Water Mass Field. - if (!(s_bcs_env.bcs_init.feature & BCS_FEAT_BODY_WATER_MASS) || \ - !s_bcs_env.bcs_init.bcs_meas_flags.body_water_mass_present) { - return; + if ((s_bcs_env.bcs_init.feature & BCS_FEAT_BODY_WATER_MASS) && \ + s_bcs_env.bcs_init.bcs_meas_flags.body_water_mass_present) + { + if (subsequent_packet_switched(max_payload, 2, &s_meas_packets.meas_packets[packet_num]) == true) + { + p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; + p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + } + + p_pkt->size += packet_field_add(BCS_MEAS_FLAG_BODY_WATER_MASS, p_meas[i].body_water_mass, p_flags, &p_field); } - if (subsequent_packet_switched(max_payload, FIELD_SIZE, &s_meas_packets.meas_packets[packet_num]) == true) { - p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; - p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); - } - - p_pkt->size += packet_field_add(BCS_MEAS_FLAG_BODY_WATER_MASS, - p_meas[i].body_water_mass, p_flags, &p_field); // Impedance Field. - if (!(s_bcs_env.bcs_init.feature & BCS_FEAT_IMPEDANCE) || \ - !s_bcs_env.bcs_init.bcs_meas_flags.impedance_present) { - return; - } - if (subsequent_packet_switched(max_payload, FIELD_SIZE, &s_meas_packets.meas_packets[packet_num]) == true) { - p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; - p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + if ((s_bcs_env.bcs_init.feature & BCS_FEAT_IMPEDANCE) && \ + s_bcs_env.bcs_init.bcs_meas_flags.impedance_present) + { + if (subsequent_packet_switched(max_payload, 2, &s_meas_packets.meas_packets[packet_num]) == true) { + p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; + p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + } + + p_pkt->size += packet_field_add(BCS_MEAS_FLAG_IMPEDANCE, p_meas[i].impedance, p_flags, &p_field); } - p_pkt->size += packet_field_add(BCS_MEAS_FLAG_IMPEDANCE, p_meas[i].impedance, p_flags, &p_field); // Weight Field. - if (!(s_bcs_env.bcs_init.feature & BCS_FEAT_WEIGHT) || \ - !s_bcs_env.bcs_init.bcs_meas_flags.weight_present) { - return; - } - if (subsequent_packet_switched(max_payload, FIELD_SIZE, - &s_meas_packets.meas_packets[packet_num]) == true) { - p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; - p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + if ((s_bcs_env.bcs_init.feature & BCS_FEAT_WEIGHT) && \ + s_bcs_env.bcs_init.bcs_meas_flags.weight_present) + { + if (subsequent_packet_switched(max_payload, 2, &s_meas_packets.meas_packets[packet_num]) == true) + { + p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; + p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + } + + p_pkt->size += packet_field_add(BCS_MEAS_FLAG_WEIGHT, p_meas[i].weight, p_flags, &p_field); } - p_pkt->size += packet_field_add(BCS_MEAS_FLAG_WEIGHT, p_meas[i].weight, p_flags, &p_field); // Height Field. - if (!(s_bcs_env.bcs_init.feature & BCS_FEAT_HEIGHT) || \ - !s_bcs_env.bcs_init.bcs_meas_flags.height_present) { - return; - } - if (subsequent_packet_switched(max_payload, LOAD_LEN, &s_meas_packets.meas_packets[packet_num]) == true) { - p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; - p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); - } + if ((s_bcs_env.bcs_init.feature & BCS_FEAT_HEIGHT) && \ + s_bcs_env.bcs_init.bcs_meas_flags.height_present) + { + if (subsequent_packet_switched(max_payload, 2, &s_meas_packets.meas_packets[packet_num]) == true) + { + p_pkt = &s_meas_packets.meas_packets[packet_num + 1]; + p_pkt->size = meas_packet_init(&p_meas[i], p_pkt, &p_flags, &p_field); + } - p_pkt->size += packet_field_add(BCS_MEAS_FLAG_HEIGHT, p_meas[i].height, p_flags, &p_field); + p_pkt->size += packet_field_add(BCS_MEAS_FLAG_HEIGHT, p_meas[i].height, p_flags, &p_field); + } } - packet_num += PACKET_ADD_2; + packet_num += 2; } s_meas_packets.packet_num = packet_num; s_meas_packets.packet_to_be_send_num = packet_num; } +static void bcs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + bcs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + bcs_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + bcs_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + bcs_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t bcs_measurement_send(uint8_t conn_idx, bcs_meas_val_t *p_bcs_meas_val, uint8_t cache_num) { - if (p_bcs_meas_val == NULL || BCS_CACHE_MEAS_NUM_MAX < cache_num) { + if (NULL == p_bcs_meas_val || BCS_CACHE_MEAS_NUM_MAX < cache_num) + { return SDK_ERR_INVALID_PARAM; } sdk_err_t error_code = SDK_ERR_IND_DISABLED; - error_code = memset_s(s_meas_packets.meas_packets, sizeof(s_meas_packets.meas_packets), \ - 0x00, sizeof(s_meas_packets.meas_packets)); - if (error_code < 0) { - return error_code; - } + memset(s_meas_packets.meas_packets, 0x00, sizeof(s_meas_packets.meas_packets)); s_meas_packets.packet_num = 0; s_meas_packets.packet_to_be_send_num = 0; - if (PRF_CLI_START_IND == s_bcs_env.meas_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_bcs_env.meas_ind_cfg[conn_idx]) + { bcs_meas_value_encoded(p_bcs_meas_val, BLE_ATT_MTU_DEFAULT - INDI_PAYLOAD_HEADER_LEN, cache_num); error_code = bcs_indicate_meas_value_chunk(conn_idx); } @@ -672,19 +648,29 @@ sdk_err_t bcs_measurement_send(uint8_t conn_idx, bcs_meas_val_t *p_bcs_meas_val, return error_code; } -sdk_err_t bcs_service_init(bcs_init_t *p_bcs_init, uint16_t *p_bcs_start_handle) +sdk_err_t bcs_service_init(bcs_init_t *p_bcs_init) { - sdk_err_t ret; - if (p_bcs_init == NULL) { + if (NULL == p_bcs_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_bcs_env.bcs_init, sizeof(bcs_init_t), p_bcs_init, sizeof(bcs_init_t)); - if (ret < 0) { - return ret; - } - s_bcs_env.p_start_handle = p_bcs_start_handle; + memcpy(&s_bcs_env.bcs_init, p_bcs_init, sizeof(bcs_init_t)); - return ble_server_prf_add(&bcs_prf_info); + s_bcs_env.start_hdl = PRF_INVALID_HANDLE; + s_bcs_env.bcs_gatts_db.shdl = &s_bcs_env.start_hdl; + s_bcs_env.bcs_gatts_db.uuid = s_bcs_svc_uuid; + s_bcs_env.bcs_gatts_db.attr_tab_cfg = (uint8_t *)&(s_bcs_env.bcs_init.char_mask); + s_bcs_env.bcs_gatts_db.max_nb_attr = BCS_IDX_NB; + s_bcs_env.bcs_gatts_db.srvc_perm = BLE_GATTS_SRVC_SECONDARY_SET; + s_bcs_env.bcs_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_bcs_env.bcs_gatts_db.attr_tab.attr_tab_16 = bcs_attr_tab; + + return ble_gatts_prf_add(&s_bcs_env.bcs_gatts_db, bcs_ble_evt_handler); +} + +uint16_t *bcs_start_handle_get(void) +{ + return &s_bcs_env.start_hdl; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.h index ab28f1f..263990c 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bcs/bcs.h @@ -49,32 +49,32 @@ * @details The Body Composition Service (BCS) exposes data related to body composition from a * body composition analyzer (Server) intended for consumer healthcare as well as * sports/fitness applications. This module implements the Body Compositon Service - * with the Body Composition Feature and Body Composition Measurement characteristics. + * with the Body Composition Feature and Body Composition Measurement characteristics. * * After \ref bcs_init_t variable is initialized, the application must call \ref bcs_service_init() - * to optionally add the Body Compisition Service, Body Composition Meaturement characteristics to + * to optionally add the Body Compisition Service, Body Composition Meaturement characteristics to * the BLE stack database according to \ref bcs_init_t.char_mask. */ #ifndef _BCS_H_ #define _BCS_H_ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include + /** * @defgroup BCS_MACRO Defines * @{ */ -#define BCS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Body Composition Service connections. */ -#define BCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of BC Measurment value. */ -#define BCS_FEAT_VAL_LEN_MAX 4 /**< Maximum length of BC Feature value. */ +#define BCS_CONNECTION_MAX 10 /**< Maximum number of Body Composition Service connections. */ +#define BCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of BC Measurment value. */ +#define BCS_FEAT_VAL_LEN_MAX 4 /**< Maximum length of BC Feature value. */ -#define INDI_PAYLOAD_HEADER_LEN 3 /**< The length of indication payload header. */ +#define INDI_PAYLOAD_HEADER_LEN 3 /**< The length of indication payload header. */ /** * @defgroup BCS_MEAS_PACKETS_INDEX Measurement packets index @@ -83,24 +83,26 @@ * The least value of MTU is 23 octets. The size of Attribute Value is (23-3) * octets which could be less than the size (30 octets) of all fields of Body * Composition Measurement. If the required data exceeds the current size (MTU - 3) - * octets, the remaining optional fields shall be sent in the subsequent indication. - * So we need no more than 2 packets. + * octets, the remaining optional fields shall be sent in the subsequent indication. + * So we need no more than 2 packets. */ -#define NUM_PACKETS 2 /**< Measurement Packet numbers. */ -#define MEAS_PACKET_FIRST 0 /**< The first Measurement Packet. */ -#define MEAS_PACKET_SUB 1 /**< The second Measurement Packet. */ +#define NUM_PACKETS 2 /**< Measurement Packet numbers. */ +#define MEAS_PACKET_FIRST 0 /**< The first Measurement Packet. */ +#define MEAS_PACKET_SUB 1 /**< The second Measurement Packet. */ /** @} */ -#define BCS_CACHE_MEAS_NUM_MAX 25 /**< Maximum number of cache muasurements value for each user. */ +#define BCS_CACHE_MEAS_NUM_MAX 25 /**< Maximum number of cache muasurements value for each user. */ -#define BCS_MEAS_UNSUCCESS 0xFFFF /**< Measurement unsuccessful. */ +#define BCS_MEAS_UNSUCCESS 0xFFFF /**< Measurement unsuccessful. */ + +#define BCS_MEAS_FLAG_DEFAULT 0x01FF /**< Measurement default flag. */ /** * @defgroup BCS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref bcs_init_t.char_mask. */ -#define BCS_CHAR_FEAT_MANDATORY 0x3F /**< Bit mask for mandatory characteristic in BCS. */ +#define BCS_CHAR_FEAT_MANDATORY 0x3F /**< Bit mask for mandatory characteristic in BCS. */ /** @} */ /** @} */ @@ -114,26 +116,28 @@ * @{ */ /**@brief Body Composition Measurement Flags. */ -enum bcs_meas_flag_bits { - BCS_MEAS_FLAG_UNIT_SI = 0x0000, /**< Flag bit for SI Measurement Units Present. */ - BCS_MEAS_FLAG_UNIT_IMPERIAL = 0x0001, /**< Flag bit for Imperial Measurement Units Present. */ - BCS_MEAS_FLAG_DATE_TIME_PRESENT = 0x0002, /**< Flag bit for Time Stamp Present. */ - BCS_MEAS_FLAG_USER_ID_PRESENT = 0x0004, /**< Flag bit for User ID Present. */ - BCS_MEAS_FLAG_BASAL_METABOLISM = 0x0008, /**< Flag bit for Basal Metabolism Present. */ - BCS_MEAS_FLAG_MUSCLE_PERCENTAGE = 0x0010, /**< Flag bit for Muscle Percentage Present. */ - BCS_MEAS_FLAG_MUSCLE_MASS = 0x0020, /**< Flag bit for Muscle Mass Present. */ - BCS_MEAS_FLAG_FAT_FREE_MASS = 0x0040, /**< Flag bit for Fat Free Mass Present. */ - BCS_MEAS_FLAG_SOFT_LEAN_MASS = 0x0080, /**< Flag bit for Soft Lean Mass Present. */ - BCS_MEAS_FLAG_BODY_WATER_MASS = 0x0100, /**< Flag bit for Body Water Mass Present. */ - BCS_MEAS_FLAG_IMPEDANCE = 0x0200, /**< Flag bit for Impedance Present. */ - BCS_MEAS_FLAG_WEIGHT = 0x0400, /**< Flag bit for Weight Present. */ - BCS_MEAS_FLAG_HEIGHT = 0x0800, /**< Flag bit for Height Present. */ - BCS_MEAS_FLAG_MUTI_PACKET = 0x1000, /**< Flag bit for Multiple Packet Measurement Present. */ +enum bcs_meas_flag_bits +{ + BCS_MEAS_FLAG_UNIT_SI = 0x0000, /**< Flag bit for SI Measurement Units Present. */ + BCS_MEAS_FLAG_UNIT_IMPERIAL = 0x0001, /**< Flag bit for Imperial Measurement Units Present. */ + BCS_MEAS_FLAG_DATE_TIME_PRESENT = 0x0002, /**< Flag bit for Time Stamp Present. */ + BCS_MEAS_FLAG_USER_ID_PRESENT = 0x0004, /**< Flag bit for User ID Present. */ + BCS_MEAS_FLAG_BASAL_METABOLISM = 0x0008, /**< Flag bit for Basal Metabolism Present. */ + BCS_MEAS_FLAG_MUSCLE_PERCENTAGE = 0x0010, /**< Flag bit for Muscle Percentage Present. */ + BCS_MEAS_FLAG_MUSCLE_MASS = 0x0020, /**< Flag bit for Muscle Mass Present. */ + BCS_MEAS_FLAG_FAT_FREE_MASS = 0x0040, /**< Flag bit for Fat Free Mass Present. */ + BCS_MEAS_FLAG_SOFT_LEAN_MASS = 0x0080, /**< Flag bit for Soft Lean Mass Present. */ + BCS_MEAS_FLAG_BODY_WATER_MASS = 0x0100, /**< Flag bit for Body Water Mass Present. */ + BCS_MEAS_FLAG_IMPEDANCE = 0x0200, /**< Flag bit for Impedance Present. */ + BCS_MEAS_FLAG_WEIGHT = 0x0400, /**< Flag bit for Weight Present. */ + BCS_MEAS_FLAG_HEIGHT = 0x0800, /**< Flag bit for Height Present. */ + BCS_MEAS_FLAG_MUTI_PACKET = 0x1000, /**< Flag bit for Multiple Packet Measurement Present. */ }; /** @} */ /**@brief Body Composition Feature characteristic bit values. */ -typedef enum { +typedef enum +{ /* Supported Flags */ BCS_FEAT_TIME_STAMP = 0x00000001, /**< Time Stamp supported */ BCS_FEAT_MULTI_USER = 0x00000002, /**< Multiple Users supported */ @@ -165,7 +169,8 @@ typedef enum { } bcs_feature_t; /**@brief BCS Weight Measurement resolutions. */ -typedef enum { +typedef enum +{ BCS_MASS_RES_500G, /**< Resolution of 0.5kg or 1lb. */ BCS_MASS_RES_200G, /**< Resolution of 0.2kg or 0.5lb. */ BCS_MASS_RES_100G, /**< Resolution of 0.1kg or 0.2lb. */ @@ -176,20 +181,23 @@ typedef enum { } bcs_mass_res_t; /**@brief BCS Height Measurement resolutions. */ -typedef enum { +typedef enum +{ BCS_HEIGHT_RES_10MM, /**< Resolution of 0.01m or 1in. */ BCS_HEIGHT_RES_5MM, /**< Resolution of 0.005m or 0.5in. */ BCS_HEIGHT_RES_1MM, /**< Resolution of 0.001m or 0.1in. */ } bcs_height_res_t; /**@brief BCS unit types. */ -typedef enum { +typedef enum +{ BCS_UNIT_SI, /**< Weight in kilograms and height in meters */ BCS_UNIT_IMPERIAL, /**< Weight in pounds and height in inches */ } bcs_unit_t; -/**@brief Body Composition Service event type. */ -typedef enum { + /**@brief Body Composition Service event type. */ +typedef enum +{ BCS_EVT_INVALID, /**< Indicate that invalid event. */ BCS_EVT_MEAS_INDICATION_ENABLE, /**< Indicate that body composition measurement indication has been enabled. */ BCS_EVT_MEAS_INDICATION_DISABLE, /**< Indicate that body composition measurement indication has been disabled. */ @@ -203,22 +211,24 @@ typedef enum { * @{ */ /**@brief Body composition Measurement flag data. */ -typedef struct { - uint8_t time_stamp_present : 1; /**< Time Stamp flag. */ - uint8_t user_id_present : 1; /**< User ID flag. */ - uint8_t basal_metabolism_present : 1; /**< Basal Metabolism flag. */ - uint8_t muscle_percentage_present : 1; /**< Muscle Percentage flag. */ - uint8_t muscle_mass_present : 1; /**< Muscle Mass flag. */ - uint8_t fat_free_mass_present : 1; /**< Fat Free Mass flag. */ - uint8_t soft_lean_mass_present : 1; /**< Soft Lean Mass flag. */ - uint8_t body_water_mass_present : 1; /**< Body Water Mass flag. */ - uint8_t impedance_present : 1; /**< Impedance flag. */ - uint8_t weight_present : 1; /**< Weight flag. */ - uint8_t height_present : 1; /**< Height flag. */ +typedef struct +{ + uint8_t time_stamp_present :1; /**< Time Stamp flag. */ + uint8_t user_id_present :1; /**< User ID flag. */ + uint8_t basal_metabolism_present :1; /**< Basal Metabolism flag. */ + uint8_t muscle_percentage_present :1; /**< Muscle Percentage flag. */ + uint8_t muscle_mass_present :1; /**< Muscle Mass flag. */ + uint8_t fat_free_mass_present :1; /**< Fat Free Mass flag. */ + uint8_t soft_lean_mass_present :1; /**< Soft Lean Mass flag. */ + uint8_t body_water_mass_present :1; /**< Body Water Mass flag. */ + uint8_t impedance_present :1; /**< Impedance flag. */ + uint8_t weight_present :1; /**< Weight flag. */ + uint8_t height_present :1; /**< Height flag. */ } bcs_meas_flag_t; /**@brief Body composition Measurement data. */ -typedef struct { +typedef struct +{ uint16_t body_fat_percentage; /**< Body Fat Percentage data. */ prf_date_time_t time_stamp; /**< Time Stamp data. */ uint8_t user_id; /**< User Index data. */ @@ -234,7 +244,8 @@ typedef struct { } bcs_meas_val_t; /**@brief Body Composition Service event. */ -typedef struct { +typedef struct +{ bcs_evt_type_t evt_type; /**< The BCS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -255,11 +266,11 @@ typedef void (*bcs_evt_handler_t)(bcs_evt_t *p_evt); * @{ */ /**@brief Body Composition Service Init variable. */ -typedef struct { +typedef struct +{ bcs_evt_handler_t evt_handler; /**< Body Composition Service event handler. */ uint32_t feature; /**< Initial value for features. */ - uint8_t - char_mask; /**< Initial mask of Supported characteristics, and configured with \ref BCS_CHAR_MASK */ + uint8_t char_mask; /**< Initial mask of Supported characteristics, and configured with \ref BCS_CHAR_MASK */ bcs_unit_t bcs_unit; /**< Initial unit system as SI or Imperial. */ bcs_meas_flag_t bcs_meas_flags; /**< Initial measurement flags. */ bcs_mass_res_t bcs_mass_res; /**< Initial resolution of mass value. */ @@ -275,24 +286,35 @@ typedef struct { ***************************************************************************************** * @brief Initialize a Body Composition Service instance and add in the DB. * - * @param[in] p_bcs_init: Pointer to BC Service initialization variable. + * @param[in] p_bcs_init: Pointer to BC Service initialization variable. * * @return Result of service initialization. ***************************************************************************************** */ -sdk_err_t bcs_service_init(bcs_init_t *p_bcs_init, uint16_t *p_bcs_start_handle); +sdk_err_t bcs_service_init(bcs_init_t *p_bcs_init); -/**@brief Send Body Composition Measurement indication. - ***************************************************************************************** +/** + ****************************************************************************************** + * @brief Send Body Composition Measurement indication. * * @param[in] conn_idx: Connection index. * @param[in] p_meas: Pointer to body composition measurement data. * @param[in] cache_num: The number of measurement caches. * - * @return Result of indicate value. - ***************************************************************************************** + * @return SDK_SUCCESS on success, otherwise an error code. + ***************************************************************************************** */ sdk_err_t bcs_measurement_send(uint8_t conn_idx, bcs_meas_val_t *p_meas, uint8_t cache_num); + +/** + ****************************************************************************************** + * @brief Get the pointer to the start handle of Body Composition Service. + * + * + * @return The pointer to the start handle. + ***************************************************************************************** + */ +uint16_t * bcs_start_handle_get(void); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/BUILD.gn new file mode 100644 index 0000000..f56cd8a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("bps") { + sources = [ "bps.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.c index d52669b..4d6a8b5 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.c @@ -43,13 +43,14 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define OFFSET_12 12 + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief Blood Pressure Service Attributes Indexes. */ -enum bps_attr_idx_t { +enum bps_attr_idx_t +{ BPS_IDX_SVC, BPS_IDX_BP_MEAS_CHAR, @@ -67,7 +68,8 @@ enum bps_attr_idx_t { }; /**@brief Blood Pressure Measurement Flags bits. */ -enum bps_meas_flag_t { +enum bps_meas_flag_t +{ BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT = (0x01 << 0), /**< Blood Pressure Units Flag bit. */ BPS_MEAS_TIME_STAMP_FLAG_BIT = (0x01 << 1), /**< Time Stamp Flag bit. */ BPS_MEAS_PULSE_RATE_FLAG_BIT = (0x01 << 2), /**< Pulse Rate Flag bit. */ @@ -80,159 +82,93 @@ enum bps_meas_flag_t { ***************************************************************************************** */ /**@brief Blood Pressure Service environment variable. */ -struct bps_env_t { +struct bps_env_t +{ bps_init_t bps_init; /**< Blood Pressure Service initialization variables. */ uint16_t start_hdl; /**< Start handle of Blood Pressure Service. */ - uint16_t - ntf_ind_cfg[BPS_CONNECTION_MAX]; /**< Notification and indication configuration for each connections. */ + uint16_t ntf_ind_cfg[BPS_CONNECTION_MAX]; /**< Notification and indication configuration for each connections. */ + ble_gatts_create_db_t bps_serv_db; /**< Blood Pressure Service DataBase. */ }; -/* -* LOCAL FUNCTION DECLARATION -***************************************************************************************** -*/ -static sdk_err_t bps_init(void); -static void bps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void bps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void bps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); + /* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ + /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct bps_env_t s_bps_env; +static const uint8_t s_bps_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BLOOD_PRESSURE); /**@brief Full BPS Database Description which is used to add attributes into theATT database. */ -static const attm_desc_t bps_attr_tab[BPS_IDX_NB] = { +static const ble_gatts_attm_desc_t bps_attr_tab[BPS_IDX_NB] = +{ // Blood Pressure Service Declaration - [BPS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [BPS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Blood Pressure Measurement Characteristic Declaration - [BPS_IDX_BP_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BPS_IDX_BP_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Blood Pressure Measurement Characteristic Value - [BPS_IDX_BP_MEAS_VAL] = { - BLE_ATT_CHAR_BLOOD_PRESSURE_MEAS, + [BPS_IDX_BP_MEAS_VAL] = {BLE_ATT_CHAR_BLOOD_PRESSURE_MEAS, #ifdef PTS_AUTO_TEST - INDICATE_PERM_UNSEC, + BLE_GATTS_INDICATE_PERM_UNSEC, #else - INDICATE_PERM(NOAUTH), + BLE_GATTS_INDICATE_PERM(BLE_GATTS_NOAUTH), #endif - ATT_VAL_LOC_USER, - BPS_BP_MEAS_MAX_LEN - }, + BLE_GATTS_ATT_VAL_LOC_USER, + BPS_BP_MEAS_MAX_LEN}, // Blood Pressure Measurement Characteristic - Client Characteristic Configuration Descriptor - [BPS_IDX_BP_MEAS_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, + [BPS_IDX_BP_MEAS_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, #ifdef PTS_AUTO_TEST - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, #else - READ_PERM(NOAUTH) | WRITE_REQ_PERM(NOAUTH), + BLE_GATTS_READ_PERM(BLE_GATTS_NOAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_NOAUTH), #endif - 0, - 0 - }, + 0, + 0}, // Intermediate Cuff Pressure Characteristic Declaration - [BPS_IDX_INTM_CUFF_PRESS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BPS_IDX_INTM_CUFF_PRESS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Intermediate Cuff Pressure Characteristic Value - [BPS_IDX_INTM_CUFF_PRESS_VAL] = { - BLE_ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE, + [BPS_IDX_INTM_CUFF_PRESS_VAL] = {BLE_ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE, #ifdef PTS_AUTO_TEST - NOTIFY_PERM_UNSEC, + BLE_GATTS_NOTIFY_PERM_UNSEC, #else - NOTIFY_PERM(NOAUTH), + BLE_GATTS_NOTIFY_PERM(BLE_GATTS_NOAUTH), #endif - ATT_VAL_LOC_USER, - BPS_BP_MEAS_MAX_LEN - }, + BLE_GATTS_ATT_VAL_LOC_USER, + BPS_BP_MEAS_MAX_LEN}, // Intermediate Cuff Pressure Characteristic - Client Characteristic Configuration Descriptor - [BPS_IDX_INTM_CUFF_PRESS_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, + [BPS_IDX_INTM_CUFF_PRESS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, #ifdef PTS_AUTO_TEST - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, #else - READ_PERM(NOAUTH) | WRITE_REQ_PERM(NOAUTH), + BLE_GATTS_READ_PERM(BLE_GATTS_NOAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_NOAUTH), #endif - 0, - 0 - }, + 0, + 0}, // Blood Pressure Feature Characteristic Declaration - [BPS_IDX_BP_FEATURE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [BPS_IDX_BP_FEATURE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Blood Pressure Feature Characteristic Value - [BPS_IDX_BP_FEATURE_VAL] = { - BLE_ATT_CHAR_BLOOD_PRESSURE_FEATURE, + [BPS_IDX_BP_FEATURE_VAL] = {BLE_ATT_CHAR_BLOOD_PRESSURE_FEATURE, #ifdef PTS_AUTO_TEST - READ_PERM_UNSEC, + BLE_GATTS_READ_PERM_UNSEC, #else - READ_PERM(NOAUTH), + BLE_GATTS_READ_PERM(BLE_GATTS_NOAUTH), #endif - ATT_VAL_LOC_USER, - sizeof(uint16_t) - }, + BLE_GATTS_ATT_VAL_LOC_USER, + sizeof(uint16_t)}, }; -/**@brief BPS interface required by profile manager. */ -static ble_prf_manager_cbs_t bps_mgr_cbs = { - (prf_init_func_t)bps_init, - NULL, - NULL -}; -/**@brief BPS GATT Server Callbacks. */ -static gatts_prf_cbs_t bps_gatts_cbs = { - bps_read_att_cb, - bps_write_att_cb, - NULL, - NULL, - bps_cccd_set_cb, -}; - -/**@brief BPS Information. */ -static const prf_server_info_t bps_prf_info = { - .max_connection_nb = BPS_CONNECTION_MAX, - .manager_cbs = &bps_mgr_cbs, - .gatts_prf_cbs = &bps_gatts_cbs -}; - -/* -* LOCAL FUNCTION DEFINITIONS -***************************************************************************************** -*/ -/** - ***************************************************************************************** - * @brief Initialize Blood Pressure service and create DB in ATT. - * - * @retval ::Error code to know if profile initialization succeed or not. + /* + * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -static sdk_err_t bps_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t bps_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_BLOOD_PRESSURE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = bps_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t*)&(s_bps_env.bps_init.char_mask); - gatts_db.max_nb_attr = BPS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = bps_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_bps_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} /** ***************************************************************************************** @@ -242,18 +178,19 @@ static sdk_err_t bps_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void bps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void bps_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_bps_env.start_hdl, - BPS_IDX_NB, - (uint8_t *)&s_bps_env.bps_init.char_mask); + BPS_IDX_NB, + (uint8_t *)&s_bps_env.bps_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case BPS_IDX_BP_MEAS_IND_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_bps_env.ntf_ind_cfg[conn_idx]; @@ -265,7 +202,8 @@ static void bps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param break; case BPS_IDX_BP_FEATURE_VAL: - if (s_bps_env.bps_init.evt_handler) { + if (s_bps_env.bps_init.evt_handler) + { s_bps_env.bps_init.evt_handler(conn_idx, BPS_EVT_READ_BL_PRESSURE_FEATURE); } cfm.length = sizeof(uint16_t); @@ -289,13 +227,13 @@ static void bps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void bps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void bps_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; bps_evt_type_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_bps_env.start_hdl, @@ -304,21 +242,21 @@ static void bps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case BPS_IDX_BP_MEAS_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event = ((PRF_CLI_START_IND == cccd_value) ?\ - BPS_EVT_BP_MEAS_INDICATION_ENABLED :\ - BPS_EVT_BP_MEAS_INDICATION_DISABLED); + BPS_EVT_BP_MEAS_INDICATION_ENABLED :\ + BPS_EVT_BP_MEAS_INDICATION_DISABLED); s_bps_env.ntf_ind_cfg[conn_idx] = cccd_value; break; case BPS_IDX_INTM_CUFF_PRESS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event = ((PRF_CLI_START_NTF == cccd_value) ?\ - BPS_EVT_INTM_CUFF_PRESS_NTF_ENABLED :\ - BPS_EVT_INTM_CUFF_PRESS_NTF_DISABLED); - \ + BPS_EVT_INTM_CUFF_PRESS_NTF_ENABLED :\ + BPS_EVT_INTM_CUFF_PRESS_NTF_DISABLED);\ s_bps_env.ntf_ind_cfg[conn_idx] = cccd_value; break; @@ -327,7 +265,8 @@ static void bps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa break; } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && BPS_EVT_INVALID != event && s_bps_env.bps_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && BPS_EVT_INVALID != event && s_bps_env.bps_init.evt_handler) + { s_bps_env.bps_init.evt_handler(conn_idx, event); } ble_gatts_write_cfm(conn_idx, &cfm); @@ -342,12 +281,13 @@ static void bps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void bps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void bps_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; bps_evt_type_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -356,19 +296,19 @@ static void bps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val BPS_IDX_NB, (uint8_t *)&s_bps_env.bps_init.char_mask); - switch (tab_index) { + switch (tab_index) + { case BPS_IDX_BP_MEAS_IND_CFG: event = ((PRF_CLI_START_IND == cccd_value) ?\ - BPS_EVT_BP_MEAS_INDICATION_ENABLED :\ - BPS_EVT_BP_MEAS_INDICATION_DISABLED); + BPS_EVT_BP_MEAS_INDICATION_ENABLED :\ + BPS_EVT_BP_MEAS_INDICATION_DISABLED); s_bps_env.ntf_ind_cfg[conn_idx] = cccd_value; break; case BPS_IDX_INTM_CUFF_PRESS_NTF_CFG: event = ((PRF_CLI_START_NTF == cccd_value) ?\ - BPS_EVT_INTM_CUFF_PRESS_NTF_ENABLED :\ - BPS_EVT_INTM_CUFF_PRESS_NTF_DISABLED); - \ + BPS_EVT_INTM_CUFF_PRESS_NTF_ENABLED :\ + BPS_EVT_INTM_CUFF_PRESS_NTF_DISABLED);\ s_bps_env.ntf_ind_cfg[conn_idx] = cccd_value; break; @@ -377,7 +317,8 @@ static void bps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (BPS_EVT_INVALID != event && s_bps_env.bps_init.evt_handler) { + if (BPS_EVT_INVALID != event && s_bps_env.bps_init.evt_handler) + { s_bps_env.bps_init.evt_handler(conn_idx, event); } } @@ -399,30 +340,32 @@ static uint16_t bps_measurement_encode(bps_meas_t *p_meas, uint8_t *p_encoded_bu uint16_t encoded_sfloat = 0; // Set measurement units flag - if (p_meas->bl_unit_in_kpa) { + if (p_meas->bl_unit_in_kpa) + { flags |= BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT; } // Blood Pressure Measurement - Systolic - encoded_sfloat = ((p_meas->systolic.exponent << OFFSET_12) & 0xF000) | + encoded_sfloat = ((p_meas->systolic.exponent << 12) & 0xF000) | ((p_meas->systolic.mantissa << 0) & 0x0FFF); p_encoded_buffer[length++] = LO_U16(encoded_sfloat); p_encoded_buffer[length++] = HI_U16(encoded_sfloat); // Blood Pressure Measurement - Diastolic - encoded_sfloat = ((p_meas->diastolic.exponent << OFFSET_12) & 0xF000) | + encoded_sfloat = ((p_meas->diastolic.exponent << 12) & 0xF000) | ((p_meas->diastolic.mantissa << 0) & 0x0FFF); p_encoded_buffer[length++] = LO_U16(encoded_sfloat); p_encoded_buffer[length++] = HI_U16(encoded_sfloat); // Blood Pressure Measurement - Mean Arterial Pressure - encoded_sfloat = ((p_meas->mean_arterial_pr.exponent << OFFSET_12) & 0xF000) | + encoded_sfloat = ((p_meas->mean_arterial_pr.exponent << 12) & 0xF000) | ((p_meas->mean_arterial_pr.mantissa << 0) & 0x0FFF); p_encoded_buffer[length++] = LO_U16(encoded_sfloat); p_encoded_buffer[length++] = HI_U16(encoded_sfloat); // Time Stamp field - if (p_meas->time_stamp_present) { + if (p_meas->time_stamp_present) + { flags |= BPS_MEAS_TIME_STAMP_FLAG_BIT; p_encoded_buffer[length++] = LO_U16(p_meas->time_stamp.year); p_encoded_buffer[length++] = HI_U16(p_meas->time_stamp.year); @@ -434,22 +377,25 @@ static uint16_t bps_measurement_encode(bps_meas_t *p_meas, uint8_t *p_encoded_bu } // Pulse Rate - if (p_meas->pulse_rate_present) { + if (p_meas->pulse_rate_present) + { flags |= BPS_MEAS_PULSE_RATE_FLAG_BIT; - encoded_sfloat = ((p_meas->pulse_rate.exponent << OFFSET_12) & 0xF000) | + encoded_sfloat = ((p_meas->pulse_rate.exponent << 12) & 0xF000) | ((p_meas->pulse_rate.mantissa << 0) & 0x0FFF); p_encoded_buffer[length++] = LO_U16(encoded_sfloat); p_encoded_buffer[length++] = HI_U16(encoded_sfloat); } // User ID - if (p_meas->user_id_present) { + if (p_meas->user_id_present) + { flags |= BPS_MEAS_USER_ID_FLAG_BIT; p_encoded_buffer[length++] = p_meas->user_id; } // Measurement Status - if (p_meas->meas_status_present) { + if (p_meas->meas_status_present) + { flags |= BPS_MEAS_MEASUREMENT_STATUS_FLAG_BIT; p_encoded_buffer[length++] = LO_U16(p_meas->meas_status); p_encoded_buffer[length++] = HI_U16(p_meas->meas_status); @@ -469,11 +415,12 @@ sdk_err_t bps_measurement_send(uint8_t conidx, bps_meas_t *p_meas) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; uint8_t encoded_bps_meas[BPS_BP_MEAS_MAX_LEN] = {0}; - gatts_noti_ind_t bps_ind; + ble_gatts_noti_ind_t bps_ind; uint16_t length = bps_measurement_encode(p_meas, encoded_bps_meas); - if (PRF_CLI_START_IND == (s_bps_env.ntf_ind_cfg[conidx] & PRF_CLI_START_IND)) { + if (PRF_CLI_START_IND == (s_bps_env.ntf_ind_cfg[conidx] & PRF_CLI_START_IND)) + { bps_ind.type = BLE_GATT_INDICATION; bps_ind.handle = prf_find_handle_by_idx(BPS_IDX_BP_MEAS_VAL, s_bps_env.start_hdl, @@ -487,17 +434,49 @@ sdk_err_t bps_measurement_send(uint8_t conidx, bps_meas_t *p_meas) return error_code; } +static void bps_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + bps_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + bps_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + bps_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + sdk_err_t bps_service_init(bps_init_t *p_bps_init) { - sdk_err_t ret; - if (p_bps_init == NULL) { + if (NULL == p_bps_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_bps_env.bps_init, sizeof(bps_init_t), p_bps_init, sizeof(bps_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_bps_env.bps_init, p_bps_init, sizeof(bps_init_t)); - return ble_server_prf_add(&bps_prf_info); + memset(&s_bps_env.bps_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_bps_env.start_hdl = PRF_INVALID_HANDLE; + s_bps_env.bps_serv_db.shdl = &s_bps_env.start_hdl; + s_bps_env.bps_serv_db.uuid = s_bps_svc_uuid; + s_bps_env.bps_serv_db.attr_tab_cfg = (uint8_t*)&(s_bps_env.bps_init.char_mask); + s_bps_env.bps_serv_db.max_nb_attr = BPS_IDX_NB; + s_bps_env.bps_serv_db.srvc_perm = 0; + s_bps_env.bps_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_bps_env.bps_serv_db.attr_tab.attr_tab_16 = bps_attr_tab; + + return ble_gatts_prf_add(&s_bps_env.bps_serv_db, bps_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.h index 6a5a7a8..33a7107 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/bps/bps.h @@ -70,18 +70,17 @@ #ifndef __BPS_H__ #define __BPS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_utils.h" #include "custom_config.h" +#include +#include /** * @defgroup BPS_MACRO Defines * @{ */ -#define BPS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of BPS connections. */ +#define BPS_CONNECTION_MAX 10 /**< Maximum number of BPS connections. */ #define BPS_BP_MEAS_MAX_LEN 20 /**< Maximum notification length. */ /** @@ -100,7 +99,8 @@ * @{ */ /**@brief Blood Pressure Service event type. */ -typedef enum { +typedef enum +{ BPS_EVT_INVALID, /**< Invalid event. */ BPS_EVT_BP_MEAS_INDICATION_ENABLED, /**< The measurement indication has been enabled. */ BPS_EVT_BP_MEAS_INDICATION_DISABLED, /**< The measurement indication has been disabled. */ @@ -110,7 +110,8 @@ typedef enum { } bps_evt_type_t; /**@brief Blood Pressure Feature bits. */ -enum bp_feature_bit { +enum bp_feature_bit +{ BP_FEATURE_BODY_MOVEMENT_BIT = (0x01 << 0), /**< Body Movement Detection Support bit. */ BP_FEATURE_CUFF_FIT_BIT = (0x01 << 1), /**< Cuff Fit Detection Support bit. */ BP_FEATURE_IRREGULAR_PULSE_BIT = (0x01 << 2), /**< Irregular Pulse Detection Support bit. */ @@ -133,33 +134,34 @@ typedef void (*bps_evt_handler_t)(uint8_t conn_idx, bps_evt_type_t event); * @{ */ /**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, defined as a 16-bit value with 12-bit mantissa and 4-bit exponent. */ -typedef struct { - int8_t exponent; /**< Base 10 exponent, only 4 bits */ - int16_t mantissa; /**< Mantissa, only 12 bits */ -} ieee_float16_t; +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, only 4 bits */ + int16_t mantissa; /**< Mantissa, only 12 bits */ +} bps_ieee_float16_t; /**@brief Blood Pressure measurement structure. */ -typedef struct { - uint8_t bl_unit_in_kpa; /**< Blood Pressure Units Flag, 0=mmHg, 1=kPa */ - uint8_t time_stamp_present; /**< Time Stamp Flag, 0=not present, 1=present. */ - uint8_t pulse_rate_present; /**< Pulse Rate Flag, 0=not present, 1=present. */ - uint8_t user_id_present; /**< User ID Flag, 0=not present, 1=present. */ - uint8_t meas_status_present; /**< Measurement Status Flag, 0=not present, 1=present. */ - ieee_float16_t systolic; /**< Blood Pressure Measurement Compound Value - Systolic. */ - ieee_float16_t diastolic; /**< Blood Pressure Measurement Compound Value - Diastolic . */ - ieee_float16_t mean_arterial_pr; /**< Blood Pressure Measurement Compound Value - Mean Arterial Pressure. */ - prf_date_time_t time_stamp; /**< Time Stamp. */ - ieee_float16_t pulse_rate; /**< Pulse Rate. */ - uint8_t user_id; /**< User ID. */ - uint16_t meas_status; /**< Measurement Status. */ +typedef struct +{ + uint8_t bl_unit_in_kpa; /**< Blood Pressure Units Flag, 0=mmHg, 1=kPa */ + uint8_t time_stamp_present; /**< Time Stamp Flag, 0=not present, 1=present. */ + uint8_t pulse_rate_present; /**< Pulse Rate Flag, 0=not present, 1=present. */ + uint8_t user_id_present; /**< User ID Flag, 0=not present, 1=present. */ + uint8_t meas_status_present; /**< Measurement Status Flag, 0=not present, 1=present. */ + bps_ieee_float16_t systolic; /**< Blood Pressure Measurement Compound Value - Systolic. */ + bps_ieee_float16_t diastolic; /**< Blood Pressure Measurement Compound Value - Diastolic . */ + bps_ieee_float16_t mean_arterial_pr; /**< Blood Pressure Measurement Compound Value - Mean Arterial Pressure. */ + prf_date_time_t time_stamp; /**< Time Stamp. */ + bps_ieee_float16_t pulse_rate; /**< Pulse Rate. */ + uint8_t user_id; /**< User ID. */ + uint16_t meas_status; /**< Measurement Status. */ } bps_meas_t; -/**@brief Blood Pressure Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Blood Pressure Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ bps_evt_handler_t evt_handler; /**< Blood Pressure Service event handler. */ - uint16_t - char_mask; /**< Mask of Supported characteristics, and configured with \ref BPS_CHAR_MASK */ + uint16_t char_mask; /**< Mask of Supported characteristics, and configured with \ref BPS_CHAR_MASK */ uint16_t bp_feature; /**< Value of Blood Pressure Feature characteristic. */ } bps_init_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/BUILD.gn new file mode 100644 index 0000000..62c57d1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("common") { + sources = [ + "ble_prf_utils.c", + "ble_srv_disc_utils.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_types.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_types.h index a95c7b6..e7e2568 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_types.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_types.h @@ -50,8 +50,8 @@ #ifndef __BLE_PRF_TYPES_H__ #define __BLE_PRF_TYPES_H__ +#include "gr_includes.h" #include -#include "gr55xx_sys.h" /** @defgroup BLE_MACRO Defines * @{ @@ -66,7 +66,8 @@ * @{ */ /**@brief The values for setting client configuration characteristics. */ -typedef enum { +typedef enum +{ PRF_CLI_STOP_NTFIND = 0x0000, /**< Stop notification/indication. */ PRF_CLI_START_NTF, /**< Start notification. */ PRF_CLI_START_IND, /**< Start indication. */ @@ -86,7 +87,8 @@ typedef void (*prf_error_handler_t)(sdk_err_t err_code); */ /**@brief Characteristic Presentation Format Descriptor structure. * The packed size is \ref PRF_CHAR_PRES_FMT_SIZE. */ -typedef struct { +typedef struct +{ uint16_t unit; /**< Unit (The Unit is a UUID). */ uint16_t description; /**< Description. */ uint8_t format; /**< Format. */ @@ -95,7 +97,8 @@ typedef struct { } prf_char_pres_fmt_t; /**@brief The date and time structure. The packed size is 7 bytes. */ -typedef struct { +typedef struct +{ uint16_t year; /**< year time element. */ uint8_t month; /**< month time element. */ uint8_t day; /**< day time element. */ @@ -105,7 +108,8 @@ typedef struct { } prf_date_time_t; /**@brief Slave preferred connection parameters. */ -typedef struct { +typedef struct +{ uint16_t con_intv_min; /**< Connection interval minimum. */ uint16_t con_intv_max; /**< Connection interval maximum. */ uint16_t slave_latency; /**< Slave latency. */ @@ -113,7 +117,8 @@ typedef struct { } gap_slv_pref_t; /**@brief Attribute information. */ -typedef struct { +typedef struct +{ uint16_t handle; /**< Attribute Handle. */ uint16_t offset; /**< Offset of the attribute value . */ uint16_t length; /**< Attribute length. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.c index f977e7a..69a5a3d 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.c @@ -39,18 +39,11 @@ * INCLUDE FILES ******************************************************************************* */ +#include "ble_prf_utils.h" +#include "utility.h" #include #include -#include "utility.h" -#include "ble_prf_utils.h" -#define OFFSET_2 2 -#define OFFSET_3 3 -#define OFFSET_4 4 -#define OFFSET_5 5 -#define OFFSET_6 6 -#define VALUE_7 7 -#define VALUE_8 8 /* * GLOBAL FUNCTION DEFINITIONS ******************************************************************************* @@ -60,48 +53,49 @@ void prf_pack_char_pres_fmt(uint8_t *p_packed_val, { *p_packed_val = p_char_pres_fmt->format; *(p_packed_val + 1) = p_char_pres_fmt->exponent; - - htole16(p_packed_val + OFFSET_2, p_char_pres_fmt->unit); - - *(p_packed_val + OFFSET_4) = p_char_pres_fmt->name_space; - - htole16(p_packed_val + OFFSET_5, p_char_pres_fmt->description); + + htole16(p_packed_val + 2, p_char_pres_fmt->unit); + + *(p_packed_val + 4) = p_char_pres_fmt->name_space; + + htole16(p_packed_val + 5, p_char_pres_fmt->description); } void prf_unpack_char_pres_fmt(const uint8_t *p_packed_val, prf_char_pres_fmt_t *p_char_pres_fmt) { + p_char_pres_fmt->format = *p_packed_val; p_char_pres_fmt->exponent = *(p_packed_val + 1); - p_char_pres_fmt->unit = le16toh(p_packed_val + OFFSET_2); - p_char_pres_fmt->name_space = *(p_packed_val + OFFSET_4); - p_char_pres_fmt->description = le16toh(p_packed_val + OFFSET_5); + p_char_pres_fmt->unit = le16toh(p_packed_val + 2); + p_char_pres_fmt->name_space = *(p_packed_val + 4); + p_char_pres_fmt->description = le16toh(p_packed_val + 5); } uint8_t prf_pack_date_time(uint8_t *p_packed_val, const prf_date_time_t *p_date_time) { htole16(p_packed_val, p_date_time->year); - *(p_packed_val + OFFSET_2) = p_date_time->month; - *(p_packed_val + OFFSET_3) = p_date_time->day; - *(p_packed_val + OFFSET_4) = p_date_time->hour; - *(p_packed_val + OFFSET_5) = p_date_time->min; - *(p_packed_val + OFFSET_6) = p_date_time->sec; + *(p_packed_val + 2) = p_date_time->month; + *(p_packed_val + 3) = p_date_time->day; + *(p_packed_val + 4) = p_date_time->hour; + *(p_packed_val + 5) = p_date_time->min; + *(p_packed_val + 6) = p_date_time->sec; - return VALUE_7; + return 7; } uint8_t prf_unpack_date_time(const uint8_t *p_packed_val, prf_date_time_t *p_date_time) { p_date_time->year = le16toh(&(p_packed_val[0])); - p_date_time->month = p_packed_val[OFFSET_2]; - p_date_time->day = p_packed_val[OFFSET_3]; - p_date_time->hour = p_packed_val[OFFSET_4]; - p_date_time->min = p_packed_val[OFFSET_5]; - p_date_time->sec = p_packed_val[OFFSET_6]; + p_date_time->month = p_packed_val[2]; + p_date_time->day = p_packed_val[3]; + p_date_time->hour = p_packed_val[4]; + p_date_time->min = p_packed_val[5]; + p_date_time->sec = p_packed_val[6]; - return VALUE_7; + return 7; } uint8_t prf_find_idx_by_handle(uint16_t handle, uint16_t start_hdl, @@ -113,8 +107,8 @@ uint8_t prf_find_idx_by_handle(uint16_t handle, uint16_t start_hdl, uint8_t bit = 0; for (uint8_t i = 1; i < char_nb; i++) { - byte = i / VALUE_8; - bit = i % VALUE_8; + byte = i / 8; + bit = i % 8; if ((p_char_mask[byte] >> bit) & 0x01) { // check if value handle correspond to requested handle if (cur_hdl == handle) { @@ -138,18 +132,17 @@ uint16_t prf_find_handle_by_idx(uint8_t idx, uint16_t start_hdl, if (!idx) { found_hdl = start_hdl; - return found_hdl; - } + } else { + for(uint8_t i = 1; i <= idx; i++) { + byte = i / 8; + bit = i % 8; - for (uint8_t i = 1; i <= idx; i++) { - byte = i / VALUE_8; - bit = i % VALUE_8; + if ((p_char_mask[byte] >> bit) & 0x01) { + cur_hdl++; - if ((p_char_mask[byte] >> bit) & 0x01) { - cur_hdl++; - - if (i == idx) { - found_hdl = cur_hdl; + if (i == idx) { + found_hdl = cur_hdl; + } } } } @@ -160,8 +153,9 @@ uint16_t prf_find_handle_by_idx(uint8_t idx, uint16_t start_hdl, bool prf_is_cccd_value_valid(uint16_t cccd_value) { if (PRF_CLI_STOP_NTFIND == cccd_value || \ - PRF_CLI_START_NTF == cccd_value || \ - PRF_CLI_START_IND == cccd_value) { + PRF_CLI_START_NTF == cccd_value || \ + PRF_CLI_START_IND == cccd_value) + { return true; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.h index 148e1db..9d2146c 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_prf_utils.h @@ -51,8 +51,8 @@ #ifndef __BLE_PRF_UTILS_H__ #define __BLE_PRF_UTILS_H__ -#include #include "ble_prf_types.h" +#include /** * @defgroup BLE_PRF_UTILS_FUNCTION Functions diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.c index 0680c58..d04e478 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.c @@ -53,7 +53,8 @@ static ble_srv_disc_state_t srv_disc_procedure[BLE_SRV_DISC_PROC_NB]; */ void ble_srv_disc_proc_state_set(uint8_t srv_disc_proc_id, ble_srv_disc_state_t srv_disc_state) { - if (BLE_SRV_DISC_PROC_MAX <= srv_disc_proc_id) { + if (BLE_SRV_DISC_PROC_MAX <= srv_disc_proc_id) + { return; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.h index 6896f44..aa751f6 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/common/ble_srv_disc_utils.h @@ -57,7 +57,7 @@ * @defgroup DIS_C_MACRO Defines * @{ */ -#define BLE_SRV_DISC_PROC_MAX 6 /**< Maximum number of services discovery procedure in one application. */ +#define BLE_SRV_DISC_PROC_MAX 6 /**< Maximum number of services discovery procedure in one application. */ /** @} */ /** @@ -65,14 +65,16 @@ * @{ */ /**@brief BLE Service Discovery Procedure State. */ -typedef enum { +typedef enum +{ BLE_SRV_DISC_NO_IMPLEMENT, /**< Service discovery procedure has not been implemented. */ BLE_SRV_DISC_UNDERWAY, /**< Service discovery procedure is underway. */ BLE_SRV_DISC_COMPLETELY, /**< Service discovery procedure has been completed. */ } ble_srv_disc_state_t; /**@brief BLE Service Discovery Procedure ID. */ -typedef enum { +typedef enum +{ BLE_SRV_DISC_PROC_ID_0, /**< Service discovery procedure ID_0. */ BLE_SRV_DISC_PROC_ID_1, /**< Service discovery procedure ID_1. */ BLE_SRV_DISC_PROC_ID_2, /**< Service discovery procedure ID_2. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/BUILD.gn new file mode 100644 index 0000000..7859293 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("cscs") { + sources = [ "cscs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.c index 09dd376..46aed0e 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.c @@ -49,7 +49,8 @@ ***************************************************************************************** */ /**@brief Cycling Speed and Cadence Service Attributes Indexes. */ -enum { +enum +{ CSCS_IDX_SVC, CSCS_IDX_CSC_MEAS_CHAR, @@ -74,32 +75,23 @@ enum { ***************************************************************************************** */ /**@brief Cycling Speed and Cadence Service environment variable. */ -struct cscs_env_t { - cscs_init_t - cscs_init; /**< Cycling Speed and Cadence Service initialization variables. */ - uint16_t start_hdl; /**< Cycling Speed and Cadence Service start handle. */ - bool - ctrl_pt_op_in_progress; /**< A previously triggered SC Control Point operation is still in progress. */ - bool - ctrl_pt_op_rsp_cplt; /**< A previously triggered SC Control Point operation response cplt. */ - uint16_t - meas_ntf_cfg[CSCS_CONNECTION_MAX]; /**< The configuration of CSC Measurement Notification \ - which is configured by the peer devices. */ - uint16_t - ctrl_point_ind_cfg[CSCS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification \ - which is configured by the peer devices. */ +struct cscs_env_t +{ + cscs_init_t cscs_init; /**< Cycling Speed and Cadence Service initialization variables. */ + uint16_t start_hdl; /**< Cycling Speed and Cadence Service start handle. */ + bool ctrl_pt_op_in_progress; /**< A previously triggered SC Control Point operation is still in progress. */ + bool ctrl_pt_op_rsp_cplt; /**< A previously triggered SC Control Point operation response cplt. */ + uint16_t meas_ntf_cfg[CSCS_CONNECTION_MAX]; /**< The configuration of CSC Measurement Notification which is configured by the peer devices. */ + uint16_t ctrl_point_ind_cfg[CSCS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification which is configured by the peer devices. */ + ble_gatts_create_db_t cscs_serv_db; /**< Cycling Speed and Cadence Service DataBase. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t cscs_init(void); -static void cscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void cscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void cscs_disconnect_cb(uint8_t conn_idx, uint8_t reason); -static void cscs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); + + static void cscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); /* @@ -107,88 +99,55 @@ static void cscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data ***************************************************************************************** */ static struct cscs_env_t s_cscs_env; +static const uint8_t s_cscs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_CYCLING_SPEED_CADENCE); /**@brief Full CSCS Database Description - Used to add attributes into the database. */ -static const attm_desc_t cscs_attr_tab[CSCS_IDX_NB] = { +static const ble_gatts_attm_desc_t cscs_attr_tab[CSCS_IDX_NB] = +{ // Cycling Speed and Cadence Service Declaration - [CSCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [CSCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // CSC Measurement Characteristic - Declaration - [CSCS_IDX_CSC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CSCS_IDX_CSC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // CSC Measurement Characteristic - Value - [CSCS_IDX_CSC_MEAS_VAL] = { - BLE_ATT_CHAR_CSC_MEAS, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - CSCS_MEAS_VAL_LEN_MAX - }, + [CSCS_IDX_CSC_MEAS_VAL] = {BLE_ATT_CHAR_CSC_MEAS, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + CSCS_MEAS_VAL_LEN_MAX}, // CSC Measurement Characteristic - Client Characteristic Configuration Descriptor - [CSCS_IDX_CSC_MEAS_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [CSCS_IDX_CSC_MEAS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // CS Feature Characteristic - Declaration - [CSCS_IDX_CSC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CSCS_IDX_CSC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // CSC Feature Characteristic - Value - [CSCS_IDX_CSC_FEAT_VAL] = { - BLE_ATT_CHAR_CSC_FEAT, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - CSCS_FEAT_VAL_LEN_MAX - }, + [CSCS_IDX_CSC_FEAT_VAL] = {BLE_ATT_CHAR_CSC_FEAT, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + CSCS_FEAT_VAL_LEN_MAX}, // Sensor Location Characteristic - Declaration - [CSCS_IDX_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CSCS_IDX_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Sensor Location Characteristic - Value - [CSCS_IDX_SENSOR_LOC_VAL] = { - BLE_ATT_CHAR_SENSOR_LOC, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - CSCS_SENSOR_LOC_VAL_LEN_MAX - }, + [CSCS_IDX_SENSOR_LOC_VAL] = {BLE_ATT_CHAR_SENSOR_LOC, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + CSCS_SENSOR_LOC_VAL_LEN_MAX}, // SC Control Point Characteristic - Declaration - [CSCS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CSCS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // SC Control Point Characteristic - Value - [CSCS_IDX_CTRL_POINT_VAL] = { - BLE_ATT_CHAR_SC_CNTL_PT, - WRITE_REQ_PERM_UNSEC | INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - CSCS_CTRL_PT_VAL_LEN_MAX - }, + [CSCS_IDX_CTRL_POINT_VAL] = {BLE_ATT_CHAR_SC_CNTL_PT, + BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_INDICATE_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + CSCS_CTRL_PT_VAL_LEN_MAX}, // SC Control Point Characteristic - Client Characteristic Configuration Descriptor - [CSCS_IDX_CTRL_POINT_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief CSCS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t cscs_task_cbs = { - (prf_init_func_t) cscs_init, - NULL, - cscs_disconnect_cb -}; - -/**@brief CSCS Task Callbacks. */ -static gatts_prf_cbs_t cscs_cb_func = { - cscs_read_att_cb, - cscs_write_att_cb, - NULL, - cscs_ntf_ind_cb, - cscs_cccd_set_cb -}; - -/**@brief CSCS Information. */ -static const prf_server_info_t cscs_prf_info = { - .max_connection_nb = CSCS_CONNECTION_MAX, - .manager_cbs = &cscs_task_cbs, - .gatts_prf_cbs = &cscs_cb_func, + [CSCS_IDX_CTRL_POINT_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, }; /* @@ -202,34 +161,7 @@ static const prf_server_info_t cscs_prf_info = { * @return Error code to know if profile initialization succeed or not. ***************************************************************************************** */ -static sdk_err_t cscs_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t rscs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_CYCLING_SPEED_CADENCE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = rscs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_cscs_env.cscs_init.char_mask); - gatts_db.max_nb_attr = CSCS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = cscs_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_cscs_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} /** ***************************************************************************************** @@ -239,18 +171,19 @@ static sdk_err_t cscs_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void cscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void cscs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, + uint8_t tab_index = prf_find_idx_by_handle(handle, s_cscs_env.start_hdl, CSCS_IDX_NB, - (uint8_t *)&s_cscs_env.cscs_init.char_mask); + (uint8_t *)&s_cscs_env.cscs_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case CSCS_IDX_CSC_MEAS_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_cscs_env.meas_ntf_cfg[conn_idx]; @@ -265,7 +198,7 @@ static void cscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_pa cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)&s_cscs_env.cscs_init.sensor_location; break; - + case CSCS_IDX_CTRL_POINT_IND_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_cscs_env.ctrl_point_ind_cfg[conn_idx]; @@ -288,14 +221,14 @@ static void cscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_pa * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void cscs_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; bool ctrl_pt_evt = false; cscs_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_cscs_env.start_hdl, @@ -305,23 +238,29 @@ static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ cfm.status = BLE_SUCCESS; event.evt_type = CSCS_EVT_INVALID; event.conn_idx = conn_idx; - - switch (tab_index) { + + switch (tab_index) + { case CSCS_IDX_CSC_MEAS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE :\ - CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE); + CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE :\ + CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE); s_cscs_env.meas_ntf_cfg[conn_idx] = cccd_value; break; case CSCS_IDX_CTRL_POINT_VAL: - if (PRF_CLI_START_IND != s_cscs_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND != s_cscs_env.ctrl_point_ind_cfg[conn_idx]) + { cfm.status = CSCS_ERROR_CCCD_INVALID; break; - } else if (s_cscs_env.ctrl_pt_op_in_progress) { + } + else if (s_cscs_env.ctrl_pt_op_in_progress) + { cfm.status = CSCS_ERROR_PROC_IN_PROGRESS; - } else if (PRF_CLI_START_IND == s_cscs_env.ctrl_point_ind_cfg[conn_idx]) { + } + else if (PRF_CLI_START_IND == s_cscs_env.ctrl_point_ind_cfg[conn_idx]) + { s_cscs_env.ctrl_pt_op_in_progress = true; ctrl_pt_evt = true; } @@ -330,8 +269,8 @@ static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ case CSCS_IDX_CTRL_POINT_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - CSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ - CSCS_EVT_CTRL_POINT_INDICATION_DISABLE); + CSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ + CSCS_EVT_CTRL_POINT_INDICATION_DISABLE); s_cscs_env.ctrl_point_ind_cfg[conn_idx] = cccd_value; break; @@ -342,10 +281,12 @@ static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ ble_gatts_write_cfm(conn_idx, &cfm); - if (ctrl_pt_evt) { + if (ctrl_pt_evt) + { cscs_sc_ctrl_pt_handler(conn_idx, p_param->value, p_param->length); - } else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && CSCS_EVT_INVALID != event.evt_type - && s_cscs_env.cscs_init.evt_handler) { + } + else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && CSCS_EVT_INVALID != event.evt_type && s_cscs_env.cscs_init.evt_handler) + { s_cscs_env.cscs_init.evt_handler(&event); } } @@ -359,12 +300,13 @@ static void cscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void cscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void cscs_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; cscs_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -375,19 +317,20 @@ static void cscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va event.evt_type = CSCS_EVT_INVALID; event.conn_idx = conn_idx; - - switch (tab_index) { + + switch (tab_index) + { case CSCS_IDX_CSC_MEAS_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE :\ - CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE); + CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE :\ + CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE); s_cscs_env.meas_ntf_cfg[conn_idx] = cccd_value; break; case CSCS_IDX_CTRL_POINT_IND_CFG: event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - CSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ - CSCS_EVT_CTRL_POINT_INDICATION_DISABLE); + CSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ + CSCS_EVT_CTRL_POINT_INDICATION_DISABLE); s_cscs_env.ctrl_point_ind_cfg[conn_idx] = cccd_value; break; @@ -395,7 +338,9 @@ static void cscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va break; } - if (CSCS_EVT_INVALID != event.evt_type && s_cscs_env.cscs_init.evt_handler) { + + if (CSCS_EVT_INVALID != event.evt_type && s_cscs_env.cscs_init.evt_handler) + { s_cscs_env.cscs_init.evt_handler(&event); } } @@ -408,17 +353,21 @@ static void cscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va * @param[in] p_param: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void cscs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void cscs_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { cscs_evt_t event; event.evt_type = CSCS_EVT_INVALID; event.conn_idx = conn_idx; - if (s_cscs_env.cscs_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (s_cscs_env.cscs_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = CSCS_EVT_CSC_MEAS_SEND_CPLT; - } else if (BLE_GATT_INDICATION == p_ntf_ind->type) { + } + else if (BLE_GATT_INDICATION == p_ntf_ind->type) + { event.evt_type = CSCS_EVT_CTRL_POINT_RSP_CPLT; s_cscs_env.ctrl_pt_op_in_progress = false; } @@ -434,7 +383,7 @@ static void cscs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_nt * @param[in] reason: Reason of disconnection. ***************************************************************************************** */ -static void cscs_disconnect_cb(uint8_t conn_idx, uint8_t reason) +static void cscs_disconnect_evt_handler(uint8_t conn_idx, uint8_t reason) { s_cscs_env.ctrl_pt_op_in_progress = false; } @@ -453,19 +402,22 @@ static void cscs_op_set_cumulative_handler(uint8_t conn_idx, const uint8_t *p_da cscs_evt_t event; uint8_t rsp[CSCS_CTRL_PT_RSP_LEN_MIN]; - rsp[INDEX_0] = CSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = CSCS_CTRL_PT_OP_SET_CUMUL_VAL; - ATrsp[INDEX_2] = CSCS_CTRL_PT_RSP_FAILED; + rsp[0] = CSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = CSCS_CTRL_PT_OP_SET_CUMUL_VAL; + rsp[2] = CSCS_CTRL_PT_RSP_FAILED; if ((sizeof(uint32_t) == length) && \ (s_cscs_env.cscs_init.feature & CSCS_FEAT_WHEEL_REVOLUTION_SUP_BIT) && \ - (s_cscs_env.cscs_init.evt_handler)) { + (s_cscs_env.cscs_init.evt_handler)) + { event.conn_idx = conn_idx; event.evt_type = CSCS_EVT_CUMUL_VAL_SET; event.p_data = p_data; event.length = length; s_cscs_env.cscs_init.evt_handler(&event); - } else { + } + else + { cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -484,20 +436,25 @@ static void cscs_op_sensor_loc_update_handler(uint8_t conn_idx, const uint8_t *p cscs_evt_t event; uint8_t rsp[CSCS_CTRL_PT_RSP_LEN_MIN]; - rsp[INDEX_0] = CSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = CSCS_CTRL_PT_OP_UPD_LOC; + rsp[0] = CSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = CSCS_CTRL_PT_OP_UPD_LOC; - if (CSCS_SENSOR_LOC_SUP_NB <= p_data[0] || (sizeof(uint8_t) != length)) { - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_INVALID_PARAM; + if (CSCS_SENSOR_LOC_SUP_NB <= p_data[0] || (sizeof(uint8_t) != length)) + { + rsp[2] = CSCS_CTRL_PT_RSP_INVALID_PARAM; cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); - } else if ((s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) && s_cscs_env.cscs_init.evt_handler) { + } + else if ((s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) && s_cscs_env.cscs_init.evt_handler) + { event.conn_idx = conn_idx; event.evt_type = CSCS_EVT_SEBSOR_LOC_UPD; event.p_data = p_data; event.length = length; s_cscs_env.cscs_init.evt_handler(&event); - } else { - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_FAILED; + } + else + { + rsp[2] = CSCS_CTRL_PT_RSP_FAILED; cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -515,24 +472,29 @@ static void cscs_op_sup_sensor_loc_req_handler(uint8_t conn_idx) uint8_t rsp[CSCS_CTRL_PT_RSP_LEN_MIN + CSCS_SENSOR_LOC_SUP_NB]; uint8_t rsp_idx = CSCS_CTRL_PT_RSP_LEN_MIN; - rsp[INDEX_0] = CSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = CSCS_CTRL_PT_OP_REQ_SUP_LOC; - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_SUCCESS; + rsp[0] = CSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = CSCS_CTRL_PT_OP_REQ_SUP_LOC; + rsp[2] = CSCS_CTRL_PT_RSP_SUCCESS; - if (s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) + { event.conn_idx = conn_idx; event.evt_type = CSCS_EVT_SUP_SEBSOR_LOC_REQ; - if (s_cscs_env.cscs_init.evt_handler) { - s_cscs_env.cscs_init.evt_handler(&event); + if (s_cscs_env.cscs_init.evt_handler) + { + s_cscs_env.cscs_init.evt_handler(&event); } - for (uint8_t i = 0; i < CSCS_SENSOR_LOC_SUP_NB; i++) { + for (uint8_t i = 0; i < CSCS_SENSOR_LOC_SUP_NB; i++) + { rsp[rsp_idx++] = i; } cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN + CSCS_SENSOR_LOC_SUP_NB); - } else { - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_FAILED; + } + else + { + rsp[2] = CSCS_CTRL_PT_RSP_FAILED; cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -550,15 +512,16 @@ static void cscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uin { uint8_t rsp[CSCS_CTRL_PT_RSP_LEN_MIN]; - switch (p_data[0]) { + switch(p_data[0]) + { case CSCS_CTRL_PT_OP_SET_CUMUL_VAL: cscs_op_set_cumulative_handler(conn_idx, &p_data[1], length - 1); break; case CSCS_CTRL_PT_OP_START_CALIB: - rsp[INDEX_0] = CSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = p_data[0]; - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_NOT_SUP; + rsp[0] = CSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = p_data[0]; + rsp[2] = CSCS_CTRL_PT_RSP_NOT_SUP; cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); break; @@ -571,9 +534,9 @@ static void cscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uin break; default: - rsp[INDEX_0] = CSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = p_data[0]; - rsp[INDEX_2] = CSCS_CTRL_PT_RSP_NOT_SUP; + rsp[0] = CSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = p_data[0]; + rsp[2] = CSCS_CTRL_PT_RSP_NOT_SUP; cscs_ctrl_pt_rsp_send(conn_idx, rsp, CSCS_CTRL_PT_RSP_LEN_MIN); break; } @@ -595,8 +558,10 @@ static uint16_t csc_meas_value_encoded(cscs_meas_val_t *p_meas, uint8_t *p_encod uint16_t length = 1; // Cumulative Wheel Revolutions and Last Wheel Event Time Fields - if (s_cscs_env.cscs_init.feature & CSCS_FEAT_WHEEL_REVOLUTION_SUP_BIT) { - if (p_meas->wheel_rev_data_present) { + if (s_cscs_env.cscs_init.feature & CSCS_FEAT_WHEEL_REVOLUTION_SUP_BIT) + { + if (p_meas->wheel_rev_data_present) + { p_encoded_buffer[length++] = LO_UINT32_T(p_meas->cumulative_wheel_revs); p_encoded_buffer[length++] = L2_UINT32_T(p_meas->cumulative_wheel_revs); p_encoded_buffer[length++] = L3_UINT32_T(p_meas->cumulative_wheel_revs); @@ -610,8 +575,10 @@ static uint16_t csc_meas_value_encoded(cscs_meas_val_t *p_meas, uint8_t *p_encod } // Cumulative Crank Revolutions and Last Crank Event Time Fields - if (s_cscs_env.cscs_init.feature & CSCS_FEAT_CRANK_REVOLUTION_SUP_BIT) { - if (p_meas->crank_rev_data_present) { + if (s_cscs_env.cscs_init.feature & CSCS_FEAT_CRANK_REVOLUTION_SUP_BIT) + { + if (p_meas->crank_rev_data_present) + { p_encoded_buffer[length++] = LO_U16(p_meas->cumulative_crank_revs); p_encoded_buffer[length++] = HI_U16(p_meas->cumulative_crank_revs); p_encoded_buffer[length++] = LO_U16(p_meas->last_crank_event_time); @@ -636,11 +603,12 @@ sdk_err_t cscs_measurement_send(uint8_t conn_idx, cscs_meas_val_t *p_meas) sdk_err_t error_code = SDK_ERR_NTF_DISABLED; uint8_t encoded_csc_meas[CSCS_MEAS_VAL_LEN_MAX]; uint16_t length; - gatts_noti_ind_t csc_ntf; + ble_gatts_noti_ind_t csc_ntf; length = csc_meas_value_encoded(p_meas, encoded_csc_meas); - if (PRF_CLI_START_NTF == s_cscs_env.meas_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_cscs_env.meas_ntf_cfg[conn_idx]) + { csc_ntf.type = BLE_GATT_NOTIFICATION; csc_ntf.handle = prf_find_handle_by_idx(CSCS_IDX_CSC_MEAS_VAL, s_cscs_env.start_hdl, @@ -656,9 +624,10 @@ sdk_err_t cscs_measurement_send(uint8_t conn_idx, cscs_meas_val_t *p_meas) sdk_err_t cscs_ctrl_pt_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t ctrl_pt_rsp; + ble_gatts_noti_ind_t ctrl_pt_rsp; - if (PRF_CLI_START_IND == s_cscs_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_cscs_env.ctrl_point_ind_cfg[conn_idx]) + { ctrl_pt_rsp.type = BLE_GATT_INDICATION; ctrl_pt_rsp.handle = prf_find_handle_by_idx(CSCS_IDX_CTRL_POINT_VAL, s_cscs_env.start_hdl, @@ -675,32 +644,72 @@ sdk_err_t cscs_sensor_loc_update(cscs_sensor_loc_t sensor_loc) { sdk_err_t error_code = BLE_SUCCESS; - if (s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (s_cscs_env.cscs_init.feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) + { s_cscs_env.cscs_init.sensor_location = sensor_loc; - } else { + } + else + { error_code = SDK_ERR_DISALLOWED; } return error_code; } +static void cscs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + cscs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + cscs_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + cscs_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index,p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + cscs_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + case BLE_GAPC_EVT_DISCONNECTED: + cscs_disconnect_evt_handler(p_evt->evt.gapc_evt.index,p_evt->evt.gapc_evt.params.disconnected.reason); + break; + default: + break; + } +} sdk_err_t cscs_service_init(cscs_init_t *p_cscs_init) { - sdk_err_t ret; - if (p_cscs_init == NULL) { + if (NULL == p_cscs_init) + { return SDK_ERR_POINTER_NULL; } - if (p_cscs_init->feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (p_cscs_init->feature & CSCS_FEAT_MULTIPLE_SENSORS_BIT) + { p_cscs_init->char_mask |= CSCS_CHAR_SENSOR_LOC_SUP; - } else { + } + else + { p_cscs_init->char_mask &= ~CSCS_CHAR_SENSOR_LOC_SUP; } - ret = memcpy_s(&s_cscs_env.cscs_init, sizeof(cscs_init_t), p_cscs_init, sizeof(cscs_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_cscs_env.cscs_init, p_cscs_init, sizeof(cscs_init_t)); - return ble_server_prf_add(&cscs_prf_info); + memset(&s_cscs_env.cscs_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_cscs_env.start_hdl = PRF_INVALID_HANDLE; + s_cscs_env.cscs_serv_db.shdl = &s_cscs_env.start_hdl; + s_cscs_env.cscs_serv_db.uuid = s_cscs_svc_uuid; + s_cscs_env.cscs_serv_db.attr_tab_cfg = (uint8_t *)&(s_cscs_env.cscs_init.char_mask); + s_cscs_env.cscs_serv_db.max_nb_attr = CSCS_IDX_NB; + s_cscs_env.cscs_serv_db.srvc_perm = 0; + s_cscs_env.cscs_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_cscs_env.cscs_serv_db.attr_tab.attr_tab_16 = cscs_attr_tab; + return ble_gatts_prf_add(&s_cscs_env.cscs_serv_db, cscs_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.h index 23384c6..42e590c 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cscs/cscs.h @@ -51,45 +51,41 @@ * and Cadence Service with CSC Measurement, CSC Feature, Sensor Location and SC Control Point characteristics. * * After \ref cscs_init_t variable is initialized, the application must call \ref cscs_service_init() - * to add the Cycling Speed and Cadence Service and CSC Measurement, CSC Feature, Sensor Location and + * to add the Cycling Speed and Cadence Service and CSC Measurement, CSC Feature, Sensor Location and * SC Control Point characteristics to the BLE Stack database according to \ref cscs_init_t.char_mask. */ #ifndef __CSCS_H__ #define __CSCS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup CSCS_MACRO Defines * @{ */ -#define CSCS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of CSCS connections. */ -#define CSCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of CSC Measurment value. */ -#define CSCS_FEAT_VAL_LEN_MAX 2 /**< Maximum length of CSC Feature value. */ -#define CSCS_SENSOR_LOC_VAL_LEN_MAX 1 /**< Maximum length of Sensor Location value. */ -#define CSCS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of SC Control Point response value. */ -/**< Maximum length of SC Control Point value. */ -#define CSCS_CTRL_PT_VAL_LEN_MAX (CSCS_CTRL_PT_RSP_LEN_MIN + CSCS_SENSOR_LOC_SUP_NB) +#define CSCS_CONNECTION_MAX 10 /**< Maximum number of CSCS connections. */ +#define CSCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of CSC Measurment value. */ +#define CSCS_FEAT_VAL_LEN_MAX 2 /**< Maximum length of CSC Feature value. */ +#define CSCS_SENSOR_LOC_VAL_LEN_MAX 1 /**< Maximum length of Sensor Location value. */ +#define CSCS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of SC Control Point response value. */ +#define CSCS_CTRL_PT_VAL_LEN_MAX (CSCS_CTRL_PT_RSP_LEN_MIN + CSCS_SENSOR_LOC_SUP_NB) /**< Maximum length of SC Control Point value. */ -#define CSCS_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point operation \ - is still in progress. */ -#define CSCS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor \ - is not configured. */ +#define CSCS_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point operation is still in progress. */ +#define CSCS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor is not configured. */ /** * @defgroup CSCS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref cscs_init_t.char_mask. */ -#define CSCS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in CSCS. */ -#define CSCS_CHAR_SENSOR_LOC_SUP 0x00c0 /**< Bit mask for Sensor Location characteristic that is optional. */ -#define CSCS_CHAR_SC_CTRL_POINT 0x0700 /**< Bit mask for SC Control Point characteristic that is optional. */ -#define CSCS_CHAR_FULL 0x07ff /**< Bit mask of the full characteristic. */ +#define CSCS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in CSCS. */ +#define CSCS_CHAR_SENSOR_LOC_SUP 0x00c0 /**< Bit mask for Sensor Location characteristic that is optional. */ +#define CSCS_CHAR_SC_CTRL_POINT 0x0700 /**< Bit mask for SC Control Point characteristic that is optional. */ +#define CSCS_CHAR_FULL 0x07ff /**< Bit mask of the full characteristic. */ /** @} */ /** @@ -97,8 +93,8 @@ * @{ * @brief Cycling Speed and Cadence Measurement Flags. */ -#define CSCS_MEAS_FLAG_WHEEL_REVOLUTION_BIT (0x01 << 0) /**< Flag bit for Wheel Revolution Data Present. */ -#define CSCS_MEAS_FLAG_CRANK_REVOLUTION_BIT (0x01 << 1) /**< Flag bit for Crank Revolution Data Present. */ +#define CSCS_MEAS_FLAG_WHEEL_REVOLUTION_BIT (0x01 << 0) /**< Flag bit for Wheel Revolution Data Present. */ +#define CSCS_MEAS_FLAG_CRANK_REVOLUTION_BIT (0x01 << 1) /**< Flag bit for Crank Revolution Data Present. */ /** @} */ /** @@ -106,10 +102,10 @@ * @{ * @brief Cycling Speed and Cadence Service feature bits. */ -#define CSCS_FEAT_WHEEL_REVOLUTION_SUP_BIT (0x01 << 0) /**< Bit for Wheel Revolution Data Supported. */ -#define CSCS_FEAT_CRANK_REVOLUTION_SUP_BIT (0x01 << 1) /**< Bit for Crank Revolution Data Supported. */ -#define CSCS_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 2) /**< Bit for Multiple Sensor Locations Supported. */ -#define CSCS_FEAR_FULL_BIT (0x07) /**< Bit for all CSC features Supported. */ +#define CSCS_FEAT_WHEEL_REVOLUTION_SUP_BIT (0x01 << 0) /**< Bit for Wheel Revolution Data Supported. */ +#define CSCS_FEAT_CRANK_REVOLUTION_SUP_BIT (0x01 << 1) /**< Bit for Crank Revolution Data Supported. */ +#define CSCS_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 2) /**< Bit for Multiple Sensor Locations Supported. */ +#define CSCS_FEAR_FULL_BIT (0x07) /**< Bit for all CSC features Supported. */ /** @} */ /** @} */ @@ -118,7 +114,8 @@ * @{ */ /**@brief Cycling Speed and Cadence Service Sensor Location. */ -typedef enum { +typedef enum +{ CSCS_SENSOR_LOC_OTHER, /**< Sensor location: other. */ CSCS_SENSOR_LOC_SHOE_TOP, /**< Sensor location: top of shoe. */ CSCS_SENSOR_LOC_SHOE_IN, /**< Sensor location: inside of shoe. */ @@ -131,7 +128,8 @@ typedef enum { } cscs_sensor_loc_t; /**@brief Cycling Speed and Cadence Service Control Point Operation Code.*/ -typedef enum { +typedef enum +{ CSCS_CTRL_PT_OP_RESERVED, /**< Reserved for future use. */ CSCS_CTRL_PT_OP_SET_CUMUL_VAL, /**< Set Cumulative value Operation Code.*/ CSCS_CTRL_PT_OP_START_CALIB, /**< Start Sensor Calibration Operation Code.*/ @@ -141,7 +139,8 @@ typedef enum { } cscs_ctrl_pt_op_code_t; /**@brief Cycling Speed and Cadence Service Control Point Response value.*/ -typedef enum { +typedef enum +{ CSCS_CTRL_PT_RSP_RESERVED, /**< Reserved value. */ CSCS_CTRL_PT_RSP_SUCCESS, /**< Operation Success. */ CSCS_CTRL_PT_RSP_NOT_SUP, /**< Operation Code Not Supported. */ @@ -150,18 +149,19 @@ typedef enum { } cscs_ctrl_pt_rsp_t; /**@brief Cycling Speed and Cadence Service event type.*/ -typedef enum { - CSCS_EVT_INVALID, /**< Indicate that invalid event. */ - CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE, /**< Indicate that CSC Measurement notification has been enabled. */ - CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE, /**< Indicate that CSC Measurement notification has been disabled. */ - CSCS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that SC Control Point indication has been enabled. */ - CSCS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that SC Control Point indication has been disabled. */ - CSCS_EVT_CSC_MEAS_SEND_CPLT, /**< Indicate that CSC Measurement has been notified. */ - CSCS_EVT_CUMUL_VAL_SET, /**< Indicate that Wheel Revolution Data needs to be set. */ - CSCS_EVT_SEBSOR_CALIBRATION, /**< Indicate that Sensor calibration procedure should be initiated. */ - CSCS_EVT_SEBSOR_LOC_UPD, /**< Indicate that Sensor Location needs to be reset. */ - CSCS_EVT_SUP_SEBSOR_LOC_REQ, /**< Indicate that request supported sensor location list. */ - CSCS_EVT_CTRL_POINT_RSP_CPLT /**< Indicate that SC Control Point response has been indicated. */ +typedef enum +{ + CSCS_EVT_INVALID, /**< Indicate that invalid event. */ + CSCS_EVT_CSC_MEAS_NOTIFICATION_ENABLE, /**< Indicate that CSC Measurement notification has been enabled. */ + CSCS_EVT_CSC_MEAS_NOTIFICATION_DISABLE, /**< Indicate that CSC Measurement notification has been disabled. */ + CSCS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that SC Control Point indication has been enabled. */ + CSCS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that SC Control Point indication has been disabled. */ + CSCS_EVT_CSC_MEAS_SEND_CPLT, /**< Indicate that CSC Measurement has been notified. */ + CSCS_EVT_CUMUL_VAL_SET, /**< Indicate that Wheel Revolution Data needs to be set. */ + CSCS_EVT_SEBSOR_CALIBRATION, /**< Indicate that Sensor calibration procedure should be initiated. */ + CSCS_EVT_SEBSOR_LOC_UPD, /**< Indicate that Sensor Location needs to be reset. */ + CSCS_EVT_SUP_SEBSOR_LOC_REQ, /**< Indicate that request supported sensor location list. */ + CSCS_EVT_CTRL_POINT_RSP_CPLT /**< Indicate that SC Control Point response has been indicated. */ } cscs_evt_type_t; /** @} */ @@ -170,7 +170,8 @@ typedef enum { * @{ */ /**@brief Cycling Speed and Cadence Service event. */ -typedef struct { +typedef struct +{ cscs_evt_type_t evt_type; /**< The CSCS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -191,7 +192,8 @@ typedef void (*cscs_evt_handler_t)(cscs_evt_t *p_evt); * @{ */ /**@brief Cycling Speed and Cadence Measurement Character value structure. */ -typedef struct { +typedef struct +{ bool wheel_rev_data_present; /**< If Wheel Revolution Data is present. */ bool crank_rev_data_present; /**< If Crank Revolution Data is present. */ uint32_t cumulative_wheel_revs; /**< Cumulative Wheel Revolutions. */ @@ -200,13 +202,11 @@ typedef struct { uint16_t last_crank_event_time; /**< Last Crank Event Time. */ } cscs_meas_val_t; -/**@brief Cycling Speed and Cadence Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Cycling Speed and Cadence Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ cscs_evt_handler_t evt_handler; /**< Cycling Speed and Cadence Service event handler. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, \ - and configured with \ref CSCS_CHAR_MASK. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref CSCS_CHAR_MASK. */ cscs_sensor_loc_t sensor_location; /**< Initial sensor location. */ uint16_t feature; /**< Initial value for features. */ } cscs_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/BUILD.gn new file mode 100644 index 0000000..7194892 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("cts") { + sources = [ "cts.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.c index 9ec5883..e0366d1 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.c @@ -43,22 +43,51 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define INDEX_2 2 -#define INDEX_3 3 -#define INDEX_7 7 -#define INDEX_8 8 -#define INDEX_9 9 -#define VALUE_7 7 -#define VALUE_12 12 -#define VALUE_31 31 -#define VALUE_23 23 -#define VALUE_59 59 +#include "app_log.h" +#include "user_app.h" + /* * ENUMERATIONS **************************************************************************************** */ + /**@brief The time zone adjustment sent by the receiving host. */ +enum +{ + CTS_HOST_DATA_ZONE, /**< Accept zone receipts from the host. */ + CTS_HOST_DATA_OFFST, /**< Accept offst receipts from the host. */ + + CTS_HOST_NB /**< The maximum number of data from the host. */ +}; + + /**@brief Accept receipts from serial ports. */ +enum +{ + CTS_SERIAL_DATA_SOURCE, /**< Source of information. */ + CTS_SERIAL_DATA_ACCURACY, /**< Drift accuracy. */ + CTS_SERIAL_DAY_SINCE, /**< Days since update.*/ + CTS_SERIAL_HOURS_SINCE, /**< hours since update. */ + + CTS_SERIAL_NB /**< The maximum number of data from the serial port. */ +}; + + /**@brief Accept receipts from peers. */ +enum +{ + CTS_PEER_DATA_YEAR, /**< Receive data from the peer year. */ + CTS_PEER_DATA_MONTH, /**< Receive data from the peer month. */ + CTS_PEER_DATA_DAY, /**< Receive data from the peer day. */ + CTS_PEER_DATA_HOUR, /**< Receive data from the peer hour */ + CTS_PEER_DATA_MIN, /**< Receive data from the peer minute */ + CTS_PEER_DATA_SEC, /**< Receive data from the peer second */ + CTS_PEER_DATA_WEEK, /**< Receive data from the peer week */ + CTS_PEER_DATA_FRACTION, /**< Receive data from the peer fracyion */ + CTS_PEER_DATA_REASON, /**< Receive data from the peer Reason for adjustment */ + + CTS_PEER_NB /**< The maximum number of data from peer devices */ +}; /**@brief Current Time Service Attributes Indexes. */ -enum { +enum +{ // Current Time Service CTS_IDX_SVC, @@ -83,136 +112,69 @@ enum { ***************************************************************************************** */ /**@brief Current Time Service environment variable. */ -struct cts_env_t { - cts_init_t cts_init; /**< Current Time Service initialization variables. */ - uint16_t start_hdl; /**< Current Time Service start handle. */ - uint16_t - cur_time_ntf_cfg[CTS_CONNECTION_MAX]; /**< The configuration of Current Time Notification - which is configured by the peer devices. */ +struct cts_env_t +{ + cts_init_t cts_init; /**< Current Time Service initialization variables. */ + uint16_t start_hdl; /**< Current Time Service start handle. */ + uint16_t cur_time_ntf_cfg[CTS_CONNECTION_MAX]; /**< The configuration of Current Time Notification which is configured by the peer devices. */ + ble_gatts_create_db_t cts_gatts_db; /**< Current Time Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t cts_init(void); -static void cts_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void cts_write_att_cb(uint8_t conidx, const gatts_write_req_cb_t *p_param); -static void cts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void cts_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); -static void cts_cur_time_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); -static void cts_loc_time_info_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); -static void cts_ref_time_info_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); -static void cts_cur_time_write_handler(gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt); -static void cts_loc_time_info_write_handler(gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt); +static void cts_cur_time_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); +static void cts_loc_time_info_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); +static void cts_ref_time_info_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct cts_env_t s_cts_env; +static struct cts_env_t s_cts_record_time; +static cts_adj_info_t s_cts_ref_info; +static cts_updata_ref_time_info_t s_cts_updata; +static uint8_t s_cts_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_CURRENT_TIME); /**@brief Full CTS Database Description - Used to add attributes into the database. */ -static const attm_desc_t cts_attr_tab[CTS_IDX_NB] = { +static const ble_gatts_attm_desc_t cts_attr_tab[CTS_IDX_NB] = +{ // CTS Service Declaration - [CTS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [CTS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Current Time Characteristic Declaration - [CTS_IDX_CUR_TIME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CTS_IDX_CUR_TIME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Current Time Characteristic Declaration value - [CTS_IDX_CUR_TIME_VAL] = { - BLE_ATT_CHAR_CT_TIME, - READ_PERM_UNSEC | NOTIFY_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - CTS_CUR_TIME_VAL_LEN - }, + [CTS_IDX_CUR_TIME_VAL] = {BLE_ATT_CHAR_CT_TIME, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_NOTIFY_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + TOTAL_CTS_CUR_TIME_VAL_LEN}, // Current Time Characteristic Declaration - Client Characteristic Configuration Descriptor - [CTS_IDX_CUR_TIMR_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [CTS_IDX_CUR_TIMR_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Local Time Information Characteristic Declaration - [CTS_IDX_LOC_TIME_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CTS_IDX_LOC_TIME_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Local Time Information Characteristic Value - [CTS_IDX_LOC_TIME_INFO_VAL] = { - BLE_ATT_CHAR_LOCAL_TIME_INFO, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - CTS_LOC_TIME_INFO_VAL_LEN - }, + [CTS_IDX_LOC_TIME_INFO_VAL] = {BLE_ATT_CHAR_LOCAL_TIME_INFO, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + TOTAL_CTS_LOC_TIME_INFO_VAL_LEN}, // Reference Time Information Characteristic Declaration - [CTS_IDX_REF_TIME_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [CTS_IDX_REF_TIME_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Reference Time Information Characteristic Value - [CTS_IDX_REF_TIME_INFO_VAL] = { - BLE_ATT_CHAR_REFERENCE_TIME_INFO, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - CTS_REF_TIME_INFO_VAL_LEN - }, -}; - -/**@brief CTS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t cts_tack_cbs = { - (prf_init_func_t) cts_init, - NULL, - NULL -}; - -/**@brief CTS Task Callbacks. */ -static gatts_prf_cbs_t cts_cb_func = { - cts_read_att_cb, - cts_write_att_cb, - NULL, - cts_gatts_ntf_ind_cb, - cts_cccd_set_cb -}; - -/**@brief CTS Information. */ -static const prf_server_info_t cts_prf_info = { - .max_connection_nb = CTS_CONNECTION_MAX, - .manager_cbs = &cts_tack_cbs, - .gatts_prf_cbs = &cts_cb_func + [CTS_IDX_REF_TIME_INFO_VAL] = {BLE_ATT_CHAR_REFERENCE_TIME_INFO, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + CTS_REF_TIME_INFO_VAL_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Current Time service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t cts_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t cts_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_CURRENT_TIME); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = cts_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_cts_env.cts_init.char_mask); - gatts_db.max_nb_attr = CTS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = cts_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_cts_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -221,21 +183,24 @@ static sdk_err_t cts_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void cts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void cts_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_cts_env.start_hdl, - CTS_IDX_NB, - (uint8_t *)&s_cts_env.cts_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_cts_env.start_hdl, + CTS_IDX_NB, + (uint8_t *)&s_cts_env.cts_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { - case CTS_IDX_CUR_TIME_VAL: { + switch (tab_index) + { + case CTS_IDX_CUR_TIME_VAL: + { uint8_t encoded_buffer[CTS_CUR_TIME_VAL_LEN]; cts_cur_time_read_handler(&cfm, encoded_buffer); + APP_LOG_INFO("Read current time success."); break; } @@ -244,15 +209,19 @@ static void cts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par cfm.value = (uint8_t *)&s_cts_env.cur_time_ntf_cfg[conn_idx]; break; - case CTS_IDX_LOC_TIME_INFO_VAL: { + case CTS_IDX_LOC_TIME_INFO_VAL: + { uint8_t encoded_buffer[CTS_LOC_TIME_INFO_VAL_LEN]; cts_loc_time_info_read_handler(&cfm, encoded_buffer); + APP_LOG_INFO("Read local time success."); break; } - case CTS_IDX_REF_TIME_INFO_VAL: { + case CTS_IDX_REF_TIME_INFO_VAL: + { uint8_t encoded_buffer[CTS_REF_TIME_INFO_VAL_LEN]; cts_ref_time_info_read_handler(&cfm, encoded_buffer); + APP_LOG_INFO("Read refence time success."); break; } @@ -273,14 +242,13 @@ static void cts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void cts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void cts_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t tab_index = 0; - uint16_t cccd_value = 0; - cts_evt_t event; - gatts_write_cfm_t cfm; - uint8_t ret; + uint16_t handle = p_param->handle; + uint16_t tab_index = 0; + uint16_t cccd_value = 0; + cts_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_cts_env.start_hdl, @@ -291,17 +259,14 @@ static void cts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p event.evt_type = CTS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case CTS_IDX_CUR_TIME_VAL: event.evt_type = CTS_EVT_CUR_TIME_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - cts_cur_time_write_handler(&cfm, &event); - ret = memcpy_s(&event.cur_time, sizeof(cts_cur_time_t), - &s_cts_env.cts_init.cur_time, sizeof(cts_cur_time_t)); - if (ret < 0) { - return; - } + event.length = current_time_universal_decode(&cfm, &event); + memcpy(&event.cur_time, &s_cts_env.cts_init.cur_time, sizeof(cts_cur_time_t)); break; case CTS_IDX_CUR_TIMR_NTF_CFG: @@ -316,12 +281,8 @@ static void cts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p event.evt_type = CTS_EVT_LOC_TIME_INFO_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - cts_loc_time_info_write_handler(&cfm, &event); - ret = memcpy_s(&event.loc_time_info, sizeof(cts_loc_time_info_t), - &s_cts_env.cts_init.loc_time_info, sizeof(cts_loc_time_info_t)); - if (ret < 0) { - return; - } + event.length = local_time_universal_decode(&cfm, &event); + memcpy(&event.loc_time_info, &s_cts_env.cts_init.loc_time_info, sizeof(cts_loc_time_info_t)); break; default: @@ -331,8 +292,8 @@ static void cts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && - CTS_EVT_INVALID != event.evt_type && s_cts_env.cts_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && CTS_EVT_INVALID != event.evt_type && s_cts_env.cts_init.evt_handler) + { s_cts_env.cts_init.evt_handler(&event); } } @@ -346,12 +307,13 @@ static void cts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void cts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void cts_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; cts_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -363,7 +325,8 @@ static void cts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = CTS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case CTS_IDX_CUR_TIMR_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ CTS_EVT_CUR_TIME_NOTIFICATION_ENABLED : \ @@ -375,7 +338,8 @@ static void cts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (CTS_EVT_INVALID != event.evt_type && s_cts_env.cts_init.evt_handler) { + if (CTS_EVT_INVALID != event.evt_type && s_cts_env.cts_init.evt_handler) + { s_cts_env.cts_init.evt_handler(&event); } } @@ -388,10 +352,11 @@ static void cts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_param: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void cts_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void cts_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { - s_cts_env.cts_init.cur_time.adjust_reason = CTS_AR_NO_CHANGE; + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { + s_cts_env.cts_init.cur_time.adjust_reason = s_cts_env.cts_init.cur_time.adjust_reason; } } @@ -407,26 +372,9 @@ static void cts_cur_time_encode(const cts_cur_time_t *p_cur_time, uint8_t *p_enc { prf_pack_date_time(p_encoded_data, &p_cur_time->day_date_time.date_time); - p_encoded_data[INDEX_7] = p_cur_time->day_date_time.day_of_week; - p_encoded_data[INDEX_8] = p_cur_time->day_date_time.fractions_256; - p_encoded_data[INDEX_9] = p_cur_time->adjust_reason; -} - -/** - ***************************************************************************************** - * @brief Decode for a Current Time. - * - * @param[in] p_data: Pointer to data to be decoded. - * @param[out] p_cur_time: Pointer to Current Time. - ***************************************************************************************** - */ -static void cts_cur_time_decode(const uint8_t *p_data, cts_cur_time_t *p_cur_time) -{ - prf_unpack_date_time(p_data, &p_cur_time->day_date_time.date_time); - - p_cur_time->day_date_time.day_of_week = p_data[INDEX_7]; - p_cur_time->day_date_time.fractions_256 = p_data[INDEX_8]; - p_cur_time->adjust_reason = p_data[INDEX_9]; + p_encoded_data[7] = p_cur_time->day_date_time.day_of_week; + p_encoded_data[8] = p_cur_time->day_date_time.fractions_256; + p_encoded_data[9] = p_cur_time->adjust_reason; } /** @@ -437,10 +385,8 @@ static void cts_cur_time_decode(const uint8_t *p_data, cts_cur_time_t *p_cur_tim * @param[out] p_encode_buffer: Pointer to encoded data will be written. ***************************************************************************************** */ -static void cts_cur_time_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) +static void cts_cur_time_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) { - s_cts_env.cts_init.cur_time.adjust_reason = CTS_AR_NO_CHANGE; - cts_cur_time_encode(&s_cts_env.cts_init.cur_time, p_encode_buffer); p_cfm->length = CTS_CUR_TIME_VAL_LEN; @@ -455,7 +401,7 @@ static void cts_cur_time_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode * @param[out] p_encode_buffer: Pointer to encoded data will be written. ***************************************************************************************** */ -static void cts_loc_time_info_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) +static void cts_loc_time_info_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) { p_encode_buffer[0] = s_cts_env.cts_init.loc_time_info.time_zone; p_encode_buffer[1] = s_cts_env.cts_init.loc_time_info.dst_offset; @@ -472,110 +418,42 @@ static void cts_loc_time_info_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_e * @param[out] p_encode_buffer: Pointer to encoded data will be written. ***************************************************************************************** */ -static void cts_ref_time_info_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) +static void cts_ref_time_info_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) { p_encode_buffer[0] = s_cts_env.cts_init.ref_time_info.source; p_encode_buffer[1] = s_cts_env.cts_init.ref_time_info.accuracy; - p_encode_buffer[INDEX_2] = s_cts_env.cts_init.ref_time_info.days_since_update; - p_encode_buffer[INDEX_3] = s_cts_env.cts_init.ref_time_info.hours_since_update; + p_encode_buffer[2] = s_cts_env.cts_init.ref_time_info.days_since_update; + p_encode_buffer[3] = s_cts_env.cts_init.ref_time_info.hours_since_update; p_cfm->value = p_encode_buffer; p_cfm->length = CTS_REF_TIME_INFO_VAL_LEN; } -/** - ***************************************************************************************** - * @brief Handle Current Time write event. - * - * @param[out] p_cfm: Pointer to GATT write attribute result description. - * @param[in] p_evt: Pointer to CTS event. - ***************************************************************************************** - */ -static void cts_cur_time_write_handler(gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt) +static void cts_ble_evt_handler(const ble_evt_t *p_evt) { - cts_cur_time_t cur_time_set = {0}; - - cts_cur_time_decode(p_evt->p_data, &cur_time_set); - - if ((CTS_TIME_YEAR_VALID_VAL_MIN <= cur_time_set.day_date_time.date_time.year) && \ - (CTS_TIME_YEAR_VALID_VAL_MIN >= cur_time_set.day_date_time.date_time.year)) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.year = cur_time_set.day_date_time.date_time.year; - } else { - if (cur_time_set.day_date_time.date_time.year == 0) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.year = cur_time_set.day_date_time.date_time.year; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } + if (NULL == p_evt) + { + return; } - if (cur_time_set.day_date_time.date_time.month <= VALUE_12) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.month = cur_time_set.day_date_time.date_time.month; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + cts_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + cts_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + cts_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + cts_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; } - - if (cur_time_set.day_date_time.date_time.day <= VALUE_31) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.day = cur_time_set.day_date_time.date_time.day; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (cur_time_set.day_date_time.date_time.hour <= VALUE_23) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.hour = cur_time_set.day_date_time.date_time.hour; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (cur_time_set.day_date_time.date_time.min <= VALUE_23) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.min = cur_time_set.day_date_time.date_time.min; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (cur_time_set.day_date_time.date_time.sec <= VALUE_23) { - s_cts_env.cts_init.cur_time.day_date_time.date_time.sec = cur_time_set.day_date_time.date_time.sec; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (cur_time_set.day_date_time.day_of_week <= VALUE_7) { - s_cts_env.cts_init.cur_time.day_date_time.day_of_week = cur_time_set.day_date_time.day_of_week; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (cur_time_set.adjust_reason <= 0x0f) { - s_cts_env.cts_init.cur_time.adjust_reason = cur_time_set.adjust_reason; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } -} - -/** - ***************************************************************************************** - * @brief Handle Local Time Information write event. - * - * @param[out] p_cfm: Pointer to GATT write attribute result description. - * @param[in] p_evt: Pointer to CTS event. - ***************************************************************************************** - */ -static void cts_loc_time_info_write_handler(gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt) -{ - cts_dst_offset_t dst_offset = (cts_dst_offset_t)p_evt->p_data[1]; - - if (CTS_TIME_ZONE_OFFSET_MIN <= (int8_t)p_evt->p_data[0] && CTS_TIME_ZONE_OFFSET_MAX >= (int8_t)p_evt->p_data[0]) { - s_cts_env.cts_init.loc_time_info.time_zone = p_evt->p_data[0]; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - if (CTS_DST_OFFSET_DOUB_DAYLIGHT_TIME >= dst_offset) { - s_cts_env.cts_init.loc_time_info.dst_offset = dst_offset; - } else { - p_cfm->status = CTS_ERROR_FIELDS_IGNORED; - } - - s_cts_env.cts_init.loc_time_info.dst_offset = (cts_dst_offset_t)p_evt->p_data[1]; } /* @@ -584,13 +462,14 @@ static void cts_loc_time_info_write_handler(gatts_write_cfm_t *p_cfm, cts_evt_t */ sdk_err_t cts_cur_time_send(uint8_t conn_idx, cts_cur_time_t *p_cur_time) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - uint8_t encoded_cur_time[CTS_CUR_TIME_VAL_LEN]; - gatts_noti_ind_t ct_ntf; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + uint8_t encoded_cur_time[CTS_CUR_TIME_VAL_LEN]; + ble_gatts_noti_ind_t ct_ntf; cts_cur_time_encode(p_cur_time, encoded_cur_time); - if (PRF_CLI_START_NTF == s_cts_env.cur_time_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_cts_env.cur_time_ntf_cfg[conn_idx]) + { ct_ntf.type = BLE_GATT_NOTIFICATION; ct_ntf.handle = prf_find_handle_by_idx(CTS_IDX_CUR_TIME_VAL, s_cts_env.start_hdl, @@ -603,50 +482,63 @@ sdk_err_t cts_cur_time_send(uint8_t conn_idx, cts_cur_time_t *p_cur_time) return error_code; } -void cts_exact_time_get(cts_exact_time_256_t *p_cts_exact_time) +void cts_exact_time_get(cts_init_t *p_cts_exact_time) { - uint8_t ret; - ret = memcpy_s(p_cts_exact_time, sizeof(cts_exact_time_256_t), - &s_cts_env.cts_init.cur_time.day_date_time, sizeof(cts_exact_time_256_t)); - if (ret < 0) { - return; - } + memcpy(p_cts_exact_time, &s_cts_env.cts_init, sizeof(cts_init_t)); } -void cts_exact_time_update(cts_exact_time_256_t *p_cts_exact_time) +void cts_exact_time_update(cts_init_t *p_cts_exact_time) { - uint8_t ret; - ret = memcpy_s(&s_cts_env.cts_init.cur_time.day_date_time, sizeof(cts_exact_time_256_t), - p_cts_exact_time, sizeof(cts_exact_time_256_t)); - if (ret < 0) { - return; + p_cts_exact_time->cur_time.adjust_reason = s_cts_env.cts_init.cur_time.adjust_reason ; + memcpy(&s_cts_env.cts_init, p_cts_exact_time, sizeof(cts_init_t)); + memcpy(&s_cts_env.cts_init.ref_time_info,&s_cts_ref_info.ref_time_info, sizeof(cts_ref_time_info_t)); + + s_cts_updata.current_time_min = s_cts_env.cts_init.cur_time.day_date_time.date_time.min; + s_cts_updata.current_time_sec = s_cts_env.cts_init.cur_time.day_date_time.date_time.sec; + + if( s_cts_updata.current_time_min > s_cts_updata.expected_time_1min_adapt || + (s_cts_updata.current_time_min == s_cts_updata.expected_time_1min_adapt && s_cts_updata.current_time_sec > s_cts_updata.before_updata_sec) + ) + { + s_cts_updata.updata_time_flag =1; + s_cts_ref_info.ref_time_info.source = s_cts_updata.stage_update_source; + if(s_cts_updata.stage_update_source == 1) + { + s_cts_env.cts_init.cur_time.adjust_reason =2; + } + else if(s_cts_updata.stage_update_source == 4) + { + s_cts_env.cts_init.cur_time.adjust_reason =1; + } } + + else + { + s_cts_updata.updata_time_flag =0; + } + + cts_cur_time_send(0, &s_cts_env.cts_init.cur_time); } void cts_cur_time_adjust(cts_adj_info_t *p_adj_info) { - uint8_t ret; - if (CTS_AR_MAUAL_TIME_UPDATE & p_adj_info->adjust_reason) { - ret = memcpy_s(&s_cts_env.cts_init.cur_time.day_date_time, - &p_adj_info->day_date_time, sizeof(cts_exact_time_256_t)); - if (ret < 0) { - return; - } + if (CTS_AR_MAUAL_TIME_UPDATE & p_adj_info->adjust_reason) + { + memcpy(&s_cts_env.cts_init.cur_time.day_date_time, &p_adj_info->day_date_time, sizeof(cts_exact_time_256_t)); } - if (CTS_AR_EXT_REF_TIME_UPDATE & p_adj_info->adjust_reason) { - ret = memcpy_s(&s_cts_env.cts_init.ref_time_info, - &p_adj_info->ref_time_info, sizeof(cts_ref_time_info_t)); - if (ret < 0) { - return; - } + if (CTS_AR_EXT_REF_TIME_UPDATE & p_adj_info->adjust_reason) + { + memcpy(&s_cts_env.cts_init.ref_time_info, &p_adj_info->ref_time_info, sizeof(cts_ref_time_info_t)); } - if (CTS_AR_TIME_ZONE_CHANGE & p_adj_info->adjust_reason) { + if (CTS_AR_TIME_ZONE_CHANGE & p_adj_info->adjust_reason) + { s_cts_env.cts_init.loc_time_info.time_zone = p_adj_info->loc_time_info.time_zone; } - if (CTS_AR_DST_CHANGE & p_adj_info->adjust_reason) { + if (CTS_AR_DST_CHANGE & p_adj_info->adjust_reason) + { s_cts_env.cts_init.loc_time_info.dst_offset = p_adj_info->loc_time_info.dst_offset; } @@ -657,18 +549,292 @@ void cts_cur_time_adjust(cts_adj_info_t *p_adj_info) sdk_err_t cts_service_init(cts_init_t *p_cts_init) { - uint8_t ret; - if (p_cts_init == NULL) { + if (NULL == p_cts_init) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_cts_env, sizeof(s_cts_env), 0, sizeof(s_cts_env)); - if (ret < 0) { - return; - } - ret = memcpy_s(&s_cts_env.cts_init, sizeof(cts_init_t), p_cts_init, sizeof(cts_init_t)); - if (ret < 0) { - return; - } - return ble_server_prf_add(&cts_prf_info); + memset(&s_cts_env, 0, sizeof(s_cts_env)); + memcpy(&s_cts_env.cts_init, p_cts_init, sizeof(cts_init_t)); + + memset(&s_cts_env.cts_gatts_db, 0, sizeof(ble_gatts_create_db_t)); + + s_cts_env.start_hdl = PRF_INVALID_HANDLE; + s_cts_env.cts_gatts_db.shdl = &s_cts_env.start_hdl; + s_cts_env.cts_gatts_db.uuid = s_cts_svc_uuid; + s_cts_env.cts_gatts_db.attr_tab_cfg = (uint8_t *)&(s_cts_env.cts_init.char_mask); + s_cts_env.cts_gatts_db.max_nb_attr = CTS_IDX_NB; + s_cts_env.cts_gatts_db.srvc_perm = 0; + s_cts_env.cts_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_cts_env.cts_gatts_db.attr_tab.attr_tab_16 = cts_attr_tab; + + return ble_gatts_prf_add(&s_cts_env.cts_gatts_db, cts_ble_evt_handler); +} + +void cts_c_data_parse(uint8_t *p_data, uint16_t length) +{ + if (0 == memcmp(p_data, "RW:", 3)) + { + reference_time_encode(&p_data[3], length-3); + return; + } + + else if(0 == memcmp(p_data, "CW:", 3)) + { + current_time_encode(&p_data[3], length-3); + return; + } + + else if (0 == memcmp(p_data, "LW:", 3)) + { + local_time_encode(&p_data[3], length-3); + return; + } +} + +void reference_time_encode(uint8_t *p_data, uint16_t length) +{ + uint16_t data_length =0; + uint8_t time_param_check_idx = 0; + uint16_t time_param_check[CTS_SERIAL_NB] = {0}; + + while (data_length < length) + { + if (p_data[data_length] <= '9' && p_data[data_length] >= '0') + { + time_param_check[time_param_check_idx] = time_param_check[time_param_check_idx] * 10 + (p_data[data_length] - '0'); + } + else if ('-' == p_data[data_length]) + { + time_param_check_idx++; + } + + data_length++; + } + + if( 7>time_param_check[CTS_SERIAL_DATA_SOURCE] && + 255>time_param_check[CTS_SERIAL_DAY_SINCE] && + 24>time_param_check[CTS_SERIAL_HOURS_SINCE] && + 256>time_param_check[CTS_SERIAL_DATA_ACCURACY] + ) + { + s_cts_updata.stage_update_source = (cts_ref_time_source_t)time_param_check[CTS_SERIAL_DATA_SOURCE]; + s_cts_ref_info.ref_time_info.days_since_update = time_param_check[CTS_SERIAL_DAY_SINCE]; + s_cts_ref_info.ref_time_info.hours_since_update = time_param_check[CTS_SERIAL_HOURS_SINCE]; + s_cts_ref_info.ref_time_info.accuracy = time_param_check[CTS_SERIAL_DATA_ACCURACY]; + APP_LOG_INFO("SOURCE=%d ACCURACY=%d DAY_SINCE=%d HOURS_SINCE=%d",s_cts_ref_info.ref_time_info.source, + s_cts_ref_info.ref_time_info.accuracy , + s_cts_ref_info.ref_time_info.days_since_update, + s_cts_ref_info.ref_time_info.hours_since_update); + } + else + { + APP_LOG_INFO("Invalid set parameter."); + } + + if(s_cts_updata.stage_update_source != s_cts_env.cts_init.ref_time_info.source) + { + memcpy(&s_cts_record_time.cts_init.cur_time.day_date_time,&s_cts_env.cts_init.cur_time.day_date_time, sizeof(cts_cur_time_t)); + s_cts_updata.before_updata_sec = s_cts_record_time.cts_init.cur_time.day_date_time.date_time.sec; + s_cts_updata.expected_time_1min_adapt = s_cts_record_time.cts_init.cur_time.day_date_time.date_time.min + 1; + + if(s_cts_updata.expected_time_1min_adapt > 59) + { + s_cts_updata.expected_time_1min_adapt = 0 ; + } + } +} + +void local_time_encode(uint8_t *p_data, uint8_t length) +{ + ble_gatts_write_cfm_t *p_cfm; + cts_evt_t p_evt; + + p_evt.length = length; + p_evt.p_data = p_data; + p_evt.length = local_time_universal_decode(p_cfm,&p_evt); + + if(p_evt.length) + { + APP_LOG_DEBUG("UART Change Local Time value\n"); + p_evt.evt_type = CTS_EVT_LOC_TIME_INFO_SET_BY_PEER; + memcpy(&p_evt.loc_time_info,&s_cts_env.cts_init.loc_time_info, sizeof(cts_loc_time_info_t)); + s_cts_env.cts_init.evt_handler(&p_evt); + } +} + +void current_time_encode(uint8_t *p_data, uint16_t length) +{ + ble_gatts_write_cfm_t *p_cfm; + cts_evt_t p_evt; + + p_evt.length = length; + p_evt.p_data = p_data; + + if(s_cts_updata.updata_time_flag) + { + p_evt.length = current_time_universal_decode(p_cfm,&p_evt); + if(p_evt.length) + { + p_evt.evt_type = CTS_EVT_CUR_TIME_SET_BY_PEER; + p_evt.length = length; + memcpy(&p_evt.cur_time, &s_cts_env.cts_init.cur_time, sizeof(cts_cur_time_t)); + s_cts_env.cts_init.evt_handler(&p_evt); + } + + s_cts_updata.expected_time_1min_adapt = 0; + s_cts_updata.before_updata_sec = 0; + s_cts_record_time.cts_init.cur_time.day_date_time.date_time.min =0; + s_cts_record_time.cts_init.cur_time.day_date_time.date_time.sec =0; + } + + else + { + APP_LOG_INFO("It is not updated for more than 1 minute\n."); + APP_LOG_INFO("Updatable time minutes: %d seconds:= %d.",s_cts_updata.expected_time_1min_adapt,s_cts_updata.before_updata_sec); + } +} + +uint8_t current_time_universal_decode(ble_gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt) +{ + uint16_t data_length =0; + uint8_t time_param_check_idx = 0; + uint16_t time_param_check[CTS_PEER_NB] = {0}; + + while (data_length < p_evt->length) + { + if (p_evt->p_data[data_length] <= '9' && p_evt->p_data[data_length] >= '0') + { + time_param_check[time_param_check_idx] = time_param_check[time_param_check_idx] * 10 + (p_evt->p_data[data_length] - '0'); + } + else if ('-' == p_evt->p_data[data_length]) + { + time_param_check_idx++; + } + + data_length++; + } + + if( CTS_TIME_YEAR_VALID_VAL_MIN=time_param_check[CTS_PEER_DATA_YEAR] && + 9>time_param_check[CTS_PEER_DATA_REASON] && + 32>time_param_check[CTS_PEER_DATA_DAY] && + 25>time_param_check[CTS_PEER_DATA_HOUR] && + 60>time_param_check[CTS_PEER_DATA_MIN] && + 60>time_param_check[CTS_PEER_DATA_SEC] && + 8>time_param_check[CTS_PEER_DATA_WEEK] && + 256>time_param_check[CTS_PEER_DATA_FRACTION] && + 13>time_param_check[CTS_PEER_DATA_MONTH] + ) + { + s_cts_env.cts_init.cur_time.adjust_reason = time_param_check[CTS_PEER_DATA_REASON]; + s_cts_env.cts_init.cur_time.day_date_time.day_of_week = time_param_check[CTS_PEER_DATA_WEEK]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.year = time_param_check[CTS_PEER_DATA_YEAR]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.month = time_param_check[CTS_PEER_DATA_MONTH]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.day = time_param_check[CTS_PEER_DATA_DAY]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.hour = time_param_check[CTS_PEER_DATA_HOUR]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.min = time_param_check[CTS_PEER_DATA_MIN]; + s_cts_env.cts_init.cur_time.day_date_time.date_time.sec = time_param_check[CTS_PEER_DATA_SEC]; + s_cts_env.cts_init.cur_time.day_date_time.fractions_256 = time_param_check[CTS_PEER_DATA_FRACTION]; + } + else + { + APP_LOG_INFO("Invalid set parameter."); + p_cfm->status = CTS_ERROR_FIELDS_IGNORED; + p_evt->length = 0; + } + return p_evt->length; +} + +uint8_t local_time_universal_decode(ble_gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt) +{ + uint16_t data_length =0; + uint8_t time_param_check_idx = 0; + int16_t time_param_check[CTS_HOST_NB] = {0}; + uint8_t flag=0; //Determine if the start bit is - + uint8_t zone_set_same=1; //Determines whether the time zone entered is the same + + while (data_length < p_evt->length) + { + if (p_evt->p_data[data_length] <= '9' && p_evt->p_data[data_length] >= '0') + { + time_param_check[time_param_check_idx] = time_param_check[time_param_check_idx] * 10 + (p_evt->p_data[data_length] - '0'); + } + else if ('-' == p_evt->p_data[data_length] ) + { + if (!data_length) + { + flag=1; + } + else + { + time_param_check_idx++; + if(flag) + time_param_check[CTS_HOST_DATA_ZONE] = -time_param_check[CTS_HOST_DATA_ZONE]; + } + } + + data_length++; + } + + if(s_cts_env.cts_init.loc_time_info.time_zone != time_param_check[CTS_HOST_DATA_ZONE]) + { + s_cts_env.cts_init.cur_time.adjust_reason =4; + } + + if(s_cts_env.cts_init.loc_time_info.time_zone == (int16_t)time_param_check[CTS_HOST_DATA_ZONE] && + s_cts_env.cts_init.loc_time_info.dst_offset == (cts_dst_offset_t)time_param_check[CTS_HOST_DATA_OFFST] + ) + { + zone_set_same = 0; + APP_LOG_INFO("Enter the same time zone."); + } + + if(time_param_check[CTS_HOST_DATA_ZONE]== -128 ) + { + s_cts_env.cts_init.loc_time_info.time_zone = time_param_check[CTS_HOST_DATA_ZONE]; + } + + else if( CTS_TIME_ZONE_OFFSET_MIN <= (int16_t)time_param_check[CTS_HOST_DATA_ZONE] && + CTS_TIME_ZONE_OFFSET_MAX >= (int16_t)time_param_check[CTS_HOST_DATA_ZONE] && + zone_set_same + ) + { + s_cts_env.cts_init.loc_time_info.time_zone = time_param_check[CTS_HOST_DATA_ZONE]; + } + + else + { + APP_LOG_INFO("Invalid set parameter."); + p_cfm->status = CTS_ERROR_FIELDS_IGNORED; + p_evt->length = 0 ; + } + + if(s_cts_env.cts_init.loc_time_info.dst_offset != (cts_dst_offset_t)time_param_check[CTS_HOST_DATA_OFFST]) + { + s_cts_env.cts_init.cur_time.adjust_reason =8; + } + + if( time_param_check[CTS_HOST_DATA_OFFST] == 255 ) + { + s_cts_env.cts_init.loc_time_info.dst_offset = (cts_dst_offset_t)time_param_check[CTS_HOST_DATA_OFFST]; + } + + else if( CTS_DST_OFFSET_DOUB_DAYLIGHT_TIME >= (cts_dst_offset_t)time_param_check[CTS_HOST_DATA_OFFST] && + time_param_check[CTS_HOST_DATA_OFFST]%2 ==0 && + time_param_check[CTS_HOST_DATA_OFFST] != 6 && + zone_set_same + ) + { + s_cts_env.cts_init.loc_time_info.dst_offset = (cts_dst_offset_t)time_param_check[CTS_HOST_DATA_OFFST]; + } + + else + { + APP_LOG_INFO("Invalid set parameter\r\n."); + p_cfm->status = CTS_ERROR_FIELDS_IGNORED; + p_evt->length = 0 ; + } + + return p_evt->length; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.h index dccc5cb..ecb2c3a 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts/cts.h @@ -57,28 +57,29 @@ #ifndef __CTS_H__ #define __CTS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup CTS_MACRO Defines * @{ */ -#define CTS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of CTS connections. */ -#define CTS_CUR_TIME_VAL_LEN 10 /**< Length of current time value. */ -#define CTS_LOC_TIME_INFO_VAL_LEN 2 /**< Length of local time information value. */ -#define CTS_REF_TIME_INFO_VAL_LEN 4 /**< Length of reference time information value. */ -#define CTS_TIME_YEAR_VALID_VAL_MIN 1582 /**< Minimum value of valid year. */ -#define CTS_TIME_YEAR_VALID_VAL_MAX 9999 /**< Maximum value of valid year. */ -#define CTS_TIME_ZONE_OFFSET_MIN (-48) /**< Minimum Value of Offset from UTC. */ -#define CTS_TIME_ZONE_OFFSET_MAX 56 /**< Maximum Value of Offset from UTC. */ -#define CTS_TIME_ACCURACY_OUT_RANGE 254 /**< Accuracy out of range. */ -#define CTS_TIME_ACCURACT_UNKNOWN 255 /**< Accuracy Unknown. */ -#define CTS_ERROR_FIELDS_IGNORED 0x80 /**< The server ignored one or more fields. */ +#define CTS_CONNECTION_MAX 10 /**< Maximum number of CTS connections. */ +#define CTS_CUR_TIME_VAL_LEN 10 /**< Length of current time value. */ +#define TOTAL_CTS_CUR_TIME_VAL_LEN 27 /**< TOTAL length of current time value. */ +#define CTS_LOC_TIME_INFO_VAL_LEN 2 /**< Length of local time information value. */ +#define TOTAL_CTS_LOC_TIME_INFO_VAL_LEN 6 /**< TOTAL length local time information value. */ +#define CTS_REF_TIME_INFO_VAL_LEN 4 /**< Length of reference time information value. */ +#define CTS_TIME_YEAR_VALID_VAL_MIN 1582 /**< Minimum value of valid year. */ +#define CTS_TIME_YEAR_VALID_VAL_MAX 9999 /**< Maximum value of valid year. */ +#define CTS_TIME_ZONE_OFFSET_MIN -48 /**< Minimum Value of Offset from UTC. */ +#define CTS_TIME_ZONE_OFFSET_MAX 56 /**< Maximum Value of Offset from UTC. */ +#define CTS_TIME_ACCURACY_OUT_RANGE 254 /**< Accuracy out of range. */ +#define CTS_TIME_ACCURACT_UNKNOWN 255 /**< Accuracy Unknown. */ +#define CTS_ERROR_FIELDS_IGNORED 0x80 /**< The server ignored one or more fields. */ /** * @defgroup CTS_CHAR_MASK Characteristics Mask @@ -86,10 +87,8 @@ * @brief Bit masks for the initialization of \ref cts_init_t.char_mask. */ #define CTS_CHAR_MANDATORY 0x0f /**< Bit mask for mandatory characteristic in CTS. */ -#define CTS_CHAR_LOC_TIME_INFO_SUP 0x30 /**< Bit mask for Local Time Information characteristic \ - that is optional. */ -#define CTS_CHAR_REF_TIME_INFO_SUP 0xc0 /**< Bit mask for Reference Time Information characteristic \ - that is optional. */ +#define CTS_CHAR_LOC_TIME_INFO_SUP 0x30 /**< Bit mask for Local Time Information characteristic that is optional. */ +#define CTS_CHAR_REF_TIME_INFO_SUP 0xc0 /**< Bit mask for Reference Time Information characteristic that is optional. */ #define CTS_CHAR_FULL 0xff /**< Bit mask of the full characteristic. */ /** @} */ @@ -103,16 +102,17 @@ #define CTS_AR_EXT_REF_TIME_UPDATE (0x01 << 1) /**< External reference time update. */ #define CTS_AR_TIME_ZONE_CHANGE (0x01 << 2) /**< Change of time zone. */ #define CTS_AR_DST_CHANGE (0x01 << 3) /**< Change of DST (daylight savings time). */ -/** @} */ -/** @} */ +/** @} */ +/** @} */ /** * @defgroup CTS_ENUM Enumerations * @{ */ /**@brief Current Time Day of week. */ -typedef enum { +typedef enum +{ CTS_WEEK_UNKNOWN_DAY, /**< Day of week is not known. */ CTS_WEEK_MONDAY, /**< Monday. */ CTS_WEEK_TUSEDAY, /**< Tuesday. */ @@ -124,15 +124,18 @@ typedef enum { } cts_week_day_t; /**@brief Local time information:Daylight Saving Time Offset. */ -typedef enum { +typedef enum +{ CTS_DST_OFFSET_STANDAR_TIME = 0x00, /**< Standard Time. */ CTS_DST_OFFSET_HALF_HOUR = 0x02, /**< Half An Hour Daylight Time (+0.5h). */ CTS_DST_OFFSET_DAYLIGHT_TIME = 0x04, /**< Daylight Time (+1h). */ CTS_DST_OFFSET_DOUB_DAYLIGHT_TIME = 0x08, /**< Double Daylight Time (+2h). */ + CTS_DST_OFFSET_DOUB_UNKNOWED_TIME = 0xff, /**< Unknown time. */ } cts_dst_offset_t; /**@brief Reference time information:Time Source. */ -typedef enum { +typedef enum +{ CTS_REF_TIME_SRC_UNKNOWN, /**< Unknown. */ CTS_REF_TIME_SRC_NET_TIME_PROTOCOL, /**< Network Time Protocol. */ CTS_REF_TIME_SRC_GPS, /**< GPS. */ @@ -143,7 +146,8 @@ typedef enum { } cts_ref_time_source_t; /**@brief Current Time Service event type. */ -typedef enum { +typedef enum +{ CTS_EVT_INVALID = 0x00, /**< Invalid event. */ CTS_EVT_CUR_TIME_NOTIFICATION_ENABLED, /**< Current Time Notification is enabled. */ CTS_EVT_CUR_TIME_NOTIFICATION_DISABLED, /**< Current Time Notification is disabled. */ @@ -157,34 +161,50 @@ typedef enum { * @{ */ /**@brief CTS Exact Time 256. */ -typedef struct { +typedef struct +{ prf_date_time_t date_time; /**< Date Time. */ uint8_t day_of_week; /**< Day of Week. */ uint8_t fractions_256; /**< 1/256th of a second. */ } cts_exact_time_256_t; /**@brief CTS Current Time value. */ -typedef struct { +typedef struct +{ cts_exact_time_256_t day_date_time; /**< Exact Time 256. */ uint8_t adjust_reason; /**< Adjust Reason. */ } cts_cur_time_t; /**@brief CTS Local Time Information. */ -typedef struct { - int8_t time_zone; /**< Time Zone, Offset from UTC in number of 15-minute increments. */ +typedef struct +{ + int16_t time_zone; /**< Time Zone, Offset from UTC in number of 15-minute increments. */ cts_dst_offset_t dst_offset; /**< Daylight Saving Time Offset. */ } cts_loc_time_info_t; /**@brief CTS Reference Time Information. */ -typedef struct { +typedef struct +{ cts_ref_time_source_t source; /**< Time Source. */ uint8_t accuracy; /**< Accuracy of time information. */ uint8_t days_since_update; /**< Days Since Update. */ uint8_t hours_since_update; /**< Hours Since Update. */ } cts_ref_time_info_t; +/**@brief CTS Reference Time Updata Information. */ +typedef struct +{ + uint8_t before_updata_sec ; /**< The second before the update. */ + uint8_t current_time_min; /**< Minutes of the current time. */ + uint8_t current_time_sec; /**< The second of the current time. */ + uint8_t expected_time_1min_adapt; /**< Minutes of the expected update time. */ + cts_ref_time_source_t stage_update_source; /**< Minutes of the expected update time. */ + uint8_t updata_time_flag; /**< 1 minute time flag bit. */ +} cts_updata_ref_time_info_t; + /**@brief CTS Adjust information. */ -typedef struct { +typedef struct +{ uint8_t adjust_reason; /**< Adjust Reason. */ cts_exact_time_256_t day_date_time; /**< Exact Time 256. */ cts_loc_time_info_t loc_time_info; /**< Local Time information. */ @@ -192,7 +212,8 @@ typedef struct { } cts_adj_info_t; /**@brief Current Time Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ cts_evt_type_t evt_type; /**< The CTS event type. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -214,12 +235,11 @@ typedef void (*cts_evt_handler_t)(cts_evt_t *p_evt); * @defgroup CTS_STRUCT Structures * @{ */ -/**@brief Current Time Service init structure. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Current Time Service init structure. This contains all option and data needed for initialization of the service. */ +typedef struct +{ cts_evt_handler_t evt_handler; /**< Current Time Service event handler. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref CTS_CHAR_MASK. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref CTS_CHAR_MASK. */ cts_cur_time_t cur_time; /**< Current Time. */ cts_loc_time_info_t loc_time_info; /**< Local Time information. */ cts_ref_time_info_t ref_time_info; /**< Reference Time information. */ @@ -245,19 +265,19 @@ sdk_err_t cts_service_init(cts_init_t *p_cts_init); ***************************************************************************************** * @brief Get exact time for user. * - * @param[out] p_cts_exact_time: Pointer to exact time. + * @param[out] p_exact_time: Pointer to exact time. ***************************************************************************************** */ -void cts_exact_time_get(cts_exact_time_256_t *p_cts_exact_time); +void cts_exact_time_get(cts_init_t *p_exact_time); /** ***************************************************************************************** * @brief Update exact time. * - * @param[in] p_exact_time: Pointer to exact time. + * @param[in] p_cts_exact_time: Pointer to exact time. ***************************************************************************************** */ -void cts_exact_time_update(cts_exact_time_256_t *p_cts_exact_time); +void cts_exact_time_update(cts_init_t *p_cts_exact_time) ; /** ***************************************************************************************** @@ -281,6 +301,70 @@ void cts_cur_time_adjust(cts_adj_info_t *p_adj_info); sdk_err_t cts_cur_time_send(uint8_t conn_idx, cts_cur_time_t *p_cur_time); /** @} */ +/** + ***************************************************************************************** + * @brief Data accepts data and processing functions. + * + * @param[in] p_data: Serial port data. + * @param[in] length: Data length. + ***************************************************************************************** + */ +void cts_c_data_parse(uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Serial port data is converted into reference time. + * + * @param[in] p_data: Serial port data. + * @param[in] length: Data length. + ***************************************************************************************** + */ +void reference_time_encode(uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Serial port data is converted into local time. + * + * @param[in] p_data: Serial port data. + * @param[in] length: Data length. + ***************************************************************************************** + */ +void local_time_encode(uint8_t *p_data, uint8_t length); + +/** + ***************************************************************************************** + * @brief Serial port data is converted into current time. + * + * @param[in] p_data: Serial port data. + * @param[in] length: Data length. + ***************************************************************************************** + */ +void current_time_encode(uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Handle Local Time Information conversion. + * + * @param[in] p_cfm: Pointer to GATT write attribute result description. + * @param[in] p_evt: Pointer to CTS event. + * + * @return Result of data lenth. + ***************************************************************************************** + */ +uint8_t local_time_universal_decode(ble_gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt) ; + +/** + ***************************************************************************************** + * @brief Decode for a Current Time. + * + * @param[in] p_cfm: Pointer to GATT write attribute result description. + * @param[in] p_evt: Pointer to CTS event. + * + * @return Result of data lenth. + ***************************************************************************************** + */ +uint8_t current_time_universal_decode(ble_gatts_write_cfm_t *p_cfm, cts_evt_t *p_evt); + #endif /** @} */ /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/BUILD.gn new file mode 100644 index 0000000..0c895c8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("cts_c") { + sources = [ "cts_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.c index 134024d..e3a6b77 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.c @@ -39,72 +39,33 @@ * INCLUDE FILES **************************************************************************************** */ -#include +#include "cts_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "cts_c.h" -#define OFFSET_1 1 -#define OFFSET_2 2 -#define OFFSET_3 3 -#define OFFSET_7 7 -#define OFFSET_8 8 -#define OFFSET_9 9 -#define OFFSET_12 12 -#define OFFSET_31 31 -#define OFFSET_23 23 -#define OFFSET_59 59 -#define ATTR_VALUE_LEN 2 +#include +#include "app_log.h" + /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Current Time Service Client environment variable. */ -struct cts_c_env_t { +struct cts_c_env_t +{ cts_c_handles_t handles; /**< Handles of CTS characteristics which will be got for peer. */ cts_c_evt_handler_t evt_handler; /**< Handler of CTS Client event */ uint8_t prf_id; /**< CTS Client profile id. */ }; - -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void cts_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void cts_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void cts_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void cts_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct cts_c_env_t s_cts_c_env; /**< Current Time Service Client environment variable. */ - -/**@brief Current Time Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t cts_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Current Time Service GATT Client Callbacks. */ -static gattc_prf_cbs_t cts_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - cts_c_att_read_cb, - cts_c_att_write_cb, - cts_c_att_ntf_ind_cb, - cts_c_srvc_browse_cb, - NULL, -}; - -/**@brief Current Time Service Client Information. */ -static const prf_client_info_t cts_c_prf_info = { - .max_connection_nb = CTS_C_CONNECTION_MAX, - .manager_cbs = &cts_c_mgr_cbs, - .gattc_prf_cbs = &cts_c_gattc_cbs +static struct cts_c_env_t s_cts_c_env; /**< Current Time Service Client environment variable. */ +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_CURRENT_TIME), HI_U16(BLE_ATT_SVC_CURRENT_TIME)}; +static ble_uuid_t s_cts_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -120,7 +81,8 @@ static const prf_client_info_t cts_c_prf_info = { */ static void cts_c_evt_handler_excute(cts_c_evt_t *p_evt) { - if (s_cts_c_env.evt_handler != NULL && CTS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_cts_c_env.evt_handler && CTS_C_EVT_INVALID != p_evt->evt_type) + { s_cts_c_env.evt_handler(p_evt); } } @@ -137,9 +99,9 @@ static void cts_c_cur_time_encode(const cts_c_cur_time_t *p_cur_time, uint8_t *p { prf_pack_date_time(p_encoded_data, &p_cur_time->day_date_time.date_time); - p_encoded_data[OFFSET_7] = p_cur_time->day_date_time.day_of_week; - p_encoded_data[OFFSET_8] = p_cur_time->day_date_time.fractions_256; - p_encoded_data[OFFSET_9] = p_cur_time->adjust_reason; + p_encoded_data[7] = p_cur_time->day_date_time.day_of_week; + p_encoded_data[8] = p_cur_time->day_date_time.fractions_256; + p_encoded_data[9] = p_cur_time->adjust_reason; } /** @@ -154,9 +116,9 @@ static void cts_c_cur_time_decode(const uint8_t *p_data, cts_c_cur_time_t *p_cur { prf_unpack_date_time(p_data, &p_cur_time->day_date_time.date_time); - p_cur_time->day_date_time.day_of_week = p_data[OFFSET_7]; - p_cur_time->day_date_time.fractions_256 = p_data[OFFSET_8]; - p_cur_time->adjust_reason = p_data[OFFSET_9]; + p_cur_time->day_date_time.day_of_week = p_data[7]; + p_cur_time->day_date_time.fractions_256 = p_data[8]; + p_cur_time->adjust_reason = p_data[9]; } /** @@ -170,9 +132,9 @@ static void cts_c_cur_time_decode(const uint8_t *p_data, cts_c_cur_time_t *p_cur static void cts_c_ref_time_info_decode(const uint8_t *p_data, cts_c_ref_time_info_t *p_ref_time_info) { p_ref_time_info->source = (cts_c_ref_time_source_t)p_data[0]; - p_ref_time_info->accuracy = p_data[OFFSET_1]; - p_ref_time_info->days_since_update = p_data[OFFSET_2]; - p_ref_time_info->hours_since_update = p_data[OFFSET_3]; + p_ref_time_info->accuracy = p_data[1]; + p_ref_time_info->days_since_update = p_data[2]; + p_ref_time_info->hours_since_update = p_data[3]; } /** @@ -185,36 +147,44 @@ static void cts_c_ref_time_info_decode(const uint8_t *p_data, cts_c_ref_time_inf static bool cts_c_cur_time_valid_check(cts_c_cur_time_t *p_cur_time) { if ((p_cur_time->day_date_time.date_time.year > CTS_C_TIME_YEAR_VALID_VAL_MAX) || \ - ((p_cur_time->day_date_time.date_time.year < CTS_C_TIME_YEAR_VALID_VAL_MIN) && \ - (CTS_C_TIME_Y_M_D_UNKNOWN != p_cur_time->day_date_time.date_time.year))) { + ((p_cur_time->day_date_time.date_time.year < CTS_C_TIME_YEAR_VALID_VAL_MIN) && \ + (CTS_C_TIME_Y_M_D_UNKNOWN != p_cur_time->day_date_time.date_time.year))) + { return false; } - if (p_cur_time->day_date_time.date_time.month > OFFSET_12) { + if (p_cur_time->day_date_time.date_time.month > 12) + { return false; } - if (p_cur_time->day_date_time.date_time.day > OFFSET_31) { + if (p_cur_time->day_date_time.date_time.day > 31) + { return false; } - if (p_cur_time->day_date_time.date_time.hour > OFFSET_23) { + if (p_cur_time->day_date_time.date_time.hour > 23) + { return false; } - if (p_cur_time->day_date_time.date_time.min > OFFSET_59) { + if (p_cur_time->day_date_time.date_time.min > 59) + { return false; } - if (p_cur_time->day_date_time.date_time.sec > OFFSET_59) { + if (p_cur_time->day_date_time.date_time.sec > 59) + { return false; } - if (p_cur_time->day_date_time.day_of_week > CTS_C_WEEK_SUNDAY) { + if (p_cur_time->day_date_time.day_of_week > CTS_C_WEEK_SUNDAY) + { return false; } - if (p_cur_time->adjust_reason > 0x0f) { + if (p_cur_time->adjust_reason > 0x0f) + { return false; } return true; @@ -230,14 +200,16 @@ static bool cts_c_cur_time_valid_check(cts_c_cur_time_t *p_cur_time) static bool cts_c_loc_time_info_valid_check(cts_c_loc_time_info_t *p_loc_time_info) { if ((p_loc_time_info->time_zone < CTS_C_TIME_ZONE_OFFSET_MIN) || \ - (p_loc_time_info->time_zone > CTS_C_TIME_ZONE_OFFSET_MAX)) { + (p_loc_time_info->time_zone > CTS_C_TIME_ZONE_OFFSET_MAX)) + { return false; } if ((CTS_C_DST_OFFSET_STANDAR_TIME != p_loc_time_info->dst_offset) && \ (CTS_C_DST_OFFSET_HALF_HOUR != p_loc_time_info->dst_offset) && \ (CTS_C_DST_OFFSET_DAYLIGHT_TIME != p_loc_time_info->dst_offset) && \ - (CTS_C_DST_OFFSET_DOUB_DAYLIGHT_TIME != p_loc_time_info->dst_offset)) { + (CTS_C_DST_OFFSET_DOUB_DAYLIGHT_TIME != p_loc_time_info->dst_offset)) + { return false; } @@ -253,7 +225,8 @@ static bool cts_c_loc_time_info_valid_check(cts_c_loc_time_info_t *p_loc_time_in */ static bool cts_c_ref_time_info_valid_check(cts_c_ref_time_info_t *p_ref_time_info) { - if (p_ref_time_info->source > CTS_C_REF_TIME_SRC_CELLUAR_NET) { + if (p_ref_time_info->source > CTS_C_REF_TIME_SRC_CELLUAR_NET) + { return false; } @@ -269,40 +242,55 @@ static bool cts_c_ref_time_info_valid_check(cts_c_ref_time_info_t *p_ref_time_in * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void cts_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void cts_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { cts_c_evt_t cts_c_evt; cts_c_evt.conn_idx = conn_idx; cts_c_evt.evt_type = CTS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_cts_c_env.handles.cts_cur_time_handle) { - cts_c_cur_time_decode(p_read_rsp->vals[0].p_value, &cts_c_evt.value.cur_time); + if (p_read_rsp->value[0].handle == s_cts_c_env.handles.cts_cur_time_handle) + { + cts_c_cur_time_decode(p_read_rsp->value[0].p_value, &cts_c_evt.value.cur_time); - if (cts_c_cur_time_valid_check(&cts_c_evt.value.cur_time)) { + if (cts_c_cur_time_valid_check(&cts_c_evt.value.cur_time)) + { cts_c_evt.evt_type = CTS_C_EVT_VALID_CUR_TIME_REC; - } else { + } + else + { cts_c_evt.evt_type = CTS_C_EVT_INVALID_CUR_TIME_REC; } - } else if (p_read_rsp->vals[0].handle == s_cts_c_env.handles.cts_loc_time_info_handle) { - cts_c_evt.value.loc_time_info.time_zone = p_read_rsp->vals[0].p_value[0]; - cts_c_evt.value.loc_time_info.dst_offset = (cts_c_dst_offset_t)p_read_rsp->vals[0].p_value[1]; + } + else if (p_read_rsp->value[0].handle == s_cts_c_env.handles.cts_loc_time_info_handle) + { + cts_c_evt.value.loc_time_info.time_zone = p_read_rsp->value[0].p_value[0]; + cts_c_evt.value.loc_time_info.dst_offset = (cts_c_dst_offset_t)p_read_rsp->value[0].p_value[1]; - if (cts_c_loc_time_info_valid_check(&cts_c_evt.value.loc_time_info)) { + if (cts_c_loc_time_info_valid_check(&cts_c_evt.value.loc_time_info)) + { cts_c_evt.evt_type = CTS_C_EVT_VALID_LOC_TIME_INFO_REC; - } else { + } + else + { cts_c_evt.evt_type = CTS_C_EVT_INVALID_LOC_TIME_INFO_REC; } - } else if (p_read_rsp->vals[0].handle == s_cts_c_env.handles.cts_ref_time_info_handle) { - cts_c_ref_time_info_decode(p_read_rsp->vals[0].p_value, &cts_c_evt.value.ref_time_info); + } + else if (p_read_rsp->value[0].handle == s_cts_c_env.handles.cts_ref_time_info_handle) + { + cts_c_ref_time_info_decode(p_read_rsp->value[0].p_value, &cts_c_evt.value.ref_time_info); - if (cts_c_ref_time_info_valid_check(&cts_c_evt.value.ref_time_info)) { + if (cts_c_ref_time_info_valid_check(&cts_c_evt.value.ref_time_info)) + { cts_c_evt.evt_type = CTS_C_EVT_VALID_REF_TIME_INFO_REC; - } else { + } + else + { cts_c_evt.evt_type = CTS_C_EVT_INVALID_REF_TIME_INFO_REC; } } @@ -319,25 +307,30 @@ static void cts_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void cts_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void cts_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { cts_c_evt_t cts_c_evt; cts_c_evt.conn_idx = conn_idx; cts_c_evt.evt_type = CTS_C_EVT_INVALID; - if (handle == s_cts_c_env.handles.cts_cur_time_cccd_handle) { + if (handle == s_cts_c_env.handles.cts_cur_time_cccd_handle) + { cts_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - CTS_C_EVT_CUR_TIME_NTF_SET_SUCCESS : - CTS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_cts_c_env.handles.cts_cur_time_handle) { + CTS_C_EVT_CUR_TIME_NTF_SET_SUCCESS : + CTS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_cts_c_env.handles.cts_cur_time_handle) + { cts_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - CTS_C_EVT_CUR_TIME_SET_SUCCESS : - CTS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_cts_c_env.handles.cts_loc_time_info_handle) { + CTS_C_EVT_CUR_TIME_SET_SUCCESS : + CTS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_cts_c_env.handles.cts_loc_time_info_handle) + { cts_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - CTS_C_EVT_LOC_TIME_INFO_SET_SUCCESS : - CTS_C_EVT_WRITE_OP_ERR; + CTS_C_EVT_LOC_TIME_INFO_SET_SUCCESS : + CTS_C_EVT_WRITE_OP_ERR; } cts_c_evt_handler_excute(&cts_c_evt); @@ -352,19 +345,23 @@ static void cts_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void cts_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void cts_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { cts_c_evt_t cts_c_evt; cts_c_evt.conn_idx = conn_idx; cts_c_evt.evt_type = CTS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_cts_c_env.handles.cts_cur_time_handle) { + if (p_ntf_ind->handle == s_cts_c_env.handles.cts_cur_time_handle) + { cts_c_cur_time_decode(p_ntf_ind->p_value, &cts_c_evt.value.cur_time); - if (cts_c_cur_time_valid_check(&cts_c_evt.value.cur_time)) { + if (cts_c_cur_time_valid_check(&cts_c_evt.value.cur_time)) + { cts_c_evt.evt_type = CTS_C_EVT_VALID_CUR_TIME_REC; - } else { + } + else + { cts_c_evt.evt_type = CTS_C_EVT_INVALID_CUR_TIME_REC; } } @@ -381,7 +378,7 @@ static void cts_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void cts_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void cts_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { cts_c_evt_t cts_c_evt; uint16_t uuid_disc; @@ -390,43 +387,79 @@ static void cts_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat cts_c_evt.conn_idx = conn_idx; cts_c_evt.evt_type = CTS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_CURRENT_TIME == uuid_disc) { - s_cts_c_env.handles.cts_srvc_start_handle = p_browse_srvc->start_hdl; - s_cts_c_env.handles.cts_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_CURRENT_TIME == uuid_disc) + { + s_cts_c_env.handles.cts_srvc_start_handle = p_browse_srvc->start_hdl; + s_cts_c_env.handles.cts_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_CT_TIME == uuid_disc) { - s_cts_c_env.handles.cts_cur_time_handle = handle_disc; - s_cts_c_env.handles.cts_cur_time_cccd_handle = handle_disc + 1; - } else if (BLE_ATT_CHAR_LOCAL_TIME_INFO == uuid_disc) { - s_cts_c_env.handles.cts_loc_time_info_handle = handle_disc; - } else if (BLE_ATT_CHAR_REFERENCE_TIME_INFO == uuid_disc) { - s_cts_c_env.handles.cts_ref_time_info_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_CT_TIME == uuid_disc) + { + s_cts_c_env.handles.cts_cur_time_handle = handle_disc; + s_cts_c_env.handles.cts_cur_time_cccd_handle = handle_disc + 1; + } + else if (BLE_ATT_CHAR_LOCAL_TIME_INFO == uuid_disc) + { + s_cts_c_env.handles.cts_loc_time_info_handle = handle_disc; + } + else if (BLE_ATT_CHAR_REFERENCE_TIME_INFO == uuid_disc) + { + s_cts_c_env.handles.cts_ref_time_info_handle = handle_disc; + } + } + else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; } - } else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; } + + cts_c_evt.evt_type = CTS_C_EVT_DISCOVERY_COMPLETE; } - - cts_c_evt.evt_type = CTS_C_EVT_DISCOVERY_COMPLETE; } - cts_c_evt_handler_excute(&cts_c_evt); } +static void cts_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + cts_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + cts_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + cts_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + cts_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} /* * GLOBAL FUNCTION DEFINITIONS @@ -434,18 +467,15 @@ static void cts_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat */ sdk_err_t cts_client_init(cts_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_cts_c_env, sizeof(s_cts_c_env), 0, sizeof(s_cts_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_cts_c_env, 0, sizeof(s_cts_c_env)); s_cts_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&cts_c_prf_info, &s_cts_c_env.prf_id); + return ble_gattc_prf_add(&s_cts_service_uuid, cts_c_ble_evt_handler); } sdk_err_t cts_c_disc_srvc_start(uint8_t conn_idx) @@ -455,93 +485,113 @@ sdk_err_t cts_c_disc_srvc_start(uint8_t conn_idx) target_uuid[0] = LO_U16(BLE_ATT_SVC_CURRENT_TIME); target_uuid[1] = HI_U16(BLE_ATT_SVC_CURRENT_TIME); - const ble_uuid_t cts_service_uuid = { + const ble_uuid_t cts_service_uuid = + { .uuid_len = 2, .uuid = target_uuid, }; - return ble_gattc_prf_services_browse(s_cts_c_env.prf_id, conn_idx, &cts_service_uuid); + return ble_gattc_services_browse(conn_idx, &cts_service_uuid); } sdk_err_t cts_c_cur_time_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_cts_c_env.handles.cts_cur_time_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_cts_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_cts_c_env.handles.cts_cur_time_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t cts_c_cur_time_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_cts_c_env.prf_id, conn_idx, s_cts_c_env.handles.cts_cur_time_handle, 0); + return ble_gattc_read(conn_idx, s_cts_c_env.handles.cts_cur_time_handle, 0); } sdk_err_t cts_c_loc_time_info_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_loc_time_info_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_loc_time_info_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_cts_c_env.prf_id, conn_idx, s_cts_c_env.handles.cts_loc_time_info_handle, 0); + return ble_gattc_read(conn_idx, s_cts_c_env.handles.cts_loc_time_info_handle, 0); } sdk_err_t cts_c_ref_time_info_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_ref_time_info_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_ref_time_info_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_cts_c_env.prf_id, conn_idx, s_cts_c_env.handles.cts_ref_time_info_handle, 0); + return ble_gattc_read(conn_idx, s_cts_c_env.handles.cts_ref_time_info_handle, 0); } sdk_err_t cts_c_cur_time_set(uint8_t conn_idx, cts_c_cur_time_t *p_cur_time) { - gattc_write_attr_value_t write_attr_value; uint8_t encoded_buffer[CTS_C_CUR_TIME_VAL_LEN]; - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_cur_time_handle) + { return SDK_ERR_INVALID_HANDLE; } cts_c_cur_time_encode(p_cur_time, encoded_buffer); - write_attr_value.handle = s_cts_c_env.handles.cts_cur_time_handle; - write_attr_value.offset = 0; - write_attr_value.length = CTS_C_CUR_TIME_VAL_LEN; - write_attr_value.p_value = encoded_buffer; - - return ble_gattc_prf_write(s_cts_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_cts_c_env.handles.cts_cur_time_handle, 0, CTS_C_CUR_TIME_VAL_LEN, (uint8_t *)&encoded_buffer); } sdk_err_t cts_c_loc_time_info_set(uint8_t conn_idx, cts_c_loc_time_info_t *p_loc_time_info) { - gattc_write_attr_value_t write_attr_value; uint8_t encoded_buffer[CTS_C_LOC_TIME_INFO_VAL_LEN]; - if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_loc_time_info_handle) { + if (BLE_ATT_INVALID_HDL == s_cts_c_env.handles.cts_loc_time_info_handle) + { return SDK_ERR_INVALID_HANDLE; } encoded_buffer[0] = p_loc_time_info->time_zone; encoded_buffer[1] = p_loc_time_info->dst_offset; - write_attr_value.handle = s_cts_c_env.handles.cts_loc_time_info_handle; - write_attr_value.offset = 0; - write_attr_value.length = CTS_C_LOC_TIME_INFO_VAL_LEN; - write_attr_value.p_value = encoded_buffer; - - return ble_gattc_prf_write(s_cts_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_cts_c_env.handles.cts_loc_time_info_handle, 0, CTS_C_LOC_TIME_INFO_VAL_LEN, encoded_buffer); } + +void cts_c_data_parse(uint8_t *p_data, uint16_t length) +{ + if(0 == memcmp(p_data, "CR", 2)) + { + APP_LOG_DEBUG("Read Current Time value."); + cts_c_cur_time_read(0); + } + else if(0 == memcmp(p_data, "LR", 2)) + { + APP_LOG_DEBUG("Read Local Time Information value."); + cts_c_loc_time_info_read(0); + } + else if(0 == memcmp(p_data, "RR", 2)) + { + APP_LOG_DEBUG("Read Reference Time Information value."); + cts_c_ref_time_info_read(0); + } + else if(0 == memcmp(p_data, "EN", 2)) + { + APP_LOG_INFO("Enabled Current Time Notification."); + cts_c_cur_time_notify_set(0, true); + + } + else if(0 == memcmp(p_data, "DN", 2)) + { + APP_LOG_INFO("Disabled Current Time Notification."); + cts_c_cur_time_notify_set(0, false); + } +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.h index 7b1586c..2fc6946 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/cts_c/cts_c.h @@ -59,29 +59,27 @@ #ifndef __CTS_C_H__ #define __CTS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup CTS_C_MACRO Defines * @{ */ -#define CTS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections. */ - -#define CTS_C_CUR_TIME_VAL_LEN 10 /**< Length of current time value. */ -#define CTS_C_LOC_TIME_INFO_VAL_LEN 2 /**< Length of local time information value. */ -#define CTS_C_TIME_Y_M_D_UNKNOWN 0 /**< Year or Month or Day is not known. */ -#define CTS_C_TIME_YEAR_VALID_VAL_MIN 1582 /**< Minimum value of valid year. */ -#define CTS_C_TIME_YEAR_VALID_VAL_MAX 9999 /**< Maximum value of valid year. */ -#define CTS_C_TIME_ZONE_OFFSET_MIN (-48) /**< Minimum Value of Offset from UTC. */ -#define CTS_C_TIME_ZONE_OFFSET_MAX 56 /**< Maximum Value of Offset from UTC. */ -#define CTS_C_TIME_ACCURACY_OUT_RANGE 254 /**< Accuracy out of range. */ -#define CTS_C_TIME_ACCURACT_UNKNOWN 255 /**< Accuracy Unknown. */ -#define CTS_C_ERROR_FIELDS_IGNORED 0x80 /**< The server ignored one or more fields. */ +#define CTS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ +#define CTS_C_CUR_TIME_VAL_LEN 10 /**< Length of current time value. */ +#define CTS_C_LOC_TIME_INFO_VAL_LEN 2 /**< Length of local time information value. */ +#define CTS_C_TIME_Y_M_D_UNKNOWN 0 /**< Year or Month or Day is not known. */ +#define CTS_C_TIME_YEAR_VALID_VAL_MIN 1582 /**< Minimum value of valid year. */ +#define CTS_C_TIME_YEAR_VALID_VAL_MAX 9999 /**< Maximum value of valid year. */ +#define CTS_C_TIME_ZONE_OFFSET_MIN -48 /**< Minimum Value of Offset from UTC. */ +#define CTS_C_TIME_ZONE_OFFSET_MAX 56 /**< Maximum Value of Offset from UTC. */ +#define CTS_C_TIME_ACCURACY_OUT_RANGE 254 /**< Accuracy out of range. */ +#define CTS_C_TIME_ACCURACT_UNKNOWN 255 /**< Accuracy Unknown. */ +#define CTS_C_ERROR_FIELDS_IGNORED 0x80 /**< The server ignored one or more fields. */ /** * @defgroup CTS_C_ADJ_REASON Current Time Adjust Reason @@ -101,7 +99,8 @@ * @{ */ /**@brief Current Time Day of week. */ -typedef enum { +typedef enum +{ CTS_C_WEEK_UNKNOWN_DAY, /**< Day of week is not known. */ CTS_C_WEEK_MONDAY, /**< Monday. */ CTS_C_WEEK_TUSEDAY, /**< Tuesday. */ @@ -113,7 +112,8 @@ typedef enum { } cts_c_week_day_t; /**@brief Local time information:Daylight Saving Time Offset. */ -typedef enum { +typedef enum +{ CTS_C_DST_OFFSET_STANDAR_TIME = 0x00, /**< Standard Time. */ CTS_C_DST_OFFSET_HALF_HOUR = 0x02, /**< Half An Hour Daylight Time (+0.5h). */ CTS_C_DST_OFFSET_DAYLIGHT_TIME = 0x04, /**< Daylight Time (+1h). */ @@ -121,7 +121,8 @@ typedef enum { } cts_c_dst_offset_t; /**@brief Reference time information:Time Source. */ -typedef enum { +typedef enum +{ CTS_C_REF_TIME_SRC_UNKNOWN, /**< Unknown. */ CTS_C_REF_TIME_SRC_NET_TIME_PROTOCOL, /**< Network Time Protocol. */ CTS_C_REF_TIME_SRC_GPS, /**< GPS. */ @@ -132,24 +133,18 @@ typedef enum { } cts_c_ref_time_source_t; /**@brief Current Time Service Client event type. */ -typedef enum { +typedef enum +{ CTS_C_EVT_INVALID, /**< CTS Client invalid event. */ CTS_C_EVT_DISCOVERY_COMPLETE, /**< CTS Client has found CTS service and its characteristics. */ - CTS_C_EVT_DISCOVERY_FAIL, /**< CTS Client found CTS service failed because of invalid operation or \ - no found at the peer. */ + CTS_C_EVT_DISCOVERY_FAIL, /**< CTS Client found CTS service failed because of invalid operation or no found at the peer. */ CTS_C_EVT_CUR_TIME_NTF_SET_SUCCESS, /**< CTS Client has set Notification of Current Time characteristic. */ - CTS_C_EVT_VALID_CUR_TIME_REC, /**< CTS Client has received valid Current Time value \ - (Read or Notification from peer). */ - CTS_C_EVT_INVALID_CUR_TIME_REC, /**< CTS Client has received invalid Current Time value \ - (Read or Notification from peer). */ - CTS_C_EVT_VALID_LOC_TIME_INFO_REC, /**< CTS Client has received valid Local Time Information value \ - (Read from peer). */ - CTS_C_EVT_INVALID_LOC_TIME_INFO_REC, /**< CTS Client has received invalid Local Time Information value \ - (Read from peer). */ - CTS_C_EVT_VALID_REF_TIME_INFO_REC, /**< CTS Client has received valid Reference Time Information Value \ - (Read from peer). */ - CTS_C_EVT_INVALID_REF_TIME_INFO_REC, /**< CTS Client has received invalid Reference Time Information Value \ - (Read from peer). */ + CTS_C_EVT_VALID_CUR_TIME_REC, /**< CTS Client has received valid Current Time value (Read or Notification from peer). */ + CTS_C_EVT_INVALID_CUR_TIME_REC, /**< CTS Client has received invalid Current Time value (Read or Notification from peer). */ + CTS_C_EVT_VALID_LOC_TIME_INFO_REC, /**< CTS Client has received valid Local Time Information value (Read from peer). */ + CTS_C_EVT_INVALID_LOC_TIME_INFO_REC, /**< CTS Client has received invalid Local Time Information value (Read from peer). */ + CTS_C_EVT_VALID_REF_TIME_INFO_REC, /**< CTS Client has received valid Reference Time Information Value (Read from peer). */ + CTS_C_EVT_INVALID_REF_TIME_INFO_REC, /**< CTS Client has received invalid Reference Time Information Value (Read from peer). */ CTS_C_EVT_CUR_TIME_SET_SUCCESS, /**< CTS Client has writen Current Time completely. */ CTS_C_EVT_LOC_TIME_INFO_SET_SUCCESS, /**< CTS Client has writen Local Time Information completely. */ CTS_C_EVT_WRITE_OP_ERR, /**< Error occured when CTS Client writen to peer. */ @@ -161,40 +156,41 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t cts_srvc_start_handle; /**< CTS Service start handle. */ uint16_t cts_srvc_end_handle; /**< CTS Service end handle. */ - uint16_t cts_cur_time_handle; /**< CTS Current Time characteristic Value handle \ - which has been got from peer. */ - uint16_t cts_cur_time_cccd_handle; /**< CTS CCCD handle of Current Time characteristic \ - which has been got from peer. */ - uint16_t cts_loc_time_info_handle; /**< CTS Local Time Information characteristic Value handle \ - which has been got from peer. */ - uint16_t cts_ref_time_info_handle; /**< CTS Reference Time Information characteristic Value handle \ - which has been got from peer. */ + uint16_t cts_cur_time_handle; /**< CTS Current Time characteristic Value handle which has been got from peer. */ + uint16_t cts_cur_time_cccd_handle; /**< CTS CCCD handle of Current Time characteristic which has been got from peer. */ + uint16_t cts_loc_time_info_handle; /**< CTS Local Time Information characteristic Value handle which has been got from peer. */ + uint16_t cts_ref_time_info_handle; /**< CTS Reference Time Information characteristic Value handle which has been got from peer. */ } cts_c_handles_t; /**@brief Exact Time 256. */ -typedef struct { +typedef struct +{ prf_date_time_t date_time; /**< Date Time. */ uint8_t day_of_week; /**< Day of Week. */ uint8_t fractions_256; /**< 1/256th of a second. */ } cts_c_exact_time_256_t; /**@brief Current Time value. */ -typedef struct { +typedef struct +{ cts_c_exact_time_256_t day_date_time; /**< Exact Time 256. */ uint8_t adjust_reason; /**< Adjust Reason. */ } cts_c_cur_time_t; /**@brief Local Time Information. */ -typedef struct { +typedef struct +{ int8_t time_zone; /**< Time Zone, Offset from UTC in number of 15 minutes increments. */ cts_c_dst_offset_t dst_offset; /**< Daylight Saving Time Offset. */ } cts_c_loc_time_info_t; /**@brief Reference Time Information. */ -typedef struct { +typedef struct +{ cts_c_ref_time_source_t source; /**< Time Source. */ uint8_t accuracy; /**< Accuracy of time information. */ uint8_t days_since_update; /**< Days Since Update. */ @@ -202,10 +198,12 @@ typedef struct { } cts_c_ref_time_info_t; /**@brief Current Time Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ cts_c_evt_type_t evt_type; /**< The CTS client event type. */ - union { + union + { cts_c_cur_time_t cur_time; /**< Curren time received. */ cts_c_loc_time_info_t loc_time_info; /**< Local time information received. */ cts_c_ref_time_info_t ref_time_info; /**< Referen time information received. */ @@ -315,6 +313,16 @@ sdk_err_t cts_c_cur_time_set(uint8_t conn_idx, cts_c_cur_time_t *p_cur_time); ***************************************************************************************** */ sdk_err_t cts_c_loc_time_info_set(uint8_t conn_idx, cts_c_loc_time_info_t *p_loc_time_info); + +/** + ***************************************************************************************** + * @brief Data accepts data and processing functions. + * + * @param[in] p_data: Serial port data. + * @param[in] length: Data length. + ***************************************************************************************** + */ +void cts_c_data_parse(uint8_t *p_data, uint16_t length); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/BUILD.gn new file mode 100644 index 0000000..d0ae73c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("dis") { + sources = [ "dis.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.c index b9049d4..bbd758e 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.c @@ -43,19 +43,14 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define INDEX_0 0 -#define INDEX_1 1 -#define INDEX_2 2 -#define INDEX_3 3 -#define INDEX_4 4 -#define INDEX_5 5 -#define INDEX_6 6 + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief Device Information Service Attributes database index list. */ -enum dis_attr_idx_t { +enum dis_attr_idx_t +{ DIS_IDX_SVC, DIS_IDX_SYSTEM_ID_CHAR, @@ -93,137 +88,76 @@ enum dis_attr_idx_t { ***************************************************************************************** */ /**@brief Device Information Service environment variable. */ -struct dis_env_t { - dis_init_t dis_init; /**< Device Information Service initialization variables. */ - uint16_t start_hdl; /**< Device Information Service start handle. */ +struct dis_env_t +{ + dis_init_t dis_init; /**< Device Information Service initialization variables. */ + uint16_t start_hdl; /**< Device Information Service start handle. */ + ble_gatts_create_db_t dis_gatts_db; /**< Device Information Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t dis_init(void); -static void dis_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct dis_env_t s_dis_env; +static const uint8_t s_dis_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_DEVICE_INFO); /**@brief Full DIS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_t dis_attr_tab[DIS_IDX_NB] = { +static const ble_gatts_attm_desc_t dis_attr_tab[DIS_IDX_NB] = +{ // Device Information Service Declaration - [DIS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // System ID Characteristic Declaration - [DIS_IDX_SYSTEM_ID_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_SYSTEM_ID_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // System ID Characteristic Value - [DIS_IDX_SYSTEM_ID_VAL] = {BLE_ATT_CHAR_SYS_ID, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_SYS_ID_LEN}, + [DIS_IDX_SYSTEM_ID_VAL] = {BLE_ATT_CHAR_SYS_ID, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_SYS_ID_LEN}, // Model Number String Characteristic Declaration - [DIS_IDX_MODEL_NB_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_MODEL_NB_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Model Number String Characteristic Value - [DIS_IDX_MODEL_NB_STR_VAL] = {BLE_ATT_CHAR_MODEL_NB, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_MODEL_NB_STR_VAL] = {BLE_ATT_CHAR_MODEL_NB, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // Serial Number String Characteristic Declaration - [DIS_IDX_SERIAL_NB_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_SERIAL_NB_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Serial Number String Characteristic Value - [DIS_IDX_SERIAL_NB_STR_VAL] = {BLE_ATT_CHAR_SERIAL_NB, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_SERIAL_NB_STR_VAL] = {BLE_ATT_CHAR_SERIAL_NB, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // Firmware Revision String Characteristic Declaration - [DIS_IDX_FIRM_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_FIRM_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Firmware Revision String Characteristic Value - [DIS_IDX_FIRM_REV_STR_VAL] = {BLE_ATT_CHAR_FW_REV, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_FIRM_REV_STR_VAL] = {BLE_ATT_CHAR_FW_REV, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // Hardware Revision String Characteristic Declaration - [DIS_IDX_HARD_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_HARD_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Hardware Revision String Characteristic Value - [DIS_IDX_HARD_REV_STR_VAL] = {BLE_ATT_CHAR_HW_REV, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_HARD_REV_STR_VAL] = {BLE_ATT_CHAR_HW_REV, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // Software Revision String Characteristic Declaration - [DIS_IDX_SW_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_SW_REV_STR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Software Revision String Characteristic Value - [DIS_IDX_SW_REV_STR_VAL] = {BLE_ATT_CHAR_SW_REV, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_SW_REV_STR_VAL] = {BLE_ATT_CHAR_SW_REV, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // Manufacturer Name Characteristic Declaration - [DIS_IDX_MANUFACTURER_NAME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_MANUFACTURER_NAME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Manufacturer Name Characteristic Value - [DIS_IDX_MANUFACTURER_NAME_VAL] = {BLE_ATT_CHAR_MANUF_NAME, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, + [DIS_IDX_MANUFACTURER_NAME_VAL] = {BLE_ATT_CHAR_MANUF_NAME, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_VAL_MAX_LEN}, // IEEE 11073-20601 Regulatory Certification Data List Characteristic Declaration - [DIS_IDX_IEEE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_IEEE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // IEEE 11073-20601 Regulatory Certification Data List Characteristic Value - [DIS_IDX_IEEE_VAL] = {BLE_ATT_CHAR_IEEE_CERTIF, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_SYS_ID_LEN}, + [DIS_IDX_IEEE_VAL] = {BLE_ATT_CHAR_IEEE_CERTIF, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_SYS_ID_LEN}, // PnP ID Characteristic Declaration - [DIS_IDX_PNP_ID_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [DIS_IDX_PNP_ID_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // PnP ID Characteristic Value - [DIS_IDX_PNP_ID_VAL] = {BLE_ATT_CHAR_PNP_ID, READ_PERM_UNSEC, ATT_VAL_LOC_USER, DIS_PNP_ID_LEN}, -}; - -/**@brief Device Information Service interface required by profile manager. */ -static ble_prf_manager_cbs_t dis_mgr_cbs = { - (prf_init_func_t)dis_init, - NULL, - NULL -}; - -/**@brief Device Information GATT Server Callbacks. */ -static gatts_prf_cbs_t dis_gatts_cbs = { - dis_read_att_cb, - NULL, - NULL, - NULL -}; - -/**@brief Device Information Service Information. */ -static const prf_server_info_t dis_prf_info = { - .max_connection_nb = DIS_CONNECTION_MAX, - .manager_cbs = &dis_mgr_cbs, - .gatts_prf_cbs = &dis_gatts_cbs + [DIS_IDX_PNP_ID_VAL] = {BLE_ATT_CHAR_PNP_ID, BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, DIS_PNP_ID_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize device information service and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t dis_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t dis_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_DEVICE_INFO); - sdk_err_t error_code = SDK_SUCCESS; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = dis_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_dis_env.dis_init.char_mask; - gatts_db.max_nb_attr = DIS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = dis_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_dis_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -232,20 +166,21 @@ static sdk_err_t dis_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void dis_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void dis_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint16_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_dis_env.start_hdl, - DIS_IDX_NB, - (uint8_t *)&s_dis_env.dis_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint16_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_dis_env.start_hdl, + DIS_IDX_NB, + (uint8_t *)&s_dis_env.dis_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; uint8_t buf[DIS_PNP_ID_LEN]; - switch (tab_index) { + switch (tab_index) + { case DIS_IDX_SYSTEM_ID_VAL: cfm.length = DIS_SYS_ID_LEN; cfm.value = (uint8_t *)s_dis_env.dis_init.p_sys_id; @@ -286,17 +221,18 @@ static void dis_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param cfm.value = (uint8_t *)s_dis_env.dis_init.reg_cert_data_list.p_list; break; - case DIS_IDX_PNP_ID_VAL: { - buf[INDEX_0] = s_dis_env.dis_init.p_pnp_id->vendor_id_source; - buf[INDEX_1] = LO_U16(s_dis_env.dis_init.p_pnp_id->vendor_id); - buf[INDEX_2] = HI_U16(s_dis_env.dis_init.p_pnp_id->vendor_id); - buf[INDEX_3] = LO_U16(s_dis_env.dis_init.p_pnp_id->product_id); - buf[INDEX_4] = HI_U16(s_dis_env.dis_init.p_pnp_id->product_id); - buf[INDEX_5] = LO_U16(s_dis_env.dis_init.p_pnp_id->product_version); - buf[INDEX_6] = HI_U16(s_dis_env.dis_init.p_pnp_id->product_version); - cfm.length = DIS_PNP_ID_LEN; - cfm.value = buf; - } + case DIS_IDX_PNP_ID_VAL: + { + buf[0] = s_dis_env.dis_init.p_pnp_id->vendor_id_source; + buf[1] = LO_U16(s_dis_env.dis_init.p_pnp_id->vendor_id); + buf[2] = HI_U16(s_dis_env.dis_init.p_pnp_id->vendor_id); + buf[3] = LO_U16(s_dis_env.dis_init.p_pnp_id->product_id); + buf[4] = HI_U16(s_dis_env.dis_init.p_pnp_id->product_id); + buf[5] = LO_U16(s_dis_env.dis_init.p_pnp_id->product_version); + buf[6] = HI_U16(s_dis_env.dis_init.p_pnp_id->product_version); + cfm.length = DIS_PNP_ID_LEN; + cfm.value = buf; + } break; default: @@ -308,21 +244,47 @@ static void dis_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param ble_gatts_read_cfm(conn_idx, &cfm); } +static void dis_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + dis_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + } +} + + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t dis_service_init(dis_init_t *p_dis_init) { - sdk_err_t ret; - if (p_dis_init == NULL) { + if (NULL == p_dis_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_dis_env.dis_init, sizeof(dis_init_t), p_dis_init, sizeof(dis_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_dis_env.dis_init, p_dis_init, sizeof(dis_init_t)); - return ble_server_prf_add(&dis_prf_info); + s_dis_env.start_hdl = PRF_INVALID_HANDLE; + s_dis_env.dis_gatts_db.shdl = &s_dis_env.start_hdl; + s_dis_env.dis_gatts_db.uuid = s_dis_svc_uuid; + s_dis_env.dis_gatts_db.attr_tab_cfg = (uint8_t *)&s_dis_env.dis_init.char_mask; + s_dis_env.dis_gatts_db.max_nb_attr = DIS_IDX_NB; + s_dis_env.dis_gatts_db.srvc_perm = 0; + s_dis_env.dis_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_dis_env.dis_gatts_db.attr_tab.attr_tab_16 = dis_attr_tab; + + return ble_gatts_prf_add(&s_dis_env.dis_gatts_db, dis_ble_evt_handler); } +uint16_t dis_service_start_handle_get(void) +{ + return s_dis_env.start_hdl; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.h index 72540a6..8cc2aad 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis/dis.h @@ -62,21 +62,19 @@ #ifndef __DIS_H__ #define __DIS_H__ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup DIS_MACRO Defines * @{ */ -#define DIS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of DIS connections. \ - The value is configurable. */ -#define DIS_SYS_ID_LEN 8 /**< System ID length. */ -#define DIS_PNP_ID_LEN 7 /**< PnP ID length. */ -#define DIS_VAL_MAX_LEN 128 /**< Maximal length for Characteristic values - 128 bytes. */ -#define DIS_IEEE_CERTIF_MIN_LEN 6 /**< IEEE Certification length (min 6 bytes). */ +#define DIS_CONNECTION_MAX 10 /**< Maximum number of DIS connections.The value is configurable. */ +#define DIS_SYS_ID_LEN 8 /**< System ID length. */ +#define DIS_PNP_ID_LEN 7 /**< PnP ID length. */ +#define DIS_VAL_MAX_LEN 128 /**< Maximal length for Characteristic values - 128 bytes. */ +#define DIS_IEEE_CERTIF_MIN_LEN 6 /**< IEEE Certification length (min 6 bytes). */ /** * @defgroup DIS_CHAR_MASK Characteristics Mask @@ -90,8 +88,7 @@ #define DIS_CHAR_HARDWARE_REV_SUP 0x00000600 /**< Bit mask of the Hardware Revision. */ #define DIS_CHAR_SOFTWARE_REV_SUP 0x00001800 /**< Bit mask of the Software Revision. */ #define DIS_CHAR_MANUFACTURER_NAME_SUP 0x00006000 /**< Bit mask of the Manufacturer Name. */ -#define DIS_CHAR_11073_CERT_DATA_SUP 0x00018000 /**< Bit mask of the IEEE 11073-20601 \ - Regulatory Certification Data List. */ +#define DIS_CHAR_11073_CERT_DATA_SUP 0x00018000 /**< Bit mask of the IEEE 11073-20601 Regulatory Certification Data List. */ #define DIS_CHAR_PNP_ID_SUP 0x00060000 /**< Bit mask of the PnP ID. */ #define DIS_CHAR_FULL 0x0007ffff /**< Bit mask of the full characteristic. */ /** @} */ @@ -112,27 +109,31 @@ * @{ */ /**@brief UTF-8 string data type. */ -typedef struct { +typedef struct +{ uint8_t length; /**< String length. */ char *p_str; /**< String data. */ } dis_string_t; /**@brief System ID parameters. The first field is the LSOs and the second * field contains the MSOs. */ -typedef struct { +typedef struct +{ uint8_t manufacturer_id[5]; /**< Manufacturer-defined ID. */ uint8_t org_unique_id[3]; /**< Organizationally unique ID (OUI) which is issued by IEEE. */ } dis_sys_id_t; /**@brief IEEE 11073-20601 Regulatory Certification Data List Structure. */ -typedef struct { +typedef struct +{ char *p_list; /**< Pointer to the list which contains the encoded opaque * structure based on IEEE 11073-20601 specification. */ uint8_t list_len; /**< Length of the list. */ } dis_reg_cert_data_list_t; /**@brief PnP ID parameters */ -typedef struct { +typedef struct +{ uint8_t vendor_id_source; /**< Vendor ID Source. */ uint16_t vendor_id; /**< Vendor ID. */ uint16_t product_id; /**< Product ID. */ @@ -141,9 +142,9 @@ typedef struct { /**@brief Device Information Service init structure. This contains all options * and data needed for initialization of the service. */ -typedef struct { - uint32_t - char_mask; /**< Initial mask of Supported characteristics, and configured with \ref DIS_CHAR_MASK. */ +typedef struct +{ + uint32_t char_mask; /**< Initial mask of Supported characteristics, and configured with \ref DIS_CHAR_MASK. */ dis_string_t manufact_name_str; /**< Initial manufacturer Name String. */ dis_string_t model_num_str; /**< Initial model Number String. */ dis_string_t serial_num_str; /**< Initial serial Number String. */ @@ -170,6 +171,16 @@ typedef struct { ***************************************************************************************** */ sdk_err_t dis_service_init(dis_init_t *p_dis_init); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the dis service start handle . + * + * @return The dis service start handle. + ***************************************************************************************** + */ +uint16_t dis_service_start_handle_get(void); + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/BUILD.gn new file mode 100644 index 0000000..02f6a66 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("dis_c") { + sources = [ "dis_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.c index 3f0ebd5..a9b78e3 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.c @@ -39,68 +39,32 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "dis_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "dis_c.h" +#include -#define INDEX_1 1 -#define INDEX_2 2 -#define INDEX_3 3 -#define INDEX_4 4 -#define INDEX_5 5 -#define INDEX_6 6 -#define INDEX_7 7 -#define OFFSET_8 8 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Device Information Service environment variable. */ -struct dis_c_env_t { +struct dis_c_env_t +{ dis_c_handles_t handles; /**< Handles of DIS characteristics which will be got for peer. */ dis_c_evt_handler_t evt_handler; /**< Handler of DIS Client event */ - uint8_t prf_id; /**< DIS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void dis_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void dis_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct dis_c_env_t s_dis_c_env; /**< Device Information Service Client environment variable. */ - -/**@brief Device Information Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t dis_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Device Information Service GATT Client Callbacks. */ -static gattc_prf_cbs_t dis_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - dis_c_att_read_cb, - NULL, - NULL, - dis_c_srvc_browse_cb, - NULL, -}; - -/**@brief Device Information Service Client Information. */ -static const prf_client_info_t dis_c_prf_info = { - .max_connection_nb = DIS_C_CONNECTION_MAX, - .manager_cbs = &dis_c_mgr_cbs, - .gattc_prf_cbs = &dis_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_DEVICE_INFO), HI_U16(BLE_ATT_SVC_DEVICE_INFO)}; +static ble_uuid_t s_dis_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -118,8 +82,10 @@ static const prf_client_info_t dis_c_prf_info = { */ static dis_c_char_type_t dis_c_char_read_type_get(uint16_t handle) { - for (uint8_t i = 0; i < DIS_C_CHARACTER_NB; i++) { - if (handle == s_dis_c_env.handles.dis_char_handle[i]) { + for (uint8_t i = 0; i < DIS_C_CHARACTER_NB; i++) + { + if (handle == s_dis_c_env.handles.dis_char_handle[i]) + { return (dis_c_char_type_t)i; } } @@ -144,24 +110,31 @@ static void dis_c_char_read_rsp_encode(dis_c_char_type_t char_read_type, { p_read_rsp_buffer->char_type = char_read_type; - if (DIS_C_SYS_ID == char_read_type) { - p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[INDEX_0] = p_data[INDEX_0]; - p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[INDEX_1] = p_data[INDEX_1]; - p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[INDEX_2] = p_data[INDEX_2]; - p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[INDEX_3] = p_data[INDEX_3]; - p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[INDEX_4] = p_data[INDEX_4]; - p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[INDEX_0] = p_data[INDEX_5]; - p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[INDEX_1] = p_data[INDEX_6]; - p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[INDEX_2] = p_data[INDEX_7]; - } else if (DIS_C_CERT_LIST == char_read_type) { + if (DIS_C_SYS_ID == char_read_type) + { + p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[0] = p_data[0]; + p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[1] = p_data[1]; + p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[2] = p_data[2]; + p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[3] = p_data[3]; + p_read_rsp_buffer->encode_rst.sys_id.manufacturer_id[4] = p_data[4]; + p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[0] = p_data[5]; + p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[1] = p_data[6]; + p_read_rsp_buffer->encode_rst.sys_id.org_unique_id[2] = p_data[7]; + } + else if (DIS_C_CERT_LIST == char_read_type) + { p_read_rsp_buffer->encode_rst.cert_list.p_list = p_data; p_read_rsp_buffer->encode_rst.cert_list.list_length = length; - } else if (DIS_C_PNP_ID == char_read_type) { - p_read_rsp_buffer->encode_rst.pnp_id.vendor_id_source = p_data[INDEX_0] | (p_data[INDEX_1] << OFFSET_8); - p_read_rsp_buffer->encode_rst.pnp_id.vendor_id = p_data[INDEX_2] | (p_data[INDEX_3] << OFFSET_8); - p_read_rsp_buffer->encode_rst.pnp_id.product_id = p_data[INDEX_4] | (p_data[INDEX_5] << OFFSET_8); - p_read_rsp_buffer->encode_rst.pnp_id.product_version = p_data[INDEX_6] | (p_data[INDEX_7] << OFFSET_8); - } else { + } + else if (DIS_C_PNP_ID == char_read_type) + { + p_read_rsp_buffer->encode_rst.pnp_id.vendor_id_source = p_data[0] | p_data[1] << 8; + p_read_rsp_buffer->encode_rst.pnp_id.vendor_id = p_data[2] | p_data[3] << 8; + p_read_rsp_buffer->encode_rst.pnp_id.product_id = p_data[4] | p_data[5] << 8; + p_read_rsp_buffer->encode_rst.pnp_id.product_version = p_data[6] | p_data[7] << 8; + } + else + { p_read_rsp_buffer->encode_rst.string_data.p_data = p_data; p_read_rsp_buffer->encode_rst.string_data.length = length; } @@ -176,7 +149,8 @@ static void dis_c_char_read_rsp_encode(dis_c_char_type_t char_read_type, */ void dis_c_evt_handler_excute(dis_c_evt_t *p_evt) { - if (s_dis_c_env.evt_handler != NULL && DIS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_dis_c_env.evt_handler && DIS_C_EVT_INVALID != p_evt->evt_type) + { s_dis_c_env.evt_handler(p_evt); } } @@ -190,7 +164,7 @@ void dis_c_evt_handler_excute(dis_c_evt_t *p_evt) * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void dis_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void dis_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { dis_c_evt_t dis_c_evt; dis_c_char_type_t char_read_type = DIS_C_CHARACTER_NB; @@ -198,15 +172,16 @@ static void dis_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ dis_c_evt.conn_idx = conn_idx; dis_c_evt.evt_type = DIS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if ((p_read_rsp->vals[0].handle >= s_dis_c_env.handles.dis_srvc_start_handle) && \ - (p_read_rsp->vals[0].handle <= s_dis_c_env.handles.dis_srvc_end_handle)) { - char_read_type = dis_c_char_read_type_get(p_read_rsp->vals[0].handle); - dis_c_char_read_rsp_encode(char_read_type, p_read_rsp->vals[0].p_value, p_read_rsp->vals[0].length, - &dis_c_evt.read_rsp); + if ((p_read_rsp->value[0].handle >= s_dis_c_env.handles.dis_srvc_start_handle) && \ + (p_read_rsp->value[0].handle <= s_dis_c_env.handles.dis_srvc_end_handle)) + { + char_read_type = dis_c_char_read_type_get(p_read_rsp->value[0].handle); + dis_c_char_read_rsp_encode(char_read_type, p_read_rsp->value[0].p_value, p_read_rsp->value[0].length, &dis_c_evt.read_rsp); dis_c_evt.evt_type = DIS_C_EVT_DEV_INFORMATION_READ_RSP; dis_c_evt_handler_excute(&dis_c_evt); } @@ -221,7 +196,7 @@ static void dis_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void dis_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void dis_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { dis_c_evt_t dis_c_evt; uint16_t uuid_disc; @@ -230,42 +205,66 @@ static void dis_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat dis_c_evt.conn_idx = conn_idx; dis_c_evt.evt_type = DIS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (BLE_SUCCESS == status) { - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_DEVICE_INFO == uuid_disc) { + if (BLE_ATT_SVC_DEVICE_INFO == uuid_disc) + { s_dis_c_env.handles.dis_srvc_start_handle = p_browse_srvc->start_hdl; s_dis_c_env.handles.dis_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << OFFSET_8; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_SYS_ID == uuid_disc) { + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_SYS_ID == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_SYS_ID] = handle_disc; - } else if (BLE_ATT_CHAR_MODEL_NB == uuid_disc) { + } + else if (BLE_ATT_CHAR_MODEL_NB == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_MODEL_NUM] = handle_disc; - } else if (BLE_ATT_CHAR_SERIAL_NB == uuid_disc) { + } + else if (BLE_ATT_CHAR_SERIAL_NB == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_SERIAL_NUM] = handle_disc; - } else if (BLE_ATT_CHAR_FW_REV == uuid_disc) { + } + else if (BLE_ATT_CHAR_FW_REV == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_FW_REV] = handle_disc; - } else if (BLE_ATT_CHAR_HW_REV == uuid_disc) { + } + else if (BLE_ATT_CHAR_HW_REV == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_HW_REV] = handle_disc; - } else if (BLE_ATT_CHAR_SW_REV == uuid_disc) { + } + else if (BLE_ATT_CHAR_SW_REV == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_SW_REV] = handle_disc; - } else if (BLE_ATT_CHAR_MANUF_NAME == uuid_disc) { + } + else if (BLE_ATT_CHAR_MANUF_NAME == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_MANUF_NAME] = handle_disc; - } else if (BLE_ATT_CHAR_IEEE_CERTIF == uuid_disc) { + } + else if (BLE_ATT_CHAR_IEEE_CERTIF == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_CERT_LIST] = handle_disc; - } else if (BLE_ATT_CHAR_PNP_ID == uuid_disc) { + } + else if (BLE_ATT_CHAR_PNP_ID == uuid_disc) + { s_dis_c_env.handles.dis_char_handle[DIS_C_PNP_ID] = handle_disc; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { break; } } @@ -277,39 +276,46 @@ static void dis_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat dis_c_evt_handler_excute(&dis_c_evt); } +static void dis_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + dis_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + dis_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t dis_client_init(dis_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_dis_c_env, sizeof(s_dis_c_env), 0, sizeof(s_dis_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_dis_c_env, 0, sizeof(s_dis_c_env)); s_dis_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&dis_c_prf_info, &s_dis_c_env.prf_id); + return ble_gattc_prf_add(&s_dis_service_uuid, dis_c_ble_evt_handler); } sdk_err_t dis_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - target_uuid[0] = LO_U16(BLE_ATT_SVC_DEVICE_INFO); - target_uuid[1] = HI_U16(BLE_ATT_SVC_DEVICE_INFO); - - const ble_uuid_t dis_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_dis_c_env.prf_id, conn_idx, &dis_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_dis_service_uuid); } sdk_err_t dis_c_char_value_read(uint8_t conn_idx, dis_c_char_type_t char_read_type) @@ -318,10 +324,11 @@ sdk_err_t dis_c_char_value_read(uint8_t conn_idx, dis_c_char_type_t char_read_ty target_handle = s_dis_c_env.handles.dis_char_handle[char_read_type]; - if (BLE_ATT_INVALID_HDL == target_handle) { + if (BLE_ATT_INVALID_HDL == target_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_dis_c_env.prf_id, conn_idx, target_handle, 0); + return ble_gattc_read(conn_idx, target_handle, 0); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.h index 17015ec..2171760 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dis_c/dis_c.h @@ -56,19 +56,18 @@ #ifndef __DIS_C_H__ #define __DIS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup DIS_C_MACRO Defines * @{ */ -#define DIS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of DIS Client connections. */ -#define DIS_C_STRING_LEN_MAX 128 /**< Maximal length for Characteristic values - 128 bytes. */ +#define DIS_C_CONNECTION_MAX 10 /**< Maximum number of DIS Client connections. */ +#define DIS_C_STRING_LEN_MAX 128 /**< Maximal length for Characteristic values - 128 bytes. */ /** * @defgroup DIS_IEEE_11073_BODY IEEE 11073-20601 Authoritative Body Type @@ -87,16 +86,17 @@ * @{ */ /**@brief Device Information Service Client event type. */ -typedef enum { - DIS_C_EVT_INVALID, /**< DIS Client invalid event. */ - DIS_C_EVT_DISCOVERY_COMPLETE, /**< DIS Client has found Device Information Service and its characteristics. */ - DIS_C_EVT_DISCOVERY_FAIL, /**< DIS Client found DIS service failed because of invalid operation or \ - no found at the peer. */ +typedef enum +{ + DIS_C_EVT_INVALID, /**< DIS Client invalid event. */ + DIS_C_EVT_DISCOVERY_COMPLETE, /**< DIS Client has found Device Information Service and its characteristics. */ + DIS_C_EVT_DISCOVERY_FAIL, /**< DIS Client found DIS service failed because of invalid operation or no found at the peer. */ DIS_C_EVT_DEV_INFORMATION_READ_RSP, /**< DIS Client has received device information value read response. */ } dis_c_evt_type_t; /**@brief Device Information Service Client characteristic type. */ -typedef enum { +typedef enum +{ DIS_C_SYS_ID, /**< System ID characteristic. */ DIS_C_MODEL_NUM, /**< Model Number String characteristic. */ DIS_C_SERIAL_NUM, /**< Serial Number String characteristic. */ @@ -115,33 +115,37 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t dis_srvc_start_handle; /**< DIS Serivce start handle. */ uint16_t dis_srvc_end_handle; /**< DIS Service end handle. */ uint16_t dis_char_handle[DIS_C_CHARACTER_NB]; /**< DIS characteristic handle. */ } dis_c_handles_t; /**@brief Response data for string-based DIS characteristics. */ -typedef struct { +typedef struct +{ uint8_t *p_data; /**< Pointer to response data. */ uint16_t length; /**< Response data length. */ } dis_c_string_t; /**@brief Response data for System ID parameters. */ -typedef struct { +typedef struct +{ uint8_t manufacturer_id[5]; /**< Manufacturer-defined ID. */ uint8_t org_unique_id[3]; /**< Organizationally unique ID (OUI) which is issued by IEEE. */ } dis_c_sys_id_t; /**@brief Response data for IEEE 11073-20601 Regulatory Certification Data List Structure. */ -typedef struct { - uint8_t *p_list; /**< Pointer to the list which contains the encoded opaque structure \ - based on IEEE 11073-20601 specification. */ +typedef struct +{ + uint8_t *p_list; /**< Pointer to the list which contains the encoded opaque structure based on IEEE 11073-20601 specification. */ uint16_t list_length; /**< Length of the list. */ } dis_c_reg_cert_data_list_t; /**@brief Response data for PnP ID parameters */ -typedef struct { +typedef struct +{ uint8_t vendor_id_source; /**< Vendor ID Source. */ uint16_t vendor_id; /**< Vendor ID. */ uint16_t product_id; /**< Product ID. */ @@ -149,21 +153,21 @@ typedef struct { } dis_c_pnp_id_t; /**@brief Device Information Service Client Read Response encode structure. */ -typedef struct { +typedef struct +{ dis_c_char_type_t char_type; /**< Characteristic type. */ - union { + union + { dis_c_sys_id_t sys_id; /**< System ID characteristic response data. */ - dis_c_string_t - string_data; /**< Model Number, Serial Number, Hardware Revision, Firmware Revision, Software Revision, \ - Manufacturer Name String characteristic response data. */ - dis_c_reg_cert_data_list_t - cert_list; /**< IEEE 11073-20601 Regulatory Certification Data List characteristic response data. */ + dis_c_string_t string_data; /**< Model Number, Serial Number, Hardware Revision, Firmware Revision, Software Revision, Manufacturer Name String characteristic response data. */ + dis_c_reg_cert_data_list_t cert_list; /**< IEEE 11073-20601 Regulatory Certification Data List characteristic response data. */ dis_c_pnp_id_t pnp_id; /**< PnP ID characteristic response data. */ } encode_rst; /**< Result of encoding. */ } ble_dis_c_read_rsp_t; /**@brief Device Information Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ dis_c_evt_type_t evt_type; /**< DIS Client event type. */ ble_dis_c_read_rsp_t read_rsp; /**< DIS Client characteristic Read Response encode. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/BUILD.gn new file mode 100644 index 0000000..9e19951 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("dss") { + sources = [ "dss.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.c index 6e4ad2d..b7f8db7 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.c @@ -1,7 +1,7 @@ /** ***************************************************************************************** * - * @file dss.c + * @file dss.h * * @brief Device Synchronize Service Implementation. * @@ -10,13 +10,13 @@ #####Copyright (c) 2019 GOODIX All rights reserved. - Redistribution and use in source and binary forms, with or without + Redsstribution 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. + * Redsstributions of source code must retain the above copyright + notice, this list of conditions and the following dssclaimer. + * Redsstributions in binary form must reproduce the above copyright + notice, this list of conditions and the following dssclaimer in the + documentation and/or other materials provided with the dsstribution. * Neither the name of GOODIX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -24,7 +24,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + ARE DSSCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS @@ -51,18 +51,11 @@ ***************************************************************************************** */ /**@brief The UUIDs of DSS service and characteristics. */ -#define DSS_SERVICE_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x01, 0x0A, 0xED, 0xA6} -#define DSS_ROLE_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x02, 0x0A, 0xED, 0xA6} -#define DSS_EVT_CNT_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x03, 0x0A, 0xED, 0xA6} -#define DSS_EVT_PERIOD_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x04, 0x0A, 0xED, 0xA6} -#define DSS_STATUS_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x05, 0x0A, 0xED, 0xA6} -#define DSS_CTRL_PT_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, - 0x06, 0x0A, 0xED, 0xA6} +#define DSS_ROLE_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x0A, 0xED, 0xA6} +#define DSS_EVT_CNT_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x0A, 0xED, 0xA6} +#define DSS_EVT_PERIOD_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x0A, 0xED, 0xA6} +#define DSS_STATUS_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x05, 0x0A, 0xED, 0xA6} +#define DSS_CTRL_PT_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x06, 0x0A, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -74,7 +67,8 @@ ***************************************************************************************** */ /**@brief Device Synchronize Service Attributes database index list. */ -enum dss_attr_idx_t { +enum dss_attr_idx_t +{ DSS_IDX_SVC, DSS_IDX_ROLE_CHAR, @@ -102,35 +96,31 @@ enum dss_attr_idx_t { ***************************************************************************************** */ /**@brief Device Synchronize Service environment variable. */ -struct dss_env_t { - dss_evt_handler_t evt_handler; - uint16_t start_hdl; - uint16_t char_mask; - dss_role_t dss_role; - dss_staus_t sync_status; - uint16_t event_period; - uint32_t sync_cnt; - uint8_t sync_cfg_conn_idx; - bool is_busy_send; - bool is_auto_calib_drift; - bool is_auto_enter_lp; - bool is_in_lp; - uint32_t auto_calib_timing; - uint8_t sync_device_num; - uint16_t evt_cnt_ntf[DSS_CONNECTION_MAX]; - uint16_t ctrl_pt_ind[DSS_CONNECTION_MAX]; +struct dss_env_t +{ + dss_evt_handler_t evt_handler; + uint16_t start_hdl; + uint16_t char_mask; + dss_role_t dss_role; + dss_staus_t sync_status; + uint16_t event_period; + uint32_t sync_cnt; + uint8_t sync_cfg_conn_idx; + bool is_busy_send; + bool is_auto_calib_drift; + bool is_auto_enter_lp; + bool is_in_lp; + uint32_t auto_calib_timing; + uint8_t sync_device_num; + uint16_t evt_cnt_ntf[DSS_CONNECTION_MAX]; + uint16_t ctrl_pt_ind[DSS_CONNECTION_MAX]; + ble_gatts_create_db_t dss_gatts_db; /**< Device Synchronize Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t dss_init(void); -static void dss_disconnect_cb(uint8_t conn_idx, uint8_t reason); -static void dss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void dss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void dss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void dss_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); static void dss_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); static sdk_err_t dss_ctrl_pt_rsp_send(uint8_t conn_idx, dss_op_id_t op_id, dss_rsp_id_t rsp_id); /* @@ -138,129 +128,63 @@ static sdk_err_t dss_ctrl_pt_rsp_send(uint8_t conn_idx, dss_op_id_t op_id, dss_r ***************************************************************************************** */ static struct dss_env_t s_dss_env; +static const uint8_t s_dss_svc_uuid[] = {DSS_SERVICE_UUID}; /**@brief Full DSS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_128_t dss_attr_tab[DSS_IDX_NB] = { - [DSS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, +static const ble_gatts_attm_desc_128_t dss_attr_tab[DSS_IDX_NB] = +{ + [DSS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_ROLE_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_ROLE_VAL] = { - DSS_ROLE_UUID, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - DSS_ROLE_VALUE_LEN - }, + [DSS_IDX_ROLE_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + [DSS_IDX_ROLE_VAL] = {DSS_ROLE_UUID, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + DSS_ROLE_VALUE_LEN}, - [DSS_IDX_SYNC_CNT_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_SYNC_CNT_VAL] = { - DSS_EVT_CNT_UUID, - READ_PERM_UNSEC | NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - DSS_EVT_CNT_VALUE_LEN - }, - [DSS_IDX_SYNC_CNT_CFG] = {ATT_128_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [DSS_IDX_SYNC_CNT_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + [DSS_IDX_SYNC_CNT_VAL] = {DSS_EVT_CNT_UUID, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + DSS_EVT_CNT_VALUE_LEN}, + [DSS_IDX_SYNC_CNT_CFG] = {ATT_128_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, - [DSS_IDX_SYNC_PERIOD_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_SYNC_PERIOD_VAL] = { - DSS_EVT_PERIOD_UUID, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - DSS_EVT_PERIOD_VALUE_LEN - }, + [DSS_IDX_SYNC_PERIOD_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + [DSS_IDX_SYNC_PERIOD_VAL] = {DSS_EVT_PERIOD_UUID, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + DSS_EVT_PERIOD_VALUE_LEN}, - [DSS_IDX_SYNC_STATUS_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_SYNC_STATUS_VAL] = { - DSS_STATUS_UUID, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - DSS_STATUS_VALUE_LEN - }, + [DSS_IDX_SYNC_STATUS_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + [DSS_IDX_SYNC_STATUS_VAL] = {DSS_STATUS_UUID, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + DSS_STATUS_VALUE_LEN}, - [DSS_IDX_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - [DSS_IDX_CTRL_PT_VAL] = { - DSS_CTRL_PT_UUID, - WRITE_REQ_PERM_UNSEC | INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - DSS_CTRL_PT_VALUE_LEN - }, - [DSS_IDX_CTRL_PT_CFG] = {ATT_128_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, -}; - -/**@brief Device Synchronize Service interface required by profile manager. */ -static ble_prf_manager_cbs_t dss_mgr_cbs = { - (prf_init_func_t)dss_init, - NULL, - dss_disconnect_cb -}; - -/**@brief Device Synchronize GATT Server Callbacks. */ -static gatts_prf_cbs_t dss_gatts_cbs = { - dss_read_att_cb, - dss_write_att_cb, - NULL, - dss_ntf_ind_cb, - dss_cccd_set_cb -}; - -/**@brief Device Synchronize Service Information. */ -static const prf_server_info_t dss_prf_info = { - .max_connection_nb = DSS_CONNECTION_MAX, - .manager_cbs = &dss_mgr_cbs, - .gatts_prf_cbs = &dss_gatts_cbs + [DSS_IDX_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + [DSS_IDX_CTRL_PT_VAL] = {DSS_CTRL_PT_UUID, + BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_INDICATE_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + DSS_CTRL_PT_VALUE_LEN}, + [DSS_IDX_CTRL_PT_CFG] = {ATT_128_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Device Synchronize Service and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t dss_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t dss_svc_uuid[] = DSS_SERVICE_UUID; - sdk_err_t error_code = SDK_SUCCESS; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = dss_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_dss_env.char_mask; - gatts_db.max_nb_attr = DSS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = dss_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_dss_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Device Synchronize Service disconnect callback. ***************************************************************************************** */ -static void dss_disconnect_cb(uint8_t conn_idx, uint8_t reason) +static void dss_disconnect_evt_handler(uint8_t conn_idx, uint8_t reason) { s_dss_env.evt_cnt_ntf[conn_idx] = 0x0000; s_dss_env.ctrl_pt_ind[conn_idx] = 0x0000; - if (conn_idx == s_dss_env.sync_cfg_conn_idx) { - s_dss_env.sync_cfg_conn_idx = GAP_INVALID_CONN_INDEX; + if (conn_idx == s_dss_env.sync_cfg_conn_idx) + { + s_dss_env.sync_cfg_conn_idx = BLE_GAP_INVALID_CONN_INDEX; } } @@ -272,9 +196,9 @@ static void dss_disconnect_cb(uint8_t conn_idx, uint8_t reason) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void dss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void dss_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint16_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_dss_env.start_hdl, @@ -283,7 +207,8 @@ static void dss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case DSS_IDX_ROLE_VAL: cfm.length = DSS_ROLE_VALUE_LEN; cfm.value = (uint8_t *)&s_dss_env.dss_role; @@ -332,11 +257,11 @@ static void dss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in] p_param: Point to the parameters of the write request. ***************************************************************************************** */ -static void dss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void dss_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; bool ctrl_pt_evt = false; s_dss_env.sync_cfg_conn_idx = conn_idx; @@ -346,8 +271,9 @@ static void dss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par (uint8_t *)&s_dss_env.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - - switch (tab_index) { + + switch (tab_index) + { case DSS_IDX_SYNC_CNT_CFG: s_dss_env.evt_cnt_ntf[conn_idx] = le16toh(&p_param->value[0]); break; @@ -367,7 +293,8 @@ static void dss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par ble_gatts_write_cfm(conn_idx, &cfm); - if (ctrl_pt_evt) { + if (ctrl_pt_evt) + { dss_ctrl_pt_handler(conn_idx, p_param->value, p_param->length); } } @@ -381,11 +308,12 @@ static void dss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void dss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void dss_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -394,7 +322,8 @@ static void dss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val DSS_IDX_NB, (uint8_t *)&s_dss_env.char_mask); - switch (tab_index) { + switch (tab_index) + { case DSS_IDX_SYNC_CNT_CFG: s_dss_env.evt_cnt_ntf[conn_idx] = cccd_value; break; @@ -417,11 +346,14 @@ static void dss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void dss_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void dss_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { s_dss_env.is_busy_send = false; - } else if (status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + } + else if (status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { s_dss_env.is_busy_send = true; } } @@ -441,11 +373,16 @@ static void dss_op_role_set_handler(uint8_t conn_idx, const uint8_t *p_data, uin dss_rsp_id_t rsp_id = DSS_RSP_ID_SUCCESS; dss_evt_t evt; - if (length != 2 || (p_data[1] != DSS_ROLE_SYNC_SOURCE && p_data[1] != DSS_ROLE_SYNC_DEVICE)) { + if (length != 2 || (p_data[1] != DSS_ROLE_SYNC_SOURCE && p_data[1] != DSS_ROLE_SYNC_DEVICE)) + { rsp_id = DSS_RSP_ID_PARAM_ERR; - } else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) { + } + else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) + { rsp_id = DSS_RSP_ID_STATUS_ERR; - } else { + } + else + { s_dss_env.dss_role = (dss_role_t)p_data[1]; evt.evt_type = s_dss_env.dss_role == DSS_ROLE_SYNC_SOURCE ? DSS_EVT_SOURCE_ROLE_SET : DSS_EVT_DEVICE_ROLE_SET; @@ -470,19 +407,29 @@ static void dss_op_sync_src_create_handler(uint8_t conn_idx, const uint8_t *p_da uint16_t event_period = le16toh(&p_data[1]); dss_evt_t evt; - if (length != 3 || (le16toh(&p_data[1]) < 32) || (le16toh(&p_data[1]) > 3200)) { + if (length != 3 || (320 > le16toh(&p_data[1])) || (3200 < le16toh(&p_data[1]))) + { rsp_id = DSS_RSP_ID_PARAM_ERR; - } else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) { + } + else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) + { rsp_id = DSS_RSP_ID_STATUS_ERR; - } else if (s_dss_env.dss_role != DSS_ROLE_SYNC_SOURCE) { + } + else if (s_dss_env.dss_role != DSS_ROLE_SYNC_SOURCE) + { rsp_id = DSS_RSP_ID_ROLE_ERR; - } else { - if (ble_sync_source_create(event_period)) { - rsp_id = DSS_RSP_ID_CREATE_SRC_FAIL; - } else { + } + else + { + if (ble_sync_source_create(event_period)) + { + rsp_id = DSS_RSP_ID_CREATE_SRC_FAIL; + } + else + { s_dss_env.sync_status = DSS_STATUS_CFG_READY; s_dss_env.event_period = event_period; - + evt.evt_type = DSS_EVT_SYNC_SRC_CREATE; s_dss_env.evt_handler(&evt); } @@ -506,31 +453,45 @@ static void dss_op_sync_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_ dss_rsp_id_t rsp_id = DSS_RSP_ID_SUCCESS; dss_evt_t evt; - if ((op_id != DSS_OP_ID_SYNC) || length != 7 || p_data[6] == 0) { + if ((op_id != DSS_OP_ID_SYNC) || length != 7 || 0 == p_data[6]) + { rsp_id = DSS_RSP_ID_PARAM_ERR; - } else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) { + } + else if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) + { rsp_id = DSS_RSP_ID_STATUS_ERR; - } else if (!s_dss_env.event_period && s_dss_env.dss_role == DSS_ROLE_SYNC_SOURCE) { + } + else if (!s_dss_env.event_period && s_dss_env.dss_role == DSS_ROLE_SYNC_SOURCE) + { rsp_id = DSS_RSP_ID_DISALLOWED; - } else if (s_dss_env.dss_role == DSS_ROLE_SYNC_INVALID) { + } + else if (s_dss_env.dss_role == DSS_ROLE_SYNC_INVALID) + { rsp_id = DSS_RSP_ID_ROLE_ERR; - } else if (!s_dss_env.evt_handler) { + } + else if (!s_dss_env.evt_handler) + { rsp_id = DSS_RSP_ID_NO_HANDLER; - } else { + } + else + { s_dss_env.is_auto_calib_drift = (p_data[1] & 0x01) ? true : false; s_dss_env.is_auto_enter_lp = (p_data[1] & 0x02) ? true : false; s_dss_env.auto_calib_timing = BUILD_U32(p_data[2], p_data[3], p_data[4], p_data[5]); s_dss_env.sync_device_num = p_data[6]; - - if (s_dss_env.is_auto_calib_drift && !s_dss_env.auto_calib_timing) { + + if (s_dss_env.is_auto_calib_drift && !s_dss_env.auto_calib_timing) + { s_dss_env.is_auto_calib_drift = false; - s_dss_env.is_auto_enter_lp = false; + s_dss_env.is_auto_enter_lp = false; rsp_id = DSS_RSP_ID_PARAM_ERR; - } else { + } + else + { s_dss_env.is_in_lp = false; s_dss_env.sync_status = s_dss_env.dss_role == DSS_ROLE_SYNC_SOURCE ? DSS_STATUS_IN_SCAN : DSS_STATUS_IN_ADV; - + evt.conn_idx = conn_idx; evt.evt_type = DSS_EVT_SYNC_SELF_OR_PEER; evt.is_enter_lp_mode = s_dss_env.is_auto_enter_lp; @@ -539,7 +500,8 @@ static void dss_op_sync_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_ } } - if (rsp_id) { + if (rsp_id) + { dss_ctrl_pt_rsp_send(conn_idx, op_id, rsp_id); } } @@ -557,17 +519,23 @@ static void dss_op_cancel_sync_handler(uint8_t conn_idx) dss_evt_t evt; if (((s_dss_env.sync_status != DSS_STATUS_IN_SCAN) && (DSS_ROLE_SYNC_SOURCE == s_dss_env.dss_role)) || - ((s_dss_env.sync_status != DSS_STATUS_IN_ADV) && (DSS_ROLE_SYNC_DEVICE == s_dss_env.dss_role))) { + ((s_dss_env.sync_status != DSS_STATUS_IN_ADV) && (DSS_ROLE_SYNC_DEVICE == s_dss_env.dss_role))) + { rsp_id = DSS_RSP_ID_STATUS_ERR; - } else if (s_dss_env.evt_handler == NULL) { + } + else if (NULL == s_dss_env.evt_handler) + { rsp_id = DSS_RSP_ID_NO_HANDLER; - } else { + } + else + { evt.conn_idx = conn_idx; evt.evt_type = DSS_EVT_SYNC_CANCEL; s_dss_env.evt_handler(&evt); } - if (rsp_id) { + if (rsp_id) + { dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_CANCEL_SYNC, rsp_id); } } @@ -584,11 +552,17 @@ static void dss_op_lp_enter_handler(uint8_t conn_idx) dss_rsp_id_t rsp_id = DSS_RSP_ID_SUCCESS; dss_evt_t evt; - if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) { + if (s_dss_env.sync_status != DSS_STATUS_CFG_READY) + { rsp_id = DSS_RSP_ID_STATUS_ERR; - } else if (s_dss_env.evt_handler == NULL) { + } + else if (NULL == s_dss_env.evt_handler) + { rsp_id = DSS_RSP_ID_NO_HANDLER; - } else { + } + else + { +// s_dss_env.is_in_lp = true; s_dss_env.is_auto_enter_lp = true; s_dss_env.sync_status = DSS_STATUS_CFG_READY; @@ -600,7 +574,8 @@ static void dss_op_lp_enter_handler(uint8_t conn_idx) s_dss_env.evt_handler(&evt); } - if (rsp_id) { + if (rsp_id) + { dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_LP_ENTER, rsp_id); } } @@ -617,11 +592,16 @@ static void dss_op_sync_destroy_handler(uint8_t conn_idx) dss_rsp_id_t rsp_id = DSS_RSP_ID_SUCCESS; dss_evt_t evt; - if (s_dss_env.dss_role == DSS_ROLE_SYNC_INVALID) { + if (s_dss_env.dss_role == DSS_ROLE_SYNC_INVALID) + { rsp_id = DSS_RSP_ID_ROLE_ERR; - } else if (ble_sync_source_destroy()) { + } + else if (ble_sync_source_destroy()) + { rsp_id = DSS_RSP_ID_DESTROY_SRC_FAIL; - } else { + } + else + { s_dss_env.sync_status = DSS_STATUS_CFG_READY; s_dss_env.is_in_lp = false; s_dss_env.is_auto_enter_lp = false; @@ -629,13 +609,14 @@ static void dss_op_sync_destroy_handler(uint8_t conn_idx) s_dss_env.event_period = 0; s_dss_env.sync_cnt = 0; s_dss_env.sync_device_num = 0; - + evt.conn_idx = conn_idx; evt.evt_type = DSS_EVT_SYNC_DESTROY; s_dss_env.evt_handler(&evt); } - - if (rsp_id) { + + if (rsp_id) + { dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_SYNC_DESTROY, rsp_id); } } @@ -653,16 +634,16 @@ static sdk_err_t dss_ctrl_pt_rsp_send(uint8_t conn_idx, dss_op_id_t op_id, dss_r { sdk_err_t error_code = SDK_ERR_IND_DISABLED; uint8_t rsp[DSS_CTRL_PT_RSP_VAL_LEN] = {0}; - gatts_noti_ind_t rsp_ind; + ble_gatts_noti_ind_t rsp_ind; rsp[0] = DSS_OP_ID_RSP; rsp[1] = op_id; rsp[2] = rsp_id; - if (s_dss_env.ctrl_pt_ind[conn_idx] == PRF_CLI_START_IND) { + if (s_dss_env.ctrl_pt_ind[conn_idx] == PRF_CLI_START_IND) + { rsp_ind.type = BLE_GATT_INDICATION; - rsp_ind.handle = prf_find_handle_by_idx(DSS_IDX_CTRL_PT_VAL, s_dss_env.start_hdl, - (uint8_t *)&s_dss_env.char_mask); + rsp_ind.handle = prf_find_handle_by_idx(DSS_IDX_CTRL_PT_VAL, s_dss_env.start_hdl, (uint8_t *)&s_dss_env.char_mask); rsp_ind.length = DSS_CTRL_PT_RSP_VAL_LEN; rsp_ind.value = rsp; @@ -683,7 +664,8 @@ static sdk_err_t dss_ctrl_pt_rsp_send(uint8_t conn_idx, dss_op_id_t op_id, dss_r */ static void dss_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length) { - switch (p_data[0]) { + switch(p_data[0]) + { case DSS_OP_ID_ROLE_SET: dss_op_role_set_handler(conn_idx, p_data, length); break; @@ -703,7 +685,7 @@ static void dss_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_ case DSS_OP_ID_SYNC_DESTROY: dss_op_sync_destroy_handler(conn_idx); break; - + case DSS_OP_ID_CANCEL_SYNC: dss_op_cancel_sync_handler(conn_idx); break; @@ -717,46 +699,52 @@ static void dss_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_ static void dss_sync_evt_cb(uint32_t sync_cnt, uint16_t event_period) { - gatts_noti_ind_t send_ntf; + ble_gatts_noti_ind_t send_ntf; sdk_err_t error_code = SDK_ERR_NTF_DISABLED; dss_evt_t evt; - if (s_dss_env.evt_handler == NULL) { + if (NULL == s_dss_env.evt_handler) + { return; } evt.evt_type = DSS_EVT_INVALID; - evt.conn_idx = GAP_INVALID_CONN_INDEX; + evt.conn_idx = BLE_GAP_INVALID_CONN_INDEX; evt.evt_type = DSS_EVT_SYNC_OCCUR; evt.sync_cnt = sync_cnt; s_dss_env.evt_handler(&evt); - if (!s_dss_env.is_in_lp && s_dss_env.is_auto_enter_lp && s_dss_env.evt_handler) { + if (!s_dss_env.is_in_lp && s_dss_env.is_auto_enter_lp && s_dss_env.evt_handler) + { evt.evt_type = DSS_EVT_LP_ENTER; evt.is_enter_lp_mode = true; s_dss_env.evt_handler(&evt); } - if (s_dss_env.is_auto_calib_drift && !(sync_cnt % s_dss_env.auto_calib_timing)) { - evt.sync_dev_num = s_dss_env.sync_device_num; + if (s_dss_env.is_auto_calib_drift && !(sync_cnt % s_dss_env.auto_calib_timing)) + { + evt.sync_dev_num = s_dss_env.sync_device_num; evt.evt_type = DSS_EVT_SYNC_SELF_OR_PEER; evt.is_enter_lp_mode = s_dss_env.is_auto_enter_lp; s_dss_env.sync_status = s_dss_env.dss_role == DSS_ROLE_SYNC_DEVICE ? DSS_STATUS_IN_ADV : DSS_STATUS_IN_SCAN; s_dss_env.evt_handler(&evt); s_dss_env.is_in_lp = false; - } else { + } + else + { s_dss_env.sync_cnt = sync_cnt; s_dss_env.event_period = event_period; - if (!s_dss_env.is_busy_send) { - if (s_dss_env.evt_cnt_ntf[s_dss_env.sync_cfg_conn_idx] == PRF_CLI_START_NTF) { + if (!s_dss_env.is_busy_send) + { + if (s_dss_env.evt_cnt_ntf[s_dss_env.sync_cfg_conn_idx] == PRF_CLI_START_NTF) + { send_ntf.type = BLE_GATT_NOTIFICATION; - send_ntf.handle = prf_find_handle_by_idx(DSS_IDX_SYNC_CNT_VAL, s_dss_env.start_hdl, - (uint8_t *)&s_dss_env.char_mask); + send_ntf.handle = prf_find_handle_by_idx(DSS_IDX_SYNC_CNT_VAL, s_dss_env.start_hdl, (uint8_t *)&s_dss_env.char_mask); send_ntf.length = DSS_EVT_CNT_VALUE_LEN; send_ntf.value = (uint8_t *)&s_dss_env.sync_cnt; @@ -767,13 +755,45 @@ static void dss_sync_evt_cb(uint32_t sync_cnt, uint16_t event_period) } } +static void dss_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + dss_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + dss_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + dss_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + dss_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + dss_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t dss_service_init(dss_evt_handler_t evt_handler) { - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } @@ -792,20 +812,39 @@ sdk_err_t dss_service_init(dss_evt_handler_t evt_handler) s_dss_env.sync_device_num = 0; s_dss_env.sync_cnt = 0; - return ble_server_prf_add(&dss_prf_info); + s_dss_env.start_hdl = PRF_INVALID_HANDLE; + + s_dss_env.dss_gatts_db.shdl = &s_dss_env.start_hdl; + s_dss_env.dss_gatts_db.uuid = s_dss_svc_uuid; + s_dss_env.dss_gatts_db.attr_tab_cfg = (uint8_t *)&(s_dss_env.char_mask); + s_dss_env.dss_gatts_db.max_nb_attr = DSS_IDX_NB; + s_dss_env.dss_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_dss_env.dss_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_dss_env.dss_gatts_db.attr_tab.attr_tab_128 = dss_attr_tab; + + return ble_gatts_prf_add(&s_dss_env.dss_gatts_db, dss_ble_evt_handler); } sdk_err_t dss_sync_op_result_send(uint8_t conn_idx, dss_evt_type_t evt_type, dss_rsp_id_t rsp_id) { - if (evt_type == DSS_EVT_SYNC_SELF_OR_PEER) { + if (evt_type == DSS_EVT_SYNC_SELF_OR_PEER) + { return dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_SYNC, rsp_id); - } else if (evt_type == DSS_EVT_SYNC_CANCEL) { + } + else if (evt_type == DSS_EVT_SYNC_CANCEL) + { return dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_CANCEL_SYNC, rsp_id); - } else if (evt_type == DSS_EVT_LP_ENTER) { + } + else if (evt_type == DSS_EVT_LP_ENTER) + { return dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_LP_ENTER, rsp_id); - } else if (evt_type == DSS_EVT_SYNC_DESTROY) { + } + else if (evt_type == DSS_EVT_SYNC_DESTROY) + { return dss_ctrl_pt_rsp_send(conn_idx, DSS_OP_ID_SYNC_DESTROY, rsp_id); - } else { + } + else + { return SDK_ERR_INVALID_PARAM; } } @@ -832,7 +871,8 @@ void dss_sync_src_distribute(uint8_t conn_idx) dss_op_id_t op_id; dss_rsp_id_t rsp_id = DSS_RSP_ID_SUCCESS; - if (DSS_ROLE_SYNC_SOURCE == s_dss_env.dss_role && ble_sync_source_distribute(conn_idx)) { + if (DSS_ROLE_SYNC_SOURCE == s_dss_env.dss_role && ble_sync_source_distribute(conn_idx)) + { rsp_id = DSS_RSP_ID_DISTR_SRC_FAIL; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.h index fa67042..0c36cdf 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/dss/dss.h @@ -59,26 +59,28 @@ #ifndef __DSS_H__ #define __DSS_H__ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup DSS_MACRO Defines * @{ */ -#define DSS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of DSS connections. */ -#define DSS_ROLE_VALUE_LEN 1 /**< Length of Role characteristic value. */ -#define DSS_EVT_CNT_VALUE_LEN 4 /**< Length of Event Count characteristic value. */ -#define DSS_EVT_PERIOD_VALUE_LEN 2 /**< Length of Event Period characteristic value. */ -#define DSS_STATUS_VALUE_LEN 1 /**< Length of Status characteristic value. */ -#define DSS_CTRL_PT_VALUE_LEN 7 /**< Length of Control Point characteristic value. */ -#define DSS_CTRL_PT_RSP_VAL_LEN 3 /**< Length of Control Point Response characteristic value. */ +#define DSS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x0A, 0xED, 0xA6 /**< DSS service UUID. */ -#define DSS_SYNC_DEV_MAX_NUM 5 /**< Maximun num of Source Sync Device. */ -#define DSS_CFG_ADV_IDX 0 /**< DSS Config Advertising Index. */ -#define DSS_SYNC_ADV_IDX 1 /**< DSS Sync Advertising Index. */ +#define DSS_CONNECTION_MAX 10 /**< Maximum number of DSS connections. */ +#define DSS_ROLE_VALUE_LEN 1 /**< Length of Role characteristic value. */ +#define DSS_EVT_CNT_VALUE_LEN 4 /**< Length of Event Count characteristic value. */ +#define DSS_EVT_PERIOD_VALUE_LEN 2 /**< Length of Event Period characteristic value. */ +#define DSS_STATUS_VALUE_LEN 1 /**< Length of Status characteristic value. */ +#define DSS_CTRL_PT_VALUE_LEN 7 /**< Length of Control Point characteristic value. */ +#define DSS_CTRL_PT_RSP_VAL_LEN 3 /**< Length of Control Point Response characteristic value. */ + +#define DSS_SYNC_DEV_MAX_NUM 5 /**< Maximun num of Source Sync Device. */ +#define DSS_CFG_ADV_IDX 0 /**< DSS Config Advertising Index. */ +#define DSS_SYNC_ADV_IDX 1 /**< DSS Sync Advertising Index. */ /** @} */ /** @@ -86,14 +88,16 @@ * @{ */ /**@brief Device Synchronize Service roles. */ -typedef enum { +typedef enum +{ DSS_ROLE_SYNC_INVALID, /**< Device synchronize invalid role. */ DSS_ROLE_SYNC_SOURCE, /**< Device synchronize source role (Create synchronize source and distribute). */ DSS_ROLE_SYNC_DEVICE, /**< Device synchronize deivce role. */ } dss_role_t; /**@brief Device Synchronize Service status. */ -typedef enum { +typedef enum +{ DSS_STATUS_CFG_READY, /**< Device is ready for config, */ DSS_STATUS_IN_ADV, /**< Device is in advertising. */ DSS_STATUS_IN_SCAN, /**< Device is in scanning. */ @@ -101,7 +105,8 @@ typedef enum { } dss_staus_t; /**@brief Device Synchronize Service control point OP IDs. */ -typedef enum { +typedef enum +{ DSS_OP_ID_INVALID, /**< Invalid op id. */ DSS_OP_ID_ROLE_SET, /**< Set role op id.*/ DSS_OP_ID_SYNC_SRC_CREATE, /**< Create synchronize source op id. */ @@ -113,7 +118,8 @@ typedef enum { } dss_op_id_t; /**@brief Device Synchronize Service control point response IDs. */ -typedef enum { +typedef enum +{ DSS_RSP_ID_SUCCESS, /**< Success. */ DSS_RSP_ID_UNSUPPORT, /**< Unsupport op. */ DSS_RSP_ID_DISALLOWED, /**< Disallowed op. */ @@ -135,7 +141,8 @@ typedef enum { /**@brief Device Synchronize Service event types. */ -typedef enum { +typedef enum +{ DSS_EVT_INVALID, /**< Invalid event. */ DSS_EVT_SOURCE_ROLE_SET, /**< Source Role set event. */ DSS_EVT_DEVICE_ROLE_SET, /**< Device Role set event. */ @@ -153,7 +160,8 @@ typedef enum { * @{ */ /**@brief Device Synchronize Service Synchronize event. */ -typedef struct { +typedef struct +{ dss_evt_type_t evt_type; /**< Event type. */ uint8_t conn_idx; /**< Connect index. */ uint32_t sync_cnt; /**< Synchronize count. */ @@ -224,7 +232,7 @@ void dss_set_status(uint8_t conn_idx, dss_staus_t status); * * @param[in] conn_idx: Connection index. * @param[in] is_auto_enter_lp: Auto enter low power mode flag. - * @param[in] is_auto_calib_drift: Auto calibration drift flag. + * @param[in] is_auto_calib_drift: Auto calibration drift flag. ***************************************************************************************** */ void dss_set_sync_params(uint8_t conn_idx, bool is_auto_enter_lp, bool is_auto_calib_drift); @@ -234,7 +242,7 @@ void dss_set_sync_params(uint8_t conn_idx, bool is_auto_enter_lp, bool is_auto_c * @brief Set Device whether in low power mode. * * @param[in] conn_idx: Connection index. - * @param[in] is_in_lp_mode: Is Device in low power mode. + * @param[in] is_in_lp_mode: Is Device in low power mode. ***************************************************************************************** */ void dss_set_lp_mode(uint8_t conn_idx, bool is_in_lp_mode); diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/BUILD.gn new file mode 100644 index 0000000..8ae5b5c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("gls") { + sources = [ + "gls.c", + "gls_db.c", + "gls_racp.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.c index 8a58b43..560e05f 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.c @@ -47,15 +47,13 @@ #include "utility.h" #include "app_log.h" -#define XPONENT_OFFSET 12 -#define ENCODE_OFFSET 8 -#define LOCATION_OFFSET 4 /* * ENUMERATIONS **************************************************************************************** */ /**@brief Glucose Service Attributes Indexes. */ -enum { +enum +{ // Glucose Service GLS_IDX_SVC, @@ -86,40 +84,28 @@ enum { ***************************************************************************************** */ /**@brief Glucose Service environment variable. */ -struct gls_env_t { - gls_init_t gls_init; /**< Glucose Service initialization variables. */ - uint16_t start_hdl; /**< Glucose Service start handle. */ - uint16_t next_seq_num; /**< Sequence number of the next database record. */ - uint8_t proc_record_idx; /**< Current record index. */ - uint16_t proc_record_seq_num; /**< Sequence number of current request. */ - uint16_t proc_records_reported; /**< Number of reported records. */ - bool is_record_continue_send; /**< State for continue send record. */ - bool - racp_in_progress; /**< A previously triggered Control Point operation is still in progress. */ - uint8_t - ntf_mask; /**< Mask for measurement notify or measurement context notify. */ - gls_racp_req_t racp_req; /**< Buffer saved current RACP request decode result. */ - uint16_t - meas_ntf_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Glucose Measurement Notification - which is configured by the peer devices. */ - uint16_t - meas_ctx_ntf_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Glucose Measurement - Context Notification which is configured by the peer devices. */ - uint16_t - racp_ind_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Record Access Control Point Indication - which is configured by the peer devices. */ +struct gls_env_t +{ + gls_init_t gls_init; /**< Glucose Service initialization variables. */ + uint16_t start_hdl; /**< Glucose Service start handle. */ + uint16_t next_seq_num; /**< Sequence number of the next database record. */ + uint8_t proc_record_idx; /**< Current record index. */ + uint16_t proc_record_seq_num; /**< Sequence number of current request. */ + uint16_t proc_records_reported; /**< Number of reported records. */ + bool is_record_continue_send; /**< State for continue send record. */ + bool racp_in_progress; /**< A previously triggered Control Point operation is still in progress. */ + uint8_t ntf_mask; /**< Mask for measurement notify or measurement context notify. */ + gls_racp_req_t racp_req; /**< Buffer saved current RACP request decode result. */ + uint16_t meas_ntf_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Glucose Measurement Notification which is configured by the peer devices. */ + uint16_t meas_ctx_ntf_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Glucose Measurement Context Notification which is configured by the peer devices. */ + uint16_t racp_ind_cfg[GLS_CONNECTION_MAX]; /**< The configuration of Record Access Control Point Indication which is configured by the peer devices. */ + ble_gatts_create_db_t gls_gatts_db; /**< Glucose Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION **************************************************************************************** */ -static sdk_err_t gls_init(void); -static void gls_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void gls_write_att_cb(uint8_t conidx, const gatts_write_req_cb_t *p_param); -static void gls_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void gls_disconnect_cb(uint8_t conn_idx, uint8_t reason); -static void gls_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); static void gls_receive_racp_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); static bool gls_are_meas_racp_cccd_configured(uint8_t conn_idx); static sdk_err_t gls_meas_val_send(uint8_t conn_idx, gls_rec_t *p_rec); @@ -129,137 +115,63 @@ static sdk_err_t gls_meas_val_send(uint8_t conn_idx, gls_rec_t *p_rec); **************************************************************************************** */ static struct gls_env_t s_gls_env; +static const uint8_t s_gls_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_GLUCOSE); /**@brief Full GLS Database Description - Used to add attributes into the database. */ -static const attm_desc_t gls_attr_tab[GLS_IDX_NB] = { +static const ble_gatts_attm_desc_t gls_attr_tab[GLS_IDX_NB] = +{ // Glucose Service Declaration - [GLS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [GLS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Glucose Measurement Characteristic Declaration - [GLS_IDX_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GLS_IDX_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Glucose Measurement Characteristic Value - [GLS_IDX_MEAS_VAL] = { - BLE_ATT_CHAR_GLUCOSE_MEAS, NOTIFY_PERM(AUTH), - ATT_VAL_LOC_USER, GLS_MEAS_VAL_LEN_MAX - }, + [GLS_IDX_MEAS_VAL] = {BLE_ATT_CHAR_GLUCOSE_MEAS, BLE_GATTS_NOTIFY_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, GLS_MEAS_VAL_LEN_MAX}, // Glucose Measurement Characteristic - Client Characteristic Configuration Descriptor - [GLS_IDX_MEAS_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM(AUTH) | WRITE_REQ_PERM(AUTH), - 0, 0 - }, + [GLS_IDX_MEAS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_AUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_AUTH), + 0, 0}, // Glucose Measurement Context Characteristic Declaration - [GLS_IDX_MEAS_CTX_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GLS_IDX_MEAS_CTX_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Glucose Measurement Context Characteristic Value - [GLS_IDX_MEAS_CTX_VAL] = { - BLE_ATT_CHAR_GLUCOSE_MEAS_CTX, NOTIFY_PERM(AUTH), - ATT_VAL_LOC_USER, GLS_MEAS_CTX_LEN_MAX - }, + [GLS_IDX_MEAS_CTX_VAL] = {BLE_ATT_CHAR_GLUCOSE_MEAS_CTX, BLE_GATTS_NOTIFY_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, GLS_MEAS_CTX_LEN_MAX}, // Glucose Measurement Context Characteristic - Client Characteristic Configuration Descriptor - [GLS_IDX_MEAS_CTX_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM(AUTH) | WRITE_REQ_PERM(AUTH), - 0, 0 - }, + [GLS_IDX_MEAS_CTX_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_AUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_AUTH), + 0, 0}, // Glucose Features Characteristic Declaration - [GLS_IDX_FEATURE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GLS_IDX_FEATURE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Glucose Features Characteristic Value #if defined(PTS_AUTO_TEST) - [GLS_IDX_FEATURE_VAL] = { - BLE_ATT_CHAR_GLUCOSE_FEATURE, READ_PERM_UNSEC, - ATT_VAL_LOC_USER, sizeof(uint16_t) - }, + [GLS_IDX_FEATURE_VAL] = {BLE_ATT_CHAR_GLUCOSE_FEATURE, BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(uint16_t)}, #else - [GLS_IDX_FEATURE_VAL] = { - BLE_ATT_CHAR_GLUCOSE_FEATURE, READ_PERM(AUTH), - ATT_VAL_LOC_USER, sizeof(uint16_t) - }, + [GLS_IDX_FEATURE_VAL] = {BLE_ATT_CHAR_GLUCOSE_FEATURE, BLE_GATTS_READ_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(uint16_t)}, #endif // Record Access Control Point characteristic Declaration - [GLS_IDX_REC_ACCESS_CTRL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GLS_IDX_REC_ACCESS_CTRL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Record Access Control Point characteristic Value - [GLS_IDX_REC_ACCESS_CTRL_VAL] = { - BLE_ATT_CHAR_REC_ACCESS_CTRL_PT, - INDICATE_PERM_UNSEC | WRITE_REQ_PERM(AUTH), - ATT_VAL_LOC_USER, - GLS_REC_ACCESS_CTRL_LEN_MAX - }, + [GLS_IDX_REC_ACCESS_CTRL_VAL] = {BLE_ATT_CHAR_REC_ACCESS_CTRL_PT, + BLE_GATTS_INDICATE_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + GLS_REC_ACCESS_CTRL_LEN_MAX}, // Record Access Control Point characteristic - Client Characteristic Configuration Descriptor - [GLS_IDX_REC_ACCESS_CTRL_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM(AUTH) | WRITE_REQ_PERM(AUTH), - 0, 0 - }, + [GLS_IDX_REC_ACCESS_CTRL_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_AUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_AUTH), + 0, 0}, }; -/**@brief GLS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t gls_tack_cbs = { - (prf_init_func_t) gls_init, - NULL, - gls_disconnect_cb -}; - -/**@brief GLS Task Callbacks. */ -static gatts_prf_cbs_t gls_cb_func = { - gls_read_att_cb, - gls_write_att_cb, - NULL, - gls_gatts_ntf_ind_cb, - gls_cccd_set_cb -}; - -/**@brief GLS Information. */ -static const prf_server_info_t gls_prf_info = { - .max_connection_nb = GLS_CONNECTION_MAX, - .manager_cbs = &gls_tack_cbs, - .gatts_prf_cbs = &gls_cb_func -}; - /* * LOCAL FUNCTION DEFINITIONS **************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Glucose Service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t gls_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t gls_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_GLUCOSE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - sdk_err_t error_code; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = gls_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_gls_env.gls_init.char_mask); - gatts_db.max_nb_attr = GLS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = gls_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_gls_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -268,9 +180,9 @@ static sdk_err_t gls_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void gls_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void gls_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_gls_env.start_hdl, @@ -279,7 +191,8 @@ static void gls_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case GLS_IDX_MEAS_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_gls_env.meas_ntf_cfg[conn_idx]; @@ -317,64 +230,78 @@ static void gls_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void gls_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void gls_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; bool racp_evt = false; gls_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; - tab_index = prf_find_idx_by_handle(handle, s_gls_env.start_hdl, - GLS_IDX_NB, (uint8_t *)&s_gls_env.gls_init.char_mask); + tab_index = prf_find_idx_by_handle(handle, + s_gls_env.start_hdl, + GLS_IDX_NB, + (uint8_t *)&s_gls_env.gls_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; event.evt_type = GLS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case GLS_IDX_MEAS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ - GLS_EVT_MEAS_NOTIFICATION_ENABLED : GLS_EVT_MEAS_NOTIFICATION_DISABLED); + GLS_EVT_MEAS_NOTIFICATION_ENABLED : \ + GLS_EVT_MEAS_NOTIFICATION_DISABLED); s_gls_env.meas_ntf_cfg[conn_idx] = cccd_value; break; case GLS_IDX_MEAS_CTX_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ - GLS_EVT_CTX_NOTIFICATION_ENABLED : GLS_EVT_CTX_NOTIFICATION_DISABLED); + GLS_EVT_CTX_NOTIFICATION_ENABLED : \ + GLS_EVT_CTX_NOTIFICATION_DISABLED); s_gls_env.meas_ctx_ntf_cfg[conn_idx] = cccd_value; break; case GLS_IDX_REC_ACCESS_CTRL_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ? \ - GLS_EVT_CTRL_INDICATION_ENABLED : GLS_EVT_CTRL_INDICATION_DISABLED); + GLS_EVT_CTRL_INDICATION_ENABLED : \ + GLS_EVT_CTRL_INDICATION_DISABLED); s_gls_env.racp_ind_cfg[conn_idx] = cccd_value; break; case GLS_IDX_REC_ACCESS_CTRL_VAL: - if (!gls_are_meas_racp_cccd_configured(conn_idx)) { + if (!gls_are_meas_racp_cccd_configured(conn_idx)) + { cfm.status = GLS_ERROR_CCCD_INVALID; - } else if (s_gls_env.racp_in_progress && GLS_RACP_OP_ABORT_OP != p_param->value[0]) { + } + else if (s_gls_env.racp_in_progress && GLS_RACP_OP_ABORT_OP != p_param->value[0]) + { cfm.status = GLS_ERROR_PROC_IN_PROCESS; - } else { + } + else + { racp_evt = true; } break; + default: cfm.status = BLE_ATT_ERR_INVALID_HANDLE; break; } ble_gatts_write_cfm(conn_idx, &cfm); - if (racp_evt) { + + if (racp_evt) + { gls_receive_racp_handler(conn_idx, p_param->value, p_param->length); } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && - GLS_EVT_INVALID != event.evt_type && s_gls_env.gls_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && GLS_EVT_INVALID != event.evt_type && s_gls_env.gls_init.evt_handler) + { s_gls_env.gls_init.evt_handler(&event); } } @@ -388,12 +315,13 @@ static void gls_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void gls_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void gls_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; gls_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -405,7 +333,8 @@ static void gls_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = GLS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case GLS_IDX_MEAS_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ GLS_EVT_MEAS_NOTIFICATION_ENABLED : \ @@ -431,7 +360,8 @@ static void gls_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (GLS_EVT_INVALID != event.evt_type && s_gls_env.gls_init.evt_handler) { + if (GLS_EVT_INVALID != event.evt_type && s_gls_env.gls_init.evt_handler) + { s_gls_env.gls_init.evt_handler(&event); } } @@ -444,7 +374,7 @@ static void gls_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] reason: Reason of disconnection. ***************************************************************************************** */ -static void gls_disconnect_cb(uint8_t conn_idx, uint8_t reason) +static void gls_disconnect_evt_handler(uint8_t conn_idx, uint8_t reason) { s_gls_env.racp_in_progress = false; } @@ -461,9 +391,12 @@ static void gls_disconnect_cb(uint8_t conn_idx, uint8_t reason) static bool gls_are_meas_racp_cccd_configured(uint8_t conn_idx) { if ((PRF_CLI_STOP_NTFIND == s_gls_env.meas_ntf_cfg[conn_idx]) || \ - (PRF_CLI_STOP_NTFIND == s_gls_env.racp_ind_cfg[conn_idx])) { + (PRF_CLI_STOP_NTFIND == s_gls_env.racp_ind_cfg[conn_idx])) + { return false; - } else { + } + else + { return true; } } @@ -481,13 +414,20 @@ static bool gls_next_sequence_num_set(void) gls_rec_t gls_res; records_num = gls_db_records_num_get(); - if (records_num > 0) { - if (gls_db_record_get(records_num - 1, &gls_res)) { + + if (0 < records_num) + { + if (gls_db_record_get(records_num - 1, &gls_res)) + { s_gls_env.next_seq_num = gls_res.meas_val.sequence_number + 1; - } else { + } + else + { return false; } - } else { + } + else + { s_gls_env.next_seq_num = 0; } @@ -506,19 +446,18 @@ static void gls_report_records_completed(uint8_t conn_idx) gls_racp_rsp_t racp_rsp; uint8_t encoded_racp_rsp[GLS_REC_ACCESS_CTRL_LEN_MAX]; uint16_t encode_length; - uint8_t ret; - ret = memset_s(&racp_rsp, sizeof(gls_racp_rsp_t), 0, sizeof(gls_racp_rsp_t)); - if (ret < 0) { - return; - } + memset(&racp_rsp, 0, sizeof(gls_racp_rsp_t)); racp_rsp.op_code = GLS_RACP_OP_RSP_CODE; racp_rsp.operand.rsp.op_code_req = GLS_RACP_OP_REP_STRD_RECS; - if (s_gls_env.proc_records_reported) { + if (s_gls_env.proc_records_reported) + { racp_rsp.operand.rsp.status = GLS_RACP_RSP_SUCCESS; - } else { + } + else + { racp_rsp.operand.rsp.status = GLS_RACP_RSP_NO_RECS_FOUND; } @@ -540,11 +479,15 @@ static void gls_all_records_report(uint8_t conn_idx, gls_racp_req_t *p_racp_req) gls_rec_t gls_res; records_num = gls_db_records_num_get(); - if (s_gls_env.proc_record_idx >= records_num) { + + if (s_gls_env.proc_record_idx >= records_num) + { s_gls_env.is_record_continue_send = false; s_gls_env.racp_in_progress = false; gls_report_records_completed(conn_idx); - } else if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) { + } + else if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) + { s_gls_env.is_record_continue_send = true; gls_meas_val_send(conn_idx, &gls_res); } @@ -565,16 +508,21 @@ static void gls_less_or_equal_records_report(uint8_t conn_idx, gls_racp_req_t *p records_num = gls_db_records_num_get(); - while (s_gls_env.proc_record_idx < records_num) { - if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) { - if (s_gls_env.proc_record_seq_num >= gls_res.meas_val.sequence_number) { + while (s_gls_env.proc_record_idx < records_num) + { + if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) + { + if (s_gls_env.proc_record_seq_num >= gls_res.meas_val.sequence_number) + { s_gls_env.is_record_continue_send = true; gls_meas_val_send(conn_idx, &gls_res); return; } s_gls_env.proc_record_idx++; - } else { + } + else + { break; } }; @@ -599,16 +547,21 @@ static void gls_greater_or_equal_records_report(uint8_t conn_idx, gls_racp_req_t records_num = gls_db_records_num_get(); - while (s_gls_env.proc_record_idx < records_num) { - if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) { - if (s_gls_env.proc_record_seq_num <= gls_res.meas_val.sequence_number) { + while (s_gls_env.proc_record_idx < records_num) + { + if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) + { + if (s_gls_env.proc_record_seq_num <= gls_res.meas_val.sequence_number) + { s_gls_env.is_record_continue_send = true; gls_meas_val_send(conn_idx, &gls_res); return; } s_gls_env.proc_record_idx++; - } else { + } + else + { break; } }; @@ -633,29 +586,36 @@ static void gls_within_range_of_records_report(uint8_t conn_idx, gls_racp_req_t records_num = gls_db_records_num_get(); - while (s_gls_env.proc_record_idx < records_num) { - if (!gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) { + while (s_gls_env.proc_record_idx < records_num) + { + if (gls_db_record_get(s_gls_env.proc_record_idx, &gls_res)) + { + if (GLS_RACP_FILTER_SEQ_NUMBER == p_racp_req->filter.racp_filter_type) + { + if ((gls_res.meas_val.sequence_number >= s_gls_env.racp_req.filter.val.seq_num.min) && \ + (gls_res.meas_val.sequence_number <= s_gls_env.racp_req.filter.val.seq_num.max)) + { + s_gls_env.is_record_continue_send = true; + gls_meas_val_send(conn_idx, &gls_res); + return; + } + } + else if (GLS_RACP_FILTER_USER_FACING_TIME == p_racp_req->filter.racp_filter_type) + { + if ( !(-1 == gls_racp_user_time_compare(&gls_res.meas_val.base_time, &s_gls_env.racp_req.filter.val.time.min)) && \ + !(-1 == gls_racp_user_time_compare(&s_gls_env.racp_req.filter.val.time.max, &gls_res.meas_val.base_time))) + { + s_gls_env.is_record_continue_send = true; + gls_meas_val_send(conn_idx, &gls_res); + break; + } + } + s_gls_env.proc_record_idx++; + } + else + { break; } - - if (GLS_RACP_FILTER_SEQ_NUMBER == p_racp_req->filter.racp_filter_type) { - if ((gls_res.meas_val.sequence_number >= s_gls_env.racp_req.filter.val.seq_num.min) && \ - (gls_res.meas_val.sequence_number <= s_gls_env.racp_req.filter.val.seq_num.max)) { - s_gls_env.is_record_continue_send = true; - gls_meas_val_send(conn_idx, &gls_res); - return; - } - } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_racp_req->filter.racp_filter_type) { - if (!(-1 == gls_racp_user_time_compare(&gls_res.meas_val.base_time, \ - &s_gls_env.racp_req.filter.val.time.min)) && \ - !(-1 == gls_racp_user_time_compare(&s_gls_env.racp_req.filter.val.time.max, \ - &gls_res.meas_val.base_time))) { - s_gls_env.is_record_continue_send = true; - gls_meas_val_send(conn_idx, &gls_res); - break; - } - } - s_gls_env.proc_record_idx++; }; s_gls_env.is_record_continue_send = false; @@ -679,21 +639,28 @@ static void gls_first_or_last_records_report(uint8_t conn_idx, gls_racp_req_t *p records_num = gls_db_records_num_get(); - if (0 < s_gls_env.proc_records_reported) { + if (0 < s_gls_env.proc_records_reported || records_num == 0) + { s_gls_env.is_record_continue_send = false; s_gls_env.racp_in_progress = false; gls_report_records_completed(conn_idx); - } else { + } + else + { s_gls_env.is_record_continue_send = true; is_get_rec = false; - if (GLS_RACP_OPERATOR_FIRST_REC == p_racp_req->filter.racp_operator) { + if (GLS_RACP_OPERATOR_FIRST_REC == p_racp_req->filter.racp_operator) + { is_get_rec = gls_db_record_get(0, &gls_res); - } else if (GLS_RACP_OPERATOR_LAST_REC == p_racp_req->filter.racp_operator) { + } + else if (GLS_RACP_OPERATOR_LAST_REC == p_racp_req->filter.racp_operator) + { is_get_rec = gls_db_record_get(records_num - 1, &gls_res); } - if (is_get_rec) { + if (is_get_rec) + { gls_meas_val_send(conn_idx, &gls_res); } } @@ -709,7 +676,8 @@ static void gls_first_or_last_records_report(uint8_t conn_idx, gls_racp_req_t *p */ static void gls_report_records_req_handler(uint8_t conn_idx, gls_racp_req_t *p_racp_req) { - switch (p_racp_req->filter.racp_operator) { + switch (p_racp_req->filter.racp_operator) + { case GLS_RACP_OPERATOR_ALL_RECS: gls_all_records_report(conn_idx, p_racp_req); break; @@ -775,14 +743,11 @@ static void gls_abort_operation_handler(uint8_t conn_idx) gls_racp_rsp_t racp_rsp; uint8_t encoded_racp_rsp[GLS_REC_ACCESS_CTRL_LEN_MAX]; uint16_t encode_length; - uint8_t ret; - ret = memset_s(&racp_rsp, sizeof(gls_racp_rsp_t), 0, sizeof(gls_racp_rsp_t)); - if (ret <0) { - return; - } + memset(&racp_rsp, 0, sizeof(gls_racp_rsp_t)); - if (s_gls_env.racp_in_progress) { + if (s_gls_env.racp_in_progress) + { s_gls_env.racp_in_progress = false; } @@ -810,40 +775,46 @@ static void gls_receive_racp_handler(uint8_t conn_idx, const uint8_t *p_data, ui gls_racp_operand_t status; uint8_t encoded_racp_rsp[GLS_REC_ACCESS_CTRL_LEN_MAX]; uint16_t encode_length; - uint8_t ret; - ret = memset_S(&s_gls_env.racp_req, sizeof(gls_racp_req_t), 0, sizeof(gls_racp_req_t)); - if (ret < 0) { - return; - } - ret = memset_S(&racp_rsp, sizeof(gls_racp_rsp_t), 0, sizeof(gls_racp_rsp_t)); - if (ret < 0) { - return; - } + memset(&s_gls_env.racp_req, 0, sizeof(gls_racp_req_t)); + memset(&racp_rsp, 0, sizeof(gls_racp_rsp_t)); - if (GLS_REC_ACCESS_CTRL_LEN_MIN <= length) { + if (GLS_REC_ACCESS_CTRL_LEN_MIN <= length) + { status = gls_racp_req_decode(p_data, length, &s_gls_env.racp_req); + if ((GLS_RACP_RSP_VALID_DECODE == status) && \ - (GLS_RACP_OP_REP_STRD_RECS <= s_gls_env.racp_req.op_code) && \ - (GLS_RACP_OP_REP_NB_OF_STRD_RECS >= s_gls_env.racp_req.op_code)) { - if (GLS_RACP_OP_REP_STRD_RECS == s_gls_env.racp_req.op_code) { + (GLS_RACP_OP_REP_STRD_RECS <= s_gls_env.racp_req.op_code) && \ + (GLS_RACP_OP_REP_NB_OF_STRD_RECS >= s_gls_env.racp_req.op_code)) + { + if (GLS_RACP_OP_REP_STRD_RECS == s_gls_env.racp_req.op_code) + { s_gls_env.racp_in_progress = true; s_gls_env.proc_records_reported = 0; s_gls_env.proc_record_idx = 0; gls_report_records_req_handler(conn_idx, &s_gls_env.racp_req); - } else if (GLS_RACP_OP_REP_NB_OF_STRD_RECS == s_gls_env.racp_req.op_code) { + } + else if (GLS_RACP_OP_REP_NB_OF_STRD_RECS == s_gls_env.racp_req.op_code) + { s_gls_env.racp_in_progress = true; gls_report_records_num_req_handler(conn_idx, &s_gls_env.racp_req); - } else if (GLS_RACP_OP_ABORT_OP == s_gls_env.racp_req.op_code) { + } + else if (GLS_RACP_OP_ABORT_OP == s_gls_env.racp_req.op_code) + { gls_abort_operation_handler(conn_idx); } - } else { - if (GLS_RACP_RSP_VALID_DECODE != status) { + } + + else + { + if (GLS_RACP_RSP_VALID_DECODE != status) + { racp_rsp.operand.rsp.status = status; } if ((GLS_RACP_OP_REP_STRD_RECS > s_gls_env.racp_req.op_code) || \ - (GLS_RACP_OP_REP_NB_OF_STRD_RECS < s_gls_env.racp_req.op_code)) { + (GLS_RACP_OP_REP_NB_OF_STRD_RECS < s_gls_env.racp_req.op_code)) + { racp_rsp.operand.rsp.status = GLS_RACP_RSP_OP_CODE_NOT_SUP; } @@ -853,6 +824,7 @@ static void gls_receive_racp_handler(uint8_t conn_idx, const uint8_t *p_data, ui gls_racp_rsp_send(conn_idx, encoded_racp_rsp, encode_length); } } + } /** @@ -876,29 +848,32 @@ static uint8_t gls_meas_value_encode(const gls_meas_val_t *p_meas, uint8_t *p_en p_encoded_buffer[length++] = LO_U16(p_meas->base_time.year); p_encoded_buffer[length++] = HI_U16(p_meas->base_time.year); - p_encoded_buffer[length++] = LO_U16(p_meas->base_time.month); - p_encoded_buffer[length++] = HI_U16(p_meas->base_time.day); - p_encoded_buffer[length++] = LO_U16(p_meas->base_time.hour); - p_encoded_buffer[length++] = HI_U16(p_meas->base_time.min); - p_encoded_buffer[length++] = LO_U16(p_meas->base_time.sec); + p_encoded_buffer[length++] = p_meas->base_time.month; + p_encoded_buffer[length++] = p_meas->base_time.day; + p_encoded_buffer[length++] = p_meas->base_time.hour; + p_encoded_buffer[length++] = p_meas->base_time.min; + p_encoded_buffer[length++] = p_meas->base_time.sec; - if (p_meas->flags & GLS_MEAS_FLAG_TIME_OFFSET) { + if (p_meas->flags & GLS_MEAS_FLAG_TIME_OFFSET) + { p_encoded_buffer[length++] = LO_U16(p_meas->time_offset); p_encoded_buffer[length++] = HI_U16(p_meas->time_offset); } - if (p_meas->flags & GLS_MEAS_FLAG_CONC_TYPE_LOC) { + if (p_meas->flags & GLS_MEAS_FLAG_CONC_TYPE_LOC) + { uint16_t encoded_concentration; - encoded_concentration = ((p_meas->glucose_concentration.exponent << XPONENT_OFFSET) & 0xF000) | + encoded_concentration = ((p_meas->glucose_concentration.exponent << 12) & 0xF000) | ((p_meas->glucose_concentration.mantissa << 0) & 0x0FFF); p_encoded_buffer[length++] = (uint8_t)(encoded_concentration); - p_encoded_buffer[length++] = (uint8_t)(encoded_concentration >> ENCODE_OFFSET); - p_encoded_buffer[length++] = (p_meas->sample_location << LOCATION_OFFSET) | (p_meas->type & 0x0F); + p_encoded_buffer[length++] = (uint8_t)(encoded_concentration >> 8); + p_encoded_buffer[length++] = (p_meas->sample_location << 4) | (p_meas->type & 0x0F); } - if (p_meas->flags & GLS_MEAS_FLAG_SENSOR_STATUS) { + if (p_meas->flags & GLS_MEAS_FLAG_SENSOR_STATUS) + { p_encoded_buffer[length++] = LO_U16(p_meas->sensor_status_annunciation); p_encoded_buffer[length++] = HI_U16(p_meas->sensor_status_annunciation); } @@ -921,17 +896,14 @@ static sdk_err_t gls_meas_val_send(uint8_t conn_idx, gls_rec_t *p_rec) sdk_err_t error_code = BLE_SUCCESS; uint8_t encoded_glc_meas[GLS_MEAS_VAL_LEN_MAX]; uint16_t length; - gatts_noti_ind_t gls_ntf; - sdk_err_t ret; + ble_gatts_noti_ind_t gls_ntf; length = gls_meas_value_encode(&p_rec->meas_val, encoded_glc_meas); - ret = memset_s(&gls_ntf, sizeof(gatts_noti_ind_t), 0, sizeof(gatts_noti_ind_t)); - if (ret < 0) { - return ret; - } + memset(&gls_ntf, 0, sizeof (ble_gatts_noti_ind_t)); - if (PRF_CLI_START_NTF == s_gls_env.meas_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_gls_env.meas_ntf_cfg[conn_idx]) + { gls_ntf.type = BLE_GATT_NOTIFICATION; gls_ntf.handle = prf_find_handle_by_idx(GLS_IDX_MEAS_VAL, s_gls_env.start_hdl, @@ -939,7 +911,9 @@ static sdk_err_t gls_meas_val_send(uint8_t conn_idx, gls_rec_t *p_rec) gls_ntf.length = length; gls_ntf.value = encoded_glc_meas; error_code = ble_gatts_noti_ind(conn_idx, &gls_ntf); - if (BLE_SUCCESS == error_code) { + + if (BLE_SUCCESS == error_code) + { s_gls_env.ntf_mask = GLS_NTF_OF_MEAS; } } @@ -955,26 +929,63 @@ static sdk_err_t gls_meas_val_send(uint8_t conn_idx, gls_rec_t *p_rec) * @param[in] p_param: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void gls_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void gls_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (SDK_SUCCESS != status) { + if (SDK_SUCCESS == status) + { + if (BLE_GATT_INDICATION == p_ntf_ind->type) + { + s_gls_env.racp_in_progress = false; + } + else if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { + if (s_gls_env.ntf_mask & GLS_NTF_OF_MEAS) + { + s_gls_env.ntf_mask = GLS_NTF_OF_NULL; + + if (s_gls_env.is_record_continue_send) + { + s_gls_env.proc_record_idx++; + s_gls_env.proc_records_reported++; + gls_report_records_req_handler(conn_idx, &s_gls_env.racp_req); + } + else + { + s_gls_env.racp_in_progress = false; + } + } + } + } +} + +static void gls_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { return; } - if (BLE_GATT_INDICATION == p_ntf_ind->type) { - s_gls_env.racp_in_progress = false; - } else if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { - if (s_gls_env.ntf_mask & GLS_NTF_OF_MEAS) { - s_gls_env.ntf_mask = GLS_NTF_OF_NULL; + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + gls_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; - if (s_gls_env.is_record_continue_send) { - s_gls_env.proc_record_idx++; - s_gls_env.proc_records_reported++; - gls_report_records_req_handler(conn_idx, &s_gls_env.racp_req); - } else { - s_gls_env.racp_in_progress = false; - } - } + case BLE_GATTS_EVT_WRITE_REQUEST: + gls_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + gls_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + gls_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + gls_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; } } @@ -991,13 +1002,14 @@ bool gls_new_meas_record(gls_rec_t *p_rec) sdk_err_t gls_racp_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t racp_rsp; + ble_gatts_noti_ind_t racp_rsp; - if (PRF_CLI_START_IND == s_gls_env.racp_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_gls_env.racp_ind_cfg[conn_idx]) + { racp_rsp.type = BLE_GATT_INDICATION; racp_rsp.handle = prf_find_handle_by_idx(GLS_IDX_REC_ACCESS_CTRL_VAL, - s_gls_env.start_hdl, - (uint8_t *)&s_gls_env.gls_init.char_mask); + s_gls_env.start_hdl, + (uint8_t *)&s_gls_env.gls_init.char_mask); racp_rsp.length = length; racp_rsp.value = p_data; error_code = ble_gatts_noti_ind(conn_idx, &racp_rsp); @@ -1008,21 +1020,25 @@ sdk_err_t gls_racp_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length sdk_err_t gls_service_init(gls_init_t *p_gls_init) { - sdk_err_t ret; - if (p_gls_init == NULL) { + if (NULL == p_gls_init) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_gls_env, sizeof(s_gls_env), 0, sizeof(s_gls_env)); - if (ret < 0) { - return ret; - } - ret = memcpy_s(&s_gls_env.gls_init, sizeof(gls_init_t), p_gls_init, sizeof(gls_init_t)); - if (ret < 0) { - return ret; - } + memset(&s_gls_env, 0, sizeof(s_gls_env)); + memcpy(&s_gls_env.gls_init, p_gls_init, sizeof(gls_init_t)); gls_next_sequence_num_set(); gls_db_init(); - return ble_server_prf_add(&gls_prf_info); + s_gls_env.start_hdl = PRF_INVALID_HANDLE; + + s_gls_env.gls_gatts_db.shdl = &s_gls_env.start_hdl; + s_gls_env.gls_gatts_db.uuid = s_gls_svc_uuid; + s_gls_env.gls_gatts_db.attr_tab_cfg = (uint8_t *)&(s_gls_env.gls_init.char_mask); + s_gls_env.gls_gatts_db.max_nb_attr = GLS_IDX_NB; + s_gls_env.gls_gatts_db.srvc_perm = 0; + s_gls_env.gls_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_gls_env.gls_gatts_db.attr_tab.attr_tab_16 = gls_attr_tab; + + return ble_gatts_prf_add(&s_gls_env.gls_gatts_db, gls_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.h index 6145dca..baba015 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls.h @@ -64,41 +64,38 @@ * INCLUDE FILES **************************************************************************************** */ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup GLS_MACRO Defines * @{ */ -#define GLS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ?\ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Glucose Profile connections. */ -#define GLS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of GLS measurement value. */ -#define GLS_MEAS_CTX_LEN_MAX 20 /**< Maximum length of GLS measurement context value. */ -#define GLS_REC_ACCESS_CTRL_LEN_MIN 2 /**< Minimum length of Record Access Control Point packet. */ -#define GLS_REC_ACCESS_CTRL_LEN_MAX 21 /**< Maximum length of Record Access Control Point packet. */ +#define GLS_CONNECTION_MAX 10 /**< Maximum number of Glucose Profile connections. */ +#define GLS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of GLS measurement value. */ +#define GLS_MEAS_CTX_LEN_MAX 20 /**< Maximum length of GLS measurement context value. */ +#define GLS_REC_ACCESS_CTRL_LEN_MIN 2 /**< Minimum length of Record Access Control Point packet. */ +#define GLS_REC_ACCESS_CTRL_LEN_MAX 21 /**< Maximum length of Record Access Control Point packet. */ #define GLS_NTF_OF_NULL 0x00 /**< Mask for no notify. */ #define GLS_NTF_OF_MEAS 0x01 /**< Mask for measurement notify. */ #define GLS_NTF_OF_MEAS_CTX 0x10 /**< Mask for measurement context notify. */ -#define GLS_ERROR_PROC_IN_PROCESS 0x80 /**< Error code: A previously triggered SC Control Point operation \ - is still in progress. */ -#define GLS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor \ - is not configured. */ +#define GLS_ERROR_PROC_IN_PROCESS 0x80 /**< Error code: A previously triggered SC Control Point operation is still in progress. */ +#define GLS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor is not configured. */ /** * @defgroup GLS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref gls_init_t.char_mask. */ -#define GLS_CHAR_MANDATORY 0x0f8f /**< Bit mask for mandatory characteristic in GLS. */ -#define GLS_CHAR_MEAS_CTX_SUP 0x0070 /**< Bit mask for Glucose Measurement Context characteristic that is optional. */ -#define GLS_CHAR_FULL 0x0fff /**< Bit mask of the full characteristic. */ +#define GLS_CHAR_MANDATORY 0x0f8f /**< Bit mask for mandatory characteristic in GLS. */ +#define GLS_CHAR_MEAS_CTX_SUP 0x0070 /**< Bit mask for Glucose Measurement Context characteristic that is optional. */ +#define GLS_CHAR_FULL 0x0fff /**< Bit mask of the full characteristic. */ /** @} */ /** @@ -157,21 +154,16 @@ */ #define GLS_MEAS_STATUS_BATT_LOW (0x01 << 0) /**< Device battery low at time of measurement */ #define GLS_MEAS_STATUS_SENSOR_FAULT (0x01 << 1) /**< Sensor malfunction or faulting at time of measurement */ -#define GLS_MEAS_STATUS_SAMPLE_SIZE (0x01 << 2) /**< Sample size for blood or control solution insufficient \ - at time of measurement */ +#define GLS_MEAS_STATUS_SAMPLE_SIZE (0x01 << 2) /**< Sample size for blood or control solution insufficient at time of measurement */ #define GLS_MEAS_STATUS_STRIP_INSERT (0x01 << 3) /**< Strip insertion error */ #define GLS_MEAS_STATUS_STRIP_TYPE (0x01 << 4) /**< Strip type incorrect for device */ #define GLS_MEAS_STATUS_RESULT_HIGH (0x01 << 5) /**< Sensor result higher than the device can process */ #define GLS_MEAS_STATUS_RESULT_LOW (0x01 << 6) /**< Sensor result lower than the device can process */ -#define GLS_MEAS_STATUS_TEMP_HIGH (0x01 << 7) /**< Sensor temperature too high for valid test/result \ - at time of measurement */ -#define GLS_MEAS_STATUS_TEMP_LOW (0x01 << 8) /**< Sensor temperature too low for valid test/result \ - at time of measurement */ -#define GLS_MEAS_STATUS_STRIP_PULL (0x01 << 9) /**< Sensor read interrupted because strip was pulled too soon \ - at time of measurement */ +#define GLS_MEAS_STATUS_TEMP_HIGH (0x01 << 7) /**< Sensor temperature too high for valid test/result at time of measurement */ +#define GLS_MEAS_STATUS_TEMP_LOW (0x01 << 8) /**< Sensor temperature too low for valid test/result at time of measurement */ +#define GLS_MEAS_STATUS_STRIP_PULL (0x01 << 9) /**< Sensor read interrupted because strip was pulled too soon at time of measurement */ #define GLS_MEAS_STATUS_GENERAL_FAULT (0x01 << 10) /**< General device fault has occurred in the sensor */ -#define GLS_MEAS_STATUS_TIME_FAULT (0x01 << 11) /**< Time fault has occurred in the sensor and \ - time may be inaccurate */ +#define GLS_MEAS_STATUS_TIME_FAULT (0x01 << 11) /**< Time fault has occurred in the sensor and time may be inaccurate */ /** @} */ /** @} */ @@ -180,7 +172,8 @@ * @{ */ /**@brief Glucose measurement type */ -typedef enum { +typedef enum +{ GLS_MEAS_TYPE_CAP_BLOOD = 0x01, /**< Capillary whole blood */ GLS_MEAS_TYPE_CAP_PLASMA, /**< Capillary plasma */ GLS_MEAS_TYPE_VEN_BLOOD, /**< Venous whole blood */ @@ -194,7 +187,8 @@ typedef enum { } gls_meas_type_t; /**@brief Glucose measurement location */ -typedef enum { +typedef enum +{ GLS_MEAS_LOC_FINGER = 0x01, /**< Finger */ GLS_MEAS_LOC_AST, /**< Alternate Site Test (AST) */ GLS_MEAS_LOC_EAR, /**< Earlobe */ @@ -203,7 +197,8 @@ typedef enum { } gls_meas_loc_t; /**@brief Glucose measurement context carbohydrate ID */ -typedef enum { +typedef enum +{ GLS_MEAS_CTX_CARB_BREAKFAST = 0x01, /**< Breakfast */ GLS_MEAS_CTX_CARB_LUNCH, /**< Lunch */ GLS_MEAS_CTX_CARB_DINNER, /**< Dinner */ @@ -214,7 +209,8 @@ typedef enum { } gls_meas_ctx_carb_id_t; /**@brief Glucose measurement context meal */ -typedef enum { +typedef enum +{ GLS_MEAS_CTX_MEAL_PREPRANDIAL = 0x01, /**< Preprandial (before meal) */ GLS_MEAS_CTX_MEAL_POSTPRANDIAL, /**< Postprandial (after meal) */ GLS_MEAS_CTX_MEAL_FASTING, /**< Fasting */ @@ -223,7 +219,8 @@ typedef enum { } gls_meas_ctx_meal_t; /**@brief Glucose measurement context tester */ -typedef enum { +typedef enum +{ GLS_MEAS_CTX_TESTER_SELF = 0x01, /**< Self */ GLS_MEAS_CTX_TESTER_PRO, /**< Health care professional */ GLS_MEAS_CTX_TESTER_LAB, /**< Lab test */ @@ -231,7 +228,8 @@ typedef enum { } gls_meas_ctx_tester_t; /**@brief Glucose measurement context health */ -typedef enum { +typedef enum +{ GLS_MEAS_CTX_HEALTH_MINOR = 0x01, /**< Minor health issues */ GLS_MEAS_CTX_HEALTH_MAJOR, /**< Major health issues */ GLS_MEAS_CTX_HEALTH_MENSES, /**< During menses */ @@ -241,7 +239,8 @@ typedef enum { } gls_meas_ctx_health_t; /**@brief Glucose measurement context medication ID */ -typedef enum { +typedef enum +{ GLS_MEAS_CTX_MED_RAPID = 0x01, /**< Rapid acting insulin */ GLS_MEAS_CTX_MED_SHORT, /**< Short acting insulin */ GLS_MEAS_CTX_MED_INTERMED, /**< Intermediate acting insulin */ @@ -250,7 +249,8 @@ typedef enum { } gls_meas_ctx_medic_id_t; /**@brief Glucose Service event type. */ -typedef enum { +typedef enum +{ GLS_EVT_INVALID = 0x00, /**< Invalid event. */ GLS_EVT_MEAS_NOTIFICATION_ENABLED, /**< Glucose Measurement notification enabled event. */ GLS_EVT_MEAS_NOTIFICATION_DISABLED, /**< Glucose Measurement notification disabled event. */ @@ -267,13 +267,15 @@ typedef enum { * @{ */ /**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, defined as a 16-bit value with 12-bit mantissa and 4-bit exponent). */ -typedef struct { +typedef struct +{ int8_t exponent; /**< Base 10 exponent, only 4 bits. */ int16_t mantissa; /**< Mantissa, only 12 bits. */ -} ieee_float16_t; +} gls_ieee_float16_t; /**@brief Glucose Service event. */ -typedef struct { +typedef struct +{ gls_evt_type_t evt_type; /**< The GLS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -294,43 +296,46 @@ typedef void (*gls_evt_handler_t)(gls_evt_t *p_evt); * @{ */ /**@brief Glucose Measurement structure. This contains glucose measurement value. */ -typedef struct { - uint8_t flags; /**< Flags. */ - uint16_t sequence_number; /**< Sequence number. */ - prf_date_time_t base_time; /**< Time stamp. */ - int16_t time_offset; /**< Time offset. */ - ieee_float16_t glucose_concentration; /**< Glucose concentration. */ - uint8_t type; /**< Type. */ - uint8_t sample_location; /**< Sample location. */ - uint16_t sensor_status_annunciation; /**< Sensor status annunciation. */ +typedef struct +{ + uint8_t flags; /**< Flags. */ + uint16_t sequence_number; /**< Sequence number. */ + prf_date_time_t base_time; /**< Time stamp. */ + int16_t time_offset; /**< Time offset. */ + gls_ieee_float16_t glucose_concentration; /**< Glucose concentration. */ + uint8_t type; /**< Type. */ + uint8_t sample_location; /**< Sample location. */ + uint16_t sensor_status_annunciation; /**< Sensor status annunciation. */ } gls_meas_val_t; /**@brief Glucose measurement context structure */ -typedef struct { - uint8_t flags; /**< Flags. */ - uint8_t extended_flags; /**< Extended Flags. */ - uint8_t carbohydrate_id; /**< Carbohydrate ID. */ - ieee_float16_t carbohydrate; /**< Carbohydrate. */ - uint8_t meal; /**< Meal. */ - uint8_t tester_and_health; /**< Tester and health. */ - uint16_t exercise_duration; /**< Exercise Duration. */ - uint8_t exercise_intensity; /**< Exercise Intensity. */ - uint8_t medication_id; /**< Medication ID. */ - ieee_float16_t medication; /**< Medication. */ - uint16_t hba1c; /**< HbA1c. */ +typedef struct +{ + uint8_t flags; /**< Flags. */ + uint8_t extended_flags; /**< Extended Flags. */ + uint8_t carbohydrate_id; /**< Carbohydrate ID. */ + gls_ieee_float16_t carbohydrate; /**< Carbohydrate. */ + uint8_t meal; /**< Meal. */ + uint8_t tester_and_health; /**< Tester and health. */ + uint16_t exercise_duration; /**< Exercise Duration. */ + uint8_t exercise_intensity; /**< Exercise Intensity. */ + uint8_t medication_id; /**< Medication ID. */ + gls_ieee_float16_t medication; /**< Medication. */ + uint16_t hba1c; /**< HbA1c. */ } gls_meas_ctx_t; /**@brief Glucose measurement record */ -typedef struct { +typedef struct +{ gls_meas_val_t meas_val; /**< Glucose measurement value. */ gls_meas_ctx_t meas_ctx; /**< Glucose measurement context. */ } gls_rec_t; /**@brief Glucose Service init stucture. This contains all option and data needed for initialization of the service. */ -typedef struct { +typedef struct +{ gls_evt_handler_t evt_handler; /**< Glucose Service event handler. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref GLS_CHAR_MASK. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref GLS_CHAR_MASK. */ uint16_t feature; /**< Initial value for features. */ } gls_init_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.c index 9d07277..f6a1a61 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.c @@ -46,17 +46,18 @@ ***************************************************************************************** */ /**@brief Glucose Service record structure. */ -struct gls_db_single_rec_t { +struct gls_db_single_rec_t +{ bool is_recorded; gls_rec_t record; }; /**@brief Glucose Service Database environment variable. */ -struct gls_db_env_t { - struct gls_db_single_rec_t database[GLS_DB_RECORDS_MAX]; /**< Glucose Service measurement values \ - records database. */ +struct gls_db_env_t +{ + struct gls_db_single_rec_t database[GLS_DB_RECORDS_MAX]; /**< Glucose Service measurement values records database. */ uint8_t rec_index[GLS_DB_RECORDS_MAX]; /**< Glucose Service measurement values record indexs. */ - uint16_t num_records; /**< Number of measurement values records in database. */ + uint16_t num_records; /**< Number of measurement values records in database. */ }; /* @@ -83,19 +84,29 @@ uint16_t gls_db_le_or_eq_record_num_get(gls_racp_filter_t *p_filter) gls_rec_t gls_res; uint16_t num_get = 0; - for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) { - if (!gls_db_record_get(i, &gls_res)) { - return num_get; + for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) + { + if (gls_db_record_get(i, &gls_res)) + { + if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) + { + if (p_filter->val.seq_num.max >= gls_res.meas_val.sequence_number) + { + num_get++; + } + } + else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) + { + if (-1 != gls_racp_user_time_compare(&p_filter->val.time.max, + &gls_res.meas_val.base_time)) + { + num_get++; + } + } } - if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) { - if (p_filter->val.seq_num.max >= gls_res.meas_val.sequence_number) { - num_get++; - } - } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) { - if (-1 != gls_racp_user_time_compare(&p_filter->val.time.max, - &gls_res.meas_val.base_time)) { - num_get++; - } + else + { + break; } } @@ -116,21 +127,33 @@ uint16_t gls_db_gt_or_eq_record_num_get(gls_racp_filter_t *p_filter) gls_rec_t gls_res; uint16_t num_get = 0; - for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) { - if (gls_db_record_get(i, &gls_res)) { - return num_get; + for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) + { + if (gls_db_record_get(i, &gls_res)) + { + if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) + { + if (p_filter->val.seq_num.min <= gls_res.meas_val.sequence_number) + { + num_get++; + } + } + else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) + { + if (-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time, + &p_filter->val.time.min)) + { + num_get++; + } + } } - if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) { - if (p_filter->val.seq_num.min <= gls_res.meas_val.sequence_number) { - num_get++; - } - } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) { - if (-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time, - &p_filter->val.time.min)) { - num_get++; - } + else + { + break; } } + + return num_get; } /** @@ -147,20 +170,31 @@ uint16_t gls_db_within_range_record_num_get(gls_racp_filter_t *p_filter) gls_rec_t gls_res; uint16_t num_get = 0; - for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) { - if (gls_db_record_get(i, &gls_res)) { - return num_get; + + for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) + { + if (gls_db_record_get(i, &gls_res)) + { + if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) + { + if ((gls_res.meas_val.sequence_number >= p_filter->val.seq_num.min) && \ + (gls_res.meas_val.sequence_number <= p_filter->val.seq_num.max)) + { + num_get++; + } + } + else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) + { + if ((-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time, &p_filter->val.time.min)) && \ + (-1 != gls_racp_user_time_compare(&p_filter->val.time.max, &gls_res.meas_val.base_time))) + { + num_get++; + } + } } - if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) { - if ((gls_res.meas_val.sequence_number >= p_filter->val.seq_num.min) && \ - (gls_res.meas_val.sequence_number <= p_filter->val.seq_num.max)) { - num_get++; - } - } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) { - if ((-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time, &p_filter->val.time.min)) && \ - (-1 != gls_racp_user_time_compare(&p_filter->val.time.max, &gls_res.meas_val.base_time))) { - num_get++; - } + else + { + break; } } @@ -173,7 +207,8 @@ uint16_t gls_db_within_range_record_num_get(gls_racp_filter_t *p_filter) */ void gls_db_init(void) { - for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) { + for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) + { s_gls_db_env.database[i].is_recorded = false; s_gls_db_env.rec_index[i] = 0xFF; } @@ -185,12 +220,15 @@ bool gls_db_record_add(gls_rec_t *p_rec) { uint8_t i = 0; - if (GLS_DB_RECORDS_MAX <= s_gls_db_env.num_records) { + if (GLS_DB_RECORDS_MAX <= s_gls_db_env.num_records) + { return false; } - for (i = 0; i < GLS_DB_RECORDS_MAX; i++) { - if (!s_gls_db_env.database[i].is_recorded) { + for (i = 0; i < GLS_DB_RECORDS_MAX; i++) + { + if (!s_gls_db_env.database[i].is_recorded) + { s_gls_db_env.database[i].is_recorded = true; s_gls_db_env.database[i].record = *p_rec; s_gls_db_env.rec_index[s_gls_db_env.num_records] = i; @@ -204,7 +242,8 @@ bool gls_db_record_add(gls_rec_t *p_rec) bool gls_db_record_delete(uint8_t rec_idx) { - if (rec_idx >= s_gls_db_env.num_records) { + if (rec_idx >= s_gls_db_env.num_records) + { return false; } @@ -212,7 +251,8 @@ bool gls_db_record_delete(uint8_t rec_idx) s_gls_db_env.num_records--; - for (uint8_t i = rec_idx; i < s_gls_db_env.num_records; i++) { + for (uint8_t i = rec_idx; i < s_gls_db_env.num_records; i++) + { s_gls_db_env.rec_index[i] = s_gls_db_env.rec_index[i + 1]; } @@ -228,7 +268,8 @@ uint16_t gls_db_filter_records_num_get(gls_racp_filter_t *p_filter) { uint16_t num_get = 0; - switch (p_filter->racp_operator) { + switch (p_filter->racp_operator) + { case GLS_RACP_OPERATOR_ALL_RECS: num_get = s_gls_db_env.num_records; break; @@ -247,7 +288,8 @@ uint16_t gls_db_filter_records_num_get(gls_racp_filter_t *p_filter) case GLS_RACP_OPERATOR_FIRST_REC: case GLS_RACP_OPERATOR_LAST_REC: - if (s_gls_db_env.num_records != 0) { + if (0 != s_gls_db_env.num_records) + { num_get = 1; } break; @@ -261,7 +303,8 @@ uint16_t gls_db_filter_records_num_get(gls_racp_filter_t *p_filter) bool gls_db_record_get(uint8_t rec_idx, gls_rec_t *p_rec) { - if (rec_idx >= s_gls_db_env.num_records) { + if (rec_idx >= s_gls_db_env.num_records) + { return false; } @@ -272,7 +315,8 @@ bool gls_db_record_get(uint8_t rec_idx, gls_rec_t *p_rec) void gls_db_record_clear(void) { - for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) { + for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) + { s_gls_db_env.database[i].is_recorded = false; s_gls_db_env.rec_index[i] = 0xFF; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.h index 1e2bc78..5288ad0 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_db.h @@ -54,10 +54,10 @@ #ifndef __GLS_DB_H__ #define __GLS_DB_H__ -#include -#include #include "gls.h" #include "gls_racp.h" +#include +#include /** * @defgroup GLS_DB_MAROC Defines diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.c index 9e04d14..a16f05f 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.c @@ -42,47 +42,64 @@ #include "gls_racp.h" #include "ble_prf_utils.h" #include "utility.h" -#define SCALE_2 2 -#define ADD_2 2 + /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ int8_t gls_racp_user_time_compare(prf_date_time_t *p_compared_date_time, prf_date_time_t *p_base_date_time) { - if (p_compared_date_time->year < p_base_date_time->year) { + if (p_compared_date_time->year < p_base_date_time->year) + { return -1; - } else if (p_compared_date_time->year > p_base_date_time->year) { + } + else if (p_compared_date_time->year > p_base_date_time->year) + { return 1; } - if (p_compared_date_time->month < p_base_date_time->month) { + if (p_compared_date_time->month < p_base_date_time->month) + { return -1; - } else if (p_compared_date_time->month > p_base_date_time->month) { + } + else if (p_compared_date_time->month > p_base_date_time->month) + { return 1; } - if (p_compared_date_time->day < p_base_date_time->day) { + if (p_compared_date_time->day < p_base_date_time->day) + { return -1; - } else if (p_compared_date_time->day > p_base_date_time->day) { + } + else if (p_compared_date_time->day > p_base_date_time->day) + { return 1; } - if (p_compared_date_time->hour < p_base_date_time->hour) { + if (p_compared_date_time->hour < p_base_date_time->hour) + { return -1; - } else if (p_compared_date_time->hour > p_base_date_time->hour) { + } + else if (p_compared_date_time->hour > p_base_date_time->hour) + { return 1; } - if (p_compared_date_time->min < p_base_date_time->min) { + if (p_compared_date_time->min < p_base_date_time->min) + { return -1; - } else if (p_compared_date_time->min > p_base_date_time->min) { + } + else if (p_compared_date_time->min > p_base_date_time->min) + { return 1; } - if (p_compared_date_time->sec < p_base_date_time->sec) { + if (p_compared_date_time->sec < p_base_date_time->sec) + { return -1; - } else if (p_compared_date_time->sec > p_base_date_time->sec) { + } + else if (p_compared_date_time->sec > p_base_date_time->sec) + { return 1; } @@ -96,78 +113,132 @@ gls_racp_operand_t gls_racp_req_decode(const uint8_t *p_data, uint16_t length, g p_racp_req->op_code = (gls_racp_op_code_t)p_data[index++]; p_racp_req->filter.racp_operator = (gls_racp_operator_t)p_data[index++]; - if ((GLS_RACP_OP_ABORT_OP != p_racp_req->op_code) && \ - (GLS_RACP_OPERATOR_ALL_RECS > p_racp_req->filter.racp_operator)) { - return GLS_RACP_RSP_INVALID_OPERATOR; + if (GLS_RACP_OP_REP_STRD_RECS == p_racp_req->op_code || + GLS_RACP_OP_DEL_STRD_RECS == p_racp_req->op_code || + GLS_RACP_OP_REP_NB_OF_STRD_RECS == p_racp_req->op_code) + { + if(GLS_RACP_OPERATOR_ALL_RECS > p_racp_req->filter.racp_operator) + { + return GLS_RACP_RSP_INVALID_OPERATOR; + } + } + else + { + if(GLS_RACP_OPERATOR_ALL_RECS <= p_racp_req->filter.racp_operator) + { + return GLS_RACP_RSP_INVALID_OPERATOR; + } } - if (GLS_RACP_OPERATOR_LAST_REC < p_racp_req->filter.racp_operator) { + if (GLS_RACP_OPERATOR_LAST_REC < p_racp_req->filter.racp_operator) + { return GLS_RACP_RSP_OPERATOR_NOT_SUP; } if ((GLS_RACP_OPERATOR_LE_OR_EQ <= p_racp_req->filter.racp_operator) && \ - ((GLS_RACP_OPERATOR_WITHIN_RANGE_OF) >= p_racp_req->filter.racp_operator)) { - if (length <= index) { + ((GLS_RACP_OPERATOR_WITHIN_RANGE_OF) >= p_racp_req->filter.racp_operator)) + { + if (length <= index) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { p_racp_req->filter.racp_filter_type = (gls_racp_filter_type_t)p_data[index++]; - if (GLS_RACP_FILTER_SEQ_NUMBER == p_racp_req->filter.racp_filter_type) { - if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) { + if (GLS_RACP_FILTER_SEQ_NUMBER == p_racp_req->filter.racp_filter_type) + { + if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { p_racp_req->filter.val.seq_num.max = BUILD_U16(p_data[index], p_data[index + 1]); } - } else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) { + } + else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { p_racp_req->filter.val.seq_num.min = BUILD_U16(p_data[index], p_data[index + 1]); } - } else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_SEQ_NUM_LEN * SCALE_2 != (length - index)) { + } + else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_SEQ_NUM_LEN * 2 != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { p_racp_req->filter.val.seq_num.min = BUILD_U16(p_data[index], p_data[index + 1]); - p_racp_req->filter.val.seq_num.max = BUILD_U16(p_data[index + ADD_2], p_data[index + 3]); + p_racp_req->filter.val.seq_num.max = BUILD_U16(p_data[index + 2], p_data[index + 3]); - if (p_racp_req->filter.val.seq_num.min > p_racp_req->filter.val.seq_num.max) { + if (p_racp_req->filter.val.seq_num.min > p_racp_req->filter.val.seq_num.max) + { return GLS_RACP_RSP_INVALID_OPERAND; } } } - } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_racp_req->filter.racp_filter_type) { - if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) { + + } + else if (GLS_RACP_FILTER_USER_FACING_TIME == p_racp_req->filter.racp_filter_type) + { + if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.max); } - } else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) { + } + else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.min); } - } else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) { - if (GLS_RACP_FILTER_USER_TIME_LEN * SCALE_2 != (length - index)) { + } + else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) + { + if (GLS_RACP_FILTER_USER_TIME_LEN * 2 != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; - } else { + } + else + { index += prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.min); prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.max); - if (gls_racp_user_time_compare(&p_racp_req->filter.val.time.max, - &p_racp_req->filter.val.time.min) != -1) { + if (-1 != gls_racp_user_time_compare(&p_racp_req->filter.val.time.max, &p_racp_req->filter.val.time.min)) + { return GLS_RACP_RSP_INVALID_OPERAND; } } } - } else { + } + else + { return GLS_RACP_RSP_OPERAND_NOT_SUP; } } - } else if (length - index) != 0) { + } + else if (0 != (length - index)) + { return GLS_RACP_RSP_INVALID_OPERAND; } @@ -181,10 +252,13 @@ uint16_t gls_racp_rsp_encode(gls_racp_rsp_t *p_racp_rsp, uint8_t *p_encoded_buff p_encoded_buffer[length++] = p_racp_rsp->op_code; p_encoded_buffer[length++] = GLS_RACP_OPERATOR_NULL; - if (GLS_RACP_OP_REP_NB_OF_STRD_RECS == p_racp_rsp->op_code) { + if (GLS_RACP_OP_REP_NB_OF_STRD_RECS == p_racp_rsp->op_code) + { p_encoded_buffer[length++] = LO_U16(p_racp_rsp->operand.num_of_record); p_encoded_buffer[length++] = HI_U16(p_racp_rsp->operand.num_of_record); - } else { + } + else + { p_encoded_buffer[length++] = p_racp_rsp->operand.rsp.op_code_req; p_encoded_buffer[length++] = p_racp_rsp->operand.rsp.status; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.h index 8e7ea4b..ca54ee3 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gls/gls_racp.h @@ -57,10 +57,10 @@ * INCLUDE FILES **************************************************************************************** */ +#include "ble_prf_types.h" +#include "gr_includes.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" /** * @defgroup GLS_RACP_MACRO Defines @@ -75,19 +75,20 @@ * @{ */ /**@brief Glucose Recoerd Access Control Point Operation Codes. */ -typedef enum { +typedef enum +{ GLS_RACP_OP_RESERVED, /**< Reserved for future use. */ GLS_RACP_OP_REP_STRD_RECS, /**< Report stored records (Operator: Value from Operator Table). */ GLS_RACP_OP_DEL_STRD_RECS, /**< Delete stored records (Operator: Value from Operator Table). */ GLS_RACP_OP_ABORT_OP, /**< Abort operation (Operator: Null 'value of 0x00 from Operator Table'). */ GLS_RACP_OP_REP_NB_OF_STRD_RECS, /**< Report number of stored records (Operator: Value from Operator Table). */ - GLS_RACP_OP_NB_OF_STRD_RECS_RSP, /**< Number of stored records response \ - (Operator: Null 'value of 0x00 from Operator Table'). */ + GLS_RACP_OP_NB_OF_STRD_RECS_RSP, /**< Number of stored records response (Operator: Null 'value of 0x00 from Operator Table'). */ GLS_RACP_OP_RSP_CODE, /**< Response Code (Operator: Null 'value of 0x00 from Operator Table'). */ } gls_racp_op_code_t; /**@brief Glucose Recoerd Access Control Point Operator. */ -typedef enum { +typedef enum +{ GLS_RACP_OPERATOR_NULL, /**< NULL. */ GLS_RACP_OPERATOR_ALL_RECS, /**< All records. */ GLS_RACP_OPERATOR_LE_OR_EQ, /**< Less than or equal to. */ @@ -98,17 +99,15 @@ typedef enum { } gls_racp_operator_t; /**@brief Glucose Recoerd Access Control Point Response codes. */ -typedef enum { +typedef enum +{ GLS_RACP_RSP_RESERVED, /**< Reserved for future use. */ GLS_RACP_RSP_SUCCESS, /**< Normal response for successful operation. */ GLS_RACP_RSP_OP_CODE_NOT_SUP, /**< Normal response if unsupported Op Code is received. */ - GLS_RACP_RSP_INVALID_OPERATOR, /**< Normal response if Operator received does not meet \ - the requirements of the service (e.g. Null was expected). */ + GLS_RACP_RSP_INVALID_OPERATOR, /**< Normal response if Operator received does not meet the requirements of the service (e.g. Null was expected). */ GLS_RACP_RSP_OPERATOR_NOT_SUP, /**< Normal response if unsupported Operator is received. */ - GLS_RACP_RSP_INVALID_OPERAND, /**< Normal response if Operand received does not meet \ - the requirements of the service. */ - GLS_RACP_RSP_NO_RECS_FOUND, /**< Normal response if request to report stored records or request to \ - delete stored records resulted in no records meeting criteria. */ + GLS_RACP_RSP_INVALID_OPERAND, /**< Normal response if Operand received does not meet the requirements of the service. */ + GLS_RACP_RSP_NO_RECS_FOUND, /**< Normal response if request to report stored records or request to delete stored records resulted in no records meeting criteria. */ GLS_RACP_RSP_ABORT_UNSUCCESSFUL, /**< Normal response if request for Abort cannot be completed. */ GLS_RACP_RSP_PROCEDURE_NOT_COMPLETED, /**< Normal response if unable to complete a procedure for any reason. */ GLS_RACP_RSP_OPERAND_NOT_SUP, /**< Normal response if unsupported Operand is received. */ @@ -116,7 +115,8 @@ typedef enum { } gls_racp_operand_t; /**@brief Glucose Recoerd Access Control Point filter types. */ -typedef enum { +typedef enum +{ GLS_RACP_FILTER_RESERVED, /**< Reserved for future use. */ GLS_RACP_FILTER_SEQ_NUMBER, /**< Filter data using Sequence Number criteria. */ GLS_RACP_FILTER_USER_FACING_TIME, /**< Filter data using User Facing Time criteria. */ @@ -128,36 +128,42 @@ typedef enum { * @{ */ /**@brief Glucose Recoerd Access Control Point filter value. */ -typedef struct { +typedef struct +{ gls_racp_operator_t racp_operator; /**< Glucose Recoerd Access Control Point Operator. */ gls_racp_filter_type_t racp_filter_type; /**< Glucose Recoerd Access Control Point filter types. */ - union { - struct { + union + { + struct + { uint16_t min; /**< Min sequence number. */ uint16_t max; /**< Max sequence number. */ - } seq_num; /**< Sequence number filtering \ - (racp_filter_type = GLS_RACP_FILTER_SEQ_NUMBER). */ - struct { + } seq_num; /**< Sequence number filtering (racp_filter_type = GLS_RACP_FILTER_SEQ_NUMBER). */ + struct + { prf_date_time_t min; /**< Min base time. */ prf_date_time_t max; /**< Max base time. */ - } time; /**< User facing time filtering \ - (filter_type = GLS_RACP_FILTER_USER_FACING_TIME). */ + } time; /**< User facing time filtering (filter_type = GLS_RACP_FILTER_USER_FACING_TIME). */ } val; /**< Filter union. */ } gls_racp_filter_t; /**@brief Glucose Recoerd Access Control Point request value. */ -typedef struct { +typedef struct +{ gls_racp_op_code_t op_code; /**< Glucose Recoerd Access Control Point Operation Code. */ gls_racp_filter_t filter; /**< Glucose Recoerd Access Control Point Operation Code. */ } gls_racp_req_t; /**@brief Glucose Recoerd Access Control Point response value. */ -typedef struct { +typedef struct +{ gls_racp_op_code_t op_code; /**< Glucose Recoerd Access Control Point Operation Code. */ gls_racp_operator_t racp_operator; /**< Glucose Recoerd Access Control Point Operator. */ - union { + union + { uint16_t num_of_record; /**< Number of record (if op_code = GLS_RACP_OP_REP_NB_OF_STRD_RECS). */ - struct { + struct + { gls_racp_op_code_t op_code_req; /**< Request Op Code. */ gls_racp_operand_t status; /**< Command Status (if op_code = GLS_RACP_OP_RSP_CODE). */ } rsp; /**< Response. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/BUILD.gn new file mode 100644 index 0000000..53fc9d7 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("gus") { + sources = [ "gus.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.c index 18f977b..f2c7c97 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.c @@ -49,12 +49,9 @@ ***************************************************************************************** */ /**@brief The UUIDs of GUS characteristics. */ -#define GUS_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, \ - 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} -#define GUS_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, \ - 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} -#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, \ - 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} +#define GUS_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} +#define GUS_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} +#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -66,9 +63,10 @@ ***************************************************************************************** */ /**@brief Goodix UART Service Attributes Indexes. */ -enum gus_attr_idx_t { +enum gus_attr_idx_t +{ GUS_IDX_SVC, - + GUS_IDX_TX_CHAR, GUS_IDX_TX_VAL, GUS_IDX_TX_CFG, @@ -88,143 +86,68 @@ enum gus_attr_idx_t { ***************************************************************************************** */ /**@brief Goodix UART Service environment variable. */ -struct gus_env_t { - gus_init_t gus_init; /**< Goodix UART Service initialization variables. */ - uint16_t start_hdl; /**< Start handle of services */ - uint16_t tx_ntf_cfg[GUS_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of the peers. */ - uint16_t - flow_ctrl_ntf_cfg[GUS_CONNECTION_MAX]; /**< Flow Control Characteristic Notification configuration of the peers. */ +struct gus_env_t +{ + gus_init_t gus_init; /**< Goodix UART Service initialization variables. */ + uint16_t start_hdl; /**< Start handle of services */ + uint16_t tx_ntf_cfg[GUS_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of the peers. */ + uint16_t flow_ctrl_ntf_cfg[GUS_CONNECTION_MAX]; /**< Flow Control Characteristic Notification configuration of the peers. */ + ble_gatts_create_db_t gus_gatts_db; /**< Goodix UART Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t gus_init(void); -static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void gus_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct gus_env_t s_gus_env; static const uint16_t s_char_mask = 0xFFFF; +static const uint8_t s_gus_svc_uuid[] = {GUS_SERVICE_UUID}; /**@brief Full GUS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_128_t gus_att_db[GUS_IDX_NB] = { +static const ble_gatts_attm_desc_128_t gus_attr_tab[GUS_IDX_NB] = +{ // GUS service - [GUS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [GUS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // GUS TX Characteristic Declaration - [GUS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GUS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // GUS TX Characteristic Value - [GUS_IDX_TX_VAL] = { - GUS_SERVER_TX_UUID, - NOTIFY_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, + [GUS_IDX_TX_VAL] = {GUS_SERVER_TX_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + GUS_MAX_DATA_LEN}, // GUS TX Characteristic - Client Characteristic Configuration Descriptor - [GUS_IDX_TX_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [GUS_IDX_TX_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // GUS RX Characteristic Declaration - [GUS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GUS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // GUS RX Characteristic Value - [GUS_IDX_RX_VAL] = { - GUS_SERVER_RX_UUID, - WRITE_REQ_PERM_UNSEC | WRITE_CMD_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, + [GUS_IDX_RX_VAL] = {GUS_SERVER_RX_UUID, + BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_WRITE_CMD_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + GUS_MAX_DATA_LEN}, // GUS FLOW_CTRL Characteristic Declaration - [GUS_IDX_FLOW_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [GUS_IDX_FLOW_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // GUS FLOW_CTRL Characteristic Value - [GUS_IDX_FLOW_CTRL_VAL] = { - GUS_FLOW_CTRL_UUID, - NOTIFY_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, + [GUS_IDX_FLOW_CTRL_VAL] = {GUS_FLOW_CTRL_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + GUS_MAX_DATA_LEN}, // GUS FLOW_CTRL Characteristic - Client Characteristic Configuration Descriptor - [GUS_IDX_FLOW_CTRL_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief GUS Service interface required by profile manager. */ -static ble_prf_manager_cbs_t gus_mgr_cbs = { - (prf_init_func_t)gus_init, - NULL, - NULL, -}; - -/**@brief GUS GATT Server Callbacks. */ -static gatts_prf_cbs_t gus_gatts_cbs = { - gus_read_att_cb, - gus_write_att_cb, - NULL, - gus_ntf_ind_cb, - gus_cccd_set_cb -}; - -/**@brief GUS Server Information. */ -static const prf_server_info_t gus_prf_info = { - .max_connection_nb = GUS_CONNECTION_MAX, - .manager_cbs = &gus_mgr_cbs, - .gatts_prf_cbs = &gus_gatts_cbs + [GUS_IDX_FLOW_CTRL_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize GUS and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t gus_init(void) -{ - const uint8_t gus_svc_uuid[] = {GUS_SERVICE_UUID}; - uint16_t start_hdl = PRF_INVALID_HANDLE; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = gus_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; - gatts_db.max_nb_attr = GUS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = gus_att_db; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_gus_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -233,9 +156,9 @@ static sdk_err_t gus_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void gus_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint16_t handle = p_param->handle; uint8_t tab_index = 0; @@ -243,7 +166,8 @@ static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case GUS_IDX_TX_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_gus_env.tx_ntf_cfg[conn_idx]; @@ -273,21 +197,22 @@ static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in] p_param: Point to the parameters of the write request. ***************************************************************************************** */ -static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void gus_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint16_t flow_ctrl_state; uint16_t cccd_value; gus_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; - tab_index = prf_find_idx_by_handle(handle, s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); + tab_index = prf_find_idx_by_handle(handle,s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); event.conn_idx = conn_idx; cfm.handle = handle; cfm.status = BLE_SUCCESS; - - switch (tab_index) { + + switch (tab_index) + { case GUS_IDX_RX_VAL: event.evt_type = GUS_EVT_RX_DATA_RECEIVED; event.p_data = (uint8_t *)p_param->value; @@ -309,9 +234,12 @@ static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p case GUS_IDX_FLOW_CTRL_VAL: flow_ctrl_state = p_param->value[0]; - if (FLOW_OFF == flow_ctrl_state) { + if (GUS_FLOW_CTRL_STATE_OFF == flow_ctrl_state) + { event.evt_type = GUS_EVT_TX_FLOW_OFF; - } else if (FLOW_ON == flow_ctrl_state) { + } + else if (GUS_FLOW_CTRL_STATE_ON == flow_ctrl_state) + { event.evt_type = GUS_EVT_TX_FLOW_ON; } break; @@ -321,8 +249,8 @@ static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p break; } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && GUS_EVT_INVALID != event.evt_type && - s_gus_env.gus_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && GUS_EVT_INVALID != event.evt_type && s_gus_env.gus_init.evt_handler) + { s_gus_env.gus_init.evt_handler(&event); } @@ -338,20 +266,22 @@ static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void gus_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; gus_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } - tab_index = prf_find_idx_by_handle(handle, s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); + tab_index = prf_find_idx_by_handle(handle,s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); event.conn_idx = conn_idx; event.evt_type = GUS_EVT_INVALID; - switch (tab_index) { + switch (tab_index) + { case GUS_IDX_TX_CFG: event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? GUS_EVT_TX_PORT_OPENED : GUS_EVT_TX_PORT_CLOSED; s_gus_env.tx_ntf_cfg[conn_idx] = cccd_value; @@ -366,7 +296,8 @@ static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (GUS_EVT_INVALID != event.evt_type && s_gus_env.gus_init.evt_handler) { + if (GUS_EVT_INVALID != event.evt_type && s_gus_env.gus_init.evt_handler) + { s_gus_env.gus_init.evt_handler(&event); } } @@ -380,29 +311,59 @@ static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void gus_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void gus_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_gus_env.gus_init.evt_handler != NULL) { + if (NULL != s_gus_env.gus_init.evt_handler) + { gus_evt_t event; event.conn_idx = conn_idx; - if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = GUS_EVT_TX_DATA_SENT; s_gus_env.gus_init.evt_handler(&event); } } } +static void gus_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + gus_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + gus_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + gus_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + gus_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_cmd; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t send_cmd; - if (PRF_CLI_START_NTF == s_gus_env.tx_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_gus_env.tx_ntf_cfg[conn_idx]) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; send_cmd.handle = prf_find_handle_by_idx(GUS_IDX_TX_VAL, s_gus_env.start_hdl, (uint8_t *)&s_char_mask); @@ -418,12 +379,13 @@ sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) return error_code; } -sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) +sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, gus_flow_ctrl_state_t flow_ctrl) { - sdk_err_t error_code = BLE_SUCCESS; - gatts_noti_ind_t send_cmd; + sdk_err_t error_code = BLE_SUCCESS; + ble_gatts_noti_ind_t send_cmd; - if (PRF_CLI_START_NTF == s_gus_env.flow_ctrl_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_gus_env.flow_ctrl_ntf_cfg[conn_idx]) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; send_cmd.handle = prf_find_handle_by_idx(GUS_IDX_FLOW_CTRL_VAL, s_gus_env.start_hdl, (uint8_t *)&s_char_mask); @@ -441,15 +403,28 @@ sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) sdk_err_t gus_service_init(gus_init_t *p_gus_init) { - sdk_err_t ret; - if (p_gus_init == NULL) { + if (NULL == p_gus_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_gus_env.gus_init, sizeof(gus_init_t), p_gus_init, sizeof(gus_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_gus_env.gus_init, p_gus_init, sizeof(gus_init_t)); - return ble_server_prf_add(&gus_prf_info); + memset(&s_gus_env.gus_gatts_db, 0, sizeof(ble_gatts_create_db_t)); + + s_gus_env.start_hdl = PRF_INVALID_HANDLE; + s_gus_env.gus_gatts_db.shdl = &s_gus_env.start_hdl; + s_gus_env.gus_gatts_db.uuid = s_gus_svc_uuid; + s_gus_env.gus_gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_gus_env.gus_gatts_db.max_nb_attr = GUS_IDX_NB; + s_gus_env.gus_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_gus_env.gus_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_gus_env.gus_gatts_db.attr_tab.attr_tab_128 = gus_attr_tab; + + return ble_gatts_prf_add(&s_gus_env.gus_gatts_db, gus_ble_evt_handler); +} + +uint16_t gus_service_start_handle_get(void) +{ + return s_gus_env.start_hdl; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.h index 87021ef..781b220 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus/gus.h @@ -61,21 +61,18 @@ #ifndef __GUS_H__ #define __GUS_H__ -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" /** * @defgroup GUS_MACRO Defines * @{ */ -#define GUS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Goodix UART Service connections. */ -#define FLOW_ON 0x01 /**< Indicate that GUS can receive data from peer. */ -#define FLOW_OFF 0x00 /**< Indicate that GUS can not receive data from peer. */ -#define GUS_MAX_DATA_LEN 247 /**< Maximum length of application data packet which is transmitted via GUS. */ -#define GUS_FLOW_CTRL_LEN 1 /**< Maximum length of ble flow control data packet which is transmitted via GUS. */ -#define GUS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x01, \ - 0x02, 0xED, 0xA6 /**< The UUID of Goodix UART Service for setting advertising data. */ +#define GUS_CONNECTION_MAX 10 /**< Maximum number of Goodix UART Service connections. */ +#define GUS_MAX_DATA_LEN 247 /**< Maximum length of application data packet which is transmitted via GUS. */ +#define GUS_FLOW_CTRL_LEN 1 /**< Maximum length of ble flow control data packet which is transmitted via GUS. */ +#define GUS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x02, 0xED, 0xA6 /**< The UUID of Goodix UART Service for setting advertising data. */ /** @} */ /** @@ -83,18 +80,27 @@ * @{ */ /**@brief Goodix UART Service event types. */ -typedef enum { - GUS_EVT_INVALID, /**< Invalid GUS event. */ - GUS_EVT_RX_DATA_RECEIVED, /**< The data from the peer has been received. */ - GUS_EVT_TX_DATA_SENT, /**< The data from the application has been sent, - and the service is ready to accept new data from the application. */ - GUS_EVT_TX_PORT_OPENED, /**< Tx port has been opened. */ - GUS_EVT_TX_PORT_CLOSED, /**< Tx port has been closed. */ - GUS_EVT_FLOW_CTRL_ENABLE, /**< GUS flow control been enabled. */ - GUS_EVT_FLOW_CTRL_DISABLE, /**< GUS flow control been disabled. */ - GUS_EVT_TX_FLOW_OFF, /**< Tx flow off control request. */ - GUS_EVT_TX_FLOW_ON, /**< Tx flow on control request. */ +typedef enum +{ + GUS_EVT_INVALID, /**< Invalid GUS event. */ + GUS_EVT_RX_DATA_RECEIVED, /**< The data from the peer has been received. */ + GUS_EVT_TX_DATA_SENT, /**< The data from the application has been sent, and the service is ready to accept new data from the application. */ + GUS_EVT_TX_PORT_OPENED, /**< Tx port has been opened. */ + GUS_EVT_TX_PORT_CLOSED, /**< Tx port has been closed. */ + GUS_EVT_FLOW_CTRL_ENABLE, /**< GUS flow control been enabled. */ + GUS_EVT_FLOW_CTRL_DISABLE, /**< GUS flow control been disabled. */ + GUS_EVT_TX_FLOW_OFF, /**< Tx flow off control request. */ + GUS_EVT_TX_FLOW_ON, /**< Tx flow on control request. */ } gus_evt_type_t; + +/**@brief Flow control state for GUS service. */ +enum gus_flow_ctrl_state +{ + GUS_FLOW_CTRL_STATE_OFF = 0, /**< Indicate that GUS can not receive data from peer. */ + GUS_FLOW_CTRL_STATE_ON /**< Indicate that GUS can receive data from peer. */ +}; +/**@brief Underlying type used for the GUS flow control state. */ +typedef uint8_t gus_flow_ctrl_state_t; /** @} */ /** @@ -102,7 +108,8 @@ typedef enum { * @{ */ /**@brief Goodix UART Service event. */ -typedef struct { +typedef struct +{ gus_evt_type_t evt_type; /**< The GUS event. */ uint8_t conn_idx; /**< The index of the connection for the data transmission. */ uint8_t *p_data; /**< Pointer to the buffer within received data. */ @@ -111,7 +118,7 @@ typedef struct { /** @} */ /** - * @defgroup GUS_TYPEDEF Typedefs + * @addtogroup GUS_TYPEDEF Typedefs * @{ */ /**@brief Goodix UART Service event handler type. */ @@ -122,12 +129,10 @@ typedef void (*gus_evt_handler_t)(gus_evt_t *p_evt); * @addtogroup GUS_STRUCT Structures * @{ */ -/**@brief Goodix UART Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { - gus_evt_handler_t - evt_handler; /**< Goodix UART Service event handler which must be provided by - the application to send and receive the data. */ +/**@brief Goodix UART Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ + gus_evt_handler_t evt_handler; /**< Goodix UART Service event handler which must be provided by the application to send and receive the data. */ } gus_init_t; /** @} */ @@ -163,13 +168,19 @@ sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); ***************************************************************************************** * @brief Send GUS Rx flow control state to peer device * - * @param[in] conn_idx: Index of the connection. - * @param[in] flow_ctrl: GUS Rx flow control state - * * @return Result of sending GUS Rx flow control state. ***************************************************************************************** */ -sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl); +sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, gus_flow_ctrl_state_t flow_ctrl); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the gus service start handle . + * + * @return The gus service start handle. + ***************************************************************************************** + */ +uint16_t gus_service_start_handle_get(void); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/BUILD.gn new file mode 100644 index 0000000..667fdab --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("gus_c") { + sources = [ "gus_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.c index fbecc5a..61a7cd9 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.c @@ -39,28 +39,18 @@ ***************************************************************************************** */ #include "gus_c.h" -#define ATTR_VALUE_LEN 2 -#define UUID_LEN_16 16 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Goodix UART Service Client environment variable. */ -struct gus_c_env_t { +struct gus_c_env_t +{ gus_c_handles_t handles; /**< Handles of GUS characteristics which will be got for peer. */ gus_c_evt_handler_t evt_handler; /**< Handler of GUS client event */ - uint8_t prf_id; /**< GUS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void gus_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void gus_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** @@ -71,31 +61,10 @@ static uint8_t s_gus_rx_char_uuid[16] = GUS_RX_CHAR_UUID; static uint8_t s_gus_tx_char_uuid[16] = GUS_TX_CHAR_UUID; static uint8_t s_gus_flow_ctrl_char_uuid[16] = GUS_FLOW_CTRL_UUID; -/**@brief GUS Client interface required by profile manager. */ -static ble_prf_manager_cbs_t gus_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief GUS GATT Client Callbacks. */ -static gattc_prf_cbs_t gus_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - gus_c_att_write_cb, - gus_c_att_ntf_ind_cb, - gus_c_srvc_browse_cb, - NULL, -}; - -/**@brief GUS Client Information. */ -static const prf_client_info_t gus_c_prf_info = { - .max_connection_nb = GUS_C_CONNECTION_MAX, - .manager_cbs = &gus_c_mgr_cbs, - .gattc_prf_cbs = &gus_c_gattc_cbs +static ble_uuid_t s_gus_service_uuid = +{ + .uuid_len = 16, + .uuid = s_gus_uuid, }; /* @@ -111,7 +80,8 @@ static const prf_client_info_t gus_c_prf_info = { */ static void gus_c_evt_handler_excute(gus_c_evt_t *p_evt) { - if (s_gus_c_env.evt_handler != NULL && GUS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_gus_c_env.evt_handler && GUS_C_EVT_INVALID != p_evt->evt_type) + { s_gus_c_env.evt_handler(p_evt); } } @@ -125,29 +95,36 @@ static void gus_c_evt_handler_excute(gus_c_evt_t *p_evt) * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void gus_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void gus_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { gus_c_evt_t gus_c_evt; gus_c_evt.conn_idx = conn_idx; gus_c_evt.evt_type = GUS_C_EVT_INVALID; - if (handle == s_gus_c_env.handles.gus_tx_cccd_handle) { + if (handle == s_gus_c_env.handles.gus_tx_cccd_handle) + { gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_TX_NTF_SET_SUCCESS : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) { + GUS_C_EVT_TX_NTF_SET_SUCCESS : \ + GUS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) + { gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_rx_handle) { + GUS_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS : \ + GUS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_gus_c_env.handles.gus_rx_handle) + { gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_TX_CPLT : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_flow_ctrl_handle) { + GUS_C_EVT_TX_CPLT : \ + GUS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_gus_c_env.handles.gus_flow_ctrl_handle) + { gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_RX_FLOW_UPDATE_CPLT : \ - GUS_C_EVT_WRITE_OP_ERR; + GUS_C_EVT_RX_FLOW_UPDATE_CPLT : \ + GUS_C_EVT_WRITE_OP_ERR; } gus_c_evt_handler_excute(&gus_c_evt); @@ -162,20 +139,26 @@ static void gus_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void gus_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { gus_c_evt_t gus_c_evt; gus_c_evt.conn_idx = conn_idx; gus_c_evt.evt_type = GUS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_gus_c_env.handles.gus_flow_ctrl_handle) { - if (FLOW_ON == p_ntf_ind->p_value[0]) { + if (p_ntf_ind->handle == s_gus_c_env.handles.gus_flow_ctrl_handle) + { + if (GUS_C_FLOW_CTRL_STATE_ON == p_ntf_ind->p_value[0]) + { gus_c_evt.evt_type = GUS_C_EVT_TX_FLOW_ON; - } else if (FLOW_OFF == p_ntf_ind->p_value[0]) { + } + else if (GUS_C_FLOW_CTRL_STATE_OFF == p_ntf_ind->p_value[0]) + { gus_c_evt.evt_type = GUS_C_EVT_TX_FLOW_OFF; } - } else if (p_ntf_ind->handle == s_gus_c_env.handles.gus_tx_handle) { + } + else if (p_ntf_ind->handle == s_gus_c_env.handles.gus_tx_handle) + { gus_c_evt.evt_type = GUS_C_EVT_PEER_DATA_RECEIVE; gus_c_evt.p_data = p_ntf_ind->p_value; gus_c_evt.length = p_ntf_ind->length; @@ -193,7 +176,7 @@ static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void gus_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void gus_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { gus_c_evt_t gus_c_evt; uint16_t handle_disc; @@ -201,140 +184,145 @@ static void gus_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat gus_c_evt.conn_idx = conn_idx; gus_c_evt.evt_type = GUS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } + if (BLE_SUCCESS == status) + { + if (16 == p_browse_srvc->uuid_len && 0 == memcmp(p_browse_srvc->uuid, s_gus_uuid, 16)) + { + s_gus_c_env.handles.gus_srvc_start_handle = p_browse_srvc->start_hdl; + s_gus_c_env.handles.gus_srvc_end_handle = p_browse_srvc->end_hdl; - if (p_browse_srvc->uuid_len == UUID_LEN_16 && memcmp(p_browse_srvc->uuid, s_gus_uuid, UUID_LEN_16) == 0) { - s_gus_c_env.handles.gus_srvc_start_handle = p_browse_srvc->start_hdl; - s_gus_c_env.handles.gus_srvc_end_handle = p_browse_srvc->end_hdl; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + handle_disc = p_browse_srvc->start_hdl + i + 1; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - handle_disc = p_browse_srvc->start_hdl + i + 1; - - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_rx_char_uuid, UUID_LEN_16) == 0) { - s_gus_c_env.handles.gus_rx_handle = handle_disc; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_tx_char_uuid, UUID_LEN_16) == 0) { - s_gus_c_env.handles.gus_tx_handle = handle_disc; - s_gus_c_env.handles.gus_tx_cccd_handle = handle_disc + 1; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_flow_ctrl_char_uuid, UUID_LEN_16) == 0) { - s_gus_c_env.handles.gus_flow_ctrl_handle = handle_disc; - s_gus_c_env.handles.gus_flow_ctrl_cccd_handle = handle_disc + 1; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_rx_char_uuid, 16)) + { + s_gus_c_env.handles.gus_rx_handle = handle_disc; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_tx_char_uuid, 16)) + { + s_gus_c_env.handles.gus_tx_handle = handle_disc; + s_gus_c_env.handles.gus_tx_cccd_handle = handle_disc + 1; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_flow_ctrl_char_uuid, 16)) + { + s_gus_c_env.handles.gus_flow_ctrl_handle = handle_disc; + s_gus_c_env.handles.gus_flow_ctrl_cccd_handle = handle_disc + 1; + } + } + + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; } } - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; - } + gus_c_evt.evt_type = GUS_C_EVT_DISCOVERY_COMPLETE; } - - gus_c_evt.evt_type = GUS_C_EVT_DISCOVERY_COMPLETE; } gus_c_evt_handler_excute(&gus_c_evt); } +static void gus_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + gus_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + gus_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + gus_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t gus_client_init(gus_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_gus_c_env, sizeof(s_gus_c_env), 0, sizeof(s_gus_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_gus_c_env, 0, sizeof(s_gus_c_env)); s_gus_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&gus_c_prf_info, &s_gus_c_env.prf_id); + return ble_gattc_prf_add(&s_gus_service_uuid, gus_c_ble_evt_handler); } sdk_err_t gus_c_disc_srvc_start(uint8_t conn_idx) { - const ble_uuid_t gus_uuid = { - .uuid_len = 16, - .uuid = s_gus_uuid, - }; - - return ble_gattc_prf_services_browse(s_gus_c_env.prf_id, conn_idx, &gus_uuid); + return ble_gattc_services_browse(conn_idx, &s_gus_service_uuid); } sdk_err_t gus_c_tx_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_tx_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_tx_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_tx_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_gus_c_env.handles.gus_tx_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t gus_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_flow_ctrl_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_gus_c_env.handles.gus_flow_ctrl_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t gus_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_rx_handle) { + if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_rx_handle) + { return SDK_ERR_INVALID_HANDLE; } - if (p_data == NULL) { + if (NULL == p_data) + { return SDK_ERR_POINTER_NULL; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_gus_c_env.handles.gus_rx_handle; - write_attr_value.length = length; - write_attr_value.p_value = p_data; - - return ble_gattc_prf_write_no_resp(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_gus_c_env.handles.gus_rx_handle, length, p_data); } -sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) +sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, gus_c_flow_ctrl_state_t flow_ctrl) { - gattc_write_attr_value_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_handle) { + if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_flow_ctrl_handle; - write_attr_value.offset = 0; - write_attr_value.length = 1; - write_attr_value.p_value = &flow_ctrl; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_gus_c_env.handles.gus_flow_ctrl_handle, 0, 1, &flow_ctrl); } + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.h index 7e1c893..8614bea 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/gus_c/gus_c.h @@ -46,12 +46,12 @@ * @{ * @brief Goodix UART Service Client module. * - * @details The Goodix Uart Service Client contains the APIs and types, which can be used by the - * application to perform scanning, connection and discover Goodix Uart Service at + * @details The Goodix Uart Service Client contains the APIs and types, which can be used by the + * application to perform scanning, connection and discover Goodix Uart Service at * peer and interact with it. * * The application must provide an event handler, then call \ref gus_client_init(). After the - * module can send and receive BLE data, application can call \ref gus_c_tx_data_send() to + * module can send and receive BLE data, application can call \ref gus_c_tx_data_send() to * send data to peer, and receive data from peer \ref GUS_C_EVT_PEER_DATA_RECEIVE, * meanwhile update its received BLE data state \ref gus_c_rx_flow_ctrl_set() to peer. */ @@ -59,33 +59,30 @@ #ifndef __GUS_C_H__ #define __GUS_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup GUS_C_MACRO Defines * @{ */ -#define GUS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of GUS Client connections. */ -#define FLOW_ON 0x01 /**< Indicate that GUS Client can receive data from peer. */ -#define FLOW_OFF 0x00 /**< Indicate that GUS Client can not receive data from peer. */ +#define GUS_C_CONNECTION_MAX 10 /**< Maximum number of GUS Client connections. */ /** * @defgroup GUS_UUID Service and Characteristics UUID * @{ */ -#define GUS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define GUS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x02, 0xED, 0xA6} /**< UUID of GUS Service. */ -#define GUS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define GUS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} /**< UUID of GUS Tx characterisitc. */ -#define GUS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define GUS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} /**< UUID of GUS Rx characterisitc. */ -#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, \ - 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**< UUID of GUS Flow Control characterisitc. */ +#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**< UUID of GUS Flow Control characterisitc. */ /** @} */ /** @} */ @@ -94,11 +91,11 @@ * @{ */ /**@brief Goodix UART Service Client event type. */ -typedef enum { +typedef enum +{ GUS_C_EVT_INVALID, /**< Invalid GUS Client event. */ GUS_C_EVT_DISCOVERY_COMPLETE, /**< GUS Client has found service and its characteristics at peer. */ - GUS_C_EVT_DISCOVERY_FAIL, /**< GUS Client found THS service failed because of invalid operation \ - or no found at peer. */ + GUS_C_EVT_DISCOVERY_FAIL, /**< GUS Client found THS service failed because of invalid operation or no found at peer. */ GUS_C_EVT_TX_NTF_SET_SUCCESS, /**< GUS Client has set peer Tx notify. */ GUS_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS, /**< GUS Client has set peer ble flow control notify. */ GUS_C_EVT_PEER_DATA_RECEIVE, /**< GUS Client has received something from peer. */ @@ -108,6 +105,15 @@ typedef enum { GUS_C_EVT_RX_FLOW_UPDATE_CPLT, /**< GUS CLient has updated flow control to peer completely. */ GUS_C_EVT_WRITE_OP_ERR, /**< Error occured when GUS Client wrote to peer. */ } gus_c_evt_type_t; + +/**@brief Flow control state for GUS Client service. */ +enum gus_c_flow_ctrl_state +{ + GUS_C_FLOW_CTRL_STATE_OFF = 0, /**< Indicate that GUS Client can not receive data from peer. */ + GUS_C_FLOW_CTRL_STATE_ON /**< Indicate that GUS Client can receive data from peer. */ +}; +/**@brief Underlying type used for the GUS Client flow control state. */ +typedef uint8_t gus_c_flow_ctrl_state_t; /** @} */ /** @@ -115,19 +121,20 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t gus_srvc_start_handle; /**< GUS Service start handle. */ uint16_t gus_srvc_end_handle; /**< GUS Service end handle. */ uint16_t gus_tx_handle; /**< Handle of GUS Tx characteristic as provided by a discovery. */ uint16_t gus_tx_cccd_handle; /**< Handle of CCCD of GUS Tx characteristic as provided by a discovery. */ uint16_t gus_rx_handle; /**< Handle of GUS Rx characteristic as provided by a discovery. */ uint16_t gus_flow_ctrl_handle; /**< Handle of GUS Flow Control characteristic as provided by a discovery. */ - uint16_t gus_flow_ctrl_cccd_handle; /**< Handle of CCCD of GUS Flow Control characteristic \ - as provided by a discovery. */ + uint16_t gus_flow_ctrl_cccd_handle; /**< Handle of CCCD of GUS Flow Control characteristic as provided by a discovery. */ } gus_c_handles_t; /**@brief Goodix UART Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< Connection index. */ gus_c_evt_type_t evt_type; /**< GUS Client event type. */ uint16_t length; /**< Length of event data. */ @@ -216,7 +223,7 @@ sdk_err_t gus_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) * @return Result of sending gus_c Rx flow control state. ***************************************************************************************** */ -sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl); +sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, gus_c_flow_ctrl_state_t flow_ctrl); /** @} */ #endif /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/BUILD.gn new file mode 100644 index 0000000..a446d70 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hids") { + sources = [ "hids.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.c index 3fb5d2d..ded7a80 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.c @@ -43,28 +43,17 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define INDEX_0 0 -#define INDEX_1 1 -#define INDEX_2 2 -#define INDEX_3 3 -#define INDEX_4 4 + /* * DEFINES ******************************************************************************* */ #define IN_REPORT_MAX_COUNT 3 /**< Maximum support input report count. */ -/**< Maximum size of a Boot Keyboard Input Report (as per Appendix B in Device Class Definition - * for Human Interface Devices (HID), Version 1.11). */ -#define HIDS_BOOT_KB_IN_REPORT_MAX_SIZE 8 -/**< Maximum size of a Boot Keyboard Output Report (as per Appendix B in Device Class Definition - * for Human Interface Devices (HID), Version 1.11). */ -#define HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE 1 -/**< Minimum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition - * for Human Interface Devices (HID), Version 1.11). */ -#define HIDS_BOOT_MOUSE_IN_REPORT_MIN_SIZE 3 -/**< Maximum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition - * for Human Interface Devices (HID), Version 1.11). */ -#define HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE 8 + +#define HIDS_BOOT_KB_IN_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Keyboard Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE 1 /**< Maximum size of a Boot Keyboard Output Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define HIDS_BOOT_MOUSE_IN_REPORT_MIN_SIZE 3 /**< Minimum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ // Protocol Mode values @@ -74,79 +63,77 @@ // HID Control Point values #define HIDS_CONTROL_POINT_SUSPEND 0x00 /**< Suspend command. */ #define HIDS_CONTROL_POINT_EXIT_SUSPEND 0x01 /**< Exit Suspend command. */ -/**< Default value for the Protocol Mode characteristic. */ -#define DEFAULT_PROTOCOL_MODE PROTOCOL_MODE_REPORT -/**< Initial value for the HID Control Point characteristic. */ -#define INITIAL_VALUE_HID_CONTROL_POINT HIDS_CONTROL_POINT_SUSPEND -#define REPORT_CNT_0 0 -#define REPORT_CNT_1 1 -#define REPORT_CNT_2 2 + +#define DEFAULT_PROTOCOL_MODE PROTOCOL_MODE_REPORT /**< Default value for the Protocol Mode characteristic. */ +#define INITIAL_VALUE_HID_CONTROL_POINT HIDS_CONTROL_POINT_SUSPEND /**< Initial value for the HID Control Point characteristic. */ + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief HIDS Attributes database index list. */ -enum hids_attr_idx_tag { +enum hids_attr_idx_tag +{ // Service - HIDS_IDX_SVC, + HIDS_IDX_SVC, // Protocol Mode characteristic - HIDS_IDX_PROTOCOL_MODE_CHAR, - HIDS_IDX_PROTOCOL_MODE_VAL, + HIDS_IDX_PROTOCOL_MODE_CHAR, + HIDS_IDX_PROTOCOL_MODE_VAL, + + //Input Report1 characteristics + HIDS_IDX_INPUT1_REPORT_CHAR, + HIDS_IDX_INPUT1_REPORT_VAL, + HIDS_IDX_INPUT1_REPORT_CCCD, + HIDS_IDX_INPUT1_REPORT_REF, + + //Input Report2 characteristics + HIDS_IDX_INPUT2_REPORT_CHAR, + HIDS_IDX_INPUT2_REPORT_VAL, + HIDS_IDX_INPUT2_REPORT_CCCD, + HIDS_IDX_INPUT2_REPORT_REF, + + //Input Report3 characteristics + HIDS_IDX_INPUT3_REPORT_CHAR, + HIDS_IDX_INPUT3_REPORT_VAL, + HIDS_IDX_INPUT3_REPORT_CCCD, + HIDS_IDX_INPUT3_REPORT_REF, + + //Output Report characteristics + HIDS_IDX_OUTPUT_REPORT_CHAR, + HIDS_IDX_OUTPUT_REPORT_VAL, + HIDS_IDX_OUTPUT_REPORT_REF, - // Input Report1 characteristics - HIDS_IDX_INPUT1_REPORT_CHAR, - HIDS_IDX_INPUT1_REPORT_VAL, - HIDS_IDX_INPUT1_REPORT_CCCD, - HIDS_IDX_INPUT1_REPORT_REF, + //Feature Report characteristic + HIDS_IDX_FEATURE_REPORT_CHAR, + HIDS_IDX_FEATURE_REPORT_VAL, + HIDS_IDX_FEATURE_REPORT_REF, - // Input Report2 characteristics - HIDS_IDX_INPUT2_REPORT_CHAR, - HIDS_IDX_INPUT2_REPORT_VAL, - HIDS_IDX_INPUT2_REPORT_CCCD, - HIDS_IDX_INPUT2_REPORT_REF, - - // Input Report3 characteristics - HIDS_IDX_INPUT3_REPORT_CHAR, - HIDS_IDX_INPUT3_REPORT_VAL, - HIDS_IDX_INPUT3_REPORT_CCCD, - HIDS_IDX_INPUT3_REPORT_REF, - - // Output Report characteristics - HIDS_IDX_OUTPUT_REPORT_CHAR, - HIDS_IDX_OUTPUT_REPORT_VAL, - HIDS_IDX_OUTPUT_REPORT_REF, - - // Feature Report characteristic - HIDS_IDX_FEATURE_REPORT_CHAR, - HIDS_IDX_FEATURE_REPORT_VAL, - HIDS_IDX_FEATURE_REPORT_REF, - - // Report Map characteristic - HIDS_IDX_REPORT_MAP_CHAR, - HIDS_IDX_REPORT_MAP_VAL, - - // Boot Keyboard Input Report characteristic - HIDS_IDX_BOOT_KB_IN_RPT_CHAR, - HIDS_IDX_BOOT_KB_IN_RPT_VAL, - HIDS_IDX_BOOT_KB_IN_RPT_CCCD, - - // Boot Keyboard Output Report characteristic + //Report Map characteristic + HIDS_IDX_REPORT_MAP_CHAR, + HIDS_IDX_REPORT_MAP_VAL, + + //Boot Keyboard Input Report characteristic + HIDS_IDX_BOOT_KB_IN_RPT_CHAR, + HIDS_IDX_BOOT_KB_IN_RPT_VAL, + HIDS_IDX_BOOT_KB_IN_RPT_CCCD, + + //Boot Keyboard Output Report characteristic HIDS_IDX_BOOT_KB_OUT_RPT_CHAR, HIDS_IDX_BOOT_KB_OUT_RPT_VAL, - + // Boot Mouse Input Report characteristic. - HIDS_IDX_BOOT_MS_IN_RPT_CHAR, - HIDS_IDX_BOOT_MS_IN_RPT_VAL, - HIDS_IDX_BOOT_MS_IN_RPT_CCCD, + HIDS_IDX_BOOT_MS_IN_RPT_CHAR, + HIDS_IDX_BOOT_MS_IN_RPT_VAL, + HIDS_IDX_BOOT_MS_IN_RPT_CCCD, + + //HID Information characteristic + HIDS_IDX_HID_INFO_CHAR, + HIDS_IDX_HID_INFO_VAL, - // HID Information characteristic - HIDS_IDX_HID_INFO_CHAR, - HIDS_IDX_HID_INFO_VAL, - - // HID Control Point characteristic - HIDS_IDX_CTRL_POINT_CHAR, - HIDS_IDX_CTRL_POINT_VAL, + //HID Control Point characteristic + HIDS_IDX_CTRL_POINT_CHAR, + HIDS_IDX_CTRL_POINT_VAL, HIDS_IDX_NB, }; @@ -155,258 +142,147 @@ enum hids_attr_idx_tag { * STRUCT DEFINE ******************************************************************************* */ -/**@brief Heart Rate Service environment variable. */ -struct hids_env_t { - hids_init_t hids_init; /**< HID Service Init Value. */ - uint16_t start_hdl; /**< HID Service start handle. */ - uint8_t - char_mask[5]; /**< Mask of Supported characteristics*/ - uint16_t - input_cccd[IN_REPORT_MAX_COUNT][HIDS_CONNECTION_MAX]; /**< Input report characteristics cccd value*/ - uint16_t - kb_input_cccd[HIDS_CONNECTION_MAX]; /**< Boot keyboard input report characteristics cccd value*/ - uint16_t - mouse_input_cccd[HIDS_CONNECTION_MAX]; /**< Boot mouse input report characteristics cccd value*/ +/**@brief Hid Service environment variable. */ +struct hids_env_t +{ + hids_init_t hids_init; /**< HID Service Init Value. */ + uint16_t start_hdl; /**< HID Service start handle. */ + uint8_t char_mask[5]; /**< Mask of Supported characteristics*/ + uint16_t input_cccd[IN_REPORT_MAX_COUNT][HIDS_CONNECTION_MAX]; /**< Input report characteristics cccd value*/ + uint16_t kb_input_cccd[HIDS_CONNECTION_MAX]; /**< Boot keyboard input report characteristics cccd value*/ + uint16_t mouse_input_cccd[HIDS_CONNECTION_MAX]; /**< Boot mouse input report characteristics cccd value*/ uint8_t protocol_mode; /**< Protocol mode. */ uint8_t ctrl_pt; /**< HID Control Point. */ - uint8_t - input_report_val[IN_REPORT_MAX_COUNT][HIDS_REPORT_MAX_SIZE]; /**< Input report characteristics value*/ - uint8_t - output_report_val[HIDS_REPORT_MAX_SIZE]; /**< Output report characteristic value*/ - uint8_t - feature_report_val[HIDS_REPORT_MAX_SIZE]; /**< Feature report characteristic value*/ - uint8_t - kb_input_report_val[HIDS_BOOT_KB_IN_REPORT_MAX_SIZE]; /**< Boot keyboard input report characteristics value*/ - uint8_t - kb_output_report_val[HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE]; /**< Boot keyboard output report characteristics value*/ - uint8_t - mouse_input_report_val[HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE]; /**< Boot mouse input report characteristics value*/ + uint8_t input_report_val[IN_REPORT_MAX_COUNT][HIDS_REPORT_MAX_SIZE]; /**< Input report characteristics value*/ + uint8_t output_report_val[HIDS_REPORT_MAX_SIZE]; /**< Output report characteristic value*/ + uint8_t feature_report_val[HIDS_REPORT_MAX_SIZE]; /**< Feature report characteristic value*/ + uint8_t kb_input_report_val[HIDS_BOOT_KB_IN_REPORT_MAX_SIZE]; /**< Boot keyboard input report characteristics value*/ + uint8_t kb_output_report_val[HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE]; /**< Boot keyboard output report characteristics value*/ + uint8_t mouse_input_report_val[HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE]; /**< Boot mouse input report characteristics value*/ + ble_gatts_create_db_t hids_gatts_db; /**< Hid Service attributs database. */ }; - -/* - * LOCAL FUNCTION DECLARATIONS - ***************************************************************************************** - */ -static sdk_err_t hids_init(void); -static void hids_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void hids_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void hids_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); - /* * LOCAL VARIABLE DEFINITIONS ******************************************************************************* */ static struct hids_env_t s_hids_env; - +static const uint8_t s_hids_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HID); /**@brief Full HID Service Database Description - Used to add attributes into the database. */ -static const attm_desc_t hids_attr_tab[HIDS_IDX_NB] = { - // HID Service Declaration - [HIDS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, +static const ble_gatts_attm_desc_t hids_attr_tab[HIDS_IDX_NB] = +{ + //HID Service Declaration + [HIDS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + + //Protocol Mode Characteristic - Declaration + [HIDS_IDX_PROTOCOL_MODE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Protocol Mode Characteristic - Value + [HIDS_IDX_PROTOCOL_MODE_VAL] = {BLE_ATT_CHAR_PROTOCOL_MODE, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(uint8_t)}, + + //Input Report1 Characteristic - Declaration + [HIDS_IDX_INPUT1_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Input Report1 Characteristic - Value + [HIDS_IDX_INPUT1_REPORT_VAL] = {BLE_ATT_CHAR_REPORT, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE}, + //Input Report1 Characteristic - Descriptor: CCCD + [HIDS_IDX_INPUT1_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), 0, 0}, + //Input Report1 Characteristic - Descriptor: Report Reference + [HIDS_IDX_INPUT1_REPORT_REF] = {BLE_ATT_DESC_REPORT_REF, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_report_ref_t)}, + + //Input Report2 Characteristic - Declaration + [HIDS_IDX_INPUT2_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Input Report2 Characteristic - Value + [HIDS_IDX_INPUT2_REPORT_VAL] = {BLE_ATT_CHAR_REPORT, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE}, + //Input Report2 Characteristic - Descriptor: CCCD + [HIDS_IDX_INPUT2_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), 0, 0}, + //Input Report2 Characteristic - Descriptor: Report Reference + [HIDS_IDX_INPUT2_REPORT_REF] = {BLE_ATT_DESC_REPORT_REF, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_report_ref_t)}, + + //Input Report3 Characteristic - Declaration + [HIDS_IDX_INPUT3_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Input Report3 Characteristic - Value + [HIDS_IDX_INPUT3_REPORT_VAL] = {BLE_ATT_CHAR_REPORT, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE}, + //Input Report3 Characteristic - Descriptor: CCCD + [HIDS_IDX_INPUT3_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), 0, 0}, + //Input Report3 Characteristic - Descriptor: Report Reference + [HIDS_IDX_INPUT3_REPORT_REF] = {BLE_ATT_DESC_REPORT_REF, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_report_ref_t)}, - // Protocol Mode Characteristic - Declaration - [HIDS_IDX_PROTOCOL_MODE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Protocol Mode Characteristic - Value - [HIDS_IDX_PROTOCOL_MODE_VAL] = { - BLE_ATT_CHAR_PROTOCOL_MODE, READ_PERM(UNAUTH) | WRITE_CMD_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(uint8_t) - }, + //Output Report Characteristic - Declaration + [HIDS_IDX_OUTPUT_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Output Report Characteristic - Value + [HIDS_IDX_OUTPUT_REPORT_VAL] = {BLE_ATT_CHAR_REPORT, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE}, + //Output Report Characteristic - Descriptor: Report Reference + [HIDS_IDX_OUTPUT_REPORT_REF] = {BLE_ATT_DESC_REPORT_REF, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_report_ref_t)}, - // Input Report1 Characteristic - Declaration - [HIDS_IDX_INPUT1_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Input Report1 Characteristic - Value - [HIDS_IDX_INPUT1_REPORT_VAL] = { - BLE_ATT_CHAR_REPORT, READ_PERM(UNAUTH) | NOTIFY_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE - }, - // Input Report1 Characteristic - Descriptor: CCCD - [HIDS_IDX_INPUT1_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), 0, 0}, - // Input Report1 Characteristic - Descriptor: Report Reference - [HIDS_IDX_INPUT1_REPORT_REF] = { - BLE_ATT_DESC_REPORT_REF, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_report_ref_t) - }, + //Feature Report Characteristic - Declaration + [HIDS_IDX_FEATURE_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Feature Report Characteristic - Value + [HIDS_IDX_FEATURE_REPORT_VAL] = {BLE_ATT_CHAR_REPORT, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE}, + //Feature Report Characteristic - Descriptor: Report Reference + [HIDS_IDX_FEATURE_REPORT_REF] = {BLE_ATT_DESC_REPORT_REF, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_report_ref_t)}, - // Input Report2 Characteristic - Declaration - [HIDS_IDX_INPUT2_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Input Report2 Characteristic - Value - [HIDS_IDX_INPUT2_REPORT_VAL] = { - BLE_ATT_CHAR_REPORT, READ_PERM(UNAUTH) | NOTIFY_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE - }, - // Input Report2 Characteristic - Descriptor: CCCD - [HIDS_IDX_INPUT2_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), 0, 0}, - // Input Report2 Characteristic - Descriptor: Report Reference - [HIDS_IDX_INPUT2_REPORT_REF] = { - BLE_ATT_DESC_REPORT_REF, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_report_ref_t) - }, + + //Report Map Characteristic - Declaration + [HIDS_IDX_REPORT_MAP_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Report Map Characteristic - Value + [HIDS_IDX_REPORT_MAP_VAL] = {BLE_ATT_CHAR_REPORT_MAP, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_REPORT_MAP_MAX_SIZE}, + + //Boot Keyboard Input Report Characteristic - Declaration + [HIDS_IDX_BOOT_KB_IN_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Boot Keyboard Input Report Characteristic - Value + [HIDS_IDX_BOOT_KB_IN_RPT_VAL] = {BLE_ATT_CHAR_BOOT_KB_IN_REPORT, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_BOOT_KB_IN_REPORT_MAX_SIZE}, + //Boot Keyboard Input Report Characteristic - Descriptor: CCCD + [HIDS_IDX_BOOT_KB_IN_RPT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), 0, 0}, - // Input Report3 Characteristic - Declaration - [HIDS_IDX_INPUT3_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Input Report3 Characteristic - Value - [HIDS_IDX_INPUT3_REPORT_VAL] = { - BLE_ATT_CHAR_REPORT, READ_PERM(UNAUTH) | NOTIFY_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE - }, - // Input Report3 Characteristic - Descriptor: CCCD - [HIDS_IDX_INPUT3_REPORT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), 0, 0}, - // Input Report3 Characteristic - Descriptor: Report Reference - [HIDS_IDX_INPUT3_REPORT_REF] = { - BLE_ATT_DESC_REPORT_REF, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_report_ref_t) - }, + //Boot Keyboard Output Report Characteristic - Declaration + [HIDS_IDX_BOOT_KB_OUT_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Boot Keyboard Output Report Characteristic - Value + [HIDS_IDX_BOOT_KB_OUT_RPT_VAL] = {BLE_ATT_CHAR_BOOT_KB_OUT_REPORT, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE}, - // Output Report Characteristic - Declaration - [HIDS_IDX_OUTPUT_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Output Report Characteristic - Value - [HIDS_IDX_OUTPUT_REPORT_VAL] = { - BLE_ATT_CHAR_REPORT, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH) | WRITE_CMD_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE - }, - // Output Report Characteristic - Descriptor: Report Reference - [HIDS_IDX_OUTPUT_REPORT_REF] = { - BLE_ATT_DESC_REPORT_REF, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_report_ref_t) - }, + + //Boot Mouse Input Report Characteristic - Declaration + [HIDS_IDX_BOOT_MS_IN_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //Boot Mouse Input Report Characteristic - Value + [HIDS_IDX_BOOT_MS_IN_RPT_VAL] = {BLE_ATT_CHAR_BOOT_MOUSE_IN_REPORT, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE}, + //Boot Mouse Input Report Characteristic - Descriptor: CCCD + [HIDS_IDX_BOOT_MS_IN_RPT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), 0, 0}, + + //HID Information Characteristic - Declaration + [HIDS_IDX_HID_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + //HID Information Characteristic - Value + [HIDS_IDX_HID_INFO_VAL] = {BLE_ATT_CHAR_HID_INFO, BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(hids_hid_info_t)}, - // Feature Report Characteristic - Declaration - [HIDS_IDX_FEATURE_REPORT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Feature Report Characteristic - Value - [HIDS_IDX_FEATURE_REPORT_VAL] = { - BLE_ATT_CHAR_REPORT, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAX_SIZE - }, - // Feature Report Characteristic - Descriptor: Report Reference - [HIDS_IDX_FEATURE_REPORT_REF] = { - BLE_ATT_DESC_REPORT_REF, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_report_ref_t) - }, - - // Report Map Characteristic - Declaration - [HIDS_IDX_REPORT_MAP_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Report Map Characteristic - Value - [HIDS_IDX_REPORT_MAP_VAL] = { - BLE_ATT_CHAR_REPORT_MAP, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_REPORT_MAP_MAX_SIZE - }, - - // Boot Keyboard Input Report Characteristic - Declaration - [HIDS_IDX_BOOT_KB_IN_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Boot Keyboard Input Report Characteristic - Value - [HIDS_IDX_BOOT_KB_IN_RPT_VAL] = { - BLE_ATT_CHAR_BOOT_KB_IN_REPORT, - READ_PERM(UNAUTH) | NOTIFY_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_BOOT_KB_IN_REPORT_MAX_SIZE - }, - // Boot Keyboard Input Report Characteristic - Descriptor: CCCD - [HIDS_IDX_BOOT_KB_IN_RPT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), 0, 0}, - - // Boot Keyboard Output Report Characteristic - Declaration - [HIDS_IDX_BOOT_KB_OUT_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Boot Keyboard Output Report Characteristic - Value - [HIDS_IDX_BOOT_KB_OUT_RPT_VAL] = { - BLE_ATT_CHAR_BOOT_KB_OUT_REPORT, - READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH) | WRITE_CMD_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE - }, - - // Boot Mouse Input Report Characteristic - Declaration - [HIDS_IDX_BOOT_MS_IN_RPT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // Boot Mouse Input Report Characteristic - Value - [HIDS_IDX_BOOT_MS_IN_RPT_VAL] = { - BLE_ATT_CHAR_BOOT_MOUSE_IN_REPORT, - READ_PERM(UNAUTH) | NOTIFY_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), - ATT_VAL_LOC_USER, HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE - }, - // Boot Mouse Input Report Characteristic - Descriptor: CCCD - [HIDS_IDX_BOOT_MS_IN_RPT_CCCD] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM(UNAUTH) | WRITE_REQ_PERM(UNAUTH), 0, 0}, - - // HID Information Characteristic - Declaration - [HIDS_IDX_HID_INFO_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // HID Information Characteristic - Value - [HIDS_IDX_HID_INFO_VAL] = { - BLE_ATT_CHAR_HID_INFO, READ_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(hids_hid_info_t) - }, - - // HID Control Point Characteristic - Declaration - [HIDS_IDX_CTRL_POINT_CHAR] = { - BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, - 0, 0 - }, - // HID Control Point Characteristic - Value - [HIDS_IDX_CTRL_POINT_VAL] = { - BLE_ATT_CHAR_HID_CTNL_PT, WRITE_CMD_PERM(UNAUTH), - ATT_VAL_LOC_USER, sizeof(uint8_t) - }, -}; - -/**@brief HIDS interface required by profile manager. */ -static ble_prf_manager_cbs_t hids_mgr_cbs = { - (prf_init_func_t)hids_init, - NULL, - NULL -}; - -/**@brief HIDS GATT server Callbacks. */ -static gatts_prf_cbs_t hids_gatts_cbs = { - hids_read_att_cb, - hids_write_att_cb, - NULL, - NULL, - hids_cccd_set_cb -}; - -/**@brief HIDS Information. */ -static const prf_server_info_t hids_prf_info = { - .max_connection_nb = HIDS_CONNECTION_MAX, - .manager_cbs = &hids_mgr_cbs, - .gatts_prf_cbs = &hids_gatts_cbs + //HID Control Point Characteristic - Declaration + [HIDS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, + 0, 0}, + //HID Control Point Characteristic - Value + [HIDS_IDX_CTRL_POINT_VAL] = {BLE_ATT_CHAR_HID_CTNL_PT, BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, sizeof(uint8_t)}, }; /* * LOCAL FUNCTION DEFINITIONS ******************************************************************************* */ - -/** - ***************************************************************************************** - * @brief Initialize HID service and create db in att. - * - * @return BLE_ATT_ERR_NO_ERROR on success, otherwise error code. - ***************************************************************************************** - */ -static sdk_err_t hids_init(void) -{ - const uint8_t hids_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HID); - gatts_create_db_t gatts_db; - uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out - * parameter of ble_gatts_srvc_db_create(). - * It must be set with PRF_INVALID_HANDLE - * to be allocated automatically by BLE Stack. */ - sdk_err_t ret; - ret = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = (uint8_t*)hids_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t*)&s_hids_env.char_mask; - gatts_db.max_nb_attr = HIDS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = hids_attr_tab; - - sdk_err_t status = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == status) { - s_hids_env.start_hdl = *gatts_db.shdl; - } - return status; -} - /** ***************************************************************************************** * @brief Handles reception of the read request. @@ -415,129 +291,130 @@ static sdk_err_t hids_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void hids_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void hids_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_hids_env.start_hdl, - HIDS_IDX_NB, - (uint8_t *)&s_hids_env.char_mask); - gatts_read_cfm_t cfm; + HIDS_IDX_NB, + (uint8_t *)&s_hids_env.char_mask); + ble_gatts_read_cfm_t cfm; cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch(tab_index) + { case HIDS_IDX_PROTOCOL_MODE_VAL: cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)(&s_hids_env.protocol_mode); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_INPUT1_REPORT_VAL: - cfm.length = s_hids_env.hids_init.input_report_array[INDEX_0].value_len; - cfm.value = (uint8_t *)(&s_hids_env.input_report_val[INDEX_0]); + cfm.length = s_hids_env.hids_init.input_report_array[0].value_len; + cfm.value = (uint8_t *)(&s_hids_env.input_report_val[0]); break; - + case HIDS_IDX_INPUT1_REPORT_CCCD: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)(&s_hids_env.input_cccd[INDEX_0][conn_idx]); + cfm.value = (uint8_t *)(&s_hids_env.input_cccd[0][conn_idx]); break; - + case HIDS_IDX_INPUT1_REPORT_REF: cfm.length = sizeof(hids_report_ref_t); - cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[INDEX_0].ref); + cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[0].ref); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_INPUT2_REPORT_VAL: - cfm.length = s_hids_env.hids_init.input_report_array[INDEX_1].value_len; - cfm.value = (uint8_t *)(&s_hids_env.input_report_val[INDEX_1]); + cfm.length = s_hids_env.hids_init.input_report_array[1].value_len; + cfm.value = (uint8_t *)(&s_hids_env.input_report_val[1]); break; - + case HIDS_IDX_INPUT2_REPORT_CCCD: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)(&s_hids_env.input_cccd[INDEX_1][conn_idx]); + cfm.value = (uint8_t *)(&s_hids_env.input_cccd[1][conn_idx]); break; - + case HIDS_IDX_INPUT2_REPORT_REF: cfm.length = sizeof(hids_report_ref_t); - cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[INDEX_1].ref); + cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[1].ref); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_INPUT3_REPORT_VAL: - cfm.length = s_hids_env.hids_init.input_report_array[INDEX_2].value_len; - cfm.value = (uint8_t *)(&s_hids_env.input_report_val[INDEX_2]); + cfm.length = s_hids_env.hids_init.input_report_array[2].value_len; + cfm.value = (uint8_t *)(&s_hids_env.input_report_val[2]); break; - + case HIDS_IDX_INPUT3_REPORT_CCCD: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)(&s_hids_env.input_cccd[INDEX_2][conn_idx]); + cfm.value = (uint8_t *)(&s_hids_env.input_cccd[2][conn_idx]); break; - + case HIDS_IDX_INPUT3_REPORT_REF: cfm.length = sizeof(hids_report_ref_t); - cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[INDEX_2].ref); + cfm.value = (uint8_t *)(&s_hids_env.hids_init.input_report_array[2].ref); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_OUTPUT_REPORT_VAL: cfm.length = s_hids_env.hids_init.output_report.value_len; cfm.value = (uint8_t *)(&s_hids_env.output_report_val); break; - + case HIDS_IDX_OUTPUT_REPORT_REF: cfm.length = sizeof(hids_report_ref_t); cfm.value = (uint8_t *)(&s_hids_env.hids_init.output_report.ref); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_FEATURE_REPORT_VAL: cfm.length = s_hids_env.hids_init.feature_report.value_len; cfm.value = (uint8_t *)(&s_hids_env.feature_report_val); break; - - case HIDS_IDX_FEATURE_REPORT_REF: + + case HIDS_IDX_FEATURE_REPORT_REF: cfm.length = sizeof(hids_report_ref_t); cfm.value = (uint8_t *)(&s_hids_env.hids_init.feature_report.ref); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_REPORT_MAP_VAL: cfm.length = s_hids_env.hids_init.report_map.len; cfm.value = (uint8_t *)(s_hids_env.hids_init.report_map.p_map); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_BOOT_KB_IN_RPT_VAL: cfm.length = HIDS_BOOT_KB_IN_REPORT_MAX_SIZE; cfm.value = (uint8_t *)(&s_hids_env.kb_input_report_val); break; - + case HIDS_IDX_BOOT_KB_IN_RPT_CCCD: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)(&s_hids_env.kb_input_cccd[conn_idx]); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_BOOT_KB_OUT_RPT_VAL: cfm.length = HIDS_IDX_BOOT_KB_IN_RPT_VAL; cfm.value = (uint8_t *)(&s_hids_env.kb_output_report_val); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_BOOT_MS_IN_RPT_VAL: cfm.length = HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE; cfm.value = (uint8_t *)(&s_hids_env.mouse_input_report_val); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_BOOT_MS_IN_RPT_CCCD: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_hids_env.mouse_input_cccd[conn_idx]; break; - /*----------------------------------------------------------------------------------*/ - +/*----------------------------------------------------------------------------------*/ + case HIDS_IDX_HID_INFO_VAL: cfm.length = sizeof(hids_hid_info_t); cfm.value = (uint8_t *)(&s_hids_env.hids_init.hid_info); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ case HIDS_IDX_CTRL_POINT_VAL: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)(&s_hids_env.ctrl_pt); break; - /*----------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------*/ default: cfm.length = 0; cfm.status = BLE_ATT_ERR_INVALID_HANDLE; @@ -557,8 +434,8 @@ static void hids_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para static void hids_cccd_check(hids_evt_t *p_evt, uint16_t cccd_value) { p_evt->evt_type = ((cccd_value == PRF_CLI_START_NTF) ? - HIDS_EVT_IN_REP_NOTIFY_ENABLED : - HIDS_EVT_IN_REP_NOTIFY_DISABLED); + HIDS_EVT_IN_REP_NOTIFY_ENABLED : + HIDS_EVT_IN_REP_NOTIFY_DISABLED); } /** @@ -573,31 +450,32 @@ static void hids_cccd_check(hids_evt_t *p_evt, uint16_t cccd_value) */ static void hids_on_cccd_write(uint8_t tab_index, uint8_t conn_idx, hids_evt_t *p_evt, uint16_t cccd_value) { - switch (tab_index) { + switch (tab_index) + { case HIDS_IDX_INPUT1_REPORT_CCCD: - s_hids_env.input_cccd[INDEX_0][conn_idx] = cccd_value; + s_hids_env.input_cccd[0][conn_idx] = cccd_value; p_evt->report_type = HIDS_REPORT_TYPE_IN1; hids_cccd_check(p_evt, cccd_value); break; - + case HIDS_IDX_INPUT2_REPORT_CCCD: - s_hids_env.input_cccd[INDEX_1][conn_idx] = cccd_value; + s_hids_env.input_cccd[1][conn_idx] = cccd_value; p_evt->report_type = HIDS_REPORT_TYPE_IN2; hids_cccd_check(p_evt, cccd_value); break; - + case HIDS_IDX_INPUT3_REPORT_CCCD: - s_hids_env.input_cccd[INDEX_2][conn_idx] = cccd_value; + s_hids_env.input_cccd[2][conn_idx] = cccd_value; p_evt->report_type = HIDS_REPORT_TYPE_IN3; hids_cccd_check(p_evt, cccd_value); break; - + case HIDS_IDX_BOOT_KB_IN_RPT_CCCD: s_hids_env.kb_input_cccd[conn_idx] = cccd_value; p_evt->report_type = HIDS_REPORT_TYPE_KB_IN; hids_cccd_check(p_evt, cccd_value); break; - + case HIDS_IDX_BOOT_MS_IN_RPT_CCCD: s_hids_env.mouse_input_cccd[conn_idx] = cccd_value; p_evt->report_type = HIDS_REPORT_TYPE_MOUSE_IN; @@ -617,10 +495,12 @@ static void hids_on_cccd_write(uint8_t tab_index, uint8_t conn_idx, hids_evt_t * * @param[in] p_param Pointer to the parameters of the write request. ***************************************************************************************** */ -static void hids_on_protocol_mode_write(hids_evt_t *p_evt, const gatts_write_req_cb_t *p_param) +static void hids_on_protocol_mode_write(hids_evt_t *p_evt, const ble_gatts_evt_write_t *p_param) { - if (p_param->length == 1) { - switch (p_param->value[INDEX_0]) { + if (p_param->length == 1) + { + switch (p_param->value[0]) + { case PROTOCOL_MODE_BOOT: p_evt->evt_type = HIDS_EVT_BOOT_MODE_ENTERED; break; @@ -632,7 +512,7 @@ static void hids_on_protocol_mode_write(hids_evt_t *p_evt, const gatts_write_req default: break; } - s_hids_env.protocol_mode = p_param->value[INDEX_0]; + s_hids_env.protocol_mode = p_param->value[0]; } } @@ -644,10 +524,12 @@ static void hids_on_protocol_mode_write(hids_evt_t *p_evt, const gatts_write_req * @param[in] p_param Pointer to the parameters of the write request. ***************************************************************************************** */ -static void hids_on_control_point_write(hids_evt_t *p_evt, const gatts_write_req_cb_t *p_param) +static void hids_on_control_point_write(hids_evt_t *p_evt, const ble_gatts_evt_write_t *p_param) { - if (p_param->length == 1) { - switch (p_param->value[INDEX_0]) { + if (p_param->length == 1) + { + switch (p_param->value[0]) + { case HIDS_CONTROL_POINT_SUSPEND: p_evt->evt_type = HIDS_EVT_HOST_SUSP; break; @@ -659,11 +541,10 @@ static void hids_on_control_point_write(hids_evt_t *p_evt, const gatts_write_req default: break; } - s_hids_env.ctrl_pt = p_param->value[INDEX_0]; + s_hids_env.ctrl_pt = p_param->value[0]; } } - /** ***************************************************************************************** * @brief Handles reception of the write request. @@ -672,146 +553,122 @@ static void hids_on_control_point_write(hids_evt_t *p_evt, const gatts_write_req * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void hids_write_att_cb(uint8_t conn_idx, - const gatts_write_req_cb_t *p_param) +static void hids_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_hids_env.start_hdl, - HIDS_IDX_NB, - (uint8_t *)&s_hids_env.char_mask); + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_hids_env.start_hdl, + HIDS_IDX_NB, + (uint8_t *)&s_hids_env.char_mask); uint16_t cccd_value; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; hids_evt_t evt; - uint8_t ret; - + evt.evt_type = HIDS_EVT_INVALID; evt.offset = p_param->offset; evt.len = p_param->length; evt.data = p_param->value; cfm.handle = handle; cfm.status = BLE_SUCCESS; - - switch (tab_index) { + + switch(tab_index) + { case HIDS_IDX_PROTOCOL_MODE_VAL: hids_on_protocol_mode_write(&evt, p_param); break; - + case HIDS_IDX_INPUT1_REPORT_CCCD: case HIDS_IDX_INPUT2_REPORT_CCCD: case HIDS_IDX_INPUT3_REPORT_CCCD: case HIDS_IDX_BOOT_KB_IN_RPT_CCCD: case HIDS_IDX_BOOT_MS_IN_RPT_CCCD: - cccd_value = le16toh(&p_param->value[INDEX_0]); + cccd_value = le16toh(&p_param->value[0]); hids_on_cccd_write(tab_index, conn_idx, &evt, cccd_value); break; - + case HIDS_IDX_INPUT1_REPORT_VAL: - if ((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[INDEX_0].value_len) { - ret = memcp_s(&s_hids_env.input_report_val[INDEX_0][p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[0].value_len) + { + memcpy(&s_hids_env.input_report_val[0][p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_IN1; } break; - + case HIDS_IDX_INPUT2_REPORT_VAL: - if ((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[INDEX_1].value_len) { - ret = memcpy_s(&s_hids_env.input_report_val[INDEX_1][p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[1].value_len) + { + memcpy(&s_hids_env.input_report_val[1][p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_IN2; } break; - + case HIDS_IDX_INPUT3_REPORT_VAL: - if ((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[INDEX_2].value_len) { - ret = memcpy_s(&s_hids_env.input_report_val[INDEX_2][p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= s_hids_env.hids_init.input_report_array[2].value_len) + { + memcpy(&s_hids_env.input_report_val[2][p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_IN3; } break; - + case HIDS_IDX_OUTPUT_REPORT_VAL: - if ((p_param->offset + p_param->length) <= s_hids_env.hids_init.output_report.value_len) { - ret = memcpy_s(&s_hids_env.output_report_val[p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= s_hids_env.hids_init.output_report.value_len) + { + memcpy(&s_hids_env.output_report_val[p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_OUT; } break; - - case HIDS_IDX_FEATURE_REPORT_VAL: - if ((p_param->offset + p_param->length) <= s_hids_env.hids_init.feature_report.value_len) { - ret = memcpy_s(&s_hids_env.feature_report_val[p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + + case HIDS_IDX_FEATURE_REPORT_VAL: + if((p_param->offset + p_param->length) <= s_hids_env.hids_init.feature_report.value_len) + { + memcpy(&s_hids_env.feature_report_val[p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_FEATURE; } break; - - case HIDS_IDX_BOOT_KB_IN_RPT_VAL: - if ((p_param->offset + p_param->length) <= HIDS_BOOT_KB_IN_REPORT_MAX_SIZE) { - ret = memcpy_s(&s_hids_env.kb_input_report_val[p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + + case HIDS_IDX_BOOT_KB_IN_RPT_VAL: + if((p_param->offset + p_param->length) <= HIDS_BOOT_KB_IN_REPORT_MAX_SIZE) + { + memcpy(&s_hids_env.kb_input_report_val[p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_KB_IN; } - break; + break; case HIDS_IDX_BOOT_KB_OUT_RPT_VAL: - if ((p_param->offset + p_param->length) <= HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE) { - ret = memcpy_s(&s_hids_env.kb_output_report_val[p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= HIDS_BOOT_KB_OUT_REPORT_MAX_SIZE) + { + memcpy(&s_hids_env.kb_output_report_val[p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_KB_OUT; } break; case HIDS_IDX_BOOT_MS_IN_RPT_VAL: - if ((p_param->offset + p_param->length) <= HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE) { - ret = memcpy_s(&s_hids_env.mouse_input_report_val[p_param->offset], p_param->length, - p_param->value, p_param->length); - if (ret < 0) { - return ret; - } + if((p_param->offset + p_param->length) <= HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE) + { + memcpy(&s_hids_env.mouse_input_report_val[p_param->offset], p_param->value, p_param->length); evt.evt_type = HIDS_EVT_REP_CHAR_WRITE; evt.report_type = HIDS_REPORT_TYPE_MOUSE_IN; } break; - + case HIDS_IDX_CTRL_POINT_VAL: hids_on_control_point_write(&evt, p_param); break; - + default: cfm.status = BLE_ATT_ERR_INVALID_HANDLE; break; } - + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && \ - HIDS_EVT_INVALID != evt.evt_type && \ - s_hids_env.hids_init.evt_handler) { + HIDS_EVT_INVALID != evt.evt_type && \ + s_hids_env.hids_init.evt_handler) + { evt.conn_idx = conn_idx; s_hids_env.hids_init.evt_handler(&evt); } @@ -819,7 +676,6 @@ static void hids_write_att_cb(uint8_t conn_idx, ble_gatts_write_cfm(conn_idx, &cfm); } - /** ***************************************************************************************** * @brief Handles reception of the cccd recover request. @@ -829,21 +685,23 @@ static void hids_write_att_cb(uint8_t conn_idx, * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void hids_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void hids_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { hids_evt_t evt; evt.evt_type = HIDS_EVT_INVALID; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_hids_env.start_hdl, - HIDS_IDX_NB, - (uint8_t *)&s_hids_env.char_mask); - hids_on_cccd_write(tab_index, conn_idx, &evt, cccd_value); + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_hids_env.start_hdl, + HIDS_IDX_NB, + (uint8_t *)&s_hids_env.char_mask); + hids_on_cccd_write(tab_index, conn_idx, &evt, cccd_value); if (HIDS_EVT_INVALID != evt.evt_type && \ - s_hids_env.hids_init.evt_handler) { + s_hids_env.hids_init.evt_handler) + { evt.conn_idx = conn_idx; s_hids_env.hids_init.evt_handler(&evt); } @@ -858,44 +716,50 @@ static void hids_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va */ static void hids_char_mask_init(hids_init_t *p_hids_init) { - s_hids_env.char_mask[INDEX_0] = 0x01; - s_hids_env.char_mask[INDEX_1] = 0x00; - s_hids_env.char_mask[INDEX_2] = 0x60; - s_hids_env.char_mask[INDEX_3] = 0x80; - s_hids_env.char_mask[INDEX_4] = 0x07; - if (p_hids_init->is_kb || p_hids_init->is_mouse) { - s_hids_env.char_mask[INDEX_0] |= 0x06; - if (p_hids_init->is_kb) { - s_hids_env.char_mask[INDEX_2] |= 0x80; - s_hids_env.char_mask[INDEX_3] |= 0x0f; + s_hids_env.char_mask[0] = 0x01; + s_hids_env.char_mask[1] = 0x00; + s_hids_env.char_mask[2] = 0x60; + s_hids_env.char_mask[3] = 0x80; + s_hids_env.char_mask[4] = 0x07; + if(p_hids_init->is_kb || p_hids_init->is_mouse) + { + s_hids_env.char_mask[0] |= 0x06; + if(p_hids_init->is_kb) + { + s_hids_env.char_mask[2] |= 0x80; + s_hids_env.char_mask[3] |= 0x0f; } - if (p_hids_init->is_mouse) { - s_hids_env.char_mask[INDEX_3] |= 0x70; + if(p_hids_init->is_mouse) + { + s_hids_env.char_mask[3] |= 0x70; } } - switch (p_hids_init->input_report_count) { - case REPORT_CNT_0: // do noting + switch(p_hids_init->input_report_count) + { + case 0://do noting break; - case REPORT_CNT_1: - s_hids_env.char_mask[INDEX_0] |= 0x78; + case 1: + s_hids_env.char_mask[0] |= 0x78; break; - case REPORT_CNT_2: - s_hids_env.char_mask[INDEX_0] |= 0xf8; - s_hids_env.char_mask[INDEX_1] |= 0x07; + case 2: + s_hids_env.char_mask[0] |= 0xf8; + s_hids_env.char_mask[1] |= 0x07; break; - default: // max count is 3 - s_hids_env.char_mask[INDEX_0] |= 0xf8; - s_hids_env.char_mask[INDEX_1] |= 0x7f; + default:// max count is 3 + s_hids_env.char_mask[0] |= 0xf8; + s_hids_env.char_mask[1] |= 0x7f; break; } - - if (p_hids_init->out_report_sup) { - s_hids_env.char_mask[INDEX_1] |= 0x80; - s_hids_env.char_mask[INDEX_2] |= 0x03; + + if(p_hids_init->out_report_sup) + { + s_hids_env.char_mask[1] |= 0x80; + s_hids_env.char_mask[2] |= 0x03; } - - if (p_hids_init->feature_report_sup) { - s_hids_env.char_mask[INDEX_2] |= 0x1c; + + if(p_hids_init->feature_report_sup) + { + s_hids_env.char_mask[2] |= 0x1c; } } @@ -914,56 +778,92 @@ static void hids_char_mask_init(hids_init_t *p_hids_init) static sdk_err_t hids_in_rep_notify(uint8_t conn_idx, uint8_t char_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code; - gatts_noti_ind_t hids_noti; + ble_gatts_noti_ind_t hids_noti; hids_noti.type = BLE_GATT_NOTIFICATION; hids_noti.handle = prf_find_handle_by_idx(char_idx, - s_hids_env.start_hdl, - (uint8_t *)&s_hids_env.char_mask); + s_hids_env.start_hdl, + (uint8_t *)&s_hids_env.char_mask); hids_noti.length = length; hids_noti.value = p_data; error_code = ble_gatts_noti_ind(conn_idx, &hids_noti); + return error_code; } +static void hids_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + hids_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + hids_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + +// case BLE_GATTS_EVT_NTF_IND: +// hids_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); +// break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + hids_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + +// case BLE_GAPC_EVT_DISCONNECTED: +// hids_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); +// break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ******************************************************************************* */ sdk_err_t hids_service_init(hids_init_t *p_hids_init) { - sdk_err_t ret; - if (p_hids_init == NULL) { + if (NULL == p_hids_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_hids_env.hids_init, sizeof(hids_init_t), p_hids_init, sizeof(hids_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_hids_env.hids_init, p_hids_init, sizeof(hids_init_t)); hids_char_mask_init(p_hids_init); s_hids_env.protocol_mode = DEFAULT_PROTOCOL_MODE; s_hids_env.ctrl_pt = INITIAL_VALUE_HID_CONTROL_POINT; - return ble_server_prf_add(&hids_prf_info); + + s_hids_env.start_hdl = PRF_INVALID_HANDLE; + + s_hids_env.hids_gatts_db.shdl = &s_hids_env.start_hdl; + s_hids_env.hids_gatts_db.uuid = s_hids_svc_uuid; + s_hids_env.hids_gatts_db.attr_tab_cfg = (uint8_t *)&(s_hids_env.char_mask); + s_hids_env.hids_gatts_db.max_nb_attr = HIDS_IDX_NB; + s_hids_env.hids_gatts_db.srvc_perm = 0; + s_hids_env.hids_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_hids_env.hids_gatts_db.attr_tab.attr_tab_16 = hids_attr_tab; + + return ble_gatts_prf_add(&s_hids_env.hids_gatts_db, hids_ble_evt_handler); } -sdk_err_t hids_input_rep_send(uint8_t conn_idx, uint8_t rep_idx, uint8_t *p_data, uint16_t uint16_t length) +sdk_err_t hids_input_rep_send(uint8_t conn_idx, uint8_t rep_idx, uint8_t *p_data, uint16_t length) { - uint16_t len = length; - sdk_err_t ret; - static const uint8_t char_idx[] = {HIDS_IDX_INPUT1_REPORT_VAL, - HIDS_IDX_INPUT2_REPORT_VAL, HIDS_IDX_INPUT3_REPORT_VAL}; + static const uint8_t char_idx[] = {HIDS_IDX_INPUT1_REPORT_VAL, HIDS_IDX_INPUT2_REPORT_VAL, HIDS_IDX_INPUT3_REPORT_VAL}; sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - if (rep_idx >= IN_REPORT_MAX_COUNT || p_data == NULL || len == 0) { + if(rep_idx >= IN_REPORT_MAX_COUNT || p_data == NULL || length == 0) + { return SDK_ERR_INVALID_PARAM; } - len = ((length > HIDS_REPORT_MAX_SIZE) ? HIDS_REPORT_MAX_SIZE : len); - ret = memcpy_s(&s_hids_env.input_report_val[rep_idx], len, p_data, len); - if (ret < 0) { - return ret; - } - if (s_hids_env.input_cccd[rep_idx][conn_idx] == PRF_CLI_START_NTF) { - error_code = hids_in_rep_notify(conn_idx, char_idx[rep_idx], p_data, len); + length = ((length > HIDS_REPORT_MAX_SIZE) ? HIDS_REPORT_MAX_SIZE : length); + memcpy(&s_hids_env.input_report_val[rep_idx], p_data, length); + if(s_hids_env.input_cccd[rep_idx][conn_idx] == PRF_CLI_START_NTF) + { + error_code = hids_in_rep_notify(conn_idx, char_idx[rep_idx], p_data, length); } return error_code; } @@ -971,17 +871,15 @@ sdk_err_t hids_input_rep_send(uint8_t conn_idx, uint8_t rep_idx, uint8_t *p_data sdk_err_t hids_boot_kb_in_rep_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - uint16_t len = length; - if (p_data == NULL || len == 0) { + if(p_data == NULL || length == 0) + { return SDK_ERR_INVALID_PARAM; } - len = ((len > HIDS_BOOT_KB_IN_REPORT_MAX_SIZE) ? HIDS_BOOT_KB_IN_REPORT_MAX_SIZE : len); - error_code = memcpy_s(&s_hids_env.kb_input_report_val, len, p_data, len); - if (error_code < 0) { - return error_code; - } - if (s_hids_env.kb_input_cccd[conn_idx] == PRF_CLI_START_NTF) { - error_code = hids_in_rep_notify(conn_idx, HIDS_IDX_BOOT_KB_IN_RPT_VAL, p_data, len); + length = ((length > HIDS_BOOT_KB_IN_REPORT_MAX_SIZE) ? HIDS_BOOT_KB_IN_REPORT_MAX_SIZE : length); + memcpy(&s_hids_env.kb_input_report_val, p_data, length); + if(s_hids_env.kb_input_cccd[conn_idx] == PRF_CLI_START_NTF) + { + error_code = hids_in_rep_notify(conn_idx, HIDS_IDX_BOOT_KB_IN_RPT_VAL, p_data, length); } return error_code; } @@ -989,17 +887,23 @@ sdk_err_t hids_boot_kb_in_rep_send(uint8_t conn_idx, uint8_t *p_data, uint16_t l sdk_err_t hids_boot_mouse_in_rep_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - uint16_t len = length; - if (p_data == NULL || length < HIDS_BOOT_MOUSE_IN_REPORT_MIN_SIZE) { + if(p_data == NULL || length < HIDS_BOOT_MOUSE_IN_REPORT_MIN_SIZE) + { return SDK_ERR_INVALID_PARAM; } - len = ((len > HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE) ? HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE : len); - error_code = memcpy_s(&s_hids_env.mouse_input_report_val, len, p_data, len); - if (error_code < 0) { - return error_code; - } - if (s_hids_env.mouse_input_cccd[conn_idx] == PRF_CLI_START_NTF) { - error_code = hids_in_rep_notify(conn_idx, HIDS_IDX_BOOT_MS_IN_RPT_VAL, p_data, len); + length = ((length > HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE) ? HIDS_BOOT_MOUSE_IN_REPORT_MAX_SIZE : length); + memcpy(&s_hids_env.mouse_input_report_val, p_data, length); + if(s_hids_env.mouse_input_cccd[conn_idx] == PRF_CLI_START_NTF) + { + error_code = hids_in_rep_notify(conn_idx, HIDS_IDX_BOOT_MS_IN_RPT_VAL, p_data, length); } return error_code; } + +uint16_t hids_service_start_handle_get(void) +{ + return s_hids_env.start_hdl; +} + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.h index a9f04cf..adcb5fa 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hids/hids.h @@ -66,21 +66,20 @@ #ifndef __HIDS_H__ #define __HIDS_H__ -#include #include "ble_prf_utils.h" -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup HIDS_MACRO Defines * @{ */ -#define HIDS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Heart Rate Service connections. */ +#define HIDS_CONNECTION_MAX 10 /**< Maximum number of Heart Rate Service connections. */ -#define HIDS_REPORT_MAX_SIZE 20 /**< Maximum length of report. */ -#define HIDS_REPORT_MAP_MAX_SIZE 512 /**< Limitation of length, as per Section 2.6.1 in HIDS Spec, version 1.0 */ +#define HIDS_REPORT_MAX_SIZE 20 /**< Maximum length of report. */ +#define HIDS_REPORT_MAP_MAX_SIZE 512 /**< Limitation of length, as per Section 2.6.1 in HIDS Spec, version 1.0 */ /** * @defgroup HIDS_REPORT_TYPE Report Type values @@ -97,8 +96,8 @@ * @{ * @brief HIDS Information Flags define. */ -#define HID_INFO_FLAG_REMOTE_WAKE_MSK 0x01 /**< Bit mask of Remote Wake flag in HIDS information. */ -#define HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02 /**< Bit mask of Normally Connectable flag in HIDS information. */ +#define HID_INFO_FLAG_REMOTE_WAKE_MSK 0x01 /**< Bit mask of Remote Wake flag in HIDS information. */ +#define HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02 /**< Bit mask of Normally Connectable flag in HIDS information. */ /** @} */ /** @} */ @@ -109,7 +108,8 @@ */ /**@brief HID Service event type. */ -typedef enum { +typedef enum +{ HIDS_EVT_INVALID, /**< Invalid event. */ HIDS_EVT_IN_REP_NOTIFY_ENABLED, /**< Input report notification enabled event. */ HIDS_EVT_IN_REP_NOTIFY_DISABLED, /**< Input report notification disabled event. */ @@ -122,7 +122,8 @@ typedef enum { /**@brief HID Service write report type. */ -typedef enum { +typedef enum +{ HIDS_REPORT_TYPE_RESERVED, /**< The reserved report type. */ HIDS_REPORT_TYPE_IN1, /**< The input report1 type. */ HIDS_REPORT_TYPE_IN2, /**< The input report2 type. */ @@ -142,27 +143,23 @@ typedef enum { */ /**@brief HID Service event. */ -typedef struct { +typedef struct +{ hids_evt_type_t evt_type; /**< Type of event. */ uint8_t conn_idx; /**< Connect index. */ hids_report_type_t report_type; /**< Type of report, see @ref hids_report_type_t. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the incoming data. */ uint8_t const * data; /**< Incoming data, variable length */ -} hids_evt_t; +}hids_evt_t; /**@brief HID Information characteristic value. */ -typedef struct { - uint16_t - bcd_hid; /**< 16-bit unsigned integer representing version number of base USB HID Specification \ - implemented by HID Device */ - uint8_t - b_country_code; /**< Identifies which country the hardware is localized for. \ - Most hardware is not localized and thus this value would be zero (0). */ - uint8_t - flags; /**< See http://developer.bluetooth.org/gatt/characteristics/Pages/ \ - CharacteristicViewer.aspx?u=org.bluetooth.characteristic.hid_information.xml */ -} hids_hid_info_t; +typedef struct +{ + uint16_t bcd_hid; /**< 16-bit unsigned integer representing version number of base USB HID Specification implemented by HID Device */ + uint8_t b_country_code; /**< Identifies which country the hardware is localized for. Most hardware is not localized and thus this value would be zero (0). */ + uint8_t flags; /**< See http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.hid_information.xml */ +}hids_hid_info_t; /**@brief Value of a Report Reference descriptor. @@ -170,22 +167,24 @@ typedef struct { * @details This is mapping information that maps the parent characteristic to the Report ID(s) and * Report Type(s) defined within a Report Map characteristic. */ -typedef struct { - uint8_t report_id; /**< Non-zero value if there is more than one instance of the same Report Type */ - uint8_t report_type; /**< Type of Report characteristic (see @ref HIDS_REPORT_TYPE) */ +typedef struct +{ + uint8_t report_id; /**< Non-zero value if there is more than one instance of the same Report Type */ + uint8_t report_type; /**< Type of Report characteristic (see @ref HIDS_REPORT_TYPE) */ } hids_report_ref_t; /**@brief HID Service Report characteristic define. */ -typedef struct { +typedef struct +{ uint16_t value_len; /**< Length of characteristic value. */ - hids_report_ref_t - ref; /**< Value of a Report Reference descriptor, see @ref hids_report_ref_t. */ + hids_report_ref_t ref; /**< Value of a Report Reference descriptor, see @ref hids_report_ref_t. */ } hids_report_int_t; /**@brief HID Service Report Map characteristic value. */ -typedef struct { +typedef struct +{ uint8_t *p_map; /**< Pointer to the report map. */ uint16_t len; /**< The length of report map. */ } hids_report_map_t; @@ -199,19 +198,18 @@ typedef void (*hids_evt_handler_t)(hids_evt_t *p_evt); /**@brief HID Service initialization variable. */ -typedef struct { - hids_evt_handler_t evt_handler; /**< Handle events in HID Service. */ - bool is_kb; /**< TRUE if device is operating as a keyboard, FALSE if it is not. */ - bool is_mouse; /**< TRUE if device is operating as a mouse, FALSE if it is not. */ - hids_hid_info_t hid_info; /**< Value of HID information characteristic. */ - hids_report_map_t report_map; /**< HID Service Report Map characteristic value. */ - uint8_t input_report_count; /**< Number of Input Report characteristics. */ - hids_report_int_t input_report_array[3]; /**< HID input Report Reference value. */ - bool - out_report_sup; /**< TRUE if output Report characteristic suport, FALSE if it is nonsupport. */ +typedef struct +{ + hids_evt_handler_t evt_handler; /**< Handle events in HID Service. */ + bool is_kb; /**< TRUE if device is operating as a keyboard, FALSE if it is not. */ + bool is_mouse; /**< TRUE if device is operating as a mouse, FALSE if it is not. */ + hids_hid_info_t hid_info; /**< Value of HID information characteristic. */ + hids_report_map_t report_map; /**< HID Service Report Map characteristic value. */ + uint8_t input_report_count; /**< Number of Input Report characteristics. */ + hids_report_int_t input_report_array[3]; /**< HID input Report Reference value. */ + bool out_report_sup; /**< TRUE if output Report characteristic suport, FALSE if it is nonsupport. */ hids_report_int_t output_report; /**< HID output Report Reference value. */ - bool - feature_report_sup; /**< TRUE if feature Report characteristic suport, FALSE if it is nonsupport. */ + bool feature_report_sup; /**< TRUE if feature Report characteristic suport, FALSE if it is nonsupport. */ hids_report_int_t feature_report; /**< HID feature Report Reference value. */ } hids_init_t; /** @} */ @@ -271,6 +269,16 @@ sdk_err_t hids_boot_kb_in_rep_send(uint8_t conn_idx, uint8_t *p_data, uint16_t l ***************************************************************************************** */ sdk_err_t hids_boot_mouse_in_rep_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the hids service start handle . + * + * @return The hids service start handle. + ***************************************************************************************** + */ +uint16_t hids_service_start_handle_get(void); + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/BUILD.gn new file mode 100644 index 0000000..ceeae7e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hrrcps") { + sources = [ "hrrcps.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.c index 1686d90..d2766b5 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.c @@ -3,7 +3,7 @@ * * @file hrrcps.c * - * @brief HRS RSCS Relay Control Point Service Implementation. + * @brief HRS hrrcps Relay Control Point Service Implementation. * **************************************************************************************** * @attention @@ -48,9 +48,9 @@ * DEFINES ***************************************************************************************** */ -#define HRRCPS_CTRL_PT_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ - 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x06, 0xED, 0xA6} -#define HRRCPS_CTRL_PT_RSP_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define HRRCPS_CTRL_PT_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A,0x46, 0x44, 0xD3, 0x02, 0x06, 0xED, 0xA6} +#define HRRCPS_CTRL_PT_RSP_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x06, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ @@ -62,9 +62,10 @@ * ENUMERATIONS **************************************************************************************** */ -/**@brief HRS RSCS Relay Control Point Service Attributes Indexes. */ -enum { - // HRS RSCS Relay Control Point Service +/**@brief HRS hrrcps Relay Control Point Service Attributes Indexes. */ +enum +{ + // HRS hrrcps Relay Control Point Service HRRCPS_IDX_SVC, // HRR Control Point @@ -83,25 +84,19 @@ enum { * STRUCTURES ***************************************************************************************** */ -/**@brief HRS RSCS Relay Control Point Service environment variable. */ -struct hrrcps_env_t { - hrrcps_evt_handler_t - evt_handler; /**< HRS RSCS Relay Control Point Service event handler. */ - uint16_t - start_hdl; /**< HRS RSCS Relay Control Point Service start handle. */ - uint16_t - ctrl_pt_rsp_ind_cfg[HRRCPS_CONNECTION_MAX]; /**< The configuration of Control Point Response \ - which is configured by the peer devices. */ +/**@brief HRS hrrcps Relay Control Point Service environment variable. */ +struct hrrcps_env_t +{ + hrrcps_evt_handler_t evt_handler; /**< HRS hrrcps Relay Control Point Service event handler. */ + uint16_t start_hdl; /**< HRS hrrcps Relay Control Point Service start handle. */ + uint16_t ctrl_pt_rsp_ind_cfg[HRRCPS_CONNECTION_MAX]; /**< The configuration of Control Point Response which is configured by the peer devices. */ + ble_gatts_create_db_t hrrcps_gatts_db; /**< HRS hrrcps Relay Control Point Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t hrrcps_init(void); -static void hrrcps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void hrrcps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void hrrcps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t ctrl_pt_id); /* @@ -110,97 +105,37 @@ static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t */ static struct hrrcps_env_t s_hrrcps_env; static uint16_t s_hrrcps_char_mask = 0x7f; +static const uint8_t s_hrrcps_svc_uuid[] = {HRRCPS_SERVICE_UUID}; /**@brief Full HRRCPS Database Description - Used to add attributes into the database. */ -static const attm_desc_128_t hrrcps_attr_tab[HRRCPS_IDX_NB] = { - // HRS RSCS Relay Control Point Service - [HRRCPS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, +static const ble_gatts_attm_desc_128_t hrrcps_attr_tab[HRRCPS_IDX_NB] = +{ + // HRS hrrcps Relay Control Point Service + [HRRCPS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // HRR Control Point Characteristic - Declaration - [HRRCPS_IDX_HRR_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HRRCPS_IDX_HRR_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // HRR Control Point Characteristic - Value - [HRRCPS_IDX_HRR_CTRL_PT_VAL] = { - HRRCPS_CTRL_PT_CHARACTERISTIC_UUID, - WRITE_REQ_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - HRRCPS_CTRL_PT_VAL_LEN - }, + [HRRCPS_IDX_HRR_CTRL_PT_VAL] = {HRRCPS_CTRL_PT_CHARACTERISTIC_UUID, + BLE_GATTS_WRITE_REQ_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + HRRCPS_CTRL_PT_VAL_LEN}, // HRR Control Point Response Characteristic - Declaration - [HRRCPS_IDX_HRR_CTRL_PT_RSP_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HRRCPS_IDX_HRR_CTRL_PT_RSP_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // HRR Control Point Response Characteristic - Value - [HRRCPS_IDX_HRR_CTRL_PT_RSP_VAL] = { - HRRCPS_CTRL_PT_RSP_CHARACTERISTIC_UUID, - INDICATE_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - HRRCPS_CTRL_PT_RSP_VAL_LEN - }, + [HRRCPS_IDX_HRR_CTRL_PT_RSP_VAL] = {HRRCPS_CTRL_PT_RSP_CHARACTERISTIC_UUID, + BLE_GATTS_INDICATE_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + HRRCPS_CTRL_PT_RSP_VAL_LEN}, // HRR Control Point Responset Characteristic - Client Characteristic Configuration Descriptor - [HRRCPS_IDX_HRR_CTRL_PT_RSP_CFG] = {ATT_128_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, -}; - -/**@brief HRRCPS Service interface required by profile manager. */ -static ble_prf_manager_cbs_t hrrcps_mgr_cbs = { - (prf_init_func_t)hrrcps_init, - NULL, - NULL -}; - -/**@brief HRRCPS GATT Server Callbacks. */ -static gatts_prf_cbs_t hrrcps_gatts_cbs = { - hrrcps_read_att_cb, - hrrcps_write_att_cb, - NULL, - NULL, - hrrcps_cccd_set_cb -}; - -/**@brief HRRCPS Service Information. */ -static const prf_server_info_t hrrcps_prf_info = { - .max_connection_nb = HRRCPS_CONNECTION_MAX, - .manager_cbs = &hrrcps_mgr_cbs, - .gatts_prf_cbs = &hrrcps_gatts_cbs + [HRRCPS_IDX_HRR_CTRL_PT_RSP_CFG] = {ATT_128_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize HRS RSCS Relay Control Point service and create database in ATT. - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t hrrcps_init(void) -{ - const uint8_t hrrcps_svc_uuid[] = {HRRCPS_SERVICE_UUID}; - uint16_t start_hdl = PRF_INVALID_HANDLE; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = hrrcps_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_hrrcps_char_mask; - gatts_db.max_nb_attr = HRRCPS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = hrrcps_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_hrrcps_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -209,9 +144,9 @@ static sdk_err_t hrrcps_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void hrrcps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void hrrcps_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = 0; @@ -219,7 +154,8 @@ static void hrrcps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_ cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case HRRCPS_IDX_HRR_CTRL_PT_RSP_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_hrrcps_env.ctrl_pt_rsp_ind_cfg[conn_idx]; @@ -242,25 +178,29 @@ static void hrrcps_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_ * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void hrrcps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void hrrcps_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint16_t cccd_value = 0; bool is_ctrl_pt_valid = false; hrrcps_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_hrrcps_env.start_hdl, HRRCPS_IDX_NB, (uint8_t *)&s_hrrcps_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case HRRCPS_IDX_HRR_CTRL_PT_VAL: if ((HRRCPS_CTRL_PT_SCAN_HRS > p_param->value[0]) || \ - (HRRCPS_CTRL_PT_RSCS_DISCONN < p_param->value[0])) { + (HRRCPS_CTRL_PT_RSCS_DISCONN < p_param->value[0])) + { cfm.status = 0x80; - } else { + } + else + { is_ctrl_pt_valid = true; } break; @@ -278,10 +218,12 @@ static void hrrcps_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t * break; } - if (is_ctrl_pt_valid) { + if (is_ctrl_pt_valid) + { hrrcps_ctrl_pt_handler(conn_idx, (hrrcps_ctrl_pt_id_t)p_param->value[0]); - } else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && HRRCPS_EVT_INVALID != event.evt_type - && s_hrrcps_env.evt_handler) { + } + else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && HRRCPS_EVT_INVALID != event.evt_type && s_hrrcps_env.evt_handler) + { event.conn_idx = conn_idx; s_hrrcps_env.evt_handler(&event); } @@ -305,7 +247,8 @@ static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t ctrl_pt event.conn_idx = conn_idx; - switch (ctrl_pt_id) { + switch (ctrl_pt_id) + { case HRRCPS_CTRL_PT_SCAN_HRS: event.evt_type = HRRCPS_EVT_SCAN_HRS; break; @@ -317,23 +260,23 @@ static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t ctrl_pt case HRRCPS_CTRL_PT_HRS_SEN_LOC_READ: event.evt_type = HRRCPS_EVT_HRS_SENSOR_LOC_READ; break; - + case HRRCPS_CTRL_PT_RSCS_SEN_LOC_READ: event.evt_type = HRRCPS_EVT_RSCS_SENSOR_LOC_READ; break; - + case HRRCPS_CTRL_PT_HRS_NTF_ENABLE: event.evt_type = HRRCPS_EVT_ENABLE_HRS_NTF; break; - + case HRRCPS_CTRL_PT_RSCS_NTF_ENABLE: event.evt_type = HRRCPS_EVT_ENABLE_RSCS_NTF; break; - + case HRRCPS_CTRL_PT_HRS_NTF_DISABLE: event.evt_type = HRRCPS_EVT_DISABLE_HRS_NTF; break; - + case HRRCPS_CTRL_PT_RSCS_NTF_DISABLE: event.evt_type = HRRCPS_EVT_DISABLE_RSCS_NTF; break; @@ -350,7 +293,8 @@ static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t ctrl_pt break; } - if (HRRCPS_EVT_INVALID != event.evt_type && s_hrrcps_env.evt_handler) { + if (HRRCPS_EVT_INVALID != event.evt_type && s_hrrcps_env.evt_handler) + { s_hrrcps_env.evt_handler(&event); } } @@ -364,18 +308,20 @@ static void hrrcps_ctrl_pt_handler(uint8_t conn_idx, hrrcps_ctrl_pt_id_t ctrl_pt * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void hrrcps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void hrrcps_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; hrrcps_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } tab_index = prf_find_idx_by_handle(handle, s_hrrcps_env.start_hdl, HRRCPS_IDX_NB, (uint8_t *)&s_hrrcps_char_mask); - switch (tab_index) { + switch (tab_index) + { case HRRCPS_IDX_HRR_CTRL_PT_RSP_CFG: event.evt_type = ((PRF_CLI_START_IND == cccd_value) ? \ HRRCPS_EVT_CTRL_PT_IND_ENABLE : \ @@ -388,7 +334,8 @@ static void hrrcps_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_ break; } - if (HRRCPS_EVT_INVALID != event.evt_type && s_hrrcps_env.evt_handler) { + if (HRRCPS_EVT_INVALID != event.evt_type && s_hrrcps_env.evt_handler) + { event.conn_idx = conn_idx; s_hrrcps_env.evt_handler(&event); } @@ -412,13 +359,37 @@ static uint16_t hrrcps_ctrl_pt_rsp_encode(hrrcps_rsp_val_t *p_rsp_val, uint8_t * p_encoded_buff[length++] = p_rsp_val->cmd_id; p_encoded_buff[length++] = p_rsp_val->rsp_id; - if (p_rsp_val->is_inc_prama) { + if (p_rsp_val->is_inc_prama) + { p_encoded_buff[length++] = p_rsp_val->rsp_param; } return length; } +static void hrrcps_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + hrrcps_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + hrrcps_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + hrrcps_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -426,12 +397,13 @@ static uint16_t hrrcps_ctrl_pt_rsp_encode(hrrcps_rsp_val_t *p_rsp_val, uint8_t * sdk_err_t hrrcps_ctrl_pt_rsp_send(uint8_t conn_idx, hrrcps_rsp_val_t *p_rsp_val) { uint8_t encoded_ctrl_pt_rsp[HRRCPS_CTRL_PT_RSP_VAL_LEN]; - gatts_noti_ind_t ctrl_pt_rsp_ind; + ble_gatts_noti_ind_t ctrl_pt_rsp_ind; uint16_t encoded_length; encoded_length =hrrcps_ctrl_pt_rsp_encode(p_rsp_val, encoded_ctrl_pt_rsp); - if (PRF_CLI_START_IND == s_hrrcps_env.ctrl_pt_rsp_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_hrrcps_env.ctrl_pt_rsp_ind_cfg[conn_idx]) + { ctrl_pt_rsp_ind.type = BLE_GATT_INDICATION; ctrl_pt_rsp_ind.handle = prf_find_handle_by_idx(HRRCPS_IDX_HRR_CTRL_PT_RSP_VAL, s_hrrcps_env.start_hdl, @@ -448,5 +420,16 @@ sdk_err_t hrrcps_ctrl_pt_rsp_send(uint8_t conn_idx, hrrcps_rsp_val_t *p_rsp_val) sdk_err_t hrrcps_service_init(hrrcps_evt_handler_t evt_handler) { s_hrrcps_env.evt_handler = evt_handler; - return ble_server_prf_add(&hrrcps_prf_info); + + s_hrrcps_env.start_hdl = PRF_INVALID_HANDLE; + + s_hrrcps_env.hrrcps_gatts_db.shdl = &s_hrrcps_env.start_hdl; + s_hrrcps_env.hrrcps_gatts_db.uuid = s_hrrcps_svc_uuid; + s_hrrcps_env.hrrcps_gatts_db.attr_tab_cfg = (uint8_t *)&s_hrrcps_char_mask; + s_hrrcps_env.hrrcps_gatts_db.max_nb_attr = HRRCPS_IDX_NB; + s_hrrcps_env.hrrcps_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_hrrcps_env.hrrcps_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_hrrcps_env.hrrcps_gatts_db.attr_tab.attr_tab_128 = hrrcps_attr_tab; + + return ble_gatts_prf_add(&s_hrrcps_env.hrrcps_gatts_db, hrrcps_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.h index 0903cfa..bff3912 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrrcps/hrrcps.h @@ -57,24 +57,21 @@ #ifndef __HRRCPS_H__ #define __HRRCPS_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup HRRCPS_MACRO Defines * @{ */ -#define HRRCPS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of \ - HRS RSCS Relay Control Point Service connections. */ -#define HRRCPS_CTRL_PT_VAL_LEN 2 /**< Length of the value of Control Point characteristic. */ -#define HRRCPS_CTRL_PT_RSP_VAL_LEN 4 /**< Length of the value of Control Point Response characteristic. */ -#define HRRCPS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x01, 0x06, 0xED, 0xA6 /**< The UUID of HRS RSCS Relay Control Point Service \ - for setting advertising data. */ +#define HRRCPS_CONNECTION_MAX 10 /**< Maximum number of HRS RSCS Relay Control Point Service connections. */ +#define HRRCPS_CTRL_PT_VAL_LEN 2 /**< Length of the value of Control Point characteristic. */ +#define HRRCPS_CTRL_PT_RSP_VAL_LEN 4 /**< Length of the value of Control Point Response characteristic. */ +#define HRRCPS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x06, 0xED, 0xA6 /**< The UUID of HRS RSCS Relay Control Point Service for setting advertising data. */ /** @} */ /** @@ -82,7 +79,8 @@ * @{ */ /**@brief HRS RSCS Relay Control Point Service Control Point IDs. */ -typedef enum { +typedef enum +{ HRRCPS_CTRL_PT_SCAN_HRS = 0x01, /**< Scan HRS device. */ HRRCPS_CTRL_PT_SCAN_RSCS, /**< Scan RSCS device. */ HRRCPS_CTRL_PT_HRS_SEN_LOC_READ, /**< Read HRS sensor location. */ @@ -99,13 +97,15 @@ typedef enum { } hrrcps_ctrl_pt_id_t; /**@brief HRS RSCS Relay Control Point Service Response IDs of Control Point. */ -typedef enum { +typedef enum +{ HRRCPS_RSP_ID_OK = 0x01, /**< Success. */ HRRCPS_RSP_ID_ERROR, /**< Fail. */ } hrrcps_rsp_id_t; /**@brief HRS RSCS Relay Control Point Service event type. */ -typedef enum { +typedef enum +{ HRRCPS_EVT_INVALID, /**< Invalid HRRCPS event type. */ HRRCPS_EVT_CTRL_PT_IND_ENABLE, /**< HRR Control Point indicaiton is enabled. */ HRRCPS_EVT_CTRL_PT_IND_DISABLE, /**< HRR Control Point indicaiton is disabled. */ @@ -127,7 +127,8 @@ typedef enum { * @{ */ /**@brief HRS RSCS Relay Control Point Response value. */ -typedef struct { +typedef struct +{ hrrcps_ctrl_pt_id_t cmd_id; /**< Control Point ID. */ hrrcps_rsp_id_t rsp_id; /**< Response ID. */ bool is_inc_prama; /**< Parameter is included or not. */ @@ -135,7 +136,8 @@ typedef struct { } hrrcps_rsp_val_t; /**@brief HRS RSCS Relay Control Point Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ hrrcps_evt_type_t evt_type; /**< The HRRCPS event type. */ } hrrcps_evt_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/BUILD.gn new file mode 100644 index 0000000..f25c0ce --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hrs") { + sources = [ "hrs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.c index 70c829b..e521e95 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.c @@ -35,17 +35,15 @@ ***************************************************************************************** */ -/* -* INCLUDE FILES -******************************************************************************* -*/ + /* + * INCLUDE FILES + ******************************************************************************* + */ #include "hrs.h" #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define DIV_2 2 - /* * DEFINES ******************************************************************************* @@ -58,20 +56,27 @@ ******************************************************************************* */ /**@brief Heart Rate Service Attributes Indexes. */ -enum hrs_attr_idx_t { +enum hrs_attr_idx_t +{ HRS_IDX_SVC, + HRS_IDX_HR_MEAS_CHAR, HRS_IDX_HR_MEAS_VAL, HRS_IDX_HR_MEAS_NTF_CFG, + HRS_IDX_BODY_SENSOR_LOC_CHAR, HRS_IDX_BODY_SENSOR_LOC_VAL, + HRS_IDX_HR_CTNL_PT_CHAR, HRS_IDX_HR_CTNL_PT_VAL, + HRS_IDX_NB, }; /**@brief Heart Rate Service Measurement flag bit. */ -enum hrs_flag_bit_t { +enum hrs_flag_bit_t +{ + HRS_BIT_RATE_FORMAT = 0x01, /**< Heart Rate Value Format bit. */ HRS_BIT_SENSOR_CONTACT_DETECTED = 0x02, /**< Sensor Contact Detected bit. */ HRS_BIT_SENSOR_CONTACT_SUPPORTED = 0x04, /**< Sensor Contact Supported bit. */ @@ -84,128 +89,65 @@ enum hrs_flag_bit_t { ******************************************************************************* */ /**@brief Heart Rate Measurement characteristic value structure. */ -struct hr_meas_char_val_t { - bool is_sensor_contact_detected; /**< True if sensor contact has been detected. */ - uint8_t hr_meas_value[HRS_MEAS_MAX_LEN]; /**< The buffer for encoded value of Heart Rate \ - Measurement characteristic. */ - uint16_t energy_expended; /**< The accumulated energy expended in kilo Joules since the last time it was reset. */ +struct hr_meas_char_val_t +{ + bool is_sensor_contact_detected; /**< True if sensor contact has been detected. */ + uint8_t hr_meas_value[HRS_MEAS_MAX_LEN]; /**< The buffer for encoded value of Heart Rate Measurement characteristic. */ + uint16_t energy_expended; /**< The accumulated energy expended in kilo Joules since the last time it was reset. */ uint16_t rr_interval[HRS_MAX_BUFFERED_RR_INTERVALS]; /**< The buffer for RR Interval measurements. */ uint8_t rr_interval_count; /**< The number of RR Interval measurements in the buffer. */ }; /**@brief Heart Rate Service environment variable. */ -struct hrs_env_t { - hrs_init_t hrs_init; /**< Heart Rate Service Init Value. */ - struct hr_meas_char_val_t hr_meas; /**< The value of Heart Rate Measurement characteristic. */ +struct hrs_env_t +{ + hrs_init_t hrs_init; /**< Heart Rate Service Init Value. */ + struct hr_meas_char_val_t hr_meas; /**< The value of Heart Rate Measurement characteristic. */ uint16_t start_hdl; /**< Heart Rate Service start handle. */ - uint16_t - ntf_cfg[HRS_CONNECTION_MAX];/**< The configuration of Heart Rate Measurement Notification \ - which is configured by the peer devices. */ + uint16_t ntf_cfg[HRS_CONNECTION_MAX];/**< The configuration of Heart Rate Measurement Notification which is configured by the peer devices. */ + ble_gatts_create_db_t hrs_serv_db; /**< Heart Rate Service DataBase. */ }; -/* -* LOCAL FUNCTION DECLARATION -******************************************************************************* -*/ -static sdk_err_t hrs_init(void); -static void hrs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void hrs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void hrs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); + /* + * LOCAL FUNCTION DECLARATION + ******************************************************************************* + */ /* * LOCAL VARIABLE DEFINITIONS ******************************************************************************* */ static struct hrs_env_t s_hrs_env; +static const uint8_t s_hrs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HEART_RATE); /**@brief Full HRS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_t hrs_attr_tab[HRS_IDX_NB] = { +static const ble_gatts_attm_desc_t hrs_attr_tab[HRS_IDX_NB] = +{ // Heart Rate Service Declaration - [HRS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [HRS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // HR Measurement Characteristic - Declaration - [HRS_IDX_HR_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HRS_IDX_HR_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // HR Measurement Characteristic - Value - [HRS_IDX_HR_MEAS_VAL] = {BLE_ATT_CHAR_HEART_RATE_MEAS, NOTIFY_PERM_UNSEC, ATT_VAL_LOC_USER, HRS_MEAS_MAX_LEN}, + [HRS_IDX_HR_MEAS_VAL] = {BLE_ATT_CHAR_HEART_RATE_MEAS, BLE_GATTS_NOTIFY_PERM_UNSEC,BLE_GATTS_ATT_VAL_LOC_USER, HRS_MEAS_MAX_LEN}, // HR Measurement Characteristic - Client Characteristic Configuration Descriptor - [HRS_IDX_HR_MEAS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [HRS_IDX_HR_MEAS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Body Sensor Location Characteristic - Declaration - [HRS_IDX_BODY_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HRS_IDX_BODY_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Body Sensor Location Characteristic - Value - [HRS_IDX_BODY_SENSOR_LOC_VAL] = {BLE_ATT_CHAR_BODY_SENSOR_LOCATION, READ_PERM_UNSEC, - ATT_VAL_LOC_USER, sizeof(uint8_t)}, + [HRS_IDX_BODY_SENSOR_LOC_VAL] = {BLE_ATT_CHAR_BODY_SENSOR_LOCATION,BLE_GATTS_READ_PERM_UNSEC, BLE_GATTS_ATT_VAL_LOC_USER, sizeof(uint8_t)}, // Heart Rate Control Point Characteristic - Declaration - [HRS_IDX_HR_CTNL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HRS_IDX_HR_CTNL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Heart Rate Control Point Characteristic - Value - [HRS_IDX_HR_CTNL_PT_VAL] = {BLE_ATT_CHAR_HEART_RATE_CNTL_POINT, WRITE_REQ_PERM_UNSEC, 0, sizeof(uint8_t)}, -}; - -/**@brief HRS interface required by profile manager. */ -static ble_prf_manager_cbs_t hrs_mgr_cbs = { - (prf_init_func_t)hrs_init, - NULL, - NULL -}; - -/**@brief HRS GATT server Callbacks. */ -static gatts_prf_cbs_t hrs_gatts_cbs = { - hrs_read_att_cb, - hrs_write_att_cb, - NULL, - NULL, - hrs_cccd_set_cb -}; - -/**@brief HRS Information. */ -static const prf_server_info_t hrs_prf_info = { - .max_connection_nb = HRS_CONNECTION_MAX, - .manager_cbs = &hrs_mgr_cbs, - .gatts_prf_cbs = &hrs_gatts_cbs + [HRS_IDX_HR_CTNL_PT_VAL] = {BLE_ATT_CHAR_HEART_RATE_CNTL_POINT,BLE_GATTS_WRITE_REQ_PERM_UNSEC,0, sizeof(uint8_t)}, }; /* * LOCAL FUNCTION DEFINITIONS ******************************************************************************* */ -/** - ***************************************************************************************** - * @brief Initialize heart rate service, and create DB in ATT. - * - * @return status code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t hrs_init(void) -{ - const uint8_t hrs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HEART_RATE); - gatts_create_db_t gatts_db; - sdk_err_t ret; - uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out - * parameter of ble_gatts_srvc_db_create() - * It must be set with PRF_INVALID_HANDLE - * to be allocated automatically by BLE Stack. */ - - ret = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = hrs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_hrs_env.hrs_init.char_mask; - gatts_db.max_nb_attr = HRS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = hrs_attr_tab; - - sdk_err_t status = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == status) { - s_hrs_env.start_hdl = *gatts_db.shdl; - } - - return status; -} /** ***************************************************************************************** @@ -215,20 +157,21 @@ static sdk_err_t hrs_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void hrs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void hrs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_hrs_env.start_hdl, - HRS_IDX_NB, - (uint8_t *)&s_hrs_env.hrs_init.char_mask); + HRS_IDX_NB, + (uint8_t *)&s_hrs_env.hrs_init.char_mask); - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; hrs_evt_t evt; cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case HRS_IDX_HR_MEAS_VAL: cfm.length = HRS_MEAS_MAX_LEN; cfm.value = s_hrs_env.hr_meas.hr_meas_value; @@ -240,7 +183,8 @@ static void hrs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param break; case HRS_IDX_BODY_SENSOR_LOC_VAL: - if (s_hrs_env.hrs_init.evt_handler) { + if (s_hrs_env.hrs_init.evt_handler) + { evt.conn_idx = conn_idx; evt.evt_type = HRS_EVT_READ_BODY_SEN_LOCATION; s_hrs_env.hrs_init.evt_handler(&evt); @@ -266,29 +210,31 @@ static void hrs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void hrs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void hrs_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_hrs_env.start_hdl, - HRS_IDX_NB, - (uint8_t *)&s_hrs_env.hrs_init.char_mask); + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_hrs_env.start_hdl, + HRS_IDX_NB, + (uint8_t *)&s_hrs_env.hrs_init.char_mask); uint16_t cccd_value; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; hrs_evt_t evt; - + cfm.handle = handle; - switch (tab_index) { + switch (tab_index) + { case HRS_IDX_HR_MEAS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); s_hrs_env.ntf_cfg[conn_idx] = cccd_value; - if (s_hrs_env.hrs_init.evt_handler) { + if (s_hrs_env.hrs_init.evt_handler) + { evt.conn_idx = conn_idx; evt.evt_type = ((cccd_value == PRF_CLI_START_NTF) ? - HRS_EVT_NOTIFICATION_ENABLED : - HRS_EVT_NOTIFICATION_DISABLED); + HRS_EVT_NOTIFICATION_ENABLED : + HRS_EVT_NOTIFICATION_DISABLED); s_hrs_env.hrs_init.evt_handler(&evt); } @@ -296,15 +242,19 @@ static void hrs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par break; case HRS_IDX_HR_CTNL_PT_VAL: - if (p_param->value[0] == HRS_CTRL_POINT_ENERGY_EXP) { - if (s_hrs_env.hrs_init.evt_handler) { + if (p_param->value[0] == HRS_CTRL_POINT_ENERGY_EXP) + { + if (s_hrs_env.hrs_init.evt_handler) + { evt.conn_idx = conn_idx; evt.evt_type = HRS_EVT_RESET_ENERGY_EXPENDED; s_hrs_env.hrs_init.evt_handler(&evt); } cfm.status = BLE_SUCCESS; - } else { + } + else + { cfm.status = 0x80; } break; @@ -326,28 +276,31 @@ static void hrs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void hrs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void hrs_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { hrs_evt_t evt; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_hrs_env.start_hdl, - HRS_IDX_NB, - (uint8_t *)&s_hrs_env.hrs_init.char_mask); + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_hrs_env.start_hdl, + HRS_IDX_NB, + (uint8_t *)&s_hrs_env.hrs_init.char_mask); - switch (tab_index) { + switch (tab_index) + { case HRS_IDX_HR_MEAS_NTF_CFG: s_hrs_env.ntf_cfg[conn_idx] = cccd_value; - if (s_hrs_env.hrs_init.evt_handler) { + if (s_hrs_env.hrs_init.evt_handler) + { evt.conn_idx = conn_idx; evt.evt_type = ((cccd_value == PRF_CLI_START_NTF) ? - HRS_EVT_NOTIFICATION_ENABLED : - HRS_EVT_NOTIFICATION_DISABLED); + HRS_EVT_NOTIFICATION_ENABLED : + HRS_EVT_NOTIFICATION_DISABLED); s_hrs_env.hrs_init.evt_handler(&evt); } break; @@ -375,40 +328,50 @@ static uint8_t hrs_hrm_encode(uint16_t heart_rate, uint8_t *p_encoded_buffer, bo uint8_t temp = 0; uint8_t flags = 0; struct hr_meas_char_val_t *p_meas_char; - + // Set sensor contact related flags - if (s_hrs_env.hrs_init.is_sensor_contact_supported) { + if (s_hrs_env.hrs_init.is_sensor_contact_supported) + { flags |= HRS_BIT_SENSOR_CONTACT_SUPPORTED; } - if (s_hrs_env.hr_meas.is_sensor_contact_detected) { + if (s_hrs_env.hr_meas.is_sensor_contact_detected) + { flags |= HRS_BIT_SENSOR_CONTACT_DETECTED; } p_meas_char = &s_hrs_env.hr_meas; // Encode heart rate measurement - if (heart_rate > 0xff) { + if (heart_rate > 0xff) + { flags |= HRS_BIT_RATE_FORMAT; p_encoded_buffer[len++] = LO_U16(heart_rate); p_encoded_buffer[len++] = HI_U16(heart_rate); - } else { + } + else + { flags &= ~HRS_BIT_RATE_FORMAT; p_encoded_buffer[len++] = (uint8_t)heart_rate; } // Encode heart rate energy - if ((s_hrs_env.hrs_init.char_mask & HRS_CHAR_ENGY_EXP_SUP) && is_energy_updated) { + if ((s_hrs_env.hrs_init.char_mask & HRS_CHAR_ENGY_EXP_SUP) && is_energy_updated) + { flags |= HRS_BIT_ENERGY_EXPENDED_STATUS; p_encoded_buffer[len++] = LO_U16(p_meas_char->energy_expended); p_encoded_buffer[len++] = HI_U16(p_meas_char->energy_expended); } // Encode rr_interval values - if (p_meas_char->rr_interval_count == 0) { + if (p_meas_char->rr_interval_count == 0) + { flags &= ~(HRS_BIT_INTERVAL); - } else { + } + else + { flags |= HRS_BIT_INTERVAL; - temp = ((HRS_MEAS_MAX_LEN - len) / DIV_2); - for (uint8_t i = 0; i < temp; i++) { + temp = ((HRS_MEAS_MAX_LEN - len) / 2); + for (uint8_t i = 0; i < temp; i++) + { p_encoded_buffer[len++] = LO_U16(p_meas_char->rr_interval[i]); p_encoded_buffer[len++] = HI_U16(p_meas_char->rr_interval[i]); } @@ -430,13 +393,15 @@ void hrs_rr_interval_add(uint16_t rr_interval) p_meas_char->rr_interval_count = 0; - for (uint8_t i = HRS_MAX_BUFFERED_RR_INTERVALS - 1; i > 0; i--) { + for (uint8_t i = HRS_MAX_BUFFERED_RR_INTERVALS - 1; i > 0; i--) + { p_meas_char->rr_interval[i] = p_meas_char->rr_interval[i - 1]; } p_meas_char->rr_interval[0] = rr_interval; p_meas_char->rr_interval_count++; - if (p_meas_char->rr_interval_count > HRS_MAX_BUFFERED_RR_INTERVALS) { + if (p_meas_char->rr_interval_count > HRS_MAX_BUFFERED_RR_INTERVALS) + { p_meas_char->rr_interval_count = HRS_MAX_BUFFERED_RR_INTERVALS; } } @@ -469,10 +434,11 @@ sdk_err_t hrs_heart_rate_measurement_send(uint8_t conn_idx, uint16_t heart_rate, { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; struct hr_meas_char_val_t *p_meas_char = &s_hrs_env.hr_meas; - uint8_t len = hrs_hrm_encode(heart_rate, p_meas_char->hr_meas_value, is_energy_updated); + uint8_t len = hrs_hrm_encode(heart_rate, p_meas_char->hr_meas_value,is_energy_updated); - if (s_hrs_env.ntf_cfg[conn_idx] == PRF_CLI_START_NTF) { - gatts_noti_ind_t hr_noti; + if (s_hrs_env.ntf_cfg[conn_idx] == PRF_CLI_START_NTF) + { + ble_gatts_noti_ind_t hr_noti; hr_noti.type = BLE_GATT_NOTIFICATION; hr_noti.handle = prf_find_handle_by_idx(HRS_IDX_HR_MEAS_VAL, @@ -487,18 +453,56 @@ sdk_err_t hrs_heart_rate_measurement_send(uint8_t conn_idx, uint16_t heart_rate, return error_code; } +static void hrs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + hrs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + hrs_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + hrs_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + default: + break; + } +} + sdk_err_t hrs_service_init(hrs_init_t *p_hrs_init) { - sdk_err_t ret; - if (p_hrs_init == NULL) { + if (NULL == p_hrs_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_hrs_env.hrs_init, sizeof(hrs_init_t), p_hrs_init, sizeof(hrs_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_hrs_env.hrs_init, p_hrs_init, sizeof(hrs_init_t)); - return ble_server_prf_add(&hrs_prf_info); + memset(&s_hrs_env.hrs_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_hrs_env.start_hdl = PRF_INVALID_HANDLE; + s_hrs_env.hrs_serv_db.shdl = &s_hrs_env.start_hdl; + s_hrs_env.hrs_serv_db.uuid = s_hrs_svc_uuid; + s_hrs_env.hrs_serv_db.attr_tab_cfg = (uint8_t *)&s_hrs_env.hrs_init.char_mask; + s_hrs_env.hrs_serv_db.max_nb_attr = HRS_IDX_NB; + s_hrs_env.hrs_serv_db.srvc_perm = 0; + s_hrs_env.hrs_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_hrs_env.hrs_serv_db.attr_tab.attr_tab_16 = hrs_attr_tab; + + return ble_gatts_prf_add(&s_hrs_env.hrs_serv_db, hrs_ble_evt_handler); } +uint16_t hrs_service_start_handle_get(void) +{ + return s_hrs_env.start_hdl; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.h index e600bca..b8ec04a 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs/hrs.h @@ -55,9 +55,8 @@ * However the value of Heart Rate Measurement characteristic is stored in user space. * * If a device supports Body Sensor Location, \ref hrs_init_t.char_mask should be - * set with the mask \ref HRS_CHAR_BODY_SENSOR_LOC_SUP to expose the Body Sensor Location characteristic. - * If Energy Expended Field is included in the Heart Rate Measurement characteristic, \ref hrs_init_t. - * char_mask must be set with \ref HRS_CHAR_ENGY_EXP_SUP. + * set with the mask \ref HRS_CHAR_BODY_SENSOR_LOC_SUP to expose the Body Sensor Location characteristic. If Energy Expended Field is included + * in the Heart Rate Measurement characteristic, \ref hrs_init_t.char_mask must be set with \ref HRS_CHAR_ENGY_EXP_SUP. * * If an event handler is provided by the application, the Heart Rate Service will pass * Heart Rate Service events to the application. @@ -69,20 +68,19 @@ #ifndef __HRS_H__ #define __HRS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup HRS_MACRO Defines * @{ */ -#define HRS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Heart Rate Service connections. */ -#define HRS_MEAS_MAX_LEN 20 /**< Maximum length of heart rate measurement characteristic. */ -#define HRS_MAX_BUFFERED_RR_INTERVALS 9 /**< Size of RR Interval buffer inside service. */ +#define HRS_CONNECTION_MAX 10 /**< Maximum number of Heart Rate Service connections. */ +#define HRS_MEAS_MAX_LEN 20 /**< Maximum length of heart rate measurement characteristic. */ +#define HRS_MAX_BUFFERED_RR_INTERVALS 9 /**< Size of RR Interval buffer inside service. */ /** * @defgroup HRS_CHAR_MASK Characteristics Mask @@ -101,7 +99,8 @@ * @{ */ /**@brief Values for sensor location. */ -typedef enum { +typedef enum +{ HRS_SENS_LOC_OTHER, /**< The sensor location is other. */ HRS_SENS_LOC_CHEST, /**< The sensor location is the chest. */ HRS_SENS_LOC_WRIST, /**< The sensor location is the wrist. */ @@ -112,7 +111,8 @@ typedef enum { } hrs_sensor_loc_t; /**@brief Heart Rate Service event types. */ -typedef enum { +typedef enum +{ HRS_EVT_NOTIFICATION_ENABLED, /**< Heart Rate value notification has been enabled. */ HRS_EVT_NOTIFICATION_DISABLED, /**< Heart Rate value notification has been disabled. */ HRS_EVT_RESET_ENERGY_EXPENDED, /**< The peer device requests to reset Energy Expended. */ @@ -125,7 +125,8 @@ typedef enum { * @{ */ /**@brief Heart Rate Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< Index of connection. */ hrs_evt_type_t evt_type; /**< Heart Rate Service event type. */ } hrs_evt_t; @@ -144,12 +145,12 @@ typedef void (*hrs_evt_handler_t)(hrs_evt_t *p_evt); * @{ */ /**@brief Heart Rate Service Init variable. */ -typedef struct { - hrs_evt_handler_t evt_handler; /**< Heart Rate Service event handler. */ - bool is_sensor_contact_supported; /**< Determine if sensor contact detection is to be supported. */ - uint8_t char_mask; /**< Mask of Supported characteristics, and configured with \ref HRS_CHAR_MASK */ - hrs_sensor_loc_t - sensor_loc; /**< The value of Body Sensor Location characteristic is static while in a connection. */ +typedef struct +{ + hrs_evt_handler_t evt_handler; /**< Heart Rate Service event handler. */ + bool is_sensor_contact_supported; /**< Determine if sensor contact detection is to be supported. */ + uint8_t char_mask; /**< Mask of Supported characteristics, and configured with \ref HRS_CHAR_MASK */ + hrs_sensor_loc_t sensor_loc; /**< The value of Body Sensor Location characteristic is static while in a connection. */ } hrs_init_t; /** @} */ @@ -234,6 +235,16 @@ void hrs_rr_interval_add(uint16_t rr_interval); ***************************************************************************************** */ sdk_err_t hrs_service_init(hrs_init_t *p_hrs_init); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the hrs service start handle . + * + * @return The hrs service start handle. + ***************************************************************************************** + */ +uint16_t hrs_service_start_handle_get(void); + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/BUILD.gn new file mode 100644 index 0000000..4e4657a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hrs_c") { + sources = [ "hrs_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.c index 3d0b9a0..59eaf68 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.c @@ -39,63 +39,32 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "hrs_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "hrs_c.h" -#define OFFSET_8 8 -#define ATTR_VALUE_LEN 2 +#include + /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Heart Rate Service environment variable. */ -struct hrs_c_env_t { +struct hrs_c_env_t +{ hrs_c_handles_t handles; /**< Handles of HRS characteristics which will be got for peer. */ hrs_c_evt_handler_t evt_handler; /**< Handler of HRS Client event */ - uint8_t prf_id; /**< HRS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void hrs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void hrs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void hrs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void hrs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct hrs_c_env_t s_hrs_c_env; /**< Heart Rate Service Client environment variable. */ - -/**@brief Heart Rate Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t hrs_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Heart Rate Service GATT Client Callbacks. */ -static gattc_prf_cbs_t hrs_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - hrs_c_att_read_cb, - hrs_c_att_write_cb, - hrs_c_att_ntf_ind_cb, - hrs_c_srvc_browse_cb, - NULL, -}; - -/**@brief Heart Rate Service Client Information. */ -static const prf_client_info_t hrs_c_prf_info = { - .max_connection_nb = HRS_C_CONNECTION_MAX, - .manager_cbs = &hrs_c_mgr_cbs, - .gattc_prf_cbs = &hrs_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_HEART_RATE), HI_U16(BLE_ATT_SVC_HEART_RATE)}; +static ble_uuid_t s_hrs_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -111,7 +80,8 @@ static const prf_client_info_t hrs_c_prf_info = { */ static void hrs_c_evt_handler_excute(hrs_c_evt_t *p_evt) { - if (s_hrs_c_env.evt_handler != NULL && HRS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_hrs_c_env.evt_handler && HRS_C_EVT_INVALID != p_evt->evt_type) + { s_hrs_c_env.evt_handler(p_evt); } } @@ -129,39 +99,45 @@ static void hrs_c_meas_value_encode(uint8_t *p_data, uint16_t length, hrs_c_hr_m { uint8_t flags = 0; uint8_t index = 0; - uint8_t ret; flags = p_data[index++]; - ret = memset_s(p_hr_meas_buff, sizeof(hrs_c_hr_meas_t), 0, sizeof(hrs_c_hr_meas_t)); - if (ret < 0) { - return ret; - } + memset(p_hr_meas_buff, 0, sizeof(hrs_c_hr_meas_t)); - if (flags & HRS_C_BIT_RATE_FORMAT) { - p_hr_meas_buff->hr_value = p_data[index] | (p_data[index + 1] << OFFSET_8); + if (flags & HRS_C_BIT_RATE_FORMAT) + { + p_hr_meas_buff->hr_value = p_data[index] | (p_data[index + 1] << 8); index += sizeof(uint16_t); - } else { + } + else + { p_hr_meas_buff->hr_value = p_data[index++]; } - if (flags & HRS_C_BIT_SENSOR_CONTACT_SUPPORTED) { - if (flags & HRS_C_BIT_SENSOR_CONTACT_DETECTED) { + if (flags & HRS_C_BIT_SENSOR_CONTACT_SUPPORTED) + { + if (flags & HRS_C_BIT_SENSOR_CONTACT_DETECTED) + { p_hr_meas_buff->is_sensor_contact_detected = true; - } else { + } + else + { p_hr_meas_buff->is_sensor_contact_detected = false; } } - if (flags & HRS_C_BIT_ENERGY_EXPENDED_STATUS) { - p_hr_meas_buff->energy_expended = p_data[index] | (p_data[index + 1] << OFFSET_8); + if (flags & HRS_C_BIT_ENERGY_EXPENDED_STATUS) + { + p_hr_meas_buff->energy_expended = p_data[index] | (p_data[index + 1] << 8); index += sizeof(uint16_t); } - if (flags & HRS_C_BIT_INTERVAL) { - for (uint8_t i = 0; index < length; i++) { + if (flags & HRS_C_BIT_INTERVAL) + { + for (uint8_t i = 0; index < length; i++) + { p_hr_meas_buff->rr_intervals_num++; - p_hr_meas_buff->rr_intervals[i] = (p_data[index] | (p_data[index + 1] << OFFSET_8)) * 1000 / 1024.0; + p_hr_meas_buff->rr_intervals[i] = (p_data[index] | (p_data[index + 1] << 8)) * 1000 / 1024.0; index += sizeof(uint16_t); } } @@ -169,27 +145,29 @@ static void hrs_c_meas_value_encode(uint8_t *p_data, uint16_t length, hrs_c_hr_m /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void hrs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void hrs_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { hrs_c_evt_t hrs_c_evt; hrs_c_evt.conn_idx = conn_idx; hrs_c_evt.evt_type = HRS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_hrs_c_env.handles.hrs_sensor_loc_handle) { + if (p_read_rsp->value[0].handle == s_hrs_c_env.handles.hrs_sensor_loc_handle) + { hrs_c_evt.evt_type = HRS_C_EVT_SENSOR_LOC_READ_RSP; - hrs_c_evt.value.sensor_loc = (hrs_c_sensor_loc_t)p_read_rsp->vals[0].p_value[0]; + hrs_c_evt.value.sensor_loc = (hrs_c_sensor_loc_t)p_read_rsp->value[0].p_value[0]; } hrs_c_evt_handler_excute(&hrs_c_evt); @@ -197,28 +175,31 @@ static void hrs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void hrs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void hrs_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { hrs_c_evt_t hrs_c_evt; hrs_c_evt.conn_idx = conn_idx; hrs_c_evt.evt_type = HRS_C_EVT_INVALID; - if (handle == s_hrs_c_env.handles.hrs_hr_meas_cccd_handle) { + if (handle == s_hrs_c_env.handles.hrs_hr_meas_cccd_handle) + { hrs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - HRS_C_EVT_HR_MEAS_NTF_SET_SUCCESS : - HRS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_hrs_c_env.handles.hrs_ctrl_point_handle) { + HRS_C_EVT_HR_MEAS_NTF_SET_SUCCESS : + HRS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_hrs_c_env.handles.hrs_ctrl_point_handle) + { hrs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - HRS_C_EVT_CTRL_POINT_SET : - HRS_C_EVT_WRITE_OP_ERR; + HRS_C_EVT_CTRL_POINT_SET : + HRS_C_EVT_WRITE_OP_ERR; } hrs_c_evt_handler_excute(&hrs_c_evt); @@ -226,21 +207,22 @@ static void hrs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle /** ***************************************************************************************** - * @brief This callback function will be called when receiving notification or indication. + * @brief This event handler function will be called when receiving notification or indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void hrs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void hrs_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { hrs_c_evt_t hrs_c_evt; hrs_c_evt.conn_idx = conn_idx; hrs_c_evt.evt_type = HRS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_hrs_c_env.handles.hrs_hr_meas_handle) { + if (p_ntf_ind->handle == s_hrs_c_env.handles.hrs_hr_meas_handle) + { hrs_c_evt.evt_type = HRS_C_EVT_HR_MEAS_VAL_RECEIVE; hrs_c_meas_value_encode(p_ntf_ind->p_value, p_ntf_ind->length, &hrs_c_evt.value.hr_meas_buff); } @@ -250,14 +232,14 @@ static void hrs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ /** ***************************************************************************************** - * @brief This callback function will be called when receiving browse service indication. + * @brief This event handler function will be called when receiving browse service indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void hrs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void hrs_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { hrs_c_evt_t hrs_c_evt; uint16_t uuid_disc; @@ -266,46 +248,86 @@ static void hrs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat hrs_c_evt.conn_idx = conn_idx; hrs_c_evt.evt_type = HRS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_HEART_RATE == uuid_disc) { - s_hrs_c_env.handles.hrs_srvc_start_handle = p_browse_srvc->start_hdl; - s_hrs_c_env.handles.hrs_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_HEART_RATE == uuid_disc) + { + s_hrs_c_env.handles.hrs_srvc_start_handle = p_browse_srvc->start_hdl; + s_hrs_c_env.handles.hrs_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_HEART_RATE_MEAS == uuid_disc) { - s_hrs_c_env.handles.hrs_hr_meas_handle = handle_disc; - } else if (BLE_ATT_CHAR_BODY_SENSOR_LOCATION == uuid_disc) { - s_hrs_c_env.handles.hrs_sensor_loc_handle = handle_disc; - } else if (BLE_ATT_CHAR_HEART_RATE_CNTL_POINT == uuid_disc) { - s_hrs_c_env.handles.hrs_ctrl_point_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_HEART_RATE_MEAS == uuid_disc) + { + s_hrs_c_env.handles.hrs_hr_meas_handle = handle_disc; + } + else if (BLE_ATT_CHAR_BODY_SENSOR_LOCATION == uuid_disc) + { + s_hrs_c_env.handles.hrs_sensor_loc_handle = handle_disc; + } + else if (BLE_ATT_CHAR_HEART_RATE_CNTL_POINT == uuid_disc) + { + s_hrs_c_env.handles.hrs_ctrl_point_handle = handle_disc; + } } - } else if (BLE_GATTC_BROWSE_ATTR_DESC == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_DESC_CLIENT_CHAR_CFG == uuid_disc) { - s_hrs_c_env.handles.hrs_hr_meas_cccd_handle = handle_disc; + else if (BLE_GATTC_BROWSE_ATTR_DESC == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_DESC_CLIENT_CHAR_CFG == uuid_disc) + { + s_hrs_c_env.handles.hrs_hr_meas_cccd_handle = handle_disc; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; } - } - hrs_c_evt.evt_type = HRS_C_EVT_DISCOVERY_COMPLETE; + hrs_c_evt.evt_type = HRS_C_EVT_DISCOVERY_COMPLETE; + } } hrs_c_evt_handler_excute(&hrs_c_evt); } +static void hrs_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + hrs_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + hrs_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + hrs_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + hrs_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} /* * GLOBAL FUNCTION DEFINITIONS @@ -313,74 +335,52 @@ static void hrs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat */ sdk_err_t hrs_client_init(hrs_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_hrs_c_env, sizeof(s_hrs_c_env), 0, sizeof(s_hrs_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_hrs_c_env, 0, sizeof(s_hrs_c_env)); s_hrs_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&hrs_c_prf_info, &s_hrs_c_env.prf_id); + return ble_gattc_prf_add(&s_hrs_service_uuid, hrs_c_ble_evt_handler); } sdk_err_t hrs_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - - target_uuid[0] = LO_U16(BLE_ATT_SVC_HEART_RATE); - target_uuid[1] = HI_U16(BLE_ATT_SVC_HEART_RATE); - - const ble_uuid_t hrs_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_hrs_c_env.prf_id, conn_idx, &hrs_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_hrs_service_uuid); } sdk_err_t hrs_c_heart_rate_meas_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_hr_meas_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_hr_meas_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_hrs_c_env.handles.hrs_hr_meas_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_hrs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_hrs_c_env.handles.hrs_hr_meas_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t hrs_c_sensor_loc_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_sensor_loc_handle) { + if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_sensor_loc_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_hrs_c_env.prf_id, conn_idx, s_hrs_c_env.handles.hrs_sensor_loc_handle, 0); + return ble_gattc_read(conn_idx, s_hrs_c_env.handles.hrs_sensor_loc_handle, 0); } sdk_err_t hrs_c_ctrl_point_set(uint8_t conn_idx, uint16_t ctrl_value) { - gattc_write_attr_value_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_ctrl_point_handle) { + if (BLE_ATT_INVALID_HDL == s_hrs_c_env.handles.hrs_ctrl_point_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_hrs_c_env.handles.hrs_ctrl_point_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ctrl_value; - - return ble_gattc_prf_write(s_hrs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_hrs_c_env.handles.hrs_ctrl_point_handle, 0, 2, (uint8_t *)&ctrl_value); } + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.h index 74bdaf3..6c4434c 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hrs_c/hrs_c.h @@ -58,21 +58,19 @@ #ifndef __HRS_C_H__ #define __HRS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" - +#include +#include /** * @defgroup HRS_C_MACRO Defines * @{ */ -#define HRS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections. */ -#define HRS_C_RR_INTERVALS_NUM_MAX 9 /**< Maximum number of RR intervals in HRS notifications. */ -#define HRS_C_CTRL_POINT_ENERGY_EXP 0x01 /**< Value for control point characteristic. */ +#define HRS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ +#define HRS_C_RR_INTERVALS_NUM_MAX 9 /**< Maximum number of RR intervals in HRS notifications. */ +#define HRS_C_CTRL_POINT_ENERGY_EXP 0x01 /**< Value for control point characteristic. */ /** @} */ /** @@ -80,20 +78,22 @@ * @{ */ /**@brief Heart Rate Service Client event type. */ -typedef enum { +typedef enum +{ HRS_C_EVT_INVALID, /**< HRS Client invalid event. */ HRS_C_EVT_DISCOVERY_COMPLETE, /**< HRS Client has found HRS service and its characteristics. */ - HRS_C_EVT_DISCOVERY_FAIL, /**< HRS Client found HRS service failed because of invalid operation or \ - no found at the peer. */ - HRS_C_EVT_HR_MEAS_NTF_SET_SUCCESS, /**< HRS Client has set Notification of Heart Rate Measure characteristic. */ - HRS_C_EVT_HR_MEAS_VAL_RECEIVE, /**< HRS Client has received Heart Rate Measure value notification from peer. */ - HRS_C_EVT_SENSOR_LOC_READ_RSP, /**< HRS Client has received Sensor Location Value read response. */ - HRS_C_EVT_CTRL_POINT_SET, /**< HRS Client has set Control Point completely. */ - HRS_C_EVT_WRITE_OP_ERR, /**< Error occured when HRS Client writen to peer. */ + HRS_C_EVT_DISCOVERY_FAIL, /**< HRS Client found HRS service failed because of invalid operation or no found at the peer. */ + HRS_C_EVT_HR_MEAS_NTF_SET_SUCCESS, /**< HRS Client has set Notification of Heart Rate Measure characteristic. */ + HRS_C_EVT_HR_MEAS_VAL_RECEIVE, /**< HRS Client has received Heart Rate Measure value notification from peer. */ + HRS_C_EVT_SENSOR_LOC_READ_RSP, /**< HRS Client has received Sensor Location Value read response. */ + HRS_C_EVT_CTRL_POINT_SET, /**< HRS Client has set Control Point completely. */ + HRS_C_EVT_WRITE_OP_ERR, /**< Error occured when HRS Client writen to peer. */ } hrs_c_evt_type_t; /**@brief Heart Rate Service Measurement flag bit. */ -typedef enum { +typedef enum +{ + HRS_C_BIT_RATE_FORMAT = 0x01, /**< Heart Rate Value Format bit. */ HRS_C_BIT_SENSOR_CONTACT_DETECTED = 0x02, /**< Sensor Contact Detected bit. */ HRS_C_BIT_SENSOR_CONTACT_SUPPORTED = 0x04, /**< Sensor Contact Supported bit. */ @@ -102,7 +102,8 @@ typedef enum { } hrs_c_flag_bit_t; /**@brief Values for sensor location. */ -typedef enum { +typedef enum +{ HRS_C_SENS_LOC_OTHER, /**< The sensor location is other. */ HRS_C_SENS_LOC_CHEST, /**< The sensor location is the chest. */ HRS_C_SENS_LOC_WRIST, /**< The sensor location is the wrist. */ @@ -118,34 +119,33 @@ typedef enum { * @{ */ /**@brief Heart Rate Measurement characteristic value structure. */ -typedef struct { +typedef struct +{ bool is_sensor_contact_detected; /**< True if sensor contact has been detected. */ uint16_t hr_value; /**< Heart Rate Value. */ uint8_t rr_intervals_num; /**< Number of RR intervals. */ float rr_intervals[HRS_C_RR_INTERVALS_NUM_MAX]; /**< RR intervals. */ - uint16_t energy_expended; /**< The accumulated energy expended in kilo Joules \ - since the last time it was reset. */ + uint16_t energy_expended; /**< The accumulated energy expended in kilo Joules since the last time it was reset. */ } hrs_c_hr_meas_t; /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t hrs_srvc_start_handle; /**< HRS Service start handle. */ uint16_t hrs_srvc_end_handle; /**< HRS Service end handle. */ - uint16_t hrs_hr_meas_handle; /**< HRS Heart Rate Measurement characteristic Value handle \ - which has been got from peer. */ - uint16_t hrs_hr_meas_cccd_handle; /**< HRS CCCD handle of Heart Rate Measurement characteristic \ - which has been got from peer. */ - uint16_t hrs_sensor_loc_handle; /**< HRS Sensor Location characteristic Value handle \ - which has been got from peer. */ - uint16_t hrs_ctrl_point_handle; /**< HRS Control Point characteristic Value handle \ - which has been got from peer. */ + uint16_t hrs_hr_meas_handle; /**< HRS Heart Rate Measurement characteristic Value handle which has been got from peer. */ + uint16_t hrs_hr_meas_cccd_handle; /**< HRS CCCD handle of Heart Rate Measurement characteristic which has been got from peer. */ + uint16_t hrs_sensor_loc_handle; /**< HRS Sensor Location characteristic Value handle which has been got from peer. */ + uint16_t hrs_ctrl_point_handle; /**< HRS Control Point characteristic Value handle which has been got from peer. */ } hrs_c_handles_t; /**@brief Heart Rate Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ hrs_c_evt_type_t evt_type; /**< HRS Client event type. */ - union { + union + { hrs_c_hr_meas_t hr_meas_buff; /**< Buffer of heart rate measurement value. */ hrs_c_sensor_loc_t sensor_loc; /**< Sensor location. */ } value; /**< Decoded result of value received. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/BUILD.gn new file mode 100644 index 0000000..672cf67 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("hts") { + sources = [ "hts.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.c index 3aa3f5c..e90b790 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.c @@ -42,18 +42,14 @@ #include "hts.h" #include "ble_prf_types.h" #include "utility.h" -#define EXPONEBT_2 (-2) -#define MANTISSA_32 32 -#define MANTISSA_32_SCALE 100 -#define OFFSET_24 24 -#define SCALE_9 9 -#define DESCALE_5 5 + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief Health Thermometer Service Attributes Indexes. */ -enum { +enum +{ HTS_IDX_SVC, HTS_IDX_TEM_MEAS_CHAR, @@ -80,133 +76,88 @@ enum { ***************************************************************************************** */ /**@brief Health Thermometer Service environment variable. */ -struct hts_env_t { - hts_init_t hts_init; /**< Health Thermometer Service initialization variables. */ - uint16_t start_hdl; /**< Health Thermometer Service start handle. */ - uint16_t - meas_ind_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Temperature Measurement Indication \ - which is configured by the peer devices. */ - uint16_t - intm_tem_ntf_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Intermediate Temperature Notification \ - which is configured by the peer devices. */ - uint16_t - meas_interval_ind_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Measurement Interval Indication \ - which is configured by the peer devices. */ +struct hts_env_t +{ + hts_init_t hts_init; /**< Health Thermometer Service initialization variables. */ + uint16_t start_hdl; /**< Health Thermometer Service start handle. */ + uint16_t meas_ind_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Temperature Measurement Indication which is configured by the peer devices. */ + uint16_t intm_tem_ntf_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Intermediate Temperature Notification which is configured by the peer devices. */ + uint16_t meas_interval_ind_cfg[HTS_CONNECTION_MAX]; /**< The configuration of Measurement Interval Indication which is configured by the peer devices. */ + ble_gatts_create_db_t hts_serv_db; /**< Health Thermometer Service DataBase. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t hts_init(void); -static void hts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void hts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void hts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); + /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct hts_env_t s_hts_env; +static const uint8_t s_hts_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HEALTH_THERMOM); /**@brief Full HTS Database Description - Used to add attributes into the database. */ -static const attm_desc_t hts_attr_tab[HTS_IDX_NB] = { +static const ble_gatts_attm_desc_t hts_attr_tab[HTS_IDX_NB] = +{ // Health Thermometer Service Declaration - [HTS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [HTS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Temperature Measurement Characteristic - Declaration - [HTS_IDX_TEM_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HTS_IDX_TEM_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Temperature Measurement Characteristic - Value - [HTS_IDX_TEM_MEAS_VAL] = { - BLE_ATT_CHAR_TEMPERATURE_MEAS, - INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - HTS_TEM_MEAS_MAX_LEN - }, + [HTS_IDX_TEM_MEAS_VAL] = {BLE_ATT_CHAR_TEMPERATURE_MEAS, + BLE_GATTS_INDICATE_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + HTS_TEM_MEAS_MAX_LEN}, // Temperature Measurement Characteristic - Client Characteristic Configuration Descriptor - [HTS_IDX_TEM_MEAS_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [HTS_IDX_TEM_MEAS_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // Temperature Type Characteristic - Declaration - [HTS_IDX_TEM_TYPE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HTS_IDX_TEM_TYPE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Temperature Measurement Characteristic - Value - [HTS_IDX_TEM_TYPE_VAL] = { - BLE_ATT_CHAR_TEMPERATURE_TYPE, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - HTS_TEM_TYPE_MAX_LEN - }, + [HTS_IDX_TEM_TYPE_VAL] = {BLE_ATT_CHAR_TEMPERATURE_TYPE, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + HTS_TEM_TYPE_MAX_LEN}, // Intermediate Temperature Characteristic - Declaration - [HTS_IDX_INTM_TEM_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HTS_IDX_INTM_TEM_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Intermediate Temperature Characteristic - Value - [HTS_IDX_INTM_TEM_VAL] = { - BLE_ATT_CHAR_INTERMED_TEMPERATURE, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - HTS_INTM_TEM_MAX_LEN - }, + [HTS_IDX_INTM_TEM_VAL] = {BLE_ATT_CHAR_INTERMED_TEMPERATURE, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + HTS_INTM_TEM_MAX_LEN}, // Intermediate Temperature Characteristic - Client Characteristic Configuration Descriptor - [HTS_IDX_INTM_TEM_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [HTS_IDX_INTM_TEM_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // Measurement Interval Characteristic - Declaration - [HTS_IDX_MEAS_INTERVAL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [HTS_IDX_MEAS_INTERVAL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Measurement Interval Characteristic - Value - [HTS_IDX_MEAS_INTERVAL_VAL] = { - BLE_ATT_CHAR_MEAS_INTERVAL, - READ_PERM_UNSEC | WRITE_REQ_PERM(AUTH) | INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - HTS_MEAS_INTERVAL_MAX_LEN - }, + [HTS_IDX_MEAS_INTERVAL_VAL] = {BLE_ATT_CHAR_MEAS_INTERVAL, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_AUTH) | BLE_GATTS_INDICATE_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + HTS_MEAS_INTERVAL_MAX_LEN}, // Measurement Interval Characteristic - Client Characteristic Configuration Descriptor - [HTS_IDX_MEAS_INTERVAL_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [HTS_IDX_MEAS_INTERVAL_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // Measurement Interval Characteristic - Valid Range Descriptor - [HTS_IDX_MEAS_INTERVAL_VRD_CFG] = { - BLE_ATT_DESC_VALID_RANGE, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - 0 - }, + [HTS_IDX_MEAS_INTERVAL_VRD_CFG] = {BLE_ATT_DESC_VALID_RANGE, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + 0}, }; -/**@brief HTS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t hts_task_cbs = { - (prf_init_func_t) hts_init, - NULL, - NULL - -}; - -/**@brief HTS Task Callbacks. */ -static gatts_prf_cbs_t hts_cb_func = { - hts_read_att_cb, - hts_write_att_cb, - NULL, - NULL, - hts_cccd_set_cb -}; - -/**@brief HTS Information. */ -static const prf_server_info_t hts_prf_info = { - .max_connection_nb = HTS_CONNECTION_MAX, - .manager_cbs = &hts_task_cbs, - .gatts_prf_cbs = &hts_cb_func, -}; - /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -218,34 +169,6 @@ static const prf_server_info_t hts_prf_info = { * @return Error code to know if profile initialization succeed or not. ***************************************************************************************** */ -static sdk_err_t hts_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t hts_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_HEALTH_THERMOM); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = hts_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_hts_env.hts_init.char_mask); - gatts_db.max_nb_attr = HTS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = hts_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_hts_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} /** ***************************************************************************************** @@ -255,30 +178,32 @@ static sdk_err_t hts_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void hts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void hts_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint16_t meas_interval[2]; - uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_hts_env.start_hdl, - HTS_IDX_NB, - (uint8_t *)&s_hts_env.hts_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint16_t meas_interval[2]; + uint8_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_hts_env.start_hdl, + HTS_IDX_NB, + (uint8_t *)&s_hts_env.hts_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case HTS_IDX_TEM_MEAS_IND_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_hts_env.meas_ind_cfg[conn_idx]; break; case HTS_IDX_TEM_TYPE_VAL: - if (s_hts_env.hts_init.evt_handler) { + if (s_hts_env.hts_init.evt_handler) + { hts_evt_t event; hts_read_characteristic_t characteristic = HTS_READ_CHAR_TEMP_TYPE; - + event.evt_type = HTS_EVT_READ_CHARACTERISTIC; event.p_data = (uint8_t *)&characteristic; event.length = sizeof(characteristic); @@ -287,17 +212,18 @@ static void hts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)&s_hts_env.hts_init.temp_type; break; - + case HTS_IDX_INTM_TEM_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_hts_env.intm_tem_ntf_cfg[conn_idx]; break; case HTS_IDX_MEAS_INTERVAL_VAL: - if (s_hts_env.hts_init.evt_handler) { + if (s_hts_env.hts_init.evt_handler) + { hts_evt_t event; hts_read_characteristic_t characteristic = HTS_READ_CHAR_MEAS_INTL; - + event.evt_type = HTS_EVT_READ_CHARACTERISTIC; event.p_data = (uint8_t *)&characteristic; event.length = sizeof(characteristic); @@ -336,13 +262,13 @@ static void hts_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void hts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void hts_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; - uint16_t tab_index = 0; + uint16_t tab_index = 0;; uint16_t cccd_value = 0; hts_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_hts_env.start_hdl, @@ -351,43 +277,47 @@ static void hts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case HTS_IDX_TEM_MEAS_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - HTS_EVT_TEM_MEAS_INDICATION_ENABLE :\ - HTS_EVT_TEM_MEAS_INDICATION_DISABLE); + HTS_EVT_TEM_MEAS_INDICATION_ENABLE :\ + HTS_EVT_TEM_MEAS_INDICATION_DISABLE); event.p_data = (uint8_t *)&s_hts_env.hts_init.meas_interval; event.length = sizeof(uint16_t); s_hts_env.meas_ind_cfg[conn_idx] = cccd_value; break; - + case HTS_IDX_INTM_TEM_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE :\ - HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE); + HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE :\ + HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE); s_hts_env.intm_tem_ntf_cfg[conn_idx] = cccd_value; break; - + case HTS_IDX_MEAS_INTERVAL_VAL: if (((le16toh(p_param->value) >= s_hts_env.hts_init.min_meas_interval_sup) && \ (le16toh(p_param->value) <= s_hts_env.hts_init.max_meas_interval_sup)) || \ - (le16toh(p_param->value) == 0)) { - event.evt_type = HTS_EVT_MEAS_INTERVAL_UPDATE; - event.p_data = p_param->value; - event.length = sizeof(uint16_t); - s_hts_env.hts_init.meas_interval = le16toh(p_param->value); - } else { - cfm.status = 0x80; // Out of Range + (0 == le16toh(p_param->value))) + { + event.evt_type = HTS_EVT_MEAS_INTERVAL_UPDATE; + event.p_data = p_param->value; + event.length = sizeof(uint16_t); + s_hts_env.hts_init.meas_interval = le16toh(p_param->value); + } + else + { + cfm.status = 0x80; // Out of Range } break; - + case HTS_IDX_MEAS_INTERVAL_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE :\ - HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE); + HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE :\ + HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE); s_hts_env.meas_interval_ind_cfg[conn_idx] = cccd_value; break; @@ -396,8 +326,8 @@ static void hts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p break; } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && HTS_EVT_INVALID != event.evt_type && - s_hts_env.hts_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && HTS_EVT_INVALID != event.evt_type && s_hts_env.hts_init.evt_handler) + { s_hts_env.hts_init.evt_handler(&event); } @@ -413,12 +343,13 @@ static void hts_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void hts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void hts_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { - uint16_t tab_index = 0; + uint16_t tab_index = 0;; hts_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -427,25 +358,26 @@ static void hts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val HTS_IDX_NB, (uint8_t *)&s_hts_env.hts_init.char_mask); - switch (tab_index) { + switch (tab_index) + { case HTS_IDX_TEM_MEAS_IND_CFG: event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - HTS_EVT_TEM_MEAS_INDICATION_ENABLE :\ - HTS_EVT_TEM_MEAS_INDICATION_DISABLE); + HTS_EVT_TEM_MEAS_INDICATION_ENABLE :\ + HTS_EVT_TEM_MEAS_INDICATION_DISABLE); s_hts_env.meas_ind_cfg[conn_idx] = cccd_value; break; - + case HTS_IDX_INTM_TEM_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE :\ - HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE); + HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE :\ + HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE); s_hts_env.intm_tem_ntf_cfg[conn_idx] = cccd_value; break; - + case HTS_IDX_MEAS_INTERVAL_IND_CFG: event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE :\ - HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE); + HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE :\ + HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE); s_hts_env.meas_interval_ind_cfg[conn_idx] = cccd_value; break; @@ -454,7 +386,8 @@ static void hts_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (HTS_EVT_INVALID != event.evt_type && s_hts_env.hts_init.evt_handler) { + if (HTS_EVT_INVALID != event.evt_type && s_hts_env.hts_init.evt_handler) + { s_hts_env.hts_init.evt_handler(&event); } } @@ -475,24 +408,27 @@ static uint16_t hts_htm_encoded(hts_meas_val_t *p_meas, uint8_t *p_encoded_buffe uint16_t length = 1; uint32_t encoded_sfloat = 0; - if (HTS_TEMPERATURE_CELCIUS == s_hts_env.hts_init.temperature_units) { - p_meas->temp_convert_value.exponent = EXPONEBT_2; + if (HTS_TEMPERATURE_CELCIUS == s_hts_env.hts_init.temperature_units) + { + p_meas->temp_convert_value.exponent = -2; p_meas->temp_convert_value.mantissa = p_meas->temp_original_value; - } else { - p_meas->temp_convert_value.exponent = EXPONEBT_2; - p_meas->temp_convert_value.mantissa = (MANTISSA_32 * MANTISSA_32_SCALE) + - ((p_meas->temp_original_value * SCALE_9) / DESCALE_5); + } + else + { + p_meas->temp_convert_value.exponent = -2; + p_meas->temp_convert_value.mantissa = (32 * 100) + ((p_meas->temp_original_value * 9) / 5); flags |= HTS_MEAS_FLAG_TEM_UINTS_BIT; } - encoded_sfloat = ((p_meas->temp_convert_value.exponent << OFFSET_24) & 0xFF000000) | + encoded_sfloat = ((p_meas->temp_convert_value.exponent << 24) & 0xFF000000) | ((p_meas->temp_convert_value.mantissa << 0) & 0x00FFFFFF); p_encoded_buffer[length++] = LO_UINT32_T(encoded_sfloat); p_encoded_buffer[length++] = L2_UINT32_T(encoded_sfloat); p_encoded_buffer[length++] = L3_UINT32_T(encoded_sfloat); p_encoded_buffer[length++] = HI_UINT32_T(encoded_sfloat); - if (s_hts_env.hts_init.time_stamp_present) { + if (s_hts_env.hts_init.time_stamp_present) + { flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT; p_encoded_buffer[length++] = LO_U16(p_meas->time_stamp.year); p_encoded_buffer[length++] = HI_U16(p_meas->time_stamp.year); @@ -503,7 +439,8 @@ static uint16_t hts_htm_encoded(hts_meas_val_t *p_meas, uint8_t *p_encoded_buffe p_encoded_buffer[length++] = p_meas->time_stamp.sec; } - if ((s_hts_env.hts_init.char_mask & HTS_CHAR_TEM_TYPE_SUP) == 0) { + if (0 == (s_hts_env.hts_init.char_mask & HTS_CHAR_TEM_TYPE_SUP)) + { flags |= HTS_MEAS_FLAG_TEM_TYPE_BIT; p_encoded_buffer[length++] = p_meas->temp_type; } @@ -521,11 +458,13 @@ sdk_err_t hts_measurement_send(uint8_t conn_idx, hts_meas_val_t *p_meas) sdk_err_t error_code = SDK_ERR_NTF_DISABLED; uint8_t encoded_hts_meas[HTS_TEM_MEAS_MAX_LEN]; uint16_t length; - gatts_noti_ind_t hts_ind; + ble_gatts_noti_ind_t hts_ind; length = hts_htm_encoded(p_meas, encoded_hts_meas); - if (HTS_TEMPERATURE_STABLE == p_meas->temp_meas_type) { - if (PRF_CLI_START_IND == (s_hts_env.meas_ind_cfg[conn_idx] & PRF_CLI_START_IND)) { + if( HTS_TEMPERATURE_STABLE == p_meas->temp_meas_type) + { + if (PRF_CLI_START_IND == (s_hts_env.meas_ind_cfg[conn_idx] & PRF_CLI_START_IND)) + { hts_ind.type = BLE_GATT_INDICATION; hts_ind.handle = prf_find_handle_by_idx(HTS_IDX_TEM_MEAS_VAL, s_hts_env.start_hdl, @@ -534,8 +473,11 @@ sdk_err_t hts_measurement_send(uint8_t conn_idx, hts_meas_val_t *p_meas) hts_ind.value = encoded_hts_meas; error_code = ble_gatts_noti_ind(conn_idx, &hts_ind); } - } else { - if (PRF_CLI_START_NTF == (s_hts_env.intm_tem_ntf_cfg[conn_idx] & PRF_CLI_START_NTF)) { + } + else + { + if (PRF_CLI_START_NTF == (s_hts_env.intm_tem_ntf_cfg[conn_idx] & PRF_CLI_START_NTF)) + { hts_ind.type = BLE_GATT_NOTIFICATION; hts_ind.handle = prf_find_handle_by_idx(HTS_IDX_INTM_TEM_VAL, s_hts_env.start_hdl, @@ -551,9 +493,10 @@ sdk_err_t hts_measurement_send(uint8_t conn_idx, hts_meas_val_t *p_meas) sdk_err_t hts_measurement_interval_send(uint8_t conn_idx) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t hts_ind; - - if (PRF_CLI_START_IND == (s_hts_env.meas_interval_ind_cfg[conn_idx] & PRF_CLI_START_IND)) { + ble_gatts_noti_ind_t hts_ind; + + if (PRF_CLI_START_IND == (s_hts_env.meas_interval_ind_cfg[conn_idx] & PRF_CLI_START_IND)) + { hts_ind.type = BLE_GATT_INDICATION; hts_ind.handle = prf_find_handle_by_idx(HTS_IDX_MEAS_INTERVAL_VAL, s_hts_env.start_hdl, @@ -565,18 +508,52 @@ sdk_err_t hts_measurement_interval_send(uint8_t conn_idx) return error_code; } +static void hts_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + hts_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + hts_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + hts_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + default: + break; + } +} + sdk_err_t hts_service_init(hts_init_t *p_hts_init) { - sdk_err_t ret; - if (p_hts_init == NULL) { + if (NULL == p_hts_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_hts_env.hts_init, sizeof(hts_init_t), p_hts_init, sizeof(hts_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_hts_env.hts_init, p_hts_init, sizeof(hts_init_t)); - return ble_server_prf_add(&hts_prf_info); + memset(&s_hts_env.hts_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_hts_env.start_hdl = PRF_INVALID_HANDLE; + s_hts_env.hts_serv_db.shdl = &s_hts_env.start_hdl; + s_hts_env.hts_serv_db.uuid = s_hts_svc_uuid; + s_hts_env.hts_serv_db.attr_tab_cfg = (uint8_t *)&(s_hts_env.hts_init.char_mask); + s_hts_env.hts_serv_db.max_nb_attr = HTS_IDX_NB; + s_hts_env.hts_serv_db.srvc_perm = 0; + s_hts_env.hts_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_hts_env.hts_serv_db.attr_tab.attr_tab_16 = hts_attr_tab; + + return ble_gatts_prf_add(&s_hts_env.hts_serv_db, hts_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.h index 49fe4fe..5d06bb5 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/hts/hts.h @@ -49,47 +49,46 @@ * @details The Health Thermometer Service exposes temperature and other data related to a * thermometer used for healthcare applications. This module implements the Health * Thermometer Service with the Temperature Meaturement, Temperature Type, Intermediate - * Temperature, and Measurement Interval characteristics. + * Temperature, and Measurement Interval characteristics. * * After \ref hts_init_t variable is initialized, the application must call \ref hts_service_init() * to optionally add the Health Thermometer Service, Temperature Meaturement, Temperature Type, * Intermediate Temperature, and Measurement Interval characteristics to the BLE stack database - * according to \ref hts_init_t.char_mask. However the value of Temperature Type is stored within + * according to \ref hts_init_t.char_mask. However the value of Temperature Type is stored within * \ref hts_init_t.temp_type which locates in user space. */ - + #ifndef _HTS_H_ #define _HTS_H_ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup HTS_MACRO Defines * @{ */ -#define HTS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Health Thermometer Service connections. */ -#define HTS_TEM_MEAS_MAX_LEN 20 /**< Maximum length of temperature measurement encode. */ -#define HTS_TEM_TYPE_MAX_LEN 1 /**< Maximum length of temperature type value. */ -#define HTS_INTM_TEM_MAX_LEN 20 /**< Maximun length of intermediate temperature encode. */ -#define HTS_MEAS_INTERVAL_MAX_LEN 2 /**< Maximum length of measurement interval value. */ -#define HTS_MEAS_INTV_DFLT_MIN 2 /**< Minimun interval of temperature measurement (in unit of 1s). */ -#define HTS_MEAS_INTV_DFLT_MAX 10 /**< Maximum interval of temperature measurement (in unit of 1s). */ +#define HTS_CONNECTION_MAX 10 /**< Maximum number of Health Thermometer Service connections. */ +#define HTS_TEM_MEAS_MAX_LEN 20 /**< Maximum length of temperature measurement encode. */ +#define HTS_TEM_TYPE_MAX_LEN 1 /**< Maximum length of temperature type value. */ +#define HTS_INTM_TEM_MAX_LEN 20 /**< Maximun length of intermediate temperature encode. */ +#define HTS_MEAS_INTERVAL_MAX_LEN 2 /**< Maximum length of measurement interval value. */ +#define HTS_MEAS_INTV_DFLT_MIN 2 /**< Minimun interval of temperature measurement (in unit of 1s). */ +#define HTS_MEAS_INTV_DFLT_MAX 10 /**< Maximum interval of temperature measurement (in unit of 1s). */ /** * @defgroup HTS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref hts_init_t.char_mask. */ -#define HTS_CHAR_MANDATORY 0x000f /**< Bit mask for mandatory characteristic in HTS. */ -#define HTS_CHAR_TEM_TYPE_SUP 0x003f /**< Bit mask for temperature type characteristic that is optional. */ -#define HTS_CHAR_INTM_TEM_SUP 0x01c0 /**< Bit mask for intermediate temperature characteristic that is optional. */ -#define HTS_CHAR_MEAS_INTERVAL_SUP 0x1e00 /**< Bit mask for mearsurement interval characteristic that is optional. */ -#define HTS_CHAR_FULL 0x1fff /**< Bit mask of the full characteristic. */ +#define HTS_CHAR_MANDATORY 0x000f /**< Bit mask for mandatory characteristic in HTS. */ +#define HTS_CHAR_TEM_TYPE_SUP 0x003f /**< Bit mask for temperature type characteristic that is optional. */ +#define HTS_CHAR_INTM_TEM_SUP 0x01c0 /**< Bit mask for intermediate temperature characteristic that is optional. */ +#define HTS_CHAR_MEAS_INTERVAL_SUP 0x1e00 /**< Bit mask for mearsurement interval characteristic that is optional. */ +#define HTS_CHAR_FULL 0x1fff /**< Bit mask of the full characteristic. */ /** @} */ /** @} */ @@ -98,39 +97,44 @@ * @{ */ /**@brief Health Thermometer Service event type.*/ -typedef enum { - HTS_EVT_INVALID, /**< Indicate that invalid event. */ - HTS_EVT_TEM_MEAS_INDICATION_ENABLE, /**< Indicate that temperature measurement indication has been enabled. */ - HTS_EVT_TEM_MEAS_INDICATION_DISABLE, /**< Indicate that temperature measurement indication has been disabled. */ - HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE, /**< Indicate that intermediate temperature notification has been enabled. */ - HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE, /**< Indicate that intermediate temperature notification has been disbled. */ - HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE, /**< Indicate that measurement interval indication has been enabled. */ - HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE, /**< Indicate that measurement interval indication has been disabled. */ - HTS_EVT_MEAS_INTERVAL_UPDATE, /**< Indicate that measurement interval has been updated. */ - HTS_EVT_READ_CHARACTERISTIC, /**< The peer reads the characteristic. */ +typedef enum +{ + HTS_EVT_INVALID, /**< Indicate that invalid event. */ + HTS_EVT_TEM_MEAS_INDICATION_ENABLE, /**< Indicate that temperature measurement indication has been enabled. */ + HTS_EVT_TEM_MEAS_INDICATION_DISABLE, /**< Indicate that temperature measurement indication has been disabled. */ + HTS_EVT_INTM_TEM_NOTIFICATION_ENABLE, /**< Indicate that intermediate temperature notification has been enabled. */ + HTS_EVT_INTM_TEM_NOTIFICATION_DISABLE, /**< Indicate that intermediate temperature notification has been disbled. */ + HTS_EVT_MEAS_INTREVAL_INDICATION_ENABLE, /**< Indicate that measurement interval indication has been enabled. */ + HTS_EVT_MEAS_INTERVAL_INDICATION_DISABLE, /**< Indicate that measurement interval indication has been disabled. */ + HTS_EVT_MEAS_INTERVAL_UPDATE, /**< Indicate that measurement interval has been updated. */ + HTS_EVT_READ_CHARACTERISTIC, /**< The peer reads the characteristic. */ } hts_evt_type_t; /**@brief Health Thermometer temperature unit, */ -typedef enum { - HTS_TEMPERATURE_CELCIUS, /**< Indicate that temperature measurement Value Unit is celcius. */ - HTS_TEMPERATURE_FAHRENHEIT, /**< Indicate that temperature measurement Value Unit is fahrenheit. */ +typedef enum +{ + HTS_TEMPERATURE_CELCIUS, /**< Indicate that temperature measurement Value Unit is celcius. */ + HTS_TEMPERATURE_FAHRENHEIT, /**< Indicate that temperature measurement Value Unit is fahrenheit. */ } hts_temp_unit_t; /**@brief Health Thermometer temperature measurement type. */ -typedef enum { - HTS_TEMPERATURE_STABLE, /**< Stable type of temperature. */ - HTS_TEMPERATURE_INTERMEDIATE, /**< Intermediary type of temperature. */ +typedef enum +{ + HTS_TEMPERATURE_STABLE, /**< Stable type of temperature. */ + HTS_TEMPERATURE_INTERMEDIATE, /**< Intermediary type of temperature. */ } hts_temp_meas_type_t; /**@brief Health Thermometer Measurement flag bits. */ -typedef enum { +typedef enum +{ HTS_MEAS_FLAG_TEM_UINTS_BIT = (0x01<<0), /**< Bit for temperature uints. */ HTS_MEAS_FLAG_TIME_STAMP_BIT = (0x01<<1), /**< Bit for time stamp. */ HTS_MEAS_FLAG_TEM_TYPE_BIT = (0x01<<2), /**< Bit for temperature type. */ } hts_flag_bit_t; /**@brief Temperature Type measurement locations. */ -typedef enum { +typedef enum +{ HTS_TEMP_TYPE_ARMPIT = 0x01, /**< Temperature measurement location: armpit. */ HTS_TEMP_TYPE_BODY, /**< Temperature measurement location: body. */ HTS_TEMP_TYPE_EAR, /**< Temperature measurement location: ear. */ @@ -143,7 +147,8 @@ typedef enum { } hts_temp_meas_loc_t; /**@brief The parameters for \ref HTS_EVT_READ_CHARACTERISTIC. */ -typedef enum { +typedef enum +{ HTS_READ_CHAR_TEMP_TYPE, /**< The peer reads the Temperature Type characteristic. */ HTS_READ_CHAR_MEAS_INTL, /**< The peer reads the Measurement Interval characteristic. */ } hts_read_characteristic_t; @@ -154,7 +159,8 @@ typedef enum { * @{ */ /**@brief Health Thermometer Service event. */ -typedef struct { +typedef struct +{ hts_evt_type_t evt_type; /**< The HTS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to the event data. */ @@ -178,13 +184,15 @@ typedef prf_date_time_t hts_date_time_t; * @{ */ /**@brief SFLOAT format (IEEE-11073 32-bit FLOAT, defined as a 32-bit vlue with 24-bit mantissa and 8-bit exponent. */ -typedef struct { - int8_t exponent; /**< Base 10 exponent, only 8 bits */ - int32_t mantissa; /**< Mantissa, only 24 bits */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, only 8 bits */ + int32_t mantissa; /**< Mantissa, only 24 bits */ } ieee_float32_t; /**@brief Health Theromometer Measurement Character value structure. */ -typedef struct { +typedef struct +{ hts_temp_meas_type_t temp_meas_type; /**< Stable or intermediary type of temperature. */ uint16_t temp_original_value; /**< Temperature measurement original value. */ ieee_float32_t temp_convert_value; /**< Temperature measurement convert value. */ @@ -192,16 +200,15 @@ typedef struct { hts_temp_meas_loc_t temp_type; /**< Temperature Type measurement location. */ } hts_meas_val_t; -/**@brief Health Thermometer Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Health Thermometer Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ hts_evt_handler_t evt_handler; /**< Health Thermometer Service event handler. */ - uint16_t - char_mask; /**< Initial mask of Supported characteristics, and configured with \ref HTS_CHAR_MASK */ - hts_temp_unit_t temperature_units; /**< Initial if Temperature is in Fahrenheit unit, Celcius otherwise. */ - bool time_stamp_present; /**< Initial if Time Stamp is present. */ - hts_temp_meas_loc_t temp_type; /**< Initial temperature type measurement location. */ - uint16_t meas_interval; /**< Initial temperature measurement interval. */ + uint16_t char_mask; /**< Initial mask of Supported characteristics, and configured with \ref HTS_CHAR_MASK */ + hts_temp_unit_t temperature_units; /**< Initial if Temperature is in Fahrenheit unit, Celcius otherwise. */ + bool time_stamp_present; /**< Initial if Time Stamp is present. */ + hts_temp_meas_loc_t temp_type; /**< Initial temperature type measurement location. */ + uint16_t meas_interval; /**< Initial temperature measurement interval. */ uint16_t min_meas_interval_sup; /**< Initial minimum temperature measurement interval support. */ uint16_t max_meas_interval_sup; /**< Initial maximum temperature measurement interval support. */ } hts_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/BUILD.gn new file mode 100644 index 0000000..7793368 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ias") { + sources = [ "ias.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.c index 8a11b90..b5d4c68 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.c @@ -35,7 +35,7 @@ ***************************************************************************************** */ -/* +/* * INCLUDE FILES ***************************************************************************************** */ @@ -55,7 +55,8 @@ ***************************************************************************************** */ /**@brief IAS Attributes database index list. */ -enum ias_attr_idx_t { +enum ias_attr_idx_t +{ IAS_IDX_SVC, IAS_IDX_ALERT_LVL_CHAR, @@ -65,9 +66,11 @@ enum ias_attr_idx_t { }; /**@brief Immediate Alert Service environment variable. */ -struct ias_env_t { - ias_init_t ias_init; /**< Immediate Alert Service initialization variables. */ - uint16_t start_hdl; /**< Immediate Alert Service start handle. */ +struct ias_env_t +{ + ias_init_t ias_init; /**< Immediate Alert Service initialization variables. */ + uint16_t start_hdl; /**< Immediate Alert Service start handle. */ + ble_gatts_create_db_t ias_serv_db; /**< Immediate Alert Service DataBase. */ }; /* * LOCAL VARIABLE DEFINITIONS @@ -79,46 +82,23 @@ static uint8_t s_char_mask = 0x07; /**< Features added into ATT database. * bit1 - Alert Level Characteristic Declaration * bit2 - Alert Level Characteristic Value */ +static const uint8_t s_ias_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_IMMEDIATE_ALERT); -/**@brief IAS Database Description - Used to add attributes into the database. */ -static const attm_desc_t ias_attr_tab[IAS_IDX_NB] = { +/**@brief IAS Database Description - Used to add attributes into the database. */ +static const ble_gatts_attm_desc_t ias_attr_tab[IAS_IDX_NB] = +{ // Immediate Alert Service Declaration - [IAS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [IAS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Level Characteristic Declaration - [IAS_IDX_ALERT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [IAS_IDX_ALERT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Level Characteristic Value - [IAS_IDX_ALERT_LVL_VAL] = {BLE_ATT_CHAR_ALERT_LEVEL, WRITE_CMD_PERM_UNSEC, 0, sizeof(uint8_t)}, + [IAS_IDX_ALERT_LVL_VAL] = {BLE_ATT_CHAR_ALERT_LEVEL, BLE_GATTS_WRITE_CMD_PERM_UNSEC, 0, sizeof(uint8_t)}, }; /* * LOCAL FUNCTION DECLARATIONS ***************************************************************************************** */ -static sdk_err_t ias_init(void); -static void ias_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); - -/**@brief IAS interface required by profile manager. */ -static ble_prf_manager_cbs_t ias_mgr_cbs = { - (prf_init_func_t)ias_init, - NULL, - NULL -}; - -/**@brief IAS GATT server Callbacks. */ -static gatts_prf_cbs_t ias_gatts_cbs = { - NULL, - ias_write_att_cb, - NULL, - NULL -}; - -/**@brief IAS Information. */ -static const prf_server_info_t ias_prf_info = { - /* There shall be only one connection with a device. */ - .max_connection_nb = 1, - .manager_cbs = &ias_mgr_cbs, - .gatts_prf_cbs = &ias_gatts_cbs -}; /* * LOCAL FUNCTION DEFINITIONS @@ -131,41 +111,6 @@ static const prf_server_info_t ias_prf_info = { * @return Error code to know if service initialization succeed or not. ***************************************************************************************** */ -static sdk_err_t ias_init(void) -{ - const uint8_t ias_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_IMMEDIATE_ALERT); - gatts_create_db_t gatts_db; - sdk_err_t ret; - uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out - * parameter of ble_gatts_srvc_db_create(). - * It must be set with PRF_INVALID_HANDLE - * to be allocated automatically by BLE Stack. */ - - ret = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = (uint8_t *)ias_svc_uuid; - gatts_db.attr_tab_cfg = &s_char_mask; - gatts_db.max_nb_attr = IAS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = ias_attr_tab; - - sdk_err_t error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_ias_env.start_hdl = *gatts_db.shdl; - - uint16_t handle = prf_find_handle_by_idx(IAS_IDX_ALERT_LVL_VAL, s_ias_env.start_hdl, &s_char_mask); - uint8_t initial_alert_level = INITIAL_ALERT_LEVEL; - - ble_gatts_value_set(handle, sizeof(uint8_t), 0, &initial_alert_level); - } - - return error_code; -} /** ***************************************************************************************** @@ -175,33 +120,40 @@ static sdk_err_t ias_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void ias_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void ias_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = prf_find_handle_by_idx(IAS_IDX_ALERT_LVL_VAL, s_ias_env.start_hdl, &s_char_mask); - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; cfm.handle = p_param->handle; - if (handle != p_param->handle) { + if (handle != p_param->handle) + { cfm.status = BLE_ATT_ERR_INVALID_HANDLE; - } else { - if (p_param->length != sizeof(uint8_t)) { + } + else + { + if (p_param->length != sizeof(uint8_t)) + { cfm.status = SDK_ERR_INVALID_ATT_VAL_LEN; - } else { - // Send write response + } + else + { + //Send write response uint8_t value = p_param->value[0]; cfm.status = (uint8_t)ble_gatts_value_set(cfm.handle, sizeof(uint8_t), 0, &value); - if (cfm.status != BLE_SUCCESS) { - return; - } - /* Alert level updated by the peer, notify app the event. */ - if (s_ias_env.ias_init.evt_handler) { - ias_evt_t evt; + if (BLE_SUCCESS == cfm.status) + { + /* Alert level updated by the peer, notify app the event. */ + if (s_ias_env.ias_init.evt_handler) + { + ias_evt_t evt; - evt.evt_type = IAS_EVT_ALERT_LEVEL_UPDATED; - evt.alert_level = value; - s_ias_env.ias_init.evt_handler(&evt); + evt.evt_type = IAS_EVT_ALERT_LEVEL_UPDATED; + evt.alert_level = value; + s_ias_env.ias_init.evt_handler(&evt); + } } } } @@ -221,13 +173,47 @@ sdk_err_t ias_alert_level_get(uint8_t *p_alert_level) return ble_gatts_value_get(handle, &length, p_alert_level); } +static void ias_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + ias_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + break; + default: + break; + } +} sdk_err_t ias_service_init(ias_init_t *p_ias_init) { - if (p_ias_init == NULL) { + if (NULL == p_ias_init) + { return SDK_ERR_POINTER_NULL; } s_ias_env.ias_init.evt_handler = p_ias_init->evt_handler; - return ble_server_prf_add(&ias_prf_info); + memset(&s_ias_env.ias_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_ias_env.start_hdl = PRF_INVALID_HANDLE; + s_ias_env.ias_serv_db.shdl = &s_ias_env.start_hdl; + s_ias_env.ias_serv_db.uuid = s_ias_svc_uuid; + s_ias_env.ias_serv_db.attr_tab_cfg = &s_char_mask; + s_ias_env.ias_serv_db.max_nb_attr = IAS_IDX_NB; + s_ias_env.ias_serv_db.srvc_perm = 0; + s_ias_env.ias_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_ias_env.ias_serv_db.attr_tab.attr_tab_16 = ias_attr_tab; + + return ble_gatts_prf_add(&s_ias_env.ias_serv_db, ias_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.h index 1e59cf2..ebea1e0 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias/ias.h @@ -47,9 +47,9 @@ * @brief Definitions and prototypes for the IAS interface. * * @details The Immediate Alert Service exposes a control point to allow a peer device to cause - * the device to immediately alert. + * the device to immediately alert. * - * The application must provide an event handler to set \ref ias_init_t.evt_handler. + * The application must provide an event handler to set \ref ias_init_t.evt_handler. * After \ref ias_init_t variable is initialized, the application must call \ref ias_service_init() * to add the Immediate Alert Service and Alert Level characteristic to the BLE Stack database, * the service will notify the application when the value of Alert Level characteristic is changed @@ -63,26 +63,28 @@ #ifndef __IAS_H__ #define __IAS_H__ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup IAS_ENUM Enumerations * @{ */ /**@brief Immediate Alert Service Alert levels. */ -enum { +enum +{ IAS_ALERT_NONE, /**< No alert. */ IAS_ALERT_MILD, /**< Mild alert. */ IAS_ALERT_HIGH, /**< High alert. */ }; /**@brief Immediate Alert Service event type. */ -typedef enum { +typedef enum +{ IAS_EVT_INVALID, /**< Invalid IAS event. */ IAS_EVT_ALERT_LEVEL_UPDATED, /**< Alert Level Updated event. */ -} ias_evt_type_t; +}ias_evt_type_t; /** @} */ /** @@ -90,10 +92,11 @@ typedef enum { * @{ */ /**@brief Immediate Alert Service event. */ -typedef struct { +typedef struct +{ ias_evt_type_t evt_type; /**< Type of event. */ uint8_t alert_level; /**< New value of Alert level. */ -} ias_evt_t; +}ias_evt_t; /** @} */ /** @@ -108,9 +111,9 @@ typedef void (*ias_evt_handler_t)(ias_evt_t *p_evt); * @addtogroup IAS_STRUCT Structures * @{ */ -/**@brief Immediate Alert Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Immediate Alert Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ ias_evt_handler_t evt_handler; /**< Immediate Alert Service event handler. */ } ias_init_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/BUILD.gn new file mode 100644 index 0000000..404dba4 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ias_c") { + sources = [ "ias_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.c index 3e564a8..f467726 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.c @@ -39,64 +39,34 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "ias_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "ias_c.h" - -#define OFFSET_8 8 +#include /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Immediate Alert Service environment variable. */ -struct ias_c_env_t { +struct ias_c_env_t +{ ias_c_handles_t handles; /**< Handles of IAS characteristics which will be got for peer. */ ias_c_evt_handler_t evt_handler; /**< Handler of IAS Client event */ uint8_t prf_id; /**< IAS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void ias_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void ias_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct ias_c_env_t s_ias_c_env; /**< Immediate Alert Service Client environment variable. */ - -/**@brief Immediate Alert Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t ias_c_mgr_cbs = { - NULL, - NULL, - NULL +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_IMMEDIATE_ALERT), HI_U16(BLE_ATT_SVC_IMMEDIATE_ALERT)}; +static ble_uuid_t s_ias_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; - -/**@brief Immediate Alert Service GATT Client Callbacks. */ -static gattc_prf_cbs_t ias_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - ias_c_att_write_cb, - NULL, - ias_c_srvc_browse_cb, - NULL, -}; - -/**@brief Immediate Alert Service Client Information. */ -static const prf_client_info_t ias_c_prf_info = { - .max_connection_nb = IAS_C_CONNECTION_MAX, - .manager_cbs = &ias_c_mgr_cbs, - .gattc_prf_cbs = &ias_c_gattc_cbs -}; - /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -110,19 +80,21 @@ static const prf_client_info_t ias_c_prf_info = { * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void ias_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void ias_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { ias_c_evt_t ias_c_evt; ias_c_evt.conn_idx = conn_idx; ias_c_evt.evt_type = IAS_C_EVT_INVALID; - if (handle == s_ias_c_env.handles.ias_alert_level_handle) { + if (handle == s_ias_c_env.handles.ias_alert_level_handle) + { ias_c_evt.evt_type = (BLE_SUCCESS == status) ?\ IAS_C_EVT_ALERT_LEVEL_SET_SUCCESS :\ IAS_C_EVT_ALERT_LEVEL_SET_ERR; - if (s_ias_c_env.evt_handler) { + if (s_ias_c_env.evt_handler) + { s_ias_c_env.evt_handler(&ias_c_evt); } } @@ -137,7 +109,7 @@ static void ias_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void ias_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void ias_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { ias_c_evt_t ias_c_evt; uint16_t uuid_disc; @@ -146,88 +118,97 @@ static void ias_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat ias_c_evt.conn_idx = conn_idx; ias_c_evt.evt_type = IAS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_IMMEDIATE_ALERT == uuid_disc) { - s_ias_c_env.handles.ias_srvc_start_handle = p_browse_srvc->start_hdl; - s_ias_c_env.handles.ias_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_IMMEDIATE_ALERT == uuid_disc) + { + s_ias_c_env.handles.ias_srvc_start_handle = p_browse_srvc->start_hdl; + s_ias_c_env.handles.ias_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_ALERT_LEVEL == uuid_disc) { - s_ias_c_env.handles.ias_alert_level_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_ALERT_LEVEL == uuid_disc) + { + s_ias_c_env.handles.ias_alert_level_handle = handle_disc; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; } - } - ias_c_evt.evt_type = IAS_C_EVT_DISCOVERY_COMPLETE; + ias_c_evt.evt_type = IAS_C_EVT_DISCOVERY_COMPLETE; + } } - if (s_ias_c_env.evt_handler) { + if (s_ias_c_env.evt_handler) + { s_ias_c_env.evt_handler(&ias_c_evt); } } +static void ias_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_WRITE_REQUEST: + ias_c_att_write_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_SRVC_BROWSE: + ias_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ias_client_init(ias_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_ias_c_env, sizeof(s_ias_c_env), 0, sizeof(s_ias_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_ias_c_env, 0, sizeof(s_ias_c_env)); s_ias_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&ias_c_prf_info, &s_ias_c_env.prf_id); + return ble_gattc_prf_add(&s_ias_service_uuid, ias_c_ble_evt_handler); } sdk_err_t ias_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - - target_uuid[0] = LO_U16(BLE_ATT_SVC_IMMEDIATE_ALERT); - target_uuid[1] = HI_U16(BLE_ATT_SVC_IMMEDIATE_ALERT); - - const ble_uuid_t ias_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_ias_c_env.prf_id, conn_idx, &ias_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_ias_service_uuid); } sdk_err_t ias_c_alert_level_set(uint8_t conn_idx, ias_c_alert_level_t alert_level) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_ias_c_env.handles.ias_alert_level_handle) { + if (BLE_ATT_INVALID_HDL == s_ias_c_env.handles.ias_alert_level_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_ias_c_env.handles.ias_alert_level_handle; - write_attr_value.length = sizeof(uint8_t); - write_attr_value.p_value = (uint8_t *)&alert_level; - - return ble_gattc_prf_write_no_resp(s_ias_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_ias_c_env.handles.ias_alert_level_handle, \ + sizeof(uint8_t), (uint8_t *)&alert_level); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.h index 767951d..f6912c8 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ias_c/ias_c.h @@ -56,18 +56,17 @@ #ifndef __IAS_C_H__ #define __IAS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup IAS_C_MACRO Defines * @{ */ -#define IAS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of IAS Client connections. */ +#define IAS_C_CONNECTION_MAX 10 /**< Maximum number of IAS Client connections. */ /** @} */ /** @@ -75,18 +74,19 @@ * @{ */ /**@brief Immediate Alert Service Alert levels. */ -typedef enum { +typedef enum +{ IAS_C_ALERT_NONE, /**< No alert. */ IAS_C_ALERT_MILD, /**< Mild alert. */ IAS_C_ALERT_HIGH, /**< High alert. */ } ias_c_alert_level_t; /**@brief Immediate Alert Service Client event type. */ -typedef enum { +typedef enum +{ IAS_C_EVT_INVALID, /**< IAS Client invalid event. */ IAS_C_EVT_DISCOVERY_COMPLETE, /**< IAS Client has found BAS service and its characteristics. */ - IAS_C_EVT_DISCOVERY_FAIL, /**< IAS Client found BAS service failed because of invalid operation \ - or no found at the peer. */ + IAS_C_EVT_DISCOVERY_FAIL, /**< IAS Client found BAS service failed because of invalid operation or no found at the peer. */ IAS_C_EVT_ALERT_LEVEL_SET_SUCCESS, /**< IAS Client has set Alert Level characteristic. */ IAS_C_EVT_ALERT_LEVEL_SET_ERR, /**< Error occured when IAS Client set Alert Level characteristic. */ } ias_c_evt_type_t; @@ -97,14 +97,16 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { - uint16_t ias_srvc_start_handle; /**< IAS Service start handle. */ - uint16_t ias_srvc_end_handle; /**< IAS Service end handle. */ - uint16_t ias_alert_level_handle; /**< IAS Alert Level characteristic Value handle which has been got from peer. */ +typedef struct +{ + uint16_t ias_srvc_start_handle; /**< IAS Service start handle. */ + uint16_t ias_srvc_end_handle; /**< IAS Service end handle. */ + uint16_t ias_alert_level_handle; /**< IAS Alert Level characteristic Value handle which has been got from peer. */ } ias_c_handles_t; /**@brief Immediate Alert Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ ias_c_evt_type_t evt_type; /**< IAS Client event type. */ } ias_c_evt_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/BUILD.gn new file mode 100644 index 0000000..5d1515d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("lls") { + sources = [ "lls.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.c index ebb95dd..98a10bf 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.c @@ -1,7 +1,7 @@ /** ***************************************************************************************** * - * @file bas.c + * @file lls.c * * @brief Link Loss Server Implementation. * @@ -49,7 +49,8 @@ ***************************************************************************************** */ /**@brief LLS Attributes database index list. */ -enum lls_attr_idx_t { +enum lls_attr_idx_t +{ LLS_IDX_SVC, LLS_IDX_ALERT_LVL_CHAR, @@ -63,9 +64,11 @@ enum lls_attr_idx_t { ***************************************************************************************** */ /**@brief Link Loss Service environment variable. */ -struct lls_env_t { - lls_init_t lls_init; /**< Link Loss Service initialization variables. */ - uint16_t start_hdl; /**< Link Loss Service start handle. */ +struct lls_env_t +{ + lls_init_t lls_init; /**< Link Loss Service initialization variables. */ + uint16_t start_hdl; /**< Link Loss Service start handle. */ + ble_gatts_create_db_t lls_serv_db; /**< Link Loss Service DataBase. */ }; /* @@ -79,92 +82,27 @@ static uint8_t s_char_mask = 0x07; /**< Features added into ATT datab * bit1 - Alert Level Characteristic Declaration * bit2 - Alert Level Characteristic Value */ +static const uint8_t s_lls_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_LINK_LOSS); /**@brief Full LLS Database Description - Used to add attributes into the * database. */ -static const attm_desc_t lls_attr_tab[LLS_IDX_NB] = { +static const ble_gatts_attm_desc_t lls_attr_tab[LLS_IDX_NB] = +{ // Link Loss Service Declaration - [LLS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [LLS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Level Characteristic Declaration - [LLS_IDX_ALERT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [LLS_IDX_ALERT_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Level Characteristic Value - [LLS_IDX_ALERT_LVL_VAL] = {BLE_ATT_CHAR_ALERT_LEVEL, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, sizeof(uint8_t)}, + [LLS_IDX_ALERT_LVL_VAL] = {BLE_ATT_CHAR_ALERT_LEVEL, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, sizeof(uint8_t)}, }; /* * LOCAL FUNCTION DECLARATIONS ******************************************************************************* */ -static sdk_err_t lls_init(void); static void lls_on_connect(uint8_t conn_idx); static void lls_on_disconnect(uint8_t conn_idx, uint8_t reason); -static void lls_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); - -/**@brief LLS interface required by profile manager. */ -static ble_prf_manager_cbs_t lls_mgr_cbs = { - (prf_init_func_t)lls_init, - lls_on_connect, - lls_on_disconnect -}; - -/**@brief LLS GATT server callbacks. */ -static gatts_prf_cbs_t lls_gatts_cbs = { - NULL, - lls_write_att_cb, - NULL, - NULL -}; - -/**@brief LLS Information. */ -static const prf_server_info_t lls_prf_info = { - /* There shall be only one connection on a device. */ - .max_connection_nb = 1, - .manager_cbs = &lls_mgr_cbs, - .gatts_prf_cbs = &lls_gatts_cbs -}; - -/** - ***************************************************************************************** - * @brief Initialize Link Loss service and create database in BLE Stack. - * - * @return BLE_ATT_ERR_NO_ERROR on success, otherwise error code. - ***************************************************************************************** - */ -static sdk_err_t lls_init(void) -{ - const uint8_t lls_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_LINK_LOSS); - gatts_create_db_t gatts_db; - sdk_err_t ret; - uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out - * parameter of ble_gatts_srvc_db_create(). - * It must be set with PRF_INVALID_HANDLE - * to be allocated automatically by BLE Stack. */ - - ret = memset_S(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = (uint8_t *)lls_svc_uuid; - gatts_db.attr_tab_cfg = &s_char_mask; - gatts_db.max_nb_attr = LLS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = lls_attr_tab; - - sdk_err_t error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_lls_env.start_hdl = *gatts_db.shdl; - - uint16_t handle = prf_find_handle_by_idx(LLS_IDX_ALERT_LVL_VAL, s_lls_env.start_hdl, &s_char_mask); - ble_gatts_value_set(handle, sizeof(uint8_t), 0, (unsigned char *)(&s_lls_env.lls_init.initial_alert_level)); - } - - return error_code; -} /** ***************************************************************************************** @@ -178,11 +116,14 @@ static void lls_on_connect(uint8_t conn_idx) lls_evt_t evt; sdk_err_t ret; - if (s_lls_env.lls_init.evt_handler) { + if (s_lls_env.lls_init.evt_handler) + { evt.evt_type = LLS_EVT_LINK_LOSS_ALERT; ret = lls_alert_level_get((unsigned char *)(&evt.alert_level)); - if (SDK_SUCCESS == ret && s_lls_env.lls_init.evt_handler) { + + if (SDK_SUCCESS == ret && s_lls_env.lls_init.evt_handler) + { /* Inform Application the link is (re)connected */ s_lls_env.lls_init.evt_handler(&evt); } @@ -200,7 +141,8 @@ static void lls_on_connect(uint8_t conn_idx) static void lls_on_disconnect(uint8_t conn_idx, uint8_t reason) { /* The reason is HCI Connection Timeout */ - if (BLE_LL_ERR_CON_TIMEOUT == reason || BLE_LL_ERR_INSTANT_PASSED == reason) { + if (BLE_LL_ERR_CON_TIMEOUT == reason || BLE_LL_ERR_INSTANT_PASSED == reason) + { /* Link loss detected, inform application */ lls_evt_t evt; sdk_err_t ret; @@ -208,8 +150,11 @@ static void lls_on_disconnect(uint8_t conn_idx, uint8_t reason) evt.evt_type = LLS_EVT_LINK_LOSS_ALERT; ret = lls_alert_level_get((unsigned char *)(&evt.alert_level)); - if (SDK_SUCCESS == ret) { - if (s_lls_env.lls_init.evt_handler) { + + if (SDK_SUCCESS == ret) + { + if (s_lls_env.lls_init.evt_handler) + { s_lls_env.lls_init.evt_handler(&evt); } } @@ -226,20 +171,26 @@ static void lls_on_disconnect(uint8_t conn_idx, uint8_t reason) * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void lls_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void lls_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = prf_find_handle_by_idx(LLS_IDX_ALERT_LVL_VAL, s_lls_env.start_hdl, &s_char_mask); - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; cfm.handle = p_param->handle; - if (handle != p_param->handle) { + if (handle != p_param->handle) + { cfm.status = BLE_ATT_ERR_INVALID_HANDLE; - } else { - if (p_param->length != sizeof(uint8_t)) { + } + else + { + if (p_param->length != sizeof(uint8_t)) + { cfm.status = SDK_ERR_INVALID_ATT_VAL_LEN; - } else { - // Send write response + } + else + { + //Send write response uint8_t value = p_param->value[0]; cfm.status = (uint8_t)ble_gatts_value_set(cfm.handle, sizeof(uint8_t), 0, &value); @@ -249,22 +200,70 @@ static void lls_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p ble_gatts_write_cfm(conn_idx, &cfm); } +static void lls_ble_evt_handler(const ble_evt_t *p_evt) +{ + if(NULL == p_evt) + { + return ; + } + + uint16_t handle; + + switch(p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + break; + case BLE_GATTS_EVT_WRITE_REQUEST: + lls_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + case BLE_GATTS_EVT_NTF_IND: + break; + case BLE_GATTS_EVT_CCCD_RECOVERY: + break; + case BLE_GAPC_EVT_CONNECTED: + lls_on_connect(p_evt->evt.gapc_evt.index); + break; + case BLE_GAPC_EVT_DISCONNECTED: + lls_on_disconnect(p_evt->evt.gapc_evt.index,p_evt->evt.gapc_evt.params.disconnected.reason); + break; + case BLE_GATT_COMMON_EVT_PRF_REGISTER: + handle = prf_find_handle_by_idx(LLS_IDX_ALERT_LVL_VAL, s_lls_env.start_hdl, &s_char_mask); + ble_gatts_value_set(handle, sizeof(uint8_t), 0, (uint8_t *)&s_lls_env.lls_init.initial_alert_level); + break; + default: + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t lls_service_init(lls_init_t *p_lls_init) { - if (p_lls_init == NULL) { + if (NULL == p_lls_init) + { return SDK_ERR_POINTER_NULL; } - s_lls_env.lls_init.evt_handler = p_lls_init->evt_handler; + s_lls_env.lls_init.evt_handler = p_lls_init->evt_handler; + s_lls_env.lls_init.initial_alert_level = p_lls_init->initial_alert_level; - return ble_server_prf_add(&lls_prf_info); + memset(&s_lls_env.lls_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_lls_env.start_hdl = PRF_INVALID_HANDLE; + s_lls_env.lls_serv_db.shdl = &s_lls_env.start_hdl; + s_lls_env.lls_serv_db.uuid = s_lls_svc_uuid; + s_lls_env.lls_serv_db.attr_tab_cfg = &s_char_mask; + s_lls_env.lls_serv_db.max_nb_attr = LLS_IDX_NB; + s_lls_env.lls_serv_db.srvc_perm = 0; + s_lls_env.lls_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_lls_env.lls_serv_db.attr_tab.attr_tab_16 = lls_attr_tab; + + return ble_gatts_prf_add(&s_lls_env.lls_serv_db, lls_ble_evt_handler); } -sdk_err_t lls_alert_level_get(uint8_t *p_alert_level) +sdk_err_t lls_alert_level_get(uint8_t *p_alert_level) { uint16_t handle = prf_find_handle_by_idx(LLS_IDX_ALERT_LVL_VAL, s_lls_env.start_hdl, (uint8_t *)&s_char_mask); uint16_t length = sizeof(uint8_t); diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.h index 7126400..50bfc90 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls/lls.h @@ -49,7 +49,7 @@ * @details The Link Loss Service uses the Alert Level characteristic to cause an alert in the * device when the link is lost. * - * The application must provide an event handler to set \ref lls_init_t.evt_handler. + * The application must provide an event handler to set \ref lls_init_t.evt_handler. * After \ref lls_init_t variable is initialized, the application must call \ref lls_service_init() * to add Alert Level Characteristic to the BLE Stack database, the service will notify the application * with the event handler when the link has been lost, and which Alert Level has been set. @@ -62,23 +62,25 @@ #ifndef __LLS_H__ #define __LLS_H__ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup LLS_ENUM Enumerations * @{ */ /** Link Loss Service alert levels. */ -typedef enum { +typedef enum +{ LLS_ALERT_LEVEL_NO_ALERT, /**< No alert. */ LLS_ALERT_LEVEL_MILD_ALERT, /**< Mild alert. */ LLS_ALERT_LEVEL_HIGH_ALERT, /**< High alert. */ } lls_alert_levels_t; /**@brief Link Loss Service event type. */ -typedef enum { +typedef enum +{ LLS_EVT_INVALID, /**< Invalid LLS event. */ LLS_EVT_LINK_LOSS_ALERT /**< Link loss alert event. */ } lls_evt_type_t; @@ -89,7 +91,8 @@ typedef enum { * @{ */ /**@brief Link Loss Service event. */ -typedef struct { +typedef struct +{ lls_evt_type_t evt_type; /**< Type of event. */ lls_alert_levels_t alert_level; /**< Alert level. */ } lls_evt_t; @@ -107,9 +110,9 @@ typedef void (*lls_evt_handler_t)(lls_evt_t *p_evt); * @addtogroup LLS_STRUCT Structures * @{ */ -/**@brief Link Loss Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Link Loss Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ lls_evt_handler_t evt_handler; /**< Link Loss Service event handler. */ lls_alert_levels_t initial_alert_level; /**< Initial value of the alert level. */ } lls_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/BUILD.gn new file mode 100644 index 0000000..1ee5d83 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("lls_c") { + sources = [ "lls_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.c index ce99689..55be44c 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.c @@ -39,62 +39,33 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "lls_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "lls_c.h" +#include -#define OFFSET_8 8 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Link Loss Service environment variable. */ -struct lls_c_env_t { +struct lls_c_env_t +{ lls_c_handles_t handles; /**< Handles of LLS characteristics which will be got for peer. */ lls_c_evt_handler_t evt_handler; /**< Handler of LLS Client event */ uint8_t prf_id; /**< LLS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void lls_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void lls_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void lls_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct lls_c_env_t s_lls_c_env; /**< Link Loss Service Client environment variable. */ - -/**@brief Link Loss Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t lls_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Link Loss Service GATT Client Callbacks. */ -static gattc_prf_cbs_t lls_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - lls_c_att_read_cb, - lls_c_att_write_cb, - NULL, - lls_c_srvc_browse_cb, - NULL, -}; - -/**@brief Link Loss Service Client Information. */ -static const prf_client_info_t lls_c_prf_info = { - .max_connection_nb = LLS_C_CONNECTION_MAX, - .manager_cbs = &lls_c_mgr_cbs, - .gattc_prf_cbs = &lls_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_LINK_LOSS), HI_U16(BLE_ATT_SVC_LINK_LOSS)}; +static ble_uuid_t s_lls_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -110,55 +81,59 @@ static const prf_client_info_t lls_c_prf_info = { */ void lls_c_evt_handler_excute(lls_c_evt_t *p_evt) { - if (s_lls_c_env.evt_handler != NULL && LLS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_lls_c_env.evt_handler && LLS_C_EVT_INVALID != p_evt->evt_type) + { s_lls_c_env.evt_handler(p_evt); } } /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void lls_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void lls_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { lls_c_evt_t lls_c_evt; lls_c_evt.conn_idx = conn_idx; lls_c_evt.evt_type = LLS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_lls_c_env.handles.lls_alert_level_handle) { + if (p_read_rsp->value[0].handle == s_lls_c_env.handles.lls_alert_level_handle) + { lls_c_evt.evt_type = LLS_C_EVT_ALERT_LEVEL_RECEIVE; - lls_c_evt.alert_level = (lls_c_alert_level_t)p_read_rsp->vals[0].p_value[0]; + lls_c_evt.alert_level = (lls_c_alert_level_t)p_read_rsp->value[0].p_value[0]; lls_c_evt_handler_excute(&lls_c_evt); } } /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void lls_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void lls_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { lls_c_evt_t lls_c_evt; lls_c_evt.conn_idx = conn_idx; lls_c_evt.evt_type = LLS_C_EVT_INVALID; - if (handle == s_lls_c_env.handles.lls_alert_level_handle) { + if (handle == s_lls_c_env.handles.lls_alert_level_handle) + { lls_c_evt.evt_type = (BLE_SUCCESS == status) ?\ LLS_C_EVT_ALERT_LEVEL_SET_SUCCESS :\ LLS_C_EVT_ALERT_LEVEL_SET_ERR; @@ -169,14 +144,14 @@ static void lls_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle /** ***************************************************************************************** - * @brief This callback function will be called when receiving browse service indication. + * @brief This event handler function will be called when receiving browse service indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void lls_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void lls_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { lls_c_evt_t lls_c_evt; uint16_t uuid_disc; @@ -185,94 +160,105 @@ static void lls_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat lls_c_evt.conn_idx = conn_idx; lls_c_evt.evt_type = LLS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_LINK_LOSS == uuid_disc) { - s_lls_c_env.handles.lls_srvc_start_handle = p_browse_srvc->start_hdl; - s_lls_c_env.handles.lls_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_LINK_LOSS == uuid_disc) + { + s_lls_c_env.handles.lls_srvc_start_handle = p_browse_srvc->start_hdl; + s_lls_c_env.handles.lls_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_ALERT_LEVEL == uuid_disc) { - s_lls_c_env.handles.lls_alert_level_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_ALERT_LEVEL == uuid_disc) + { + s_lls_c_env.handles.lls_alert_level_handle = handle_disc; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; } - } - lls_c_evt.evt_type = LLS_C_EVT_DISCOVERY_COMPLETE; + lls_c_evt.evt_type = LLS_C_EVT_DISCOVERY_COMPLETE; + } } lls_c_evt_handler_excute(&lls_c_evt); } +static void lls_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_WRITE_RSP: + lls_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_READ_RSP: + lls_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_SRVC_BROWSE: + lls_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + } +} /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t lls_client_init(lls_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_lls_c_env, sizeof(s_lls_c_env), 0, sizeof(s_lls_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_lls_c_env, 0, sizeof(s_lls_c_env)); s_lls_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&lls_c_prf_info, &s_lls_c_env.prf_id); + return ble_gattc_prf_add(&s_lls_service_uuid, lls_c_ble_evt_handler); } sdk_err_t lls_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - - target_uuid[0] = LO_U16(BLE_ATT_SVC_LINK_LOSS); - target_uuid[1] = HI_U16(BLE_ATT_SVC_LINK_LOSS); - - const ble_uuid_t lls_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_lls_c_env.prf_id, conn_idx, &lls_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_lls_service_uuid); } sdk_err_t lls_c_alert_level_set(uint8_t conn_idx, lls_c_alert_level_t alert_level) { - gattc_write_attr_value_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_lls_c_env.handles.lls_alert_level_handle) { + if (BLE_ATT_INVALID_HDL == s_lls_c_env.handles.lls_alert_level_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_lls_c_env.handles.lls_alert_level_handle; - write_attr_value.offset = 0; - write_attr_value.length = sizeof(uint8_t); - write_attr_value.p_value = (uint8_t *)&alert_level; - - return ble_gattc_prf_write(s_lls_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_lls_c_env.handles.lls_alert_level_handle, 0, sizeof(uint8_t), (uint8_t *)&alert_level); } sdk_err_t lls_c_alert_level_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_lls_c_env.handles.lls_alert_level_handle) { + if (BLE_ATT_INVALID_HDL == s_lls_c_env.handles.lls_alert_level_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_lls_c_env.prf_id, conn_idx, s_lls_c_env.handles.lls_alert_level_handle, 0); + return ble_gattc_read(conn_idx, s_lls_c_env.handles.lls_alert_level_handle, 0); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.h index eaa789b..5e9c1ca 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lls_c/lls_c.h @@ -56,18 +56,17 @@ #ifndef __LLS_C_H__ #define __LLS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup LLS_C_MACRO Defines * @{ */ -#define LLS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of LLS Client connections. */ +#define LLS_C_CONNECTION_MAX 10 /**< Maximum number of LLS Client connections. */ /** @} */ /** @@ -75,21 +74,22 @@ * @{ */ /**@brief Link Loss Service Client alert levels. */ -typedef enum { +typedef enum +{ LLS_C_ALERT_LEVEL_NO_ALERT, /**< No alert. */ LLS_C_ALERT_LEVEL_MILD_ALERT, /**< Mild alert. */ LLS_C_ALERT_LEVEL_HIGH_ALERT, /**< High alert. */ } lls_c_alert_level_t; /**@brief Link Loss Service Client event type. */ -typedef enum { - LLS_C_EVT_INVALID, /**< LLS Client invalid event. */ - LLS_C_EVT_DISCOVERY_COMPLETE, /**< LLS Client has found LLS service and its characteristics. */ - LLS_C_EVT_DISCOVERY_FAIL, /**< LLS Client found LLS service failed \ - because of invalid operation or no found at the peer. */ - LLS_C_EVT_ALERT_LEVEL_SET_SUCCESS, /**< LLS Client has set Alert Level characteristics. */ - LLS_C_EVT_ALERT_LEVEL_SET_ERR, /**< Error occured when LLS Client set Alert Level characteristics. */ - LLS_C_EVT_ALERT_LEVEL_RECEIVE, /**< LLS Client has received Alert Level value. */ +typedef enum +{ + LLS_C_EVT_INVALID, /**< LLS Client invalid event. */ + LLS_C_EVT_DISCOVERY_COMPLETE, /**< LLS Client has found LLS service and its characteristics. */ + LLS_C_EVT_DISCOVERY_FAIL, /**< LLS Client found LLS service failed because of invalid operation or no found at the peer. */ + LLS_C_EVT_ALERT_LEVEL_SET_SUCCESS, /**< LLS Client has set Alert Level characteristics. */ + LLS_C_EVT_ALERT_LEVEL_SET_ERR, /**< Error occured when LLS Client set Alert Level characteristics. */ + LLS_C_EVT_ALERT_LEVEL_RECEIVE, /**< LLS Client has received Alert Level value. */ } lls_c_evt_type_t; /** @} */ @@ -98,15 +98,16 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t lls_srvc_start_handle; /**< LLS Service start handle. */ uint16_t lls_srvc_end_handle; /**< LLS Service end handle. */ - uint16_t lls_alert_level_handle; /**< LLS Alert Level characteristic Value handle \ - which has been got from peer. */ + uint16_t lls_alert_level_handle; /**< LLS Alert Level characteristic Value handle which has been got from peer. */ } lls_c_handles_t; /**@brief Link Loss Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ lls_c_evt_type_t evt_type; /**< LLS Client event type. */ lls_c_alert_level_t alert_level; /**< Alert level. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/BUILD.gn new file mode 100644 index 0000000..fcff582 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("lms") { + sources = [ "lms.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.c new file mode 100644 index 0000000..db9dbf0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.c @@ -0,0 +1,440 @@ +/** + **************************************************************************************** + * + * @file lms.c + * + * @brief Log Management Service Implementation. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + /* + * INCLUDE FILES + **************************************************************************************** + */ +#include "lms.h" +#include "ble_prf_types.h" +#include "ble_prf_utils.h" +#include "utility.h" + +/* + * DEFINES + **************************************************************************************** + */ +/**@brief Proprietary UUIDs. */ +#define LMS_SERVICE_CMD_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x0B, 0xED, 0xA6} +#define LMS_SERVICE_DATA_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x0B, 0xED, 0xA6} + +/**@brief Macros for conversion of 128bit to 16bit UUID. */ +#define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) +#define ATT_128_CHARACTERISTIC BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_CHARACTERISTIC) +#define ATT_128_CLIENT_CHAR_CFG BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DESC_CLIENT_CHAR_CFG) + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/**@brief LMS Service Attributes Indexes. */ +enum lms_attr_idx_tag +{ + LMS_IDX_SVC, + + LMS_IDX_CMD_CHAR, + LMS_IDX_CMD_VAL, + LMS_IDX_CMD_CFG, + LMS_IDX_DATA_CHAR, + LMS_IDX_DATA_VAL, + LMS_IDX_DATA_CFG, + + LMS_IDX_NB, +}; + +/* + * STRUCT DEFINE + **************************************************************************************** + */ +struct lms_env_t +{ + lms_init_t lms_init; + uint16_t cmd_ntf_cfg[LMS_CONNECTION_MAX]; + uint16_t data_ntf_cfg[LMS_CONNECTION_MAX]; + uint16_t start_hdl; + ble_gatts_create_db_t lms_att_db; +}; + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +static struct lms_env_t s_lms_env; +static uint16_t s_char_mask = 0xff; +static const uint8_t s_ths_svc_uuid[] = {LMS_SERVICE_UUID}; + +/**@brief Full LMS Database Description - Used to add attributes into the database. */ +static const ble_gatts_attm_desc_128_t lms_att_db[LMS_IDX_NB] = { + // LMS service + [LMS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + + // LMS TX Characteristic Declaration + [LMS_IDX_CMD_CHAR] = {ATT_128_CHARACTERISTIC,BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + // LMS TX Characteristic Value + [LMS_IDX_CMD_VAL] = {LMS_SERVICE_CMD_UUID, + BLE_GATTS_WRITE_CMD_PERM_UNSEC | BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + LMS_MAX_DATA_LEN}, + + // LMS TX Characteristic - Client Characteristic Configuration Descriptor + [LMS_IDX_CMD_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC| BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, + + // LMS RX Characteristic Declaration + [LMS_IDX_DATA_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0 }, + + // LMS RX Characteristic Value + [LMS_IDX_DATA_VAL] = {LMS_SERVICE_DATA_UUID, + BLE_GATTS_WRITE_CMD_PERM_UNSEC | BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + LMS_MAX_DATA_LEN}, + [LMS_IDX_DATA_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC| BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, +}; + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + ***************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] conn_idx: Connection index + * @param[in] p_param: The parameters of the read request. + ***************************************************************************************** + */ +static void lms_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) +{ + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; + + tab_index = prf_find_idx_by_handle(handle, s_lms_env.start_hdl, LMS_IDX_NB, (uint8_t*)&s_char_mask); + + cfm.handle = handle; + cfm.status = BLE_SUCCESS; + + switch(tab_index) + { + case LMS_IDX_CMD_CFG: + cfm.length = sizeof(uint16_t); + cfm.value = (uint8_t *)(&s_lms_env.cmd_ntf_cfg[conn_idx]); + break; + case LMS_IDX_DATA_CFG: + cfm.length = sizeof(uint16_t); + cfm.value = (uint8_t *)(&s_lms_env.data_ntf_cfg[conn_idx]); + break; + + default: + cfm.length = 0; + cfm.status = BLE_ATT_ERR_INVALID_HANDLE; + break; + } + + ble_gatts_read_cfm(conn_idx,&cfm); +} + +/** + ***************************************************************************************** + * @brief Handles reception of the write request. + * + * @param[in] conn_idx: of connection index + * @param[in] p_param: Pointer to the parameters of the write request. + ***************************************************************************************** + */ +static void lms_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) +{ + ble_gatts_write_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; + uint16_t cccd_value = 0; + lms_evt_t event; + + tab_index = prf_find_idx_by_handle(handle, s_lms_env.start_hdl, LMS_IDX_NB, (uint8_t*)&s_char_mask); + + cfm.handle = handle; + cfm.status = BLE_SUCCESS; + + switch(tab_index) + { + + case LMS_IDX_CMD_VAL: + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = LMS_EVT_CMD_RECEIVE_DATA; + event.p_data = (uint8_t*)p_param->value; + event.length = p_param->length; + + s_lms_env.lms_init.evt_handler(&event); + } + + break; + + case LMS_IDX_CMD_CFG: + cccd_value = le16toh(&p_param->value[0]); + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ + LMS_EVT_CMD_NOTIFICATION_ENABLED : + LMS_EVT_CMD_NOTIFICATION_DISABLED; + s_lms_env.lms_init.evt_handler(&event); + } + s_lms_env.cmd_ntf_cfg[conn_idx] = cccd_value; + break; + + case LMS_IDX_DATA_VAL: + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = LMS_EVT_DATA_RECEIVE_DATA; + event.p_data = (uint8_t*)p_param->value; + event.length = p_param->length; + + s_lms_env.lms_init.evt_handler(&event); + } + break; + + case LMS_IDX_DATA_CFG: + cccd_value = le16toh(&p_param->value[0]); + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ + LMS_EVT_DATA_NOTIFICATION_ENABLED : + LMS_EVT_DATA_NOTIFICATION_DISABLED; + s_lms_env.lms_init.evt_handler(&event); + } + s_lms_env.data_ntf_cfg[conn_idx] = cccd_value; + + break; + + + + default: + cfm.status = BLE_ATT_ERR_INVALID_HANDLE; + break; + } + + ble_gatts_write_cfm(conn_idx,&cfm); +} + +/** + ***************************************************************************************** + * @brief Handles reception of the cccd recover request. + * + * @param[in]: conn_idx: Connection index + * @param[in]: handle: The handle of cccd attribute. + * @param[in]: cccd_value: The value of cccd attribute. + ***************************************************************************************** + */ +static void lms_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +{ + uint8_t tab_index = 0; + lms_evt_t event; + + if (!prf_is_cccd_value_valid(cccd_value)) + { + return; + } + + tab_index = prf_find_idx_by_handle(handle, s_lms_env.start_hdl, LMS_IDX_NB, (uint8_t*)&s_char_mask); + + switch(tab_index) + { + case LMS_IDX_CMD_CFG: + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ + LMS_EVT_CMD_NOTIFICATION_ENABLED : + LMS_EVT_CMD_NOTIFICATION_DISABLED; + s_lms_env.lms_init.evt_handler(&event); + } + s_lms_env.cmd_ntf_cfg[conn_idx] = cccd_value; + break; + + case LMS_IDX_DATA_CFG: + if(s_lms_env.lms_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ + LMS_EVT_DATA_NOTIFICATION_ENABLED : + LMS_EVT_DATA_NOTIFICATION_DISABLED; + s_lms_env.lms_init.evt_handler(&event); + } + s_lms_env.data_ntf_cfg[conn_idx] = cccd_value; + break; + + default: + break; + } +} + +/** + ***************************************************************************************** + * @brief Handles reception of the complete event. + * + * @param[in] conn_idx: Connection index + * @param[in] p_param: Pointer to the parameters of the complete event. + * + * @return If the event was consumed or not. + ***************************************************************************************** + */ +static void lms_ntf_cplt_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) +{ + if(s_lms_env.lms_init.evt_handler != NULL) + { + lms_evt_t event; + uint8_t tab_index = 0; + uint8_t handle = p_ntf_ind->handle; + + event.conn_idx = conn_idx; + tab_index = prf_find_idx_by_handle(handle, s_lms_env.start_hdl, LMS_IDX_NB, (uint8_t*)&s_char_mask); + if(status == BLE_SUCCESS) + { + if(p_ntf_ind->type == BLE_GATT_NOTIFICATION && LMS_IDX_CMD_VAL == tab_index) + { + event.evt_type = LMS_EVT_CMD_NOTIFY_COMPLETE; + s_lms_env.lms_init.evt_handler(&event); + } + else if (p_ntf_ind->type == BLE_GATT_NOTIFICATION && LMS_IDX_DATA_VAL == tab_index) + { + event.evt_type = LMS_EVT_DATA_NOTIFY_COMPLETE; + s_lms_env.lms_init.evt_handler(&event); + } + } + } + } + +static void lms_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + lms_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + lms_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + lms_ntf_cplt_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + lms_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +sdk_err_t lms_notify_cmd(uint8_t conn_idx,uint8_t* p_data,uint16_t len) +{ + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t send_cmd; + + if(s_lms_env.cmd_ntf_cfg[conn_idx] == PRF_CLI_START_NTF) + { + // Fill in the parameter structure + send_cmd.type = BLE_GATT_NOTIFICATION; + send_cmd.handle = prf_find_handle_by_idx(LMS_IDX_CMD_VAL, s_lms_env.start_hdl, (uint8_t*)&s_char_mask); + // pack measured value in database + send_cmd.length = len; + send_cmd.value = p_data; + // send notification to peer device + error_code = ble_gatts_noti_ind(conn_idx,&send_cmd); + } + return error_code; +} +sdk_err_t lms_notify_data(uint8_t conn_idx,uint8_t* p_data,uint16_t len) +{ + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t send_cmd; + + if(s_lms_env.data_ntf_cfg[conn_idx] == PRF_CLI_START_NTF) + { + // Fill in the parameter structure + send_cmd.type = BLE_GATT_NOTIFICATION; + send_cmd.handle = prf_find_handle_by_idx(LMS_IDX_DATA_VAL, s_lms_env.start_hdl, (uint8_t*)&s_char_mask); + // pack measured value in database + send_cmd.length = len; + send_cmd.value = p_data; + + error_code = ble_gatts_noti_ind(conn_idx,&send_cmd); + } + return error_code; +} + + +sdk_err_t lms_service_init(lms_init_t *p_lms_init) +{ + if (NULL == p_lms_init) + { + return SDK_ERR_POINTER_NULL; + } + + s_lms_env.lms_init.evt_handler = p_lms_init->evt_handler; + + memset(&s_lms_env.lms_att_db, 0, sizeof(ble_gatts_create_db_t)); + + s_lms_env.start_hdl = PRF_INVALID_HANDLE; + s_lms_env.lms_att_db.shdl = &s_lms_env.start_hdl; + s_lms_env.lms_att_db.uuid = s_ths_svc_uuid; + s_lms_env.lms_att_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_lms_env.lms_att_db.max_nb_attr = LMS_IDX_NB; + s_lms_env.lms_att_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_lms_env.lms_att_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_lms_env.lms_att_db.attr_tab.attr_tab_128 = lms_att_db; + + return ble_gatts_prf_add(&s_lms_env.lms_att_db, lms_ble_evt_handler); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.h new file mode 100644 index 0000000..b79a525 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lms/lms.h @@ -0,0 +1,179 @@ +/** + **************************************************************************************** + * + * @file lms.h + * + * @brief Log Management Service API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/** + * @addtogroup BLE_SRV BLE Services + * @{ + * @brief Definitions and prototypes for the BLE Service interface. + */ + +/** + * @defgroup BLE_SDK_LMS LMS Service (LMS) + * @{ + * @brief Definitions and prototypes for the LMS interface. + * + * @details The Log Management Service is a customized service with Command and Data + * characteristics. This module implements the log storage and sending function. + * After @ref lms_init_t variable is initialized, the developer shall call + * @ref lms_service_init() to add the LMS Service and RX, TX, Control characteristic + * to the BLE stack database. + * + * This module also provides \ref lms_notify_data() function to the application + * to send data to peer. + */ + +#ifndef _LMS_H_ +#define _LMS_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "gr_includes.h" + +/** + * @defgroup LMS_MACRO Defines + * @{ + */ +#define LMS_CONNECTION_MAX 10 /**< Maximum number of LMS Service connections. */ +#define LMS_MAX_DATA_LEN 244 /**< Maximum length of LMS characteristic. */ +#define LMS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x0B, 0xED, 0xA6 /**< The UUID of LMS Service for setting advertising data. */ + +#define LMS_PATTERN_VALUE 0x474f4f44 /**< The Fast OTA pattern value. */ +/** @} */ + +/** + * @defgroup LMS_ENUM Enumerations + * @{ + */ +/**@brief LMS Service event type. */ +typedef enum +{ + LMS_EVT_INVALID, + LMS_EVT_CMD_NOTIFICATION_ENABLED, + LMS_EVT_CMD_NOTIFICATION_DISABLED, + LMS_EVT_CMD_RECEIVE_DATA, + LMS_EVT_CMD_NOTIFY_COMPLETE, + LMS_EVT_DATA_NOTIFICATION_ENABLED, + LMS_EVT_DATA_NOTIFICATION_DISABLED, + LMS_EVT_DATA_RECEIVE_DATA, + LMS_EVT_DATA_NOTIFY_COMPLETE +} lms_evt_type_t; +/** @} */ + +/** + * @defgroup LMS_STRUCT Structures + * @{ + */ +/**@brief LMS Service event. */ +typedef struct +{ + lms_evt_type_t evt_type; /**< The LMS event. */ + uint8_t conn_idx; /**< Index of connection. */ + uint8_t *p_data; /**< Pointer to data. */ + uint16_t length; /**< Length of data. */ +} lms_evt_t; +/** @} */ + +/** + * @defgroup LMS_TYPEDEF Typedefs + * @{ + */ +/**@brief LMS Service event handler type. */ +typedef void (*lms_evt_handler_t)(lms_evt_t *p_evt); + +/** @} */ + +/** + * @defgroup LMS_STRUCT Structures + * @{ + */ +/**@brief LMS Service initialization variable. */ +typedef struct +{ + lms_evt_handler_t evt_handler; /**< Handler to handle lms event. */ +} lms_init_t; +/** @} */ + + +/** + * @defgroup LMS_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Add an LMS Service instance in the DB + * + * @param[in] p_lms_init :Pointer to LMS Service environment variable + * + * @return Result of service initialization. + ***************************************************************************************** + */ +sdk_err_t lms_service_init(lms_init_t *p_lms_init); + + +/** + ***************************************************************************************** + * @brief Send data to peer device + * + * @param[in] conn_idx: Connection index + * @param[in] p_data: The Pointer of send value + * @param[in] length: The Lenth of send value + * + * @return Result of notify and indicate value + ***************************************************************************************** + */ +sdk_err_t lms_notify_cmd(uint8_t conn_idx, uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Send data to peer device + * + * @param[in] conn_idx: Connection index + * @param[in] p_data: The Pointer of send value + * @param[in] length: The Lenth of send value + * + * @return Result of notify and indicate value + ***************************************************************************************** + */ +sdk_err_t lms_notify_data(uint8_t conn_idx, uint8_t *p_data,uint16_t length); +/** @} */ + +#endif +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/BUILD.gn new file mode 100644 index 0000000..d406d5d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("lns") { + sources = [ "lns.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.c index c0d0129..d8cd395 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.c @@ -39,20 +39,20 @@ * INCLUDE FILES **************************************************************************************** */ -#include +#include "lns.h" #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#include "lns.h" +#include /* * DEFINES ***************************************************************************************** */ #define LNS_DEFAULT_GATT_PAYLOAD 20 -#define LNS_LOG_INFO_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define LNS_LOG_INFO_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x08, 0xED, 0xA6} -#define LNS_LOG_CTRL_PT_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ +#define LNS_LOG_CTRL_PT_CHARACTERISTIC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x08, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ @@ -65,7 +65,8 @@ **************************************************************************************** */ /**@brief Log Notification Service Attributes Indexes. */ -enum { +enum +{ // Log Notification Service LNS_IDX_SVC, @@ -87,27 +88,20 @@ enum { ***************************************************************************************** */ /**@brief Log Notification Service environment variable. */ -struct lns_env_t { - lns_evt_handler_t evt_handler; /**< Log Notification Service event handler. */ - uint16_t start_hdl; /**< Log Notification Service start handle. */ - uint16_t payload_len; /**< Length of gatt payload. */ - uint16_t - log_info_ntf_cfg[LNS_CONNECTION_MAX]; /**< The configuration of Log Information Notification \ - which is configured by the peer devices. */ - uint16_t - log_ctrl_pt_ind_cfg[LNS_CONNECTION_MAX]; /**< The configuration of Log Control Point indication \ - which is configured by the peer devices. */ +struct lns_env_t +{ + lns_evt_handler_t evt_handler; /**< Log Notification Service event handler. */ + uint16_t start_hdl; /**< Log Notification Service start handle. */ + uint16_t payload_len; /**< Length of gatt payload. */ + uint16_t log_info_ntf_cfg[LNS_CONNECTION_MAX]; /**< The configuration of Log Information Notification which is configured by the peer devices. */ + uint16_t log_ctrl_pt_ind_cfg[LNS_CONNECTION_MAX]; /**< The configuration of Log Control Point indication which is configured by the peer devices. */ + ble_gatts_create_db_t lns_gatts_db; /**< Log Notification Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t lns_init(void); -static void lns_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void lns_gatts_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); -static void lns_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); static sdk_err_t lns_log_info_chunk(uint8_t conn_idx); static void lns_evt_handler(lns_evt_t *p_evt); @@ -117,101 +111,40 @@ static void lns_evt_handler(lns_evt_t *p_evt); */ static struct lns_env_t s_lns_env; static lns_log_data_t s_log_data_ntf; -static uint16_t s_lns_char_mask = 0x007f; +static uint16_t s_lns_char_mask = 0x007f; +static const uint8_t s_lns_svc_uuid[] = {LNS_SERVICE_UUID}; /**@brief Full LNS Database Description - Used to add attributes into the database. */ -static const attm_desc_128_t lns_attr_tab[LNS_IDX_NB] = { +static const ble_gatts_attm_desc_128_t lns_attr_tab[LNS_IDX_NB] = +{ // Log Notification Service Declaration - [LNS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [LNS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Log Information Characteristic - Declaration - [LNS_IDX_LOG_INFO_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [LNS_IDX_LOG_INFO_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Log Information Characteristic - Value - [LNS_IDX_LOG_INFO_VAL] = { - LNS_LOG_INFO_CHARACTERISTIC_UUID, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - LNS_LOG_INFO_VAL_LEN - }, + [LNS_IDX_LOG_INFO_VAL] = {LNS_LOG_INFO_CHARACTERISTIC_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + LNS_LOG_INFO_VAL_LEN}, // Log Information Characteristic - Client Characteristic Configuration Descriptor - [LNS_IDX_LOG_INFO_NTF_CFG] = {ATT_128_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [LNS_IDX_LOG_INFO_NTF_CFG] = {ATT_128_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Log Control Point Characteristic - Declaration - [LNS_IDX_LOG_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [LNS_IDX_LOG_CTRL_PT_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Log Control Point Characteristic - Value - [LNS_IDX_LOG_CTRL_PT_VAL] = { - LNS_LOG_CTRL_PT_CHARACTERISTIC_UUID, - INDICATE_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128), - LNS_LOG_CTRL_PT_VAL_LEN - }, + [LNS_IDX_LOG_CTRL_PT_VAL] = {LNS_LOG_CTRL_PT_CHARACTERISTIC_UUID, + BLE_GATTS_INDICATE_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128), + LNS_LOG_CTRL_PT_VAL_LEN}, // Log Control Point Characteristic - Client Characteristic Configuration Descriptor - [LNS_IDX_LOG_CTRL_PT_IND_CFG] = {ATT_128_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, -}; - -/**@brief LNS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t lns_task_cbs = { - (prf_init_func_t) lns_init, - NULL, - NULL, -}; - -/**@brief LNS Task Callbacks. */ -static gatts_prf_cbs_t lns_cb_func = { - lns_read_att_cb, - lns_write_att_cb, - NULL, - lns_gatts_cplt_cb, - lns_cccd_set_cb -}; - -/**@brief LNS Information. */ -static const prf_server_info_t lns_prf_info = { - .max_connection_nb = LNS_CONNECTION_MAX, - .manager_cbs = &lns_task_cbs, - .gatts_prf_cbs = &lns_cb_func, + [LNS_IDX_LOG_CTRL_PT_IND_CFG] = {ATT_128_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Log Notification Service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t lns_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t lns_svc_uuid[] = {LNS_SERVICE_UUID}; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = lns_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_lns_char_mask; - gatts_db.max_nb_attr = LNS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = lns_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_lns_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -220,18 +153,19 @@ static sdk_err_t lns_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void lns_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void lns_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, - s_lns_env.start_hdl, - LNS_IDX_NB, - (uint8_t *)&s_lns_char_mask); + s_lns_env.start_hdl, + LNS_IDX_NB, + (uint8_t *)&s_lns_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case LNS_IDX_LOG_INFO_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_lns_env.log_info_ntf_cfg[conn_idx]; @@ -259,13 +193,13 @@ static void lns_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void lns_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; lns_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_lns_env.start_hdl, @@ -276,7 +210,8 @@ static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par event.evt_type = LNS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case LNS_IDX_LOG_INFO_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ @@ -293,8 +228,10 @@ static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par s_lns_env.log_ctrl_pt_ind_cfg[conn_idx] = cccd_value; break; - case LNS_IDX_LOG_CTRL_PT_VAL: { - switch (p_param->value[0]) { + case LNS_IDX_LOG_CTRL_PT_VAL: + { + switch (p_param->value[0]) + { case LNS_CTRL_PT_TRACE_STATUS_GET: event.evt_type = LNS_EVT_TRACE_STATUS_GET; break; @@ -311,7 +248,7 @@ static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par break; } } - break; + break; default: cfm.status = BLE_ATT_ERR_INVALID_HANDLE; @@ -320,7 +257,8 @@ static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && LNS_EVT_INVALID != event.evt_type) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && LNS_EVT_INVALID != event.evt_type) + { lns_evt_handler(&event); } } @@ -334,12 +272,13 @@ static void lns_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void lns_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void lns_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; lns_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -351,7 +290,8 @@ static void lns_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = LNS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case LNS_IDX_LOG_INFO_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ LNS_EVT_LOG_INFO_NTF_ENABLE : \ @@ -370,7 +310,8 @@ static void lns_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (LNS_EVT_INVALID != event.evt_type && s_lns_env.evt_handler) { + if (LNS_EVT_INVALID != event.evt_type && s_lns_env.evt_handler) + { s_lns_env.evt_handler(&event); } } @@ -383,7 +324,7 @@ static void lns_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_param: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void lns_gatts_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void lns_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { uint8_t tab_index; @@ -391,10 +332,15 @@ static void lns_gatts_cplt_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ s_lns_env.start_hdl, LNS_IDX_NB, (uint8_t *)&s_lns_char_mask); - if (LNS_IDX_LOG_INFO_VAL == tab_index) { - if (BLE_SUCCESS == status) { + + if (LNS_IDX_LOG_INFO_VAL == tab_index) + { + if (BLE_SUCCESS == status) + { lns_log_info_chunk(conn_idx); - } else { + } + else + { s_log_data_ntf.length = 0; s_log_data_ntf.offset = 0; @@ -414,7 +360,8 @@ static void lns_evt_handler(lns_evt_t *p_evt) { uint8_t trace_log_num = 0; - switch (p_evt->evt_type) { + switch (p_evt->evt_type) + { case LNS_EVT_TRACE_STATUS_GET: trace_log_num = fault_db_records_num_get(); lns_log_status_send(p_evt->conn_idx, trace_log_num); @@ -427,11 +374,10 @@ static void lns_evt_handler(lns_evt_t *p_evt) case LNS_EVT_TRACE_INFO_CLEAR: fault_db_record_clear(); break; - default : - break; } - if (LNS_EVT_INVALID != p_evt->evt_type && s_lns_env.evt_handler) { + if (LNS_EVT_INVALID != p_evt->evt_type && s_lns_env.evt_handler) + { s_lns_env.evt_handler(p_evt); } } @@ -449,12 +395,13 @@ static sdk_err_t lns_log_info_chunk(uint8_t conn_idx) { uint16_t chunk_len = 0; sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t data_ntf; + ble_gatts_noti_ind_t data_ntf; chunk_len = s_log_data_ntf.length - s_log_data_ntf.offset; chunk_len = chunk_len > s_lns_env.payload_len ? s_lns_env.payload_len : chunk_len; - if (chunk_len == 0) { + if (0 == chunk_len) + { s_log_data_ntf.length = 0; s_log_data_ntf.offset = 0; @@ -463,7 +410,8 @@ static sdk_err_t lns_log_info_chunk(uint8_t conn_idx) return SDK_SUCCESS; } - if (PRF_CLI_START_NTF == s_lns_env.log_info_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_lns_env.log_info_ntf_cfg[conn_idx]) + { data_ntf.type = BLE_GATT_NOTIFICATION; data_ntf.handle = prf_find_handle_by_idx(LNS_IDX_LOG_INFO_VAL, s_lns_env.start_hdl, @@ -474,13 +422,41 @@ static sdk_err_t lns_log_info_chunk(uint8_t conn_idx) error_code = ble_gatts_noti_ind(conn_idx, &data_ntf); } - if (SDK_SUCCESS == error_code) { + if (SDK_SUCCESS == error_code) + { s_log_data_ntf.offset += chunk_len; } return error_code; } +static void lns_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + lns_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + lns_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + lns_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + lns_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -489,8 +465,17 @@ sdk_err_t lns_service_init(lns_evt_handler_t evt_handler) { s_lns_env.evt_handler = evt_handler; s_lns_env.payload_len = LNS_DEFAULT_GATT_PAYLOAD; + s_lns_env.start_hdl = PRF_INVALID_HANDLE; - return ble_server_prf_add(&lns_prf_info); + s_lns_env.lns_gatts_db.shdl = &s_lns_env.start_hdl; + s_lns_env.lns_gatts_db.uuid = s_lns_svc_uuid; + s_lns_env.lns_gatts_db.attr_tab_cfg = (uint8_t *)&s_lns_char_mask; + s_lns_env.lns_gatts_db.max_nb_attr = LNS_IDX_NB; + s_lns_env.lns_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_lns_env.lns_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_lns_env.lns_gatts_db.attr_tab.attr_tab_128 = lns_attr_tab; + + return ble_gatts_prf_add(&s_lns_env.lns_gatts_db, lns_ble_evt_handler); } sdk_err_t lns_log_info_send(uint8_t conn_idx) @@ -499,9 +484,12 @@ sdk_err_t lns_log_info_send(uint8_t conn_idx) s_log_data_ntf.length = fault_db_records_total_len_get(); s_log_data_ntf.p_data = sys_malloc(s_log_data_ntf.length); - if (s_log_data_ntf.p_data) { + if (s_log_data_ntf.p_data) + { fault_db_records_dump(s_log_data_ntf.p_data, &s_log_data_ntf.length); - } else { + } + else + { return SDK_ERR_NO_RESOURCES; } @@ -511,13 +499,14 @@ sdk_err_t lns_log_info_send(uint8_t conn_idx) sdk_err_t lns_log_status_send(uint8_t conn_idx, const uint8_t log_num) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t status_ind; + ble_gatts_noti_ind_t status_ind; - if (PRF_CLI_START_IND == s_lns_env.log_ctrl_pt_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_lns_env.log_ctrl_pt_ind_cfg[conn_idx]) + { status_ind.type = BLE_GATT_INDICATION; status_ind.handle = prf_find_handle_by_idx(LNS_IDX_LOG_CTRL_PT_VAL, - s_lns_env.start_hdl, - (uint8_t *)&s_lns_char_mask); + s_lns_env.start_hdl, + (uint8_t *)&s_lns_char_mask); status_ind.length = LNS_LOG_CTRL_PT_VAL_LEN; status_ind.value = (uint8_t *)&log_num; @@ -529,9 +518,12 @@ sdk_err_t lns_log_status_send(uint8_t conn_idx, const uint8_t log_num) sdk_err_t lns_pay_load_update(uint8_t conn_idx, const uint16_t payload_len) { - if (s_lns_env.payload_len > LNS_LOG_INFO_VAL_LEN) { + if (s_lns_env.payload_len > LNS_LOG_INFO_VAL_LEN) + { s_lns_env.payload_len = LNS_LOG_INFO_VAL_LEN; - } else { + } + else + { s_lns_env.payload_len = payload_len; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.h index 2c845e8..bc24cc5 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/lns/lns.h @@ -45,35 +45,30 @@ * @{ * @brief Log Notification Service module. * - * @details The Log Notification Service shall expose the Log Info characteristic and - * the Log Control Point characteristic. + * @details The Log Notification Service shall expose the Log Info characteristic and the Log Control Point characteristic. * - * After \ref lns_init_t variable is intialized, the application - * must call \ref lns_service_init() to add Log Notification Service and - * Log Info and Log Control Point characteristics to the BLE Stack database. + * The application must call \ref lns_service_init() to add Log Notification Service and Log Info + * and Log Control Point characteristics to the BLE Stack database. */ #ifndef __LNS_H__ #define __LNS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "fault_trace.h" +#include +#include /** * @defgroup LNS_MACRO Defines * @{ */ -#define LNS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Log Notification \ - Service connections. */ -#define LNS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x01, 0x08, 0xED, 0xA6 /**< The UUID of Log Notification Service for \ - setting advertising data. */ -#define LNS_LOG_INFO_VAL_LEN 244 /**< Length of Log Information value. */ -#define LNS_LOG_CTRL_PT_VAL_LEN 1 /**< Length of Log Control Point value. */ +#define LNS_CONNECTION_MAX 10 /**< Maximum number of Log Notification Service connections. */ +#define LNS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x08, 0xED, 0xA6 /**< The UUID of Log Notification Service for setting advertising data. */ +#define LNS_LOG_INFO_VAL_LEN 244 /**< Length of Log Information value. */ +#define LNS_LOG_CTRL_PT_VAL_LEN 1 /**< Length of Log Control Point value. */ /** @} */ /** @@ -81,14 +76,16 @@ * @{ */ /**@brief Log Notification Service Control Point. */ -typedef enum { +typedef enum +{ LNS_CTRL_PT_TRACE_STATUS_GET = 0x01, /**< Get trace info status. */ LNS_CTRL_PT_TRACE_INFO_DUMP, /**< Dump saved trace info. */ LNS_CTRL_PT_TRACE_INFO_CLEAR, /**< Clear trace information. */ } lns_ctrl_pt_t; /**@brief Log Notification Service event type. */ -typedef enum { +typedef enum +{ LNS_EVT_INVALID, /**< Invalid lns event type. */ LNS_EVT_LOG_INFO_NTF_ENABLE, /**< Trace Information notification is enabled. */ LNS_EVT_LOG_INFO_NTF_DISABLE, /**< Trace Information notification is disabled. */ @@ -105,13 +102,15 @@ typedef enum { * @{ */ /**@brief Log Notification Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ lns_evt_type_t evt_type; /**< The lns event type. */ } lns_evt_t; /**@brief Log Information data. */ -typedef struct { +typedef struct +{ uint8_t *p_data; /**< Pointer to data. */ uint32_t length; /**< Length of data. */ uint32_t offset; /**< Offset of data. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/BUILD.gn new file mode 100644 index 0000000..3c2e5fe --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("mlmr") { + sources = [ "mlmr.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.c index 43cea0e..cb1c98d 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.c @@ -3,7 +3,7 @@ * * @file mlmr.c * - * @brief Goodix UART Service Implementation. + * @brief MLMR Service Implementation. * ***************************************************************************************** * @attention @@ -45,19 +45,15 @@ #include "utility.h" #include "user_app.h" #include "app_log.h" -#define MTU_DEF_OFFSET 3 -#define DATA_COPY_LEN 2 + /* * DEFINES ***************************************************************************************** */ -/**@brief The UUIDs of GUS characteristics. */ -#define GUS_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, - 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} -#define GUS_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, - 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} -#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, - 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} +/**@brief The UUIDs of MLMR characteristics. */ +#define MLMR_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} +#define MLMR_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} +#define MLMR_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -68,172 +64,97 @@ * ENUMERATIONS ***************************************************************************************** */ -/**@brief Goodix UART Service Attributes Indexes. */ -enum gus_attr_idx_t { - GUS_IDX_SVC, +/**@brief Multi Link Multi Role Service Attributes Indexes. */ +enum mlmr_attr_idx_t +{ + MLMR_IDX_SVC, + + MLMR_IDX_TX_CHAR, + MLMR_IDX_TX_VAL, + MLMR_IDX_TX_CFG, - GUS_IDX_TX_CHAR, - GUS_IDX_TX_VAL, - GUS_IDX_TX_CFG, + MLMR_IDX_RX_CHAR, + MLMR_IDX_RX_VAL, - GUS_IDX_RX_CHAR, - GUS_IDX_RX_VAL, + MLMR_IDX_FLOW_CTRL_CHAR, + MLMR_IDX_FLOW_CTRL_VAL, + MLMR_IDX_FLOW_CTRL_CFG, - GUS_IDX_FLOW_CTRL_CHAR, - GUS_IDX_FLOW_CTRL_VAL, - GUS_IDX_FLOW_CTRL_CFG, - - GUS_IDX_NB, + MLMR_IDX_NB, }; /* * STRUCTURES ***************************************************************************************** */ -/**@brief Goodix UART Service environment variable. */ -struct gus_env_t { - gus_init_t gus_init; /**< Goodix UART Service initialization variables. */ +/**@brief Multi Link Multi Role Service environment variable. */ +struct mlmr_env_t +{ + mlmr_init_t mlmr_init; /**< Multi Link Multi Role Service initialization variables. */ uint16_t start_hdl; /**< Start handle of services */ - uint16_t tx_ntf_cfg[GUS_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of - the peers. */ - uint16_t - flow_ctrl_ntf_cfg[GUS_CONNECTION_MAX]; /**< Flow Control Characteristic Notification configuration of the peers. */ + uint16_t tx_ntf_cfg[MLMR_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of the peers. */ + uint16_t flow_ctrl_ntf_cfg[MLMR_CONNECTION_MAX]; /**< Flow Control Characteristic Notification configuration of the peers. */ + ble_gatts_create_db_t mlmr_gatts_db; /**< Running Speed and Cadence Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t gus_init(void); -static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void gus_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct gus_env_t s_gus_env; +static struct mlmr_env_t s_mlmr_env; static const uint16_t s_char_mask = 0x003F; +static uint8_t s_mlmr_svc_uuid[] = {MLMR_SERVICE_UUID}; static uint16_t received_data_len[CFG_BOND_DEVS]; static uint16_t send_data_len[CFG_BOND_DEVS]; static uint8_t adv_header = 0xA0; static uint8_t rx_buffer[CFG_BOND_DEVS][516]; -/**@brief Full GUS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_128_t gus_att_db[GUS_IDX_NB] = { - // GUS service - [GUS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, +/**@brief Full MLMR Database Description which is used to add attributes into the ATT database. */ +static const ble_gatts_attm_desc_128_t mlmr_attr_tab[MLMR_IDX_NB] = +{ + // MLMR service + [MLMR_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, - // GUS TX Characteristic Declaration - [GUS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // GUS TX Characteristic Value - [GUS_IDX_TX_VAL] = { - GUS_SERVER_TX_UUID, - NOTIFY_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, - // GUS TX Characteristic - Client Characteristic Configuration Descriptor - [GUS_IDX_TX_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + // MLMR TX Characteristic Declaration + [MLMR_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + // MLMR TX Characteristic Value + [MLMR_IDX_TX_VAL] = {MLMR_SERVER_TX_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + MLMR_MAX_DATA_LEN}, + // MLMR TX Characteristic - Client Characteristic Configuration Descriptor + [MLMR_IDX_TX_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, - // GUS RX Characteristic Declaration - [GUS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // GUS RX Characteristic Value - [GUS_IDX_RX_VAL] = { - GUS_SERVER_RX_UUID, - WRITE_REQ_PERM_UNSEC | WRITE_CMD_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, + // MLMR RX Characteristic Declaration + [MLMR_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + // MLMR RX Characteristic Value + [MLMR_IDX_RX_VAL] = {MLMR_SERVER_RX_UUID, + BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_WRITE_CMD_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + MLMR_MAX_DATA_LEN}, - // GUS FLOW_CTRL Characteristic Declaration - [GUS_IDX_FLOW_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, - // GUS FLOW_CTRL Characteristic Value - [GUS_IDX_FLOW_CTRL_VAL] = { - GUS_FLOW_CTRL_UUID, - NOTIFY_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - GUS_MAX_DATA_LEN - }, - // GUS FLOW_CTRL Characteristic - Client Characteristic Configuration Descriptor - [GUS_IDX_FLOW_CTRL_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief GUS Service interface required by profile manager. */ -static ble_prf_manager_cbs_t gus_mgr_cbs = { - (prf_init_func_t)gus_init, - NULL, - NULL, -}; - -/**@brief GUS GATT Server Callbacks. */ -static gatts_prf_cbs_t gus_gatts_cbs = { - gus_read_att_cb, - gus_write_att_cb, - NULL, - gus_ntf_ind_cb, - gus_cccd_set_cb -}; - -/**@brief GUS Server Information. */ -static const prf_server_info_t gus_prf_info = { - .max_connection_nb = GUS_CONNECTION_MAX, - .manager_cbs = &gus_mgr_cbs, - .gatts_prf_cbs = &gus_gatts_cbs + // MLMR FLOW_CTRL Characteristic Declaration + [MLMR_IDX_FLOW_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, + // MLMR FLOW_CTRL Characteristic Value + [MLMR_IDX_FLOW_CTRL_VAL] = {MLMR_FLOW_CTRL_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + MLMR_MAX_DATA_LEN}, + // MLMR FLOW_CTRL Characteristic - Client Characteristic Configuration Descriptor + [MLMR_IDX_FLOW_CTRL_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize GUS and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t gus_init(void) -{ - const uint8_t gus_svc_uuid[] = {GUS_SERVICE_UUID}; - uint16_t start_hdl = PRF_INVALID_HANDLE; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = gus_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; - gatts_db.max_nb_attr = GUS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = gus_att_db; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_gus_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -242,26 +163,27 @@ static sdk_err_t gus_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void mlmr_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint16_t handle = p_param->handle; uint8_t tab_index = 0; - tab_index = prf_find_idx_by_handle(handle, s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); + tab_index = prf_find_idx_by_handle(handle, s_mlmr_env.start_hdl, MLMR_IDX_NB, (uint8_t *)&s_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { - case GUS_IDX_TX_CFG: + switch (tab_index) + { + case MLMR_IDX_TX_CFG: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)&s_gus_env.tx_ntf_cfg[conn_idx]; + cfm.value = (uint8_t *)&s_mlmr_env.tx_ntf_cfg[conn_idx]; cfm.status = BLE_SUCCESS; break; - case GUS_IDX_FLOW_CTRL_CFG: + case MLMR_IDX_FLOW_CTRL_CFG: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)&s_gus_env.flow_ctrl_ntf_cfg[conn_idx]; + cfm.value = (uint8_t *)&s_mlmr_env.flow_ctrl_ntf_cfg[conn_idx]; cfm.status = BLE_SUCCESS; break; @@ -274,18 +196,15 @@ static void gus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param ble_gatts_read_cfm(conn_idx, &cfm); } -void gus_combin_received_packet(uint8_t conn_idx, uint16_t length, uint8_t *p_received_data, uint8_t *p_combin_data) +void mlmr_combin_received_packet(uint8_t conn_idx, uint16_t length, uint8_t *p_received_data, uint8_t *p_combin_data) { uint8_t *buffer = p_combin_data; - uint8_t ret; - if (send_data_len[conn_idx] > received_data_len[conn_idx]) { + if(send_data_len[conn_idx] > received_data_len[conn_idx]) + { buffer += received_data_len[conn_idx]; - ret = memcpy_s(buffer, length, p_received_data, length); - if (ret < 0) { - return; - } - received_data_len[conn_idx] += length; + memcpy(buffer, p_received_data, length); + received_data_len[conn_idx] += length; } } @@ -297,68 +216,74 @@ void gus_combin_received_packet(uint8_t conn_idx, uint16_t length, uint8_t *p_re * @param[in] p_param: Point to the parameters of the write request. ***************************************************************************************** */ -static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void mlmr_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint16_t cccd_value; - gus_evt_t event; - gatts_write_cfm_t cfm; - uint8_t ret; + mlmr_evt_t event; + ble_gatts_write_cfm_t cfm; - tab_index = prf_find_idx_by_handle(handle, s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); + tab_index = prf_find_idx_by_handle(handle,s_mlmr_env.start_hdl, MLMR_IDX_NB, (uint8_t *)&s_char_mask); event.conn_idx = conn_idx; cfm.handle = handle; cfm.status = BLE_SUCCESS; - - switch (tab_index) { - case GUS_IDX_RX_VAL: - event.evt_type = GUS_EVT_RX_DATA_RECEIVED; - if (((uint8_t *)p_param->value)[0] == adv_header) { + + switch (tab_index) + { + case MLMR_IDX_RX_VAL: + event.evt_type = MLMR_EVT_RX_DATA_RECEIVED; + if(((uint8_t *)p_param->value)[0] == adv_header) + { uint16_t data_len; - ret = memcpy(&data_len, DATA_COPY_LEN, &(((uint8_t *)p_param->value)[1]), DATA_COPY_LEN); - if (ret < 0) { - return; - } + memcpy(&data_len, &(((uint8_t *)p_param->value)[1]), 2); + received_data_len[conn_idx] = 0; + memset(rx_buffer[conn_idx], 0, 516); - if (data_len <= (MAX_MTU_DEFUALT - MTU_DEF_OFFSET)) { + if(data_len <= (MAX_MTU_DEFUALT - 3)) + { event.p_data = (uint8_t *)p_param->value; event.length = p_param->length; - s_gus_env.gus_init.evt_handler(&event); - } else { + s_mlmr_env.mlmr_init.evt_handler(&event); + } + else + { send_data_len[conn_idx] = data_len; - gus_combin_received_packet(conn_idx, p_param->length, - (uint8_t *)p_param->value, rx_buffer[conn_idx]); - if (received_data_len[conn_idx] == send_data_len[conn_idx]) { + mlmr_combin_received_packet(conn_idx, p_param->length, (uint8_t *)p_param->value, rx_buffer[conn_idx]); + if(received_data_len[conn_idx] == send_data_len[conn_idx]) + { event.p_data = rx_buffer[conn_idx]; event.length = send_data_len[conn_idx]; - s_gus_env.gus_init.evt_handler(&event); + s_mlmr_env.mlmr_init.evt_handler(&event); received_data_len[conn_idx] = 0; } } - } else { - gus_combin_received_packet(conn_idx, p_param->length, (uint8_t *)p_param->value, rx_buffer[conn_idx]); - - if (received_data_len[conn_idx] == send_data_len[conn_idx]) { + } + else + { + mlmr_combin_received_packet(conn_idx, p_param->length, (uint8_t *)p_param->value, rx_buffer[conn_idx]); + + if(received_data_len[conn_idx] == send_data_len[conn_idx]) + { event.p_data = rx_buffer[conn_idx]; event.length = send_data_len[conn_idx]; - s_gus_env.gus_init.evt_handler(&event); + s_mlmr_env.mlmr_init.evt_handler(&event); received_data_len[conn_idx] = 0; } } break; - case GUS_IDX_TX_CFG: + case MLMR_IDX_TX_CFG: cccd_value = le16toh(&p_param->value[0]); - event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? GUS_EVT_TX_PORT_OPENED : GUS_EVT_TX_PORT_CLOSED; - s_gus_env.tx_ntf_cfg[conn_idx] = cccd_value; - s_gus_env.gus_init.evt_handler(&event); + event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? MLMR_EVT_TX_PORT_OPENED : MLMR_EVT_TX_PORT_CLOSED; + s_mlmr_env.tx_ntf_cfg[conn_idx] = cccd_value; + s_mlmr_env.mlmr_init.evt_handler(&event); break; default: cfm.status = BLE_ATT_ERR_INVALID_HANDLE; - s_gus_env.gus_init.evt_handler(&event); + s_mlmr_env.mlmr_init.evt_handler(&event); break; } @@ -374,36 +299,39 @@ static void gus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void mlmr_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; - gus_evt_t event; + mlmr_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } - tab_index = prf_find_idx_by_handle(handle, s_gus_env.start_hdl, GUS_IDX_NB, (uint8_t *)&s_char_mask); + tab_index = prf_find_idx_by_handle(handle,s_mlmr_env.start_hdl, MLMR_IDX_NB, (uint8_t *)&s_char_mask); event.conn_idx = conn_idx; - event.evt_type = GUS_EVT_INVALID; + event.evt_type = MLMR_EVT_INVALID; - switch (tab_index) { - case GUS_IDX_TX_CFG: - event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? GUS_EVT_TX_PORT_OPENED : GUS_EVT_TX_PORT_CLOSED; - s_gus_env.tx_ntf_cfg[conn_idx] = cccd_value; + switch (tab_index) + { + case MLMR_IDX_TX_CFG: + event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? MLMR_EVT_TX_PORT_OPENED : MLMR_EVT_TX_PORT_CLOSED; + s_mlmr_env.tx_ntf_cfg[conn_idx] = cccd_value; break; - case GUS_IDX_FLOW_CTRL_CFG: - event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? GUS_EVT_FLOW_CTRL_ENABLE : GUS_EVT_FLOW_CTRL_DISABLE; - s_gus_env.flow_ctrl_ntf_cfg[conn_idx] = cccd_value; + case MLMR_IDX_FLOW_CTRL_CFG: + event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? MLMR_EVT_FLOW_CTRL_ENABLE : MLMR_EVT_FLOW_CTRL_DISABLE; + s_mlmr_env.flow_ctrl_ntf_cfg[conn_idx] = cccd_value; break; default: break; } - if (GUS_EVT_INVALID != event.evt_type && s_gus_env.gus_init.evt_handler) { - s_gus_env.gus_init.evt_handler(&event); + if (MLMR_EVT_INVALID != event.evt_type && s_mlmr_env.mlmr_init.evt_handler) + { + s_mlmr_env.mlmr_init.evt_handler(&event); } } @@ -416,48 +344,83 @@ static void gus_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void gus_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void mlmr_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_gus_env.gus_init.evt_handler != NULL) { - gus_evt_t event; + if (NULL != s_mlmr_env.mlmr_init.evt_handler) + { + mlmr_evt_t event; event.conn_idx = conn_idx; - if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) { - event.evt_type = GUS_EVT_TX_DATA_SENT; - s_gus_env.gus_init.evt_handler(&event); + if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { + event.evt_type = MLMR_EVT_TX_DATA_SENT; + s_mlmr_env.mlmr_init.evt_handler(&event); } } } +static void mlmr_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + mlmr_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + mlmr_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + mlmr_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + mlmr_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ -sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) +sdk_err_t mlmr_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_cmd; + ble_gatts_noti_ind_t send_cmd; uint8_t *buffer = p_data; - if (PRF_CLI_START_NTF == s_gus_env.tx_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_mlmr_env.tx_ntf_cfg[conn_idx]) + { send_cmd.type = BLE_GATT_NOTIFICATION; - send_cmd.handle = prf_find_handle_by_idx(GUS_IDX_TX_VAL, s_gus_env.start_hdl, (uint8_t *)&s_char_mask); + send_cmd.handle = prf_find_handle_by_idx(MLMR_IDX_TX_VAL, s_mlmr_env.start_hdl, (uint8_t *)&s_char_mask); - if (length > (MAX_MTU_DEFUALT - MTU_DEF_OFFSET)) { - while length > MAX_MTU_DEFUALT - MTU_DEF_OFFSET) { + if(length > (MAX_MTU_DEFUALT - 3)) + { + while(length > MAX_MTU_DEFUALT - 3) + { send_cmd.value = buffer; - send_cmd.length = MAX_MTU_DEFUALT - MTU_DEF_OFFSET; + send_cmd.length = MAX_MTU_DEFUALT - 3; error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); - buffer += (MAX_MTU_DEFUALT - MTU_DEF_OFFSET); - length -= (MAX_MTU_DEFUALT - MTU_DEF_OFFSET); + buffer += (MAX_MTU_DEFUALT - 3); + length -= (MAX_MTU_DEFUALT - 3); } - - if (length != 0 && length < (MAX_MTU_DEFUALT - MTU_DEF_OFFSET)) { + + if(length != 0 && length < (MAX_MTU_DEFUALT - 3)) + { send_cmd.length = length; send_cmd.value = buffer; error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); } - } else { + } + else + { send_cmd.value = buffer; send_cmd.length = length; error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); @@ -467,15 +430,16 @@ sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) return error_code; } -sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) +sdk_err_t mlmr_rx_flow_ctrl_set(uint8_t conn_idx, mlmr_flow_ctrl_state_t flow_ctrl) { sdk_err_t error_code = BLE_SUCCESS; - gatts_noti_ind_t send_cmd; + ble_gatts_noti_ind_t send_cmd; - if (PRF_CLI_START_NTF == s_gus_env.flow_ctrl_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_mlmr_env.flow_ctrl_ntf_cfg[conn_idx]) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; - send_cmd.handle = prf_find_handle_by_idx(GUS_IDX_FLOW_CTRL_VAL, s_gus_env.start_hdl, (uint8_t *)&s_char_mask); + send_cmd.handle = prf_find_handle_by_idx(MLMR_IDX_FLOW_CTRL_VAL, s_mlmr_env.start_hdl, (uint8_t *)&s_char_mask); // Pack measured value in database send_cmd.length = 1; @@ -488,16 +452,24 @@ sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) return error_code; } -sdk_err_t gus_service_init(gus_init_t *p_gus_init) +sdk_err_t mlmr_service_init(mlmr_init_t *p_mlmr_init) { - sdk_err_t ret; - if (p_gus_init == NULL) { + if (NULL == p_mlmr_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_gus_env.gus_init, sizeof(gus_init_t), p_gus_init, sizeof(gus_init_t)); - if (ret < 0) { - return ret; - } - return ble_server_prf_add(&gus_prf_info); + memcpy(&s_mlmr_env.mlmr_init, p_mlmr_init, sizeof(mlmr_init_t)); + + s_mlmr_env.start_hdl = PRF_INVALID_HANDLE; + + s_mlmr_env.mlmr_gatts_db.shdl = &s_mlmr_env.start_hdl; + s_mlmr_env.mlmr_gatts_db.uuid = s_mlmr_svc_uuid; + s_mlmr_env.mlmr_gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_mlmr_env.mlmr_gatts_db.max_nb_attr = MLMR_IDX_NB; + s_mlmr_env.mlmr_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_mlmr_env.mlmr_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_mlmr_env.mlmr_gatts_db.attr_tab.attr_tab_128 = mlmr_attr_tab; + + return ble_gatts_prf_add(&s_mlmr_env.mlmr_gatts_db, mlmr_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.h index b878d8b..73fbca2 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr/mlmr.h @@ -3,7 +3,7 @@ * * @file mlmr.h * - * @brief Goodix UART Service API + * @brief Multi Link Multi Role Service API * ***************************************************************************************** * @attention @@ -42,109 +42,114 @@ */ /** - * @defgroup BLE_SDK_GUS Goodix UART Service (GUS) + * @defgroup BLE_SDK_MLMR Multi Link Multi Role Service (MLMR) * @{ - * @brief Definitions and prototypes for the GUS interface. + * @brief Definitions and prototypes for the MLMR interface. * - * @details The Goodix UART Service is a customized GATT-based service with Tx, Rx and Flow Control + * @details The Multi Link Multi Role Service is a customized GATT-based service with Tx, Rx and Flow Control * characteristics. The application uses the service to send and receive data to and * from the peer. The application data is sent to the peer as Handle Value Notification, * and the data received from the peer is transmitted with GATT Write Command. * - * After \ref gus_init_t variable is initialized , the application must call \ref gus_service_init() + * After \ref mlmr_init_t variable is initialized , the application must call \ref mlmr_service_init() * to add the Goodix Uart Service and Rx, Tx, Flow Control characteristics to the BLE Stack - * database. The application can send the data to the peer with \ref gus_tx_data_send() after - * \ref GUS_EVT_TX_PORT_OPENED received. The application should copy the received data to its own buffer - * when handling \ref GUS_EVT_RX_DATA_RECEIVED. + * database. The application can send the data to the peer with \ref mlmr_tx_data_send() after + * \ref MLMR_EVT_TX_PORT_OPENED received. The application should copy the received data to its own buffer + * when handling \ref MLMR_EVT_RX_DATA_RECEIVED. */ -#ifndef GUS_H -#define GUS_H +#ifndef __MLMR_H__ +#define __MLMR_H__ -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" /** - * @defgroup GUS_MACRO Defines + * @defgroup MLMR_MACRO Defines * @{ */ -#define GUS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Goodix UART Service connections. */ -#define FLOW_ON 0x01 /**< Indicate that GUS can receive data from peer. */ -#define FLOW_OFF 0x00 /**< Indicate that GUS can not receive data from peer. */ -#define GUS_MAX_DATA_LEN 247 /**< Maximum length of application data packet which is transmitted via GUS. */ -#define GUS_FLOW_CTRL_LEN 1 /**< Maximum length of ble flow control data packet which is transmitted via GUS. */ -#define GUS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x02, \ - 0xED, 0xA6 /**< The UUID of Goodix UART Service for setting advertising data. */ +#define MLMR_CONNECTION_MAX 10 /**< Maximum number of Multi Link Multi Role Service connections. */ +#define MLMR_MAX_DATA_LEN 247 /**< Maximum length of application data packet which is transmitted via MLMR. */ +#define MLMR_FLOW_CTRL_LEN 1 /**< Maximum length of ble flow control data packet which is transmitted via MLMR. */ +#define MLMR_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x02, 0xED, 0xA6 /**< The UUID of Multi Link Multi Role Service for setting advertising data. */ /** @} */ /** - * @defgroup GUS_ENUM Enumerations + * @defgroup MLMR_ENUM Enumerations * @{ */ -/**@brief Goodix UART Service event types. */ -typedef enum { - GUS_EVT_INVALID, /**< Invalid GUS event. */ - GUS_EVT_RX_DATA_RECEIVED, /**< The data from the peer has been received. */ - GUS_EVT_TX_DATA_SENT, /**< The data from the application has been sent, \ - and the service is ready to accept new data from the application. */ - GUS_EVT_TX_PORT_OPENED, /**< Tx port has been opened. */ - GUS_EVT_TX_PORT_CLOSED, /**< Tx port has been closed. */ - GUS_EVT_FLOW_CTRL_ENABLE, /**< GUS flow control been enabled. */ - GUS_EVT_FLOW_CTRL_DISABLE, /**< GUS flow control been disabled. */ - GUS_EVT_TX_FLOW_OFF, /**< Tx flow off control request. */ - GUS_EVT_TX_FLOW_ON, /**< Tx flow on control request. */ -} gus_evt_type_t; +/**@brief Multi Link Multi Role Service event types. */ +typedef enum +{ + MLMR_EVT_INVALID, /**< Invalid MLMR event. */ + MLMR_EVT_RX_DATA_RECEIVED, /**< The data from the peer has been received. */ + MLMR_EVT_TX_DATA_SENT, /**< The data from the application has been sent, and the service is ready to accept new data from the application. */ + MLMR_EVT_TX_PORT_OPENED, /**< Tx port has been opened. */ + MLMR_EVT_TX_PORT_CLOSED, /**< Tx port has been closed. */ + MLMR_EVT_FLOW_CTRL_ENABLE, /**< MLMR flow control been enabled. */ + MLMR_EVT_FLOW_CTRL_DISABLE, /**< MLMR flow control been disabled. */ + MLMR_EVT_TX_FLOW_OFF, /**< Tx flow off control request. */ + MLMR_EVT_TX_FLOW_ON, /**< Tx flow on control request. */ +} mlmr_evt_type_t; + +/**@brief Flow control state for MLMR service. */ +enum mlmr_flow_ctrl_state +{ + MLMR_FLOW_CTRL_STATE_OFF = 0, /**< Indicate that MLMR can not receive data from peer. */ + MLMR_FLOW_CTRL_STATE_ON /**< Indicate that MLMR can receive data from peer. */ +}; +/**@brief Underlying type used for the MLMR flow control state. */ +typedef uint8_t mlmr_flow_ctrl_state_t; /** @} */ /** - * @defgroup GUS_STRUCT Structures + * @defgroup MLMR_STRUCT Structures * @{ */ -/**@brief Goodix UART Service event. */ -typedef struct { - gus_evt_type_t evt_type; /**< The GUS event. */ +/**@brief Multi Link Multi Role Service event. */ +typedef struct +{ + mlmr_evt_type_t evt_type; /**< The MLMR event. */ uint8_t conn_idx; /**< The index of the connection for the data transmission. */ uint8_t *p_data; /**< Pointer to the buffer within received data. */ uint16_t length; /**< Length of received data. */ -} gus_evt_t; +} mlmr_evt_t; /** @} */ /** - * @defgroup GUS_TYPEDEF Typedefs + * @defgroup MLMR_TYPEDEF Typedefs * @{ */ -/**@brief Goodix UART Service event handler type. */ -typedef void (*gus_evt_handler_t)(gus_evt_t *p_evt); +/**@brief Multi Link Multi Role Service event handler type. */ +typedef void (*mlmr_evt_handler_t)(mlmr_evt_t *p_evt); /** @} */ /** - * @addtogroup GUS_STRUCT Structures + * @addtogroup MLMR_STRUCT Structures * @{ */ -/** @brief Goodix UART Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { - gus_evt_handler_t - evt_handler; /**< Goodix UART Service event handler which must be provided - by the application to send and receive the data. */ -} gus_init_t; +/**@brief Multi Link Multi Role Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ + mlmr_evt_handler_t evt_handler; /**< Multi Link Multi Role Service event handler which must be provided by the application to send and receive the data. */ +} mlmr_init_t; /** @} */ /** - * @defgroup GUS_FUNCTION Functions + * @defgroup MLMR_FUNCTION Functions * @{ */ /** ***************************************************************************************** - * @brief Initialize a Goodix UART Service instance and add in the database. + * @brief Initialize a Multi Link Multi Role Service instance and add in the database. * - * @param[in] p_gus_init: Pointer to Goodix UART Service initialization variables. + * @param[in] p_mlmr_init: Pointer to Multi Link Multi Role Service initialization variables. * * @return Result of service initialization. ***************************************************************************************** */ -sdk_err_t gus_service_init(gus_init_t *p_gus_init); +sdk_err_t mlmr_service_init(mlmr_init_t *p_mlmr_init); /** ***************************************************************************************** @@ -157,19 +162,19 @@ sdk_err_t gus_service_init(gus_init_t *p_gus_init); * @return Result of sending data. ***************************************************************************************** */ -sdk_err_t gus_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); +sdk_err_t mlmr_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); /** ***************************************************************************************** - * @brief Send GUS Rx flow control state to peer device + * @brief Send MLMR Rx flow control state to peer device * * @param[in] conn_idx: Index of the connection. - * @param[in] flow_ctrl: GUS Rx flow control state + * @param[in] flow_ctrl: MLMR Rx flow control state * - * @return Result of sending GUS Rx flow control state. + * @return Result of sending MLMR Rx flow control state. ***************************************************************************************** */ -sdk_err_t gus_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl); +sdk_err_t mlmr_rx_flow_ctrl_set(uint8_t conn_idx, mlmr_flow_ctrl_state_t flow_ctrl); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/BUILD.gn new file mode 100644 index 0000000..6a6f09b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("mlmr_c") { + sources = [ "mlmr_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.c index e0be6e8..511d4d9 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.c @@ -3,7 +3,7 @@ * * @file mlmr_c.c * - * @brief Goodix UART Client Implementation. + * @brief Multi Link Multi Role Client Implementation. * ***************************************************************************************** * @attention @@ -41,71 +41,35 @@ #include "mlmr_c.h" #include "user_app.h" #include "app_log.h" -#define DATA_COPY_LEN 2 -#define MAX_MTU_OFFSET 3 -#define UUID_LEN 16 -#define ATTR_LEN_DEF 2 - /* * STRUCT DEFINE ***************************************************************************************** */ -/**@brief Goodix UART Service Client environment variable. */ -struct gus_c_env_t { - gus_c_handles_t handles; /**< Handles of GUS characteristics which will be got for peer. */ - gus_c_evt_handler_t evt_handler; /**< Handler of GUS client event */ - uint8_t prf_id; /**< GUS Client profile id. */ +/**@brief Multi Link Multi Role Service Client environment variable. */ +struct mlmr_c_env_t +{ + mlmr_c_handles_t handles; /**< Handles of MLMR_C characteristics which will be got for peer. */ + mlmr_c_evt_handler_t evt_handler; /**< Handler of MLMR client event */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void gus_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void gus_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct gus_c_env_t s_gus_c_env; /**< GUS Client environment variable. */ -static uint8_t s_gus_uuid[16] = GUS_SVC_UUID; -static uint8_t s_gus_rx_char_uuid[16] = GUS_RX_CHAR_UUID; -static uint8_t s_gus_tx_char_uuid[16] = GUS_TX_CHAR_UUID; -static uint8_t s_gus_flow_ctrl_char_uuid[16] = GUS_FLOW_CTRL_UUID; +static struct mlmr_c_env_t s_mlmr_c_env; /**< MLMR Client environment variable. */ +static uint8_t s_mlmr_c_uuid[16] = MLMR_C_SVC_UUID; +static uint8_t s_mlmr_c_rx_char_uuid[16] = MLMR_C_RX_CHAR_UUID; +static uint8_t s_mlmr_c_tx_char_uuid[16] = MLMR_C_TX_CHAR_UUID; +static uint8_t s_mlmr_c_flow_ctrl_char_uuid[16] = MLMR_C_FLOW_CTRL_UUID; -static uint16_t received_data_len[CFG_BOND_DEVS]; -static uint16_t send_data_len[CFG_BOND_DEVS]; -static uint8_t adv_header = 0xA0; -static uint8_t rx_buffer[CFG_BOND_DEVS][516]; - - -/**@brief GUS Client interface required by profile manager. */ -static ble_prf_manager_cbs_t gus_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief GUS GATT Client Callbacks. */ -static gattc_prf_cbs_t gus_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - gus_c_att_write_cb, - gus_c_att_ntf_ind_cb, - gus_c_srvc_browse_cb, - NULL, -}; - -/**@brief GUS Client Information. */ -static const prf_client_info_t gus_c_prf_info = { - .max_connection_nb = GUS_C_CONNECTION_MAX, - .manager_cbs = &gus_c_mgr_cbs, - .gattc_prf_cbs = &gus_c_gattc_cbs +static uint16_t received_data_len[CFG_BOND_DEVS]; +static uint16_t send_data_len[CFG_BOND_DEVS]; +static uint8_t adv_header = 0xA0; +static uint8_t rx_buffer[CFG_BOND_DEVS][516]; +static ble_uuid_t s_mlmr_c_service_uuid = +{ + .uuid_len = 16, + .uuid = s_mlmr_c_uuid, }; /* @@ -114,15 +78,16 @@ static const prf_client_info_t gus_c_prf_info = { */ /** ***************************************************************************************** - * @brief Excute GUS Service Client event handler. + * @brief Excute MLMR Service Client event handler. * - * @param[in] p_evt: Pointer to GUS Service Client event structure. + * @param[in] p_evt: Pointer to MLMR Service Client event structure. ***************************************************************************************** */ -static void gus_c_evt_handler_excute(gus_c_evt_t *p_evt) +static void mlmr_c_evt_handler_excute(mlmr_c_evt_t *p_evt) { - if (s_gus_c_env.evt_handler != NULL && GUS_C_EVT_INVALID != p_evt->evt_type) { - s_gus_c_env.evt_handler(p_evt); + if (NULL != s_mlmr_c_env.evt_handler && MLMR_C_EVT_INVALID != p_evt->evt_type) + { + s_mlmr_c_env.evt_handler(p_evt); } } @@ -135,45 +100,49 @@ static void gus_c_evt_handler_excute(gus_c_evt_t *p_evt) * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void gus_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void mlmr_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { - gus_c_evt_t gus_c_evt; + mlmr_c_evt_t mlmr_c_evt; - gus_c_evt.conn_idx = conn_idx; - gus_c_evt.evt_type = GUS_C_EVT_INVALID; + mlmr_c_evt.conn_idx = conn_idx; + mlmr_c_evt.evt_type = MLMR_C_EVT_INVALID; - if (handle == s_gus_c_env.handles.gus_tx_cccd_handle) { - gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_TX_NTF_SET_SUCCESS : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) { - gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_rx_handle) { - gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_TX_CPLT : \ - GUS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_gus_c_env.handles.gus_flow_ctrl_handle) { - gus_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - GUS_C_EVT_RX_FLOW_UPDATE_CPLT : \ - GUS_C_EVT_WRITE_OP_ERR; + if (handle == s_mlmr_c_env.handles.mlmr_c_tx_cccd_handle) + { + mlmr_c_evt.evt_type = (BLE_SUCCESS == status) ? \ + MLMR_C_EVT_TX_NTF_SET_SUCCESS : \ + MLMR_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_mlmr_c_env.handles.mlmr_c_flow_ctrl_cccd_handle) + { + mlmr_c_evt.evt_type = (BLE_SUCCESS == status) ? \ + MLMR_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS : \ + MLMR_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_mlmr_c_env.handles.mlmr_c_rx_handle) + { + mlmr_c_evt.evt_type = (BLE_SUCCESS == status) ? \ + MLMR_C_EVT_TX_CPLT : \ + MLMR_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_mlmr_c_env.handles.mlmr_c_flow_ctrl_handle) + { + mlmr_c_evt.evt_type = (BLE_SUCCESS == status) ? \ + MLMR_C_EVT_RX_FLOW_UPDATE_CPLT : \ + MLMR_C_EVT_WRITE_OP_ERR; } - gus_c_evt_handler_excute(&gus_c_evt); + mlmr_c_evt_handler_excute(&mlmr_c_evt); } void combin_received_packet(uint8_t conn_idx, uint16_t length, uint8_t *p_received_data, uint8_t *p_combin_data) { uint8_t *buffer = p_combin_data; - uint8_t ret; - if (send_data_len[conn_idx] > received_data_len[conn_idx]) { + if(send_data_len[conn_idx] > received_data_len[conn_idx]) + { buffer += received_data_len[conn_idx]; - ret = memcpy_s(buffer, length, p_received_data, length); - if (ret < 0) { - return; - } + memcpy(buffer, p_received_data,length); received_data_len[conn_idx] += length; } } @@ -187,50 +156,62 @@ void combin_received_packet(uint8_t conn_idx, uint16_t length, uint8_t *p_receiv * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void mlmr_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { - gus_c_evt_t gus_c_evt; - uint8_t ret; - uint16_t data_length; + mlmr_c_evt_t mlmr_c_evt; - gus_c_evt.conn_idx = conn_idx; - gus_c_evt.evt_type = GUS_C_EVT_INVALID; + mlmr_c_evt.conn_idx = conn_idx; + mlmr_c_evt.evt_type = MLMR_C_EVT_INVALID; - if (p_ntf_ind->handle == s_gus_c_env.handles.gus_flow_ctrl_handle) { - if (FLOW_ON == p_ntf_ind->p_value[0]) { - gus_c_evt.evt_type = GUS_C_EVT_TX_FLOW_ON; - } else if (FLOW_OFF == p_ntf_ind->p_value[0]) { - gus_c_evt.evt_type = GUS_C_EVT_TX_FLOW_OFF; + if (p_ntf_ind->handle == s_mlmr_c_env.handles.mlmr_c_flow_ctrl_handle) + { + if (MLMR_C_FLOW_CTRL_STATE_ON == p_ntf_ind->p_value[0]) + { + mlmr_c_evt.evt_type = MLMR_C_EVT_TX_FLOW_ON; } - } else if (p_ntf_ind->handle == s_gus_c_env.handles.gus_tx_handle) { - gus_c_evt.evt_type = GUS_C_EVT_PEER_DATA_RECEIVE; - if (p_ntf_ind->p_value[0] == adv_header) { - ret = memcpy_s(&data_length, DATA_COPY_LEN, - sizeof(&(((uint8_t *)p_ntf_ind->p_value)[1]), DATA_COPY_LEN); - if (ret <0) { - return; + else if (MLMR_C_FLOW_CTRL_STATE_OFF == p_ntf_ind->p_value[0]) + { + mlmr_c_evt.evt_type = MLMR_C_EVT_TX_FLOW_OFF; + } + } + else if (p_ntf_ind->handle == s_mlmr_c_env.handles.mlmr_c_tx_handle) + { + mlmr_c_evt.evt_type = MLMR_C_EVT_PEER_DATA_RECEIVE; + if(p_ntf_ind->p_value[0] == adv_header) + { + uint16_t data_length; + memcpy(&data_length, &(((uint8_t *)p_ntf_ind->p_value)[1]), 2); + received_data_len[conn_idx] = 0; + memset(rx_buffer[conn_idx], 0, 516); + + if(data_length <= (MAX_MTU_DEFUALT - 3)) + { + mlmr_c_evt.evt_type = MLMR_C_EVT_PEER_DATA_RECEIVE; + mlmr_c_evt.p_data = p_ntf_ind->p_value; + mlmr_c_evt.length = p_ntf_ind->length; + mlmr_c_evt_handler_excute(&mlmr_c_evt); } - if (data_length <= (MAX_MTU_DEFUALT - MAX_MTU_OFFSET)) { - gus_c_evt.evt_type = GUS_C_EVT_PEER_DATA_RECEIVE; - gus_c_evt.p_data = p_ntf_ind->p_value; - gus_c_evt.length = p_ntf_ind->length; - gus_c_evt_handler_excute(&gus_c_evt); - } else { + else + { send_data_len[conn_idx] = data_length; combin_received_packet(conn_idx, p_ntf_ind->length, p_ntf_ind->p_value, rx_buffer[conn_idx]); - if (received_data_len[conn_idx] == send_data_len[conn_idx]) { - gus_c_evt.p_data = rx_buffer[conn_idx]; - gus_c_evt.length = send_data_len[conn_idx]; - gus_c_evt_handler_excute(&gus_c_evt); + if(received_data_len[conn_idx] == send_data_len[conn_idx]) + { + mlmr_c_evt.p_data = rx_buffer[conn_idx]; + mlmr_c_evt.length = send_data_len[conn_idx]; + mlmr_c_evt_handler_excute(&mlmr_c_evt); received_data_len[conn_idx] = 0; } } - } else { + } + else + { combin_received_packet(conn_idx, p_ntf_ind->length, p_ntf_ind->p_value, rx_buffer[conn_idx]); - if (received_data_len[conn_idx] == send_data_len[conn_idx]) { - gus_c_evt.p_data = rx_buffer[conn_idx]; - gus_c_evt.length = send_data_len[conn_idx]; - gus_c_evt_handler_excute(&gus_c_evt); + if(received_data_len[conn_idx] == send_data_len[conn_idx]) + { + mlmr_c_evt.p_data = rx_buffer[conn_idx]; + mlmr_c_evt.length = send_data_len[conn_idx]; + mlmr_c_evt_handler_excute(&mlmr_c_evt); received_data_len[conn_idx] = 0; } } @@ -246,167 +227,173 @@ static void gus_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void gus_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void mlmr_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { - gus_c_evt_t gus_c_evt; + mlmr_c_evt_t mlmr_c_evt; uint16_t handle_disc; - gus_c_evt.conn_idx = conn_idx; - gus_c_evt.evt_type = GUS_C_EVT_DISCOVERY_FAIL; + mlmr_c_evt.conn_idx = conn_idx; + mlmr_c_evt.evt_type = MLMR_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (BLE_SUCCESS == status) { - if (p_browse_srvc->uuid_len == UUID_LEN && - memcmp(p_browse_srvc->uuid, s_gus_uuid, UUID_LEN) == 0) { - s_gus_c_env.handles.gus_srvc_start_handle = p_browse_srvc->start_hdl; - s_gus_c_env.handles.gus_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_SUCCESS == status) + { + if (16 == p_browse_srvc->uuid_len && 0 == memcmp(p_browse_srvc->uuid, s_mlmr_c_uuid, 16)) + { + s_mlmr_c_env.handles.mlmr_c_srvc_start_handle = p_browse_srvc->start_hdl; + s_mlmr_c_env.handles.mlmr_c_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_rx_char_uuid, UUID_LEN) == 0) { - s_gus_c_env.handles.gus_rx_handle = handle_disc; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_tx_char_uuid, UUID_LEN) == 0) { - s_gus_c_env.handles.gus_tx_handle = handle_disc; - s_gus_c_env.handles.gus_tx_cccd_handle = handle_disc + 1; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_gus_flow_ctrl_char_uuid, UUID_LEN) == 0) { - s_gus_c_env.handles.gus_flow_ctrl_handle = handle_disc; - s_gus_c_env.handles.gus_flow_ctrl_cccd_handle = handle_disc + 1; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_mlmr_c_rx_char_uuid, 16)) + { + s_mlmr_c_env.handles.mlmr_c_rx_handle = handle_disc; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_mlmr_c_tx_char_uuid, 16)) + { + s_mlmr_c_env.handles.mlmr_c_tx_handle = handle_disc; + s_mlmr_c_env.handles.mlmr_c_tx_cccd_handle = handle_disc + 1; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_mlmr_c_flow_ctrl_char_uuid, 16)) + { + s_mlmr_c_env.handles.mlmr_c_flow_ctrl_handle = handle_disc; + s_mlmr_c_env.handles.mlmr_c_flow_ctrl_cccd_handle = handle_disc + 1; } } - - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { + + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { break; } } - gus_c_evt.evt_type = GUS_C_EVT_DISCOVERY_COMPLETE; + mlmr_c_evt.evt_type = MLMR_C_EVT_DISCOVERY_COMPLETE; } } - gus_c_evt_handler_excute(&gus_c_evt); + mlmr_c_evt_handler_excute(&mlmr_c_evt); +} + +static void mlmr_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + mlmr_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + mlmr_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + mlmr_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } } /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ -sdk_err_t gus_client_init(gus_c_evt_handler_t evt_handler) +sdk_err_t mlmr_client_init(mlmr_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_gus_c_env, sizeof(s_gus_c_env), 0, sizeof(s_gus_c_env)); - if (ret < 0) { - return ret; - } - s_gus_c_env.evt_handler = evt_handler; + memset(&s_mlmr_c_env, 0, sizeof(s_mlmr_c_env)); + s_mlmr_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&gus_c_prf_info, &s_gus_c_env.prf_id); + return ble_gattc_prf_add(&s_mlmr_c_service_uuid, mlmr_c_ble_evt_handler); } -sdk_err_t gus_c_disc_srvc_start(uint8_t conn_idx) +sdk_err_t mlmr_c_disc_srvc_start(uint8_t conn_idx) { - const ble_uuid_t gus_uuid = { - .uuid_len = 16, - .uuid = s_gus_uuid, - }; - - return ble_gattc_prf_services_browse(s_gus_c_env.prf_id, conn_idx, &gus_uuid); + return ble_gattc_services_browse(conn_idx, &s_mlmr_c_service_uuid); } -sdk_err_t gus_c_tx_notify_set(uint8_t conn_idx, bool is_enable) +sdk_err_t mlmr_c_tx_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_tx_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_mlmr_c_env.handles.mlmr_c_tx_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_tx_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_LEN_DEF; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_mlmr_c_env.handles.mlmr_c_tx_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } -sdk_err_t gus_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable) +sdk_err_t mlmr_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_mlmr_c_env.handles.mlmr_c_flow_ctrl_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_flow_ctrl_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_LEN_DEF; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_mlmr_c_env.handles.mlmr_c_flow_ctrl_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } -sdk_err_t gus_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) +sdk_err_t mlmr_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code; uint8_t *buffer = p_data; - gattc_write_no_resp_t write_attr_value; - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_rx_handle) { + if (BLE_ATT_INVALID_HDL == s_mlmr_c_env.handles.mlmr_c_rx_handle) + { return SDK_ERR_INVALID_HANDLE; } - if (p_data == NULL) { + if (NULL == p_data) + { return SDK_ERR_POINTER_NULL; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_gus_c_env.handles.gus_rx_handle; - - if (length > (MAX_MTU_DEFUALT - MAX_MTU_OFFSET)) { - while (length > MAX_MTU_DEFUALT - MAX_MTU_OFFSET) { - write_attr_value.p_value = buffer; - write_attr_value.length = MAX_MTU_DEFUALT - MAX_MTU_OFFSET; - error_code = ble_gattc_prf_write_no_resp(s_gus_c_env.prf_id, conn_idx, &write_attr_value); - buffer += (MAX_MTU_DEFUALT - MAX_MTU_OFFSET); - length -= (MAX_MTU_DEFUALT - MAX_MTU_OFFSET); + if(length > (MAX_MTU_DEFUALT - 3)) + { + while(length > MAX_MTU_DEFUALT - 3) + { + error_code = ble_gattc_write_no_resp(conn_idx, false, s_mlmr_c_env.handles.mlmr_c_rx_handle, MAX_MTU_DEFUALT - 3, buffer); + buffer += (MAX_MTU_DEFUALT - 3); + length -= (MAX_MTU_DEFUALT - 3); } - - if (length != 0 && length < (MAX_MTU_DEFUALT - MAX_MTU_OFFSET)) { - write_attr_value.length = length; - write_attr_value.p_value = buffer; - error_code = ble_gattc_prf_write_no_resp(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + + if(length != 0 && length < (MAX_MTU_DEFUALT - 3)) + { + error_code = ble_gattc_write_no_resp(conn_idx, false, s_mlmr_c_env.handles.mlmr_c_rx_handle, length, buffer); } - } else { - write_attr_value.p_value = buffer; - write_attr_value.length = length; - error_code = ble_gattc_prf_write_no_resp(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + } + else + { + error_code = ble_gattc_write_no_resp(conn_idx, false, s_mlmr_c_env.handles.mlmr_c_rx_handle, length, buffer); } return error_code; } -sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl) +sdk_err_t mlmr_c_rx_flow_ctrl_set(uint8_t conn_idx, mlmr_c_flow_ctrl_state_t flow_ctrl) { - gattc_write_attr_value_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_gus_c_env.handles.gus_flow_ctrl_handle) { + if (BLE_ATT_INVALID_HDL == s_mlmr_c_env.handles.mlmr_c_flow_ctrl_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_gus_c_env.handles.gus_flow_ctrl_handle; - write_attr_value.offset = 0; - write_attr_value.length = 1; - write_attr_value.p_value = &flow_ctrl; - - return ble_gattc_prf_write(s_gus_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_mlmr_c_env.handles.mlmr_c_flow_ctrl_handle, 0, 1, &flow_ctrl); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.h index 12e1c0c..7096dd8 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/mlmr_c/mlmr_c.h @@ -3,7 +3,7 @@ * * @file mlmr_c.h * - * @brief Header file - Goodix UART Service Client + * @brief Header file - Multi Link Multi Role Service Client * ***************************************************************************************** * @attention @@ -42,136 +42,143 @@ */ /** - * @defgroup BLE_SDK_GUS_C Goodix UART Service Client (GUS_C) + * @defgroup BLE_SDK_MLMR_C Multi Link Multi Role Service Client (MLMR_C) * @{ - * @brief Goodix UART Service Client module. + * @brief Multi Link Multi Role Service Client module. * - * @details The Goodix Uart Service Client contains the APIs and types, which can be used by the - * application to perform scanning, connection and discover Goodix Uart Service at + * @details The Multi Link Multi Role Service Client contains the APIs and types, which can be used by the + * application to perform scanning, connection and discover Multi Link Multi Role Service at * peer and interact with it. * - * The application must provide an event handler, then call \ref gus_client_init(). After the - * module can send and receive BLE data, application can call \ref gus_c_tx_data_send() to - * send data to peer, and receive data from peer \ref GUS_C_EVT_PEER_DATA_RECEIVE, - * meanwhile update its received BLE data state \ref gus_c_rx_flow_ctrl_set() to peer. + * The application must provide an event handler, then call \ref mlmr_client_init(). After the + * module can send and receive BLE data, application can call \ref mlmr_c_tx_data_send() to + * send data to peer, and receive data from peer \ref MLMR_C_EVT_PEER_DATA_RECEIVE, + * meanwhile update its received BLE data state \ref mlmr_c_rx_flow_ctrl_set() to peer. */ -#ifndef GUS_C_H -#define GUS_C_H +#ifndef __MLMR_C_H__ +#define __MLMR_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** - * @defgroup GUS_C_MACRO Defines + * @defgroup MLMR_C_MACRO Defines * @{ */ -#define GUS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of GUS Client connections. */ -#define FLOW_ON 0x01 /**< Indicate that GUS Client can receive data from peer. */ -#define FLOW_OFF 0x00 /**< Indicate that GUS Client can not receive data from peer. */ +#define MLMR_C_CONNECTION_MAX 10 /**< Maximum number of MLMR Client connections. */ /** - * @defgroup GUS_UUID Service and Characteristics UUID + * @defgroup MLMR_C_UUID Service and Characteristics UUID * @{ */ -#define GUS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, \ - 0x44, 0xD3, 0x01, 0x02, 0xED, 0xA6} /**< UUID of GUS Service. */ -#define GUS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, \ - 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} /**< UUID of GUS Tx characterisitc. */ -#define GUS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, \ - 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} /**< UUID of GUS Rx characterisitc. */ -#define GUS_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, \ - 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**< UUID of GUS Flow Control characterisitc. */ +#define MLMR_C_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x02, 0xED, 0xA6} /**< UUID of MLMR_C Service. */ +#define MLMR_C_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x02, 0xED, 0xA6} /**< UUID of MLMR_C Tx characterisitc. */ +#define MLMR_C_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x02, 0xED, 0xA6} /**< UUID of MLMR_C Rx characterisitc. */ +#define MLMR_C_FLOW_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x02, 0xED, 0xA6} /**< UUID of MLMR_C Flow Control characterisitc. */ /** @} */ /** @} */ /** - * @defgroup GUS_C_ENUM Enumerations + * @defgroup MLMR_C_ENUM Enumerations * @{ */ -/**@brief Goodix UART Service Client event type. */ -typedef enum { - GUS_C_EVT_INVALID, /**< Invalid GUS Client event. */ - GUS_C_EVT_DISCOVERY_COMPLETE, /**< GUS Client has found service and its characteristics at peer. */ - GUS_C_EVT_DISCOVERY_FAIL, /**< GUS Client found THS service failed because of invalid operation \ - or no found at peer. */ - GUS_C_EVT_TX_NTF_SET_SUCCESS, /**< GUS Client has set peer Tx notify. */ - GUS_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS, /**< GUS Client has set peer ble flow control notify. */ - GUS_C_EVT_PEER_DATA_RECEIVE, /**< GUS Client has received something from peer. */ - GUS_C_EVT_TX_CPLT, /**< GUS Client has sent something to peer successfully. */ - GUS_C_EVT_TX_FLOW_OFF, /**< GUS Client has received Tx flow off control request from peer. */ - GUS_C_EVT_TX_FLOW_ON, /**< GUS Client has received Tx flow on control request from peer. */ - GUS_C_EVT_RX_FLOW_UPDATE_CPLT, /**< GUS CLient has updated flow control to peer completely. */ - GUS_C_EVT_WRITE_OP_ERR, /**< Error occured when GUS Client wrote to peer. */ -} gus_c_evt_type_t; +/**@brief Multi Link Multi Role Service Client event type. */ +typedef enum +{ + MLMR_C_EVT_INVALID, /**< Invalid MLMR Client event. */ + MLMR_C_EVT_DISCOVERY_COMPLETE, /**< MLMR Client has found service and its characteristics at peer. */ + MLMR_C_EVT_DISCOVERY_FAIL, /**< MLMR Client found the service failed because of invalid operation or no found at peer. */ + MLMR_C_EVT_TX_NTF_SET_SUCCESS, /**< MLMR Client has set peer Tx notify. */ + MLMR_C_EVT_FLOW_CTRL_NTF_SET_SUCCESS, /**< MLMR Client has set peer ble flow control notify. */ + MLMR_C_EVT_PEER_DATA_RECEIVE, /**< MLMR Client has received something from peer. */ + MLMR_C_EVT_TX_CPLT, /**< MLMR Client has sent something to peer successfully. */ + MLMR_C_EVT_TX_FLOW_OFF, /**< MLMR Client has received Tx flow off control request from peer. */ + MLMR_C_EVT_TX_FLOW_ON, /**< MLMR Client has received Tx flow on control request from peer. */ + MLMR_C_EVT_RX_FLOW_UPDATE_CPLT, /**< MLMR CLient has updated flow control to peer completely. */ + MLMR_C_EVT_WRITE_OP_ERR, /**< Error occured when MLMR Client wrote to peer. */ +} mlmr_c_evt_type_t; + +/**@brief Flow control state for MLMR Client service. */ +enum mlmr_c_flow_ctrl_state +{ + MLMR_C_FLOW_CTRL_STATE_OFF = 0, /**< Indicate that MLMR Client can not receive data from peer. */ + MLMR_C_FLOW_CTRL_STATE_ON /**< Indicate that MLMR Client can receive data from peer. */ +}; +/**@brief Underlying type used for the MLMR Client flow control state. */ +typedef uint8_t mlmr_c_flow_ctrl_state_t; /** @} */ /** - * @defgroup GUS_C_STRUCT Structures + * @defgroup MLMR_C_STRUCT Structures * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { - uint16_t gus_srvc_start_handle; /**< GUS Service start handle. */ - uint16_t gus_srvc_end_handle; /**< GUS Service end handle. */ - uint16_t gus_tx_handle; /**< Handle of GUS Tx characteristic as provided by a discovery. */ - uint16_t gus_tx_cccd_handle; /**< Handle of CCCD of GUS Tx characteristic as provided by a discovery. */ - uint16_t gus_rx_handle; /**< Handle of GUS Rx characteristic as provided by a discovery. */ - uint16_t gus_flow_ctrl_handle; /**< Handle of GUS Flow Control characteristic as provided by a discovery. */ - uint16_t gus_flow_ctrl_cccd_handle; /**< Handle of CCCD of GUS Flow Control characteristic \ - as provided by a discovery. */ -} gus_c_handles_t; +typedef struct +{ + uint16_t mlmr_c_srvc_start_handle; /**< MLMR_C Service start handle. */ + uint16_t mlmr_c_srvc_end_handle; /**< MLMR_C Service end handle. */ + uint16_t mlmr_c_tx_handle; /**< Handle of MLMR_C Tx characteristic as provided by a discovery. */ + uint16_t mlmr_c_tx_cccd_handle; /**< Handle of CCCD of MLMR_C Tx characteristic as provided by a discovery. */ + uint16_t mlmr_c_rx_handle; /**< Handle of MLMR_C Rx characteristic as provided by a discovery. */ + uint16_t mlmr_c_flow_ctrl_handle; /**< Handle of MLMR_C Flow Control characteristic as provided by a discovery. */ + uint16_t mlmr_c_flow_ctrl_cccd_handle; /**< Handle of CCCD of MLMR_C Flow Control characteristic as provided by a discovery. */ +} mlmr_c_handles_t; -/**@brief Goodix UART Service Client event. */ -typedef struct { - uint8_t conn_idx; /**< Connection index. */ - gus_c_evt_type_t evt_type; /**< GUS Client event type. */ - uint16_t length; /**< Length of event data. */ - uint8_t *p_data; /**< Pointer to event data. */ -} gus_c_evt_t; +/**@brief Multi Link Multi Role Service Client event. */ +typedef struct +{ + uint8_t conn_idx; /**< Connection index. */ + mlmr_c_evt_type_t evt_type; /**< MLMR Client event type. */ + uint16_t length; /**< Length of event data. */ + uint8_t *p_data; /**< Pointer to event data. */ +} mlmr_c_evt_t; /** @} */ /** - * @defgroup GUS_C_TYPEDEF Typedefs + * @defgroup MLMR_C_TYPEDEF Typedefs * @{ */ -/**@brief Goodix UART Service Client event handler type. */ -typedef void (* gus_c_evt_handler_t)(gus_c_evt_t *p_evt); +/**@brief Multi Link Multi Role Service Client event handler type. */ +typedef void (* mlmr_c_evt_handler_t)(mlmr_c_evt_t *p_evt); /** @} */ /** - * @defgroup GUS_C_FUNCTION Functions + * @defgroup MLMR_C_FUNCTION Functions * @{ */ /** ***************************************************************************************** - * @brief Register GUS Client event handler. + * @brief Register MLMR Client event handler. * - * @param[in] evt_handler: Goodix UART Service Client event handler. + * @param[in] evt_handler: Multi Link Multi Role Service Client event handler. * * @return Result of initialization. ***************************************************************************************** */ -sdk_err_t gus_client_init(gus_c_evt_handler_t evt_handler); +sdk_err_t mlmr_client_init(mlmr_c_evt_handler_t evt_handler); /** ***************************************************************************************** - * @brief Discovery GUS on peer. + * @brief Discovery MLMR_C on peer. * * @param[in] conn_idx: Index of connection. * * @return Operation result. ***************************************************************************************** */ -sdk_err_t gus_c_disc_srvc_start(uint8_t conn_idx); +sdk_err_t mlmr_c_disc_srvc_start(uint8_t conn_idx); /** ***************************************************************************************** - * @brief Enable or disable peer GUS Tx characteristic notify. + * @brief Enable or disable peer MLMR_C Tx characteristic notify. * * @param[in] conn_idx: Connection index. * @param[in] is_enable: Enable or disable ths Tx notify. @@ -179,11 +186,11 @@ sdk_err_t gus_c_disc_srvc_start(uint8_t conn_idx); * @return Operation result. ***************************************************************************************** */ -sdk_err_t gus_c_tx_notify_set(uint8_t conn_idx, bool is_enable); +sdk_err_t mlmr_c_tx_notify_set(uint8_t conn_idx, bool is_enable); /** ***************************************************************************************** - * @brief Enable or disable peer device GUS flow control notify. + * @brief Enable or disable peer device MLMR_C flow control notify. * * @param[in] conn_idx: Connection index. * @param[in] is_enable: Enable or disable ths Tx notify. @@ -191,7 +198,7 @@ sdk_err_t gus_c_tx_notify_set(uint8_t conn_idx, bool is_enable); * @return Operation result. ***************************************************************************************** */ -sdk_err_t gus_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable); +sdk_err_t mlmr_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable); /** ***************************************************************************************** @@ -204,19 +211,19 @@ sdk_err_t gus_c_flow_ctrl_notify_set(uint8_t conn_idx, bool is_enable); * @return Operation result. ***************************************************************************************** */ -sdk_err_t gus_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); +sdk_err_t mlmr_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length); /** ***************************************************************************************** - * @brief Send GUS Client Rx flow control state to peer device + * @brief Send MLMR Client Rx flow control state to peer device * * @param[in] conn_idx: Connection index. - * @param[in] flow_ctrl: GUS client Rx flow control state. + * @param[in] flow_ctrl: MLMR client Rx flow control state. * - * @return Result of sending gus_c Rx flow control state. + * @return Result of sending mlmr_c Rx flow control state. ***************************************************************************************** */ -sdk_err_t gus_c_rx_flow_ctrl_set(uint8_t conn_idx, uint8_t flow_ctrl); +sdk_err_t mlmr_c_rx_flow_ctrl_set(uint8_t conn_idx, mlmr_c_flow_ctrl_state_t flow_ctrl); /** @} */ #endif /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/BUILD.gn new file mode 100644 index 0000000..a0d5223 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ndcs") { + sources = [ "ndcs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.c index 183786e..a5c83d5 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.c @@ -44,13 +44,13 @@ #include "ble_prf_utils.h" #include "utility.h" -#define INDEX_7 7 /* * ENUMERATIONS **************************************************************************************** */ /**@brief Next DST Change Service Attributes Indexes. */ -enum { +enum +{ // Next DST Change Service NDCS_IDX_SVC, @@ -66,103 +66,45 @@ enum { ***************************************************************************************** */ /**@brief Next DST Change Service environment variable. */ -struct ndcs_env_t { - uint16_t char_mask; /**< Mask of supported characteristics. */ - uint16_t start_hdl; /**< Next DST Change Service start handle. */ - ndcs_time_dst_t time_with_dst; /**< Time with DST value. */ +struct ndcs_env_t +{ + uint16_t char_mask; /**< Mask of supported characteristics. */ + uint16_t start_hdl; /**< Next DST Change Service start handle. */ + ndcs_time_dst_t time_with_dst; /**< Time with DST value. */ + ble_gatts_create_db_t ndcs_gatts_db; /**< Next DST Change Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t ndcs_init(void); -static void ndcs_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void ndcs_time_with_dst_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); +static void ndcs_time_with_dst_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct ndcs_env_t s_ndcs_env; +static const uint8_t s_ndcs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_NEXT_DST_CHANGE); /**@brief Full NDCS Database Description - Used to add attributes into the database. */ -static const attm_desc_t ndcs_attr_tab[NDCS_IDX_NB] = { +static const ble_gatts_attm_desc_t ndcs_attr_tab[NDCS_IDX_NB] = +{ // NDCS Service Declaration - [NDCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [NDCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Time with DST Characteristic Declaration - [NDCS_IDX_TIME_DST_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [NDCS_IDX_TIME_DST_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Time with DST Characteristic Declaration value - [NDCS_IDX_TIME_DST_VAL] = { - BLE_ATT_CHAR_TIME_WITH_DST, - READ_PERM(AUTH), - ATT_VAL_LOC_USER, - NDCS_TIME_WITH_DST_VAL_LEN - }, -}; - -/**@brief NDCS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t ndcs_tack_cbs = { - (prf_init_func_t) ndcs_init, - NULL, - NULL -}; - -/**@brief NDCS Task Callbacks. */ -static gatts_prf_cbs_t ndcs_cb_func = { - ndcs_read_att_cb, - NULL, - NULL, - NULL -}; - -/**@brief NDCS Information. */ -static const prf_server_info_t ndcs_prf_info = { - .max_connection_nb = NDCS_CONNECTION_MAX, - .manager_cbs = &ndcs_tack_cbs, - .gatts_prf_cbs = &ndcs_cb_func + [NDCS_IDX_TIME_DST_VAL] = {BLE_ATT_CHAR_TIME_WITH_DST, + BLE_GATTS_READ_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + NDCS_TIME_WITH_DST_VAL_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Next DST Change service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t ndcs_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t ndcs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_NEXT_DST_CHANGE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = ndcs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_ndcs_env.char_mask); - gatts_db.max_nb_attr = NDCS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = ndcs_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_ndcs_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -171,9 +113,9 @@ static sdk_err_t ndcs_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void ndcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void ndcs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_ndcs_env.start_hdl, @@ -182,8 +124,10 @@ static void ndcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { - case NDCS_IDX_TIME_DST_VAL: { + switch (tab_index) + { + case NDCS_IDX_TIME_DST_VAL: + { uint8_t encoded_buffer[NDCS_TIME_WITH_DST_VAL_LEN]; ndcs_time_with_dst_read_handler(&cfm, encoded_buffer); break; @@ -206,29 +150,38 @@ static void ndcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para * @param[out] p_encode_buffer: Pointer to encoded data will be written. ***************************************************************************************** */ -static void ndcs_time_with_dst_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) +static void ndcs_time_with_dst_read_handler(ble_gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer) { prf_pack_date_time(p_encode_buffer, &s_ndcs_env.time_with_dst.date_time); - p_encode_buffer[INDEX_7] = s_ndcs_env.time_with_dst.dst_offset; + p_encode_buffer[7] = s_ndcs_env.time_with_dst.dst_offset; p_cfm->length = NDCS_TIME_WITH_DST_VAL_LEN; p_cfm->value = p_encode_buffer; } +static void ndcs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + ndcs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ void ndcs_day_time_update(prf_date_time_t *p_day_time) { - uint8_t ret; - - ret = memcpy_s(&s_ndcs_env.time_with_dst.date_time, sizeof(prf_date_time_t), - p_day_time, sizeof(prf_date_time_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_ndcs_env.time_with_dst.date_time, p_day_time, sizeof(prf_date_time_t)); } void ndcs_dst_offset_update(ndcs_dst_offset_t dst_offset) @@ -240,5 +193,15 @@ sdk_err_t ndcs_service_init(uint8_t char_mask) { s_ndcs_env.char_mask = char_mask; - return ble_server_prf_add(&ndcs_prf_info); + s_ndcs_env.start_hdl = PRF_INVALID_HANDLE; + + s_ndcs_env.ndcs_gatts_db.shdl = &s_ndcs_env.start_hdl; + s_ndcs_env.ndcs_gatts_db.uuid = s_ndcs_svc_uuid; + s_ndcs_env.ndcs_gatts_db.attr_tab_cfg = (uint8_t *)&(s_ndcs_env.char_mask); + s_ndcs_env.ndcs_gatts_db.max_nb_attr = NDCS_IDX_NB; + s_ndcs_env.ndcs_gatts_db.srvc_perm = 0; + s_ndcs_env.ndcs_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_ndcs_env.ndcs_gatts_db.attr_tab.attr_tab_16 = ndcs_attr_tab; + + return ble_gatts_prf_add(&s_ndcs_env.ndcs_gatts_db, ndcs_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.h index cc15099..be68521 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ndcs/ndcs.h @@ -49,27 +49,26 @@ * @details The Next DST Change Service exposes the Time with DST characteristic. This module * implements the Next DST Change Service with Time with DST characteristics. * - * The application must call \ref ndcs_service_init() to add Next DST Change Service + * The application must call \ref ndcs_service_init() to add Next DST Change Service * and Time with DST characteristic to the BLE Stack database. */ #ifndef __NDCS_H__ #define __NDCS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup NDCS_MACRO Defines * @{ */ -#define NDCS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of NDCS connections. */ -#define NDCS_TIME_WITH_DST_VAL_LEN 8 /**< Length of Time with DST value. */ -#define NDCS_CHAR_FULL 0x07 /**< Bit mask for mandatory characteristic in NDCS. */ +#define NDCS_CONNECTION_MAX 10 /**< Maximum number of NDCS connections. */ +#define NDCS_TIME_WITH_DST_VAL_LEN 8 /**< Length of Time with DST value. */ +#define NDCS_CHAR_FULL 0x07 /**< Bit mask for mandatory characteristic in NDCS. */ /** @} */ /** @@ -77,7 +76,8 @@ * @{ */ /**@brief Daylight Saving Time Offset. */ -typedef enum { +typedef enum +{ NDCS_DST_OFFSET_STANDAR_TIME, /**< Standard Time. */ NDCS_DST_OFFSET_HALF_HOUR, /**< Half An Hour Daylight Time (+0.5h). */ NDCS_DST_OFFSET_DAYLIGHT_TIME, /**< Daylight Time (+1h). */ @@ -90,7 +90,8 @@ typedef enum { * @{ */ /**@brief Time with DST. */ -typedef struct { +typedef struct +{ prf_date_time_t date_time; /**< Date Time. */ ndcs_dst_offset_t dst_offset; /**< Daylight Saving Time Offset. */ } ndcs_time_dst_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/BUILD.gn new file mode 100644 index 0000000..23ecada --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("otas") { + sources = [ "otas.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.c index 71c06a0..1c14cf7 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.c @@ -35,28 +35,28 @@ ***************************************************************************************** */ -/* -* INCLUDE FILES -**************************************************************************************** -*/ + /* + * INCLUDE FILES + **************************************************************************************** + */ #include "otas.h" #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" +#include "dfu_port.h" +#include "hal_flash.h" +#include "app_log.h" + /* * DEFINES **************************************************************************************** */ /**@brief Proprietary UUIDs. */ -#define OTA_SERVICE_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, - 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x04, 0xED, 0xA6} -#define OTA_SERVICE_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, - 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x04, 0xED, 0xA6} -#define OTA_SERVICE_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, - 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x04, 0xED, 0xA6} -#define OTA_SERVICE_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, - 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x04, 0xED, 0xA6} +#define OTA_SERVICE_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x04, 0xED, 0xA6} +#define OTA_SERVICE_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x04, 0xED, 0xA6} +#define OTA_SERVICE_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x04, 0xED, 0xA6} +#define OTA_SERVICE_CTRL_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x04, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -68,7 +68,8 @@ **************************************************************************************** */ /**@brief OTA Service Attributes Indexes. */ -enum otas_attr_idx_tag { +enum otas_attr_idx_tag +{ OTAS_IDX_SVC, OTAS_IDX_TX_CHAR, @@ -78,6 +79,7 @@ enum otas_attr_idx_tag { OTAS_IDX_RX_VAL, OTAS_IDX_CTRL_CHAR, OTAS_IDX_CTRL_VAL, + OTAS_IDX_CTRL_CFG, OTAS_IDX_NB, }; @@ -86,138 +88,69 @@ enum otas_attr_idx_tag { * STRUCT DEFINE **************************************************************************************** */ -struct otas_env_t { - otas_init_t otas_init; - uint16_t ntf_cfg[OTAS_CONNECTION_MAX]; - uint16_t start_hdl; +struct otas_env_t +{ + otas_init_t otas_init; + uint16_t tx_ntf_cfg[OTAS_CONNECTION_MAX]; + uint16_t ctrl_pt_ind_cfg[OTAS_CONNECTION_MAX]; + uint16_t start_hdl; + ble_gatts_create_db_t otas_att_db; }; - -/* -* LOCAL FUNCTION DECLARATION -**************************************************************************************** -*/ -static sdk_err_t otas_init(void); -static void otas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void otas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void otas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void otas_gatts_cmpl_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - +struct otas_env_t s_otas_env; /* * LOCAL VARIABLE DEFINITIONS **************************************************************************************** */ -static struct otas_env_t s_otas_env; -static uint16_t s_char_mask = 0xff; +static uint16_t s_char_mask = 0x1ff; +static const uint8_t s_otas_svc_uuid[] = {BLE_UUID_OTA_SERVICE}; + /**@brief Full OTAS Database Description - Used to add attributes into the database. */ -static const attm_desc_128_t otas_att_db[OTAS_IDX_NB] = { +static const ble_gatts_attm_desc_128_t otas_att_db[OTAS_IDX_NB] = { // OTA service - [OTAS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [OTAS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // OTA TX Characteristic Declaration - [OTAS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [OTAS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC,BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // OTA TX Characteristic Value - [OTAS_IDX_TX_VAL] = { - OTA_SERVICE_TX_UUID, - NOTIFY_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - OTAS_MAX_DATA_LEN - }, - + [OTAS_IDX_TX_VAL] = {OTA_SERVICE_TX_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + OTAS_MAX_DATA_LEN}, // OTA TX Characteristic - Client Characteristic Configuration Descriptor - [OTAS_IDX_TX_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC| WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [OTAS_IDX_TX_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC| BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // OTA RX Characteristic Declaration - [OTAS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0 }, + [OTAS_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // OTA RX Characteristic Value - [OTAS_IDX_RX_VAL] = { - OTA_SERVICE_RX_UUID, - WRITE_CMD_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - OTAS_MAX_DATA_LEN - }, + [OTAS_IDX_RX_VAL] = {OTA_SERVICE_RX_UUID, + BLE_GATTS_WRITE_CMD_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + OTAS_MAX_DATA_LEN}, // OTA CTRL Characteristic Declaration - [OTAS_IDX_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [OTAS_IDX_CTRL_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, - // OTA CTRL Characteristic Value - [OTAS_IDX_CTRL_VAL] = { - OTA_SERVICE_CTRL_UUID, - WRITE_CMD_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - sizeof(uint32_t) - }, -}; - -/**@brief OTA Server Task interface required by profile manager. */ -static ble_prf_manager_cbs_t otas_tack_cbs = { - (prf_init_func_t) otas_init, - NULL, - NULL, -}; - -/**@brief OTA Server Task Callbacks. */ -static gatts_prf_cbs_t otas_cb_func = { - otas_read_att_cb, - otas_write_att_cb, - NULL, - otas_gatts_cmpl_cb, - otas_cccd_set_cb -}; - -/**@brief OTA Server Information. */ -static const prf_server_info_t otas_prf_info = { - .max_connection_nb = OTAS_CONNECTION_MAX, - .manager_cbs = &otas_tack_cbs, - .gatts_prf_cbs =&otas_cb_func + // OTA CTRL Characteristic Value BLE_GATTS_WRITE_CMD_PERM_UNSEC + [OTAS_IDX_CTRL_VAL] = {OTA_SERVICE_CTRL_UUID, + BLE_GATTS_WRITE_CMD_PERM_UNSEC | BLE_GATTS_INDICATE_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + sizeof(uint32_t)}, + // OTA CTRL Characteristic - Client Characteristic Configuration Descriptor + [OTAS_IDX_CTRL_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS **************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize OTA service create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t otas_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t otas_svc_uuid[] = OTA_SERVICE_UUID; - sdk_err_t error_code = SDK_SUCCESS; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = otas_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t*)&s_char_mask; - gatts_db.max_nb_attr = OTAS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = otas_att_db; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_otas_env.start_hdl = *(gatts_db.shdl); - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -226,21 +159,27 @@ static sdk_err_t otas_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void otas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void otas_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = 0; + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; tab_index = prf_find_idx_by_handle(handle, s_otas_env.start_hdl, OTAS_IDX_NB, (uint8_t*)&s_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch(tab_index) + { case OTAS_IDX_TX_CFG: cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)(&s_otas_env.ntf_cfg[conn_idx]); + cfm.value = (uint8_t *)(&s_otas_env.tx_ntf_cfg[conn_idx]); + break; + + case OTAS_IDX_CTRL_CFG: + cfm.length = sizeof(uint16_t); + cfm.value = (uint8_t *)(&s_otas_env.ctrl_pt_ind_cfg[conn_idx]); break; default: @@ -249,7 +188,33 @@ static void otas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para break; } - ble_gatts_read_cfm(conn_idx, &cfm); + ble_gatts_read_cfm(conn_idx,&cfm); +} + +/** + ***************************************************************************************** + * @brief Handles control point cmd. + * + * @param[in] p_data: Pointer to the cmd data. + * @param[in] length: Length of the cmd data. + ***************************************************************************************** + */ +static void otas_control_point_handler(uint8_t conn_idx, uint8_t *p_data, uint16_t length) +{ + otas_evt_t event; + + event.conn_idx = conn_idx; + event.evt_type = OTAS_EVT_INVALID; + + if (le32toh(p_data) == OTAS_CTRL_PT_OP_DFU_ENTER) + { + event.evt_type = OTAS_EVT_DFU_TASK_ENTER; + } + + if(s_otas_env.otas_init.evt_handler != NULL && event.evt_type != OTAS_EVT_INVALID) + { + s_otas_env.otas_init.evt_handler(&event); + } } /** @@ -260,22 +225,24 @@ static void otas_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void otas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void otas_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - gatts_write_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = 0; - uint16_t cccd_value = 0; - otas_evt_t event; + ble_gatts_write_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; + uint16_t cccd_value = 0; + otas_evt_t event; tab_index = prf_find_idx_by_handle(handle, s_otas_env.start_hdl, OTAS_IDX_NB, (uint8_t*)&s_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch(tab_index) + { case OTAS_IDX_RX_VAL: - if (s_otas_env.otas_init.evt_handler != NULL) { + if(s_otas_env.otas_init.evt_handler != NULL) + { event.conn_idx = conn_idx; event.evt_type = OTAS_EVT_RX_RECEIVE_DATA; event.p_data = (uint8_t*)p_param->value; @@ -283,29 +250,37 @@ static void otas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa s_otas_env.otas_init.evt_handler(&event); } - break; case OTAS_IDX_TX_CFG: cccd_value = le16toh(&p_param->value[0]); - if (s_otas_env.otas_init.evt_handler != NULL) { + if(s_otas_env.otas_init.evt_handler != NULL) + { event.conn_idx = conn_idx; event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ - OTAS_EVT_TX_NOTIFICATION_ENABLED : - OTAS_EVT_TX_NOTIFICATION_DISABLED; + OTAS_EVT_TX_NOTIFICATION_ENABLED : + OTAS_EVT_TX_NOTIFICATION_DISABLED; s_otas_env.otas_init.evt_handler(&event); } - s_otas_env.ntf_cfg[conn_idx] = cccd_value; + s_otas_env.tx_ntf_cfg[conn_idx] = cccd_value; + break; + + case OTAS_IDX_CTRL_CFG: + cccd_value = le16toh(&p_param->value[0]); + if(s_otas_env.otas_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_IND) ?\ + OTAS_EVT_CTRL_PT_INDICATION_ENABLED : + OTAS_EVT_CTRL_PT_INDICATION_DISABLED; + + s_otas_env.otas_init.evt_handler(&event); + } + s_otas_env.ctrl_pt_ind_cfg[conn_idx] = cccd_value; break; case OTAS_IDX_CTRL_VAL: - if (le32toh(&p_param->value[0]) == OTAS_CTRL_ENTER_DFU) { - if (s_otas_env.otas_init.evt_handler != NULL) { - event.conn_idx = conn_idx; - event.evt_type = OTAS_EVT_DFU_MODE_ENTER; - s_otas_env.otas_init.evt_handler(&event); - } - } + otas_control_point_handler(conn_idx, p_param->value, p_param->length); break; default: @@ -313,7 +288,7 @@ static void otas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa break; } - ble_gatts_write_cfm(conn_idx, &cfm); + ble_gatts_write_cfm(conn_idx,&cfm); } /** @@ -325,29 +300,43 @@ static void otas_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void otas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void otas_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; otas_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } tab_index = prf_find_idx_by_handle(handle, s_otas_env.start_hdl, OTAS_IDX_NB, (uint8_t*)&s_char_mask); - switch (tab_index) { + switch(tab_index) + { case OTAS_IDX_TX_CFG: - if (s_otas_env.otas_init.evt_handler != NULL) { + if(s_otas_env.otas_init.evt_handler != NULL) + { event.conn_idx = conn_idx; event.evt_type = (cccd_value == PRF_CLI_START_NTF) ?\ - OTAS_EVT_TX_NOTIFICATION_ENABLED : - OTAS_EVT_TX_NOTIFICATION_DISABLED; + OTAS_EVT_TX_NOTIFICATION_ENABLED : + OTAS_EVT_TX_NOTIFICATION_DISABLED; s_otas_env.otas_init.evt_handler(&event); } - s_otas_env.ntf_cfg[conn_idx] = cccd_value; + s_otas_env.tx_ntf_cfg[conn_idx] = cccd_value; break; + case OTAS_IDX_CTRL_CFG: + if(s_otas_env.otas_init.evt_handler != NULL) + { + event.conn_idx = conn_idx; + event.evt_type = (cccd_value == PRF_CLI_START_IND) ?\ + OTAS_EVT_CTRL_PT_INDICATION_ENABLED : + OTAS_EVT_CTRL_PT_INDICATION_DISABLED; + s_otas_env.otas_init.evt_handler(&event); + } + s_otas_env.ctrl_pt_ind_cfg[conn_idx] = cccd_value; + default: break; } @@ -363,14 +352,17 @@ static void otas_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va * @return If the event was consumed or not. ***************************************************************************************** */ -static void otas_gatts_cmpl_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void otas_ntf_cplt_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_otas_env.otas_init.evt_handler != NULL) { + if(s_otas_env.otas_init.evt_handler != NULL) + { otas_evt_t event; event.conn_idx = conn_idx; - if (status == BLE_SUCCESS) { - if (p_ntf_ind->type == BLE_GATT_NOTIFICATION) { + if(status == BLE_SUCCESS) + { + if(p_ntf_ind->type == BLE_GATT_NOTIFICATION) + { event.evt_type = OTAS_EVT_NOTIFY_COMPLETE; s_otas_env.otas_init.evt_handler(&event); } @@ -378,16 +370,44 @@ static void otas_gatts_cmpl_cb(uint8_t conn_idx, uint8_t status, const ble_gatts } } +static void otas_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + otas_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + otas_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + otas_ntf_cplt_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + otas_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ -sdk_err_t otas_notify_tx_data(uint8_t conn_idx, uint8_t* p_data, uint16_t len) +sdk_err_t otas_notify_tx_data(uint8_t conn_idx,uint8_t* p_data,uint16_t len) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_cmd; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + ble_gatts_noti_ind_t send_cmd; - if (s_otas_env.ntf_cfg[conn_idx] == PRF_CLI_START_NTF) { + if(s_otas_env.tx_ntf_cfg[conn_idx] == PRF_CLI_START_NTF) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; send_cmd.handle = prf_find_handle_by_idx(OTAS_IDX_TX_VAL, s_otas_env.start_hdl, (uint8_t*)&s_char_mask); @@ -395,7 +415,7 @@ sdk_err_t otas_notify_tx_data(uint8_t conn_idx, uint8_t* p_data, uint16_t len) send_cmd.length = len; send_cmd.value = p_data; // send notification to peer device - error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); + error_code = ble_gatts_noti_ind(conn_idx,&send_cmd); } return error_code; } @@ -403,11 +423,30 @@ sdk_err_t otas_notify_tx_data(uint8_t conn_idx, uint8_t* p_data, uint16_t len) sdk_err_t otas_service_init(otas_init_t *p_otas_init) { - if (p_otas_init == NULL) { + if (NULL == p_otas_init) + { return SDK_ERR_POINTER_NULL; } s_otas_env.otas_init.evt_handler = p_otas_init->evt_handler; - return ble_server_prf_add(&otas_prf_info); + memset(&s_otas_env.otas_att_db, 0, sizeof(ble_gatts_create_db_t)); + + s_otas_env.start_hdl = PRF_INVALID_HANDLE; + s_otas_env.otas_att_db.shdl = &s_otas_env.start_hdl; + s_otas_env.otas_att_db.uuid = s_otas_svc_uuid; + s_otas_env.otas_att_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_otas_env.otas_att_db.max_nb_attr = OTAS_IDX_NB; + s_otas_env.otas_att_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_otas_env.otas_att_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_otas_env.otas_att_db.attr_tab.attr_tab_128 = otas_att_db; + + return ble_gatts_prf_add(&s_otas_env.otas_att_db, otas_ble_evt_handler); } + +uint16_t otas_service_start_handle_get(void) +{ + return s_otas_env.start_hdl; +} + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.h index 5c0dbea..6fc6335 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas/otas.h @@ -3,7 +3,7 @@ * * @file otas.h * - * @brief OTA Service API + * @brief Over The Air Service API * **************************************************************************************** * @attention @@ -46,8 +46,8 @@ * @{ * @brief Definitions and prototypes for the OTAS interface. * - * @details The OTA Service exposes the state of a battery within a device. - * This module implements the Battery Service with the Battery Level + * @details The OTA Service is a customized service with Tx, Rx and Flow Control + * characteristics. This module implements the Battery Service with the Battery Level * characteristic. After @ref otas_init_t variable is initialized, the * developer shall call @ref otas_service_init() to add the OTA * Service and RX, TX, Control characteristic to the BLE stack database. @@ -63,33 +63,53 @@ * INCLUDE FILES **************************************************************************************** */ -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include "flash_scatter_config.h" /** * @defgroup OTAS_MACRO Defines * @{ */ -#define OTAS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of OTA Service connections. */ -#define OTAS_MAX_DATA_LEN 244 /**< Maximum length of OTAS characteristic. */ -#define BLE_UUID_OTA_SERVICE 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x01, 0x04, 0xED, 0xA6 /**< The UUID of OTA Service for setting advertising data. */ -#define OTAS_CTRL_ENTER_DFU 0x474f4f44 /**< OTAS enter DFU control. */ +#define OTAS_CONNECTION_MAX 10 /**< Maximum number of OTA Service connections. */ +#define OTAS_MAX_DATA_LEN 244 /**< Maximum length of OTAS characteristic. */ +#define OTAS_VERSION 0x02 /**< The OTA VERSION. */ +#define BLE_UUID_OTA_SERVICE 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x04, 0xED, 0xA6 /**< The UUID of OTA Service for setting advertising data. */ /** @} */ /** * @defgroup OTA_ENUM Enumerations * @{ */ +/**@brief OTA Service dfu mode.*/ +typedef enum +{ + OTAS_DFU_MODE_RESERVED, /**< Reserved for future use. */ + OTAS_DFU_MODE_COPY_UPGRADE, /**< OTAS Copy DFU mode (Double bank, Background). */ + OTAS_DFU_MODE_NON_COPY_UPGRADE, /**< OTAS Non-Copy DFU mode (Single bank, Non-background). */ +} otas_dfu_mode_t; + +/**@brief OTA Service Control Point Operation Code.*/ +typedef enum +{ + OTAS_CTRL_PT_OP_RESERVED, /**< Reserved for future use. */ + OTAS_CTRL_PT_OP_DFU_ENTER = 0x474f4f44, /**< OTAS task enter Operation Code.*/ + OTAS_CTRL_PT_OP_RSP_CODE = 0x10, /**< Response code. */ +} otas_ctrl_pt_op_code_t; + /**@brief OTA Service event type. */ -typedef enum { - OTAS_EVT_INVALID, - OTAS_EVT_TX_NOTIFICATION_ENABLED, - OTAS_EVT_TX_NOTIFICATION_DISABLED, - OTAS_EVT_RX_RECEIVE_DATA, - OTAS_EVT_NOTIFY_COMPLETE, - OTAS_EVT_DFU_MODE_ENTER, +typedef enum +{ + OTAS_EVT_INVALID, /**< Invalid event for ota service. */ + OTAS_EVT_TX_NOTIFICATION_ENABLED, /**< tx notification enable event for ota service. */ + OTAS_EVT_TX_NOTIFICATION_DISABLED, /**< tx notification disable event for ota service. */ + OTAS_EVT_CTRL_PT_INDICATION_ENABLED, /**< control point indication enable event for ota service. */ + OTAS_EVT_CTRL_PT_INDICATION_DISABLED, /**< control point indication disable event for ota service. */ + OTAS_EVT_RX_RECEIVE_DATA, /**< rx receive data event for ota service. */ + OTAS_EVT_NOTIFY_COMPLETE, /**< notify complete event for ota service. */ + OTAS_EVT_DFU_TASK_ENTER, /**< set dfu task enter event for ota service. */ + OTAS_EVT_DFU_MODE_SET, /**< set dfu mode for ota service. */ } otas_evt_type_t; /** @} */ @@ -98,11 +118,13 @@ typedef enum { * @{ */ /**@brief OTA Service event. */ -typedef struct { - otas_evt_type_t evt_type; /**< The OTAS event. */ - uint8_t conn_idx; /**< Index of connection. */ - uint8_t *p_data; /**< Pointer to data. */ - uint16_t length; /**< Length of data. */ +typedef struct +{ + otas_evt_type_t evt_type; /**< The OTAS event. */ + uint8_t conn_idx; /**< Index of connection. */ + uint8_t *p_data; /**< Pointer to data. */ + uint16_t length; /**< Length of data. */ + otas_dfu_mode_t dfu_mode; /**< OTA Service dfu mode. */ } otas_evt_t; /** @} */ @@ -112,9 +134,6 @@ typedef struct { */ /**@brief OTA Service event handler type. */ typedef void (*otas_evt_handler_t)(otas_evt_t *p_evt); - -/**@brief OTA Service function type. */ -typedef void (*function)(void); /** @} */ /** @@ -122,8 +141,9 @@ typedef void (*function)(void); * @{ */ /**@brief OTA Service initialization variable. */ -typedef struct { - otas_evt_handler_t evt_handler; /**< Handler to handle otas event. */ +typedef struct +{ + otas_evt_handler_t evt_handler; /**< Handler to handle otas event. */ } otas_init_t; /** @} */ @@ -143,7 +163,6 @@ typedef struct { */ sdk_err_t otas_service_init(otas_init_t *p_otas_init); - /** ***************************************************************************************** * @brief Send data to peer device @@ -155,9 +174,19 @@ sdk_err_t otas_service_init(otas_init_t *p_otas_init); * @return Result of notify and indicate value ***************************************************************************************** */ -sdk_err_t otas_notify_tx_data(uint8_t conn_idx, uint8_t *p_data, uint16_t length); +sdk_err_t otas_notify_tx_data(uint8_t conn_idx, uint8_t *p_data,uint16_t length); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the ots service start handle . + * + * @return The ots service start handle. + ***************************************************************************************** + */ +uint16_t otas_service_start_handle_get(void); /** @} */ #endif + /** @} */ /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/BUILD.gn new file mode 100644 index 0000000..5013965 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("otas_c") { + sources = [ "otas_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.c index 194d8eb..45e3a44 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.c @@ -42,63 +42,37 @@ #include "otas_c.h" #include -#define ATTR_VALUE_LEN 2 -#define UUID_LEN_16 16 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief OTA Service Client environment variable. */ -struct otas_c_env_t { - otas_c_handles_t handles; /**< Handles of OTA characteristics which will be got for peer. */ - otas_c_evt_handler_t evt_handler; /**< Handler of OTA client event */ - uint8_t prf_id; /**< OTA Client profile id. */ +struct otas_c_env_t +{ + otas_c_handles_t handles; /**< Handles of OTA characteristics which will be got for peer. */ + otas_c_evt_handler_t evt_handler; /**< Handler of OTA client event */ + uint8_t prf_id; /**< OTA Client profile id. */ + ble_gatts_create_db_t otas_c_gatts_db; /**< OTA Client attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static void otas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void otas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void otas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct otas_c_env_t s_otas_c_env; -static uint8_t s_otas_uuid[16] = OTAS_SVC_UUID; -static uint8_t s_otas_tx_char_uuid[16] = OTAS_TX_CHAR_UUID; -static uint8_t s_otas_rx_char_uuid[16] = OTAS_RX_CHAR_UUID; -static uint8_t s_otas_ctrl_char_uuid[16] = OTAS_CTRL_CHAR_UUID; - - -/**@brief OTA Client interface required by profile manager. */ -static ble_prf_manager_cbs_t otas_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief OTA GATT Client Callbacks. */ -static gattc_prf_cbs_t otas_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - otas_c_att_write_cb, - otas_c_att_ntf_ind_cb, - otas_c_srvc_browse_cb, - NULL, -}; - -/**@brief OTA Client Information. */ -static const prf_client_info_t otas_c_prf_info = { - .max_connection_nb = OTAS_C_CONNECTION_MAX, - .manager_cbs = &otas_c_mgr_cbs, - .gattc_prf_cbs = &otas_c_gattc_cbs +static uint8_t s_otas_uuid[16] = OTAS_SVC_UUID; +static uint8_t s_otas_tx_char_uuid[16] = OTAS_TX_CHAR_UUID; +static uint8_t s_otas_rx_char_uuid[16] = OTAS_RX_CHAR_UUID; +static uint8_t s_otas_ctrl_char_uuid[16] = OTAS_CTRL_CHAR_UUID; +static ble_uuid_t s_otas_c_service_uuid = +{ + .uuid_len = 16, + .uuid = s_otas_uuid, }; /* @@ -114,7 +88,8 @@ static const prf_client_info_t otas_c_prf_info = { */ static void otas_c_evt_handler_execute(otas_c_evt_t *p_evt) { - if (s_otas_c_env.evt_handler != NULL && OTAS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_otas_c_env.evt_handler && OTAS_C_EVT_INVALID != p_evt->evt_type) + { s_otas_c_env.evt_handler(p_evt); } } @@ -128,22 +103,27 @@ static void otas_c_evt_handler_execute(otas_c_evt_t *p_evt) * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void otas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void otas_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { otas_c_evt_t otas_c_evt; otas_c_evt.conn_idx = conn_idx; otas_c_evt.evt_type = OTAS_C_EVT_INVALID; - if (handle == s_otas_c_env.handles.otas_tx_cccd_handle) { + if (handle == s_otas_c_env.handles.otas_tx_cccd_handle) + { otas_c_evt.evt_type = (BLE_SUCCESS == status) ? \ OTAS_C_EVT_TX_NTF_SET_SUCCESS : \ OTAS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_otas_c_env.handles.otas_ctrl_handle) { + } + else if (handle == s_otas_c_env.handles.otas_ctrl_handle) + { otas_c_evt.evt_type = (BLE_SUCCESS == status) ? \ OTAS_C_EVT_CTRL_SUCCESS : \ OTAS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_otas_c_env.handles.otas_rx_handle) { + } + else if (handle == s_otas_c_env.handles.otas_rx_handle) + { otas_c_evt.evt_type = (BLE_SUCCESS == status) ? \ OTAS_C_EVT_TX_CPLT : \ OTAS_C_EVT_WRITE_OP_ERR; @@ -161,7 +141,7 @@ static void otas_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handl * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void otas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void otas_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { otas_c_evt_t otas_c_evt; @@ -170,7 +150,8 @@ static void otas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p otas_c_evt.p_data = p_ntf_ind->p_value; otas_c_evt.length = p_ntf_ind->length; - if (p_ntf_ind->handle == s_otas_c_env.handles.otas_tx_handle) { + if (p_ntf_ind->handle == s_otas_c_env.handles.otas_tx_handle) + { otas_c_evt.evt_type = OTAS_C_EVT_PEER_DATA_RECEIVE; } @@ -186,7 +167,7 @@ static void otas_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void otas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void otas_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { otas_c_evt_t otas_c_evt; uint16_t handle_disc; @@ -194,120 +175,134 @@ static void otas_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_ga otas_c_evt.conn_idx = conn_idx; otas_c_evt.evt_type = OTAS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } + if (BLE_SUCCESS == status) + { + if (16 == p_browse_srvc->uuid_len && 0 == memcmp(p_browse_srvc->uuid, s_otas_uuid, 16)) + { + s_otas_c_env.handles.otas_srvc_start_handle = p_browse_srvc->start_hdl; + s_otas_c_env.handles.otas_srvc_end_handle = p_browse_srvc->end_hdl; - if (p_browse_srvc->uuid_len == UUID_LEN_16 && memcmp(p_browse_srvc->uuid, s_otas_uuid, UUID_LEN_16) == 0) { - s_otas_c_env.handles.otas_srvc_start_handle = p_browse_srvc->start_hdl; - s_otas_c_env.handles.otas_srvc_end_handle = p_browse_srvc->end_hdl; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + handle_disc = p_browse_srvc->start_hdl + i + 1; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - handle_disc = p_browse_srvc->start_hdl + i + 1; + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) + { + if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_rx_char_uuid, 16)) + { + s_otas_c_env.handles.otas_rx_handle = handle_disc; + } + else if (0 == (memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_tx_char_uuid, 16))) + { + s_otas_c_env.handles.otas_tx_handle = handle_disc; + s_otas_c_env.handles.otas_tx_cccd_handle = handle_disc + 1; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_ctrl_char_uuid, 16)) + { + s_otas_c_env.handles.otas_ctrl_handle = handle_disc; + } + } - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) { - if (memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_rx_char_uuid, UUID_LEN_16) == 0) { - s_otas_c_env.handles.otas_rx_handle = handle_disc; - } else if ((memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_tx_char_uuid, UUID_LEN_16) == 0)) { - s_otas_c_env.handles.otas_tx_handle = handle_disc; - s_otas_c_env.handles.otas_tx_cccd_handle = handle_disc + 1; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_otas_ctrl_char_uuid, UUID_LEN_16) == 0) { - s_otas_c_env.handles.otas_ctrl_handle = handle_disc; + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; } } - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; - } + otas_c_evt.evt_type = OTAS_C_EVT_DISCOVERY_COMPLETE; } - - otas_c_evt.evt_type = OTAS_C_EVT_DISCOVERY_COMPLETE; } otas_c_evt_handler_execute(&otas_c_evt); } +static void otas_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + otas_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + break; + + case BLE_GATTC_EVT_WRITE_RSP: + otas_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + otas_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t otas_client_init(otas_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_otas_c_env, sizeof(s_otas_c_env), 0, sizeof(s_otas_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_otas_c_env, 0, sizeof(s_otas_c_env)); s_otas_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&otas_c_prf_info, &s_otas_c_env.prf_id); + return ble_gattc_prf_add(&s_otas_c_service_uuid, otas_c_ble_evt_handler); } - sdk_err_t otas_c_disc_srvc_start(uint8_t conn_idx) { - const ble_uuid_t ths_uuid = { + const ble_uuid_t otas_uuid = + { .uuid_len = 16, .uuid = s_otas_uuid, }; - return ble_gattc_prf_services_browse(s_otas_c_env.prf_id, conn_idx, &ths_uuid); + return ble_gattc_services_browse(conn_idx, &otas_uuid); } - sdk_err_t otas_c_tx_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_tx_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_tx_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_otas_c_env.handles.otas_tx_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_otas_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_otas_c_env.handles.otas_tx_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t otas_c_ctrl_data_send(uint8_t conn_idx, uint32_t data) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_ctrl_handle) { + if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_ctrl_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_otas_c_env.handles.otas_ctrl_handle; - write_attr_value.length = sizeof(uint32_t); - write_attr_value.p_value = (uint8_t*)&data; - - return ble_gattc_prf_write_no_resp(s_otas_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_otas_c_env.handles.otas_ctrl_handle, sizeof(uint32_t), (uint8_t*)&data); } sdk_err_t otas_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_rx_handle) { + if (BLE_ATT_INVALID_HDL == s_otas_c_env.handles.otas_rx_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_otas_c_env.handles.otas_rx_handle; - write_attr_value.length = length; - write_attr_value.p_value = p_data; - - return ble_gattc_prf_write_no_resp(s_otas_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_otas_c_env.handles.otas_rx_handle, length, p_data); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.h index af2107a..b5664e0 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/otas_c/otas_c.h @@ -3,7 +3,7 @@ * * @file otas_c.h * - * @brief OTAS Client API + * @brief Over The Air Service Client API * ***************************************************************************************** * @attention @@ -55,32 +55,31 @@ #ifndef __OTAS_C_H__ #define __OTAS_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup OTAS_C_MACRO Defines * @{ */ -#define OTAS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of OTAS Client connections. */ +#define OTAS_C_CONNECTION_MAX 10 /**< Maximum number of OTAS Client connections. */ /** * @defgroup OTAS_UUID OTAS UUIDs * @{ * @brief OTAS service and characteristcs UUID. */ -#define OTAS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x01, 0x04, 0xED, 0xA6} /**< UUID of OTA Service. */ -#define OTAS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x02, 0x04, 0xED, 0xA6} /**< UUID of OTA TX Characteristic. */ -#define OTAS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x03, 0x04, 0xED, 0xA6} /**< UUID of OTA RX Characteristic. */ -#define OTAS_CTRL_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, \ - 0x04, 0x04, 0xED, 0xA6} /**< UUID of OTA Control Characteristic. */ +#define OTAS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x04, 0xED, 0xA6} /**< UUID of OTA Service. */ +#define OTAS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ + 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x04, 0xED, 0xA6} /**< UUID of OTA TX Characteristic. */ +#define OTAS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ + 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x04, 0xED, 0xA6} /**< UUID of OTA RX Characteristic. */ +#define OTAS_CTRL_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ + 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x04, 0xED, 0xA6} /**< UUID of OTA Control Characteristic. */ /** @} */ /** @} */ @@ -89,16 +88,16 @@ * @{ */ /**@brief OTA Service Client event type. */ -typedef enum { - OTAS_C_EVT_INVALID, /**< OTA Client invalid event. */ - OTAS_C_EVT_DISCOVERY_COMPLETE, /**< OTA Client has found THS service and its characteristics. */ - OTAS_C_EVT_DISCOVERY_FAIL, /**< OTA Client found THS service failed because of invalid operation \ - or no found at the peer. */ - OTAS_C_EVT_TX_NTF_SET_SUCCESS, /**< OTA Client has set peer Tx notify. */ - OTAS_C_EVT_CTRL_SUCCESS, /**< OTA Client has set control info. */ - OTAS_C_EVT_PEER_DATA_RECEIVE, /**< OTA Client has received data from peer. */ - OTAS_C_EVT_TX_CPLT, /**< OTA Client has sent something to a peer successfully. */ - OTAS_C_EVT_WRITE_OP_ERR, /**< Error occured when OTA Client writen to peer. */ +typedef enum +{ + OTAS_C_EVT_INVALID, /**< OTA Client invalid event. */ + OTAS_C_EVT_DISCOVERY_COMPLETE, /**< OTA Client has found THS service and its characteristics. */ + OTAS_C_EVT_DISCOVERY_FAIL, /**< OTA Client found THS service failed because of invalid operation or no found at the peer. */ + OTAS_C_EVT_TX_NTF_SET_SUCCESS, /**< OTA Client has set peer Tx notify. */ + OTAS_C_EVT_CTRL_SUCCESS, /**< OTA Client has set control info. */ + OTAS_C_EVT_PEER_DATA_RECEIVE, /**< OTA Client has received data from peer. */ + OTAS_C_EVT_TX_CPLT, /**< OTA Client has sent something to a peer successfully. */ + OTAS_C_EVT_WRITE_OP_ERR, /**< Error occured when OTA Client writen to peer. */ } otas_c_evt_type_t; /** @} */ @@ -107,17 +106,19 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { - uint16_t otas_srvc_start_handle; /**< OTA Service start handle. */ - uint16_t otas_srvc_end_handle; /**< OTA Service end handle. */ - uint16_t otas_tx_handle; /**< OTA tx characteristic handle which has been got from peer. */ - uint16_t otas_tx_cccd_handle; /**< OTA tx characteristic CCCD handle which has been got from peer. */ - uint16_t otas_rx_handle; /**< OTA rx characteristic handle which has been got from peer. */ - uint16_t otas_ctrl_handle; /**< OTA control characteristic handle which has been got from peer. */ +typedef struct +{ + uint16_t otas_srvc_start_handle; /**< OTA Service start handle. */ + uint16_t otas_srvc_end_handle; /**< OTA Service end handle. */ + uint16_t otas_tx_handle; /**< OTA tx characteristic handle which has been got from peer. */ + uint16_t otas_tx_cccd_handle; /**< OTA tx characteristic CCCD handle which has been got from peer. */ + uint16_t otas_rx_handle; /**< OTA rx characteristic handle which has been got from peer. */ + uint16_t otas_ctrl_handle; /**< OTA control characteristic handle which has been got from peer. */ } otas_c_handles_t; /**@brief OTA Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ otas_c_evt_type_t evt_type; /**< OTA client event type. */ uint8_t *p_data; /**< Pointer to event data. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/BUILD.gn new file mode 100644 index 0000000..1f0e315 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("pass") { + sources = [ "pass.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.c index 8eca9ff..7728a90 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.c @@ -49,7 +49,8 @@ **************************************************************************************** */ /**@brief Phone Alert Status Service Attributes Indexes. */ -enum { +enum +{ // Phone Alert Status Service PASS_IDX_SVC, @@ -75,136 +76,61 @@ enum { ***************************************************************************************** */ /**@brief Phone Alert Status Service environment variable. */ -struct pass_env_t { - pass_init_t pass_init; /**< Phone Alert Status Service initialization variables. */ - uint16_t start_hdl; /**< Phone Alert Status Service start handle. */ - uint16_t - alert_status_ntf_cfg[PASS_CONNECTION_MAX]; /**< The configuration of Alert Status Notification - which is configured by the peer devices. */ - uint16_t - ringer_setting_ntf_cfg[PASS_CONNECTION_MAX]; /**< The configuration of Ringer Setting Notification - which is configured by the peer devices. */ +struct pass_env_t +{ + pass_init_t pass_init; /**< Phone Alert Status Service initialization variables. */ + uint16_t start_hdl; /**< Phone Alert Status Service start handle. */ + uint16_t alert_status_ntf_cfg[PASS_CONNECTION_MAX]; /**< The configuration of Alert Status Notification which is configured by the peer devices. */ + uint16_t ringer_setting_ntf_cfg[PASS_CONNECTION_MAX]; /**< The configuration of Ringer Setting Notification which is configured by the peer devices. */ + ble_gatts_create_db_t pass_gatts_db; /**< Running Speed and Cadence Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t pass_init(void); -static void pass_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void pass_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); - - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct pass_env_t s_pass_env; +static const uint8_t s_pass_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_PHONE_ALERT_STATUS); /**@brief Full PASS Database Description - Used to add attributes into the database. */ -static const attm_desc_t pass_attr_tab[PASS_IDX_NB] = { +static const ble_gatts_attm_desc_t pass_attr_tab[PASS_IDX_NB] = +{ // Phone Alert Status Service Declaration - [PASS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [PASS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Status Characteristic - Declaration - [PASS_IDX_ALERT_STATUS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [PASS_IDX_ALERT_STATUS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Alert Status Characteristic - Value - [PASS_IDX_ALERT_STATUS_VAL] = { - BLE_ATT_CHAR_ALERT_STATUS, - NOTIFY_PERM_UNSEC | READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - PASS_ALERT_STATUS_VAL_LEN - }, + [PASS_IDX_ALERT_STATUS_VAL] = {BLE_ATT_CHAR_ALERT_STATUS, + BLE_GATTS_NOTIFY_PERM_UNSEC | BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + PASS_ALERT_STATUS_VAL_LEN}, // Alert Status Characteristic - Client Characteristic Configuration Descriptor - [PASS_IDX_ALERT_STATUS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [PASS_IDX_ALERT_STATUS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Ringer Setting Characteristic - Declaration - [PASS_IDX_RINGER_SET_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [PASS_IDX_RINGER_SET_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Ringer Setting Characteristic - Value - [PASS_IDX_RINGER_SET_VAL] = { - BLE_ATT_CHAR_RINGER_SETTING, - NOTIFY_PERM_UNSEC | READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - PASS_RINGER_SET_VAL_LEN - }, + [PASS_IDX_RINGER_SET_VAL] = {BLE_ATT_CHAR_RINGER_SETTING, + BLE_GATTS_NOTIFY_PERM_UNSEC | BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + PASS_RINGER_SET_VAL_LEN}, // Ringer Setting Characteristic - Client Characteristic Configuration Descriptor - [PASS_IDX_RINGER_SET_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, 0, 0}, + [PASS_IDX_RINGER_SET_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, 0, 0}, // Ringer Setting Characteristic - Declaration - [PASS_IDX_RINGER_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [PASS_IDX_RINGER_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Ringer Setting Characteristic - Value - [PASS_IDX_RINGER_CTRL_PT_VAL] = { - BLE_ATT_CHAR_RINGER_CNTL_POINT, - WRITE_CMD_PERM_UNSEC, - ATT_VAL_LOC_USER, - PASS_RINGER_CTRL_PT_VAL_LEN - }, -}; - -/**@brief PASS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t pass_task_cbs = { - (prf_init_func_t) pass_init, - NULL, - NULL, -}; - -/**@brief PASS Task Callbacks. */ -static gatts_prf_cbs_t pass_cb_func = { - pass_read_att_cb, - pass_write_att_cb, - NULL, - NULL, - pass_cccd_set_cb -}; - -/**@brief PASS Information. */ -static const prf_server_info_t pass_prf_info = { - .max_connection_nb = PASS_CONNECTION_MAX, - .manager_cbs = &pass_task_cbs, - .gatts_prf_cbs = &pass_cb_func, + [PASS_IDX_RINGER_CTRL_PT_VAL] = {BLE_ATT_CHAR_RINGER_CNTL_POINT, + BLE_GATTS_WRITE_CMD_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + PASS_RINGER_CTRL_PT_VAL_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Phone Alert Status Service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t pass_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t pass_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_PHONE_ALERT_STATUS); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = pass_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *) & (s_pass_env.pass_init.char_mask); - gatts_db.max_nb_attr = PASS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = pass_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_pass_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -213,18 +139,19 @@ static sdk_err_t pass_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void pass_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void pass_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, - s_pass_env.start_hdl, - PASS_IDX_NB, - (uint8_t *)&s_pass_env.pass_init.char_mask); + s_pass_env.start_hdl, + PASS_IDX_NB, + (uint8_t *)&s_pass_env.pass_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case PASS_IDX_ALERT_STATUS_VAL: cfm.length = PASS_ALERT_STATUS_VAL_LEN; cfm.value = &s_pass_env.pass_init.alert_status; @@ -262,13 +189,13 @@ static void pass_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_pa * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void pass_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; pass_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_pass_env.start_hdl, @@ -279,7 +206,8 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ event.evt_type = PASS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case PASS_IDX_ALERT_STATUS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ @@ -296,11 +224,14 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ s_pass_env.ringer_setting_ntf_cfg[conn_idx] = cccd_value; break; - case PASS_IDX_RINGER_CTRL_PT_VAL: { - switch (p_param->value[0]) { + case PASS_IDX_RINGER_CTRL_PT_VAL: + { + switch (p_param->value[0]) + { case PASS_CTRL_PT_SILENT_MODE: if ((PASS_RINGER_SET_NORMAL == s_pass_env.pass_init.ringer_setting) && \ - (PASS_RINGER_ACTIVE & s_pass_env.pass_init.alert_status)) { + (PASS_RINGER_ACTIVE & s_pass_env.pass_init.alert_status)) + { event.evt_type = PASS_EVT_SILENT_MODE_SET; } break; @@ -311,7 +242,8 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ case PASS_CTRL_PT_CANCEL_SLIENT_MODE: if ((PASS_RINGER_SET_SILENT == s_pass_env.pass_init.ringer_setting) && \ - (PASS_RINGER_ACTIVE & s_pass_env.pass_init.alert_status)) { + (PASS_RINGER_ACTIVE & s_pass_env.pass_init.alert_status)) + { event.evt_type = PASS_EVT_SILENT_MODE_CANCEL; } break; @@ -320,7 +252,7 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ break; } } - break; + break; default: cfm.status = BLE_ATT_ERR_INVALID_HANDLE; @@ -329,8 +261,8 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && PASS_EVT_INVALID != event.evt_type - && s_pass_env.pass_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && PASS_EVT_INVALID != event.evt_type && s_pass_env.pass_init.evt_handler) + { s_pass_env.pass_init.evt_handler(&event); } } @@ -344,12 +276,13 @@ static void pass_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_ * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void pass_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void pass_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; pass_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -361,7 +294,8 @@ static void pass_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va event.evt_type = PASS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case PASS_IDX_ALERT_STATUS_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ PASS_EVT_ALERT_STATUS_NTF_ENABLE : \ @@ -380,7 +314,8 @@ static void pass_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va break; } - if (PASS_EVT_INVALID != event.evt_type && s_pass_env.pass_init.evt_handler) { + if (PASS_EVT_INVALID != event.evt_type && s_pass_env.pass_init.evt_handler) + { s_pass_env.pass_init.evt_handler(&event); } } @@ -395,13 +330,14 @@ static void pass_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va static sdk_err_t pass_alert_status_send(uint8_t conn_idx) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t alert_status_ntf; + ble_gatts_noti_ind_t alert_status_ntf; - if (PRF_CLI_START_NTF == s_pass_env.alert_status_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_pass_env.alert_status_ntf_cfg[conn_idx]) + { alert_status_ntf.type = BLE_GATT_NOTIFICATION; alert_status_ntf.handle = prf_find_handle_by_idx(PASS_IDX_ALERT_STATUS_VAL, - s_pass_env.start_hdl, - (uint8_t *)&s_pass_env.pass_init.char_mask); + s_pass_env.start_hdl, + (uint8_t *)&s_pass_env.pass_init.char_mask); alert_status_ntf.length = PASS_ALERT_STATUS_VAL_LEN; alert_status_ntf.value = &s_pass_env.pass_init.alert_status; error_code = ble_gatts_noti_ind(conn_idx, &alert_status_ntf); @@ -420,13 +356,14 @@ static sdk_err_t pass_alert_status_send(uint8_t conn_idx) sdk_err_t pass_ringer_set_send(uint8_t conn_idx) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t ringer_set_ntf; + ble_gatts_noti_ind_t ringer_set_ntf; - if (PRF_CLI_START_NTF == s_pass_env.ringer_setting_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_pass_env.ringer_setting_ntf_cfg[conn_idx]) + { ringer_set_ntf.type = BLE_GATT_NOTIFICATION; ringer_set_ntf.handle = prf_find_handle_by_idx(PASS_IDX_RINGER_SET_VAL, - s_pass_env.start_hdl, - (uint8_t *)&s_pass_env.pass_init.char_mask); + s_pass_env.start_hdl, + (uint8_t *)&s_pass_env.pass_init.char_mask); ringer_set_ntf.length = PASS_ALERT_STATUS_VAL_LEN; ringer_set_ntf.value = &s_pass_env.pass_init.ringer_setting; error_code = ble_gatts_noti_ind(conn_idx, &ringer_set_ntf); @@ -435,6 +372,29 @@ sdk_err_t pass_ringer_set_send(uint8_t conn_idx) return error_code; } +static void pass_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + pass_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + pass_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + pass_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -446,7 +406,8 @@ uint8_t pass_ringer_setting_get(void) void pass_alert_status_set(uint8_t conn_idx, uint8_t new_status) { - if (new_status != s_pass_env.pass_init.alert_status) { + if (new_status != s_pass_env.pass_init.alert_status) + { s_pass_env.pass_init.alert_status = new_status; pass_alert_status_send(conn_idx); } @@ -454,7 +415,8 @@ void pass_alert_status_set(uint8_t conn_idx, uint8_t new_status) void pass_ringer_setting_set(uint8_t conn_idx, uint8_t new_setting) { - if (new_setting != s_pass_env.pass_init.ringer_setting) { + if (new_setting != s_pass_env.pass_init.ringer_setting) + { s_pass_env.pass_init.ringer_setting = new_setting; pass_ringer_set_send(conn_idx); } @@ -462,16 +424,23 @@ void pass_ringer_setting_set(uint8_t conn_idx, uint8_t new_setting) sdk_err_t pass_service_init(pass_init_t *p_pass_init) { - sdk_err_t ret; - if (p_pass_init == NULL) { + if (NULL == p_pass_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_pass_env.pass_init, sizeof(pass_init_t), p_pass_init, sizeof(pass_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_pass_env.pass_init, p_pass_init, sizeof(pass_init_t)); - return ble_server_prf_add(&pass_prf_info); + s_pass_env.start_hdl = PRF_INVALID_HANDLE; + + s_pass_env.pass_gatts_db.shdl = &s_pass_env.start_hdl; + s_pass_env.pass_gatts_db.uuid = s_pass_svc_uuid; + s_pass_env.pass_gatts_db.attr_tab_cfg = (uint8_t *)&(s_pass_env.pass_init.char_mask); + s_pass_env.pass_gatts_db.max_nb_attr = PASS_IDX_NB; + s_pass_env.pass_gatts_db.srvc_perm = 0; + s_pass_env.pass_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_pass_env.pass_gatts_db.attr_tab.attr_tab_16 = pass_attr_tab; + + return ble_gatts_prf_add(&s_pass_env.pass_gatts_db, pass_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.h index b6ce0fa..2693e83 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass/pass.h @@ -56,17 +56,16 @@ #ifndef __PASS_H__ #define __PASS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup PASS_MACRO Defines * @{ */ -#define PASS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Phone Alert Status Service connections. */ +#define PASS_CONNECTION_MAX 10 /**< Maximum number of Phone Alert Status Service connections. */ #define PASS_ALERT_STATUS_VAL_LEN 1 /**< Length of Alert Status value. */ #define PASS_RINGER_SET_VAL_LEN 1 /**< Length of Ringer Setting value. */ #define PASS_RINGER_CTRL_PT_VAL_LEN 1 /**< Length of Ringer Control Point value. */ @@ -76,9 +75,9 @@ * @{ * @brief Bit masks for the initialization of \ref pass_init_t.char_mask. */ -#define PASS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in PASS. */ -#define PASS_CHAR_RING_CTRL_PT_SUP 0x0180 /**< Bit mask for Ringer Control Point characteristic in PASS. */ -#define PASS_CHAR_FULL 0x01ff /**< Bit mask of the full characteristic. */ +#define PASS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in PASS. */ +#define PASS_CHAR_RING_CTRL_PT_SUP 0x0180 /**< Bit mask for Ringer Control Point characteristic in PASS. */ +#define PASS_CHAR_FULL 0x01ff /**< Bit mask of the full characteristic. */ /** @} */ /** @@ -108,14 +107,16 @@ * @{ */ /**@brief Phone Alert Status Service Ringer Control Point. */ -typedef enum { +typedef enum +{ PASS_CTRL_PT_SILENT_MODE = 0x01, /**< Silent Mode. */ PASS_CTRL_PT_MUTE_ONCE, /**< Mute Once. */ PASS_CTRL_PT_CANCEL_SLIENT_MODE, /**< Cancel Silent Mode. */ } pass_ringer_ctrl_pt_t; /**@brief Phone Alert Status Service event type. */ -typedef enum { +typedef enum +{ PASS_EVT_INVALID, /**< Invalid PASS event type. */ PASS_EVT_ALERT_STATUS_NTF_ENABLE, /**< Alert Status notification is enabled. */ PASS_EVT_ALERT_STATUS_NTF_DISABLE, /**< Alert Status notification is disabled. */ @@ -132,7 +133,8 @@ typedef enum { * @{ */ /**@brief Phone Alert Status Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ pass_evt_type_t evt_type; /**< The CTS event type. */ } pass_evt_t; @@ -150,12 +152,11 @@ typedef void (*pass_evt_handler_t)(pass_evt_t *p_evt); * @defgroup PASS_STRUCT Structures * @{ */ -/**@brief Phone Alert Status Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Phone Alert Status Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ pass_evt_handler_t evt_handler; /**< Phone Alert Status Service event handler. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref PASS_CHAR_MASK. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref PASS_CHAR_MASK. */ uint8_t alert_status; /**< Initial alert status. */ uint8_t ringer_setting; /**< Initial ringer setting. */ } pass_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/BUILD.gn new file mode 100644 index 0000000..d13bd51 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("pass_c") { + sources = [ "pass_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.c index 995ab06..3d883b6 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.c @@ -39,65 +39,34 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "pass_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "pass_c.h" -#define ATTR_VALUE_LEN 2 -#define UUID_OFFSET_8 8 +#include + /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Phone Alert Status Service Client environment variable. */ -struct pass_c_env_t { +struct pass_c_env_t +{ pass_c_handles_t handles; /**< Handles of PASS characteristics which will be got for peer. */ pass_c_evt_handler_t evt_handler; /**< Handler of PASS Client event */ - uint8_t prf_id; /**< PASS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void pass_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void pass_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void pass_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void pass_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct pass_c_env_t s_pass_c_env; /**< Phone Alert Status Service Client environment variable. */ - -/**@brief Phone Alert Status Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t pass_c_mgr_cbs = { - NULL, - NULL, - NULL +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_PHONE_ALERT_STATUS), HI_U16(BLE_ATT_SVC_PHONE_ALERT_STATUS)}; +static ble_uuid_t s_pass_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; - -/**@brief Phone Alert Status Service GATT Client Callbacks. */ -static gattc_prf_cbs_t pass_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - pass_c_att_read_cb, - pass_c_att_write_cb, - pass_c_att_ntf_ind_cb, - pass_c_srvc_browse_cb, - NULL, -}; - -/**@brief Phone Alert Status Service Client Information. */ -static const prf_client_info_t pass_c_prf_info = { - .max_connection_nb = PASS_C_CONNECTION_MAX, - .manager_cbs = &pass_c_mgr_cbs, - .gattc_prf_cbs = &pass_c_gattc_cbs -}; - + /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -111,7 +80,8 @@ static const prf_client_info_t pass_c_prf_info = { */ static void pass_c_evt_handler_excute(pass_c_evt_t *p_evt) { - if (s_pass_c_env.evt_handler != NULL && PASS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_pass_c_env.evt_handler && PASS_C_EVT_INVALID != p_evt->evt_type) + { s_pass_c_env.evt_handler(p_evt); } } @@ -125,23 +95,27 @@ static void pass_c_evt_handler_excute(pass_c_evt_t *p_evt) * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void pass_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void pass_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { pass_c_evt_t pass_c_evt; pass_c_evt.conn_idx = conn_idx; pass_c_evt.evt_type = PASS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_pass_c_env.handles.pass_alert_status_handle) { + if (p_read_rsp->value[0].handle == s_pass_c_env.handles.pass_alert_status_handle) + { pass_c_evt.evt_type = PASS_C_EVT_ALERT_STATUS_RECEIVE; - pass_c_evt.value.alert_status = p_read_rsp->vals[0].p_value[0]; - } else if (p_read_rsp->vals[0].handle == s_pass_c_env.handles.pass_ringer_set_handle) { + pass_c_evt.value.alert_status = p_read_rsp->value[0].p_value[0]; + } + else if (p_read_rsp->value[0].handle == s_pass_c_env.handles.pass_ringer_set_handle) + { pass_c_evt.evt_type = PASS_C_EVT_RINGER_SET_RECEIVE; - pass_c_evt.value.ringer_set = p_read_rsp->vals[0].p_value[0]; + pass_c_evt.value.ringer_set = p_read_rsp->value[0].p_value[0]; } pass_c_evt_handler_excute(&pass_c_evt); @@ -156,28 +130,33 @@ static void pass_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void pass_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void pass_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { pass_c_evt_t pass_c_evt; pass_c_evt.conn_idx = conn_idx; pass_c_evt.evt_type = PASS_C_EVT_INVALID; - if (handle == s_pass_c_env.handles.pass_alert_status_cccd_handle) { + if (handle == s_pass_c_env.handles.pass_alert_status_cccd_handle) + { pass_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - PASS_C_EVT_ALERT_STATUS_NTF_SET_SUCCESS : - PASS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_pass_c_env.handles.pass_ringer_set_cccd_handle) { + PASS_C_EVT_ALERT_STATUS_NTF_SET_SUCCESS : + PASS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_pass_c_env.handles.pass_ringer_set_cccd_handle) + { pass_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - PASS_C_EVT_RINGER_SET_NTF_SET_SUCCESS : - PASS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_pass_c_env.handles.pass_ringer_ctrl_pt_handle) { + PASS_C_EVT_RINGER_SET_NTF_SET_SUCCESS : + PASS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_pass_c_env.handles.pass_ringer_ctrl_pt_handle) + { pass_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - PASS_C_EVT_CTRL_POINT_SET_SUCCESS : - PASS_C_EVT_WRITE_OP_ERR; + PASS_C_EVT_CTRL_POINT_SET_SUCCESS : + PASS_C_EVT_WRITE_OP_ERR; } - pass_c_evt_handler_excute(&pass_c_evt); + pass_c_evt_handler_excute(&pass_c_evt);; } /** @@ -189,17 +168,20 @@ static void pass_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handl * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void pass_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void pass_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { pass_c_evt_t pass_c_evt; pass_c_evt.conn_idx = conn_idx; pass_c_evt.evt_type = PASS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_pass_c_env.handles.pass_alert_status_handle) { + if (p_ntf_ind->handle == s_pass_c_env.handles.pass_alert_status_handle) + { pass_c_evt.evt_type = PASS_C_EVT_ALERT_STATUS_RECEIVE; pass_c_evt.value.alert_status = p_ntf_ind->p_value[0]; - } else if (p_ntf_ind->handle == s_pass_c_env.handles.pass_ringer_set_handle) { + } + else if (p_ntf_ind->handle == s_pass_c_env.handles.pass_ringer_set_handle) + { pass_c_evt.evt_type = PASS_C_EVT_RINGER_SET_RECEIVE; pass_c_evt.value.ringer_set = p_ntf_ind->p_value[0]; } @@ -216,7 +198,7 @@ static void pass_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void pass_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void pass_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { pass_c_evt_t pass_c_evt; uint16_t uuid_disc; @@ -224,143 +206,156 @@ static void pass_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_ga pass_c_evt.conn_idx = conn_idx; pass_c_evt.evt_type = PASS_C_EVT_DISCOVERY_FAIL; - - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << UUID_OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_PHONE_ALERT_STATUS == uuid_disc) { - s_pass_c_env.handles.pass_srvc_start_handle = p_browse_srvc->start_hdl; - s_pass_c_env.handles.pass_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_PHONE_ALERT_STATUS == uuid_disc) + { + s_pass_c_env.handles.pass_srvc_start_handle = p_browse_srvc->start_hdl; + s_pass_c_env.handles.pass_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) { - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | \ - p_browse_srvc->info[i].attr.uuid[1] << UUID_OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < p_browse_srvc->end_hdl - p_browse_srvc->start_hdl; i++) + { + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_ATT_CHAR_ALERT_STATUS == uuid_disc) { - s_pass_c_env.handles.pass_alert_status_handle = handle_disc; - s_pass_c_env.handles.pass_alert_status_cccd_handle = handle_disc + 1; - } else if (BLE_ATT_CHAR_RINGER_CNTL_POINT == uuid_disc) { - s_pass_c_env.handles.pass_ringer_ctrl_pt_handle = handle_disc; - } else if (BLE_ATT_CHAR_RINGER_SETTING == uuid_disc) { - s_pass_c_env.handles.pass_ringer_set_handle = handle_disc; - s_pass_c_env.handles.pass_ringer_set_cccd_handle = handle_disc + 1; + if (BLE_ATT_CHAR_ALERT_STATUS == uuid_disc) + { + s_pass_c_env.handles.pass_alert_status_handle = handle_disc; + s_pass_c_env.handles.pass_alert_status_cccd_handle = handle_disc + 1; + } + else if (BLE_ATT_CHAR_RINGER_CNTL_POINT == uuid_disc) + { + s_pass_c_env.handles.pass_ringer_ctrl_pt_handle = handle_disc; + } + else if (BLE_ATT_CHAR_RINGER_SETTING == uuid_disc) + { + s_pass_c_env.handles.pass_ringer_set_handle = handle_disc; + s_pass_c_env.handles.pass_ringer_set_cccd_handle = handle_disc + 1; + } + } + else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; } - } else if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; } - } - pass_c_evt.evt_type = PASS_C_EVT_DISCOVERY_COMPLETE; + pass_c_evt.evt_type = PASS_C_EVT_DISCOVERY_COMPLETE; + } } pass_c_evt_handler_excute(&pass_c_evt); } +static void pass_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + pass_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + pass_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + pass_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + pass_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t pass_client_init(pass_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_pass_c_env, sizeof(s_pass_c_env), 0, sizeof(s_pass_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_pass_c_env, 0, sizeof(s_pass_c_env)); s_pass_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&pass_c_prf_info, &s_pass_c_env.prf_id); + return ble_gattc_prf_add(&s_pass_service_uuid, pass_c_ble_evt_handler); } sdk_err_t pass_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - target_uuid[0] = LO_U16(BLE_ATT_SVC_PHONE_ALERT_STATUS); - target_uuid[1] = HI_U16(BLE_ATT_SVC_PHONE_ALERT_STATUS); - const ble_uuid_t pass_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - return ble_gattc_prf_services_browse(s_pass_c_env.prf_id, conn_idx, &pass_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_pass_service_uuid); } sdk_err_t pass_c_alert_status_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_alert_status_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_alert_status_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_pass_c_env.handles.pass_alert_status_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_pass_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_pass_c_env.handles.pass_alert_status_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t pass_c_ringer_set_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_set_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_set_cccd_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_pass_c_env.handles.pass_ringer_set_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_pass_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_pass_c_env.handles.pass_ringer_set_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t pass_c_ctrl_point_set(uint8_t conn_idx, uint8_t ctrl_value) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_ctrl_pt_handle) { + if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_ctrl_pt_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_pass_c_env.handles.pass_ringer_ctrl_pt_handle; - write_attr_value.length = PASS_C_RINGER_CTRL_PT_VAL_LEN; - write_attr_value.p_value = &ctrl_value; - - return ble_gattc_prf_write_no_resp(s_pass_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_pass_c_env.handles.pass_ringer_ctrl_pt_handle, PASS_C_RINGER_CTRL_PT_VAL_LEN, &ctrl_value); } sdk_err_t pass_c_alert_status_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_alert_status_handle) { + if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_alert_status_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_pass_c_env.prf_id, conn_idx, s_pass_c_env.handles.pass_alert_status_handle, 0); + return ble_gattc_read(conn_idx, s_pass_c_env.handles.pass_alert_status_handle, 0); } sdk_err_t pass_c_ringer_set_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_set_handle) { + if (BLE_ATT_INVALID_HDL == s_pass_c_env.handles.pass_ringer_set_handle) + { return BLE_ATT_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_pass_c_env.prf_id, conn_idx, s_pass_c_env.handles.pass_ringer_set_handle, 0); + return ble_gattc_read(conn_idx, s_pass_c_env.handles.pass_ringer_set_handle, 0); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.h index 5b53096..3b1e083 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pass_c/pass_c.h @@ -3,7 +3,7 @@ * * @file pass_c.h * - * @brief API + * @brief Phone Alert Status Service Client API. * ***************************************************************************************** * @attention @@ -59,11 +59,11 @@ #ifndef __PASS_C_H__ #define __PASS_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup PASS_C_MACRO Defines @@ -74,8 +74,7 @@ * @{ * @brief PASS Alert Status bits. */ -#define PASS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections. */ +#define PASS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ #define PASS_C_NO_STATE_ACTIVE (0x00) /**< Bit for no state active. */ #define PASS_C_RINGER_ACTIVE (0x01 << 0) /**< Bit for ringer State active. */ #define PASS_C_VIBRATE_ACTIVE (0x01 << 1) /**< Bit for vibrate State active. */ @@ -100,26 +99,25 @@ * @{ */ /**@brief Phone Alert Status Service Client Ringer Control Point. */ -typedef enum { +typedef enum +{ PASS_C_CTRL_PT_SILENT_MODE = 0x01, /**< Silent Mode. */ PASS_C_CTRL_PT_MUTE_ONCE, /**< Mute Once. */ PASS_C_CTRL_PT_CANCEL_SLIENT_MODE, /**< Cancel Silent Mode. */ } pass_c_ringer_ctrl_pt_t; /**@brief Phone Alert Status Service Client event type. */ -typedef enum { - PASS_C_EVT_INVALID, /**< PASS Client invalid event. */ +typedef enum +{ + PASS_C_EVT_INVALID, /*<* PASS Client invalid event. */ PASS_C_EVT_DISCOVERY_COMPLETE, /**< PASS Client has found PASS service and its characteristics. */ - PASS_C_EVT_DISCOVERY_FAIL, /**< PASS Client found PASS service failed because of \ - invalid operation or no found at the peer. */ - PASS_C_EVT_ALERT_STATUS_NTF_SET_SUCCESS, /**< PASS Client has set Notification of Alert Status characteristic. */ - PASS_C_EVT_RINGER_SET_NTF_SET_SUCCESS, /**< PASS Client has set Notification of Ringer Setting characteristic. */ - PASS_C_EVT_ALERT_STATUS_RECEIVE, /**< PASS Client has received Alert Status value \ - (Read or Notification from peer). */ - PASS_C_EVT_RINGER_SET_RECEIVE, /**< PASS Client has received Ringer Setting Value \ - (Read or Notification from peer). */ - PASS_C_EVT_CTRL_POINT_SET_SUCCESS, /**< PASS Client has writen Control Point completely. */ - PASS_C_EVT_WRITE_OP_ERR, /**< Error occured when PASS Client writen to peer. */ + PASS_C_EVT_DISCOVERY_FAIL, /**< PASS Client found PASS service failed because of invalid operation or no found at the peer. */ + PASS_C_EVT_ALERT_STATUS_NTF_SET_SUCCESS, /**< PASS Client has set Notification of Alert Status characteristic. */ + PASS_C_EVT_RINGER_SET_NTF_SET_SUCCESS, /**< PASS Client has set Notification of Ringer Setting characteristic. */ + PASS_C_EVT_ALERT_STATUS_RECEIVE, /**< PASS Client has received Alert Status value (Read or Notification from peer). */ + PASS_C_EVT_RINGER_SET_RECEIVE, /**< PASS Client has received Ringer Setting Value (Read or Notification from peer). */ + PASS_C_EVT_CTRL_POINT_SET_SUCCESS, /**< PASS Client has writen Control Point completely. */ + PASS_C_EVT_WRITE_OP_ERR, /**< Error occured when PASS Client writen to peer. */ } pass_c_evt_type_t; /** @} */ @@ -129,26 +127,24 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t pass_srvc_start_handle; /**< PASS Service start handle. */ uint16_t pass_srvc_end_handle; /**< PASS Service end handle. */ - uint16_t pass_alert_status_handle; /**< PASS Alert Status characteristic Value handle \ - which has been got from peer. */ - uint16_t pass_alert_status_cccd_handle; /**< PASS CCCD handle of Alert Status characteristic \ - which has been got from peer. */ - uint16_t pass_ringer_set_handle; /**< PASS Ringer Setting characteristic Value handle \ - which has been got from peer. */ - uint16_t pass_ringer_set_cccd_handle; /**< PASS CCCD handle of Ringer Setting characteristic \ - which has been got from peer. */ - uint16_t pass_ringer_ctrl_pt_handle; /**< PASS Ringer Control Point characteristic Value handle \ - which has been got from peer. */ + uint16_t pass_alert_status_handle; /**< PASS Alert Status characteristic Value handle which has been got from peer. */ + uint16_t pass_alert_status_cccd_handle; /**< PASS CCCD handle of Alert Status characteristic which has been got from peer. */ + uint16_t pass_ringer_set_handle; /**< PASS Ringer Setting characteristic Value handle which has been got from peer. */ + uint16_t pass_ringer_set_cccd_handle; /**< PASS CCCD handle of Ringer Setting characteristic which has been got from peer. */ + uint16_t pass_ringer_ctrl_pt_handle; /**< PASS Ringer Control Point characteristic Value handle which has been got from peer. */ } pass_c_handles_t; /**@brief Phone Alert Status Client Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ pass_c_evt_type_t evt_type; /**< The PASS event type. */ - union { + union + { uint8_t alert_status; /**< Alert status received. */ uint8_t ringer_set; /**< Ringer setting received. */ } value; /**< Value received. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/BUILD.gn new file mode 100644 index 0000000..002bfe6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("pcs") { + sources = [ "pcs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.c index 8893300..daef8fa 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.c @@ -49,10 +49,8 @@ ***************************************************************************************** */ /**@brief The UUIDs of PCS characteristics. */ -#define PCS_CHARACTERISTIC_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ - 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x05, 0xED, 0xA6} -#define PCS_CHARACTERISTIC_SETTING_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ - 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x05, 0xED, 0xA6} +#define PCS_CHARACTERISTIC_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x05, 0xED, 0xA6} +#define PCS_CHARACTERISTIC_SETTING_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x05, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -64,7 +62,8 @@ ***************************************************************************************** */ /**@brief PCS Service Attributes Indexes. */ -enum pcs_attr_idx_t { +enum pcs_attr_idx_t +{ PCS_IDX_SVC, PCS_IDX_TX_CHAR, @@ -83,134 +82,60 @@ enum pcs_attr_idx_t { ***************************************************************************************** */ /**@brief PCS Service environment variable. */ -struct pcs_env_t { - pcs_init_t pcs_init; /**< PCS Service initialization variables. */ - uint16_t start_hdl; /**< Start handle of services */ - uint16_t tx_ntf_cfg[PCS_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of the peers. */ - uint16_t setting_ind_cfg[PCS_CONNECTION_MAX]; /**< Setting Characteristic Indication configuration - of the peers. */ +struct pcs_env_t +{ + pcs_init_t pcs_init; /**< PCS Service initialization variables. */ + uint16_t start_hdl; /**< Start handle of services */ + uint16_t tx_ntf_cfg[PCS_CONNECTION_MAX]; /**< TX Characteristic Notification configuration of the peers. */ + uint16_t setting_ind_cfg[PCS_CONNECTION_MAX]; /**< Setting Characteristic Indication configuration of the peers. */ + ble_gatts_create_db_t pcs_gatts_db; /**< Running Speed and Cadence Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t pcs_init(void); -static void pcs_disconnected(uint8_t conn_idx, uint8_t disconn_reason); -static void pcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void pcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void pcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void pcs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct pcs_env_t s_pcs_env; static const uint16_t s_char_mask = 0xFFFF; +static const uint8_t s_pcs_svc_uuid[] = {PCS_SERVICE_UUID}; /**@brief Full PCS Database Description which is used to add attributes into the ATT database. */ -static const attm_desc_128_t pcs_att_db[PCS_IDX_NB] = { +static const ble_gatts_attm_desc_128_t pcs_attr_tab[PCS_IDX_NB] = +{ // PCS service - [PCS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [PCS_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // PCS TX Characteristic Declaration - [PCS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [PCS_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // PCS TX Characteristic Value - [PCS_IDX_TX_VAL] = { - PCS_CHARACTERISTIC_TX_UUID, - NOTIFY_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - PCS_MAX_DATA_LEN - }, + [PCS_IDX_TX_VAL] = {PCS_CHARACTERISTIC_TX_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + PCS_MAX_DATA_LEN}, // PCS TX Characteristic - Client Characteristic Configuration Descriptor - [PCS_IDX_TX_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, - + [PCS_IDX_TX_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, + // PCS settings - [PCS_IDX_SETTING_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [PCS_IDX_SETTING_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // PCS settings Value - [PCS_IDX_SETTING_VAL] = { - PCS_CHARACTERISTIC_SETTING_UUID, - (WRITE_CMD_PERM_UNSEC | INDICATE_PERM_UNSEC), - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - PCS_MAX_DATA_LEN - }, + [PCS_IDX_SETTING_VAL] = {PCS_CHARACTERISTIC_SETTING_UUID, + (BLE_GATTS_WRITE_CMD_PERM_UNSEC | BLE_GATTS_INDICATE_PERM_UNSEC), + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + PCS_MAX_DATA_LEN}, // ths settings cfg - [PCS_IDX_SETTING_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - (READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC | WRITE_CMD_PERM_UNSEC), - 0, - 0 - }, -}; - -/**@brief PCS Service interface required by profile manager. */ -static ble_prf_manager_cbs_t pcs_mgr_cbs = { - (prf_init_func_t)pcs_init, - NULL, - pcs_disconnected, -}; - -/**@brief PCS GATT Server Callbacks. */ -static gatts_prf_cbs_t pcs_gatts_cbs = { - pcs_read_att_cb, - pcs_write_att_cb, - NULL, - pcs_ntf_ind_cb, - pcs_cccd_set_cb -}; - -/**@brief PCS Server Information. */ -static const prf_server_info_t pcs_prf_info = { - .max_connection_nb = PCS_CONNECTION_MAX, - .manager_cbs = &pcs_mgr_cbs, - .gatts_prf_cbs = &pcs_gatts_cbs + [PCS_IDX_SETTING_CFG] = {ATT_128_CLIENT_CHAR_CFG, + (BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_WRITE_CMD_PERM_UNSEC), + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize PCS and create DB in ATT. - * - * @return Error code to know if service initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t pcs_init(void) -{ - const uint8_t pcs_svc_uuid[] = {PCS_SERVICE_UUID}; - uint16_t start_hdl = PRF_INVALID_HANDLE; - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = pcs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; - gatts_db.max_nb_attr = PCS_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = pcs_att_db; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_pcs_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -219,9 +144,9 @@ static sdk_err_t pcs_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void pcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void pcs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint16_t handle = p_param->handle; uint8_t tab_index = 0; @@ -229,7 +154,8 @@ static void pcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case PCS_IDX_TX_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_pcs_env.tx_ntf_cfg[conn_idx]; @@ -241,7 +167,7 @@ static void pcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par cfm.value = (uint8_t *)&s_pcs_env.setting_ind_cfg[conn_idx]; cfm.status = BLE_SUCCESS; break; - + default: cfm.length = 0; cfm.status = BLE_ATT_ERR_INVALID_HANDLE; @@ -259,20 +185,22 @@ static void pcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par * @param[in] p_param: Point to the parameters of the write request. ***************************************************************************************** */ -static void pcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void pcs_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint16_t cccd_value; pcs_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_pcs_env.start_hdl, PCS_IDX_NB, (uint8_t *)&s_char_mask); event.conn_idx = conn_idx; cfm.handle = handle; cfm.status = BLE_SUCCESS; + + switch (tab_index) + { - switch (tab_index) { case PCS_IDX_TX_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? PCS_EVT_TX_ENABLE : PCS_EVT_TX_DISABLE; @@ -294,8 +222,8 @@ static void pcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p break; } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && PCS_EVT_INVALID != event.evt_type && - s_pcs_env.pcs_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && PCS_EVT_INVALID != event.evt_type && s_pcs_env.pcs_init.evt_handler) + { event.conn_idx = conn_idx; event.p_data = (uint8_t *)p_param->value; event.length = p_param->length; @@ -315,12 +243,13 @@ static void pcs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void pcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void pcs_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; pcs_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -328,7 +257,8 @@ static void pcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.conn_idx = conn_idx; event.evt_type = PCS_EVT_INVALID; - switch (tab_index) { + switch (tab_index) + { case PCS_IDX_SETTING_CFG: event.evt_type = (PRF_CLI_START_IND == cccd_value) ? PCS_EVT_SETTING_ENABLE : PCS_EVT_SETTING_DISABLE; s_pcs_env.setting_ind_cfg[conn_idx] = cccd_value; @@ -338,7 +268,8 @@ static void pcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (PCS_EVT_INVALID != event.evt_type && s_pcs_env.pcs_init.evt_handler) { + if (PCS_EVT_INVALID != event.evt_type && s_pcs_env.pcs_init.evt_handler) + { s_pcs_env.pcs_init.evt_handler(&event); } } @@ -350,16 +281,18 @@ static void pcs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] conn_idx: Index of the connection. ***************************************************************************************** */ -static void pcs_disconnected(uint8_t conn_idx, uint8_t disconn_reason) +static void pcs_disconnect_evt_handler(uint8_t conn_idx, uint8_t disconn_reason) { - pcs_evt_t event = { + pcs_evt_t event = + { .conn_idx = conn_idx, .evt_type = PCS_EVT_DISCONNECTED, .p_data = &disconn_reason, .length = sizeof(uint8_t) }; - if (s_pcs_env.pcs_init.evt_handler) { + if (s_pcs_env.pcs_init.evt_handler) + { s_pcs_env.pcs_init.evt_handler(&event); } } @@ -373,19 +306,52 @@ static void pcs_disconnected(uint8_t conn_idx, uint8_t disconn_reason) * @param[in] p_ntf_ind: Pointer to the structure of the complete event. ***************************************************************************************** */ -static void pcs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void pcs_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_pcs_env.pcs_init.evt_handler != NULL) { + if (NULL != s_pcs_env.pcs_init.evt_handler) + { pcs_evt_t event; event.conn_idx = conn_idx; - if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (BLE_SUCCESS == status && BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = PCS_EVT_TX_DATA_SENT; s_pcs_env.pcs_init.evt_handler(&event); } } } +static void pcs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + pcs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + pcs_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + pcs_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + pcs_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + pcs_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -393,9 +359,10 @@ static void pcs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf sdk_err_t pcs_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_rsp; + ble_gatts_noti_ind_t send_rsp; - if (PRF_CLI_START_NTF == s_pcs_env.tx_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_pcs_env.tx_ntf_cfg[conn_idx]) + { // Fill in the parameter structure send_rsp.type = BLE_GATT_NOTIFICATION; send_rsp.handle = prf_find_handle_by_idx(PCS_IDX_TX_VAL, s_pcs_env.start_hdl, (uint8_t *)&s_char_mask); @@ -414,9 +381,10 @@ sdk_err_t pcs_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) sdk_err_t pcs_setting_reply(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t send_cmd; + ble_gatts_noti_ind_t send_cmd; - if (PRF_CLI_START_IND == s_pcs_env.setting_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_pcs_env.setting_ind_cfg[conn_idx]) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_INDICATION; send_cmd.handle = prf_find_handle_by_idx(PCS_IDX_SETTING_VAL, s_pcs_env.start_hdl, (uint8_t *)&s_char_mask); @@ -434,15 +402,22 @@ sdk_err_t pcs_setting_reply(uint8_t conn_idx, uint8_t *p_data, uint16_t length) sdk_err_t pcs_service_init(pcs_init_t *p_pcs_init) { - sdk_err_t ret; - if (p_pcs_init == NULL) { + if (NULL == p_pcs_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_pcs_env.pcs_init, sizeof(pcs_init_t), p_pcs_init, sizeof(pcs_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_pcs_env.pcs_init, p_pcs_init, sizeof(pcs_init_t)); - return ble_server_prf_add(&pcs_prf_info); + s_pcs_env.start_hdl = PRF_INVALID_HANDLE; + + s_pcs_env.pcs_gatts_db.shdl = &s_pcs_env.start_hdl; + s_pcs_env.pcs_gatts_db.uuid = s_pcs_svc_uuid; + s_pcs_env.pcs_gatts_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_pcs_env.pcs_gatts_db.max_nb_attr = PCS_IDX_NB; + s_pcs_env.pcs_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_pcs_env.pcs_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_pcs_env.pcs_gatts_db.attr_tab.attr_tab_128 = pcs_attr_tab; + + return ble_gatts_prf_add(&s_pcs_env.pcs_gatts_db, pcs_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.h index 5757c6e..d90c014 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/pcs/pcs.h @@ -58,18 +58,17 @@ #ifndef __PCS_H__ #define __PCS_H__ -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" /** * @defgroup PCS_MACRO Defines * @{ */ -#define PCS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Power Consumption Service connections. */ -#define PCS_MAX_DATA_LEN 244 /**< Maximum length of application data packet which is transmitted via PCS. */ -#define PCS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x05, \ - 0xED, 0xA6 /**< The UUID of Power Consumption Service for setting advertising data. */ +#define PCS_CONNECTION_MAX 10 /**< Maximum number of Power Consumption Service connections. */ +#define PCS_MAX_DATA_LEN 244 /**< Maximum length of application data packet which is transmitted via PCS. */ +#define PCS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x05, 0xED, 0xA6 /**< The UUID of Power Consumption Service for setting advertising data. */ #define PCS_SET_PARAM_SUCCESS 0x00 /**< PCS parameters set successfully. */ #define PCS_SET_PARAM_FAIL 0x81 /**< PCS parameters set unsuccessfully. */ @@ -86,7 +85,8 @@ * @{ */ /**@brief PCS Service event types. */ -typedef enum { +typedef enum +{ PCS_EVT_INVALID, /**< Invalid PCS event. */ PCS_EVT_TX_ENABLE, /**< TX notify has been enabled. */ PCS_EVT_TX_DISABLE, /**< TX notify has been disabled. */ @@ -98,7 +98,8 @@ typedef enum { } pcs_evt_type_t; /**@brief PCS Service settings types. */ -typedef enum { +typedef enum +{ PCS_SETTING_TYPE_ADV_INTERVAL, /**< BLE Advertising Interval parameter. */ PCS_SETTING_TYPE_CONN_PARAM, /**< BLE Connection parameter. */ PCS_SETTING_TYPE_PHY, /**< Radio Phy mode, 1M, 2M, Encoded. */ @@ -112,7 +113,8 @@ typedef enum { * @{ */ /**@brief PCS Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ pcs_evt_type_t evt_type; /**< The PCS event type. */ uint8_t *p_data; /**< Pointer to data. */ @@ -132,9 +134,9 @@ typedef void (*pcs_evt_handler_t)(pcs_evt_t *p_evt); * @addtogroup PCS_STRUCT Structures * @{ */ -/**@brief PCS Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief PCS Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ pcs_evt_handler_t evt_handler; /**< PCS Service event handler. */ } pcs_init_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/BUILD.gn new file mode 100644 index 0000000..06ea183 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("rscs") { + sources = [ "rscs.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.c index 70992d3..c137129 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.c @@ -43,13 +43,14 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define INDEX_2 + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief Running Speed and Cadence Service Attributes Indexes. */ -enum { +enum +{ RSCS_IDX_SVC, RSCS_IDX_RSC_MEAS_CHAR, @@ -74,32 +75,22 @@ enum { ***************************************************************************************** */ /**@brief Running Speed and Cadence Service environment variable. */ -struct rscs_env_t { - rscs_init_t - rscs_init; /**< Running Speed and Cadence Service initialization variables. */ - uint16_t start_hdl; /**< Running Speed and Cadence Service start handle. */ - bool - ctrl_pt_op_in_progress; /**< A previously triggered SC Control Point operation is still in progress. */ - bool - ctrl_pt_op_rsp_cplt; /**< A previously triggered SC Control Point operation response cplt. */ - uint16_t - meas_ntf_cfg[RSCS_CONNECTION_MAX]; /**< The configuration of RCS Measurement Notification - which is configured by the peer devices. */ - uint16_t - ctrl_point_ind_cfg[RSCS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification - which is configured by the peer devices. */ +struct rscs_env_t +{ + rscs_init_t rscs_init; /**< Running Speed and Cadence Service initialization variables. */ + uint16_t start_hdl; /**< Running Speed and Cadence Service start handle. */ + bool ctrl_pt_op_in_progress; /**< A previously triggered SC Control Point operation is still in progress. */ + bool ctrl_pt_op_rsp_cplt; /**< A previously triggered SC Control Point operation response cplt. */ + uint16_t meas_ntf_cfg[RSCS_CONNECTION_MAX]; /**< The configuration of RCS Measurement Notification which is configured by the peer devices. */ + uint16_t ctrl_point_ind_cfg[RSCS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification which is configured by the peer devices. */ + ble_gatts_create_db_t rscs_gatts_db; /**< Running Speed and Cadence Service attributs database. */ }; -/* + + /* * LOCAL FUNCTION DECLARATION - ***************************************************************************************** + **************************************************************************************** */ -static sdk_err_t rscs_init(void); -static void rscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void rscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void rscs_disconnect_cb(uint8_t conn_idx, uint8_t reason); -static void rscs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); static void rscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); /* @@ -107,130 +98,61 @@ static void rscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_da ***************************************************************************************** */ static struct rscs_env_t s_rscs_env; +static const uint8_t s_rscs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_RUNNING_SPEED_CADENCE); /**@brief Full RSCS Database Description - Used to add attributes into the database. */ -static const attm_desc_t rscs_attr_tab[RSCS_IDX_NB] = { +static const ble_gatts_attm_desc_t rscs_attr_tab[RSCS_IDX_NB] = +{ // Running Speed and Cadence Service Declaration - [RSCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [RSCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // RSC Measurement Characteristic - Declaration - [RSCS_IDX_RSC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RSCS_IDX_RSC_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // RSC Measurement Characteristic - Value - [RSCS_IDX_RSC_MEAS_VAL] = { - BLE_ATT_CHAR_RSC_MEAS, - NOTIFY_PERM_UNSEC, - ATT_VAL_LOC_USER, - RSCS_MEAS_VAL_LEN_MAX - }, + [RSCS_IDX_RSC_MEAS_VAL] = {BLE_ATT_CHAR_RSC_MEAS, + BLE_GATTS_NOTIFY_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + RSCS_MEAS_VAL_LEN_MAX}, // RSC Measurement Characteristic - Client Characteristic Configuration Descriptor - [RSCS_IDX_RSC_MEAS_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [RSCS_IDX_RSC_MEAS_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // RSC Feature Characteristic - Declaration - [RSCS_IDX_RSC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RSCS_IDX_RSC_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // RSC Feature Characteristic - Value - [RSCS_IDX_RSC_FEAT_VAL] = { - BLE_ATT_CHAR_RSC_FEAT, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - RSCS_FEAT_VAL_LEN_MAX - }, + [RSCS_IDX_RSC_FEAT_VAL] = {BLE_ATT_CHAR_RSC_FEAT, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + RSCS_FEAT_VAL_LEN_MAX}, // Sensor Location Characteristic - Declaration - [RSCS_IDX_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RSCS_IDX_SENSOR_LOC_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Sensor Location Characteristic - Value - [RSCS_IDX_SENSOR_LOC_VAL] = { - BLE_ATT_CHAR_SENSOR_LOC, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - RSCS_SENSOR_LOC_VAL_LEN_MAX - }, + [RSCS_IDX_SENSOR_LOC_VAL] = {BLE_ATT_CHAR_SENSOR_LOC, + BLE_GATTS_READ_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + RSCS_SENSOR_LOC_VAL_LEN_MAX}, // SC Control Point Characteristic - Declaration - [RSCS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RSCS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // SC Control Point Characteristic - Value - [RSCS_IDX_CTRL_POINT_VAL] = { - BLE_ATT_CHAR_SC_CNTL_PT, - WRITE_REQ_PERM_UNSEC | INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - RSCS_CTRL_PT_VAL_LEN_MAX - }, + [RSCS_IDX_CTRL_POINT_VAL] = {BLE_ATT_CHAR_SC_CNTL_PT, + BLE_GATTS_WRITE_REQ_PERM_UNSEC | BLE_GATTS_INDICATE_PERM_UNSEC, + BLE_GATTS_ATT_VAL_LOC_USER, + RSCS_CTRL_PT_VAL_LEN_MAX}, // SC Control Point Characteristic - Client Characteristic Configuration Descriptor - [RSCS_IDX_CTRL_POINT_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief RSCS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t rscs_task_cbs = { - (prf_init_func_t) rscs_init, - NULL, - rscs_disconnect_cb, -}; - -/**@brief RSCS Task Callbacks. */ -static gatts_prf_cbs_t rscs_cb_func = { - rscs_read_att_cb, - rscs_write_att_cb, - NULL, - rscs_ntf_ind_cb, - rscs_cccd_set_cb -}; - -/**@brief RSCS Information. */ -static const prf_server_info_t rscs_prf_info = { - .max_connection_nb = RSCS_CONNECTION_MAX, - .manager_cbs = &rscs_task_cbs, - .gatts_prf_cbs = &rscs_cb_func, + [RSCS_IDX_CTRL_POINT_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Running Speed and Cadence service create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t rscs_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t rscs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_RUNNING_SPEED_CADENCE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = rscs_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_rscs_env.rscs_init.char_mask); - gatts_db.max_nb_attr = RSCS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = rscs_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_rscs_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -239,18 +161,19 @@ static sdk_err_t rscs_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void rscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void rscs_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_rscs_env.start_hdl, - RSCS_IDX_NB, - (uint8_t *)&s_rscs_env.rscs_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_rscs_env.start_hdl, + RSCS_IDX_NB, + (uint8_t *)&s_rscs_env.rscs_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case RSCS_IDX_RSC_MEAS_NTF_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_rscs_env.meas_ntf_cfg[conn_idx]; @@ -265,7 +188,7 @@ static void rscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)&s_rscs_env.rscs_init.sensor_location; break; - + case RSCS_IDX_CTRL_POINT_IND_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_rscs_env.ctrl_point_ind_cfg[conn_idx]; @@ -288,14 +211,14 @@ static void rscs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void rscs_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t tab_index = 0; - uint16_t cccd_value = 0; - bool ctrl_pt_evt = false; - rscs_evt_t event; - gatts_write_cfm_t cfm; + uint16_t handle = p_param->handle; + uint16_t tab_index = 0; + uint16_t cccd_value = 0; + bool ctrl_pt_evt = false; + rscs_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_rscs_env.start_hdl, @@ -305,23 +228,29 @@ static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa cfm.status = BLE_SUCCESS; event.evt_type = RSCS_EVT_INVALID; event.conn_idx = conn_idx; - - switch (tab_index) { + + switch (tab_index) + { case RSCS_IDX_RSC_MEAS_NTF_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE :\ - RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE); + RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE :\ + RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE); s_rscs_env.meas_ntf_cfg[conn_idx] = cccd_value; break; case RSCS_IDX_CTRL_POINT_VAL: - if (PRF_CLI_START_IND != s_rscs_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND != s_rscs_env.ctrl_point_ind_cfg[conn_idx]) + { cfm.status = RSCS_ERROR_CCCD_INVALID; break; - } else if (s_rscs_env.ctrl_pt_op_in_progress) { + } + else if (s_rscs_env.ctrl_pt_op_in_progress) + { cfm.status = RSCS_ERROR_PROC_IN_PROGRESS; - } else if (PRF_CLI_START_IND == s_rscs_env.ctrl_point_ind_cfg[conn_idx]) { + } + else if (PRF_CLI_START_IND == s_rscs_env.ctrl_point_ind_cfg[conn_idx]) + { s_rscs_env.ctrl_pt_op_in_progress = true; ctrl_pt_evt = true; } @@ -330,8 +259,8 @@ static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa case RSCS_IDX_CTRL_POINT_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - RSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ - RSCS_EVT_CTRL_POINT_INDICATION_DISABLE); + RSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ + RSCS_EVT_CTRL_POINT_INDICATION_DISABLE); s_rscs_env.ctrl_point_ind_cfg[conn_idx] = cccd_value; break; @@ -342,14 +271,17 @@ static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa ble_gatts_write_cfm(conn_idx, &cfm); - if (ctrl_pt_evt) { + if (ctrl_pt_evt) + { rscs_sc_ctrl_pt_handler(conn_idx, p_param->value, p_param->length); - } else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && RSCS_EVT_INVALID != event.evt_type - && s_rscs_env.rscs_init.evt_handler) { + } + else if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && RSCS_EVT_INVALID != event.evt_type && s_rscs_env.rscs_init.evt_handler) + { s_rscs_env.rscs_init.evt_handler(&event); } } + /** ***************************************************************************************** * @brief Handles reception of the cccd recover request. @@ -359,43 +291,46 @@ static void rscs_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void rscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void rscs_cccd_set_evt_handler(uint8_t conn_idx, const ble_gatts_evt_cccd_rec_t *p_cccd_rec) { uint16_t tab_index = 0; rscs_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(p_cccd_rec->cccd_val)) + { return; } - tab_index = prf_find_idx_by_handle(handle, + tab_index = prf_find_idx_by_handle(p_cccd_rec->handle, s_rscs_env.start_hdl, RSCS_IDX_NB, (uint8_t *)&s_rscs_env.rscs_init.char_mask); event.evt_type = RSCS_EVT_INVALID; event.conn_idx = conn_idx; - - switch (tab_index) { + + switch (tab_index) + { case RSCS_IDX_RSC_MEAS_NTF_CFG: - event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ?\ - RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE :\ - RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE); - s_rscs_env.meas_ntf_cfg[conn_idx] = cccd_value; + event.evt_type = ((PRF_CLI_START_NTF == p_cccd_rec->cccd_val) ?\ + RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE :\ + RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE); + s_rscs_env.meas_ntf_cfg[conn_idx] = p_cccd_rec->cccd_val; break; case RSCS_IDX_CTRL_POINT_IND_CFG: - event.evt_type = ((PRF_CLI_START_IND == cccd_value) ?\ - RSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ - RSCS_EVT_CTRL_POINT_INDICATION_DISABLE); - s_rscs_env.ctrl_point_ind_cfg[conn_idx] = cccd_value; + event.evt_type = ((PRF_CLI_START_IND == p_cccd_rec->cccd_val) ?\ + RSCS_EVT_CTRL_POINT_INDICATION_ENABLE :\ + RSCS_EVT_CTRL_POINT_INDICATION_DISABLE); + s_rscs_env.ctrl_point_ind_cfg[conn_idx] = p_cccd_rec->cccd_val; break; default: break; } - if (RSCS_EVT_INVALID != event.evt_type && s_rscs_env.rscs_init.evt_handler) { + if (RSCS_EVT_INVALID != event.evt_type && s_rscs_env.rscs_init.evt_handler) + { s_rscs_env.rscs_init.evt_handler(&event); } } @@ -409,17 +344,21 @@ static void rscs_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_va * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void rscs_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void rscs_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { rscs_evt_t event; event.evt_type = RSCS_EVT_INVALID; event.conn_idx = conn_idx; - if (s_rscs_env.rscs_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (s_rscs_env.rscs_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = RSCS_EVT_RSC_MEAS_SEND_CPLT; - } else if (BLE_GATT_INDICATION == p_ntf_ind->type) { + } + else if (BLE_GATT_INDICATION == p_ntf_ind->type) + { event.evt_type = RSCS_EVT_CTRL_POINT_RSP_CPLT; s_rscs_env.ctrl_pt_op_in_progress = false; } @@ -441,19 +380,22 @@ static void rscs_op_set_cumulative_handler(uint8_t conn_idx, const uint8_t *p_da rscs_evt_t event; uint8_t rsp[RSCS_CTRL_PT_RSP_LEN_MIN]; - rsp[INDEX_0] = RSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = RSCS_CTRL_PT_OP_SET_CUMUL_VAL; - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_FAILED; + rsp[0] = RSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = RSCS_CTRL_PT_OP_SET_CUMUL_VAL; + rsp[2] = RSCS_CTRL_PT_RSP_FAILED; if ((sizeof(uint32_t) == length) && \ (s_rscs_env.rscs_init.feature & RSCS_FEAT_TOTAL_DISTANCE_BIT) && \ - (s_rscs_env.rscs_init.evt_handler)) { + (s_rscs_env.rscs_init.evt_handler)) + { event.conn_idx = conn_idx; event.evt_type = RSCS_EVT_CUMUL_VAL_SET; event.p_data = p_data; event.length = length; s_rscs_env.rscs_init.evt_handler(&event); - } else { + } + else + { rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -470,15 +412,18 @@ static void rscs_op_start_calibration_handler(uint8_t conn_idx) rscs_evt_t event; uint8_t rsp[RSCS_CTRL_PT_RSP_LEN_MIN]; - rsp[INDEX_0] = RSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = RSCS_CTRL_PT_OP_START_CALIB; - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_FAILED; + rsp[0] = RSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = RSCS_CTRL_PT_OP_START_CALIB; + rsp[2] = RSCS_CTRL_PT_RSP_FAILED; - if ((s_rscs_env.rscs_init.feature & RSCS_FEAT_CALIBRATION_PROCEDURE_BIT) && s_rscs_env.rscs_init.evt_handler) { + if ((s_rscs_env.rscs_init.feature & RSCS_FEAT_CALIBRATION_PROCEDURE_BIT) && s_rscs_env.rscs_init.evt_handler) + { event.conn_idx = conn_idx; event.evt_type = RSCS_EVT_SEBSOR_CALIBRATION; s_rscs_env.rscs_init.evt_handler(&event); - } else { + } + else + { rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -497,20 +442,25 @@ static void rscs_op_sensor_loc_update_handler(uint8_t conn_idx, const uint8_t *p rscs_evt_t event; uint8_t rsp[RSCS_CTRL_PT_RSP_LEN_MIN]; - rsp[INDEX_0] = RSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = RSCS_CTRL_PT_OP_UPD_LOC; + rsp[0] = RSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = RSCS_CTRL_PT_OP_UPD_LOC; - if (RSCS_SENSOR_LOC_SUP_NB <= p_data[0] || sizeof(uint8_t) != length) { - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_INVALID_PARAM; + if (RSCS_SENSOR_LOC_SUP_NB <= p_data[0] || sizeof(uint8_t) != length) + { + rsp[2] = RSCS_CTRL_PT_RSP_INVALID_PARAM; rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); - } else if ((s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) && s_rscs_env.rscs_init.evt_handler) { + } + else if ((s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) && s_rscs_env.rscs_init.evt_handler) + { event.conn_idx = conn_idx; event.evt_type = RSCS_EVT_SEBSOR_LOC_UPD; event.p_data = p_data; event.length = length; s_rscs_env.rscs_init.evt_handler(&event); - } else { - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_FAILED; + } + else + { + rsp[2] = RSCS_CTRL_PT_RSP_FAILED; rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -528,24 +478,29 @@ static void rscs_op_sup_sensor_loc_req_handler(uint8_t conn_idx) uint8_t rsp[RSCS_CTRL_PT_RSP_LEN_MIN + RSCS_SENSOR_LOC_SUP_NB]; uint8_t rsp_idx = RSCS_CTRL_PT_RSP_LEN_MIN; - rsp[INDEX_0] = RSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = RSCS_CTRL_PT_OP_REQ_SUP_LOC; - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_SUCCESS; + rsp[0] = RSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = RSCS_CTRL_PT_OP_REQ_SUP_LOC; + rsp[2] = RSCS_CTRL_PT_RSP_SUCCESS; - if (s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) + { event.conn_idx = conn_idx; event.evt_type = RSCS_EVT_SUP_SEBSOR_LOC_REQ; - if (s_rscs_env.rscs_init.evt_handler) { - s_rscs_env.rscs_init.evt_handler(&event); + if (s_rscs_env.rscs_init.evt_handler) + { + s_rscs_env.rscs_init.evt_handler(&event); } - for (uint8_t i = 0; i < RSCS_SENSOR_LOC_SUP_NB; i++) { + for (uint8_t i = 0; i < RSCS_SENSOR_LOC_SUP_NB; i++) + { rsp[rsp_idx++] = i; } rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN + RSCS_SENSOR_LOC_SUP_NB); - } else { - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_FAILED; + } + else + { + rsp[2] = RSCS_CTRL_PT_RSP_FAILED; rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); } } @@ -558,7 +513,7 @@ static void rscs_op_sup_sensor_loc_req_handler(uint8_t conn_idx) * @param[in] reason: Reason of disconnection. ***************************************************************************************** */ -static void rscs_disconnect_cb(uint8_t conn_idx, uint8_t reason) +static void rscs_disconnect_evt_handler(uint8_t conn_idx, uint8_t reason) { s_rscs_env.ctrl_pt_op_in_progress = false; } @@ -576,7 +531,8 @@ static void rscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uin { uint8_t rsp[RSCS_CTRL_PT_RSP_LEN_MIN]; - switch (p_data[0]) { + switch(p_data[0]) + { case RSCS_CTRL_PT_OP_SET_CUMUL_VAL: rscs_op_set_cumulative_handler(conn_idx, &p_data[1], length - 1); break; @@ -594,9 +550,9 @@ static void rscs_sc_ctrl_pt_handler(uint8_t conn_idx, const uint8_t *p_data, uin break; default: - rsp[INDEX_0] = RSCS_CTRL_PT_OP_RSP_CODE; - rsp[INDEX_1] = p_data[0]; - rsp[INDEX_2] = RSCS_CTRL_PT_RSP_NOT_SUP; + rsp[0] = RSCS_CTRL_PT_OP_RSP_CODE; + rsp[1] = p_data[0]; + rsp[2] = RSCS_CTRL_PT_RSP_NOT_SUP; rscs_ctrl_pt_rsp_send(conn_idx, rsp, RSCS_CTRL_PT_RSP_LEN_MIN); break; } @@ -625,8 +581,10 @@ static uint16_t rsc_meas_value_encoded(rscs_meas_val_t *p_meas, uint8_t *p_encod p_encoded_buffer[length++] = p_meas->inst_cadence; // Instantaneous stride length field - if (s_rscs_env.rscs_init.feature & RSCS_FEAT_INSTANT_STRIDE_LEN_BIT) { - if (p_meas->inst_stride_length_present) { + if (s_rscs_env.rscs_init.feature & RSCS_FEAT_INSTANT_STRIDE_LEN_BIT) + { + if (p_meas->inst_stride_length_present) + { p_encoded_buffer[length++] = LO_U16(p_meas->inst_stride_length); p_encoded_buffer[length++] = HI_U16(p_meas->inst_stride_length); // Flags field @@ -635,8 +593,10 @@ static uint16_t rsc_meas_value_encoded(rscs_meas_val_t *p_meas, uint8_t *p_encod } // Total distance field - if (s_rscs_env.rscs_init.feature & RSCS_FEAT_TOTAL_DISTANCE_BIT) { - if (p_meas->total_distance_present) { + if (s_rscs_env.rscs_init.feature & RSCS_FEAT_TOTAL_DISTANCE_BIT) + { + if (p_meas->total_distance_present) + { p_encoded_buffer[length++] = LO_UINT32_T(p_meas->total_distance); p_encoded_buffer[length++] = L2_UINT32_T(p_meas->total_distance); p_encoded_buffer[length++] = L3_UINT32_T(p_meas->total_distance); @@ -647,8 +607,10 @@ static uint16_t rsc_meas_value_encoded(rscs_meas_val_t *p_meas, uint8_t *p_encod } // Flags field - if (s_rscs_env.rscs_init.feature & RSCS_FEAT_RUNNING_OR_WALKING_STATUS_BIT) { - if (p_meas->is_run_or_walk) { + if (s_rscs_env.rscs_init.feature & RSCS_FEAT_RUNNING_OR_WALKING_STATUS_BIT) + { + if (p_meas->is_run_or_walk) + { flags |= RSCS_MEAS_FLAG_RUNNING_OR_WALKING_BIT; } } @@ -658,20 +620,52 @@ static uint16_t rsc_meas_value_encoded(rscs_meas_val_t *p_meas, uint8_t *p_encod return length; } +static void rscs_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + rscs_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + rscs_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + rscs_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + rscs_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.cccd_recovery); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + rscs_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ sdk_err_t rscs_measurement_send(uint8_t conn_idx, rscs_meas_val_t *p_meas) { - sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - uint8_t encoded_rsc_meas[RSCS_MEAS_VAL_LEN_MAX]; - uint16_t length; - gatts_noti_ind_t rsc_ntf; + sdk_err_t error_code = SDK_ERR_NTF_DISABLED; + uint8_t encoded_rsc_meas[RSCS_MEAS_VAL_LEN_MAX]; + uint16_t length; + ble_gatts_noti_ind_t rsc_ntf; length = rsc_meas_value_encoded(p_meas, encoded_rsc_meas); - if (PRF_CLI_START_NTF == s_rscs_env.meas_ntf_cfg[conn_idx]) { + if (PRF_CLI_START_NTF == s_rscs_env.meas_ntf_cfg[conn_idx]) + { rsc_ntf.type = BLE_GATT_NOTIFICATION; rsc_ntf.handle = prf_find_handle_by_idx(RSCS_IDX_RSC_MEAS_VAL, s_rscs_env.start_hdl, @@ -686,10 +680,11 @@ sdk_err_t rscs_measurement_send(uint8_t conn_idx, rscs_meas_val_t *p_meas) sdk_err_t rscs_ctrl_pt_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t ctrl_pt_rsp; + sdk_err_t error_code = SDK_ERR_IND_DISABLED; + ble_gatts_noti_ind_t ctrl_pt_rsp; - if (PRF_CLI_START_IND == s_rscs_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_rscs_env.ctrl_point_ind_cfg[conn_idx]) + { ctrl_pt_rsp.type = BLE_GATT_INDICATION; ctrl_pt_rsp.handle = prf_find_handle_by_idx(RSCS_IDX_CTRL_POINT_VAL, s_rscs_env.start_hdl, @@ -706,9 +701,12 @@ sdk_err_t rscs_sensor_loc_update(rscs_sensor_loc_t sensor_loc) { sdk_err_t error_code = BLE_SUCCESS; - if (s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (s_rscs_env.rscs_init.feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) + { s_rscs_env.rscs_init.sensor_location = sensor_loc; - } else { + } + else + { error_code = SDK_ERR_DISALLOWED; } @@ -717,22 +715,32 @@ sdk_err_t rscs_sensor_loc_update(rscs_sensor_loc_t sensor_loc) sdk_err_t rscs_service_init(rscs_init_t *p_rscs_init) { - sdk_err_t ret; - if (p_rscs_init == NULL) { + if (NULL == p_rscs_init) + { return SDK_ERR_POINTER_NULL; } - if (p_rscs_init->feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) { + if (p_rscs_init->feature & RSCS_FEAT_MULTIPLE_SENSORS_BIT) + { p_rscs_init->char_mask |= RSCS_CHAR_SENSOR_LOC_SUP; - } else { + } + else + { p_rscs_init->char_mask &= ~RSCS_CHAR_SENSOR_LOC_SUP; } - ret = memcpy_s(&s_rscs_env.rscs_init, sizeof(rscs_init_t), p_rscs_init, sizeof(rscs_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_rscs_env.rscs_init, p_rscs_init, sizeof(rscs_init_t)); - return ble_server_prf_add(&rscs_prf_info); + s_rscs_env.start_hdl = PRF_INVALID_HANDLE; + + s_rscs_env.rscs_gatts_db.shdl = &s_rscs_env.start_hdl; + s_rscs_env.rscs_gatts_db.uuid = s_rscs_svc_uuid; + s_rscs_env.rscs_gatts_db.attr_tab_cfg = (uint8_t *)&(s_rscs_env.rscs_init.char_mask); + s_rscs_env.rscs_gatts_db.max_nb_attr = RSCS_IDX_NB; + s_rscs_env.rscs_gatts_db.srvc_perm = 0; + s_rscs_env.rscs_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_rscs_env.rscs_gatts_db.attr_tab.attr_tab_16 = rscs_attr_tab; + + return ble_gatts_prf_add(&s_rscs_env.rscs_gatts_db, rscs_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.h index 496b4f6..51c932a 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs/rscs.h @@ -47,52 +47,46 @@ * @brief Definitions and prototypes for the RSCS interface. * * @details The Running Speed and Cadence (RSC) Service exposes speed, cadence and other data related to - * fitness applications such as the stride length and the total distance the user has traveled + * fitness applications such as the stride length and the total distance the user has traveled * while using the Running Speed and Cadence sensor (Server). This module implements the Running * Speed and Cadence Service with RSC Measurement, RSC Feature, Sensor Location and SC Control * Point characteristics. * * After \ref rscs_init_t variable is initialized, the application must call \ref rscs_service_init() - * to add the Running Speed and Cadence Service and RSC Measurement, RSC Feature, Sensor Location and + * to add the Running Speed and Cadence Service and RSC Measurement, RSC Feature, Sensor Location and * SC Control Point characteristics to the BLE Stack database according to \ref rscs_init_t.char_mask. */ #ifndef __RSCS_H__ #define __RSCS_H__ +#include "gr_includes.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup RSCS_MACRO Defines * @{ */ -#define RSCS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Running Speed and \ - Cadence Service connections. */ -#define RSCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of RSC measurement value. */ -#define RSCS_FEAT_VAL_LEN_MAX 2 /**< Maximum length of RSC Feature value. */ -#define RSCS_SENSOR_LOC_VAL_LEN_MAX 1 /**< Maximum length of RSC Sensor Location value. */ -#define RSCS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of SC Control Point responce value. */ -/**< Maximum length of SC Control Point value. */ -#define RSCS_CTRL_PT_VAL_LEN_MAX (RSCS_CTRL_PT_RSP_LEN_MIN + RSCS_SENSOR_LOC_SUP_NB) +#define RSCS_CONNECTION_MAX 10 /**< Maximum number of Running Speed and Cadence Service connections. */ +#define RSCS_MEAS_VAL_LEN_MAX 20 /**< Maximum length of RSC measurement value. */ +#define RSCS_FEAT_VAL_LEN_MAX 2 /**< Maximum length of RSC Feature value. */ +#define RSCS_SENSOR_LOC_VAL_LEN_MAX 1 /**< Maximum length of RSC Sensor Location value. */ +#define RSCS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of SC Control Point responce value. */ +#define RSCS_CTRL_PT_VAL_LEN_MAX (RSCS_CTRL_PT_RSP_LEN_MIN + RSCS_SENSOR_LOC_SUP_NB) /**< Maximum length of SC Control Point value. */ -#define RSCS_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point operation \ - is still in progress. */ -#define RSCS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor \ - is not configured. */ +#define RSCS_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point operation is still in progress. */ +#define RSCS_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor is not configured. */ /** * @defgroup RSCS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref rscs_init_t.char_mask. */ -#define RSCS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in RSCS.*/ -#define RSCS_CHAR_SENSOR_LOC_SUP 0x00c0 /**< Bit mask for Sensor Location characteristic that is optional.*/ -#define RSCS_CHAR_SC_CTRL_POINT 0x0700 /**< Bit mask for SC Control Point characteristic that is optional.*/ -#define RSCS_CHAR_FULL 0x07ff /**< Bit mask of the full characteristic.*/ +#define RSCS_CHAR_MANDATORY 0x003f /**< Bit mask for mandatory characteristic in RSCS. */ +#define RSCS_CHAR_SENSOR_LOC_SUP 0x00c0 /**< Bit mask for Sensor Location characteristic that is optional. */ +#define RSCS_CHAR_SC_CTRL_POINT 0x0700 /**< Bit mask for SC Control Point characteristic that is optional. */ +#define RSCS_CHAR_FULL 0x07ff /**< Bit mask of the full characteristic. */ /** @} */ /** @@ -100,9 +94,9 @@ * @{ * @brief Running Speed and Cadence Measurement Flags. */ -#define RSCS_MEAS_FLAG_INST_STRIDE_LEN_BIT (0x01 << 0) /**< Flag bit for Instantaneous Stride Length Measurement.*/ -#define RSCS_MEAS_FLAG_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Flag bit for Total Distance Measurement.*/ -#define RSCS_MEAS_FLAG_RUNNING_OR_WALKING_BIT (0x01 << 2) /**< Flag bit for Running or Walking.*/ +#define RSCS_MEAS_FLAG_INST_STRIDE_LEN_BIT (0x01 << 0) /**< Flag bit for Instantaneous Stride Length Measurement. */ +#define RSCS_MEAS_FLAG_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Flag bit for Total Distance Measurement. */ +#define RSCS_MEAS_FLAG_RUNNING_OR_WALKING_BIT (0x01 << 2) /**< Flag bit for Running or Walking. */ /** @} */ /** @@ -110,13 +104,12 @@ * @{ * @brief Running Speed and Cadence Service feature bits. */ -/**< Bit for Instantaneous Stride Length Measurement Supported.*/ -#define RSCS_FEAT_INSTANT_STRIDE_LEN_BIT (0x01 << 0) -#define RSCS_FEAT_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Bit for Total Distance Measurement Supported. */ -#define RSCS_FEAT_RUNNING_OR_WALKING_STATUS_BIT (0x01 << 2) /**< Bit for Running or Walking Status Supported. */ -#define RSCS_FEAT_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Bit for Calibration Procedure Supported. */ -#define RSCS_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Bit for Multiple Sensor Locations Supported. */ -#define RSCS_FEAR_FULL_BIT (0x1f) /**< Bit for all RSC features Supported. */ +#define RSCS_FEAT_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Bit for Instantaneous Stride Length Measurement Supported. */ +#define RSCS_FEAT_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Bit for Total Distance Measurement Supported. */ +#define RSCS_FEAT_RUNNING_OR_WALKING_STATUS_BIT (0x01 << 2) /**< Bit for Running or Walking Status Supported. */ +#define RSCS_FEAT_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Bit for Calibration Procedure Supported. */ +#define RSCS_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Bit for Multiple Sensor Locations Supported. */ +#define RSCS_FEAR_FULL_BIT (0x1f) /**< Bit for all RSC features Supported. */ /** @} */ /** @} */ @@ -125,7 +118,8 @@ * @{ */ /**@brief Running Speed and Cadence Service Sensor Location. */ -typedef enum { +typedef enum +{ RSCS_SENSOR_LOC_OTHER, /**< Sensor location: other. */ RSCS_SENSOR_LOC_SHOE_TOP, /**< Sensor location: top of shoe. */ RSCS_SENSOR_LOC_SHOE_IN, /**< Sensor location: inside of shoe. */ @@ -138,7 +132,8 @@ typedef enum { } rscs_sensor_loc_t; /**@brief Running Speed and Cadence Service Control Point Operation Code.*/ -typedef enum { +typedef enum +{ RSCS_CTRL_PT_OP_RESERVED, /**< Reserved for future use. */ RSCS_CTRL_PT_OP_SET_CUMUL_VAL, /**< Set Cumulative value Operation Code.*/ RSCS_CTRL_PT_OP_START_CALIB, /**< Start Sensor Calibration Operation Code.*/ @@ -148,7 +143,8 @@ typedef enum { } rscs_ctrl_pt_op_code_t; /**@brief Running Speed and Cadence Service Control Point Response value.*/ -typedef enum { +typedef enum +{ RSCS_CTRL_PT_RSP_RESERVED, /**< Reserved value. */ RSCS_CTRL_PT_RSP_SUCCESS, /**< Operation Succeeded. */ RSCS_CTRL_PT_RSP_NOT_SUP, /**< Operation Code Not Supported. */ @@ -157,18 +153,19 @@ typedef enum { } rscs_ctrl_pt_rsp_t; /**@brief Running Speed and Cadence Service event type.*/ -typedef enum { - RSCS_EVT_INVALID, /**< Indicate that invalid event. */ - RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE, /**< Indicate that RSC Measurement notification has been enabled. */ - RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE, /**< Indicate that RSC Measurement notification has been disabled. */ - RSCS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that SC Control Point indication has been enabled. */ - RSCS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that SC Control Point indication has been disabled. */ - RSCS_EVT_RSC_MEAS_SEND_CPLT, /**< Indicate that RSC Measurement has been notified. */ - RSCS_EVT_CUMUL_VAL_SET, /**< Indicate that Total Distance value needs to be set. */ - RSCS_EVT_SEBSOR_CALIBRATION, /**< Indicate that Sensor calibration procedure should be initiated. */ - RSCS_EVT_SEBSOR_LOC_UPD, /**< Indicate that Sensor Location needs to be reset. */ - RSCS_EVT_SUP_SEBSOR_LOC_REQ, /**< Indicate that request supported sensor location list. */ - RSCS_EVT_CTRL_POINT_RSP_CPLT /**< Indicate that SC Control Point response has been indicated. */ +typedef enum +{ + RSCS_EVT_INVALID, /**< Indicate that invalid event. */ + RSCS_EVT_RSC_MEAS_NOTIFICATION_ENABLE, /**< Indicate that RSC Measurement notification has been enabled. */ + RSCS_EVT_RSC_MEAS_NOTIFICATION_DISABLE, /**< Indicate that RSC Measurement notification has been disabled. */ + RSCS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that SC Control Point indication has been enabled. */ + RSCS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that SC Control Point indication has been disabled. */ + RSCS_EVT_RSC_MEAS_SEND_CPLT, /**< Indicate that RSC Measurement has been notified. */ + RSCS_EVT_CUMUL_VAL_SET, /**< Indicate that Total Distance value needs to be set. */ + RSCS_EVT_SEBSOR_CALIBRATION, /**< Indicate that Sensor calibration procedure should be initiated. */ + RSCS_EVT_SEBSOR_LOC_UPD, /**< Indicate that Sensor Location needs to be reset. */ + RSCS_EVT_SUP_SEBSOR_LOC_REQ, /**< Indicate that request supported sensor location list. */ + RSCS_EVT_CTRL_POINT_RSP_CPLT /**< Indicate that SC Control Point response has been indicated. */ } rscs_evt_type_t; /** @} */ @@ -177,7 +174,8 @@ typedef enum { * @{ */ /**@brief Running Speed and Cadence Service event. */ -typedef struct { +typedef struct +{ rscs_evt_type_t evt_type; /**< The RSCS event type. */ uint8_t conn_idx; /**< The index of the connection. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -185,7 +183,8 @@ typedef struct { } rscs_evt_t; /**@brief Running Speed and Cadence Measurement Character value structure. */ -typedef struct { +typedef struct +{ bool inst_stride_length_present; /**< If Instantaneous Stride Length is present. */ bool total_distance_present; /**< If Total Distance is present. */ bool is_run_or_walk; /**< True: Running, False: Walking. */ @@ -208,12 +207,11 @@ typedef void (*rscs_evt_handler_t)(rscs_evt_t *p_evt); * @defgroup RSCS_STRUCT Structures * @{ */ -/**@brief Running Speed and Cadence Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Running Speed and Cadence Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ rscs_evt_handler_t evt_handler; /**< Running Speed and Cadence Service event handler. */ - uint16_t - char_mask; /**< Initial mask of supported characteristics, and configured with \ref RSCS_CHAR_MASK. */ + uint16_t char_mask; /**< Initial mask of supported characteristics, and configured with \ref RSCS_CHAR_MASK. */ rscs_sensor_loc_t sensor_location; /**< Initial sensor location. */ uint16_t feature; /**< Initial value for features. */ } rscs_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/BUILD.gn new file mode 100644 index 0000000..f50eeb0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("rscs_c") { + sources = [ "rscs_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.c index eeac0da..25824fd 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.c @@ -39,67 +39,32 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "rscs_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "rscs_c.h" +#include -#define UUID_OFFSET_8 8 -#define INDIX_OFFSET_1 1 -#define INDIX_OFFSET_2 2 -#define INDIX_OFFSET_3 3 -#define ATTR_VALUE_LEN 2 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Running Speed and Cadence Service Client environment variable. */ -struct rscs_c_env_t { +struct rscs_c_env_t +{ rscs_c_handles_t handles; /**< Handles of RSCS characteristics which will be got for peer. */ rscs_c_evt_handler_t evt_handler; /**< Handler of RSCS Client event */ - uint8_t prf_id; /**< RSCS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void rscs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void rscs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void rscs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void rscs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct rscs_c_env_t s_rscs_c_env; /**< Running Speed and Cadence Service Client environment variable. */ - -/**@brief Running Speed and Cadence Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t rscs_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Running Speed and Cadence Service GATT Client Callbacks. */ -static gattc_prf_cbs_t rscs_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - rscs_c_att_read_cb, - rscs_c_att_write_cb, - rscs_c_att_ntf_ind_cb, - rscs_c_srvc_browse_cb, - NULL, -}; - -/**@brief Running Speed and Cadence Service Client Information. */ -static const prf_client_info_t rscs_c_prf_info = { - .max_connection_nb = RSCS_C_CONNECTION_MAX, - .manager_cbs = &rscs_c_mgr_cbs, - .gattc_prf_cbs = &rscs_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_RUNNING_SPEED_CADENCE), HI_U16(BLE_ATT_SVC_RUNNING_SPEED_CADENCE)}; +static ble_uuid_t s_rscs_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -115,7 +80,8 @@ static const prf_client_info_t rscs_c_prf_info = { */ static void rscs_c_evt_handler_excute(rscs_c_evt_t *p_evt) { - if (s_rscs_c_env.evt_handler != NULL && RSCS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_rscs_c_env.evt_handler && RSCS_C_EVT_INVALID != p_evt->evt_type) + { s_rscs_c_env.evt_handler(p_evt); } } @@ -133,12 +99,8 @@ static void rscs_c_meas_value_encode(uint8_t *p_data, uint16_t length, rscs_c_me { uint8_t flags = 0; uint8_t index = 0; - uint8_t ret = 0; flags = p_data[index++]; - ret = memset_s(p_rsc_meas_buff, sizeof(rscs_c_meas_val_t), 0, sizeof(rscs_c_meas_val_t)); - if (ret < 0) { - return; - } + memset(p_rsc_meas_buff, 0, sizeof(rscs_c_meas_val_t)); // Instantaneous speed field p_rsc_meas_buff->inst_speed = BUILD_U16(p_data[index], p_data[index + 1]); index += sizeof(uint16_t); @@ -146,26 +108,31 @@ static void rscs_c_meas_value_encode(uint8_t *p_data, uint16_t length, rscs_c_me p_rsc_meas_buff->inst_cadence = p_data[index++]; // Instantaneous stride length field - if (flags & RSCS_C_MEAS_FLAG_INST_STRIDE_LEN_BIT) { + if (flags & RSCS_C_MEAS_FLAG_INST_STRIDE_LEN_BIT) + { p_rsc_meas_buff->inst_stride_length_present = true; p_rsc_meas_buff->inst_stride_length = BUILD_U16(p_data[index], p_data[index + 1]); index += sizeof(uint16_t); } // Total distance field - if (flags & RSCS_C_MEAS_FLAG_TOTAL_DISTANCE_BIT) { + if (flags & RSCS_C_MEAS_FLAG_TOTAL_DISTANCE_BIT) + { p_rsc_meas_buff->total_distance_present = true; p_rsc_meas_buff->total_distance = BUILD_U32(p_data[index], - p_data[index + INDIX_OFFSET_1], - p_data[index + INDIX_OFFSET_2], - p_data[index + INDIX_OFFSET_3]); + p_data[index + 1], + p_data[index + 2], + p_data[index + 3]); index += sizeof(uint32_t); } // Running or Walking field - if (flags & RSCS_C_MEAS_FLAG_RUNNING_OR_WALKING_BIT) { + if (flags & RSCS_C_MEAS_FLAG_RUNNING_OR_WALKING_BIT) + { p_rsc_meas_buff->is_run_or_walk = true; - } else { + } + else + { p_rsc_meas_buff->is_run_or_walk = false; } } @@ -179,23 +146,27 @@ static void rscs_c_meas_value_encode(uint8_t *p_data, uint16_t length, rscs_c_me * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void rscs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void rscs_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { rscs_c_evt_t rscs_c_evt; rscs_c_evt.conn_idx = conn_idx; rscs_c_evt.evt_type = RSCS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_rscs_c_env.handles.rscs_rsc_feature_handle) { + if (p_read_rsp->value[0].handle == s_rscs_c_env.handles.rscs_rsc_feature_handle) + { rscs_c_evt.evt_type = RSCS_C_EVT_RSC_FEATURE_RECEIVE; - rscs_c_evt.value.rsc_feature = BUILD_U16(p_read_rsp->vals[0].p_value[0], p_read_rsp->vals[0].p_value[1]); - } else if (p_read_rsp->vals[0].handle == s_rscs_c_env.handles.rscs_sensor_loc_handle) { + rscs_c_evt.value.rsc_feature = BUILD_U16(p_read_rsp->value[0].p_value[0], p_read_rsp->value[0].p_value[1]); + } + else if (p_read_rsp->value[0].handle == s_rscs_c_env.handles.rscs_sensor_loc_handle) + { rscs_c_evt.evt_type = RSCS_C_EVT_SENSOR_LOC_RECEIVE; - rscs_c_evt.value.rsc_sensor_loc = (rscs_c_sensor_loc_t)p_read_rsp->vals[0].p_value[0]; + rscs_c_evt.value.rsc_sensor_loc = (rscs_c_sensor_loc_t)p_read_rsp->value[0].p_value[0]; } rscs_c_evt_handler_excute(&rscs_c_evt); @@ -210,25 +181,30 @@ static void rscs_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void rscs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void rscs_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { rscs_c_evt_t rscs_c_evt; rscs_c_evt.conn_idx = conn_idx; rscs_c_evt.evt_type = RSCS_C_EVT_INVALID; - if (handle == s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle) { + if (handle == s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle) + { rscs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - RSCS_C_EVT_RSC_MEAS_NTF_SET_SUCCESS : - RSCS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle) { + RSCS_C_EVT_RSC_MEAS_NTF_SET_SUCCESS : + RSCS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle) + { rscs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - RSCS_C_EVT_CTRL_PT_IND_SET_SUCCESS : - RSCS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_rscs_c_env.handles.rscs_ctrl_pt_handle) { + RSCS_C_EVT_CTRL_PT_IND_SET_SUCCESS : + RSCS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_rscs_c_env.handles.rscs_ctrl_pt_handle) + { rscs_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - RSCS_C_EVT_CTRL_PT_SET_SUCCESS : - RSCS_C_EVT_WRITE_OP_ERR; + RSCS_C_EVT_CTRL_PT_SET_SUCCESS : + RSCS_C_EVT_WRITE_OP_ERR; } rscs_c_evt_handler_excute(&rscs_c_evt); @@ -243,23 +219,22 @@ static void rscs_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handl * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void rscs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void rscs_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { rscs_c_evt_t rscs_c_evt; - uint8_t ret; rscs_c_evt.conn_idx = conn_idx; rscs_c_evt.evt_type = RSCS_C_EVT_INVALID; - if (p_ntf_ind->handle == s_rscs_c_env.handles.rscs_rsc_meas_handle) { + if (p_ntf_ind->handle == s_rscs_c_env.handles.rscs_rsc_meas_handle) + { rscs_c_evt.evt_type = RSCS_C_EVT_RSC_MEAS_VAL_RECEIVE; rscs_c_meas_value_encode(p_ntf_ind->p_value, p_ntf_ind->length, &rscs_c_evt.value.rsc_meas_buff); - } else if (p_ntf_ind->handle == s_rscs_c_env.handles.rscs_ctrl_pt_handle) { + } + else if (p_ntf_ind->handle == s_rscs_c_env.handles.rscs_ctrl_pt_handle) + { rscs_c_evt.evt_type = RSCS_C_EVT_CTRL_PT_RSP_RECEIVE; - ret = memcpy_s(rscs_c_evt.value.ctrl_pt_rsp, p_ntf_ind->p_value, p_ntf_ind->length); - if (ret < 0) { - return; - } + memcpy(rscs_c_evt.value.ctrl_pt_rsp, p_ntf_ind->p_value, p_ntf_ind->length); } rscs_c_evt_handler_excute(&rscs_c_evt); @@ -274,7 +249,7 @@ static void rscs_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void rscs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void rscs_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { rscs_c_evt_t rscs_c_evt; uint16_t uuid_disc; @@ -283,143 +258,158 @@ static void rscs_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_ga rscs_c_evt.conn_idx = conn_idx; rscs_c_evt.evt_type = RSCS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << UUID_OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_RUNNING_SPEED_CADENCE == uuid_disc) { - s_rscs_c_env.handles.rscs_srvc_start_handle = p_browse_srvc->start_hdl; - s_rscs_c_env.handles.rscs_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_RUNNING_SPEED_CADENCE == uuid_disc) + { + s_rscs_c_env.handles.rscs_srvc_start_handle = p_browse_srvc->start_hdl; + s_rscs_c_env.handles.rscs_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << UUID_OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_RSC_MEAS == uuid_disc) { - s_rscs_c_env.handles.rscs_rsc_meas_handle = handle_disc; - s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle = handle_disc + 1; - } else if (BLE_ATT_CHAR_RSC_FEAT == uuid_disc) { - s_rscs_c_env.handles.rscs_rsc_feature_handle = handle_disc; - } else if (BLE_ATT_CHAR_SENSOR_LOC == uuid_disc) { - s_rscs_c_env.handles.rscs_sensor_loc_handle = handle_disc; - } else if (BLE_ATT_CHAR_SC_CNTL_PT == uuid_disc) { - s_rscs_c_env.handles.rscs_ctrl_pt_handle = handle_disc; - s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle = handle_disc + 1; - } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_RSC_MEAS == uuid_disc) + { + s_rscs_c_env.handles.rscs_rsc_meas_handle = handle_disc; + s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle = handle_disc + 1; + } + else if (BLE_ATT_CHAR_RSC_FEAT == uuid_disc) + { + s_rscs_c_env.handles.rscs_rsc_feature_handle = handle_disc; + } + else if (BLE_ATT_CHAR_SENSOR_LOC == uuid_disc) + { + s_rscs_c_env.handles.rscs_sensor_loc_handle = handle_disc; + } + else if (BLE_ATT_CHAR_SC_CNTL_PT == uuid_disc) + { + s_rscs_c_env.handles.rscs_ctrl_pt_handle = handle_disc; + s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle = handle_disc + 1; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; + } } - } - rscs_c_evt.evt_type = RSCS_C_EVT_DISCOVERY_COMPLETE; + rscs_c_evt.evt_type = RSCS_C_EVT_DISCOVERY_COMPLETE; + } } rscs_c_evt_handler_excute(&rscs_c_evt); } +static void rscs_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + rscs_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_READ_RSP: + rscs_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + rscs_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + rscs_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t rscs_client_init(rscs_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_rscs_c_env, sizeof(s_rscs_c_env), 0, sizeof(s_rscs_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_rscs_c_env, 0, sizeof(s_rscs_c_env)) ; s_rscs_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&rscs_c_prf_info, &s_rscs_c_env.prf_id); + return ble_gattc_prf_add(&s_rscs_service_uuid, rscs_c_ble_evt_handler); } sdk_err_t rscs_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - target_uuid[0] = LO_U16(BLE_ATT_SVC_RUNNING_SPEED_CADENCE); - target_uuid[1] = HI_U16(BLE_ATT_SVC_RUNNING_SPEED_CADENCE); - const ble_uuid_t rscs_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_rscs_c_env.prf_id, conn_idx, &rscs_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_rscs_service_uuid); } sdk_err_t rscs_c_rsc_meas_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_rscs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_rscs_c_env.handles.rscs_rsc_meas_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t rscs_c_rsc_feature_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_rsc_feature_handle) { + if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_rsc_feature_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_rscs_c_env.prf_id, conn_idx, s_rscs_c_env.handles.rscs_rsc_feature_handle, 0); + return ble_gattc_read(conn_idx, s_rscs_c_env.handles.rscs_rsc_feature_handle, 0); } sdk_err_t rscs_c_sensor_loc_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_sensor_loc_handle) { + if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_sensor_loc_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_rscs_c_env.prf_id, conn_idx, s_rscs_c_env.handles.rscs_sensor_loc_handle, 0); + return ble_gattc_read(conn_idx, s_rscs_c_env.handles.rscs_sensor_loc_handle, 0); } sdk_err_t rscs_c_ctrl_pt_indicate_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ind_value = is_enable ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ind_value; - - return ble_gattc_prf_write(s_rscs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_rscs_c_env.handles.rscs_ctrl_pt_cccd_handle, 0, 2, (uint8_t *)&ind_value); } sdk_err_t rscs_c_ctrl_pt_set(uint8_t conn_idx, uint16_t ctrl_value) { - gattc_write_attr_value_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_ctrl_pt_handle) { + if (BLE_ATT_INVALID_HDL == s_rscs_c_env.handles.rscs_ctrl_pt_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_rscs_c_env.handles.rscs_ctrl_pt_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ctrl_value; - - return ble_gattc_prf_write(s_rscs_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_rscs_c_env.handles.rscs_ctrl_pt_handle, 0, 2, (uint8_t *)&ctrl_value); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.h index 0a1435e..0433fcf 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rscs_c/rscs_c.h @@ -52,41 +52,36 @@ * After Running Speed and Cadence Service Client discoveries peer Running Speed and Cadence Service, * application can call \ref rscs_c_rsc_meas_notify_set(), then will receive Running Speed and Cadence * data from peer, and can call \ref rscs_c_sensor_loc_read() and \ref rscs_c_rsc_feature_read() to get - * sensor location information and the supported features of the Server, - * also can call \ref rscs_c_ctrl_pt_set() + * sensor location information and the supported features of the Server, also can call \ref rscs_c_ctrl_pt_set() * to send control point to peer. */ #ifndef __RSCS_C_H__ #define __RSCS_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup RSCS_C_MACRO Defines * @{ */ -#define RSCS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of HRS Client connections. */ -/**< Maximum length of SC Control Point response value. */ -#define RSCS_C_PT_RSP_LEN_MAX (3 + RSCS_C_SENSOR_LOC_SUP_NB) -#define RSCS_C_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point \ - operation is still in progress. */ -#define RSCS_C_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration \ - descriptor is not configured. */ +#define RSCS_C_CONNECTION_MAX 10 /**< Maximum number of HRS Client connections. */ +#define RSCS_C_PT_RSP_LEN_MAX (3 + RSCS_C_SENSOR_LOC_SUP_NB) /**< Maximum length of SC Control Point response value. */ +#define RSCS_C_ERROR_PROC_IN_PROGRESS 0x80 /**< Error code: A previously triggered SC Control Point operation is still in progress. */ +#define RSCS_C_ERROR_CCCD_INVALID 0x81 /**< Error code: The Client Characteristic Configuration descriptor is not configured. */ /** * @defgroup RSCS_C_MEAS_FLAG_BIT Measurement Flag Bits * @{ * @brief Running Speed and Cadence Measurement Flags. */ -#define RSCS_C_MEAS_FLAG_INST_STRIDE_LEN_BIT (0x01 << 0) /**< Flag bit for Instantaneous Stride Length Measurement.*/ -#define RSCS_C_MEAS_FLAG_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Flag bit for Total Distance Measurement. */ -#define RSCS_C_MEAS_FLAG_RUNNING_OR_WALKING_BIT (0x01 << 2) /**< Flag bit for Running or Walking. */ +#define RSCS_C_MEAS_FLAG_INST_STRIDE_LEN_BIT (0x01 << 0) /**< Flag bit for Instantaneous Stride Length Measurement. */ +#define RSCS_C_MEAS_FLAG_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Flag bit for Total Distance Measurement. */ +#define RSCS_C_MEAS_FLAG_RUNNING_OR_WALKING_BIT (0x01 << 2) /**< Flag bit for Running or Walking. */ /** @} */ /** @@ -94,12 +89,11 @@ * @{ * @brief Running Speed and Cadence Service feature bits. */ -#define RSCS_C_FEAT_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Bit for Instantaneous Stride Length \ - Measurement Supported. */ -#define RSCS_C_FEAT_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Bit for Total Distance Measurement Supported.*/ -#define RSCS_C_FEAT_RUNNING_OR_WALKING_STATUS_BIT (0x01 << 2) /**< Bit for Running or Walking Status Supported.*/ -#define RSCS_C_FEAT_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Bit for Calibration Procedure Supported.*/ -#define RSCS_C_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Bit for Multiple Sensor Locations Supported.*/ +#define RSCS_C_FEAT_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Bit for Instantaneous Stride Length Measurement Supported. */ +#define RSCS_C_FEAT_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Bit for Total Distance Measurement Supported. */ +#define RSCS_C_FEAT_RUNNING_OR_WALKING_STATUS_BIT (0x01 << 2) /**< Bit for Running or Walking Status Supported. */ +#define RSCS_C_FEAT_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Bit for Calibration Procedure Supported. */ +#define RSCS_C_FEAT_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Bit for Multiple Sensor Locations Supported. */ /** @} */ /** @} */ @@ -108,23 +102,24 @@ * @{ */ /**@brief Running Speed and Cadence Service Client event type. */ -typedef enum { - RSCS_C_EVT_INVALID, /**< RSCS Client invalid event. */ +typedef enum +{ + RSCS_C_EVT_INVALID, /*<* RSCS Client invalid event. */ RSCS_C_EVT_DISCOVERY_COMPLETE, /**< RSCS Client has found RSCS service and its characteristics. */ - RSCS_C_EVT_DISCOVERY_FAIL, /**< RSCS Client found RSCS service failed because of invalid operation \ - or no found at the peer. */ + RSCS_C_EVT_DISCOVERY_FAIL, /**< RSCS Client found RSCS service failed because of invalid operation or no found at the peer. */ RSCS_C_EVT_RSC_MEAS_NTF_SET_SUCCESS, /**< RSCS Client has set Notification of RSC Measure characteristic. */ RSCS_C_EVT_CTRL_PT_IND_SET_SUCCESS, /**< RSCS Client has set Indication of Control Point characteristic. */ - RSCS_C_EVT_RSC_MEAS_VAL_RECEIVE, /**< RSCS Client has received RSC Measurement value notification from peer.*/ + RSCS_C_EVT_RSC_MEAS_VAL_RECEIVE, /**< RSCS Client has received RSC Measurement value notification from peer. */ RSCS_C_EVT_RSC_FEATURE_RECEIVE, /**< RSCS Client has received RSC Feature Value read response. */ RSCS_C_EVT_SENSOR_LOC_RECEIVE, /**< RSCS Client has received Sensor Location Value read response. */ RSCS_C_EVT_CTRL_PT_SET_SUCCESS, /**< RSCS Client has writen Control Point completely. */ - RSCS_C_EVT_CTRL_PT_RSP_RECEIVE, /**< RSCS Client has received Indication of Control Point characteristic.*/ + RSCS_C_EVT_CTRL_PT_RSP_RECEIVE, /**< RSCS Client has received Indication of Control Point characteristic. */ RSCS_C_EVT_WRITE_OP_ERR, /**< Error occured when RSCS Client writen to peer. */ } rscs_c_evt_type_t; /**@brief Running Speed and Cadence Service Sensor Location. */ -typedef enum { +typedef enum +{ RSCS_C_SENSOR_LOC_OTHER, /**< Sensor location: other. */ RSCS_C_SENSOR_LOC_SHOE_TOP, /**< Sensor location: top of shoe. */ RSCS_C_SENSOR_LOC_SHOE_IN, /**< Sensor location: inside of shoe. */ @@ -137,7 +132,8 @@ typedef enum { } rscs_c_sensor_loc_t; /**@brief Running Speed and Cadence Service Control Point Operation Code.*/ -typedef enum { +typedef enum +{ RSCS_C_CTRL_PT_OP_RESERVED, /**< Reserved for future use. */ RSCS_C_CTRL_PT_OP_SET_CUMUL_VAL, /**< Set Cumulative value Operation Code.*/ RSCS_C_CTRL_PT_OP_START_CALIB, /**< Start Sensor Calibration Operation Code.*/ @@ -147,7 +143,8 @@ typedef enum { } rscs_c_ctrl_pt_op_code_t; /**@brief Running Speed and Cadence Service Control Point Response value.*/ -typedef enum { +typedef enum +{ RSCS_C_CTRL_PT_RSP_RESERVED, /**< Reserved value. */ RSCS_C_CTRL_PT_RSP_SUCCESS, /**< Operation Succeeded. */ RSCS_C_CTRL_PT_RSP_NOT_SUP, /**< Operation Code Not Supported. */ @@ -161,7 +158,8 @@ typedef enum { * @{ */ /**@brief Running Speed and Cadence Measurement Character value structure. */ -typedef struct { +typedef struct +{ bool inst_stride_length_present; /**< If Instantaneous Stride Length is present. */ bool total_distance_present; /**< If Total Distance is present. */ bool is_run_or_walk; /**< True: Running, False: Walking. */ @@ -172,34 +170,32 @@ typedef struct { } rscs_c_meas_val_t; /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t rscs_srvc_start_handle; /**< RSCS Service start handle. */ uint16_t rscs_srvc_end_handle; /**< RSCS Service end handle. */ - uint16_t rscs_rsc_meas_handle; /**< RSCS RSC Measurement characteristic Value handle \ - which has been got from peer. */ - uint16_t rscs_rsc_meas_cccd_handle; /**< RSCS CCCD handle of RSC Measurement characteristic \ - which has been got from peer. */ - uint16_t rscs_sensor_loc_handle; /**< RSCS Sensor Location characteristic Value handle \ - which has been got from peer. */ - uint16_t rscs_rsc_feature_handle; /**< RSCS RSC Feature characteristic Value handle \ - which has been got from peer. */ - uint16_t rscs_ctrl_pt_handle; /**< RSCS Control Point characteristic Value handle \ - which has been got from peer. */ - uint16_t rscs_ctrl_pt_cccd_handle; /**< RSCS CCCD handle of Control Point characteristic \ - which has been got from peer. */ + uint16_t rscs_rsc_meas_handle; /**< RSCS RSC Measurement characteristic Value handle which has been got from peer. */ + uint16_t rscs_rsc_meas_cccd_handle; /**< RSCS CCCD handle of RSC Measurement characteristic which has been got from peer. */ + uint16_t rscs_sensor_loc_handle; /**< RSCS Sensor Location characteristic Value handle which has been got from peer. */ + uint16_t rscs_rsc_feature_handle; /**< RSCS RSC Feature characteristic Value handle which has been got from peer. */ + uint16_t rscs_ctrl_pt_handle; /**< RSCS Control Point characteristic Value handle which has been got from peer. */ + uint16_t rscs_ctrl_pt_cccd_handle; /**< RSCS CCCD handle of Control Point characteristic which has been got from peer. */ } rscs_c_handles_t; /**@brief Running Speed and Cadence Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ rscs_c_evt_type_t evt_type; /**< RSCS Client event type. */ uint16_t handle; /**< Handle of characteristic. */ - union { + union + { rscs_c_meas_val_t rsc_meas_buff; /**< Buffer of RSC measurement value. */ uint16_t rsc_feature; /**< RSC feature received. */ rscs_c_sensor_loc_t rsc_sensor_loc; /**< RSC sensor location received. */ uint8_t ctrl_pt_rsp[RSCS_C_PT_RSP_LEN_MAX]; /**< SC Control Point Response. */ } value; /**< Decoded result of value received. */ + } rscs_c_evt_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/BUILD.gn new file mode 100644 index 0000000..6dfab52 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("rtus") { + sources = [ "rtus.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.c index ee8201e..d30e6ba 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.c @@ -49,7 +49,8 @@ **************************************************************************************** */ /**@brief Reference Time Update Service Attributes Indexes. */ -enum { +enum +{ // Reference Time Update Service RTUS_IDX_SVC, @@ -69,113 +70,48 @@ enum { ***************************************************************************************** */ /**@brief Reference Time Update Service environment variable. */ -struct rtus_env_t { +struct rtus_env_t +{ rtus_init_t rtus_init; /**< Reference Time Update Service initialization variables. */ uint16_t start_hdl; /**< Reference Time Update Service start handle. */ rtus_update_state_t update_state; /**< State of time update. */ + ble_gatts_create_db_t rtus_gatts_db; /**< Reference Time Update Service attributs database. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static sdk_err_t rtus_init(void); -static void rtus_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void rtus_write_att_cb(uint8_t conidx, const gatts_write_req_cb_t *p_param); /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct rtus_env_t s_rtus_env; +static const uint8_t s_rtus_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_REF_TIME_UPDATE); /**@brief Full RTUS Database Description - Used to add attributes into the database. */ -static const attm_desc_t rtus_attr_tab[RTUS_IDX_NB] = { +static const ble_gatts_attm_desc_t rtus_attr_tab[RTUS_IDX_NB] = +{ // RTUS Service Declaration - [RTUS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [RTUS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Time Update Control Point Characteristic Declaration - [RTUS_IDX_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RTUS_IDX_CTRL_PT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Time Update Control Point Characteristic Declaration value - [RTUS_IDX_CTRL_PT_VAL] = { - BLE_ATT_CHAR_TIME_UPDATE_CNTL_POINT, - WRITE_CMD_PERM(AUTH), - ATT_VAL_LOC_USER, - RTUS_CTRL_PT_VAL_LEN - }, + [RTUS_IDX_CTRL_PT_VAL] = {BLE_ATT_CHAR_TIME_UPDATE_CNTL_POINT, + BLE_GATTS_WRITE_CMD_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + RTUS_CTRL_PT_VAL_LEN}, // Time Update State Characteristic Declaration - [RTUS_IDX_UPDATE_STATE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [RTUS_IDX_UPDATE_STATE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Time Update State Characteristic Declaration value - [RTUS_IDX_UPDATE_STATE_VAL] = { - BLE_ATT_CHAR_TIME_UPDATE_STATE, - READ_PERM(AUTH), - ATT_VAL_LOC_USER, - RTUS_UPDATE_STATE_VAL_LEN - }, -}; - -/**@brief RTUS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t rtus_tack_cbs = { - (prf_init_func_t) rtus_init, - NULL, - NULL -}; - -/**@brief RTUS Task Callbacks. */ -static gatts_prf_cbs_t rtus_cb_func = { - rtus_read_att_cb, - rtus_write_att_cb, - NULL, - NULL -}; - -/**@brief RTUS Information. */ -static const prf_server_info_t rtus_prf_info = { - .max_connection_nb = RTUS_CONNECTION_MAX, - .manager_cbs = &rtus_tack_cbs, - .gatts_prf_cbs = &rtus_cb_func + [RTUS_IDX_UPDATE_STATE_VAL] = {BLE_ATT_CHAR_TIME_UPDATE_STATE, + BLE_GATTS_READ_PERM(BLE_GATTS_AUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + RTUS_UPDATE_STATE_VAL_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Reference Time Update service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t rtus_init(void) -{ - // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t rtus_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_REF_TIME_UPDATE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = rtus_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_rtus_env.rtus_init.char_mask); - gatts_db.max_nb_attr = RTUS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = rtus_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_rtus_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -184,9 +120,9 @@ static sdk_err_t rtus_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void rtus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void rtus_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, s_rtus_env.start_hdl, @@ -195,7 +131,8 @@ static void rtus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case RTUS_IDX_UPDATE_STATE_VAL: cfm.length = RTUS_UPDATE_STATE_VAL_LEN; cfm.value = (uint8_t *)&s_rtus_env.update_state; @@ -217,13 +154,13 @@ static void rtus_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_para * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void rtus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void rtus_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; rtus_ctrl_pt_t ctrl_pt; rtus_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_rtus_env.start_hdl, @@ -234,15 +171,21 @@ static void rtus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa event.evt_type = RTUS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case RTUS_IDX_CTRL_PT_VAL: ctrl_pt = (rtus_ctrl_pt_t)p_param->value[0]; - if (RTUS_CTRL_PT_GET_UPDATE == ctrl_pt) { + if (RTUS_CTRL_PT_GET_UPDATE == ctrl_pt) + { event.evt_type = RTUS_EVT_GET_UPDATE; - } else if (RTUS_CTRL_PT_CANCEL_UPDATE == ctrl_pt) { + } + else if (RTUS_CTRL_PT_CANCEL_UPDATE == ctrl_pt) + { event.evt_type = RTUS_EVT_CANCEL_UPDATE; - } else { + } + else + { break; } @@ -253,12 +196,31 @@ static void rtus_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_pa ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && RTUS_EVT_INVALID != event.evt_type - && s_rtus_env.rtus_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && RTUS_EVT_INVALID != event.evt_type && s_rtus_env.rtus_init.evt_handler) + { s_rtus_env.rtus_init.evt_handler(&event); } } +static void rtus_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + rtus_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + rtus_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -275,16 +237,23 @@ void rtus_update_result_set(rtus_update_result_t update_result) sdk_err_t rtus_service_init(rtus_init_t *p_rtus_init) { - sdk_err_t ret; - if (p_rtus_init == NULL) { + if (NULL == p_rtus_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_rtus_env.rtus_init, sizeof(rtus_init_t), p_rtus_init, sizeof(rtus_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_rtus_env.rtus_init, p_rtus_init, sizeof(rtus_init_t)); - return ble_server_prf_add(&rtus_prf_info); + s_rtus_env.start_hdl = PRF_INVALID_HANDLE; + + s_rtus_env.rtus_gatts_db.shdl = &s_rtus_env.start_hdl; + s_rtus_env.rtus_gatts_db.uuid = s_rtus_svc_uuid; + s_rtus_env.rtus_gatts_db.attr_tab_cfg = (uint8_t *)&(s_rtus_env.rtus_init.char_mask); + s_rtus_env.rtus_gatts_db.max_nb_attr = RTUS_IDX_NB; + s_rtus_env.rtus_gatts_db.srvc_perm = 0; + s_rtus_env.rtus_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_rtus_env.rtus_gatts_db.attr_tab.attr_tab_16 = rtus_attr_tab; + + return ble_gatts_prf_add(&s_rtus_env.rtus_gatts_db, rtus_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.h index b9b402a..5d92074 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/rtus/rtus.h @@ -57,20 +57,19 @@ #ifndef __RTUS_H__ #define __RTUS_H__ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup RTUS_MACRO Defines * @{ */ -#define RTUS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of RTUS connections. */ -#define RTUS_CTRL_PT_VAL_LEN 1 /**< Length of Time Update Control Point value. */ -#define RTUS_UPDATE_STATE_VAL_LEN 2 /**< Length of Time Update State value. */ -#define RTUS_CHAR_FULL 0x1f /**< Bit mask for mandatory characteristic in RTUS. */ +#define RTUS_CONNECTION_MAX 10 /**< Maximum number of RTUS connections. */ +#define RTUS_CTRL_PT_VAL_LEN 1 /**< Length of Time Update Control Point value. */ +#define RTUS_UPDATE_STATE_VAL_LEN 2 /**< Length of Time Update State value. */ +#define RTUS_CHAR_FULL 0x1f /**< Bit mask for mandatory characteristic in RTUS. */ /** @} */ /** @@ -78,19 +77,22 @@ * @{ */ /**@brief RTUS Time Update Control Point. */ -typedef enum { +typedef enum +{ RTUS_CTRL_PT_GET_UPDATE = 0x01, /**< Get reference update. */ RTUS_CTRL_PT_CANCEL_UPDATE, /**< Cancel reference update. */ } rtus_ctrl_pt_t; /**@brief RTUS Current State. */ -typedef enum { +typedef enum +{ RTUS_CUR_STATE_IDLE, /**< Idle update state. */ RTUS_CUR_STATE_PENDING, /**< Update pending state. */ } rtus_cur_state_t; /**@brief RTUS Time Update Result. */ -typedef enum { +typedef enum +{ RTUS_UPDATE_RESULT_SCCESSFUL, /**< Time update successful. */ RTUS_UPDATE_RESULT_CANCELED, /**< Time update canceled. */ RTUS_UPDATE_RESULT_NO_CONN_TO_REF, /**< No Connection To Reference. */ @@ -100,7 +102,8 @@ typedef enum { } rtus_update_result_t; /**@brief RTUS Event type. */ -typedef enum { +typedef enum +{ RTUS_EVT_INVALID, /**< Invalid event. */ RTUS_EVT_GET_UPDATE, /**< Get reference update. */ RTUS_EVT_CANCEL_UPDATE, /**< Cancel reference update. */ @@ -112,13 +115,15 @@ typedef enum { * @{ */ /**@brief RTUS Time Update State. */ -typedef struct { +typedef struct +{ rtus_cur_state_t cur_state; /**< RTUS Current State. */ rtus_update_result_t update_result; /**< Time Update Result. */ } rtus_update_state_t; /**@brief RTUS Event data. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ rtus_evt_type_t evt_type; /**< RTUS event type. */ } rtus_evt_t; @@ -136,9 +141,9 @@ typedef void (*rtus_evt_handler_t)(rtus_evt_t *p_evt); * @defgroup RTUS_STRUCT Structures * @{ */ -/**@brief Reference Time Update Service init structure. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief Reference Time Update Service init structure. This contains all option and data needed for initialization of the service. */ +typedef struct +{ rtus_evt_handler_t evt_handler; /**< Reference Time Update Service event handler. */ uint16_t char_mask; /**< Initial mask of supported characteristics. */ } rtus_init_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/BUILD.gn new file mode 100644 index 0000000..0ddf7d5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("sample") { + sources = [ "sample_service.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.c index a70b440..10f5b82 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.c @@ -1,9 +1,9 @@ /** ***************************************************************************************** * - * @file sample_profile.c + * @file sample_service.c * - * @brief sample_profile Server Implementation. + * @brief sample profile Server Implementation. * ***************************************************************************************** * @attention @@ -48,10 +48,8 @@ ***************************************************************************************** */ /**@brief The UUIDs of GUS characteristics. */ -#define SAMPLE_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, - 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x01, 0xED, 0xA6} -#define SAMPLE_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, - 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x01, 0xED, 0xA6} +#define SAMPLE_SERVER_TX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x01, 0xED, 0xA6} +#define SAMPLE_SERVER_RX_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x01, 0xED, 0xA6} /**@brief Macros for conversion of 128bit to 16bit UUID. */ #define ATT_128_PRIMARY_SERVICE BLE_ATT_16_TO_128_ARRAY(BLE_ATT_DECL_PRIMARY_SERVICE) @@ -63,7 +61,8 @@ ***************************************************************************************** */ /**@brief Sample Service Attributes Indexes. */ -enum samples_attr_idx_t { +enum samples_attr_idx_t +{ SAMPLES_IDX_SVC, SAMPLES_IDX_TX_CHAR, @@ -80,23 +79,14 @@ enum samples_attr_idx_t { ***************************************************************************************** */ /**@brief Samples Service environment variable. */ -typedef struct { - samples_init_t samples_init; /**< Sample Service initialization variables. */ - uint16_t start_hdl; /**< Service start handle. */ - uint16_t - tx_ntf_cfg[SAMPLES_CONNECTION_MAX]; /**< TX Character Notification configuration of peer devices. */ +typedef struct +{ + samples_init_t samples_init; /**< Sample Service initialization variables. */ + uint16_t start_hdl; /**< Service start handle. */ + uint16_t tx_ntf_cfg[SAMPLES_CONNECTION_MAX]; /**< TX Character Notification configuration of peer devices. */ + ble_gatts_create_db_t sample_gatts_db; /**< Running Speed and Cadence Service attributs database. */ } samples_env_t; -/* -* LOCAL FUNCTION DECLARATION -***************************************************************************************** -*/ -static sdk_err_t samples_init(void); -static void samples_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param); -static void samples_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param); -static void samples_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void samples_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** @@ -106,106 +96,40 @@ static uint8_t s_samples_ins_cnt = 0; /**< Number of static uint8_t s_now_ins_cnt = 0; static samples_evt_type_t s_now_notify_cmp_type = SAMPLES_EVT_TX_NOTIFY_COMPLETE; static const uint16_t s_samples_features = 0xFFFF; +static const uint8_t s_samples_svc_uuid[] = {SAMPLES_SERVICE_UUID}; /**@brief Full SAMPLES Database Description - Used to add attributes into the database. */ -static const attm_desc_128_t samples_att_db[SAMPLES_IDX_NB] = { +static const ble_gatts_attm_desc_128_t samples_attr_tab[SAMPLES_IDX_NB] = +{ // SAMPLE service - [SAMPLES_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [SAMPLES_IDX_SVC] = {ATT_128_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // SAMPLE TX Characteristic Declaration - [SAMPLES_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [SAMPLES_IDX_TX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // SAMPLE TX Characteristic Value - [SAMPLES_IDX_TX_VAL] = { - SAMPLE_SERVER_TX_UUID, - NOTIFY_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - SAMPLES_MAX_DATA_LEN - }, + [SAMPLES_IDX_TX_VAL] = {SAMPLE_SERVER_TX_UUID, + BLE_GATTS_NOTIFY_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + SAMPLES_MAX_DATA_LEN }, // SAMPLE TX Characteristic - Client Characteristic Configuration Descriptor - [SAMPLES_IDX_TX_CFG] = { - ATT_128_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [SAMPLES_IDX_TX_CFG] = {ATT_128_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM_UNSEC | BLE_GATTS_WRITE_REQ_PERM_UNSEC, + 0, + 0}, // SAMPLE RX Characteristic Declaration - [SAMPLES_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0 }, + [SAMPLES_IDX_RX_CHAR] = {ATT_128_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0 }, // SAMPLE RX Characteristic Value - [SAMPLES_IDX_RX_VAL] = { - SAMPLE_SERVER_RX_UUID, - WRITE_CMD_PERM_UNSEC, - (ATT_VAL_LOC_USER | ATT_UUID_TYPE_SET(UUID_TYPE_128)), - SAMPLES_MAX_DATA_LEN - }, -}; - -/**@brief SAMPLE Server Task interface required by profile manager. */ -static ble_prf_manager_cbs_t samples_tack_cbs = { - (prf_init_func_t) samples_init, - NULL, - NULL -}; - -/**@brief SAMPLE Server Task Callbacks. */ -static gatts_prf_cbs_t samples_cb_func = { - samples_read_att_cb, - samples_write_att_cb, - NULL, - samples_ntf_ind_cb, - samples_cccd_set_cb -}; - -/**@brief SAMPLE Server Information. */ -static const prf_server_info_t samples_prf_info = { - .max_connection_nb = SAMPLES_CONNECTION_MAX, - .manager_cbs = &samples_tack_cbs, - .gatts_prf_cbs = &samples_cb_func + [SAMPLES_IDX_RX_VAL] = {SAMPLE_SERVER_RX_UUID, + BLE_GATTS_WRITE_CMD_PERM_UNSEC, + (BLE_GATTS_ATT_VAL_LOC_USER | BLE_GATTS_ATT_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128)), + SAMPLES_MAX_DATA_LEN}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Sample Service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t samples_init(void) -{ - const uint8_t samples_svc_uuid[] = {SAMPLES_SERVICE_UUID}; - sdk_err_t error_code = SDK_SUCCESS; - uint16_t start_hdl = 0; - gatts_create_db_t gatts_db; - sdk_err_t ret; - - ret = memset(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; - } - for (uint8_t i = 0; i < s_samples_ins_cnt; i++) { - gatts_db.shdl = &start_hdl; - gatts_db.uuid = samples_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&s_samples_features; - gatts_db.max_nb_attr = SAMPLES_IDX_NB; - gatts_db.srvc_perm = SRVC_UUID_TYPE_SET(UUID_TYPE_128); - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_128; - gatts_db.attr_tab.attr_tab_128 = samples_att_db; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (error_code == SDK_SUCCESS) { - s_samples_env[i].start_hdl = *(gatts_db.shdl); - } else { - return error_code; - } - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -214,19 +138,22 @@ static sdk_err_t samples_init(void) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void samples_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void samples_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint8_t i = 0; - gatts_read_cfm_t cfm; - - for (i = 0; i < s_samples_ins_cnt; i++) { + ble_gatts_read_cfm_t cfm; + + for (i = 0; i < s_samples_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_samples_env[i].start_hdl, - SAMPLES_IDX_NB, + SAMPLES_IDX_NB, (uint8_t *)&s_samples_features); - if (tab_index > 0) { + + if (tab_index > 0) + { break; } } @@ -234,12 +161,13 @@ static void samples_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_p cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case SAMPLES_IDX_TX_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_samples_env[i].tx_ntf_cfg[conn_idx]; break; - + default: break; } @@ -255,40 +183,43 @@ static void samples_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_p * @param[in] p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void samples_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void samples_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint8_t handle = p_param->handle; uint8_t tab_index = 0; uint8_t i = 0; uint16_t cccd_value = 0; samples_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; cfm.handle = handle; cfm.status = BLE_SUCCESS; - for (i = 0; i < s_samples_ins_cnt; i++) { + for (i = 0; i < s_samples_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_samples_env[i].start_hdl, SAMPLES_IDX_NB, (uint8_t *)&s_samples_features); - if (tab_index > 0) { + if (tab_index > 0) + { break; } } - switch (tab_index) { + switch (tab_index) + { case SAMPLES_IDX_RX_VAL: - event.conn_idx = conn_idx; - event.evt_type = SAMPLES_EVT_RX_RECEIVE_DATA; + event.conn_idx = conn_idx; + event.evt_type = SAMPLES_EVT_RX_RECEIVE_DATA; break; case SAMPLES_IDX_TX_CFG: cccd_value = le16toh(&p_param->value[0]); event.conn_idx = conn_idx; event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? \ - SAMPLES_EVT_TX_NOTIFICATION_ENABLED :\ - SAMPLES_EVT_TX_NOTIFICATION_DISABLED; + SAMPLES_EVT_TX_NOTIFICATION_ENABLED :\ + SAMPLES_EVT_TX_NOTIFICATION_DISABLED; s_samples_env[i].tx_ntf_cfg[conn_idx] = cccd_value; break; @@ -298,7 +229,8 @@ static void samples_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p } if ((BLE_ATT_ERR_INVALID_HANDLE != cfm.status) &&\ (SAMPLES_EVT_INVALID != event.evt_type) &&\ - (s_samples_env[i].samples_init.evt_handler)) { + (s_samples_env[i].samples_init.evt_handler)) + { s_samples_env[i].samples_init.evt_handler(&event); } @@ -314,35 +246,39 @@ static void samples_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void samples_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void samples_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; uint8_t i = 0; samples_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } event.evt_type = SAMPLES_EVT_INVALID; event.conn_idx = conn_idx; - for (i = 0; i < s_samples_ins_cnt; i++) { + for (i = 0; i < s_samples_ins_cnt; i++) + { tab_index = prf_find_idx_by_handle(handle, s_samples_env[i].start_hdl, SAMPLES_IDX_NB, (uint8_t *)&s_samples_features); - if (tab_index > 0) { + if (tab_index > 0) + { break; } } - switch (tab_index) { + switch (tab_index) + { case SAMPLES_IDX_TX_CFG: event.conn_idx = conn_idx; event.evt_type = (PRF_CLI_START_NTF == cccd_value) ? \ - SAMPLES_EVT_TX_NOTIFICATION_ENABLED :\ - SAMPLES_EVT_TX_NOTIFICATION_DISABLED; + SAMPLES_EVT_TX_NOTIFICATION_ENABLED :\ + SAMPLES_EVT_TX_NOTIFICATION_DISABLED; s_samples_env[i].tx_ntf_cfg[conn_idx] = cccd_value; break; @@ -350,7 +286,8 @@ static void samples_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd break; } if ((SAMPLES_EVT_INVALID != event.evt_type) &&\ - (s_samples_env[i].samples_init.evt_handler)) { + (s_samples_env[i].samples_init.evt_handler)) + { s_samples_env[i].samples_init.evt_handler(&event); } } @@ -365,14 +302,17 @@ static void samples_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd * @return If the event was consumed or not. ***************************************************************************************** */ -static void samples_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void samples_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_samples_env[s_now_ins_cnt].samples_init.evt_handler != NULL) { + if (s_samples_env[s_now_ins_cnt].samples_init.evt_handler != NULL) + { samples_evt_t event; event.conn_idx = conn_idx; - if (status == BLE_SUCCESS) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (status == BLE_SUCCESS) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = s_now_notify_cmp_type; s_samples_env[s_now_ins_cnt].samples_init.evt_handler(&event); } @@ -380,6 +320,33 @@ static void samples_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts } } +static void samples_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + samples_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + samples_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + samples_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + samples_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** @@ -387,15 +354,17 @@ static void samples_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts sdk_err_t samples_notify_tx_data(uint8_t conn_idx, uint8_t ins_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - gatts_noti_ind_t send_cmd; + ble_gatts_noti_ind_t send_cmd; - if (PRF_CLI_START_NTF == s_samples_env[ins_idx].tx_ntf_cfg[conn_idx]) { - if (ins_idx <= s_samples_ins_cnt) { + if (PRF_CLI_START_NTF == s_samples_env[ins_idx].tx_ntf_cfg[conn_idx]) + { + if (ins_idx <= s_samples_ins_cnt) + { // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; send_cmd.handle = prf_find_handle_by_idx(SAMPLES_IDX_TX_VAL, - s_samples_env[ins_idx].start_hdl, - (uint8_t *)&s_samples_features); + s_samples_env[ins_idx].start_hdl, + (uint8_t *)&s_samples_features); // pack measured value in database send_cmd.length = length; send_cmd.value = p_data; @@ -412,20 +381,34 @@ sdk_err_t samples_notify_tx_data(uint8_t conn_idx, uint8_t ins_idx, uint8_t *p_d sdk_err_t samples_service_init(samples_init_t samples_init[], uint8_t ins_num) { - sdk_err_t ret; + sdk_err_t error_code = SDK_SUCCESS; - if (ins_num > SAMPLES_INSTANCE_MAX) { + if (ins_num > SAMPLES_INSTANCE_MAX) + { return SDK_ERR_INVALID_PARAM; } - for (uint8_t i = 0; i < ins_num; i++) { - ret = memcpy_s(&s_samples_env[i].samples_init, sizeof(samples_init_t), - &samples_init[i], sizeof(samples_init_t)); - if (ret < 0) { - return ret; - } + for (uint8_t i = 0; i < ins_num; i++) + { + memcpy(&s_samples_env[i].samples_init, &samples_init[i], sizeof(samples_init_t)); } s_samples_ins_cnt = ins_num; - return ble_server_prf_add(&samples_prf_info); + + for (uint8_t i = 0; i < ins_num; i++) + { + s_samples_env[i].start_hdl = PRF_INVALID_HANDLE; + + s_samples_env[i].sample_gatts_db.shdl = &s_samples_env[i].start_hdl; + s_samples_env[i].sample_gatts_db.uuid = s_samples_svc_uuid; + s_samples_env[i].sample_gatts_db.attr_tab_cfg = (uint8_t *)&s_samples_features; + s_samples_env[i].sample_gatts_db.max_nb_attr = SAMPLES_IDX_NB; + s_samples_env[i].sample_gatts_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_samples_env[i].sample_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_samples_env[i].sample_gatts_db.attr_tab.attr_tab_128 = samples_attr_tab; + + error_code |= ble_gatts_prf_add(&s_samples_env[i].sample_gatts_db, samples_ble_evt_handler); + } + + return error_code; } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.h index 6f5344c..fc0dc07 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/sample/sample_service.h @@ -3,7 +3,7 @@ * * @file sample_service.h * - * @brief Header file - sample_profile Server Role + * @brief Sample Service API. * ***************************************************************************************** * @attention @@ -46,32 +46,30 @@ * @{ * @brief Definitions and prototypes for the GUS interface. * - * @details The Sample Service demonstrates how to add vendor service to BLE Stack database, which includes + * @details The Sample Service demonstrates how to add vendor service to BLE Stack database, which includes * Tx and Rx base charateristic, developer can changes and adds other characteristics. - * + * * After \ref samples_init_t variable is initialized, the application must call \ref samples_service_init() * to add example characteristics to the BLE Stack database, and it provides \ref samples_notify_tx_data(). */ -#ifndef SAMPLE_PROFILE_H -#define SAMPLE_PROFILE_H +#ifndef _SAMPLE_PROFILE_H_ +#define _SAMPLE_PROFILE_H_ +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup SAMPLES_MACRO Defines * @{ */ -#define SAMPLES_INSTANCE_MAX 0x01 /**< Maximum number of Sample Service instances. The value is configurable.*/ -#define SAMPLES_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Sample Service connections. */ -#define SAMPLES_MAX_DATA_LEN 244 /**< Maximum length of sample charateristic value. */ -#define SAMPLES_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ - 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x01, 0xED, 0xA6 /**< The UUID of Sample Service for \ - setting advertising data. */ +#define SAMPLES_INSTANCE_MAX 0x01 /**< Maximum number of Sample Service instances. The value is configurable. */ +#define SAMPLES_CONNECTION_MAX 10 /**< Maximum number of Sample Service connections. */ +#define SAMPLES_MAX_DATA_LEN 244 /**< Maximum length of sample charateristic value. */ +#define SAMPLES_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x01, 0xED, 0xA6 /**< The UUID of Sample Service for setting advertising data. */ /** @} */ /** @@ -79,7 +77,8 @@ * @{ */ /**@brief Sample Service event type. */ -typedef enum { +typedef enum +{ SAMPLES_EVT_INVALID, SAMPLES_EVT_TX_NOTIFICATION_ENABLED, SAMPLES_EVT_TX_NOTIFICATION_DISABLED, @@ -93,7 +92,8 @@ typedef enum { * @{ */ /**@brief Sample Service event. */ -typedef struct { +typedef struct +{ samples_evt_type_t evt_type; /**< The sample service event. */ uint8_t conn_idx; /**< The connection index. */ uint8_t *p_data; /**< Pointer to event data. */ @@ -114,7 +114,8 @@ typedef void (*samples_evt_handler_t)(samples_evt_t *p_evt); * @{ */ /**@brief Sample Service init stucture. This contains all option and data needed for initialization of the service. */ -typedef struct { +typedef struct +{ samples_evt_handler_t evt_handler; /**handle; - uint8_t tab_index = 0; + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; tab_index = prf_find_idx_by_handle(handle, s_ths_env.start_hdl, THS_IDX_NB, (uint8_t *)&s_char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { + switch (tab_index) + { case THS_IDX_TX_CFG: cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_ths_env.data_ntf_cfg[conn_idx]; @@ -289,12 +210,12 @@ static void ths_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_par * @return If the request was consumed or not. ***************************************************************************************** */ -static void ths_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void ths_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint8_t handle = p_param->handle; - uint8_t tab_index = 0; - ths_evt_t event; - gatts_write_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = 0; + ths_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_ths_env.start_hdl, THS_IDX_NB, (uint8_t *)&s_char_mask); cfm.handle = handle; @@ -303,7 +224,8 @@ static void ths_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p event.conn_idx = conn_idx; event.evt_type = THS_EVT_INVALID; - switch (tab_index) { + switch (tab_index) + { case THS_IDX_TX_CFG: s_ths_env.data_ntf_cfg[conn_idx] = le16toh(&p_param->value[0]); break; @@ -318,7 +240,8 @@ static void ths_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p case THS_IDX_SETTINGS_VAL: event.evt_type = THS_EVT_SETTINGS_CHANGED; - if (THS_SETTINGS_TYPE_TRANS_MODE == p_param->value[0]) { + if (THS_SETTINGS_TYPE_TRANS_MODE == p_param->value[0]) + { s_ths_env.ths_init.transport_mode = (ths_transport_mode_t)p_param->value[1]; } break; @@ -332,8 +255,8 @@ static void ths_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p break; } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && THS_EVT_INVALID != event.evt_type && - s_ths_env.ths_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && THS_EVT_INVALID != event.evt_type && s_ths_env.ths_init.evt_handler) + { event.length = p_param->length; event.p_data = (uint8_t *)p_param->value; s_ths_env.ths_init.evt_handler(&event); @@ -351,17 +274,19 @@ static void ths_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void ths_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void ths_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint8_t tab_index = 0; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } tab_index = prf_find_idx_by_handle(handle, s_ths_env.start_hdl, THS_IDX_NB, (uint8_t *)&s_char_mask); - switch (tab_index) { + switch (tab_index) + { case THS_IDX_TX_CFG: s_ths_env.data_ntf_cfg[conn_idx] = cccd_value; break; @@ -377,16 +302,18 @@ static void ths_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val /** ***************************************************************************************** - * @brief Handles reception of the complete event. + * @brief Handles reception of the notification complete event. * * @param[in] conn_idx: Connection index. * @param[in] p_param: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void ths_gatts_cmpl_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void ths_ntf_cplt_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_ths_env.ths_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type && THS_IDX_TX_VAL == s_noti_cfg_idx) { + if (s_ths_env.ths_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type && THS_IDX_TX_VAL == s_noti_cfg_idx) + { ths_evt_t event; event.conn_idx = conn_idx; event.evt_type = THS_EVT_DATA_SENT; @@ -395,6 +322,33 @@ static void ths_gatts_cmpl_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ } } +static void ths_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + ths_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + ths_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + ths_ntf_cplt_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + ths_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -403,18 +357,19 @@ sdk_err_t ths_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - if (PRF_CLI_START_NTF == s_ths_env.data_ntf_cfg[conn_idx]) { - gatts_noti_ind_t send_cmd; + if (PRF_CLI_START_NTF == s_ths_env.data_ntf_cfg[conn_idx]) + { + ble_gatts_noti_ind_t send_cmd; - // Fill in the parameter structure - send_cmd.type = BLE_GATT_NOTIFICATION; - send_cmd.handle = prf_find_handle_by_idx(THS_IDX_TX_VAL, s_ths_env.start_hdl, (uint8_t *)&s_char_mask); - // Pack measured value in database - send_cmd.length = length; - send_cmd.value = p_data; - // Send notification to peer device - error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); - s_noti_cfg_idx = THS_IDX_TX_VAL; + // Fill in the parameter structure + send_cmd.type = BLE_GATT_NOTIFICATION; + send_cmd.handle = prf_find_handle_by_idx(THS_IDX_TX_VAL, s_ths_env.start_hdl, (uint8_t *)&s_char_mask); + // Pack measured value in database + send_cmd.length = length; + send_cmd.value = p_data; + // Send notification to peer device + error_code = ble_gatts_noti_ind(conn_idx, &send_cmd); + s_noti_cfg_idx = THS_IDX_TX_VAL; } return error_code; @@ -424,8 +379,9 @@ sdk_err_t ths_settings_notify(uint8_t conn_idx, uint8_t *p_settings, uint16_t le { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; - if (PRF_CLI_START_NTF == s_ths_env.settings_ntf_cfg[conn_idx]) { - gatts_noti_ind_t send_cmd; + if (PRF_CLI_START_NTF == s_ths_env.settings_ntf_cfg[conn_idx]) + { + ble_gatts_noti_ind_t send_cmd; // Fill in the parameter structure send_cmd.type = BLE_GATT_NOTIFICATION; @@ -450,16 +406,24 @@ ths_transport_mode_t ths_transport_mode_get(void) sdk_err_t ths_service_init(ths_init_t *p_ths_init) { - sdk_err_t ret; - if (p_ths_init == NULL) { + if (NULL == p_ths_init) + { return SDK_ERR_POINTER_NULL; } - ret = memcpy_s(&s_ths_env.ths_init, sizeof(ths_init_t), p_ths_init, sizeof(ths_init_t)); - if (ret < 0) { - return ret; - } + memcpy(&s_ths_env.ths_init, p_ths_init, sizeof(ths_init_t)); - return ble_server_prf_add(&ths_prf_info); + memset(&s_ths_env.ths_att_db, 0, sizeof(ble_gatts_create_db_t)); + + s_ths_env.start_hdl = PRF_INVALID_HANDLE; + s_ths_env.ths_att_db.shdl = &s_ths_env.start_hdl; + s_ths_env.ths_att_db.uuid = s_ths_svc_uuid; + s_ths_env.ths_att_db.attr_tab_cfg = (uint8_t *)&s_char_mask; + s_ths_env.ths_att_db.max_nb_attr = THS_IDX_NB; + s_ths_env.ths_att_db.srvc_perm = BLE_GATTS_SRVC_UUID_TYPE_SET(BLE_GATTS_UUID_TYPE_128); + s_ths_env.ths_att_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_128; + s_ths_env.ths_att_db.attr_tab.attr_tab_128 = ths_attr_tab; + + return ble_gatts_prf_add(&s_ths_env.ths_att_db, ths_ble_evt_handler); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths/ths.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths/ths.h index e267fe6..3f202aa 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths/ths.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths/ths.h @@ -47,12 +47,12 @@ * @brief Definitions and prototypes for the THS interface. * * @details The Throughput Service is a customized GATT-based service with Settings, Toggle, - * Tx and Rx characteristics. The developer uses the service to test throughput. + * Tx and Rx characteristics. The developer uses the service to test throughput. * The data is sent to the peer as Handle Value Notification, and the data received * from the peer is transmitted with GATT Write Command. * * The peer writes Toggle characteristic to command the application starting/stopping - * throughput. The application calls \ref ths_data_send() to send data to the peer. + * throughput. The application calls \ref ths_data_send() to send data to the peer. * The application handles \ref THS_EVT_DATA_RECEIVED in \ref ths_init_t.evt_handler() * to get the data received from the peer. The application uses ths_settings_notify() to * request the change of the parameters related with throughput, including CI, MTU, PDU and PHY. @@ -61,20 +61,18 @@ #ifndef _THS_H_ #define _THS_H_ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup THS_MACRO Defines * @{ */ -#define THS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Throughput Service connections.*/ -#define THS_MAX_DATA_LEN 512 /**< Maximum length of the value of Rx or Tx characteristic. */ -#define THS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, \ - 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x03, 0xED, 0xA6 /**< The UUID of Throughput Service \ - for setting advertising data. */ +#define THS_CONNECTION_MAX 10 /**< Maximum number of Throughput Service connections. */ +#define THS_MAX_DATA_LEN 512 /**< Maximum length of the value of Rx or Tx characteristic. */ +#define THS_SERVICE_UUID 0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x03, 0xED, 0xA6 /**< The UUID of Throughput Service for setting advertising data. */ /** @} */ /** @@ -82,38 +80,40 @@ * @{ */ /**@brief Throughput data transport mode. */ -typedef enum { +typedef enum +{ THS_SLAVE_NOTIFY_MODE, /**< Only allow device notify. */ THS_MASTER_WRITE_MODE, /**< Only allow peer writes. */ THS_DOUBLE_MODE, /**< Allow device notify and peer writes at the same time. */ } ths_transport_mode_t; /**@brief Throughput Service event type. */ -typedef enum { +typedef enum +{ THS_EVT_INVALID, /**< Invalid THS event type. */ - THS_EVT_DATA_RECEIVED, /**< The data from the peer has been received. \ - The application gets the data in \ref ths_evt_t.p_data. */ - THS_EVT_DATA_SENT, /**< The data from the application has been sent, \ - and the service is ready to accept new data from the application. */ + THS_EVT_DATA_RECEIVED, /**< The data from the peer has been received. The application gets the data in \ref ths_evt_t.p_data. */ + THS_EVT_DATA_SENT, /**< The data from the application has been sent, and the service is ready to accept new data from the application. */ THS_EVT_SETTINGS_CHANGED, /**< The settings parameters, like MTU, PHY, have been changed by the peer. */ THS_EVT_TOGGLE_SET, /**< The toggle state has been set by the peer. */ } ths_evt_type_t; /**@brief Throughput toggle state of sending the data. */ -enum ths_toggle_state_t { +enum ths_toggle_state_t +{ THS_TOGGLE_STATE_OFF, /**< Sending data is disabled. */ THS_TOGGLE_STATE_ON, /**< Sending data is enabled. */ }; /**@brief Throughput service settings types. */ -typedef enum { +typedef enum +{ THS_SETTINGS_TYPE_CI, /**< BLE Connection Interval parameter. */ THS_SETTINGS_TYPE_MTU, /**< MTU Size. */ THS_SETTINGS_TYPE_PDU, /**< PDU Size. */ THS_SETTINGS_TYPE_PHY, /**< Radio Phy mode, 1M, 2M, Encoded. */ THS_SETTINGS_TYPE_TRANS_MODE, /**< Data transmission mode. */ THS_SETTINGS_TYPE_TX_POWER, /**< Connect Tx power. */ -} ths_settings_type_t; +}ths_settings_type_t; /** @} */ /** @@ -121,7 +121,8 @@ typedef enum { * @{ */ /**@brief Throughput Service event. */ -typedef struct { +typedef struct +{ ths_evt_type_t evt_type; /**< The THS event type. */ ths_settings_type_t setting_type; /**< The THS parameter set type. */ uint8_t conn_idx; /**< The index of the connection for the data transmission. */ @@ -142,12 +143,10 @@ typedef void (*ths_evt_handler_t)(ths_evt_t *p_evt); * @addtogroup THS_STRUCT Structures * @{ */ -/**@brief Throughput Service init stucture. - * This contains all option and data needed for initialization of the service. */ -typedef struct { - ths_evt_handler_t - evt_handler; /**< Throughput Service event handler which must be provided \ - by the application to send and receive the data and the settings change. */ +/**@brief Throughput Service init stucture. This contains all option and data needed for initialization of the service. */ +typedef struct +{ + ths_evt_handler_t evt_handler; /**< Throughput Service event handler which must be provided by the application to send and receive the data and the settings change. */ ths_transport_mode_t transport_mode; /**< The transport mode of a device. */ } ths_init_t; /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/BUILD.gn new file mode 100644 index 0000000..47aaa96 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("ths_c") { + sources = [ "ths_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.c index 8c7e026..68481f3 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.c @@ -41,66 +41,35 @@ */ #include "ths_c.h" #include -#define ATTR_VALUE_LEN 2 -#define UUID_LEN 16 /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Throughput Service Client environment variable. */ -struct ths_c_env_t { +struct ths_c_env_t +{ ths_c_handles_t handles; /**< Handles of THS characteristics which will be got for peer. */ ths_c_evt_handler_t evt_handler; /**< Handler of THS client event */ uint8_t prf_id; /**< THS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void ths_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle); -static void ths_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); -static void ths_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ -static struct ths_c_env_t - s_ths_c_env; /**< THS Client environment variable. */ +static struct ths_c_env_t s_ths_c_env; /**< THS Client environment variable. */ static uint8_t s_ths_uuid[16] = THS_SVC_UUID; static uint8_t s_ths_tx_char_uuid[16] = THS_TX_CHAR_UUID; static uint8_t s_ths_rx_char_uuid[16] = THS_RX_CHAR_UUID; static uint8_t s_ths_setting_char_uuid[16] = THS_SETTING_CHAR_UUID; static uint8_t s_toggle_char_uuid[16] = THS_TOGGLE_CHAR_UUID; -/**@brief THS Client interface required by profile manager. */ -static ble_prf_manager_cbs_t ths_c_mgr_cbs = { - NULL, - NULL, - NULL -}; -/**@brief THS GATT Client Callbacks. */ -static gattc_prf_cbs_t ths_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - NULL, - ths_c_att_write_cb, - ths_c_att_ntf_ind_cb, - ths_c_srvc_browse_cb, - NULL, +static ble_uuid_t s_ths_service_uuid = +{ + .uuid_len = 16, + .uuid = s_ths_uuid, }; - -/**@brief THS Client Information. */ -static const prf_client_info_t ths_c_prf_info = { - .max_connection_nb = THS_C_CONNECTION_MAX, - .manager_cbs = &ths_c_mgr_cbs, - .gattc_prf_cbs = &ths_c_gattc_cbs -}; - /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -114,47 +83,57 @@ static const prf_client_info_t ths_c_prf_info = { */ static void ths_c_evt_handler_excute(ths_c_evt_t *p_evt) { - if (s_ths_c_env.evt_handler != NULL && THS_C_EVT_INVALID != p_evt->evt_type) { + if (NULL != s_ths_c_env.evt_handler && THS_C_EVT_INVALID != p_evt->evt_type) + { s_ths_c_env.evt_handler(p_evt); } } /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] handle: The handle of attribute. ***************************************************************************************** */ -static void ths_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle) +static void ths_c_att_write_evt_handler(uint8_t conn_idx, uint8_t status, uint16_t handle) { ths_c_evt_t ths_c_evt; ths_c_evt.conn_idx = conn_idx; ths_c_evt.evt_type = THS_C_EVT_INVALID; - if (handle == s_ths_c_env.handles.ths_tx_cccd_handle) { + if (handle == s_ths_c_env.handles.ths_tx_cccd_handle) + { ths_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - THS_C_EVT_TX_NTF_SET_SUCCESS : \ - THS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ths_c_env.handles.ths_setting_cccd_handle) { + THS_C_EVT_TX_NTF_SET_SUCCESS : \ + THS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ths_c_env.handles.ths_setting_cccd_handle) + { ths_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - THS_C_EVT_SETTING_NTF_SET_SUCCESS : \ - THS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ths_c_env.handles.ths_toggle_handle) { + THS_C_EVT_SETTING_NTF_SET_SUCCESS : \ + THS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ths_c_env.handles.ths_toggle_handle) + { ths_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - THS_C_EVT_TOGGLE_SET_SUCCESS : \ - THS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ths_c_env.handles.ths_setting_handle) { + THS_C_EVT_TOGGLE_SET_SUCCESS : \ + THS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ths_c_env.handles.ths_setting_handle) + { ths_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - THS_C_EVT_PARAM_SET_SUCCESS : \ - THS_C_EVT_WRITE_OP_ERR; - } else if (handle == s_ths_c_env.handles.ths_rx_handle) { + THS_C_EVT_PARAM_SET_SUCCESS : \ + THS_C_EVT_WRITE_OP_ERR; + } + else if (handle == s_ths_c_env.handles.ths_rx_handle) + { ths_c_evt.evt_type = (BLE_SUCCESS == status) ? \ - THS_C_EVT_TX_SUCCESS : \ - THS_C_EVT_WRITE_OP_ERR; + THS_C_EVT_TX_SUCCESS : \ + THS_C_EVT_WRITE_OP_ERR; } ths_c_evt_handler_excute(&ths_c_evt); @@ -162,14 +141,14 @@ static void ths_c_att_write_cb(uint8_t conn_idx, uint8_t status, uint16_t handle /** ***************************************************************************************** - * @brief This callback function will be called when receiving notification or indication. + * @brief This event handler function will be called when receiving notification or indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_ntf_ind: The information of notification or indication. ***************************************************************************************** */ -static void ths_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind) +static void ths_c_att_ntf_ind_evt_handler(uint8_t conn_idx, const ble_gattc_evt_ntf_ind_t *p_ntf_ind) { ths_c_evt_t ths_c_evt; @@ -178,9 +157,12 @@ static void ths_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ ths_c_evt.p_data = p_ntf_ind->p_value; ths_c_evt.length = p_ntf_ind->length; - if (p_ntf_ind->handle == s_ths_c_env.handles.ths_setting_handle) { + if (p_ntf_ind->handle == s_ths_c_env.handles.ths_setting_handle) + { ths_c_evt.evt_type = THS_C_EVT_SETTING_RSP_RECEIVE; - } else if (p_ntf_ind->handle == s_ths_c_env.handles.ths_tx_handle) { + } + else if (p_ntf_ind->handle == s_ths_c_env.handles.ths_tx_handle) + { ths_c_evt.evt_type = THS_C_EVT_THRP_DATA_RECEIVE; } @@ -189,14 +171,14 @@ static void ths_c_att_ntf_ind_cb(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ /** ***************************************************************************************** - * @brief This callback function will be called when receiving browse service indication. + * @brief This event handler function will be called when receiving browse service indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void ths_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void ths_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { ths_c_evt_t ths_c_evt; uint16_t handle_disc; @@ -204,153 +186,154 @@ static void ths_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat ths_c_evt.conn_idx = conn_idx; ths_c_evt.evt_type = THS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - if (p_browse_srvc->uuid_len == UUID_LEN && memcmp(p_browse_srvc->uuid, s_ths_uuid, UUID_LEN) == 0) { - s_ths_c_env.handles.ths_srvc_start_handle = p_browse_srvc->start_hdl; - s_ths_c_env.handles.ths_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_SUCCESS == status) + { + if (16 == p_browse_srvc->uuid_len && 0 == memcmp(p_browse_srvc->uuid, s_ths_uuid, 16)) + { + s_ths_c_env.handles.ths_srvc_start_handle = p_browse_srvc->start_hdl; + s_ths_c_env.handles.ths_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) { - if (memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_rx_char_uuid, UUID_LEN) == 0) { - s_ths_c_env.handles.ths_rx_handle = handle_disc; - } else if ((memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_tx_char_uuid, UUID_LEN) == 0)) { - s_ths_c_env.handles.ths_tx_handle = handle_disc; - s_ths_c_env.handles.ths_tx_cccd_handle = handle_disc + 1; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_setting_char_uuid, UUID_LEN) == 0) { - s_ths_c_env.handles.ths_setting_handle = handle_disc; - s_ths_c_env.handles.ths_setting_cccd_handle = handle_disc + 1; - } else if (memcmp(p_browse_srvc->info[i].attr.uuid, s_toggle_char_uuid, UUID_LEN) == 0) { - s_ths_c_env.handles.ths_toggle_handle = handle_disc; + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_ATTR_VAL) + { + if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_rx_char_uuid, 16)) + { + s_ths_c_env.handles.ths_rx_handle = handle_disc; + } + else if (0 == (memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_tx_char_uuid, 16))) + { + s_ths_c_env.handles.ths_tx_handle = handle_disc; + s_ths_c_env.handles.ths_tx_cccd_handle = handle_disc + 1; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_ths_setting_char_uuid, 16)) + { + s_ths_c_env.handles.ths_setting_handle = handle_disc; + s_ths_c_env.handles.ths_setting_cccd_handle = handle_disc + 1; + } + else if (0 == memcmp(p_browse_srvc->info[i].attr.uuid, s_toggle_char_uuid, 16)) + { + s_ths_c_env.handles.ths_toggle_handle = handle_disc; + } + } + + if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) + { + break; } } - if (p_browse_srvc->info[i].attr_type == BLE_GATTC_BROWSE_NONE) { - break; - } + ths_c_evt.evt_type = THS_C_EVT_DISCOVERY_COMPLETE; } - - ths_c_evt.evt_type = THS_C_EVT_DISCOVERY_COMPLETE; } ths_c_evt_handler_excute(&ths_c_evt); } +static void ths_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTC_EVT_SRVC_BROWSE: + ths_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + ths_c_att_write_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, p_evt->evt.gattc_evt.params.write_rsp.handle); + break; + + case BLE_GATTC_EVT_NTF_IND: + ths_c_att_ntf_ind_evt_handler(p_evt->evt.gattc_evt.index, &p_evt->evt.gattc_evt.params.ntf_ind); + break; + } +} /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t ths_client_init(ths_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_ths_c_env, sizeof(s_ths_c_env), 0, sizeof(s_ths_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_ths_c_env, 0, sizeof(s_ths_c_env)); s_ths_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&ths_c_prf_info, &s_ths_c_env.prf_id); + return ble_gattc_prf_add(&s_ths_service_uuid, ths_c_ble_evt_handler); } sdk_err_t ths_c_disc_srvc_start(uint8_t conn_idx) { - const ble_uuid_t ths_uuid = { - .uuid_len = 16, - .uuid = s_ths_uuid, - }; - - return ble_gattc_prf_services_browse(s_ths_c_env.prf_id, conn_idx, &ths_uuid); + return ble_gattc_services_browse(conn_idx, &s_ths_service_uuid); } sdk_err_t ths_c_tx_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_tx_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_tx_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ths_c_env.handles.ths_tx_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_ths_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx,s_ths_c_env.handles.ths_tx_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ths_c_setting_notify_set(uint8_t conn_idx, bool is_enable) { - gattc_write_attr_value_t write_attr_value; uint16_t ntf_value = is_enable ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; - if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_setting_cccd_handle) { + if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_setting_cccd_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.handle = s_ths_c_env.handles.ths_setting_cccd_handle; - write_attr_value.offset = 0; - write_attr_value.length = ATTR_VALUE_LEN; - write_attr_value.p_value = (uint8_t *)&ntf_value; - - return ble_gattc_prf_write(s_ths_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write(conn_idx, s_ths_c_env.handles.ths_setting_cccd_handle, 0, 2, (uint8_t *)&ntf_value); } sdk_err_t ths_c_comm_param_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_setting_handle) { + if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_setting_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_ths_c_env.handles.ths_setting_handle; - write_attr_value.length = length; - write_attr_value.p_value = p_data; - - return ble_gattc_prf_write_no_resp(s_ths_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_ths_c_env.handles.ths_setting_handle, length, p_data); } sdk_err_t ths_c_toggle_set(uint8_t conn_idx, bool is_enable) { - gattc_write_no_resp_t write_attr_value; - - if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_toggle_handle) { + if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_toggle_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_ths_c_env.handles.ths_toggle_handle; - write_attr_value.length = 1; - write_attr_value.p_value = (uint8_t *)&is_enable; - - return ble_gattc_prf_write_no_resp(s_ths_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_ths_c_env.handles.ths_toggle_handle, 1, (uint8_t *)&is_enable); } sdk_err_t ths_c_tx_data_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { - gattc_write_no_resp_t write_attr_value; - if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_rx_handle) { + if (BLE_ATT_INVALID_HDL == s_ths_c_env.handles.ths_rx_handle) + { return SDK_ERR_INVALID_HANDLE; } - write_attr_value.signed_write = false; - write_attr_value.handle = s_ths_c_env.handles.ths_rx_handle; - write_attr_value.length = length; - write_attr_value.p_value = p_data; - - return ble_gattc_prf_write_no_resp(s_ths_c_env.prf_id, conn_idx, &write_attr_value); + return ble_gattc_write_no_resp(conn_idx, false, s_ths_c_env.handles.ths_rx_handle, length, p_data); } + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.h index 2ec0fd9..3521312 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/ths_c/ths_c.h @@ -39,7 +39,6 @@ * @addtogroup BLE_SRV BLE Services * @{ */ - /** * @defgroup BLE_SDK_THS_C Throughput Service Client (THS_C) * @{ @@ -50,7 +49,7 @@ * interact with it. * * The application must provide to register, then call \ref ths_client_init(). After the module can - * send setting parameters and throughput data to peer, it will notify application. + * send setting parameters and throughput data to peer, it will notify application. * It includes only Throughput Service notify data, only Throughput Service Client write data * and both send data test mode \ref ths_c_transport_mode_t. */ @@ -58,11 +57,11 @@ #ifndef __THS_C_H__ #define __THS_C_H__ +#include "ble_prf_types.h" +#include "gr_includes.h" +#include "custom_config.h" #include #include -#include "ble_prf_types.h" -#include "gr55xx_sys.h" -#include "custom_config.h" /** * @defgroup THS_C_MACRO Defines @@ -73,18 +72,17 @@ * @{ * @brief THS service and characteristcs UUID. */ -#define THS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of THS Client connections. */ -#define THS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, \ - 0xD3, 0x01, 0x03, 0xED, 0xA6} /**< UUID of THS Service. */ -#define THS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, \ - 0xD3, 0x02, 0x03, 0xED, 0xA6} /**< UUID of THS Tx Characteristic. */ -#define THS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, \ - 0xD3, 0x03, 0x03, 0xED, 0xA6} /**< UUID of THS Rx Characteristic. */ -#define THS_SETTING_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, \ - 0xD3, 0x04, 0x03, 0xED, 0xA6} /**< UUID of THS Setting Characteristic. */ -#define THS_TOGGLE_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80, 0x0A, 0x46, 0x44, \ - 0xD3, 0x05, 0x03, 0xED, 0xA6} /**< UUID of THS Toggle Characteristic. */ +#define THS_C_CONNECTION_MAX 10 /**< Maximum number of THS Client connections. */ +#define THS_SVC_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x01, 0x03, 0xED, 0xA6} /**< UUID of THS Service. */ +#define THS_TX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x02, 0x03, 0xED, 0xA6} /**< UUID of THS Tx Characteristic. */ +#define THS_RX_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x03, 0x03, 0xED, 0xA6} /**< UUID of THS Rx Characteristic. */ +#define THS_SETTING_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x04, 0x03, 0xED, 0xA6} /**< UUID of THS Setting Characteristic. */ +#define THS_TOGGLE_CHAR_UUID {0x1B, 0xD7, 0x90, 0xEC, 0xE8, 0xB9, 0x75, 0x80,\ + 0x0A, 0x46, 0x44, 0xD3, 0x05, 0x03, 0xED, 0xA6} /**< UUID of THS Toggle Characteristic. */ /** @} */ /** @} */ @@ -93,15 +91,16 @@ * @{ */ /**@brief Throughput Service Client data transport mode. */ -typedef enum { +typedef enum +{ THS_C_SLAVE_NOTIFY_MODE, /** The device recieves data from the peer via notify. */ THS_C_MASTER_WRITE_MODE, /** The device writes data to the peer. */ - THS_C_DOUBLE_MODE, /** The device recieve data from the peer via notify and \ - write data to the peer at the same time. */ + THS_C_DOUBLE_MODE, /** The device recieve data from the peer via notify and write data to the peer at the same time. */ } ths_c_transport_mode_t; /**@brief Throughput service settings types. */ -typedef enum { +typedef enum +{ THS_C_SETTINGS_TYPE_CI, /**< BLE Connection Interval parameter. */ THS_C_SETTINGS_TYPE_MTU, /**< MTU Size. */ THS_C_SETTINGS_TYPE_PDU, /**< PDU Size. */ @@ -111,11 +110,11 @@ typedef enum { } ths_c_settings_type_t; /**@brief Throughput Service Client event type. */ -typedef enum { +typedef enum +{ THS_C_EVT_INVALID, /**< THS Client invalid event. */ THS_C_EVT_DISCOVERY_COMPLETE, /**< THS Client has found THS service and its characteristics. */ - THS_C_EVT_DISCOVERY_FAIL, /**< THS Client found THS service failed because of invalid operation \ - or no found at the peer. */ + THS_C_EVT_DISCOVERY_FAIL, /**< THS Client found THS service failed because of invalid operation or no found at the peer. */ THS_C_EVT_TX_NTF_SET_SUCCESS, /**< THS Client has set peer Tx notify. */ THS_C_EVT_SETTING_NTF_SET_SUCCESS, /**< THS Client has set peer Settings notify. */ THS_C_EVT_TOGGLE_SET_SUCCESS, /**< THS Client has set toggle no. */ @@ -132,7 +131,8 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t ths_srvc_start_handle; /**< THS Service start handle. */ uint16_t ths_srvc_end_handle; /**< THS Service end handle. */ uint16_t ths_tx_handle; /**< THS Tx characteristic handle which has been got from peer. */ @@ -144,7 +144,8 @@ typedef struct { } ths_c_handles_t; /**@brief Throughput Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ ths_c_evt_type_t evt_type; /**< THS client event type. */ uint8_t *p_data; /**< Pointer to event data. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/BUILD.gn new file mode 100644 index 0000000..06022f1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("tps") { + sources = [ "tps.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.c index 8107f5a..eef235f 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.c @@ -43,14 +43,14 @@ #include "ble_prf_types.h" #include "ble_prf_utils.h" #include "utility.h" -#define OFFSET_100 100 -#define OFFSET_20 20 + /* * ENUMERATIONS ***************************************************************************************** */ /**@brief Tx Power Service attributes index. */ -enum tps_attr_idx_tag { +enum tps_attr_idx_tag +{ TPS_IDX_SVC, TPS_IDX_TX_POWER_LVL_CHAR, @@ -64,9 +64,11 @@ enum tps_attr_idx_tag { ***************************************************************************************** */ /**@brief Tx Power Service environment variable. */ -struct tps_env_t { - tps_init_t tps_init; /**< Tx Power Service initialization variables. */ - uint16_t start_hdl; /**< Tx Power Service start handle. */ +struct tps_env_t +{ + tps_init_t tps_init; /**< Tx Power Service initialization variables. */ + uint16_t start_hdl; /**< Tx Power Service start handle. */ + ble_gatts_create_db_t tps_serv_db; /**< Tx Power Service DataBase. */ }; /* @@ -79,89 +81,56 @@ static uint8_t s_char_mask = 0x07; /**< Features added into ATT database. * bit1 - Tx Power Level Characteristic Declaration * bit2 - Tx Power Level Characteristic Value */ +static const uint8_t s_tps_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_TX_POWER); /**@brief TPS Database Description - Used to add attributes into the database. */ -static const attm_desc_t tps_attr_tab[TPS_IDX_NB] = { +static const ble_gatts_attm_desc_t tps_attr_tab[TPS_IDX_NB] = +{ // Tx Power Service Declaration - [TPS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [TPS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Tx Power Level Characteristic Declaration - [TPS_IDX_TX_POWER_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [TPS_IDX_TX_POWER_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Tx Power Level Characteristic Value - [TPS_IDX_TX_POWER_LVL_VAL] = {BLE_ATT_CHAR_TX_POWER_LEVEL, READ_PERM_UNSEC, 0, sizeof(int8_t)}, + [TPS_IDX_TX_POWER_LVL_VAL] = {BLE_ATT_CHAR_TX_POWER_LEVEL, BLE_GATTS_READ_PERM_UNSEC, 0, sizeof(int8_t)}, }; /* * LOCAL FUNCTION DECLARATIONS ***************************************************************************************** */ -static sdk_err_t tps_init(void); - -/**@brief TPS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t tps_mgr_cbs = { - (prf_init_func_t)tps_init, - NULL, - NULL -}; - -/**@brief TPS GATT server Callbacks. */ -static gatts_prf_cbs_t tps_gatts_cbs = { - NULL, - NULL, - NULL, - NULL -}; - -/**@brief TPS Information. */ -static const prf_server_info_t tps_prf_info = { - /* There shall be only one connection on a device */ - .max_connection_nb = 1, - .manager_cbs = &tps_mgr_cbs, - .gatts_prf_cbs = &tps_gatts_cbs -}; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize TP service and create db in BLE Stack. - * - * @return BLE_ATT_ERR_NO_ERROR on success, otherwise error code. - ***************************************************************************************** - */ -static sdk_err_t tps_init(void) +static void tps_ble_evt_handler(const ble_evt_t *p_evt) { - const uint8_t tps_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_TX_POWER); - gatts_create_db_t gatts_db; - sdk_err_t ret; - uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out - * parameter of ble_gatts_srvc_db_create(). - * It must be set with PRF_INVALID_HANDLE - * to be allocated automatically by BLE Stack. */ - - ret = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (ret < 0) { - return ret; + if (NULL == p_evt) + { + return; } - gatts_db.shdl = &start_hdl; - gatts_db.uuid = (uint8_t *)tps_svc_uuid; - gatts_db.attr_tab_cfg = &s_char_mask; - gatts_db.max_nb_attr = TPS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = tps_attr_tab; + uint16_t handle; - sdk_err_t error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_tps_env.start_hdl = *gatts_db.shdl; + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + break; - uint16_t handle = prf_find_handle_by_idx(TPS_IDX_TX_POWER_LVL_VAL, s_tps_env.start_hdl, &s_char_mask); - ble_gatts_value_set(handle, sizeof(uint8_t), 0, (uint8_t *)&s_tps_env.tps_init.initial_tx_power_level); + case BLE_GATTS_EVT_WRITE_REQUEST: + break; + + case BLE_GATTS_EVT_NTF_IND: + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + break; + + case BLE_GATT_COMMON_EVT_PRF_REGISTER: + handle = prf_find_handle_by_idx(TPS_IDX_TX_POWER_LVL_VAL, s_tps_env.start_hdl, &s_char_mask); + ble_gatts_value_set(handle, sizeof(uint8_t), 0, (uint8_t *)&s_tps_env.tps_init.initial_tx_power_level); + break; } - - return error_code; } /* @@ -170,23 +139,42 @@ static sdk_err_t tps_init(void) */ sdk_err_t tps_service_init(tps_init_t *p_tps_init) { - if (p_tps_init == NULL) { + if (NULL == p_tps_init) + { return SDK_ERR_POINTER_NULL; } s_tps_env.tps_init.initial_tx_power_level = p_tps_init->initial_tx_power_level; - return ble_server_prf_add(&tps_prf_info); + memset(&s_tps_env.tps_serv_db, 0, sizeof(ble_gatts_create_db_t)); + + s_tps_env.start_hdl = PRF_INVALID_HANDLE; + s_tps_env.tps_serv_db.shdl = &s_tps_env.start_hdl; + s_tps_env.tps_serv_db.uuid = s_tps_svc_uuid; + s_tps_env.tps_serv_db.attr_tab_cfg = &s_char_mask; + s_tps_env.tps_serv_db.max_nb_attr = TPS_IDX_NB; + s_tps_env.tps_serv_db.srvc_perm = 0; + s_tps_env.tps_serv_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_tps_env.tps_serv_db.attr_tab.attr_tab_16 = tps_attr_tab; + + return ble_gatts_prf_add(&s_tps_env.tps_serv_db, tps_ble_evt_handler); } -sdk_err_t tps_tx_power_level_set(int8_t tx_power_level) +sdk_err_t tps_tx_power_level_set(int8_t tx_power_level) { - if (tx_power_level < -OFFSET_100 || tx_power_level > OFFSET_20) { + if (tx_power_level < -100 || tx_power_level > 20) + { return SDK_ERR_INVALID_PARAM; - } else { + } + else + { uint16_t handle = prf_find_handle_by_idx(TPS_IDX_TX_POWER_LVL_VAL, s_tps_env.start_hdl, &s_char_mask); return ble_gatts_value_set(handle, sizeof(int8_t), 0, (uint8_t *)&tx_power_level); } } +uint16_t tps_service_start_handle_get(void) +{ + return s_tps_env.start_hdl; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.h index 517f232..29d2c4e 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps/tps.h @@ -60,16 +60,17 @@ #ifndef __TPS_H__ #define __TPS_H__ -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" +#include /** * @defgroup TPS_STRUCT Structures * @{ */ /**@brief Tx Power Servic init stucture. This contains all option and data needed for initialization of the service. */ -typedef struct { +typedef struct +{ int8_t initial_tx_power_level; /**< Initial value of Tx Power Level characteristic (in dBm) */ } tps_init_t; /** @} */ @@ -99,6 +100,16 @@ sdk_err_t tps_service_init(tps_init_t *p_tps_init); ***************************************************************************************** */ sdk_err_t tps_tx_power_level_set(int8_t tx_power_level); + +/** + ***************************************************************************************** + * @brief Provide the interface for other modules to obtain the tps service start handle . + * + * @return The tps service start handle. + ***************************************************************************************** + */ +uint16_t tps_service_start_handle_get(void); + /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/BUILD.gn new file mode 100644 index 0000000..82a07af --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("tps_c") { + sources = [ "tps_c.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.c index cd16cae..24863eb 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.c @@ -39,60 +39,33 @@ * INCLUDE FILES ***************************************************************************************** */ -#include +#include "tps_c.h" #include "ble_prf_utils.h" #include "utility.h" -#include "tps_c.h" -#define UUID_OFFSET_8 8 +#include + /* * STRUCT DEFINE ***************************************************************************************** */ /**@brief Tx Power Service environment variable. */ -struct tps_c_env_t { +struct tps_c_env_t +{ tps_c_handles_t handles; /**< Handles of TPS characteristics which will be got for peer. */ tps_c_evt_handler_t evt_handler; /**< Handler of TPS Client event */ uint8_t prf_id; /**< TPS Client profile id. */ }; -/* - * LOCAL FUNCTION DECLARATION - ***************************************************************************************** - */ -static void tps_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); -static void tps_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); - /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct tps_c_env_t s_tps_c_env; /**< Tx Power Service Client environment variable. */ - -/**@brief Tx Power Service Client interface required by profile manager. */ -static ble_prf_manager_cbs_t tps_c_mgr_cbs = { - NULL, - NULL, - NULL -}; - -/**@brief Tx Power Service GATT Client Callbacks. */ -static gattc_prf_cbs_t tps_c_gattc_cbs = { - NULL, - NULL, - NULL, - NULL, - tps_c_att_read_cb, - NULL, - NULL, - tps_c_srvc_browse_cb, - NULL, -}; - -/**@brief Tx Power Service Client Information. */ -static const prf_client_info_t bas_c_prf_info = { - .max_connection_nb = TPS_C_CONNECTION_MAX, - .manager_cbs = &tps_c_mgr_cbs, - .gattc_prf_cbs = &tps_c_gattc_cbs +static uint8_t s_target_uuid[2] = {LO_U16(BLE_ATT_SVC_TX_POWER), HI_U16(BLE_ATT_SVC_TX_POWER)}; +static ble_uuid_t s_tps_service_uuid = +{ + .uuid_len = 2, + .uuid = s_target_uuid, }; /* @@ -102,29 +75,32 @@ static const prf_client_info_t bas_c_prf_info = { /** ***************************************************************************************** - * @brief This callback function will be called when receiving read response. + * @brief This event handler function will be called when receiving read response. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_read_rsp: The information of read response. ***************************************************************************************** */ -static void tps_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp) +static void tps_c_att_read_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_read_t *p_read_rsp) { tps_c_evt_t tps_c_evt; tps_c_evt.conn_idx = conn_idx; tps_c_evt.evt_type = TPS_C_EVT_INVALID; - if (BLE_SUCCESS != status) { + if (BLE_SUCCESS != status) + { return; } - if (p_read_rsp->vals[0].handle == s_tps_c_env.handles.tps_tx_power_level_handle) { + if (p_read_rsp->value[0].handle == s_tps_c_env.handles.tps_tx_power_level_handle) + { tps_c_evt.evt_type = TPS_C_EVT_TX_POWER_LEVEL_RECEIVE; - tps_c_evt.tx_power_level = p_read_rsp->vals[0].p_value[0]; + tps_c_evt.tx_power_level = p_read_rsp->value[0].p_value[0]; - if (s_tps_c_env.evt_handler) { + if (s_tps_c_env.evt_handler) + { s_tps_c_env.evt_handler(&tps_c_evt); } } @@ -132,14 +108,14 @@ static void tps_c_att_read_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_ /** ***************************************************************************************** - * @brief This callback function will be called when receiving browse service indication. + * @brief This event handler function will be called when receiving browse service indication. * * @param[in] conn_idx: The connection index. * @param[in] status: The status of GATTC operation. * @param[in] p_browse_srvc: The information of service browse. ***************************************************************************************** */ -static void tps_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc) +static void tps_c_srvc_browse_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gattc_evt_browse_srvc_t *p_browse_srvc) { tps_c_evt_t tps_c_evt; uint16_t uuid_disc; @@ -148,81 +124,95 @@ static void tps_c_srvc_browse_cb(uint8_t conn_idx, uint8_t status, const ble_gat tps_c_evt.conn_idx = conn_idx; tps_c_evt.evt_type = TPS_C_EVT_DISCOVERY_FAIL; - if (BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) { + if(BLE_GATT_ERR_BROWSE_NO_ANY_MORE == status) + { return; } - if (status != BLE_SUCCESS) { - return; - } - uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << UUID_OFFSET_8; + if (BLE_SUCCESS == status) + { + uuid_disc = p_browse_srvc->uuid[0] | p_browse_srvc->uuid[1] << 8; - if (BLE_ATT_SVC_TX_POWER == uuid_disc) { - s_tps_c_env.handles.tps_srvc_start_handle = p_browse_srvc->start_hdl; - s_tps_c_env.handles.tps_srvc_end_handle = p_browse_srvc->end_hdl; + if (BLE_ATT_SVC_TX_POWER == uuid_disc) + { + s_tps_c_env.handles.tps_srvc_start_handle = p_browse_srvc->start_hdl; + s_tps_c_env.handles.tps_srvc_end_handle = p_browse_srvc->end_hdl; - for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) { - uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << UUID_OFFSET_8; - handle_disc = p_browse_srvc->start_hdl + i + 1; + for (uint32_t i = 0; i < (p_browse_srvc->end_hdl - p_browse_srvc->start_hdl); i++) + { + uuid_disc = p_browse_srvc->info[i].attr.uuid[0] | p_browse_srvc->info[i].attr.uuid[1] << 8; + handle_disc = p_browse_srvc->start_hdl + i + 1; - if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) { - if (BLE_ATT_CHAR_TX_POWER_LEVEL == uuid_disc) { - s_tps_c_env.handles.tps_tx_power_level_handle = handle_disc; + if (BLE_GATTC_BROWSE_ATTR_VAL == p_browse_srvc->info[i].attr_type) + { + if (BLE_ATT_CHAR_TX_POWER_LEVEL == uuid_disc) + { + s_tps_c_env.handles.tps_tx_power_level_handle = handle_disc; + } + } + else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) + { + break; } - } else if (BLE_GATTC_BROWSE_NONE == p_browse_srvc->info[i].attr_type) { - break; } - } - tps_c_evt.evt_type = TPS_C_EVT_DISCOVERY_COMPLETE; + tps_c_evt.evt_type = TPS_C_EVT_DISCOVERY_COMPLETE; + } } - if (s_tps_c_env.evt_handler) { + if (s_tps_c_env.evt_handler) + { s_tps_c_env.evt_handler(&tps_c_evt); } } +static void tps_c_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + tps_c_att_read_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.read_rsp); + break; + + case BLE_GATTC_EVT_SRVC_BROWSE: + tps_c_srvc_browse_evt_handler(p_evt->evt.gattc_evt.index, p_evt->evt_status, &p_evt->evt.gattc_evt.params.srvc_browse); + break; + } +} /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t tps_client_init(tps_c_evt_handler_t evt_handler) { - sdk_err_t ret; - if (evt_handler == NULL) { + if (NULL == evt_handler) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_tps_c_env, sizeof(s_tps_c_env), 0, sizeof(s_tps_c_env)); - if (ret < 0) { - return ret; - } + memset(&s_tps_c_env, 0, sizeof(s_tps_c_env)); s_tps_c_env.evt_handler = evt_handler; - return ble_client_prf_add(&bas_c_prf_info, &s_tps_c_env.prf_id); + return ble_gattc_prf_add(&s_tps_service_uuid, tps_c_ble_evt_handler); } sdk_err_t tps_c_disc_srvc_start(uint8_t conn_idx) { - uint8_t target_uuid[2]; - - target_uuid[0] = LO_U16(BLE_ATT_SVC_TX_POWER); - target_uuid[1] = HI_U16(BLE_ATT_SVC_TX_POWER); - - const ble_uuid_t tps_service_uuid = { - .uuid_len = 2, - .uuid = target_uuid, - }; - - return ble_gattc_prf_services_browse(s_tps_c_env.prf_id, conn_idx, &tps_service_uuid); + return ble_gattc_services_browse(conn_idx, &s_tps_service_uuid); } sdk_err_t tps_c_tx_power_level_read(uint8_t conn_idx) { - if (BLE_ATT_INVALID_HDL == s_tps_c_env.handles.tps_tx_power_level_handle) { + if (BLE_ATT_INVALID_HDL == s_tps_c_env.handles.tps_tx_power_level_handle) + { return SDK_ERR_INVALID_HANDLE; } - return ble_gattc_prf_read(s_tps_c_env.prf_id, conn_idx, s_tps_c_env.handles.tps_tx_power_level_handle, 0); + return ble_gattc_read(conn_idx, s_tps_c_env.handles.tps_tx_power_level_handle, 0); } diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.h index 02e4063..8399332 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/tps_c/tps_c.h @@ -56,18 +56,17 @@ #ifndef __TPS_C_H__ #define __TPS_C_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "ble_prf_types.h" #include "custom_config.h" +#include +#include /** * @defgroup TPS_C_MACRO Defines * @{ */ -#define TPS_C_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of TPS Client connections. */ +#define TPS_C_CONNECTION_MAX 10 /**< Maximum number of TPS Client connections. */ /** @} */ /** @@ -75,11 +74,11 @@ * @{ */ /**@brief Tx Power Service Client event type. */ -typedef enum { +typedef enum +{ TPS_C_EVT_INVALID, /**< TPS Client invalid event. */ TPS_C_EVT_DISCOVERY_COMPLETE, /**< TPS Client has found TPS service and its characteristics. */ - TPS_C_EVT_DISCOVERY_FAIL, /**< TPS Client found TPS service failed because of invalid operation or \ - no found at the peer. */ + TPS_C_EVT_DISCOVERY_FAIL, /**< TPS Client found TPS service failed because of invalid operation or no found at the peer. */ TPS_C_EVT_TX_POWER_LEVEL_RECEIVE, /**< TPS Client has received Tx Power Level value. */ } tps_c_evt_type_t; /** @} */ @@ -89,15 +88,16 @@ typedef enum { * @{ */ /**@brief Handles on the connected peer device needed to interact with it. */ -typedef struct { +typedef struct +{ uint16_t tps_srvc_start_handle; /**< TPS Service start handle. */ uint16_t tps_srvc_end_handle; /**< TPS Service end handle. */ - uint16_t tps_tx_power_level_handle; /**< TPS Tx Power Level characteristic Value handle \ - which has been got from peer. */ + uint16_t tps_tx_power_level_handle; /**< TPS Tx Power Level characteristic Value handle which has been got from peer. */ } tps_c_handles_t; /**@brief Tx Power Service Client event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The connection index. */ tps_c_evt_type_t evt_type; /**< TPS Client event type. */ int8_t tx_power_level; /**< Tx Power level. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/BUILD.gn new file mode 100644 index 0000000..112bc10 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("uds") { + sources = [ "uds.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.c index ac4e701..ff530a6 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.c @@ -46,30 +46,13 @@ #include "utility.h" #include "app_log.h" -#define HEIGHT_165 165 -#define HEIGHT_1650 1650 -#define YEAR_2000_2000 2000 -#define MONTH_01 01 -#define DAY_01 01 -#define INDEX_2 2 -#define INDEX_3 3 -#define INDEX_5 5 -#define AGE_18 18 -#define YEAR_LOW 1582 -#define YEAR_HIGHT 9999 -#define ROLL_NUM 63 -#define MONTH_12 12 -#define DAY_31 31 -#define HEIGHT_40 40 -#define HEIGHT_250 250 -#define USER_DATA_OFFSET 2 -#define NAME_LEN_OFFSET 3 /* * ENUMERATIONS **************************************************************************************** */ /**@brief User Data Service Attributes Indexes. */ -enum { +enum +{ // User Data Service UDS_IDX_SVC, @@ -120,237 +103,145 @@ enum { ***************************************************************************************** */ /**@brief User Data Service environment variable. */ -struct uds_env_t { - uds_init_t - uds_init; /**< User Data Service initialization variables. */ +struct uds_env_t +{ + uds_init_t uds_init; /**< User Data Service initialization variables. */ uint16_t start_hdl; /**< User Data Service start handle. */ - bool - ucp_in_progress; /**< A previously triggered Control Point operationis - still in progress. */ - uint8_t - segm_head_roll_num; /**< Rolling Segment Number of Segmentation Header. */ + bool ucp_in_progress; /**< A previously triggered Control Point operation is still in progress. */ + uint8_t segm_head_roll_num; /**< Rolling Segment Number of Segmentation Header. */ uint8_t consent_try_num; /**< The number of consent tries. */ - uint16_t - db_change_incr_ntf_cfg[UDS_CONNECTION_MAX]; /**< The configuration of Current Time Notification - which is configured by the peer devices. */ - uint16_t - ctrl_point_ind_cfg[UDS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification - which is configured by the peer devices. */ - uint16_t - regist_user_ind_cfg[UDS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification - which is configured by the peer devices. */ + uint16_t db_change_incr_ntf_cfg[UDS_CONNECTION_MAX]; /**< The configuration of Current Time Notification which is configured by the peer devices. */ + uint16_t ctrl_point_ind_cfg[UDS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification which is configured by the peer devices. */ + uint16_t regist_user_ind_cfg[UDS_CONNECTION_MAX]; /**< The configuration of SC Control Point Notification which is configured by the peer devices. */ + ble_gatts_create_db_t uds_gatts_db; /**< User Data Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t uds_init(void); -static void uds_disconnect_cb(uint8_t conn_idx, uint8_t reason); - -static void uds_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void uds_write_att_cb(uint8_t conidx, const gatts_write_req_cb_t *p_param); -static void uds_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_req); -static void uds_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void uds_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); -static void uds_age_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); -static void uds_date_of_birth_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); -static void uds_first_name_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); -static void uds_height_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); -static void uds_gender_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); -static void uds_db_change_incr_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm); +static sdk_err_t uds_age_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); +static sdk_err_t uds_date_of_birth_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); +static sdk_err_t uds_first_name_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); +static sdk_err_t uds_height_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); +static sdk_err_t uds_gender_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); +static sdk_err_t uds_db_change_incr_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt); static void uds_receive_ucp_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length); static void uds_regist_user_value_encode(uint8_t conn_idx); static sdk_err_t uds_indicate_user_char_val_chunk(uint8_t conn_idx); + /* * LOCAL VARIABLE DEFINITIONS ***************************************************************************************** */ static struct uds_env_t s_uds_env; static uds_regi_user_data_stream_t s_regi_user_char_val_stream; +static uint8_t local_buf[UDS_REGI_USER_VAL_LEN_MAX * 5 * 3]; +static uint16_t local_segm_length[10]; +static const uint8_t s_uds_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_USER_DATA); +extern wss_db_user_buf_t s_wss_db_user_buf; +extern wss_rec_cmd_queue_t s_wss_db_rec_cmd_queue; /**@brief Full UDS Database Description - Used to add attributes into the database. */ -static const attm_desc_t uds_attr_tab[UDS_IDX_NB] = { +static const ble_gatts_attm_desc_t uds_attr_tab[UDS_IDX_NB] = +{ // User Data Service Declaration - [UDS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Database Change Increment Characteristic - Declaration - [UDS_IDX_DB_CHANGE_INCR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_DB_CHANGE_INCR_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Database Change Increment Characteristic - Value - [UDS_IDX_DB_CHANGE_INCR_VAL] = { - BLE_ATT_CHAR_DATABASE_CHANGE_INCREMENT, - READ_PERM_UNSEC | NOTIFY_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_DB_CHANGE_INCR_VAL_LEN_MAX - }, + [UDS_IDX_DB_CHANGE_INCR_VAL] = {BLE_ATT_CHAR_DATABASE_CHANGE_INCREMENT, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_NOTIFY_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_DB_CHANGE_INCR_VAL_LEN_MAX}, // Database Change Increment Characteristic - Client Characteristic Configuration Descriptor - [UDS_IDX_DB_CHANGE_INCR_NTF_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, + [UDS_IDX_DB_CHANGE_INCR_NTF_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, // User Index Characteristic - Declaration - [UDS_IDX_USER_INDEX_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_USER_INDEX_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // User Index Characteristic - Value - [UDS_IDX_USER_INDEX_VAL] = { - BLE_ATT_CHAR_USER_INDEX, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_USER_INDEX_VAL_LEN_MAX - }, + [UDS_IDX_USER_INDEX_VAL] = {BLE_ATT_CHAR_USER_INDEX, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_USER_INDEX_VAL_LEN_MAX}, // User Control Point Characteristic - Declaration - [UDS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_CTRL_POINT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // User Control Point Characteristic - Value - [UDS_IDX_CTRL_POINT_VAL] = { - BLE_ATT_CHAR_USER_CONTROL_POINT, - WRITE_REQ_PERM_UNSEC | INDICATE_PERM(UNAUTH), - ATT_VAL_LOC_USER, - UDS_CTRL_PT_VAL_LEN_MAX - }, + [UDS_IDX_CTRL_POINT_VAL] = {BLE_ATT_CHAR_USER_CONTROL_POINT, + BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_INDICATE_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_CTRL_PT_VAL_LEN_MAX}, // User Control Point Characteristic - Client Characteristic Configuration Descriptor - [UDS_IDX_CTRL_POINT_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, - + [UDS_IDX_CTRL_POINT_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, + // Age Characteristic - Declaration - [UDS_IDX_AGE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_AGE_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Age Characteristic - Value - [UDS_IDX_AGE_VAL] = { - BLE_ATT_CHAR_AGE, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_AGE_VAL_LEN_MAX - }, + [UDS_IDX_AGE_VAL] = {BLE_ATT_CHAR_AGE, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_AGE_VAL_LEN_MAX}, // Date of Birth Characteristic - Declaration - [UDS_IDX_DATE_OF_BIRTH_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_DATE_OF_BIRTH_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Date of Birth Characteristic - Value - [UDS_IDX_DATE_OF_BIRTH_VAL] = { - BLE_ATT_CHAR_DATE_OF_BIRTH, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_DATE_OF_BIRTH_VAL_LEN_MAX - }, - + [UDS_IDX_DATE_OF_BIRTH_VAL] = {BLE_ATT_CHAR_DATE_OF_BIRTH, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_DATE_OF_BIRTH_VAL_LEN_MAX}, + // First Name Characteristic - Declaration - [UDS_IDX_FIRST_NAME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_FIRST_NAME_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // First Name Characteristic - Value - [UDS_IDX_FIRST_NAME_VAL] = { - BLE_ATT_CHAR_FIRST_NAME, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_FIRST_NAME_VAL_LEN_MAX - }, + [UDS_IDX_FIRST_NAME_VAL] = {BLE_ATT_CHAR_FIRST_NAME, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_FIRST_NAME_VAL_LEN_MAX}, // Height Characteristic - Declaration - [UDS_IDX_HEIGHT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_HEIGHT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Height Characteristic - Value - [UDS_IDX_HEIGHT_VAL] = { - BLE_ATT_CHAR_HEIGHT, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_HEIGHT_VAL_LEN_MAX - }, - + [UDS_IDX_HEIGHT_VAL] = {BLE_ATT_CHAR_HEIGHT, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_HEIGHT_VAL_LEN_MAX}, + // Gender Characteristic - Declaration - [UDS_IDX_GENDER_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_GENDER_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Gender Characteristic - Value - [UDS_IDX_GENDER_VAL] = { - BLE_ATT_CHAR_GENDER, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_GENDER_VAL_LEN_MAX - }, - + [UDS_IDX_GENDER_VAL] = {BLE_ATT_CHAR_GENDER, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_GENDER_VAL_LEN_MAX}, + // Registered User Characteristic Declaration - [UDS_IDX_REGIST_USER_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [UDS_IDX_REGIST_USER_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Registered User Characteristic Declaration value - [UDS_IDX_REGIST_USER_VAL] = { - BLE_ATT_CHAR_REGISTERED_USER, - INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - UDS_REGI_USER_VAL_LEN_MAX - }, + [UDS_IDX_REGIST_USER_VAL] = {BLE_ATT_CHAR_REGISTERED_USER, + BLE_GATTS_INDICATE_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + UDS_REGI_USER_VAL_LEN_MAX}, // Registered User Characteristic Declaration - Client Characteristic Configuration Descriptor - [UDS_IDX_REGIST_USER_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief UDS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t uds_task_cbs = { - (prf_init_func_t) uds_init, - NULL, - uds_disconnect_cb -}; - -/**@brief UDS Task Callbacks. */ -static gatts_prf_cbs_t uds_cb_func = { - uds_read_att_cb, - uds_write_att_cb, - uds_gatts_prep_write_cb, - uds_gatts_ntf_ind_cb, - uds_cccd_set_cb -}; - -/**@brief UDS Information. */ -static const prf_server_info_t uds_prf_info = { - .max_connection_nb = UDS_CONNECTION_MAX, - .manager_cbs = &uds_task_cbs, - .gatts_prf_cbs = &uds_cb_func + [UDS_IDX_REGIST_USER_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize User Data service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t uds_init(void) -{ - // The start handle must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t uds_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_USER_DATA); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = uds_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_uds_env.uds_init.char_mask); - gatts_db.max_nb_attr = UDS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = uds_attr_tab; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_uds_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the disconnection event. @@ -359,7 +250,7 @@ static sdk_err_t uds_init(void) * @param[in] reason: Reason of disconnection. ***************************************************************************************** */ -static void uds_disconnect_cb(uint8_t conn_idx, uint8_t reason) +static void uds_disconnect_evt_handler(uint8_t conn_idx, uint8_t reason) { s_uds_env.ucp_in_progress = false; } @@ -372,96 +263,114 @@ static void uds_disconnect_cb(uint8_t conn_idx, uint8_t reason) * @param[in] p_param: Pointer to the parameters of the read request. ***************************************************************************************** */ -static void uds_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void uds_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; + ble_gatts_read_cfm_t cfm; uint8_t handle = p_param->handle; uint8_t tab_index = prf_find_idx_by_handle(handle, - s_uds_env.start_hdl, - UDS_IDX_NB, - (uint8_t *)&s_uds_env.uds_init.char_mask); + s_uds_env.start_hdl, + UDS_IDX_NB, + (uint8_t *)&s_uds_env.uds_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - wss_rec_t loc_rec; + uint32_t db_change_incr_val; - switch (tab_index) { - case UDS_IDX_AGE_VAL: { - if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) { + switch (tab_index) + { + case UDS_IDX_AGE_VAL: + { + if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) + { cfm.status = BLE_ATT_ERR_READ_NOT_PERMITTED; cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)UDS_ERROR_UD_ACCESS_NOT_PERMIT; - } else { - wss_db_record_get(s_uds_env.uds_init.user_index, &loc_rec); + } + else + { cfm.length = sizeof(uint8_t); - cfm.value = (uint8_t *)&loc_rec.age; + cfm.value = (uint8_t *)&s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].age; } break; } - case UDS_IDX_DATE_OF_BIRTH_VAL: { - if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) { + case UDS_IDX_DATE_OF_BIRTH_VAL: + { + if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) + { cfm.status = BLE_ATT_ERR_READ_NOT_PERMITTED; cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)UDS_ERROR_UD_ACCESS_NOT_PERMIT; - } else { - wss_db_record_get(s_uds_env.uds_init.user_index, &loc_rec); + } + else + { cfm.length = sizeof(birth_date_t); - cfm.value = (uint8_t *)&loc_rec.date_of_birth; + cfm.value = (uint8_t *)&s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].date_of_birth; } break; } - case UDS_IDX_FIRST_NAME_VAL: { - if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) { + case UDS_IDX_FIRST_NAME_VAL: + { + if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) + { cfm.status = BLE_ATT_ERR_READ_NOT_PERMITTED; cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)UDS_ERROR_UD_ACCESS_NOT_PERMIT; - } else { - wss_db_record_get(s_uds_env.uds_init.user_index, &loc_rec); - cfm.length = loc_rec.name_length; - cfm.value = (uint8_t *)loc_rec.first_name; + } + else + { + cfm.length = s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].name_length; + cfm.value = (uint8_t *)&s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].first_name; } break; } - case UDS_IDX_HEIGHT_VAL: { - if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) { + case UDS_IDX_HEIGHT_VAL: + { + if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) + { cfm.status = BLE_ATT_ERR_READ_NOT_PERMITTED; cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)UDS_ERROR_UD_ACCESS_NOT_PERMIT; - } else { - wss_db_record_get(s_uds_env.uds_init.user_index, &loc_rec); + } + else + { cfm.length = sizeof(uint16_t); - cfm.value = (uint8_t *)&loc_rec.height; + cfm.value = (uint8_t *)&s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].height; } break; } - case UDS_IDX_GENDER_VAL: { - if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) { + case UDS_IDX_GENDER_VAL: + { + if (s_uds_env.uds_init.user_index == UDS_UNKNOWN_USER) + { cfm.status = BLE_ATT_ERR_READ_NOT_PERMITTED; cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)UDS_ERROR_UD_ACCESS_NOT_PERMIT; - } else { - wss_db_record_get(s_uds_env.uds_init.user_index, &loc_rec); + } + else + { cfm.length = sizeof(uint8_t); - cfm.value = (uint8_t *)&loc_rec.gender; + cfm.value = (uint8_t *)&s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].gender; } break; } - case UDS_IDX_DB_CHANGE_INCR_VAL: { - uint8_t user_index = s_uds_env.uds_init.user_index; - if (UDS_UNKNOWN_USER == user_index) { - uint32_t db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; + case UDS_IDX_DB_CHANGE_INCR_VAL: + { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { + db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; + + cfm.length = sizeof(uint32_t); + cfm.value = (uint8_t *)&db_change_incr_val; + } + else + { cfm.length = sizeof(uint32_t); - cfm.value = (uint8_t *)&db_change_incr_val; - } else { - if (wss_db_record_get(user_index, &loc_rec)) { - cfm.length = sizeof(uint32_t); - cfm.value = (uint8_t *)&loc_rec.db_change_incr_val; - } + cfm.value = (uint8_t *)&(s_wss_db_user_buf.user_data[s_uds_env.uds_init.user_index].db_change_incr_val); } break; } @@ -471,19 +380,22 @@ static void uds_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param cfm.value = (uint8_t *)&s_uds_env.db_change_incr_ntf_cfg[conn_idx]; break; - case UDS_IDX_USER_INDEX_VAL: { + case UDS_IDX_USER_INDEX_VAL: + { cfm.length = sizeof(uint8_t); cfm.value = (uint8_t *)&s_uds_env.uds_init.user_index; break; } - case UDS_IDX_REGIST_USER_IND_CFG: { + case UDS_IDX_REGIST_USER_IND_CFG: + { cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_uds_env.regist_user_ind_cfg[conn_idx]; break; } - case UDS_IDX_CTRL_POINT_IND_CFG: { + case UDS_IDX_CTRL_POINT_IND_CFG: + { cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_uds_env.ctrl_point_ind_cfg[conn_idx]; break; @@ -506,14 +418,14 @@ static void uds_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: Pointer to the parameters of the write request. ***************************************************************************************** */ -static void uds_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void uds_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { uint16_t handle = p_param->handle; uint16_t tab_index = 0; uint16_t cccd_value = 0; bool ucp_evt = false; uds_evt_t event; - gatts_write_cfm_t cfm; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_uds_env.start_hdl, @@ -524,66 +436,73 @@ static void uds_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par event.evt_type = UDS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case UDS_IDX_AGE_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } - - event.evt_type = UDS_EVT_AGE_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_age_write_handler(p_param->value, p_param->length, &cfm); + + uds_age_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_DATE_OF_BIRTH_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } - event.evt_type = UDS_EVT_DATE_OF_BIRTH_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_date_of_birth_write_handler(p_param->value, p_param->length, &cfm); + + uds_date_of_birth_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_FIRST_NAME_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } event.evt_type = UDS_EVT_FIRST_NAME_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_first_name_write_handler(p_param->value, p_param->length, &cfm); + + uds_first_name_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_HEIGHT_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } - event.evt_type = UDS_EVT_HEIGHT_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_height_write_handler(p_param->value, p_param->length, &cfm); + + uds_height_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_GENDER_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } - event.evt_type = UDS_EVT_GENDER_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_gender_write_handler(p_param->value, p_param->length, &cfm); + + uds_gender_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_DB_CHANGE_INCR_VAL: - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { cfm.status = UDS_ERROR_UD_ACCESS_NOT_PERMIT; } - event.evt_type = UDS_EVT_DB_CHANGE_INCR_SET_BY_PEER; event.p_data = p_param->value; event.length = p_param->length; - uds_db_change_incr_write_handler(p_param->value, p_param->length, &cfm); + + uds_db_change_incr_write_handler(p_param->value, p_param->length, &cfm, &event); break; case UDS_IDX_DB_CHANGE_INCR_NTF_CFG: @@ -603,14 +522,27 @@ static void uds_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par break; case UDS_IDX_CTRL_POINT_VAL: - if (PRF_CLI_START_IND != s_uds_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND != s_uds_env.ctrl_point_ind_cfg[conn_idx]) + { cfm.status = UDS_ERROR_CCCD_INVALID; break; - } else if (s_uds_env.ucp_in_progress) { + } + else if (s_uds_env.ucp_in_progress) + { cfm.status = UDS_ERROR_PROC_IN_PROGRESS; - } else if (PRF_CLI_START_IND == s_uds_env.ctrl_point_ind_cfg[conn_idx]) { - ucp_evt = true; - s_uds_env.ucp_in_progress = true; + } + else if (PRF_CLI_START_IND == s_uds_env.ctrl_point_ind_cfg[conn_idx]) + { + if (UDS_CTRL_PT_OP_LIST_ALL_USERS == p_param->value[0] && \ + (PRF_CLI_START_IND != s_uds_env.regist_user_ind_cfg[conn_idx])) + { + cfm.status = UDS_ERROR_CCCD_INVALID; + } + else + { + ucp_evt = true; + s_uds_env.ucp_in_progress = true; + } } break; @@ -629,13 +561,15 @@ static void uds_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par ble_gatts_write_cfm(conn_idx, &cfm); - if (ucp_evt) { + if (ucp_evt) + { uds_receive_ucp_handler(conn_idx, p_param->value, p_param->length); } - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && UDS_EVT_INVALID != event.evt_type && - s_uds_env.uds_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && UDS_EVT_INVALID != event.evt_type && s_uds_env.uds_init.evt_handler) + { s_uds_env.uds_init.evt_handler(&event); } + } /** @@ -646,14 +580,15 @@ static void uds_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_par * @param[in]: p_prep_req: Pointer to the handle of cccd attribute. ***************************************************************************************** */ -static void uds_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req_cb_t *p_prep_req) +static void uds_gatts_prep_write_evt_handler(uint8_t conn_idx, const ble_gatts_evt_prep_write_t *p_prep_req) { - gatts_prep_write_cfm_t cfm; + ble_gatts_prep_write_cfm_t cfm; cfm.handle = p_prep_req->handle; cfm.length = UDS_REGI_USER_VAL_LEN_MAX; cfm.status = BLE_SUCCESS; + APP_LOG_DEBUG("Prepare write."); ble_gatts_prepare_write_cfm(conn_idx, &cfm); } @@ -666,12 +601,13 @@ static void uds_gatts_prep_write_cb(uint8_t conn_idx, const gatts_prep_write_req * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void uds_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void uds_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; uds_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -683,7 +619,8 @@ static void uds_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = UDS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case UDS_IDX_DB_CHANGE_INCR_NTF_CFG: event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ UDS_EVT_DB_CHANGE_INCR_NOTIFICATION_ENABLE : \ @@ -709,7 +646,8 @@ static void uds_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val break; } - if (UDS_EVT_INVALID != event.evt_type && s_uds_env.uds_init.evt_handler) { + if (UDS_EVT_INVALID != event.evt_type && s_uds_env.uds_init.evt_handler) + { s_uds_env.uds_init.evt_handler(&event); } } @@ -723,7 +661,7 @@ static void uds_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void uds_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void uds_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { uds_evt_t event; @@ -731,22 +669,29 @@ static void uds_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gat event.conn_idx = conn_idx; uint8_t tab_index; - tab_index = prf_find_idx_by_handle(p_ntf_ind->handle, + tab_index = prf_find_idx_by_handle(p_ntf_ind->handle, s_uds_env.start_hdl, UDS_IDX_NB, (uint8_t *)&s_uds_env.uds_init.char_mask); - if (BLE_GAP_ERR_TIMEOUT == status) { + if (BLE_GAP_ERR_TIMEOUT == status) + { ble_gap_disconnect(conn_idx); } - if (s_uds_env.uds_init.evt_handler && SDK_SUCCESS == status) { - if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) { + if (s_uds_env.uds_init.evt_handler && SDK_SUCCESS == status) + { + if (BLE_GATT_NOTIFICATION == p_ntf_ind->type) + { event.evt_type = UDS_EVT_DB_CHANGE_INCR_SEND_CPLT; s_uds_env.uds_init.evt_handler(&event); - } else if (BLE_GATT_INDICATION == p_ntf_ind->type && (UDS_IDX_REGIST_USER_VAL == tab_index)) { + } + else if (BLE_GATT_INDICATION == p_ntf_ind->type && (UDS_IDX_REGIST_USER_VAL == tab_index)) + { uds_indicate_user_char_val_chunk(conn_idx); - } else if (BLE_GATT_INDICATION == p_ntf_ind->type && (UDS_IDX_CTRL_POINT_VAL == tab_index)) { + } + else if (BLE_GATT_INDICATION == p_ntf_ind->type && (UDS_IDX_CTRL_POINT_VAL == tab_index)) + { event.evt_type = UDS_EVT_CTRL_POINT_RSP_CPLT; s_uds_env.ucp_in_progress = false; s_uds_env.uds_init.evt_handler(&event); @@ -754,15 +699,6 @@ static void uds_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gat } } -/** - ***************************************************************************************** - * @brief Change the endian of Registered User Name. - * - * @param[in] user_index: index. - * @param[in] p_param: Pointer to the parameters of the complete event. - ***************************************************************************************** - */ - /** ***************************************************************************************** * @brief Handle Age Characteristic write event. @@ -772,16 +708,31 @@ static void uds_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gat * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_age_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_age_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - if (length != 1 || p_data[0] > 100) { - p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - uint8_t age = p_data[0]; - uint8_t user_index = s_uds_env.uds_init.user_index; + sdk_err_t error_code; - wss_db_record_age_set(user_index, age); + if (length != 1 || p_data[0] > 120) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; } + else + { + p_evt->evt_type = UDS_EVT_AGE_SET_BY_PEER; + + uint8_t age = p_data[0]; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].age = age; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } + + return error_code; } /** @@ -793,24 +744,97 @@ static void uds_age_write_handler(const uint8_t *p_data, uint16_t length, gatts_ * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_date_of_birth_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_date_of_birth_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - if (length != 4) { + sdk_err_t error_code; + + if (length != 4) + { p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - birth_date_t date_of_birth; + error_code = BLE_GATT_ERR_WRITE; + } + else + { + birth_date_t date_of_birth; date_of_birth.year = BUILD_U16(p_data[0], p_data[1]); - date_of_birth.month = p_data[INDEX_2]; - date_of_birth.day = p_data[INDEX_3]; - - if (date_of_birth.month > MONTH_12 || (date_of_birth.day > DAY_31) ||\ - ((date_of_birth.year < YEAR_LOW || date_of_birth.year > YEAR_HIGHT) && (date_of_birth.year != 0))) { + date_of_birth.month = p_data[2]; + date_of_birth.day = p_data[3]; + + if (date_of_birth.month > 12 || (date_of_birth.day > 31) ||\ + ((date_of_birth.year < 1582 || date_of_birth.year > 9999) && (date_of_birth.year != 0))) + { p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - uint8_t user_index = s_uds_env.uds_init.user_index; - wss_db_record_date_of_birth_set(user_index, &date_of_birth); + error_code = BLE_GATT_ERR_WRITE; + } + else + { + if ((((date_of_birth.month == 1) || (date_of_birth.month == 3) || (date_of_birth.month == 5) || + (date_of_birth.month == 7) || (date_of_birth.month == 8) || (date_of_birth.month == 10) || (date_of_birth.month == 12)) + && (date_of_birth.day > 31)) || + (((date_of_birth.month == 4) || (date_of_birth.month == 6) || (date_of_birth.month == 9) || (date_of_birth.month == 11)) + && (date_of_birth.day > 30))) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; + } + else if (date_of_birth.month == 2) + { + if (((date_of_birth.year % 4 == 0) && (date_of_birth.year % 100 != 0)) || (date_of_birth.year % 400 ==0)) // leap year + { + if (date_of_birth.day > 29) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; + } + else + { + p_evt->evt_type = UDS_EVT_DATE_OF_BIRTH_SET_BY_PEER; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].date_of_birth = date_of_birth; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } + } + else // average year + { + if (date_of_birth.day > 28) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; + } + else + { + p_evt->evt_type = UDS_EVT_DATE_OF_BIRTH_SET_BY_PEER; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].date_of_birth = date_of_birth; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } + } + } + else + { + p_evt->evt_type = UDS_EVT_DATE_OF_BIRTH_SET_BY_PEER; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].date_of_birth = date_of_birth; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } } } + return error_code; } /** @@ -822,10 +846,19 @@ static void uds_date_of_birth_write_handler(const uint8_t *p_data, uint16_t leng * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_first_name_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_first_name_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - uint8_t user_index = s_uds_env.uds_init.user_index; - wss_db_record_first_name_set(user_index, p_data, length); + sdk_err_t error_code; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].name_length = length; + memcpy(&s_wss_db_user_buf.user_data[cur_user_id].first_name, p_data, length); + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + return error_code; } /** @@ -837,19 +870,37 @@ static void uds_first_name_write_handler(const uint8_t *p_data, uint16_t length, * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_height_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_height_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - if (length != INDEX_2) { + sdk_err_t error_code; + + if (length != 2) + { p_cfm->status = BLE_GATT_ERR_WRITE; - } else { + error_code = BLE_GATT_ERR_WRITE; + } + else + { uint16_t height = BUILD_U16(p_data[0], p_data[1]); - if (height < HEIGHT_40 || height > HEIGHT_250) { + if (height < 40 || 250 < height) + { p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - uint8_t user_index = s_uds_env.uds_init.user_index; - wss_db_record_height_set(user_index, height); + error_code = BLE_GATT_ERR_WRITE; + } + else + { + p_evt->evt_type = UDS_EVT_HEIGHT_SET_BY_PEER; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].height = height; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; } } + return error_code; } /** @@ -861,16 +912,30 @@ static void uds_height_write_handler(const uint8_t *p_data, uint16_t length, gat * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_gender_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_gender_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - if (length != 1 || (p_data[0] > INDEX_2)) { - p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - uint8_t gender = p_data[0]; - uint8_t user_index = s_uds_env.uds_init.user_index; + sdk_err_t error_code; - wss_db_record_gender_set(user_index, gender); + if (length != 1 || (p_data[0] > 2)) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; } + else + { + p_evt->evt_type = UDS_EVT_GENDER_SET_BY_PEER; + uint8_t gender = p_data[0]; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].gender = gender; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } + + return error_code; } /** @@ -882,16 +947,30 @@ static void uds_gender_write_handler(const uint8_t *p_data, uint16_t length, gat * @param[in] p_cfm: Pointer of the write confirmation. ***************************************************************************************** */ -static void uds_db_change_incr_write_handler(const uint8_t *p_data, uint16_t length, gatts_write_cfm_t *p_cfm) +static sdk_err_t uds_db_change_incr_write_handler(const uint8_t *p_data, uint16_t length, ble_gatts_write_cfm_t *p_cfm, uds_evt_t *p_evt) { - if (length != UDS_DB_CHANGE_INCR_VAL_LEN_MAX) { - p_cfm->status = BLE_GATT_ERR_WRITE; - } else { - uint8_t user_index = s_uds_env.uds_init.user_index; + sdk_err_t error_code; - uint32_t db_change_incr_val = BUILD_U32(p_data[0], p_data[1], p_data[INDEX_2], p_data[INDEX_3]); - bool status = wss_db_record_db_change_incr_val_set(user_index, db_change_incr_val); + if (length != UDS_DB_CHANGE_INCR_VAL_LEN_MAX) + { + p_cfm->status = BLE_GATT_ERR_WRITE; + error_code = BLE_GATT_ERR_WRITE; } + else + { + p_evt->evt_type = UDS_EVT_DB_CHANGE_INCR_SET_BY_PEER; + uint32_t db_change_incr_val = BUILD_U32(p_data[0], p_data[1], p_data[2], p_data[3]); + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].db_change_incr_val = db_change_incr_val; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_WRITE_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + error_code = BLE_SUCCESS; + } + + return error_code; } /** @@ -910,53 +989,50 @@ static void uds_op_regist_new_user_handler(uint8_t conn_idx, const uint8_t *p_da rsp[0] = UDS_CTRL_PT_OP_RSP_CODE; rsp[1] = UDS_CTRL_PT_OP_REGIST_NEW_USER; - rsp[INDEX_2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + rsp[2] = UDS_CTRL_PT_RSP_SUCCESS; uint16_t consent_code = BUILD_U16(p_data[0], p_data[1]); - if ((sizeof(uint16_t) != length) || (UDS_CONSENT_CODE_VAL_MAX < consent_code)) { + + if ((sizeof(uint16_t) != length) || (UDS_CONSENT_CODE_VAL_MAX < consent_code)) + { + rsp[2] = UDS_CTRL_PT_RSP_INVALID_PARAM; uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); - } else { - uds_chars_val_t uds_chars_val; - uint8_t user_nums; - uint8_t db_change_incr_val; - uint8_t new_user_index; + } + else + { + uint8_t new_user_id; + new_user_id = wss_db_user_id_get(); - user_nums = (uint8_t)wss_db_records_num_get(); - if (WSS_DB_RECORDS_MAX <= user_nums) { - wss_db_record_delete(1); - new_user_index = 0x01; - } else { - new_user_index = user_nums; + if (UDS_UNKNOWN_USER == new_user_id) + { + new_user_id = 0x01; } - uint8_t first_name[] = "tom"; - db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; - uds_chars_val.age = AGE_18; - uds_chars_val.height = HEIGHT_165; // The unit is cm. - uds_chars_val.gender = 0x00; - uds_chars_val.date_of_birth.year = YEAR_2000; - uds_chars_val.date_of_birth.month = MONTH_01; - uds_chars_val.date_of_birth.day = DAY_01; - uds_chars_val.p_first_name = &first_name[0]; - uds_chars_val.name_length = sizeof(first_name); - rsp[INDEX_3] = new_user_index; + uint8_t first_name[] = {'d', 'e', 'f', 'a', 'u', 'l', 't'}; - if (wss_db_record_add(new_user_index, consent_code, db_change_incr_val, &uds_chars_val) - && s_uds_env.uds_init.evt_handler) { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_SUCCESS; + s_wss_db_user_buf.user_id = new_user_id; + s_wss_db_user_buf.user_data[new_user_id].consent_code = consent_code; + s_wss_db_user_buf.user_data[new_user_id].db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; + s_wss_db_user_buf.user_data[new_user_id].age = 18; + s_wss_db_user_buf.user_data[new_user_id].height = 165; // The unit is cm. + s_wss_db_user_buf.user_data[new_user_id].gender = 0x00; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.year = 2000; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.month = 01; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.day = 01; + s_wss_db_user_buf.user_data[new_user_id].name_length = sizeof(first_name); + memcpy(s_wss_db_user_buf.user_data[new_user_id].first_name, &first_name[0], sizeof(first_name)); + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_ADD_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); - event.conn_idx = conn_idx; - event.evt_type = UDS_EVT_REGIST_NEW_USER; - event.p_data = &new_user_index; - event.length = length; - s_uds_env.uds_init.evt_handler(&event); - s_uds_env.uds_init.user_index = new_user_index; + event.conn_idx = conn_idx; + event.evt_type = UDS_EVT_REGIST_NEW_USER; + event.p_data = &new_user_id; + event.length = length; + s_uds_env.uds_init.evt_handler(&event); + s_uds_env.uds_init.user_index = new_user_id; - uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN + 1); - } else { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_FAILED; - uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); - } + rsp[3] = new_user_id; + uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN + 1); } } @@ -972,46 +1048,64 @@ static void uds_op_regist_new_user_handler(uint8_t conn_idx, const uint8_t *p_da static void uds_op_consent_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length) { uds_evt_t event; + uint8_t cur_user_id = p_data[0]; uint8_t rsp[UDS_CTRL_PT_RSP_LEN_MIN]; rsp[0] = UDS_CTRL_PT_OP_RSP_CODE; rsp[1] = UDS_CTRL_PT_OP_CONSENT; - rsp[INDEX_2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + rsp[2] = UDS_CTRL_PT_RSP_SUCCESS; - uint16_t consent_code = BUILD_U16(p_data[1], p_data[INDEX_2]); + uint16_t consent_code = BUILD_U16(p_data[1], p_data[2]); - if (UDS_CONSENT_TRY_NUM_MAX <= s_uds_env.consent_try_num) { + if (UDS_CONSENT_TRY_NUM_MAX <= s_uds_env.consent_try_num) + { #if defined(PTS_AUTO_TEST) - wss_db_record_clear(); -#endif - rsp[INDEX_2] = UDS_CTRL_PT_RSP_FAILED; - } else if (((sizeof(uint16_t)+sizeof(uint8_t)) == length) && \ - (UDS_UNKNOWN_USER > p_data[0]) && \ - (UDS_CONSENT_CODE_VAL_MAX >= consent_code)) { - uint8_t user_index = p_data[0]; - wss_rec_t loc_rec; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; - bool status = wss_db_record_get(user_index, &loc_rec); - if (consent_code != loc_rec.consent_code || (!status)) { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_USER_NOT_AUTH; + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].consent_code = 0xFFFF; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_CLEAR_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); +#endif + rsp[2] = UDS_CTRL_PT_RSP_FAILED; + } + else if (((sizeof(uint16_t)+sizeof(uint8_t)) != length) || \ + (UDS_UNKNOWN_USER < cur_user_id) || \ + (UDS_UNKNOWN_USER > cur_user_id && (cur_user_id >= WSS_DB_RECORDS_MAX)) || \ + (UDS_CONSENT_CODE_VAL_MAX <= consent_code)) + { + rsp[2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + } + else + { + if (consent_code != s_wss_db_user_buf.user_data[cur_user_id].consent_code) + { + rsp[2] = UDS_CTRL_PT_RSP_USER_NOT_AUTH; s_uds_env.consent_try_num++; #if defined(PTS_AUTO_TEST) - wss_db_record_delete(s_uds_env.uds_init.user_index); -#endif - } else { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_SUCCESS; - event.conn_idx = conn_idx; - event.evt_type = UDS_EVT_USER_GRANT_ACCESS; - event.p_data = p_data; - event.length = length; + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].consent_code = 0xFFFF; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_CLEAR_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); +#endif + } + else + { + event.conn_idx = conn_idx; + event.evt_type = UDS_EVT_USER_GRANT_ACCESS; + event.p_data = p_data; + event.length = length; + event.uds_chars_val.height = s_wss_db_user_buf.user_data[cur_user_id].height; s_uds_env.uds_init.evt_handler(&event); - s_uds_env.uds_init.user_index = user_index; + + s_uds_env.uds_init.user_index = cur_user_id; s_uds_env.consent_try_num = 0; - s_uds_env.uds_init.evt_handler(&event); } } + uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); } @@ -1031,24 +1125,33 @@ static void uds_op_del_user_data_handler(uint8_t conn_idx, const uint8_t *p_data rsp[0] = UDS_CTRL_PT_OP_RSP_CODE; rsp[1] = UDS_CTRL_PT_OP_DEL_USER_DATA; - rsp[INDEX_2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + rsp[2] = UDS_CTRL_PT_RSP_SUCCESS; - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_USER_NOT_AUTH; - } else { - if (wss_db_record_delete(s_uds_env.uds_init.user_index)) { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_SUCCESS; - - event.conn_idx = conn_idx; - event.evt_type = UDS_EVT_DEL_USER_DATA; - event.p_data = p_data; - event.length = length; - s_uds_env.uds_init.evt_handler(&event); - s_uds_env.uds_init.user_index = UDS_UNKNOWN_USER; - } else { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_FAILED; - } + if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) + { + rsp[2] = UDS_CTRL_PT_RSP_USER_NOT_AUTH; } + else if (length > 0) + { + rsp[2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + } + else + { + uint8_t cur_user_id = s_uds_env.uds_init.user_index; + + s_wss_db_user_buf.user_id = cur_user_id; + s_wss_db_user_buf.user_data[cur_user_id].consent_code = 0xFFFF; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_DEL_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + event.conn_idx = conn_idx; + event.evt_type = UDS_EVT_DEL_USER_DATA; + event.p_data = p_data; + event.length = length; + s_uds_env.uds_init.evt_handler(&event); + s_uds_env.uds_init.user_index = UDS_UNKNOWN_USER; + } + uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); } @@ -1068,22 +1171,37 @@ static void uds_op_list_all_users_handler(uint8_t conn_idx, const uint8_t *p_dat rsp[0] = UDS_CTRL_PT_OP_RSP_CODE; rsp[1] = UDS_CTRL_PT_OP_LIST_ALL_USERS; - rsp[INDEX_2] = UDS_CTRL_PT_RSP_SUCCESS; + rsp[2] = UDS_CTRL_PT_RSP_SUCCESS; uint16_t user_num = wss_db_records_num_get(); - if (UDS_UNKNOWN_USER > user_num && 0 < user_num) { + + if (length > 0) + { + rsp[2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); + } + else if (UDS_UNKNOWN_USER > user_num) + { event.conn_idx = conn_idx; event.evt_type = UDS_EVT_CTRL_POINT_SET_BY_PEER; event.p_data = p_data; event.length = length; s_uds_env.uds_init.evt_handler(&event); - s_uds_env.regist_user_ind_cfg[conn_idx] = UDS_EVT_CTRL_POINT_INDICATION_ENABLE; - - uds_regist_user_value_encode(0); // start indicate the value of the registered user char. - uds_indicate_user_char_val_chunk(conn_idx); - } else if (user_num == 0) { - rsp[INDEX_3] = user_num; + if (PRF_CLI_START_IND == s_uds_env.regist_user_ind_cfg[conn_idx]) + { + uds_regist_user_value_encode(0); + uds_indicate_user_char_val_chunk(conn_idx); + } + else + { + rsp[3] = user_num; + uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN + 1); + } + } + else if (0 == user_num) + { + rsp[3] = user_num; uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN + 1); } } @@ -1100,40 +1218,63 @@ static void uds_op_list_all_users_handler(uint8_t conn_idx, const uint8_t *p_dat static void uds_op_del_users_handler(uint8_t conn_idx, const uint8_t *p_data, uint16_t length) { uds_evt_t event; + uint8_t cur_user_id = p_data[0]; uint8_t rsp[UDS_CTRL_PT_RSP_LEN_MIN+1]; rsp[0] = UDS_CTRL_PT_OP_RSP_CODE; rsp[1] = UDS_CTRL_PT_OP_DEL_USERS; - rsp[INDEX_2] = UDS_CTRL_PT_RSP_INVALID_PARAM; + rsp[2] = UDS_CTRL_PT_RSP_SUCCESS; + rsp[3] = cur_user_id; - if (sizeof(uint8_t) != length || UDS_UNKNOWN_USER < p_data[0] || (s_uds_env.uds_init.user_index < p_data[0] - && p_data[0] < UDS_UNKNOWN_USER)) { - s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present = false; - s_uds_env.uds_init.uds_regi_user_data_flag.user_name_truncated = false; + if (sizeof(uint8_t) != length || UDS_UNKNOWN_USER < cur_user_id || \ + (WSS_DB_RECORDS_MAX <= cur_user_id && cur_user_id < UDS_UNKNOWN_USER)) + { + rsp[2] = UDS_CTRL_PT_RSP_INVALID_PARAM; uds_ctrl_pt_rsp_send(conn_idx, rsp, UDS_CTRL_PT_RSP_LEN_MIN); - } else { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_SUCCESS; - - uint8_t user_index = p_data[0]; - if (UDS_UNKNOWN_USER == user_index) { - wss_db_record_clear(); - rsp[INDEX_3] = UDS_UNKNOWN_USER; - s_uds_env.uds_init.user_index = UDS_UNKNOWN_USER; - } else { - if (!wss_db_record_delete(user_index)) { - rsp[INDEX_2] = UDS_CTRL_PT_RSP_FAILED; - } else { - rsp[INDEX_3] = user_index; + } + else + { + if (UDS_UNKNOWN_USER == cur_user_id) + { + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_CLEAR_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + { + s_uds_env.uds_init.user_index = UDS_UNKNOWN_USER; + + for (uint8_t i=0; i= chunk_len && segm_num_per_user == 0) { - uint8_t segm_header = 0; - - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { - s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present = false; - } - - uint8_t regi_user_data_flags = 0; - uint8_t regi_user_index; - - segm_header |= (s_uds_env.segm_head_roll_num << USER_DATA_OFFSET); - segm_header |= UDS_ONLY_REGI_USER_SEGM; // the only packet. - - if (s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present) { - regi_user_data_flags |= UDS_REGI_USER_NAME_PRESENT; - } - - if (s_uds_env.uds_init.uds_regi_user_data_flag.user_name_truncated) { - regi_user_data_flags |= UDS_USER_NAME_TRUNCATED; - } - - regi_user_index = i; - - local_buf[length++] = segm_header; - local_buf[length++] = regi_user_data_flags; - local_buf[length++] = regi_user_index; - - ret = memcpy_s(&local_buf[length], loc_rec.name_length, - loc_rec.first_name, loc_rec.name_length); - if (ret < 0) { - return; - } - length += loc_rec.name_length; - - local_segm_length[segm_total_num++] = loc_rec.name_length + NAME_LEN_OFFSET; - s_regi_user_char_val_stream.length += (loc_rec.name_length + NAME_LEN_OFFSET); - name_offset_per_user += loc_rec.name_length; - } else if (UDS_REGI_USER_DATA_LEN_MAX >= chunk_len && segm_num_per_user != 0) { - uint8_t segm_header = 0; - segm_header |= (s_uds_env.segm_head_roll_num << USER_DATA_OFFSET); - segm_header |= UDS_LAST_REGI_USER_SEGM; // the last packet. - local_buf[length++] = segm_header; - - ret = memcpy_s(&local_buf[length], chunk_len, loc_rec.first_name + name_offset_per_user, chunk_len); - if (ret < 0) { - return; - } - length += chunk_len; - - local_segm_length[segm_total_num++] = chunk_len + 1; - s_regi_user_char_val_stream.length += (chunk_len + 1); - name_offset_per_user += chunk_len; - } else if (UDS_REGI_USER_DATA_LEN_MAX < chunk_len) { - if (segm_num_per_user == 0) { + do + { + chunk_len = user_data.name_length - name_offset_per_user; + + if (UDS_REGI_USER_DATA_LEN_MAX - 2 >= chunk_len && 0 == segm_num_per_user) + { uint8_t segm_header = 0; - if (UDS_UNKNOWN_USER == s_uds_env.uds_init.user_index) { - s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present = false; - } + uint8_t regi_user_data_flags = 0; uint8_t regi_user_index; - segm_header |= (s_uds_env.segm_head_roll_num << USER_DATA_OFFSET); - segm_header |= UDS_FIRST_REGI_USER_SEGM; // the first packet. - if (s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present) { + segm_header |= (s_uds_env.segm_head_roll_num << 2); + segm_header |= UDS_ONLY_REGI_USER_SEGM; // the only packet. + + if (s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present) + { regi_user_data_flags |= UDS_REGI_USER_NAME_PRESENT; } - if (s_uds_env.uds_init.uds_regi_user_data_flag.user_name_truncated) { + if (s_uds_env.uds_init.uds_regi_user_data_flag.user_name_truncated) + { regi_user_data_flags |= UDS_USER_NAME_TRUNCATED; } @@ -1353,42 +1443,90 @@ static void uds_regist_user_value_encode(uint8_t conn_idx) local_buf[length++] = regi_user_data_flags; local_buf[length++] = regi_user_index; - ret = memcpy_s(&local_buf[length], UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET, - loc_rec.first_name, UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET); - if (ret < 0) { - return; - } - length += UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET; + memcpy(&local_buf[length], user_data.first_name, user_data.name_length); + length += user_data.name_length; - local_segm_length[segm_total_num++] = UDS_REGI_USER_VAL_LEN_MAX; - s_regi_user_char_val_stream.length += UDS_REGI_USER_VAL_LEN_MAX; - name_offset_per_user += UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET; - } else { + local_segm_length[segm_total_num++] = user_data.name_length + 3; + s_regi_user_char_val_stream.length += (user_data.name_length + 3); + name_offset_per_user += user_data.name_length; + + } + else if (UDS_REGI_USER_DATA_LEN_MAX >= chunk_len && 0 != segm_num_per_user) + { uint8_t segm_header = 0; - segm_header |= (s_uds_env.segm_head_roll_num << USER_DATA_OFFSET); - segm_header |= UDS_MIDDLE_REGI_USER_SEGM; // the middle packet. + segm_header |= (s_uds_env.segm_head_roll_num << 2); + segm_header |= UDS_LAST_REGI_USER_SEGM; // the last packet. local_buf[length++] = segm_header; - ret = memcpy_s(&local_buf[length], UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET, - loc_rec.first_name + name_offset_per_user, - UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET); - if (ret < 0) { - return; - } - length += UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET; - local_segm_length[segm_total_num++] = UDS_REGI_USER_VAL_LEN_MAX; - s_regi_user_char_val_stream.length += UDS_REGI_USER_VAL_LEN_MAX; - name_offset_per_user += UDS_REGI_USER_DATA_LEN_MAX - USER_DATA_OFFSET; + memcpy(&local_buf[length], user_data.first_name + name_offset_per_user, chunk_len); + length += chunk_len; + + local_segm_length[segm_total_num++] = chunk_len + 1; + s_regi_user_char_val_stream.length += (chunk_len + 1); + name_offset_per_user += chunk_len; + } + else if (UDS_REGI_USER_DATA_LEN_MAX < chunk_len) + { + if (0 == segm_num_per_user) + { + uint8_t segm_header = 0; + uint8_t regi_user_data_flags = 0; + uint8_t regi_user_index; + + segm_header |= (s_uds_env.segm_head_roll_num << 2); + segm_header |= UDS_FIRST_REGI_USER_SEGM; // the first packet. + + if (s_uds_env.uds_init.uds_regi_user_data_flag.regi_user_name_present) + { + regi_user_data_flags |= UDS_REGI_USER_NAME_PRESENT; + } + + if (s_uds_env.uds_init.uds_regi_user_data_flag.user_name_truncated) + { + regi_user_data_flags |= UDS_USER_NAME_TRUNCATED; + } + + regi_user_index = i; + + local_buf[length++] = segm_header; + local_buf[length++] = regi_user_data_flags; + local_buf[length++] = regi_user_index; + + memcpy(&local_buf[length], user_data.first_name, UDS_REGI_USER_DATA_LEN_MAX - 2); + length += UDS_REGI_USER_DATA_LEN_MAX - 2; + + local_segm_length[segm_total_num++] = UDS_REGI_USER_VAL_LEN_MAX; + s_regi_user_char_val_stream.length += UDS_REGI_USER_VAL_LEN_MAX; + name_offset_per_user += UDS_REGI_USER_DATA_LEN_MAX - 2; + } + else + { + uint8_t segm_header = 0; + segm_header |= (s_uds_env.segm_head_roll_num << 2); + segm_header |= UDS_MIDDLE_REGI_USER_SEGM; // the middle packet. + + local_buf[length++] = segm_header; + memcpy(&local_buf[length], user_data.first_name + name_offset_per_user, UDS_REGI_USER_DATA_LEN_MAX - 2); + length += UDS_REGI_USER_DATA_LEN_MAX - 2; + + local_segm_length[segm_total_num++] = UDS_REGI_USER_VAL_LEN_MAX; + s_regi_user_char_val_stream.length += UDS_REGI_USER_VAL_LEN_MAX; + name_offset_per_user += UDS_REGI_USER_DATA_LEN_MAX - 2; + } + } + segm_num_per_user++; + if (63 == s_uds_env.segm_head_roll_num) + { + s_uds_env.segm_head_roll_num = 0; + } + else + { + s_uds_env.segm_head_roll_num++; } } - segm_num_per_user++; - if (s_uds_env.segm_head_roll_num == ROLL_NUM) { - s_uds_env.segm_head_roll_num = 0; - } else { - s_uds_env.segm_head_roll_num++; - } - } while (name_offset_per_user != loc_rec.name_length); + while (name_offset_per_user != user_data.name_length); + } } s_regi_user_char_val_stream.segm_offset = segm_total_num; @@ -1398,6 +1536,41 @@ static void uds_regist_user_value_encode(uint8_t conn_idx) s_regi_user_char_val_stream.offset = 0; } +static void uds_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + uds_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + uds_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_PREP_WRITE_REQUEST: + uds_gatts_prep_write_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.prep_wr_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + uds_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + uds_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + + case BLE_GAPC_EVT_DISCONNECTED: + uds_disconnect_evt_handler(p_evt->evt.gapc_evt.index, p_evt->evt.gapc_evt.params.disconnected.reason); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** @@ -1412,31 +1585,24 @@ uint8_t uds_get_cur_user_index(uint8_t conn_idx) return s_uds_env.uds_init.user_index; } -sdk_err_t uds_regi_user_val_send(uint8_t conn_idx) -{ - uds_regist_user_value_encode(0); - return uds_indicate_user_char_val_chunk(conn_idx); -} - sdk_err_t uds_db_change_incr_val_send(uint8_t conn_idx, uint8_t user_index) { sdk_err_t error_code = SDK_ERR_NTF_DISABLED; uint16_t length; - gatts_noti_ind_t uds_ntf; - wss_rec_t loc_rec; + ble_gatts_noti_ind_t uds_ntf; - if (UDS_UNKNOWN_USER != user_index) { - if (wss_db_record_get(user_index, &loc_rec)) { - length = sizeof(loc_rec.db_change_incr_val); - if (PRF_CLI_START_NTF == s_uds_env.db_change_incr_ntf_cfg[conn_idx]) { - uds_ntf.type = BLE_GATT_NOTIFICATION; - uds_ntf.handle = prf_find_handle_by_idx(UDS_IDX_DB_CHANGE_INCR_VAL, - s_uds_env.start_hdl, - (uint8_t *)&s_uds_env.uds_init.char_mask); - uds_ntf.length = length; - uds_ntf.value = (uint8_t *)&loc_rec.db_change_incr_val; - error_code = ble_gatts_noti_ind(conn_idx, &uds_ntf); - } + if (UDS_UNKNOWN_USER != user_index) + { + length = sizeof(s_wss_db_user_buf.user_data[user_index].db_change_incr_val); + if (PRF_CLI_START_NTF == s_uds_env.db_change_incr_ntf_cfg[conn_idx]) + { + uds_ntf.type = BLE_GATT_NOTIFICATION; + uds_ntf.handle = prf_find_handle_by_idx(UDS_IDX_DB_CHANGE_INCR_VAL, + s_uds_env.start_hdl, + (uint8_t *)&s_uds_env.uds_init.char_mask); + uds_ntf.length = length; + uds_ntf.value = (uint8_t *)&(s_wss_db_user_buf.user_data[user_index].db_change_incr_val); + error_code = ble_gatts_noti_ind(conn_idx, &uds_ntf); } } return error_code; @@ -1445,13 +1611,14 @@ sdk_err_t uds_db_change_incr_val_send(uint8_t conn_idx, uint8_t user_index) sdk_err_t uds_ctrl_pt_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t length) { sdk_err_t error_code = SDK_ERR_IND_DISABLED; - gatts_noti_ind_t ctrl_pt_rsp; + ble_gatts_noti_ind_t ctrl_pt_rsp; - if (PRF_CLI_START_IND == s_uds_env.ctrl_point_ind_cfg[conn_idx]) { + if (PRF_CLI_START_IND == s_uds_env.ctrl_point_ind_cfg[conn_idx]) + { ctrl_pt_rsp.type = BLE_GATT_INDICATION; ctrl_pt_rsp.handle = prf_find_handle_by_idx(UDS_IDX_CTRL_POINT_VAL, - s_uds_env.start_hdl, - (uint8_t *)&s_uds_env.uds_init.char_mask); + s_uds_env.start_hdl, + (uint8_t *)&s_uds_env.uds_init.char_mask); ctrl_pt_rsp.length = length; ctrl_pt_rsp.value = p_data; error_code = ble_gatts_noti_ind(conn_idx, &ctrl_pt_rsp); @@ -1462,51 +1629,63 @@ sdk_err_t uds_ctrl_pt_rsp_send(uint8_t conn_idx, uint8_t *p_data, uint16_t lengt sdk_err_t uds_service_init(uds_init_t *p_uds_init) { - sdk_err_t ret; - if (p_uds_init == NULL) { + if (NULL == p_uds_init) + { return SDK_ERR_POINTER_NULL; } - ret = memset_s(&s_uds_env, sizeof(s_uds_env), 0, sizeof(s_uds_env)); - if (ret < 0) { - return ret; - } - ret = memcpy_s(&s_uds_env.uds_init, sizeof(uds_init_t), p_uds_init, sizeof(uds_init_t)); - if (ret < 0) { - return ret; - } + memset(&s_uds_env, 0, sizeof(s_uds_env)); + memcpy(&s_uds_env.uds_init, p_uds_init, sizeof(uds_init_t)); - return ble_server_prf_add(&uds_prf_info); + s_uds_env.start_hdl = PRF_INVALID_HANDLE; + + s_uds_env.uds_gatts_db.shdl = &s_uds_env.start_hdl; + s_uds_env.uds_gatts_db.uuid = s_uds_svc_uuid; + s_uds_env.uds_gatts_db.attr_tab_cfg = (uint8_t *)&(s_uds_env.uds_init.char_mask); + s_uds_env.uds_gatts_db.max_nb_attr = UDS_IDX_NB; + s_uds_env.uds_gatts_db.srvc_perm = 0; + s_uds_env.uds_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_uds_env.uds_gatts_db.attr_tab.attr_tab_16 = uds_attr_tab; + + return ble_gatts_prf_add(&s_uds_env.uds_gatts_db, uds_ble_evt_handler); } #if defined(PTS_AUTO_TEST) void uds_regist_new_user(uint8_t conn_idx) { - uint16_t consent_code = 0x0001; + uint8_t new_user_id; + new_user_id = wss_db_user_id_get(); - uds_chars_val_t uds_chars_val; - uint8_t user_index; - uint8_t db_change_incr_val; + if (UDS_UNKNOWN_USER == new_user_id) + { + new_user_id = 0x01; + } - user_index = (uint8_t)wss_db_records_num_get(); - s_uds_env.uds_init.user_index = user_index; - uint8_t first_name[] = "tom"; - db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; - uds_chars_val.age = AGE_18; - uds_chars_val.height = HEIGHT_1650; - uds_chars_val.gender = 0x00; - uds_chars_val.date_of_birth.year = YEAR_2000; - uds_chars_val.date_of_birth.month = MONTH_01; - uds_chars_val.date_of_birth.day = DAY_01; - uds_chars_val.p_first_name = &first_name[0]; - uds_chars_val.name_length = sizeof(first_name); + uint8_t first_name[] = {'d', 'e', 'f', 'a', 'u', 'l', 't'}; - wss_db_record_add(user_index, consent_code, db_change_incr_val, &uds_chars_val); + s_wss_db_user_buf.user_id = new_user_id; + s_wss_db_user_buf.user_data[new_user_id].consent_code = 0x0001; + s_wss_db_user_buf.user_data[new_user_id].db_change_incr_val = UDS_DB_CHANGE_INCR_DEFAULT_VAL; + s_wss_db_user_buf.user_data[new_user_id].age = 18; + s_wss_db_user_buf.user_data[new_user_id].height = 165; // The unit is cm. + s_wss_db_user_buf.user_data[new_user_id].gender = 0x00; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.year = 2000; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.month = 01; + s_wss_db_user_buf.user_data[new_user_id].date_of_birth.day = 01; + s_wss_db_user_buf.user_data[new_user_id].name_length = sizeof(first_name); + memcpy(s_wss_db_user_buf.user_data[new_user_id].first_name, &first_name[0], sizeof(first_name)); + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_ADD_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); + + s_uds_env.uds_init.user_index = new_user_id; } void uds_del_users(uint8_t conn_idx) { - uint8_t user_index = 0x00; - wss_db_record_delete(user_index); + s_wss_db_user_buf.user_id = 0x00; + wss_db_rec_cmd_type_t ucp_cmd = UCP_CMD_TYPE_DEL_REC; + wss_db_ucp_cmd_queue_elem_push(&s_wss_db_rec_cmd_queue, ucp_cmd); } #endif + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.h index 6f9d7d1..7511bde 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/uds/uds.h @@ -52,68 +52,66 @@ * * After \ref uds_init_t variable is intialized, the application must call \ref uds_service_init() * to add User Data Service and UDS Characteristic, Database Change Increment, User Index, User - * Control Point and Registered User characteristics to the BLE Stack database according to + * Control Point and Registered User characteristics to the BLE Stack database according to * \ref uds_init_t.char_mask. */ #ifndef __UDS_H__ #define __UDS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup UDS_MACRO Defines * @{ */ -#define UDS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of UDS connections. */ +#define UDS_CONNECTION_MAX 10 /**< Maximum number of UDS connections. */ +#define UDS_AGE_VAL_LEN_MAX 2 /**< Maximum length of Age Characteristic value. */ +#define UDS_DATE_OF_BIRTH_VAL_LEN_MAX 4 /**< Maximum length of Date of Birth Characteristic value. */ +#define UDS_FIRST_NAME_VAL_LEN_MAX 50 /**< Maximum length of First Name Characteristic value. */ +#define UDS_HEIGHT_VAL_LEN_MAX 2 /**< Maximum length of Height Characteristic value. */ +#define UDS_GENDER_VAL_LEN_MAX 2 /**< Maximum length of Gender Characteristic value. */ +#define UDS_DB_CHANGE_INCR_VAL_LEN_MAX 4 /**< Maximum length of Database Change Increment value. */ +#define UDS_USER_INDEX_VAL_LEN_MAX 1 /**< Maximum length of User Index value. */ +#define UDS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of User Control Point response value. */ +#define UDS_CTRL_PT_RSP_LEN_MAX 20 /**< Maximum length of User Control Point response value. */ +#define UDS_CTRL_PT_VAL_LEN_MAX 19 /**< Maximum length of User Control Point value. */ +#define UDS_REGI_USER_DATA_LEN_MAX 19 /**< Maximum length of Registered User Data value. */ +#define UDS_REGI_USER_VAL_LEN_MAX 20 /**< Maximum length of Registered User Characteristic value. */ -#define UDS_AGE_VAL_LEN_MAX 2 /**< Maximum length of Age Characteristic value. */ -#define UDS_DATE_OF_BIRTH_VAL_LEN_MAX 4 /**< Maximum length of Date of Birth Characteristic value. */ -#define UDS_FIRST_NAME_VAL_LEN_MAX 50 /**< Maximum length of First Name Characteristic value. */ -#define UDS_HEIGHT_VAL_LEN_MAX 2 /**< Maximum length of Height Characteristic value. */ -#define UDS_GENDER_VAL_LEN_MAX 2 /**< Maximum length of Gender Characteristic value. */ -#define UDS_DB_CHANGE_INCR_VAL_LEN_MAX 4 /**< Maximum length of Database Change Increment value. */ -#define UDS_USER_INDEX_VAL_LEN_MAX 1 /**< Maximum length of User Index value. */ -#define UDS_CTRL_PT_RSP_LEN_MIN 3 /**< Mimimum length of User Control Point response value. */ -#define UDS_CTRL_PT_RSP_LEN_MAX 20 /**< Maximum length of User Control Point response value. */ -#define UDS_CTRL_PT_VAL_LEN_MAX 19 /**< Maximum length of User Control Point value. */ -#define UDS_REGI_USER_DATA_LEN_MAX 19 /**< Maximum length of Registered User Data value. */ -#define UDS_REGI_USER_VAL_LEN_MAX 20 /**< Maximum length of Registered User Characteristic value. */ +#define UDS_ERROR_UD_ACCESS_NOT_PERMIT 0x80 /**< Error code: The user data access is not permitted. */ +#define UDS_ERROR_PROC_IN_PROGRESS 0xFE /**< Error code: A previously triggered User Control Point operation is still in progress. */ +#define UDS_ERROR_CCCD_INVALID 0xFD /**< Error code: The Client Characteristic Configuration descriptor is not configured. */ -#define UDS_ERROR_UD_ACCESS_NOT_PERMIT 0x80 /**< Error code: The user data access is not permitted. */ -#define UDS_ERROR_PROC_IN_PROGRESS 0xFE /**< Error code: A previously triggered User Control Point operation \ - is still in progress. */ -#define UDS_ERROR_CCCD_INVALID 0xFD /**< Error code: The Client Characteristic Configuration descriptor \ - is not configured. */ +#define UDS_DB_CHANGE_INCR_DEFAULT_VAL 0x00 /**< Database Change Increment default value. */ +#define UDS_UNKNOWN_USER 0xFF /**< Unknown User. */ +#define UDS_CONSENT_CODE_VAL_MAX 0x270F /**< Maximum value of Consent Code. */ +#define UDS_CONSENT_TRY_NUM_MAX 0x04 /**< Maximum number of consent tries. */ -#define UDS_DB_CHANGE_INCR_DEFAULT_VAL 0x00 /**< Database Change Increment default value. */ -#define UDS_UNKNOWN_USER 0xFF /**< Unknown User. */ -#define UDS_CONSENT_CODE_VAL_MAX 0x270F /**< Maximum value of Consent Code. */ -#define UDS_CONSENT_TRY_NUM_MAX 0x04 /**< Maximum number of consent tries. */ +#define UDS_MIDDLE_REGI_USER_SEGM 0x00 /**< The middle segment of Registered User Characterristic value. */ +#define UDS_FIRST_REGI_USER_SEGM 0x01 /**< The first segment of Registered User Characterristic value. */ +#define UDS_LAST_REGI_USER_SEGM 0x02 /**< The last segment of Registered User Characterristic value. */ +#define UDS_ONLY_REGI_USER_SEGM 0x03 /**< The only segment of Registered User Characterristic value. */ -#define UDS_MIDDLE_REGI_USER_SEGM 0x00 /**< The middle segment of Registered User Characterristic value. */ -#define UDS_FIRST_REGI_USER_SEGM 0x01 /**< The first segment of Registered User Characterristic value. */ -#define UDS_LAST_REGI_USER_SEGM 0x02 /**< The last segment of Registered User Characterristic value. */ -#define UDS_ONLY_REGI_USER_SEGM 0x03 /**< The only segment of Registered User Characterristic value. */ +#define UDS_MEAS_FLAG_DEFAULT 0x3E /**< The default flag of UDS MEAS */ /** * @defgroup UDS_CHAR_MASK Characteristics Mask * @{ * @brief Bit masks for the initialization of \ref uds_init_t.char_mask. */ -#define UDS_CHAR_MANDATORY 0x000001FF /**< Bit mask for mandatory characteristic in UDS.*/ -#define UDS_CHAR_AGE_SUP 0x00000600 /**< Bit mask for Age characteristic that is optional.*/ -#define UDS_CHAR_DATE_OF_BIRTH_SUP 0x00001800 /**< Bit mask for date of birth characteristic that is optional.*/ -#define UDS_CHAR_FIRST_NAME_SUP 0x00006000 /**< Bit mask for first name characteristic that is optional. */ -#define UDS_CHAR_HEIGHT_SUP 0x00018000 /**< Bit mask for height characteristic that is optional.*/ -#define UDS_CHAR_GENDER_SUP 0x00060000 /**< Bit mask for gender characteristic that is optional.*/ -#define UDS_CHAR_REGIST_USER_SUP 0x00380000 /**< Bit mask for Registered User characteristic that is optional.*/ -#define UDS_CHAR_FULL 0x003FFFFF /**< Bit mask of the full characteristic.*/ +#define UDS_CHAR_MANDATORY 0x000001FF /**< Bit mask for mandatory characteristic in UDS. */ +#define UDS_CHAR_AGE_SUP 0x00000600 /**< Bit mask for Age characteristic that is optional. */ +#define UDS_CHAR_DATE_OF_BIRTH_SUP 0x00001800 /**< Bit mask for date of birth characteristic that is optional. */ +#define UDS_CHAR_FIRST_NAME_SUP 0x00006000 /**< Bit mask for first name characteristic that is optional. */ +#define UDS_CHAR_HEIGHT_SUP 0x00018000 /**< Bit mask for height characteristic that is optional. */ +#define UDS_CHAR_GENDER_SUP 0x00060000 /**< Bit mask for gender characteristic that is optional. */ +#define UDS_CHAR_REGIST_USER_SUP 0x00380000 /**< Bit mask for Registered User characteristic that is optional. */ +#define UDS_CHAR_FULL 0x003FFFFF /**< Bit mask of the full characteristic. */ /** @} */ /** @} */ @@ -122,7 +120,8 @@ * @{ */ /**@brief User Data Service Control Point Operation Code.*/ -typedef enum { +typedef enum +{ UDS_CTRL_PT_OP_RESERVED, /**< Reserved for future use. */ UDS_CTRL_PT_OP_REGIST_NEW_USER, /**< Register New User Operation Code.*/ UDS_CTRL_PT_OP_CONSENT, /**< Consent Operation Code.*/ @@ -133,7 +132,8 @@ typedef enum { } uds_ctrl_pt_op_code_t; /**@brief User Data Service Control Point Response value.*/ -typedef enum { +typedef enum +{ UDS_CTRL_PT_RSP_RESERVED, /**< Reserved value. */ UDS_CTRL_PT_RSP_SUCCESS, /**< Operation Success. */ UDS_CTRL_PT_RSP_NOT_SUP, /**< Operation Code Not Supported. */ @@ -143,12 +143,13 @@ typedef enum { } uds_ctrl_pt_rsp_t; /**@brief User Data Service event type. */ -typedef enum { +typedef enum +{ UDS_EVT_INVALID = 0x00, /**< Invalid event. */ UDS_EVT_DB_CHANGE_INCR_NOTIFICATION_ENABLE, /**< Database Change Increment Notification is enabled. */ UDS_EVT_DB_CHANGE_INCR_NOTIFICATION_DISABLE, /**< Database Change Increment Notification is disabled. */ - UDS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that User Control Point indication has been enabled.*/ - UDS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that User Control Point indication has been disabled.*/ + UDS_EVT_CTRL_POINT_INDICATION_ENABLE, /**< Indicate that User Control Point indication has been enabled. */ + UDS_EVT_CTRL_POINT_INDICATION_DISABLE, /**< Indicate that User Control Point indication has been disabled. */ UDS_EVT_REGIST_USER_INDICATION_ENABLE, /**< Indicate that Registered User indication has been enabled. */ UDS_EVT_REGIST_USER_INDICATION_DISABLE, /**< Indicate that Registered User indication has been disabled. */ UDS_EVT_DB_CHANGE_INCR_SEND_CPLT, /**< Indicate that Database Change Increment has been notified. */ @@ -164,11 +165,12 @@ typedef enum { UDS_EVT_USER_GRANT_ACCESS, /**< Indicate that User is waiting to be granted access. */ UDS_EVT_REGIST_NEW_USER, /**< Indicate that User is waiting to be granted access. */ UDS_EVT_DEL_USER_DATA, - UDS_EVT_DEL_USERS, + UDS_EVT_DEL_USERS, } uds_evt_type_t; /**@brief UDS Characteristics Flags. */ -enum uds_chars_flag_bits { +enum uds_chars_flag_bits +{ UDS_CHARS_WEIGHT_PRESENT = 0x01, /**< Flag bit for Weight Present. */ UDS_CHARS_AGE_PRESENT = 0x02, /**< Flag bit for Age Present. */ UDS_CHARS_BIRTH_DATE_PRESENT = 0x04, /**< Flag bit for Date of Birth Present. */ @@ -178,7 +180,8 @@ enum uds_chars_flag_bits { }; /**@brief Registered User Data Flags. */ -enum uds_regi_user_data_flag_bits { +enum uds_regi_user_data_flag_bits +{ UDS_REGI_USER_NAME_PRESENT = 0x01, /**< Flag bit for Registered User Name Present. */ UDS_USER_NAME_TRUNCATED = 0x02, /**< Flag bit for User Name is truncated. */ }; @@ -189,42 +192,47 @@ enum uds_regi_user_data_flag_bits { * @{ */ /**@brief UDS Characteristic - birthdate's structure. */ -typedef struct { +typedef struct +{ uint16_t year; /**< year time element of birth date. */ uint8_t month; /**< month time element of birth date. */ uint8_t day; /**< day time element of birth date. */ } birth_date_t; /**@brief UDS Characteristics Flags structure. */ -typedef struct { - uint8_t weight_present : 1; /**< Weight Present. */ - uint8_t age_present : 1; /**< Age Present. */ - uint8_t birth_date_present : 1; /**< Date of Birth Present. */ - uint8_t first_name_present : 1; /**< First Name Present. */ - uint8_t height_present : 1; /**< Height Present. */ - uint8_t gender_present : 1; /**< Gender Present. */ +typedef struct +{ + uint8_t weight_present :1; /**< Weight Present. */ + uint8_t age_present :1; /**< Age Present. */ + uint8_t birth_date_present :1; /**< Date of Birth Present. */ + uint8_t first_name_present :1; /**< First Name Present. */ + uint8_t height_present :1; /**< Height Present. */ + uint8_t gender_present :1; /**< Gender Present. */ } uds_chars_flag_t; /**@brief UDS Characteristics value structure. */ -typedef struct { +typedef struct +{ uint16_t weight; /**< User's weight. */ - uint8_t age; /**< User's age. */ - birth_date_t date_of_birth; /**< User's birth date. */ - uint16_t height; /**< User's height. */ - uint8_t gender; /**< User's gender. */ + uint8_t age; /**< User's age. */ + birth_date_t date_of_birth; /**< User's birth date. */ + uint16_t height; /**< User's height. */ + uint8_t gender; /**< User's gender. */ uint8_t *p_first_name; /**< User's first name. */ uint16_t name_length; /**< Length of User's first name. */ } uds_chars_val_t; /**@brief Registered User Data Flags structure. */ -typedef struct { - uint8_t regi_user_name_present : 1; /**< Registered User Name Present. */ - uint8_t user_name_truncated : 1; /**< User Name is truncated. */ - uint8_t reserved : 6; /**< Reserved for Future Use. */ +typedef struct +{ + uint8_t regi_user_name_present :1; /**< Registered User Name Present. */ + uint8_t user_name_truncated :1; /**< User Name is truncated. */ + uint8_t reserved :6; /**< Reserved for Future Use. */ } uds_regi_user_data_flag_t; /**@brief User Data Service event. */ -typedef struct { +typedef struct +{ uint8_t conn_idx; /**< The index of the connection. */ uds_evt_type_t evt_type; /**< The UDS event type. */ const uint8_t *p_data; /**< Pointer to event data. */ @@ -248,7 +256,8 @@ typedef void (*uds_evt_handler_t)(uds_evt_t *p_evt); * @{ */ /**@brief UDS Registered User Data stream. */ -typedef struct { +typedef struct +{ uint8_t *p_data; /**< Pointer to Registered User Data stream. */ uint16_t length; /**< Length of Registered User Data stream. */ uint16_t offset; /**< Offset of Registered User Data stream. */ @@ -257,13 +266,11 @@ typedef struct { uint16_t segm_offset; /**< Offset of Registered User Data segmentations' number. */ } uds_regi_user_data_stream_t; -/**@brief User Data Service init structure. - * This contains all option and data needed for initialization of the service. */ -typedef struct { +/**@brief User Data Service init structure. This contains all option and data needed for initialization of the service. */ +typedef struct +{ uds_evt_handler_t evt_handler; /**< User Data Service event handler. */ - uint32_t - char_mask; /**< Initialize the mask of supported characteristics, \ - and configured with \ref UDS_CHAR_MASK. */ + uint32_t char_mask; /**< Initialize the mask of supported characteristics, and configured with \ref UDS_CHAR_MASK. */ uint8_t user_index; /**< Initialize the user index. */ uint8_t db_change_incr_val; /**< Initialize the Database Change Increment value. */ uds_regi_user_data_flag_t uds_regi_user_data_flag; /**< Initialize the Registered User Data Flags structure. */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/BUILD.gn new file mode 100644 index 0000000..dedd3c6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("wss") { + sources = [ "wss.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.c b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.c index ac687ab..27fbbe6 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.c +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.c @@ -46,30 +46,22 @@ #include "utility.h" #include "app_log.h" -#define WEIGHTS_SCALE 0.005 -#define HEIGHT_SCALE 0.01 -#define LB_KG 0.01 -#define LB_KG_SCALE 0.4535924 -#define TURN_TO_M 0.1 -#define TURN_TO_M_SCALE 0.0254 -#define PACKET_LEN_OFFSET 4 -#define CACHE_NUM_LOW 25 -#define SCALE_10 10 /* * ENUMERATIONS **************************************************************************************** */ /**@brief Weight Scale Service Attributes Indexes. */ -enum { +enum +{ // Weight Scale Service WSS_IDX_SVC, - + WSS_IDX_INCL_SVC, - + // WSS Scale Feature Characteristics WSS_IDX_WS_FEAT_CHAR, WSS_IDX_WS_FEAT_VAL, - + // Weight Measurement Characteristic WSS_IDX_WEIGHT_MEAS_CHAR, WSS_IDX_WEIGHT_MEAS_VAL, @@ -83,34 +75,31 @@ enum { ***************************************************************************************** */ /**@brief Weight Scale measurement data stream. */ -typedef struct { +typedef struct +{ uint8_t *p_data; /**< Pointer to data. */ uint16_t length; /**< Length of data. */ uint16_t offset; /**< Offset of data. */ } wss_meas_data_stream_t; /**@brief Weight Scale Service environment variable. */ -struct wss_env_t { +struct wss_env_t +{ wss_init_t wss_init; /**< Weight Scale Service initialization variables. */ uint16_t start_hdl; /**< Weight Scale Service start handle. */ uint8_t cur_user_index; /**< Current User Index. */ - uint16_t - meas_ind_cfg[WSS_CONNECTION_MAX]; /**< The configuration of Weight Scale Indication - which is configured by the peer devices. */ + uint16_t meas_ind_cfg[WSS_CONNECTION_MAX]; /**< The configuration of Weight Scale Indication which is configured by the peer devices. */ uint16_t *p_incl_srvc_start_handle; + ble_gatts_create_db_t wss_gatts_db; /**< Weight Scale Service attributs database. */ }; /* * LOCAL FUNCTION DECLARATION ***************************************************************************************** */ -static sdk_err_t wss_init(void); -static void wss_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param); -static void wss_write_att_cb(uint8_t conidx, const gatts_write_req_cb_t *p_param); -static void wss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value); -static void wss_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); -static uint16_t wss_meas_value_encoded(wss_meas_val_t *p_wss_meas_val, uint8_t cache_num); +static uint16_t wss_meas_value_encoded(wss_meas_val_t *p_wss_meas_val, uint8_t index); static uint16_t wss_indicate_meas_value_chunk(uint8_t conn_idx); +static uint8_t local_buff[WSS_MEAS_VAL_LEN_MAX * WSS_CACHE_MEAS_NUM_MAX]; /* * LOCAL VARIABLE DEFINITIONS @@ -119,108 +108,43 @@ static uint16_t wss_indicate_meas_value_chunk(uint8_t conn_idx); static struct wss_env_t s_wss_env; static wss_meas_data_stream_t s_wss_meas_val; static uint16_t s_packet_length; +static const uint8_t s_wss_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_WEIGHT_SCALE); /**@brief Full WSS Database Description - Used to add attributes into the database. */ -static const attm_desc_t wss_attr_tab[WSS_IDX_NB] = { +static const ble_gatts_attm_desc_t wss_attr_tab[WSS_IDX_NB] = +{ // WSS Service Declaration - [WSS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0}, + [WSS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, - // Include Service Declaration - [WSS_IDX_INCL_SVC] = {BLE_ATT_DECL_INCLUDE, READ_PERM_UNSEC, 0, 0}, + //Include Service Declaration + [WSS_IDX_INCL_SVC] = {BLE_ATT_DECL_INCLUDE, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Weight Scale Feature Characteristic - Declaration - [WSS_IDX_WS_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [WSS_IDX_WS_FEAT_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Weight Scale Feature Characteristic - Value - [WSS_IDX_WS_FEAT_VAL] = { - BLE_ATT_CHAR_WEIGHT_SCALE_FEATURE, - READ_PERM_UNSEC, - ATT_VAL_LOC_USER, - WSS_FEAT_VAL_LEN_MAX - }, + [WSS_IDX_WS_FEAT_VAL] = {BLE_ATT_CHAR_WEIGHT_SCALE_FEATURE, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + WSS_FEAT_VAL_LEN_MAX}, // Weight Measurement Characteristic - Declaration - [WSS_IDX_WEIGHT_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0}, + [WSS_IDX_WEIGHT_MEAS_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, BLE_GATTS_READ_PERM_UNSEC, 0, 0}, // Weight Measurement Characteristic Declaration - value - [WSS_IDX_WEIGHT_MEAS_VAL] = { - BLE_ATT_CHAR_WEIGHT_MEASUREMENT, - INDICATE_PERM_UNSEC, - ATT_VAL_LOC_USER, - WSS_MEAS_VAL_LEN_MAX - }, + [WSS_IDX_WEIGHT_MEAS_VAL] = {BLE_ATT_CHAR_WEIGHT_MEASUREMENT, + BLE_GATTS_INDICATE_PERM(BLE_GATTS_UNAUTH), + BLE_GATTS_ATT_VAL_LOC_USER, + WSS_MEAS_VAL_LEN_MAX}, // Weight Measurement Declaration - Client Characteristic Configuration Descriptor - [WSS_IDX_WEIGHT_MEAS_IND_CFG] = { - BLE_ATT_DESC_CLIENT_CHAR_CFG, - READ_PERM_UNSEC | WRITE_REQ_PERM_UNSEC, - 0, - 0 - }, -}; - -/**@brief WSS Task interface required by profile manager. */ -static ble_prf_manager_cbs_t wss_task_cbs = { - (prf_init_func_t) wss_init, - NULL, - NULL -}; - -/**@brief WSS Task Callbacks. */ -static gatts_prf_cbs_t wss_cb_func = { - wss_read_att_cb, - wss_write_att_cb, - NULL, - wss_gatts_ntf_ind_cb, - wss_cccd_set_cb -}; - -/**@brief WSS Information. */ -static const prf_server_info_t wss_prf_info = { - .max_connection_nb = WSS_CONNECTION_MAX, - .manager_cbs = &wss_task_cbs, - .gatts_prf_cbs = &wss_cb_func + [WSS_IDX_WEIGHT_MEAS_IND_CFG] = {BLE_ATT_DESC_CLIENT_CHAR_CFG, + BLE_GATTS_READ_PERM(BLE_GATTS_UNAUTH) | BLE_GATTS_WRITE_REQ_PERM(BLE_GATTS_UNAUTH), + 0, + 0}, }; /* * LOCAL FUNCTION DEFINITIONS ***************************************************************************************** */ -/** - ***************************************************************************************** - * @brief Initialize Weight Scale service and create db in att - * - * @return Error code to know if profile initialization succeed or not. - ***************************************************************************************** - */ -static sdk_err_t wss_init(void) -{ - // The start handle must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack. - uint16_t start_hdl = PRF_INVALID_HANDLE; - const uint8_t wss_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_WEIGHT_SCALE); - sdk_err_t error_code; - gatts_create_db_t gatts_db; - - error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db)); - if (error_code < 0) { - return error_code; - } - - gatts_db.shdl = &start_hdl; - gatts_db.uuid = wss_svc_uuid; - gatts_db.attr_tab_cfg = (uint8_t *)&(s_wss_env.wss_init.char_mask); - gatts_db.max_nb_attr = WSS_IDX_NB; - gatts_db.srvc_perm = 0; - gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16; - gatts_db.attr_tab.attr_tab_16 = wss_attr_tab; - gatts_db.inc_srvc_num = 1; - gatts_db.inc_srvc_handle[0] = s_wss_env.p_incl_srvc_start_handle; - - error_code = ble_gatts_srvc_db_create(&gatts_db); - if (SDK_SUCCESS == error_code) { - s_wss_env.start_hdl = *gatts_db.shdl; - } - - return error_code; -} - /** ***************************************************************************************** * @brief Handles reception of the attribute info request message. @@ -229,31 +153,35 @@ static sdk_err_t wss_init(void) * @param[in] p_param: The parameters of the read request. ***************************************************************************************** */ -static void wss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param) +static void wss_read_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_read_t *p_param) { - gatts_read_cfm_t cfm; - uint8_t handle = p_param->handle; - uint8_t tab_index = prf_find_idx_by_handle(handle, - s_wss_env.start_hdl, - WSS_IDX_NB, - (uint8_t *)&s_wss_env.wss_init.char_mask); + ble_gatts_read_cfm_t cfm; + uint8_t handle = p_param->handle; + uint8_t tab_index = prf_find_idx_by_handle(handle, + s_wss_env.start_hdl, + WSS_IDX_NB, + (uint8_t *)&s_wss_env.wss_init.char_mask); cfm.handle = handle; cfm.status = BLE_SUCCESS; - switch (tab_index) { - case WSS_IDX_WS_FEAT_VAL: { + switch (tab_index) + { + case WSS_IDX_WS_FEAT_VAL: + { cfm.length = sizeof(uint32_t); cfm.value = (uint8_t *)&s_wss_env.wss_init.feature; break; } - case WSS_IDX_WEIGHT_MEAS_IND_CFG: { + case WSS_IDX_WEIGHT_MEAS_IND_CFG: + { cfm.length = sizeof(uint16_t); cfm.value = (uint8_t *)&s_wss_env.meas_ind_cfg[conn_idx]; break; } - default: { + default: + { cfm.length = 0; cfm.status = BLE_ATT_ERR_INVALID_HANDLE; break; @@ -271,13 +199,13 @@ static void wss_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param * @param[in]: p_param: The parameters of the write request. ***************************************************************************************** */ -static void wss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_param) +static void wss_write_att_evt_handler(uint8_t conn_idx, const ble_gatts_evt_write_t *p_param) { - uint16_t handle = p_param->handle; - uint16_t tab_index = 0; - uint16_t cccd_value = 0; - wss_evt_t event; - gatts_write_cfm_t cfm; + uint16_t handle = p_param->handle; + uint16_t tab_index = 0; + uint16_t cccd_value = 0; + wss_evt_t event; + ble_gatts_write_cfm_t cfm; tab_index = prf_find_idx_by_handle(handle, s_wss_env.start_hdl, @@ -288,7 +216,8 @@ static void wss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p event.evt_type = WSS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case WSS_IDX_WEIGHT_MEAS_IND_CFG: cccd_value = le16toh(&p_param->value[0]); event.evt_type = ((PRF_CLI_START_IND == cccd_value) ? \ @@ -304,8 +233,8 @@ static void wss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p ble_gatts_write_cfm(conn_idx, &cfm); - if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && WSS_EVT_INVALID != event.evt_type && - s_wss_env.wss_init.evt_handler) { + if (BLE_ATT_ERR_INVALID_HANDLE != cfm.status && WSS_EVT_INVALID != event.evt_type && s_wss_env.wss_init.evt_handler) + { s_wss_env.wss_init.evt_handler(&event); } } @@ -319,12 +248,13 @@ static void wss_write_att_cb(uint8_t conn_idx, const gatts_write_req_cb_t *p_p * @param[in]: cccd_value: The value of cccd attribute. ***************************************************************************************** */ -static void wss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) +static void wss_cccd_set_evt_handler(uint8_t conn_idx, uint16_t handle, uint16_t cccd_value) { uint16_t tab_index = 0; wss_evt_t event; - if (!prf_is_cccd_value_valid(cccd_value)) { + if (!prf_is_cccd_value_valid(cccd_value)) + { return; } @@ -336,19 +266,21 @@ static void wss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val event.evt_type = WSS_EVT_INVALID; event.conn_idx = conn_idx; - switch (tab_index) { + switch (tab_index) + { case WSS_IDX_WEIGHT_MEAS_IND_CFG: - event.evt_type = ((PRF_CLI_START_NTF == cccd_value) ? \ + event.evt_type = ((PRF_CLI_START_IND == cccd_value) ? \ WSS_EVT_MEAS_INDICATION_ENABLE : \ WSS_EVT_MEAS_INDICATION_DISABLE); s_wss_env.meas_ind_cfg[conn_idx] = cccd_value; break; - + default: break; } - if (WSS_EVT_INVALID != event.evt_type && s_wss_env.wss_init.evt_handler) { + if (WSS_EVT_INVALID != event.evt_type && s_wss_env.wss_init.evt_handler) + { s_wss_env.wss_init.evt_handler(&event); } } @@ -362,10 +294,12 @@ static void wss_cccd_set_cb(uint8_t conn_idx, uint16_t handle, uint16_t cccd_val * @param[in] p_ntf_ind: Pointer to the parameters of the complete event. ***************************************************************************************** */ -static void wss_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind) +static void wss_ntf_ind_evt_handler(uint8_t conn_idx, uint8_t status, const ble_gatts_evt_ntf_ind_t *p_ntf_ind) { - if (s_wss_env.wss_init.evt_handler && SDK_SUCCESS == status && s_wss_env.meas_ind_cfg[conn_idx]) { - if (BLE_GATT_INDICATION == p_ntf_ind->type) { + if (s_wss_env.wss_init.evt_handler && SDK_SUCCESS == status && s_wss_env.meas_ind_cfg[conn_idx]) + { + if (BLE_GATT_INDICATION == p_ntf_ind->type) + { wss_indicate_meas_value_chunk(conn_idx); } } @@ -382,18 +316,19 @@ static void wss_gatts_ntf_ind_cb(uint8_t conn_idx, uint8_t status, const ble_gat */ static uint16_t wss_indicate_meas_value_chunk(uint8_t conn_idx) { - uint16_t chunk_len; - gatts_noti_ind_t wss_meas_ind; - sdk_err_t error_code; - + uint16_t chunk_len; + ble_gatts_noti_ind_t wss_meas_ind; + sdk_err_t error_code; + chunk_len = s_wss_meas_val.length - s_wss_meas_val.offset; chunk_len = chunk_len > s_packet_length ? s_packet_length : chunk_len; - - if (chunk_len == 0) { + + if (0 == chunk_len) + { s_wss_meas_val.p_data = NULL; s_wss_meas_val.length = 0; s_wss_meas_val.offset = 0; - + return SDK_SUCCESS; } @@ -405,7 +340,8 @@ static uint16_t wss_indicate_meas_value_chunk(uint8_t conn_idx) wss_meas_ind.value = (uint8_t *)s_wss_meas_val.p_data + s_wss_meas_val.offset; error_code = ble_gatts_noti_ind(conn_idx, &wss_meas_ind); - if (SDK_SUCCESS == error_code) { + if (SDK_SUCCESS == error_code) + { s_wss_meas_val.offset += chunk_len; } @@ -424,28 +360,33 @@ static uint16_t wss_indicate_meas_value_chunk(uint8_t conn_idx) */ static uint16_t wss_meas_value_encoded(wss_meas_val_t *p_wss_meas_val, uint8_t cache_num) { - uint8_t local_buff[WSS_MEAS_VAL_LEN_MAX * WSS_CACHE_MEAS_NUM_MAX] = {0}; uint8_t flags = 0; uint16_t length = 0; double height_in_m; double weight_in_kg; - + + memset(local_buff, 0, sizeof(local_buff)); s_wss_meas_val.length = 0; - - for (uint8_t i = 0; i < cache_num; i++) { + + for (uint8_t i = 0; i < cache_num; i++) + { length++; - if (WSS_MEAS_UNSUCCESS != p_wss_meas_val->weight) { + if (WSS_MEAS_UNSUCCESS != p_wss_meas_val->weight) + { // Weight Field local_buff[length++] = LO_U16(p_wss_meas_val[i].weight); local_buff[length++] = HI_U16(p_wss_meas_val[i].weight); - } else { + } + else + { // Weight Field local_buff[length++] = LO_U16(WSS_MEAS_UNSUCCESS); local_buff[length++] = HI_U16(WSS_MEAS_UNSUCCESS); } - + // Time Stamp Field - if ((s_wss_env.wss_init.feature & WSS_FEAT_TIME_STAMP) && (s_wss_env.wss_init.time_stamp_present)) { + if (s_wss_env.wss_init.feature & WSS_FEAT_TIME_STAMP && (s_wss_env.wss_init.time_stamp_present)) + { local_buff[length++] = LO_U16(p_wss_meas_val[i].time_stamp.year); local_buff[length++] = HI_U16(p_wss_meas_val[i].time_stamp.year); local_buff[length++] = p_wss_meas_val[i].time_stamp.month; @@ -457,79 +398,123 @@ static uint16_t wss_meas_value_encoded(wss_meas_val_t *p_wss_meas_val, uint8_t c } // User ID Field - if ((s_wss_env.wss_init.feature & WSS_FEAT_MULTI_USER) && (s_wss_env.wss_init.multi_user_present)) { + if (s_wss_env.wss_init.feature & WSS_FEAT_MULTI_USER && (s_wss_env.wss_init.multi_user_present)) + { local_buff[length++] = p_wss_meas_val[i].user_id; flags |= WSS_MEAS_FLAG_USER_ID_PRESENT; } - if (WSS_MEAS_UNSUCCESS != p_wss_meas_val->weight) { + if (WSS_MEAS_UNSUCCESS != p_wss_meas_val->weight) + { // BMI and Height Fields - if ((WSS_FEAT_BMI & s_wss_env.wss_init.feature) && (s_wss_env.wss_init.bmi_present)) { + if (WSS_FEAT_BMI & s_wss_env.wss_init.feature && (s_wss_env.wss_init.bmi_present)) + { uint16_t bmi; - + s_packet_length = WSS_MEAS_VAL_LEN_MAX; - - if (WSS_UNIT_SI == s_wss_env.wss_init.wss_unit) { + + if (WSS_UNIT_SI == s_wss_env.wss_init.wss_unit) + { if ((WSS_FEAT_MASS_RES_5G & s_wss_env.wss_init.feature) && \ (WSS_FEAT_HEIGHT_RES_1MM & s_wss_env.wss_init.feature) && \ (WSS_HEIGHT_RES_1MM == s_wss_env.wss_init.wss_height_res) && \ - (WSS_MASS_RES_5G == s_wss_env.wss_init.wss_mass_res)) { - weight_in_kg = p_wss_meas_val[i].weight * WEIGHTS_SCALE; - height_in_m = p_wss_meas_val->height * HEIGHT_SCALE; - bmi = (weight_in_kg/(height_in_m * height_in_m)) * SCALE_10; + (WSS_MASS_RES_5G == s_wss_env.wss_init.wss_mass_res)) + { + weight_in_kg = p_wss_meas_val[i].weight * 0.005; + height_in_m = p_wss_meas_val->height * 0.01; + bmi = (weight_in_kg/(height_in_m * height_in_m)) * 10; } - } else { + } + else + { if ((WSS_FEAT_MASS_RES_5G & s_wss_env.wss_init.feature) && \ (WSS_FEAT_HEIGHT_RES_1MM & s_wss_env.wss_init.feature) && \ (WSS_HEIGHT_RES_1MM == s_wss_env.wss_init.wss_height_res) && \ - (WSS_MASS_RES_5G == s_wss_env.wss_init.wss_mass_res)) { - weight_in_kg = p_wss_meas_val[i].weight * LB_KG * LB_KG_SCALE; // turn lb to kg. - height_in_m = p_wss_meas_val->height * TURN_TO_M * TURN_TO_M_SCALE; // turn in to m. - bmi = (weight_in_kg/(height_in_m * height_in_m)) * SCALE_10; - } + (WSS_MASS_RES_5G == s_wss_env.wss_init.wss_mass_res)) + { + weight_in_kg = p_wss_meas_val[i].weight * 0.01 * 0.4535924; // turn lb to kg. + height_in_m = p_wss_meas_val->height * 0.1 * 0.0254; // turn in to m. + bmi = (weight_in_kg/(height_in_m * height_in_m)) * 10; + } } local_buff[length++] = LO_U16(bmi); local_buff[length++] = HI_U16(bmi); - local_buff[length++] = LO_U16(p_wss_meas_val->height * SCALE_10); - local_buff[length++] = HI_U16(p_wss_meas_val->height * SCALE_10); + local_buff[length++] = LO_U16(p_wss_meas_val->height * 10); + local_buff[length++] = HI_U16(p_wss_meas_val->height * 10); flags |= WSS_MEAS_FLAG_BMI_HEIGHT_PRESENT; - } else if ((WSS_FEAT_BMI & s_wss_env.wss_init.feature) && (!s_wss_env.wss_init.bmi_present)) { - s_packet_length = WSS_MEAS_VAL_LEN_MAX - PACKET_LEN_OFFSET; } - } else { - s_packet_length = WSS_MEAS_VAL_LEN_MAX - PACKET_LEN_OFFSET; + else if (WSS_FEAT_BMI & s_wss_env.wss_init.feature && (!s_wss_env.wss_init.bmi_present)) + { + s_packet_length = WSS_MEAS_VAL_LEN_MAX - 4; + } } - - if (WSS_UNIT_SI == s_wss_env.wss_init.wss_unit) { + else + { + s_packet_length = WSS_MEAS_VAL_LEN_MAX - 4; + } + + if (WSS_UNIT_SI == s_wss_env.wss_init.wss_unit) + { flags |= WSS_MEAS_FLAG_UNIT_SI; - } else { + } + else + { flags |= WSS_MEAS_FLAG_UNIT_IMPERIAL; } - + local_buff[s_wss_meas_val.length] = flags; s_wss_meas_val.length = length; } - + s_wss_meas_val.offset = 0; s_wss_meas_val.p_data = &local_buff[0]; - + return length; } +static void wss_ble_evt_handler(const ble_evt_t *p_evt) +{ + if (NULL == p_evt) + { + return; + } + + switch (p_evt->evt_id) + { + case BLE_GATTS_EVT_READ_REQUEST: + wss_read_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.read_req); + break; + + case BLE_GATTS_EVT_WRITE_REQUEST: + wss_write_att_evt_handler(p_evt->evt.gatts_evt.index, &p_evt->evt.gatts_evt.params.write_req); + break; + + case BLE_GATTS_EVT_NTF_IND: + wss_ntf_ind_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt_status, &p_evt->evt.gatts_evt.params.ntf_ind_sended); + break; + + case BLE_GATTS_EVT_CCCD_RECOVERY: + wss_cccd_set_evt_handler(p_evt->evt.gatts_evt.index, p_evt->evt.gatts_evt.params.cccd_recovery.handle, p_evt->evt.gatts_evt.params.cccd_recovery.cccd_val); + break; + } +} + /* * GLOBAL FUNCTION DEFINITIONS ***************************************************************************************** */ sdk_err_t wss_measurement_send(uint8_t conn_idx, wss_meas_val_t *p_wss_meas_val, uint8_t cache_num) { - if (p_wss_meas_val == NULL || cache_num > CACHE_NUM_LOW) { + if (NULL == p_wss_meas_val || 25 < cache_num) + { return SDK_ERR_INVALID_PARAM; } - + sdk_err_t error_code = SDK_ERR_IND_DISABLED; - - if (PRF_CLI_START_IND == s_wss_env.meas_ind_cfg[conn_idx]) { + + if (PRF_CLI_START_IND == s_wss_env.meas_ind_cfg[conn_idx]) + { wss_meas_value_encoded(p_wss_meas_val, cache_num); error_code = wss_indicate_meas_value_chunk(conn_idx); } @@ -539,20 +524,27 @@ sdk_err_t wss_measurement_send(uint8_t conn_idx, wss_meas_val_t *p_wss_meas_val, sdk_err_t wss_service_init(wss_init_t *p_wss_init, uint16_t *p_incl_srvc_start_handle) { - sdk_err_t ret; - if (p_wss_init == NULL) { + if (NULL == p_wss_init) + { return SDK_ERR_POINTER_NULL; } - ret = memset_S(&s_wss_env, sizeof(s_wss_env), 0, sizeof(s_wss_env)); - if (ret < 0) { - return ret; - } - ret = memcpy_s(&s_wss_env.wss_init, sizeof(wss_init_t), p_wss_init, sizeof(wss_init_t)); - if (ret < 0) { - return ret; - } + memset(&s_wss_env, 0, sizeof(s_wss_env)); + memcpy(&s_wss_env.wss_init, p_wss_init, sizeof(wss_init_t)); s_wss_env.p_incl_srvc_start_handle = p_incl_srvc_start_handle; + + s_wss_env.start_hdl = PRF_INVALID_HANDLE; + s_wss_env.wss_gatts_db.shdl = &s_wss_env.start_hdl; + s_wss_env.wss_gatts_db.uuid = s_wss_svc_uuid; + s_wss_env.wss_gatts_db.attr_tab_cfg = (uint8_t *)&(s_wss_env.wss_init.char_mask); + s_wss_env.wss_gatts_db.max_nb_attr = WSS_IDX_NB; + s_wss_env.wss_gatts_db.srvc_perm = 0; + s_wss_env.wss_gatts_db.attr_tab_type = BLE_GATTS_SERVICE_TABLE_TYPE_16; + s_wss_env.wss_gatts_db.attr_tab.attr_tab_16 = wss_attr_tab; + s_wss_env.wss_gatts_db.inc_srvc_num = 1; + s_wss_env.wss_gatts_db.inc_srvc_handle[0] = p_incl_srvc_start_handle; - return ble_server_prf_add(&wss_prf_info); + return ble_gatts_prf_add(&s_wss_env.wss_gatts_db, wss_ble_evt_handler); } + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.h b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.h index 8fe50e0..5ca6e09 100644 --- a/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/profiles/wss/wss.h @@ -50,29 +50,28 @@ * (Server) intended for consumer healthcare as well as sports/fitness applications. * * After \ref wss_init_t variable is intialized, the application must call \ref wss_service_init() - * to add Weight Scale Feature and Weight Measurement characteristics to the BLE Stack database + * to add Weight Scale Feature and Weight Measurement characteristics to the BLE Stack database * according to \ref wss_init_t.char_mask. */ #ifndef __WSS_H__ #define __WSS_H__ -#include -#include -#include "gr55xx_sys.h" +#include "gr_includes.h" #include "custom_config.h" #include "ble_prf_utils.h" +#include +#include /** * @defgroup WSS_MACRO Defines * @{ */ -#define WSS_CONNECTION_MAX (10 < CFG_MAX_CONNECTIONS ? \ - 10 : CFG_MAX_CONNECTIONS) /**< Maximum number of Weight Scale Service connections. */ -#define WSS_MEAS_VAL_LEN_MAX 15 /**< Maximum length of Weight Measurment value. */ -#define WSS_CACHE_MEAS_NUM_MAX 25 /**< Maximum number of cache muasurements value for each user. */ -#define WSS_FEAT_VAL_LEN_MAX 1 /**< Maximum length of WS Feature value. */ -#define WSS_MEAS_UNSUCCESS 0xFFFF /**< Measurement Unsuccessful. */ +#define WSS_CONNECTION_MAX 10 /**< Maximum number of Weight Scale Service connections. */ +#define WSS_MEAS_VAL_LEN_MAX 15 /**< Maximum length of Weight Measurment value. */ +#define WSS_CACHE_MEAS_NUM_MAX 25 /**< Maximum number of cache muasurements value for each user. */ +#define WSS_FEAT_VAL_LEN_MAX 1 /**< Maximum length of WS Feature value. */ +#define WSS_MEAS_UNSUCCESS 0xFFFF /**< Measurement Unsuccessful. */ /** * @defgroup WSS_CHAR_MASK Characteristics Mask * @{ @@ -86,22 +85,19 @@ * @defgroup WSS_ENUM Enumerations * @{ */ -/** - * @defgroup WSS_MEAS_FLAG_BIT Measurement Flag Bits - * @{ - * @brief Weight Scale Measurement Flags. - */ -enum wss_meas_flag_bits { +/**@brief Weight Scale Measurement Flags.*/ +enum wss_meas_flag_bits +{ WSS_MEAS_FLAG_UNIT_SI = 0x00, /**< Flag bit for SI Measurement Units Present. */ WSS_MEAS_FLAG_UNIT_IMPERIAL = 0x01, /**< Flag bit for Imperial Measurement Units Present. */ WSS_MEAS_FLAG_DATE_TIME_PRESENT = 0x02, /**< Flag bit for Time Stamp Present. */ WSS_MEAS_FLAG_USER_ID_PRESENT = 0x04, /**< Flag bit for User ID Present. */ WSS_MEAS_FLAG_BMI_HEIGHT_PRESENT = 0x08, /**< Flag bit for BMI and Height Present. */ }; -/** @} */ /**@brief Weight Scale Feature characteristic bit values.*/ -typedef enum { +typedef enum +{ /* Supported Flags */ WSS_FEAT_TIME_STAMP = 0x00000001, /**< Time Stamp supported. */ WSS_FEAT_MULTI_USER = 0x00000002, /**< Multiple Users supported. */ @@ -115,17 +111,18 @@ typedef enum { WSS_FEAT_MASS_RES_20G = 0x00000028, /**< Resolution of 0.02kg or 0.05lb. */ WSS_FEAT_MASS_RES_10G = 0x00000030, /**< Resolution of 0.01kg or 0.02lb. */ WSS_FEAT_MASS_RES_5G = 0x00000038, /**< Resolution of 0.005kg or 0.01lb. */ - + /* Height Measurement Resolution */ WSS_FEAT_HEIGHT_RES_10MM = 0x00000080, /**< Resolution of 0.01m or 1in. */ WSS_FEAT_HEIGHT_RES_5MM = 0x00000100, /**< Resolution of 0.005m or 0.5in. */ WSS_FEAT_HEIGHT_RES_1MM = 0x00000180, /**< Resolution of 0.001m or 0.1in. */ - + WSS_FEAT_FULL_BIT = 0x000001BF, } wss_feature_t; /**@brief WSS Weight Measurement resolutions. */ -typedef enum { +typedef enum +{ WSS_MASS_RES_500G, /**< Resolution of 0.5kg or 1lb. */ WSS_MASS_RES_200G, /**< Resolution of 0.2kg or 0.5lb. */ WSS_MASS_RES_100G, /**< Resolution of 0.1kg or 0.2lb. */ @@ -136,34 +133,38 @@ typedef enum { } wss_mass_res_t; /**@brief WSS Height Measurement resolutions. */ -typedef enum { +typedef enum +{ WSS_HEIGHT_RES_10MM, /**< Resolution of 0.01m or 1in. */ WSS_HEIGHT_RES_5MM, /**< Resolution of 0.005m or 0.5in. */ WSS_HEIGHT_RES_1MM, /**< Resolution of 0.001m or 0.1in. */ } wss_height_res_t; /**@brief WSS unit types. */ -typedef enum { +typedef enum +{ WSS_UNIT_SI, /**< Weight in kilograms and height in meters */ WSS_UNIT_IMPERIAL, /**< Weight in pounds and height in inches */ } wss_unit_t; -/**@brief Weight Scale Service event type. */ -typedef enum { + /**@brief Weight Scale Service event type. */ +typedef enum +{ WSS_EVT_INVALID, /**< Indicate that invalid event. */ WSS_EVT_MEAS_INDICATION_ENABLE, /**< Indicate that body composition measurement indication has been enabled. */ WSS_EVT_MEAS_INDICATION_DISABLE, /**< Indicate that body composition measurement indication has been disabled. */ WSS_EVT_MEAS_INDICATION_CPLT, /**< Indicate that BC Measurement has been indicated. */ WSS_EVT_MEAS_READ_CHARACTERISTIC, /**< The peer reads the characteristic. */ -} wss_evt_type_t; +} wss_evt_type_t; /** @} */ -/** +/** * @defgroup WSS_STRUCT Structures * @{ - */ + */ /**@brief Weight Scale Measurement data. */ -typedef struct { +typedef struct +{ uint16_t weight; /**< Weight. */ prf_date_time_t time_stamp; /**< Time stamp. */ uint8_t user_id; /**< User index. */ @@ -172,10 +173,11 @@ typedef struct { } wss_meas_val_t; /**@brief Weight Scale Service event. */ -typedef struct { +typedef struct +{ wss_evt_type_t evt_type; /**< The WSS event type. */ - uint8_t conn_idx; /**< The index of the connection. */ - const uint8_t *p_data; /**< Pointer to event data. */ + uint8_t conn_idx; /**< The index of the connection. */ + const uint8_t *p_data; /**< Pointer to event data. */ uint16_t length; /**< Length of event data. */ } wss_evt_t; /** @} */ @@ -193,11 +195,11 @@ typedef void (*wss_evt_handler_t)(wss_evt_t *p_evt); * @{ */ /**@brief Weight Scale Service Init variable. */ -typedef struct { +typedef struct +{ wss_evt_handler_t evt_handler; /**< Weight Scale Service event handler. */ uint32_t feature; /**< Initial value for features. */ - uint8_t - char_mask; /**< Initial mask of Supported characteristics, and configured with \ref WSS_CHAR_MASK */ + uint8_t char_mask; /**< Initial mask of Supported characteristics, and configured with \ref WSS_CHAR_MASK */ wss_unit_t wss_unit; /**< Initial the unit system as SI or Imperial. */ wss_mass_res_t wss_mass_res; /**< Initial resolution of mass value. */ wss_height_res_t wss_height_res; /**< Initial resolution of height value. */ @@ -215,8 +217,8 @@ typedef struct { ***************************************************************************************** * @brief Initialize a Weight Scale Service instance and add in the DB. * - * @param[in] p_wss_init: Pointer to WSS Service initialization variable. - * + * @param[in] p_wss_init: Pointer to WSS Service initialization variable. + * @param[in] p_bcs_start_handle: Pointer to the included service(BCS) start handle. * @return Result of service initialization. ***************************************************************************************** */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/BUILD.gn new file mode 100644 index 0000000..c6ea37e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("sdk") { +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble.h old mode 100755 new mode 100644 index 9775f7c..a105e0c --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble.h @@ -35,10 +35,10 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -*/ + /** + * @addtogroup BLE + * @{ + */ /** @addtogroup BLE_COMMEN BLE Common @@ -59,23 +59,28 @@ #include "ble_l2cap.h" #include "ble_prf.h" #include "ble_sec.h" +#include "ble_event.h" + +#include /** @addtogroup BLE_COMMEN_ENUM Enumerations * @{ */ /** - * @brief RF TX mode. + * @brief RF TX mode. */ -typedef enum { +typedef enum +{ BLE_RF_TX_MODE_INVALID = 0, BLE_RF_TX_MODE_LP_MODE = 1, BLE_RF_TX_MODE_ULP_MODE = 2, } ble_rf_tx_mode_t; /** - * @brief The resistance value (ohm) of the RF match circuit. + * @brief The resistance value (ohm) of the RF match circuit. */ -typedef enum { +typedef enum +{ BLE_RF_MATCH_CIRCUIT_25OHM = 25, BLE_RF_MATCH_CIRCUIT_100OHM = 100, } ble_rf_match_circuit_t; @@ -85,20 +90,11 @@ typedef enum { /** @addtogroup BLE_COMMEN_STRUCTURES Structures * @{ */ -/** @brief The app callbacks for GAP, GATT, SM and L2CAP. */ -typedef struct { - app_ble_init_cmp_cb_t - app_ble_init_cmp_callback; /**< Callback function for BLE initialization completed */ - gap_cb_fun_t *app_gap_callbacks; /**< Callback function for GAP */ - const gatt_common_cb_fun_t *app_gatt_common_callback; /**< Callback function for GATT common */ - const gattc_cb_fun_t *app_gattc_callback; /**< Callback function for GATT Client */ - sec_cb_fun_t *app_sec_callback; /**< Callback function for SM*/ -} app_callback_t; - -/** @brief The table contains the pointers to four arrays which are used +/**@brief The table contains the pointers to four arrays which are used * as heap memory by BLE stack in ROM. The size of four arrays depends on * the number of connections and the number of attributes of profiles. */ -typedef struct { +typedef struct +{ uint32_t *env_ret; /**< Pointer to the array for environment heap */ uint32_t *db_ret; /**< Pointer to the array for ATT DB heap */ uint32_t *msg_ret; /**< Pointer to the array for message heap */ @@ -113,18 +109,19 @@ typedef struct { uint32_t bm_size; /**< The size of the array for bond manager heap */ uint8_t *conn_buf; /**< Pointer to the array for connection heap */ uint32_t conn_size; /**< The size of the array for connection heap */ -} stack_heaps_table_t; + uint8_t *scan_dup_filt_list_buf; /**< Pointer to the array for adv duplicate filter */ + uint32_t scan_dup_filt_list_size; /**< The size of the array for adv duplicate filter */ +}stack_heaps_table_t; -/** @brief The function pointers for HCI UART. */ -typedef struct { - void (*init)(void); /**< Initialize UART. */ - void (*flow_on)(void); /**< Flow control on. */ - bool (*flow_off)(void); /**< Flow control off. */ - void (*finish_transfers)(void); /**< Finish the current transferring. */ - /**< Read data. */ - void (*read)(uint8_t *bufptr, uint32_t size, uint8_t (*callback) (uint8_t*, uint8_t), uint8_t* dummy); - /**< Write data. */ - void (*write)(uint8_t *bufptr, uint32_t size, uint8_t (*callback) (uint8_t*, uint8_t), uint8_t* dummy); +/**@brief The function pointers for HCI UART. */ +typedef struct +{ + void (*init)(void); /**< Initialize UART. */ + void (*flow_on)(void); /**< Flow control on. */ + bool (*flow_off)(void); /**< Flow control off. */ + void (*finish_transfers)(void); /**< Finish the current transferring. */ + void (*read)(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); /**< Read data. */ + void (*write)(uint8_t *bufptr, uint32_t size, void (*callback) (void*, uint8_t), void* dummy); /**< Write data. */ } hci_uart_call_t; /** @} */ @@ -132,7 +129,7 @@ typedef struct { * @{ */ -/** @brief The BLE sync event callback. */ +/**@brief The BLE sync event callback. */ typedef void (*ble_sync_evt_cb_t)(uint32_t sync_cnt, uint16_t sync_period); /** @} */ @@ -140,13 +137,22 @@ typedef void (*ble_sync_evt_cb_t)(uint32_t sync_cnt, uint16_t sync_period); * @{ */ /** ***************************************************************************************** - * @brief Initialize BEL Stack. + * @brief Initialize BLE Stack. * - * @param[in] p_app_callback: Pointer to the structure of app callbacks. + * @param[in] evt_handler: Pointer to ble events handler. * @param[in] p_heaps_table: Pointer to the BLE stack heaps table. ***************************************************************************************** */ -void ble_stack_init(app_callback_t *p_app_callback, stack_heaps_table_t *p_heaps_table); +uint16_t ble_stack_init(ble_evt_handler_t evt_handler, stack_heaps_table_t *p_heaps_table); + +/** + ***************************************************************************************** + * @brief Initialize only BLE Stack Controller. + * + * @param[in] p_heaps_table: Pointer to the BLE stack heaps table. + ***************************************************************************************** + */ +void ble_stack_controller_init(stack_heaps_table_t *p_heaps_table); /** ***************************************************************************************** @@ -173,42 +179,38 @@ void ble_idle_time_notify_cb_register(void (*callback)(uint32_t hs)); /** ***************************************************************************************** - * @brief Register BLE event - start notification callback function. + * @brief Register BLE activity start notification callback function. * - * @param[in] callback: function pointer of BLE event - start notification. - * @note param[in] of callback: e_role - the role of event, - * @ref gap_role_t for possible roles. + * @param[in] callback: function pointer of BLE activity start notification function. + * @note param[in] of callback: e_role - the role of activity, gap_activity_role_t for possible roles. * param[in] of callback: index - The index parameter is interpreted by role. - * If the role is @ref GAP_EVENT_ROLE_ADV, it's the index of Advertising. - * If the role is @ref GAP_EVENT_ROLE_CON, it's the index of Connection. + * If role is GAP_ACTIVITY_ROLE_ADV, it's the index of Advertising. + * If role is GAP_ACTIVITY_ROLE_CON, it's the index of Connection. * For all other roles, it should be ignored. - * A callback will be called by BLE ISR when the BLE event starts every time. + * Callback will be called by BLE ISR when the BLE activity starts every time. * It should be realized as simlpe as you can. * Notice: You must define the start callback in the RAM space to avoid hardfault. * It's not suitable for ISO activities. ***************************************************************************************** */ -void ble_start_notify_cb_register(void (*callback)(gap_event_role_t e_role, - uint8_t index)); +void ble_activity_start_notify_cb_register(void (*callback)(ble_gap_actv_role_t e_role, uint8_t index)); /** ***************************************************************************************** - * @brief Register BLE event end notification callback function. + * @brief Register BLE activity end notification callback function. * - * @param[in] callback: function pointer of BLE event - end notification function. - * @note param[in] of callback: e_role - the role of event, - * @ref gap_role_t for possible roles. + * @param[in] callback: function pointer of BLE activity end notification function. + * @note param[in] of callback: e_role - the role of activity,gap_activity_role_t for possible roles. * param[in] of callback: index - The index parameter is interpreted by role. - * If the role is @ref GAP_EVENT_ROLE_ADV, it's the index of Advertising. - * If the role is @ref GAP_EVENT_ROLE_CON, it's the index of Connection. + * If role is GAP_ACTIVITY_ROLE_ADV, it's the index of Advertising. + * If role is GAP_ACTIVITY_ROLE_CON, it's the index of Connection. * For all other roles, it should be ignored. - * A callback will be called by BLE ISR when the BLE event ends every time. + * Callback will be called by BLE ISR when the BLE activity ends every time. * It should be realized as simlpe as you can. You'd better to define it in the RAM space * It's not suitable for ISO activities. ***************************************************************************************** */ -void ble_end_notify_cb_register(void (*callback)(gap_event_role_t e_role, - uint8_t index)); +void ble_activity_end_notify_cb_register(void (*callback)(ble_gap_actv_role_t e_role, uint8_t index)); /** ***************************************************************************************** @@ -264,10 +266,10 @@ uint16_t ble_sync_source_destroy(void); * BLE_RF_TX_MODE_LP_MODE: LP mode. * BLE_RF_TX_MODE_ULP_MODE: ULP mode. * Others: invalid mode. - * + * * @note This function should be called before BLE stack init. * - * @return SDK_SUCCESS: Successfully set Tx mode. + * @return SDK_SUCCESS: Successfully set Tx mode. * SDK_ERR_DISALLOWED: Failed to set Tx mode. ***************************************************************************************** */ @@ -283,7 +285,7 @@ uint8_t ble_rf_tx_mode_set(ble_rf_tx_mode_t e_rf_tx_mode); ***************************************************************************************** */ ble_rf_tx_mode_t ble_rf_tx_mode_get(void); - + /** ***************************************************************************************** * @brief Set the resistance value of the RF match circuit (unit: ohm). diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_att.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_att.h old mode 100755 new mode 100644 index ce9e56b..ccc8c0e --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_att.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_att.h @@ -35,12 +35,12 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -*/ + /** + * @addtogroup BLE + * @{ + */ -/** + /** * @addtogroup BLE_ATT Attribute Protocol (ATT) * @{ * @brief Definitions and prototypes for ATT. @@ -52,12 +52,11 @@ /** @addtogroup BLE_ATT_DEFINES Defines * @{ */ -#define BLE_ATT_UUID_16(uuid) (uuid) /**< Convert CPU’s integer definition to - LSB-first 16-bit UUID. */ -#define BLE_ATT_MTU_DEFAULT (23) /**< Default ATT MTU size in bytes. */ -#define BLE_ATT_INVALID_HDL (0x0000) /**< Invalid attribute handle. */ -#define BLE_ATT_HANDLE_START (0x0001) /**< Attribute handle start. */ -#define BLE_ATT_HANDLE_END (0xFFFF) /**< Attribute handle end. */ +#define BLE_ATT_UUID_16(uuid) (uuid) /**< Convert CPU’s integer definition to LSB-first 16-bit UUID. */ +#define BLE_ATT_MTU_DEFAULT (23) /**< Default ATT MTU size in bytes. */ +#define BLE_ATT_INVALID_HDL (0x0000) /**< Invalid attribute handle. */ +#define BLE_ATT_HANDLE_START (0x0001) /**< Attribute handle start. */ +#define BLE_ATT_HANDLE_END (0xFFFF) /**< Attribute handle end. */ /** @defgroup BLE_ATT_UUID_LEN Attribute UUID Length(bytes) * @{ */ @@ -80,23 +79,20 @@ /** @defgroup BLE_ATT_CHAR_EXTENDED_PROPERTIES Characteristic Extended Properties * @{ */ -#define BLE_ATT_EXT_RELIABLE_WRITE 0x0001 /**< Characteristic Extended Property: Reliable Write. */ -#define BLE_ATT_EXT_WRITABLE_AUX 0x0002 /**< Characteristic Extended Property: Writable Auxiliaries. */ -#define BLE_ATT_EXT_RFU 0xFFFC /**< Characteristic Extended Property: - Reserved for Future Use. */ +#define BLE_ATT_EXT_RELIABLE_WRITE 0x0001 /**< Characteristic Extended Property: Reliable Write. */ +#define BLE_ATT_EXT_WRITABLE_AUX 0x0002 /**< Characteristic Extended Property: Writable Auxiliaries. */ +#define BLE_ATT_EXT_RFU 0xFFFC /**< Characteristic Extended Property: Reserved for Future Use. */ /** @} */ -/** @brief Characteristic Base UUID. */ +/**@brief Characteristic Base UUID. */ #define BLE_ATT_BT_UUID_128 {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, \ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - /** @brief Change a 16-bit UUID array to a 128-bit one (append 0). * @param uuid: 16-bit UUID * @retval None */ #define BLE_ATT_16_TO_128_ARRAY(uuid) {(uuid) & 0xFF, ((uuid) >> 8) & 0xFF, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } /** @brief Change a 16-bit UUID array to a 16-bit one (append 0). * @param uuid: 16-bit UUID * @retval None @@ -108,854 +104,442 @@ /** @addtogroup BLE_ATT_ENUMERATIONS Enumerations * @{ */ -/** @brief Attribute Specification Definitions: Common 16-bit (Universal Unique Identifier). */ -typedef enum { - BLE_ATT_INVALID_UUID = BLE_ATT_UUID_16(0x0000), - /**< Invalid UUID. */ +/**@brief Attribute Specification Definitions: Common 16-bit (Universal Unique Identifier). */ +typedef enum +{ + BLE_ATT_INVALID_UUID = BLE_ATT_UUID_16(0x0000), /**< Invalid UUID. */ /*----------------- SERVICES ---------------------*/ - BLE_ATT_SVC_GENERIC_ACCESS = BLE_ATT_UUID_16(0x1800), - /**< Generic Access Profile. */ - BLE_ATT_SVC_GENERIC_ATTRIBUTE = BLE_ATT_UUID_16(0x1801), - /**< Attribute Profile. */ - BLE_ATT_SVC_IMMEDIATE_ALERT = BLE_ATT_UUID_16(0x1802), - /**< Immediate Alert Service. */ - BLE_ATT_SVC_LINK_LOSS = BLE_ATT_UUID_16(0x1803), - /**< Link Loss Service. */ - BLE_ATT_SVC_TX_POWER = BLE_ATT_UUID_16(0x1804), - /**< TX Power Service. */ - BLE_ATT_SVC_CURRENT_TIME = BLE_ATT_UUID_16(0x1805), - /**< Current Time Service. */ - BLE_ATT_SVC_REF_TIME_UPDATE = BLE_ATT_UUID_16(0x1806), - /**< Reference Time Update Service. */ - BLE_ATT_SVC_NEXT_DST_CHANGE = BLE_ATT_UUID_16(0x1807), - /**< Next DST Change Service. */ - BLE_ATT_SVC_GLUCOSE = BLE_ATT_UUID_16(0x1808), - /**< Glucose Service. */ - BLE_ATT_SVC_HEALTH_THERMOM = BLE_ATT_UUID_16(0x1809), - /**< Health Thermometer Service. */ - BLE_ATT_SVC_DEVICE_INFO = BLE_ATT_UUID_16(0x180A), - /**< Device Information Service. */ - BLE_ATT_SVC_HEART_RATE = BLE_ATT_UUID_16(0x180D), - /**< Heart Rate Service. */ - BLE_ATT_SVC_PHONE_ALERT_STATUS = BLE_ATT_UUID_16(0x180E), - /**< Phone Alert Status Service. */ - BLE_ATT_SVC_BATTERY_SERVICE = BLE_ATT_UUID_16(0x180F), - /**< Battery Service. */ - BLE_ATT_SVC_BLOOD_PRESSURE = BLE_ATT_UUID_16(0x1810), - /**< Blood Pressure Service. */ - BLE_ATT_SVC_ALERT_NTF = BLE_ATT_UUID_16(0x1811), - /**< Alert Notification Service. */ - BLE_ATT_SVC_HID = BLE_ATT_UUID_16(0x1812), - /**< HID Service. */ - BLE_ATT_SVC_SCAN_PARAMETERS = BLE_ATT_UUID_16(0x1813), - /**< Scan Parameters Service. */ - BLE_ATT_SVC_RUNNING_SPEED_CADENCE = BLE_ATT_UUID_16(0x1814), - /**< Running Speed and Cadence Service. */ - BLE_ATT_SVC_CYCLING_SPEED_CADENCE = BLE_ATT_UUID_16(0x1816), - /**< Cycling Speed and Cadence Service. */ - BLE_ATT_SVC_CYCLING_POWER = BLE_ATT_UUID_16(0x1818), - /**< Cycling Power Service. */ - BLE_ATT_SVC_LOCATION_AND_NAVIGATION = BLE_ATT_UUID_16(0x1819), - /**< Location and Navigation Service. */ - BLE_ATT_SVC_ENVIRONMENTAL_SENSING = BLE_ATT_UUID_16(0x181A), - /**< Environmental Sensing Service. */ - BLE_ATT_SVC_BODY_COMPOSITION = BLE_ATT_UUID_16(0x181B), - /**< Body Composition Service. */ - BLE_ATT_SVC_USER_DATA = BLE_ATT_UUID_16(0x181C), - /**< User Data Service. */ - BLE_ATT_SVC_WEIGHT_SCALE = BLE_ATT_UUID_16(0x181D), - /**< Weight Scale Service. */ - BLE_ATT_SVC_BOND_MANAGEMENT = BLE_ATT_UUID_16(0x181E), - /**< Bond Management Service. */ - BLE_ATT_SVC_CONTINUOUS_GLUCOSE_MONITORING = BLE_ATT_UUID_16(0x181F), - /**< Continuous Glucose Monitoring Service. */ - BLE_ATT_SVC_IP_SUPPORT = BLE_ATT_UUID_16(0x1820), - /**< Internet Protocol Support Service. */ - BLE_ATT_SVC_INDOOR_POSITIONING = BLE_ATT_UUID_16(0x1821), - /**< Indoor Positioning Service. */ - BLE_ATT_SVC_PULSE_OXIMETER = BLE_ATT_UUID_16(0x1822), - /**< Pulse Oximeter Service. */ - BLE_ATT_SVC_HTTP_PROXY = BLE_ATT_UUID_16(0x1823), - /**< HTTP Proxy Service. */ - BLE_ATT_SVC_TRANSPORT_DISCOVERY = BLE_ATT_UUID_16(0x1824), - /**< Transport Discovery Service. */ - BLE_ATT_SVC_OBJECT_TRANSFER = BLE_ATT_UUID_16(0x1825), - /**< Object Transfer Service. */ + BLE_ATT_SVC_GENERIC_ACCESS = BLE_ATT_UUID_16(0x1800), /**< Generic Access Profile. */ + BLE_ATT_SVC_GENERIC_ATTRIBUTE = BLE_ATT_UUID_16(0x1801), /**< Attribute Profile. */ + BLE_ATT_SVC_IMMEDIATE_ALERT = BLE_ATT_UUID_16(0x1802), /**< Immediate Alert Service. */ + BLE_ATT_SVC_LINK_LOSS = BLE_ATT_UUID_16(0x1803), /**< Link Loss Service. */ + BLE_ATT_SVC_TX_POWER = BLE_ATT_UUID_16(0x1804), /**< TX Power Service. */ + BLE_ATT_SVC_CURRENT_TIME = BLE_ATT_UUID_16(0x1805), /**< Current Time Service. */ + BLE_ATT_SVC_REF_TIME_UPDATE = BLE_ATT_UUID_16(0x1806), /**< Reference Time Update Service. */ + BLE_ATT_SVC_NEXT_DST_CHANGE = BLE_ATT_UUID_16(0x1807), /**< Next DST Change Service. */ + BLE_ATT_SVC_GLUCOSE = BLE_ATT_UUID_16(0x1808), /**< Glucose Service. */ + BLE_ATT_SVC_HEALTH_THERMOM = BLE_ATT_UUID_16(0x1809), /**< Health Thermometer Service. */ + BLE_ATT_SVC_DEVICE_INFO = BLE_ATT_UUID_16(0x180A), /**< Device Information Service. */ + BLE_ATT_SVC_HEART_RATE = BLE_ATT_UUID_16(0x180D), /**< Heart Rate Service. */ + BLE_ATT_SVC_PHONE_ALERT_STATUS = BLE_ATT_UUID_16(0x180E), /**< Phone Alert Status Service. */ + BLE_ATT_SVC_BATTERY_SERVICE = BLE_ATT_UUID_16(0x180F), /**< Battery Service. */ + BLE_ATT_SVC_BLOOD_PRESSURE = BLE_ATT_UUID_16(0x1810), /**< Blood Pressure Service. */ + BLE_ATT_SVC_ALERT_NTF = BLE_ATT_UUID_16(0x1811), /**< Alert Notification Service. */ + BLE_ATT_SVC_HID = BLE_ATT_UUID_16(0x1812), /**< HID Service. */ + BLE_ATT_SVC_SCAN_PARAMETERS = BLE_ATT_UUID_16(0x1813), /**< Scan Parameters Service. */ + BLE_ATT_SVC_RUNNING_SPEED_CADENCE = BLE_ATT_UUID_16(0x1814), /**< Running Speed and Cadence Service. */ + BLE_ATT_SVC_CYCLING_SPEED_CADENCE = BLE_ATT_UUID_16(0x1816), /**< Cycling Speed and Cadence Service. */ + BLE_ATT_SVC_CYCLING_POWER = BLE_ATT_UUID_16(0x1818), /**< Cycling Power Service. */ + BLE_ATT_SVC_LOCATION_AND_NAVIGATION = BLE_ATT_UUID_16(0x1819), /**< Location and Navigation Service. */ + BLE_ATT_SVC_ENVIRONMENTAL_SENSING = BLE_ATT_UUID_16(0x181A), /**< Environmental Sensing Service. */ + BLE_ATT_SVC_BODY_COMPOSITION = BLE_ATT_UUID_16(0x181B), /**< Body Composition Service. */ + BLE_ATT_SVC_USER_DATA = BLE_ATT_UUID_16(0x181C), /**< User Data Service. */ + BLE_ATT_SVC_WEIGHT_SCALE = BLE_ATT_UUID_16(0x181D), /**< Weight Scale Service. */ + BLE_ATT_SVC_BOND_MANAGEMENT = BLE_ATT_UUID_16(0x181E), /**< Bond Management Service. */ + BLE_ATT_SVC_CONTINUOUS_GLUCOSE_MONITORING = BLE_ATT_UUID_16(0x181F), /**< Continuous Glucose Monitoring Service. */ + BLE_ATT_SVC_IP_SUPPORT = BLE_ATT_UUID_16(0x1820), /**< Internet Protocol Support Service. */ + BLE_ATT_SVC_INDOOR_POSITIONING = BLE_ATT_UUID_16(0x1821), /**< Indoor Positioning Service. */ + BLE_ATT_SVC_PULSE_OXIMETER = BLE_ATT_UUID_16(0x1822), /**< Pulse Oximeter Service. */ + BLE_ATT_SVC_HTTP_PROXY = BLE_ATT_UUID_16(0x1823), /**< HTTP Proxy Service. */ + BLE_ATT_SVC_TRANSPORT_DISCOVERY = BLE_ATT_UUID_16(0x1824), /**< Transport Discovery Service. */ + BLE_ATT_SVC_OBJECT_TRANSFER = BLE_ATT_UUID_16(0x1825), /**< Object Transfer Service. */ /*------------------- UNITS ---------------------*/ - BLE_ATT_UNIT_UNITLESS = BLE_ATT_UUID_16(0x2700), - /**< No defined unit. */ - BLE_ATT_UNIT_METRE = BLE_ATT_UUID_16(0x2701), - /**< Length unit: meter. */ - BLE_ATT_UNIT_KG = BLE_ATT_UUID_16(0x2702), - /**< Mass unit: kilogram. */ - BLE_ATT_UNIT_SECOND = BLE_ATT_UUID_16(0x2703), - /**< Time unit: second. */ - BLE_ATT_UNIT_AMPERE = BLE_ATT_UUID_16(0x2704), - /**< Electric current unit: ampere. */ - BLE_ATT_UNIT_KELVIN = BLE_ATT_UUID_16(0x2705), - /**< Thermodynamic Temperature unit: kelvin. */ - BLE_ATT_UNIT_MOLE = BLE_ATT_UUID_16(0x2706), - /**< Amount of substance unit: mole. */ - BLE_ATT_UNIT_CANDELA = BLE_ATT_UUID_16(0x2707), - /**< Luminous intensity unit: candela. */ - BLE_ATT_UNIT_SQ_METRE = BLE_ATT_UUID_16(0x2710), - /**< Area unit: square meter. */ - BLE_ATT_UNIT_CUBIC_METRE = BLE_ATT_UUID_16(0x2710), - /**< Column unit: cubic meter. */ - BLE_ATT_UNIT_METRE_PER_SECOND = BLE_ATT_UUID_16(0x2711), - /**< Velocity unit: meter per second. */ - BLE_ATT_UNIT_METRES_PER_SEC_SQ = BLE_ATT_UUID_16(0x2712), - /**< Acceleration unit: meter per second squared. */ - BLE_ATT_UNIT_RECIPROCAL_METRE = BLE_ATT_UUID_16(0x2713), - /**< Wavenumber unit: reciprocal meter. */ - BLE_ATT_UNIT_DENS_KG_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2714), - /**< Density unit: kilogram per cubic meter. */ - BLE_ATT_UNIT_KG_PER_SQ_METRE = BLE_ATT_UUID_16(0x2715), - /**< Surface density unit: (kg/m^2)kilogram per square meter. */ - BLE_ATT_UNIT_CUBIC_METRE_PER_KG = BLE_ATT_UUID_16(0x2716), - /**< Specific volume unit: cubic meter per kilogram. */ - BLE_ATT_UNIT_AMPERE_PER_SQ_METRE = BLE_ATT_UUID_16(0x2717), - /**< Current density unit: ampere per square meter. */ - BLE_ATT_UNIT_AMPERE_PER_METRE = BLE_ATT_UUID_16(0x2718), - /**< Magnetic field strength unit: ampere per meter. */ - BLE_ATT_UNIT_MOLE_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2719), - /**< Amount concentration unit: mole per cubic meter. */ - BLE_ATT_UNIT_MASS_KG_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x271A), - /**< Mass Concentration unit: kilogram per cubic meter. */ - BLE_ATT_UNIT_CANDELA_PER_SQ_METRE = BLE_ATT_UUID_16(0x271B), - /**< Luminance unit: candela per square meter. */ - BLE_ATT_UNIT_REFRACTIVE_INDEX = BLE_ATT_UUID_16(0x271C), - /**< Refractive index unit. */ - BLE_ATT_UNIT_RELATIVE_PERMEABILITY = BLE_ATT_UUID_16(0x271D), - /**< Relative permeability unit. */ - BLE_ATT_UNIT_RADIAN = BLE_ATT_UUID_16(0x2720), - /**< Plane angle unit: radian. */ - BLE_ATT_UNIT_STERADIAN = BLE_ATT_UUID_16(0x2721), - /**< Solid angle unit: steradian. */ - BLE_ATT_UNIT_HERTZ = BLE_ATT_UUID_16(0x2722), - /**< Frequency unit: hertz. */ - BLE_ATT_UNIT_NEWTON = BLE_ATT_UUID_16(0x2723), - /**< Force unit: newton. */ - BLE_ATT_UNIT_PASCAL = BLE_ATT_UUID_16(0x2724), - /**< Pressure unit: pascal. */ - BLE_ATT_UNIT_JOULE = BLE_ATT_UUID_16(0x2725), - /**< Energy unit: joule. */ - BLE_ATT_UNIT_WATT = BLE_ATT_UUID_16(0x2726), - /**< Power unit: watt. */ - BLE_ATT_UNIT_COULOMB = BLE_ATT_UUID_16(0x2727), - /**< Electric Charge unit: coulomb. */ - BLE_ATT_UNIT_VOLT = BLE_ATT_UUID_16(0x2728), - /**< Electric potential difference unit: Volt. */ - BLE_ATT_UNIT_FARAD = BLE_ATT_UUID_16(0x2729), - /**< Capacitance unit: Farad. */ - BLE_ATT_UNIT_OHM = BLE_ATT_UUID_16(0x272A), - /**< Electric resistance unit: ohm. */ - BLE_ATT_UNIT_SIEMENS = BLE_ATT_UUID_16(0x272B), - /**< Electric conductance unit: siemens. */ - BLE_ATT_UNIT_WEBER = BLE_ATT_UUID_16(0x272C), - /**< Magnetic flux unit: weber. */ - BLE_ATT_UNIT_TESLA = BLE_ATT_UUID_16(0x272D), - /**< Magnetic flux density unit: Tesla. */ - BLE_ATT_UNIT_HENRY = BLE_ATT_UUID_16(0x272E), - /**< Inductance unit: henry. */ - BLE_ATT_UNIT_CELSIUS = BLE_ATT_UUID_16(0x272F), - /**< Temperature unit: degree Celsius. */ - BLE_ATT_UNIT_LUMEN = BLE_ATT_UUID_16(0x2730), - /**< Luminous flux unit: lumen. */ - BLE_ATT_UNIT_LUX = BLE_ATT_UUID_16(0x2731), - /**< Illuminance unit: lux. */ - BLE_ATT_UNIT_BECQUEREL = BLE_ATT_UUID_16(0x2732), - /**< Enable referred to a radionuclide unit: becquerel. */ - BLE_ATT_UNIT_GRAY = BLE_ATT_UUID_16(0x2733), - /**< Absorbed dose unit: gray. */ - BLE_ATT_UNIT_SIEVERT = BLE_ATT_UUID_16(0x2734), - /**< Dose equivalent unit: sievert. */ - BLE_ATT_UNIT_KATAL = BLE_ATT_UUID_16(0x2735), - /**< Catalytic enable unit: katal. */ - BLE_ATT_UNIT_PASCAL_SECOND = BLE_ATT_UUID_16(0x2740), - /**< Synamic viscosity unit: pascal second. */ - BLE_ATT_UNIT_NEWTON_METRE = BLE_ATT_UUID_16(0x2741), - /**< Moment of force unit: (N.m)newton meter. */ - BLE_ATT_UNIT_NEWTON_PER_METRE = BLE_ATT_UUID_16(0x2742), - /**< Surface tension unit: newton per meter. */ - BLE_ATT_UNIT_RADIAN_PER_SECOND = BLE_ATT_UUID_16(0x2743), - /**< Angular velocity unit: radian per second. */ - BLE_ATT_UNIT_RADIAN_PER_SECOND_SQ = BLE_ATT_UUID_16(0x2744), - /**< Angular acceleration unit: radian per second squared. */ - BLE_ATT_UNIT_WATT_PER_SQ_METRE = BLE_ATT_UUID_16(0x2745), - /**< Heat flux density unit: watt per square meter. */ - BLE_ATT_UNIT_JOULE_PER_KELVIN = BLE_ATT_UUID_16(0x2746), - /**< Heat capacity unit: joule per Kelvin. */ - BLE_ATT_UNIT_JOULE_PER_KG_KELVIN = BLE_ATT_UUID_16(0x2747), - /**< Specific heat capacity unit: joule per kilogram kelvin. */ - BLE_ATT_UNIT_JOULE_PER_KG = BLE_ATT_UUID_16(0x2748), - /**< Specific Energy unit: joule per kilogram. */ - BLE_ATT_UNIT_WATT_PER_METRE_KELVIN = BLE_ATT_UUID_16(0x2749), - /**< Thermal conductivity unit: watt per meter Kelvin. */ - BLE_ATT_UNIT_JOULE_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x274A), - /**< Energy Density unit: joule per cubic meter. */ - BLE_ATT_UNIT_VOLT_PER_METRE = BLE_ATT_UUID_16(0x274B), - /**< Electric field strength unit: volt per meter. */ - BLE_ATT_UNIT_COULOMB_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x274C), - /**< Electric charge density unit: coulomb per cubic meter. */ - BLE_ATT_UNIT_SURF_COULOMB_PER_SQ_METRE = BLE_ATT_UUID_16(0x274D), - /**< Surface charge density unit: coulomb/(square meter). */ - BLE_ATT_UNIT_FLUX_COULOMB_PER_SQ_METRE = BLE_ATT_UUID_16(0x274E), - /**< Electric flux density unit: coulomb per square meter. */ - BLE_ATT_UNIT_FARAD_PER_METRE = BLE_ATT_UUID_16(0x274F), - /**< Permittivity unit: farad per meter. */ - BLE_ATT_UNIT_HENRY_PER_METRE = BLE_ATT_UUID_16(0x2750), - /**< Permeability unit: henry per meter. */ - BLE_ATT_UNIT_JOULE_PER_MOLE = BLE_ATT_UUID_16(0x2751), - /**< Molar energy unit: joule per mole. */ - BLE_ATT_UNIT_JOULE_PER_MOLE_KELVIN = BLE_ATT_UUID_16(0x2752), - /**< Molar entropy unit: joule per mole kelvin. */ - BLE_ATT_UNIT_COULOMB_PER_KG = BLE_ATT_UUID_16(0x2753), - /**< Exposure unit: coulomb per kilogram. */ - BLE_ATT_UNIT_GRAY_PER_SECOND = BLE_ATT_UUID_16(0x2754), - /**< Absorbed dose rate unit: gray per second. */ - BLE_ATT_UNIT_WATT_PER_STERADIAN = BLE_ATT_UUID_16(0x2755), - /**< Radiant intensity unit: watt per steradian. */ - BLE_ATT_UNIT_WATT_PER_SQ_METRE_STERADIAN = BLE_ATT_UUID_16(0x2756), - /**< Radiance unit: watt per square meter steradian. */ - BLE_ATT_UNIT_KATAL_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2757), - /**< Catalytic active - concentration unit: katal per cubic meter. */ - BLE_ATT_UNIT_MINUTE = BLE_ATT_UUID_16(0x2760), - /**< Time unit: minute. */ - BLE_ATT_UNIT_HOUR = BLE_ATT_UUID_16(0x2761), - /**< Time unit: hour. */ - BLE_ATT_UNIT_DAY = BLE_ATT_UUID_16(0x2762), - /**< Time unit: day. */ - BLE_ATT_UNIT_ANGLE_DEGREE = BLE_ATT_UUID_16(0x2763), - /**< Plane angle unit: degree. */ - BLE_ATT_UNIT_ANGLE_MINUTE = BLE_ATT_UUID_16(0x2764), - /**< Plane angle unit: minute. */ - BLE_ATT_UNIT_ANGLE_SECOND = BLE_ATT_UUID_16(0x2765), - /**< Plane angle unit: second. */ - BLE_ATT_UNIT_HECTARE = BLE_ATT_UUID_16(0x2766), - /**< Area unit: hectare. */ - BLE_ATT_UNIT_LITRE = BLE_ATT_UUID_16(0x2767), - /**< Volume unit: litre. */ - BLE_ATT_UNIT_TONNE = BLE_ATT_UUID_16(0x2768), - /**< Mass unit: tonne. */ - BLE_ATT_UNIT_BAR = BLE_ATT_UUID_16(0x2780), - /**< Pressure unit: bar. */ - BLE_ATT_UNIT_MM_MERCURY = BLE_ATT_UUID_16(0x2781), - /**< Pressure unit: millimetre of mercury. */ - BLE_ATT_UNIT_ANGSTROM = BLE_ATT_UUID_16(0x2782), - /**< Length unit: angstrom. */ - BLE_ATT_UNIT_NAUTICAL_MILE = BLE_ATT_UUID_16(0x2783), - /**< Length unit: nautical mile. */ - BLE_ATT_UNIT_BARN = BLE_ATT_UUID_16(0x2784), - /**< Area unit: barn. */ - BLE_ATT_UNIT_KNOT = BLE_ATT_UUID_16(0x2785), - /**< Velocity unit: knot. */ - BLE_ATT_UNIT_NEPER = BLE_ATT_UUID_16(0x2786), - /**< Logarithmic radio quantity unit: neper. */ - BLE_ATT_UNIT_BEL = BLE_ATT_UUID_16(0x2787), - /**< Logarithmic radio quantity unit: bel. */ - BLE_ATT_UNIT_YARD = BLE_ATT_UUID_16(0x27A0), - /**< Length unit: yard. */ - BLE_ATT_UNIT_PARSEC = BLE_ATT_UUID_16(0x27A1), - /**< Length unit: parsec. */ - BLE_ATT_UNIT_INCH = BLE_ATT_UUID_16(0x27A2), - /**< Length unit: inch. */ - BLE_ATT_UNIT_FOOT = BLE_ATT_UUID_16(0x27A3), - /**< Length unit: foot. */ - BLE_ATT_UNIT_MILE = BLE_ATT_UUID_16(0x27A4), - /**< Length unit: mile. */ - BLE_ATT_UNIT_POUND_FORCE_PER_SQ_INCH = BLE_ATT_UUID_16(0x27A5), - /**< Pressure unit: pound-force per square inch. */ - BLE_ATT_UNIT_KM_PER_HOUR = BLE_ATT_UUID_16(0x27A6), - /**< Velocity unit: kilometre per hour. */ - BLE_ATT_UNIT_MILE_PER_HOUR = BLE_ATT_UUID_16(0x27A7), - /**< Velocity unit: mile per hour. */ - BLE_ATT_UNIT_REVOLUTION_PER_MINUTE = BLE_ATT_UUID_16(0x27A8), - /**< Angular velocity unit: revolution per minute. */ - BLE_ATT_UNIT_GRAM_CALORIE = BLE_ATT_UUID_16(0x27A9), - /**< Energy unit: gram calorie. */ - BLE_ATT_UNIT_KG_CALORIE = BLE_ATT_UUID_16(0x27AA), - /**< Energy unit: kilogram calorie. */ - BLE_ATT_UNIT_KILOWATT_HOUR = BLE_ATT_UUID_16(0x27AB), - /**< Energy unit: kilowatt hour. */ - BLE_ATT_UNIT_FAHRENHEIT = BLE_ATT_UUID_16(0x27AC), - /**< Thermodynamic temperature unit: degree Fahrenheit. */ - BLE_ATT_UNIT_PERCENTAGE = BLE_ATT_UUID_16(0x27AD), - /**< Unit: Percentage. */ - BLE_ATT_UNIT_PER_MILLE = BLE_ATT_UUID_16(0x27AE), - /**< Unit: per mille. */ - BLE_ATT_UNIT_BEATS_PER_MINUTE = BLE_ATT_UUID_16(0x27AF), - /**< Period unit: beats per minute. */ - BLE_ATT_UNIT_AMPERE_HOURS = BLE_ATT_UUID_16(0x27B0), - /**< Electric charge unit: ampere hours. */ - BLE_ATT_UNIT_MILLIGRAM_PER_DECILITRE = BLE_ATT_UUID_16(0x27B1), - /**< Mass density unit: milligram per decilitre. */ - BLE_ATT_UNIT_MILLIMOLE_PER_LITRE = BLE_ATT_UUID_16(0x27B2), - /**< Mass density unit: millimole per litre. */ - BLE_ATT_UNIT_YEAR = BLE_ATT_UUID_16(0x27B3), - /**< Time unit: year. */ - BLE_ATT_UNIT_MONTH = BLE_ATT_UUID_16(0x27B4), - /**< Time unit: month. */ + BLE_ATT_UNIT_UNITLESS = BLE_ATT_UUID_16(0x2700), /**< No defined unit. */ + BLE_ATT_UNIT_METRE = BLE_ATT_UUID_16(0x2701), /**< Length unit: meter. */ + BLE_ATT_UNIT_KG = BLE_ATT_UUID_16(0x2702), /**< Mass unit: kilogram. */ + BLE_ATT_UNIT_SECOND = BLE_ATT_UUID_16(0x2703), /**< Time unit: second. */ + BLE_ATT_UNIT_AMPERE = BLE_ATT_UUID_16(0x2704), /**< Electric current unit: ampere. */ + BLE_ATT_UNIT_KELVIN = BLE_ATT_UUID_16(0x2705), /**< Thermodynamic Temperature unit: kelvin. */ + BLE_ATT_UNIT_MOLE = BLE_ATT_UUID_16(0x2706), /**< Amount of substance unit: mole. */ + BLE_ATT_UNIT_CANDELA = BLE_ATT_UUID_16(0x2707), /**< Luminous intensity unit: candela. */ + BLE_ATT_UNIT_SQ_METRE = BLE_ATT_UUID_16(0x2710), /**< Area unit: square meter. */ + BLE_ATT_UNIT_CUBIC_METRE = BLE_ATT_UUID_16(0x2710), /**< Column unit: cubic meter. */ + BLE_ATT_UNIT_METRE_PER_SECOND = BLE_ATT_UUID_16(0x2711), /**< Velocity unit: meter per second. */ + BLE_ATT_UNIT_METRES_PER_SEC_SQ = BLE_ATT_UUID_16(0x2712), /**< Acceleration unit: meter per second squared. */ + BLE_ATT_UNIT_RECIPROCAL_METRE = BLE_ATT_UUID_16(0x2713), /**< Wavenumber unit: reciprocal meter. */ + BLE_ATT_UNIT_DENS_KG_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2714), /**< Density unit: kilogram per cubic meter. */ + BLE_ATT_UNIT_KG_PER_SQ_METRE = BLE_ATT_UUID_16(0x2715), /**< Surface density unit: kilogram per square meter. */ + BLE_ATT_UNIT_CUBIC_METRE_PER_KG = BLE_ATT_UUID_16(0x2716), /**< Specific volume unit: cubic meter per kilogram. */ + BLE_ATT_UNIT_AMPERE_PER_SQ_METRE = BLE_ATT_UUID_16(0x2717), /**< Current density unit: ampere per square meter. */ + BLE_ATT_UNIT_AMPERE_PER_METRE = BLE_ATT_UUID_16(0x2718), /**< Magnetic field strength unit: ampere per meter. */ + BLE_ATT_UNIT_MOLE_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2719), /**< Amount concentration unit: mole per cubic meter. */ + BLE_ATT_UNIT_MASS_KG_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x271A), /**< Mass Concentration unit: kilogram per cubic meter. */ + BLE_ATT_UNIT_CANDELA_PER_SQ_METRE = BLE_ATT_UUID_16(0x271B), /**< Luminance unit: candela per square meter. */ + BLE_ATT_UNIT_REFRACTIVE_INDEX = BLE_ATT_UUID_16(0x271C), /**< Refractive index unit. */ + BLE_ATT_UNIT_RELATIVE_PERMEABILITY = BLE_ATT_UUID_16(0x271D), /**< Relative permeability unit. */ + BLE_ATT_UNIT_RADIAN = BLE_ATT_UUID_16(0x2720), /**< Plane angle unit: radian. */ + BLE_ATT_UNIT_STERADIAN = BLE_ATT_UUID_16(0x2721), /**< Solid angle unit: steradian. */ + BLE_ATT_UNIT_HERTZ = BLE_ATT_UUID_16(0x2722), /**< Frequency unit: hertz. */ + BLE_ATT_UNIT_NEWTON = BLE_ATT_UUID_16(0x2723), /**< Force unit: newton. */ + BLE_ATT_UNIT_PASCAL = BLE_ATT_UUID_16(0x2724), /**< Pressure unit: pascal. */ + BLE_ATT_UNIT_JOULE = BLE_ATT_UUID_16(0x2725), /**< Energy unit: joule. */ + BLE_ATT_UNIT_WATT = BLE_ATT_UUID_16(0x2726), /**< Power unit: watt. */ + BLE_ATT_UNIT_COULOMB = BLE_ATT_UUID_16(0x2727), /**< Electric Charge unit: coulomb. */ + BLE_ATT_UNIT_VOLT = BLE_ATT_UUID_16(0x2728), /**< Electric potential difference unit: Volt. */ + BLE_ATT_UNIT_FARAD = BLE_ATT_UUID_16(0x2729), /**< Capacitance unit: Farad. */ + BLE_ATT_UNIT_OHM = BLE_ATT_UUID_16(0x272A), /**< Electric resistance unit: ohm. */ + BLE_ATT_UNIT_SIEMENS = BLE_ATT_UUID_16(0x272B), /**< Electric conductance unit: siemens. */ + BLE_ATT_UNIT_WEBER = BLE_ATT_UUID_16(0x272C), /**< Magnetic flux unit: weber. */ + BLE_ATT_UNIT_TESLA = BLE_ATT_UUID_16(0x272D), /**< Magnetic flux density unit: Tesla. */ + BLE_ATT_UNIT_HENRY = BLE_ATT_UUID_16(0x272E), /**< Inductance unit: henry. */ + BLE_ATT_UNIT_CELSIUS = BLE_ATT_UUID_16(0x272F), /**< Temperature unit: degree Celsius. */ + BLE_ATT_UNIT_LUMEN = BLE_ATT_UUID_16(0x2730), /**< Luminous flux unit: lumen. */ + BLE_ATT_UNIT_LUX = BLE_ATT_UUID_16(0x2731), /**< Illuminance unit: lux. */ + BLE_ATT_UNIT_BECQUEREL = BLE_ATT_UUID_16(0x2732), /**< Activity referred to a radionuclide unit: becquerel. */ + BLE_ATT_UNIT_GRAY = BLE_ATT_UUID_16(0x2733), /**< Absorbed dose unit: gray. */ + BLE_ATT_UNIT_SIEVERT = BLE_ATT_UUID_16(0x2734), /**< Dose equivalent unit: sievert. */ + BLE_ATT_UNIT_KATAL = BLE_ATT_UUID_16(0x2735), /**< Catalytic activity unit: katal. */ + BLE_ATT_UNIT_PASCAL_SECOND = BLE_ATT_UUID_16(0x2740), /**< Synamic viscosity unit: pascal second. */ + BLE_ATT_UNIT_NEWTON_METRE = BLE_ATT_UUID_16(0x2741), /**< Moment of force unit: newton meter. */ + BLE_ATT_UNIT_NEWTON_PER_METRE = BLE_ATT_UUID_16(0x2742), /**< Surface tension unit: newton per meter. */ + BLE_ATT_UNIT_RADIAN_PER_SECOND = BLE_ATT_UUID_16(0x2743), /**< Angular velocity unit: radian per second. */ + BLE_ATT_UNIT_RADIAN_PER_SECOND_SQ = BLE_ATT_UUID_16(0x2744), /**< Angular acceleration unit: radian per second squared. */ + BLE_ATT_UNIT_WATT_PER_SQ_METRE = BLE_ATT_UUID_16(0x2745), /**< Heat flux density unit: watt per square meter. */ + BLE_ATT_UNIT_JOULE_PER_KELVIN = BLE_ATT_UUID_16(0x2746), /**< Heat capacity unit: joule per Kelvin. */ + BLE_ATT_UNIT_JOULE_PER_KG_KELVIN = BLE_ATT_UUID_16(0x2747), /**< Specific heat capacity unit: joule per kilogram kelvin. */ + BLE_ATT_UNIT_JOULE_PER_KG = BLE_ATT_UUID_16(0x2748), /**< Specific Energy unit: joule per kilogram. */ + BLE_ATT_UNIT_WATT_PER_METRE_KELVIN = BLE_ATT_UUID_16(0x2749), /**< Thermal conductivity unit: watt per meter Kelvin. */ + BLE_ATT_UNIT_JOULE_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x274A), /**< Energy Density unit: joule per cubic meter. */ + BLE_ATT_UNIT_VOLT_PER_METRE = BLE_ATT_UUID_16(0x274B), /**< Electric field strength unit: volt per meter. */ + BLE_ATT_UNIT_COULOMB_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x274C), /**< Electric charge density unit: coulomb per cubic meter. */ + BLE_ATT_UNIT_SURF_COULOMB_PER_SQ_METRE = BLE_ATT_UUID_16(0x274D), /**< Surface charge density unit: coulomb per square meter. */ + BLE_ATT_UNIT_FLUX_COULOMB_PER_SQ_METRE = BLE_ATT_UUID_16(0x274E), /**< Electric flux density unit: coulomb per square meter. */ + BLE_ATT_UNIT_FARAD_PER_METRE = BLE_ATT_UUID_16(0x274F), /**< Permittivity unit: farad per meter. */ + BLE_ATT_UNIT_HENRY_PER_METRE = BLE_ATT_UUID_16(0x2750), /**< Permeability unit: henry per meter. */ + BLE_ATT_UNIT_JOULE_PER_MOLE = BLE_ATT_UUID_16(0x2751), /**< Molar energy unit: joule per mole. */ + BLE_ATT_UNIT_JOULE_PER_MOLE_KELVIN = BLE_ATT_UUID_16(0x2752), /**< Molar entropy unit: joule per mole kelvin. */ + BLE_ATT_UNIT_COULOMB_PER_KG = BLE_ATT_UUID_16(0x2753), /**< Exposure unit: coulomb per kilogram. */ + BLE_ATT_UNIT_GRAY_PER_SECOND = BLE_ATT_UUID_16(0x2754), /**< Absorbed dose rate unit: gray per second. */ + BLE_ATT_UNIT_WATT_PER_STERADIAN = BLE_ATT_UUID_16(0x2755), /**< Radiant intensity unit: watt per steradian. */ + BLE_ATT_UNIT_WATT_PER_SQ_METRE_STERADIAN = BLE_ATT_UUID_16(0x2756), /**< Radiance unit: watt per square meter steradian. */ + BLE_ATT_UNIT_KATAL_PER_CUBIC_METRE = BLE_ATT_UUID_16(0x2757), /**< Catalytic activity concentration unit: katal per cubic meter. */ + BLE_ATT_UNIT_MINUTE = BLE_ATT_UUID_16(0x2760), /**< Time unit: minute. */ + BLE_ATT_UNIT_HOUR = BLE_ATT_UUID_16(0x2761), /**< Time unit: hour. */ + BLE_ATT_UNIT_DAY = BLE_ATT_UUID_16(0x2762), /**< Time unit: day. */ + BLE_ATT_UNIT_ANGLE_DEGREE = BLE_ATT_UUID_16(0x2763), /**< Plane angle unit: degree. */ + BLE_ATT_UNIT_ANGLE_MINUTE = BLE_ATT_UUID_16(0x2764), /**< Plane angle unit: minute. */ + BLE_ATT_UNIT_ANGLE_SECOND = BLE_ATT_UUID_16(0x2765), /**< Plane angle unit: second. */ + BLE_ATT_UNIT_HECTARE = BLE_ATT_UUID_16(0x2766), /**< Area unit: hectare. */ + BLE_ATT_UNIT_LITRE = BLE_ATT_UUID_16(0x2767), /**< Volume unit: litre. */ + BLE_ATT_UNIT_TONNE = BLE_ATT_UUID_16(0x2768), /**< Mass unit: tonne. */ + BLE_ATT_UNIT_BAR = BLE_ATT_UUID_16(0x2780), /**< Pressure unit: bar. */ + BLE_ATT_UNIT_MM_MERCURY = BLE_ATT_UUID_16(0x2781), /**< Pressure unit: millimetre of mercury. */ + BLE_ATT_UNIT_ANGSTROM = BLE_ATT_UUID_16(0x2782), /**< Length unit: angstrom. */ + BLE_ATT_UNIT_NAUTICAL_MILE = BLE_ATT_UUID_16(0x2783), /**< Length unit: nautical mile. */ + BLE_ATT_UNIT_BARN = BLE_ATT_UUID_16(0x2784), /**< Area unit: barn. */ + BLE_ATT_UNIT_KNOT = BLE_ATT_UUID_16(0x2785), /**< Velocity unit: knot. */ + BLE_ATT_UNIT_NEPER = BLE_ATT_UUID_16(0x2786), /**< Logarithmic radio quantity unit: neper. */ + BLE_ATT_UNIT_BEL = BLE_ATT_UUID_16(0x2787), /**< Logarithmic radio quantity unit: bel. */ + BLE_ATT_UNIT_YARD = BLE_ATT_UUID_16(0x27A0), /**< Length unit: yard. */ + BLE_ATT_UNIT_PARSEC = BLE_ATT_UUID_16(0x27A1), /**< Length unit: parsec. */ + BLE_ATT_UNIT_INCH = BLE_ATT_UUID_16(0x27A2), /**< Length unit: inch. */ + BLE_ATT_UNIT_FOOT = BLE_ATT_UUID_16(0x27A3), /**< Length unit: foot. */ + BLE_ATT_UNIT_MILE = BLE_ATT_UUID_16(0x27A4), /**< Length unit: mile. */ + BLE_ATT_UNIT_POUND_FORCE_PER_SQ_INCH = BLE_ATT_UUID_16(0x27A5), /**< Pressure unit: pound-force per square inch. */ + BLE_ATT_UNIT_KM_PER_HOUR = BLE_ATT_UUID_16(0x27A6), /**< Velocity unit: kilometre per hour. */ + BLE_ATT_UNIT_MILE_PER_HOUR = BLE_ATT_UUID_16(0x27A7), /**< Velocity unit: mile per hour. */ + BLE_ATT_UNIT_REVOLUTION_PER_MINUTE = BLE_ATT_UUID_16(0x27A8), /**< Angular velocity unit: revolution per minute. */ + BLE_ATT_UNIT_GRAM_CALORIE = BLE_ATT_UUID_16(0x27A9), /**< Energy unit: gram calorie. */ + BLE_ATT_UNIT_KG_CALORIE = BLE_ATT_UUID_16(0x27AA), /**< Energy unit: kilogram calorie. */ + BLE_ATT_UNIT_KILOWATT_HOUR = BLE_ATT_UUID_16(0x27AB), /**< Energy unit: kilowatt hour. */ + BLE_ATT_UNIT_FAHRENHEIT = BLE_ATT_UUID_16(0x27AC), /**< Thermodynamic temperature unit: degree Fahrenheit. */ + BLE_ATT_UNIT_PERCENTAGE = BLE_ATT_UUID_16(0x27AD), /**< Unit: Percentage. */ + BLE_ATT_UNIT_PER_MILLE = BLE_ATT_UUID_16(0x27AE), /**< Unit: per mille. */ + BLE_ATT_UNIT_BEATS_PER_MINUTE = BLE_ATT_UUID_16(0x27AF), /**< Period unit: beats per minute. */ + BLE_ATT_UNIT_AMPERE_HOURS = BLE_ATT_UUID_16(0x27B0), /**< Electric charge unit: ampere hours. */ + BLE_ATT_UNIT_MILLIGRAM_PER_DECILITRE = BLE_ATT_UUID_16(0x27B1), /**< Mass density unit: milligram per decilitre. */ + BLE_ATT_UNIT_MILLIMOLE_PER_LITRE = BLE_ATT_UUID_16(0x27B2), /**< Mass density unit: millimole per litre. */ + BLE_ATT_UNIT_YEAR = BLE_ATT_UUID_16(0x27B3), /**< Time unit: year. */ + BLE_ATT_UNIT_MONTH = BLE_ATT_UUID_16(0x27B4), /**< Time unit: month. */ /*---------------- DECLARATIONS -----------------*/ - BLE_ATT_DECL_PRIMARY_SERVICE = BLE_ATT_UUID_16(0x2800), - /**< Primary service Declaration. */ - BLE_ATT_DECL_SECONDARY_SERVICE = BLE_ATT_UUID_16(0x2801), - /**< Secondary service Declaration. */ - BLE_ATT_DECL_INCLUDE = BLE_ATT_UUID_16(0x2802), - /**< Include Declaration. */ - BLE_ATT_DECL_CHARACTERISTIC = BLE_ATT_UUID_16(0x2803), - /**< Characteristic Declaration. */ + BLE_ATT_DECL_PRIMARY_SERVICE = BLE_ATT_UUID_16(0x2800), /**< Primary service Declaration. */ + BLE_ATT_DECL_SECONDARY_SERVICE = BLE_ATT_UUID_16(0x2801), /**< Secondary service Declaration. */ + BLE_ATT_DECL_INCLUDE = BLE_ATT_UUID_16(0x2802), /**< Include Declaration. */ + BLE_ATT_DECL_CHARACTERISTIC = BLE_ATT_UUID_16(0x2803), /**< Characteristic Declaration. */ - /*----------------- DESCRIPTORS -----------------*/ - BLE_ATT_DESC_CHAR_EXT_PROPERTIES = BLE_ATT_UUID_16(0x2900), - /**< Characteristic extended properties. */ - BLE_ATT_DESC_CHAR_USER_DESCRIPTION = BLE_ATT_UUID_16(0x2901), - /**< Characteristic user description. */ - BLE_ATT_DESC_CLIENT_CHAR_CFG = BLE_ATT_UUID_16(0x2902), - /**< Client characteristic configuration. */ - BLE_ATT_DESC_SERVER_CHAR_CFG = BLE_ATT_UUID_16(0x2903), - /**< Server characteristic configuration. */ - BLE_ATT_DESC_CHAR_PRES_FORMAT = BLE_ATT_UUID_16(0x2904), - /**< Characteristic Presentation Format. */ - BLE_ATT_DESC_CHAR_AGGREGATE_FORMAT = BLE_ATT_UUID_16(0x2905), - /**< Characteristic Aggregate Format. */ - BLE_ATT_DESC_VALID_RANGE = BLE_ATT_UUID_16(0x2906), - /**< Valid Range. */ - BLE_ATT_DESC_EXT_REPORT_REF = BLE_ATT_UUID_16(0x2907), - /**< External Report Reference. */ - BLE_ATT_DESC_REPORT_REF = BLE_ATT_UUID_16(0x2908), - /**< Report Reference. */ - BLE_ATT_DESC_ES_CONFIGURATION = BLE_ATT_UUID_16(0x290B), - /**< Environmental Sensing Configuration. */ - BLE_ATT_DESC_ES_MEASUREMENT = BLE_ATT_UUID_16(0x290C), - /**< Environmental Sensing Measurement. */ - BLE_ATT_DESC_ES_TRIGGER_SETTING = BLE_ATT_UUID_16(0x290D), - /**< Environmental Sensing Trigger Setting. */ + /*----------------- DESCRIPTORS -----------------*/ + BLE_ATT_DESC_CHAR_EXT_PROPERTIES = BLE_ATT_UUID_16(0x2900), /**< Characteristic extended properties. */ + BLE_ATT_DESC_CHAR_USER_DESCRIPTION = BLE_ATT_UUID_16(0x2901), /**< Characteristic user description. */ + BLE_ATT_DESC_CLIENT_CHAR_CFG = BLE_ATT_UUID_16(0x2902), /**< Client characteristic configuration. */ + BLE_ATT_DESC_SERVER_CHAR_CFG = BLE_ATT_UUID_16(0x2903), /**< Server characteristic configuration. */ + BLE_ATT_DESC_CHAR_PRES_FORMAT = BLE_ATT_UUID_16(0x2904), /**< Characteristic Presentation Format. */ + BLE_ATT_DESC_CHAR_AGGREGATE_FORMAT = BLE_ATT_UUID_16(0x2905), /**< Characteristic Aggregate Format. */ + BLE_ATT_DESC_VALID_RANGE = BLE_ATT_UUID_16(0x2906), /**< Valid Range. */ + BLE_ATT_DESC_EXT_REPORT_REF = BLE_ATT_UUID_16(0x2907), /**< External Report Reference. */ + BLE_ATT_DESC_REPORT_REF = BLE_ATT_UUID_16(0x2908), /**< Report Reference. */ + BLE_ATT_DESC_ES_CONFIGURATION = BLE_ATT_UUID_16(0x290B), /**< Environmental Sensing Configuration. */ + BLE_ATT_DESC_ES_MEASUREMENT = BLE_ATT_UUID_16(0x290C), /**< Environmental Sensing Measurement. */ + BLE_ATT_DESC_ES_TRIGGER_SETTING = BLE_ATT_UUID_16(0x290D), /**< Environmental Sensing Trigger Setting. */ /*--------------- CHARACTERISTICS ---------------*/ - BLE_ATT_CHAR_DEVICE_NAME = BLE_ATT_UUID_16(0x2A00), - /**< Device name. */ - BLE_ATT_CHAR_APPEARANCE = BLE_ATT_UUID_16(0x2A01), - /**< Appearance. */ - BLE_ATT_CHAR_PRIVACY_FLAG = BLE_ATT_UUID_16(0x2A02), - /**< Privacy flag. */ - BLE_ATT_CHAR_RECONNECTION_ADDR = BLE_ATT_UUID_16(0x2A03), - /**< Reconnection address. */ - BLE_ATT_CHAR_PERIPH_PREF_CON_PARAM = BLE_ATT_UUID_16(0x2A04), - /**< Peripheral preferred connection parameters. */ - BLE_ATT_CHAR_SERVICE_CHANGED = BLE_ATT_UUID_16(0x2A05), - /**< Service handles changed. */ - BLE_ATT_CHAR_ALERT_LEVEL = BLE_ATT_UUID_16(0x2A06), - /**< Alert Level characteristic. */ - BLE_ATT_CHAR_TX_POWER_LEVEL = BLE_ATT_UUID_16(0x2A07), - /**< Tx Power Level. */ - BLE_ATT_CHAR_DATE_TIME = BLE_ATT_UUID_16(0x2A08), - /**< Date Time. */ - BLE_ATT_CHAR_DAY_WEEK = BLE_ATT_UUID_16(0x2A09), - /**< Day of Week. */ - BLE_ATT_CHAR_DAY_DATE_TIME = BLE_ATT_UUID_16(0x2A0A), - /**< Day Date Time. */ - BLE_ATT_CHAR_EXACT_TIME_256 = BLE_ATT_UUID_16(0x2A0C), - /**< Exact time 256. */ - BLE_ATT_CHAR_DST_OFFSET = BLE_ATT_UUID_16(0x2A0D), - /**< DST Offset. */ - BLE_ATT_CHAR_TIME_ZONE = BLE_ATT_UUID_16(0x2A0E), - /**< Time zone. */ - BLE_ATT_CHAR_LOCAL_TIME_INFO = BLE_ATT_UUID_16(0x2A0F), - /**< Local time Information. */ - BLE_ATT_CHAR_TIME_WITH_DST = BLE_ATT_UUID_16(0x2A11), - /**< Time with DST. */ - BLE_ATT_CHAR_TIME_ACCURACY = BLE_ATT_UUID_16(0x2A12), - /**< Time Accuracy. */ - BLE_ATT_CHAR_TIME_SOURCE = BLE_ATT_UUID_16(0x2A13), - /**< Time Source. */ - BLE_ATT_CHAR_REFERENCE_TIME_INFO = BLE_ATT_UUID_16(0x2A14), - /**< Reference Time Information. */ - BLE_ATT_CHAR_TIME_UPDATE_CNTL_POINT = BLE_ATT_UUID_16(0x2A16), - /**< Time Update Control Point. */ - BLE_ATT_CHAR_TIME_UPDATE_STATE = BLE_ATT_UUID_16(0x2A17), - /**< Time Update State. */ - BLE_ATT_CHAR_GLUCOSE_MEAS = BLE_ATT_UUID_16(0x2A18), - /**< Glucose Measurement. */ - BLE_ATT_CHAR_BATTERY_LEVEL = BLE_ATT_UUID_16(0x2A19), - /**< Battery Level. */ - BLE_ATT_CHAR_TEMPERATURE_MEAS = BLE_ATT_UUID_16(0x2A1C), - /**< Temperature Measurement. */ - BLE_ATT_CHAR_TEMPERATURE_TYPE = BLE_ATT_UUID_16(0x2A1D), - /**< Temperature Type. */ - BLE_ATT_CHAR_INTERMED_TEMPERATURE = BLE_ATT_UUID_16(0x2A1E), - /**< Intermediate Temperature. */ - BLE_ATT_CHAR_MEAS_INTERVAL = BLE_ATT_UUID_16(0x2A21), - /**< Measurement Interval. */ - BLE_ATT_CHAR_BOOT_KB_IN_REPORT = BLE_ATT_UUID_16(0x2A22), - /**< Boot Keyboard Input Report. */ - BLE_ATT_CHAR_SYS_ID = BLE_ATT_UUID_16(0x2A23), - /**< System ID. */ - BLE_ATT_CHAR_MODEL_NB = BLE_ATT_UUID_16(0x2A24), - /**< Model Number String. */ - BLE_ATT_CHAR_SERIAL_NB = BLE_ATT_UUID_16(0x2A25), - /**< Serial Number String. */ - BLE_ATT_CHAR_FW_REV = BLE_ATT_UUID_16(0x2A26), - /**< Firmware Revision String. */ - BLE_ATT_CHAR_HW_REV = BLE_ATT_UUID_16(0x2A27), - /**< Hardware revision String. */ - BLE_ATT_CHAR_SW_REV = BLE_ATT_UUID_16(0x2A28), - /**< Software Revision String. */ - BLE_ATT_CHAR_MANUF_NAME = BLE_ATT_UUID_16(0x2A29), - /**< Manufacturer Name String. */ - BLE_ATT_CHAR_IEEE_CERTIF = BLE_ATT_UUID_16(0x2A2A), - /**< IEEE Regulatory Certification Data List. */ - BLE_ATT_CHAR_CT_TIME = BLE_ATT_UUID_16(0x2A2B), - /**< CT Time. */ - BLE_ATT_CHAR_MAGN_DECLINE = BLE_ATT_UUID_16(0x2A2C), - /**< Magnetic Declination. */ - BLE_ATT_CHAR_SCAN_REFRESH = BLE_ATT_UUID_16(0x2A31), - /**< Scan Refresh. */ - BLE_ATT_CHAR_BOOT_KB_OUT_REPORT = BLE_ATT_UUID_16(0x2A32), - /**< Boot Keyboard Output Report. */ - BLE_ATT_CHAR_BOOT_MOUSE_IN_REPORT = BLE_ATT_UUID_16(0x2A33), - /**< Boot Mouse Input Report. */ - BLE_ATT_CHAR_GLUCOSE_MEAS_CTX = BLE_ATT_UUID_16(0x2A34), - /**< Glucose Measurement Context. */ - BLE_ATT_CHAR_BLOOD_PRESSURE_MEAS = BLE_ATT_UUID_16(0x2A35), - /**< Blood Pressure Measurement. */ - BLE_ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE = BLE_ATT_UUID_16(0x2A36), - /**< Intermediate Cuff Pressure. */ - BLE_ATT_CHAR_HEART_RATE_MEAS = BLE_ATT_UUID_16(0x2A37), - /**< Heart Rate Measurement. */ - BLE_ATT_CHAR_BODY_SENSOR_LOCATION = BLE_ATT_UUID_16(0x2A38), - /**< Body Sensor Location. */ - BLE_ATT_CHAR_HEART_RATE_CNTL_POINT = BLE_ATT_UUID_16(0x2A39), - /**< Heart Rate Control Point. */ - BLE_ATT_CHAR_ALERT_STATUS = BLE_ATT_UUID_16(0x2A3F), - /**< Alert Status. */ - BLE_ATT_CHAR_RINGER_CNTL_POINT = BLE_ATT_UUID_16(0x2A40), - /**< Ringer Control Point. */ - BLE_ATT_CHAR_RINGER_SETTING = BLE_ATT_UUID_16(0x2A41), - /**< Ringer Setting. */ - BLE_ATT_CHAR_ALERT_CAT_ID_BIT_MASK = BLE_ATT_UUID_16(0x2A42), - /**< Alert Category ID Bit Mask. */ - BLE_ATT_CHAR_ALERT_CAT_ID = BLE_ATT_UUID_16(0x2A43), - /**< Alert Category ID. */ - BLE_ATT_CHAR_ALERT_NTF_CTNL_PT = BLE_ATT_UUID_16(0x2A44), - /**< Alert Notification Control Point. */ - BLE_ATT_CHAR_UNREAD_ALERT_STATUS = BLE_ATT_UUID_16(0x2A45), - /**< Unread Alert Status. */ - BLE_ATT_CHAR_NEW_ALERT = BLE_ATT_UUID_16(0x2A46), - /**< New Alert. */ - BLE_ATT_CHAR_SUP_NEW_ALERT_CAT = BLE_ATT_UUID_16(0x2A47), - /**< Supported New Alert Category. */ - BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT = BLE_ATT_UUID_16(0x2A48), - /**< Supported Unread Alert Category. */ - BLE_ATT_CHAR_BLOOD_PRESSURE_FEATURE = BLE_ATT_UUID_16(0x2A49), - /**< Blood Pressure Feature. */ - BLE_ATT_CHAR_HID_INFO = BLE_ATT_UUID_16(0x2A4A), - /**< HID Information. */ - BLE_ATT_CHAR_REPORT_MAP = BLE_ATT_UUID_16(0x2A4B), - /**< Report Map. */ - BLE_ATT_CHAR_HID_CTNL_PT = BLE_ATT_UUID_16(0x2A4C), - /**< HID Control Point. */ - BLE_ATT_CHAR_REPORT = BLE_ATT_UUID_16(0x2A4D), - /**< Report. */ - BLE_ATT_CHAR_PROTOCOL_MODE = BLE_ATT_UUID_16(0x2A4E), - /**< Protocol Mode. */ - BLE_ATT_CHAR_SCAN_INTV_WD = BLE_ATT_UUID_16(0x2A4F), - /**< Scan Interval Window. */ - BLE_ATT_CHAR_PNP_ID = BLE_ATT_UUID_16(0x2A50), - /**< PnP ID. */ - BLE_ATT_CHAR_GLUCOSE_FEATURE = BLE_ATT_UUID_16(0x2A51), - /**< Glucose Feature. */ - BLE_ATT_CHAR_REC_ACCESS_CTRL_PT = BLE_ATT_UUID_16(0x2A52), - /**< Record access control point. */ - BLE_ATT_CHAR_RSC_MEAS = BLE_ATT_UUID_16(0x2A53), - /**< RSC Measurement. */ - BLE_ATT_CHAR_RSC_FEAT = BLE_ATT_UUID_16(0x2A54), - /**< RSC Feature. */ - BLE_ATT_CHAR_SC_CNTL_PT = BLE_ATT_UUID_16(0x2A55), - /**< SC Control Point. */ - BLE_ATT_CHAR_CSC_MEAS = BLE_ATT_UUID_16(0x2A5B), - /**< CSC Measurement. */ - BLE_ATT_CHAR_CSC_FEAT = BLE_ATT_UUID_16(0x2A5C), - /**< CSC Feature. */ - BLE_ATT_CHAR_SENSOR_LOC = BLE_ATT_UUID_16(0x2A5D), - /**< Sensor Location. */ - BLE_ATT_CHAR_PLX_SPOT_CHECK_MEASUREMENT_LOC = BLE_ATT_UUID_16(0x2A5E), - /**< PLX Spot-Check Measurement. */ - BLE_ATT_CHAR_PLX_CONTINUOUS_MEASUREMENT_LOC = BLE_ATT_UUID_16(0x2A5F), - /**< PLX Continuous Measurement. */ - BLE_ATT_CHAR_PLX_FEATURES_LOC = BLE_ATT_UUID_16(0x2A60), - /**< PLX Features. */ - BLE_ATT_CHAR_CP_MEAS = BLE_ATT_UUID_16(0x2A63), - /**< CP Measurement. */ - BLE_ATT_CHAR_CP_VECTOR = BLE_ATT_UUID_16(0x2A64), - /**< CP Vector. */ - BLE_ATT_CHAR_CP_FEAT = BLE_ATT_UUID_16(0x2A65), - /**< CP Feature. */ - BLE_ATT_CHAR_CP_CNTL_PT = BLE_ATT_UUID_16(0x2A66), - /**< CP Control Point. */ - BLE_ATT_CHAR_LOC_SPEED = BLE_ATT_UUID_16(0x2A67), - /**< Location and Speed. */ - BLE_ATT_CHAR_NAVIGATION = BLE_ATT_UUID_16(0x2A68), - /**< Navigation. */ - BLE_ATT_CHAR_POS_QUALITY = BLE_ATT_UUID_16(0x2A69), - /**< Position Quality. */ - BLE_ATT_CHAR_LN_FEAT = BLE_ATT_UUID_16(0x2A6A), - /**< LN Feature. */ - BLE_ATT_CHAR_LN_CNTL_PT = BLE_ATT_UUID_16(0x2A6B), - /**< LN Control Point. */ - BLE_ATT_CHAR_ELEVATION = BLE_ATT_UUID_16(0x2A6C), - /**< Elevation. */ - BLE_ATT_CHAR_PRESSURE = BLE_ATT_UUID_16(0x2A6D), - /**< Pressure. */ - BLE_ATT_CHAR_TEMPERATURE = BLE_ATT_UUID_16(0x2A6E), - /**< Temperature. */ - BLE_ATT_CHAR_HUMIDITY = BLE_ATT_UUID_16(0x2A6F), - /**< Humidity. */ - BLE_ATT_CHAR_TRUE_WIND_SPEED = BLE_ATT_UUID_16(0x2A70), - /**< True Wind Speed. */ - BLE_ATT_CHAR_TRUE_WIND_DIR = BLE_ATT_UUID_16(0x2A71), - /**< True Wind Direction. */ - BLE_ATT_CHAR_APRNT_WIND_SPEED = BLE_ATT_UUID_16(0x2A72), - /**< Apparent Wind Speed. */ - BLE_ATT_CHAR_APRNT_WIND_DIRECTION = BLE_ATT_UUID_16(0x2A73), - /**< Apparent Wind Direction. */ - BLE_ATT_CHAR_GUST_FACTOR = BLE_ATT_UUID_16(0x2A74), - /**< Gust Factor. */ - BLE_ATT_CHAR_POLLEN_CONC = BLE_ATT_UUID_16(0x2A75), - /**< Pollen Concentration. */ - BLE_ATT_CHAR_UV_INDEX = BLE_ATT_UUID_16(0x2A76), - /**< UV Index. */ - BLE_ATT_CHAR_IRRADIANCE = BLE_ATT_UUID_16(0x2A77), - /**< Irradiance. */ - BLE_ATT_CHAR_RAINFALL = BLE_ATT_UUID_16(0x2A78), - /**< Rainfall. */ - BLE_ATT_CHAR_WIND_CHILL = BLE_ATT_UUID_16(0x2A79), - /**< Wind Chill. */ - BLE_ATT_CHAR_HEAT_INDEX = BLE_ATT_UUID_16(0x2A7A), - /**< Heat Index. */ - BLE_ATT_CHAR_DEW_POINT = BLE_ATT_UUID_16(0x2A7B), - /**< Dew Point. */ - BLE_ATT_CHAR_DESCRIPTOR_VALUE_CHANGED = BLE_ATT_UUID_16(0x2A7D), - /**< Descriptor Value Changed. */ - BLE_ATT_CHAR_AEROBIC_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A7E), - /**< Aerobic Heart Rate Lower Limit. */ - BLE_ATT_CHAR_AEROBIC_THRESHOLD = BLE_ATT_UUID_16(0x2A7F), - /**< Aerobic Threshold. */ - BLE_ATT_CHAR_AGE = BLE_ATT_UUID_16(0x2A80), - /**< Age. */ - BLE_ATT_CHAR_ANAEROBIC_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A81), - /**< Anaerobic Heart Rate Lower Limit. */ - BLE_ATT_CHAR_ANAEROBIC_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A82), - /**< Anaerobic Heart Rate Upper Limit. */ - BLE_ATT_CHAR_ANAEROBIC_THRESHHOLD = BLE_ATT_UUID_16(0x2A83), - /**< Anaerobic Threshhold. */ - BLE_ATT_CHAR_AEROBIC_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A84), - /**< Aerobic Heart Rate Upper Limit. */ - BLE_ATT_CHAR_DATE_OF_BIRTH = BLE_ATT_UUID_16(0x2A85), - /**< Date of Birth. */ - BLE_ATT_CHAR_DATE_OF_THRESHOLD_ASSESSMENT = BLE_ATT_UUID_16(0x2A86), - /**< Date of Threshold Assessment. */ - BLE_ATT_CHAR_EMAIL_ADDRESS = BLE_ATT_UUID_16(0x2A87), - /**< Email Address. */ - BLE_ATT_CHAR_FAT_BURN_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A88), - /**< Fat Burn Heart Rate Lower Limit. */ - BLE_ATT_CHAR_FAT_BURN_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A89), - /**< Fat Burn Heart Rate Upper Limit. */ - BLE_ATT_CHAR_FIRST_NAME = BLE_ATT_UUID_16(0x2A8A), - /**< First Name. */ - BLE_ATT_CHAR_FIVE_ZONE_HEART_RATE_LIMITS = BLE_ATT_UUID_16(0x2A8B), - /**< Five Zone Heart Rate Limits. */ - BLE_ATT_CHAR_GENDER = BLE_ATT_UUID_16(0x2A8C), - /**< Gender. */ - BLE_ATT_CHAR_MAX_HEART_RATE = BLE_ATT_UUID_16(0x2A8D), - /**< Max Heart Rate. */ - BLE_ATT_CHAR_HEIGHT = BLE_ATT_UUID_16(0x2A8E), - /**< Height. */ - BLE_ATT_CHAR_HIP_CIRCUMFERENCE = BLE_ATT_UUID_16(0x2A8F), - /**< Hip Circumference. */ - BLE_ATT_CHAR_LAST_NAME = BLE_ATT_UUID_16(0x2A90), - /**< Last Name. */ - BLE_ATT_CHAR_MAXIMUM_RECOMMENDED_HEART_RATE = BLE_ATT_UUID_16(0x2A91), - /**< Maximum Recommended Heart Rate. */ - BLE_ATT_CHAR_RESTING_HEART_RATE = BLE_ATT_UUID_16(0x2A92), - /**< Resting Heart Rate. */ - BLE_ATT_CHAR_SPORT_TYPE_FOR_AEROBIC_AND_ANAEROBIC_THRESHOLDS = BLE_ATT_UUID_16(0x2A93), - /**< Sport Type For Aerobic And Anaerobic Thresholds. */ - BLE_ATT_CHAR_THREE_ZONE_HEART_RATE_LIMITS = BLE_ATT_UUID_16(0x2A94), - /**< Three Zone Heart Rate Limits. */ - BLE_ATT_CHAR_TWO_ZONE_HEART_RATE_LIMIT = BLE_ATT_UUID_16(0x2A95), - /**< Two Zone Heart Rate Limits. */ - BLE_ATT_CHAR_VO2_MAX = BLE_ATT_UUID_16(0x2A96), - /**< Vo2 Max. */ - BLE_ATT_CHAR_WAIST_CIRCUMFERENCE = BLE_ATT_UUID_16(0x2A97), - /**< Waist Circumference. */ - BLE_ATT_CHAR_WEIGHT = BLE_ATT_UUID_16(0x2A98), - /**< Weight. */ - BLE_ATT_CHAR_DATABASE_CHANGE_INCREMENT = BLE_ATT_UUID_16(0x2A99), - /**< Database Change Increment. */ - BLE_ATT_CHAR_USER_INDEX = BLE_ATT_UUID_16(0x2A9A), - /**< User Index. */ - BLE_ATT_CHAR_BODY_COMPOSITION_FEATURE = BLE_ATT_UUID_16(0x2A9B), - /**< Body Composition Feature. */ - BLE_ATT_CHAR_BODY_COMPOSITION_MEASUREMENT = BLE_ATT_UUID_16(0x2A9C), - /**< Body Composition Measurement. */ - BLE_ATT_CHAR_WEIGHT_MEASUREMENT = BLE_ATT_UUID_16(0x2A9D), - /**< Weight Measurement. */ - BLE_ATT_CHAR_WEIGHT_SCALE_FEATURE = BLE_ATT_UUID_16(0x2A9E), - /**< Weight Scale Feature. */ - BLE_ATT_CHAR_USER_CONTROL_POINT = BLE_ATT_UUID_16(0x2A9F), - /**< User Control Point. */ - BLE_ATT_CHAR_MAGN_FLUX_2D = BLE_ATT_UUID_16(0x2AA0), - /**< Flux Density - 2D. */ - BLE_ATT_CHAR_MAGN_FLUX_3D = BLE_ATT_UUID_16(0x2AA1), - /**< Magnetic Flux Density - 3D. */ - BLE_ATT_CHAR_LANGUAGE = BLE_ATT_UUID_16(0x2AA2), - /**< Language string. */ - BLE_ATT_CHAR_BAR_PRES_TREND = BLE_ATT_UUID_16(0x2AA3), - /**< Barometric Pressure Trend. */ - BLE_ATT_CHAR_CTL_ADDR_RESOL_SUPP = BLE_ATT_UUID_16(0x2AA6), - /**< Central Address Resolution Support. */ - BLE_ATT_CHAR_OTS_FEATURES = BLE_ATT_UUID_16(0x2ABD), - /**< OTS Service Feature. */ - BLE_ATT_CHAR_OTS_OBJECT_NAME = BLE_ATT_UUID_16(0x2ABE), - /**< Object Name. */ - BLE_ATT_CHAR_OTS_OBJECT_TYPE = BLE_ATT_UUID_16(0x2ABF), - /**< Object Type. */ - BLE_ATT_CHAR_OTS_OBJECT_SIZE = BLE_ATT_UUID_16(0x2AC0), - /**< Object Size. */ - BLE_ATT_CHAR_OTS_OBJECT_FIRST_CREATED = BLE_ATT_UUID_16(0x2AC1), - /**< Object First Created. */ - BLE_ATT_CHAR_OTS_OBJECT_LAST_MODIFIED = BLE_ATT_UUID_16(0x2AC2), - /**< Object Last Modified. */ - BLE_ATT_CHAR_OTS_OBJECT_ID = BLE_ATT_UUID_16(0x2AC3), - /**< Object ID. */ - BLE_ATT_CHAR_OTS_OBJECT_PROPERTIES = BLE_ATT_UUID_16(0x2AC4), - /**< Object Properties. */ - BLE_ATT_CHAR_OTS_OACP = BLE_ATT_UUID_16(0x2AC5), - /**< Object Action Control Point. */ - BLE_ATT_CHAR_OTS_OLCP = BLE_ATT_UUID_16(0x2AC6), - /**< Object List Control Point. */ - BLE_ATT_CHAR_OTS_LF = BLE_ATT_UUID_16(0x2AC7), - /**< Object List Filter. */ - BLE_ATT_CHAR_OTS_OBJECT_CHANGED = BLE_ATT_UUID_16(0x2AC8), - /**< Object Changed. */ - BLE_ATT_CHAR_RSLV_PRIV_ADDR_ONLY = BLE_ATT_UUID_16(0x2AC9), - /**< Resolvable Private Address only. */ - - BLE_ATT_CHAR_UNSPECIFIED = BLE_ATT_UUID_16(0X2ACA), - /**< Unspecified. */ - BLE_ATT_CHAR_DIRE_LISTING = BLE_ATT_UUID_16(0X2ACB), - /**< Directory Listing. */ - BLE_ATT_CHAR_FIT_MACH_FEAT = BLE_ATT_UUID_16(0X2ACC), - /**< Fitness Machine Feature. */ - BLE_ATT_CHAR_TREADMILL_DATA = BLE_ATT_UUID_16(0X2ACD), - /**< Treadmill Data. */ - BLE_ATT_CHAR_CROSS_TRAINER_DATA = BLE_ATT_UUID_16(0X2ACE), - /**< Cross Trainer Data. */ - BLE_ATT_CHAR_STEP_CLIMBER_DATA = BLE_ATT_UUID_16(0X2ACF), - /**< Step Climber Data. */ - BLE_ATT_CHAR_STSIR_CLIMBER_DATA = BLE_ATT_UUID_16(0X2AD0), - /**< Stair Climber Data. */ - BLE_ATT_CHAR_ROWER_DATA = BLE_ATT_UUID_16(0X2AD1), - /**< Rower Data. */ - BLE_ATT_CHAR_INDOOR_BIKE_DATA = BLE_ATT_UUID_16(0X2AD2), - /**< Indoor Bike Data. */ - BLE_ATT_CHAR_TRAIN_STATUS = BLE_ATT_UUID_16(0X2AD3), - /**< Training Status. */ - BLE_ATT_CHAR_SUP_SPEED_RANGE = BLE_ATT_UUID_16(0X2AD4), - /**< Supported Speed Range. */ - BLE_ATT_CHAR_SUP_INCL_RANGE = BLE_ATT_UUID_16(0X2AD5), - /**< Supported Inclination Range. */ - BLE_ATT_CHAR_SUP_RESIST_LEVEL_RANGE = BLE_ATT_UUID_16(0X2AD6), - /**< Supported Resistance Level Range. */ - BLE_ATT_CHAR_SUP_HEART_RATE_RANGE = BLE_ATT_UUID_16(0X2AD7), - /**< Supported Heart Rate Range. */ - BLE_ATT_CHAR_SUP_POWER_RANGE = BLE_ATT_UUID_16(0X2AD8), - /**< Supported Power Range. */ - BLE_ATT_CHAR_FIT_MACH_CNTL_PT = BLE_ATT_UUID_16(0X2AD9), - /**< Fitness Machine Control Point. */ - BLE_ATT_CHAR_FIT_MACH_STATUS = BLE_ATT_UUID_16(0X2ADA), - /**< Fitness Machine Status. */ - BLE_ATT_CHAR_MESH_PROV_DATA_IN = BLE_ATT_UUID_16(0X2ADB), - /**< Mesh Provisioning Data In. */ - BLE_ATT_CHAR_MESH_PROV_DATA_OUT = BLE_ATT_UUID_16(0X2ADC), - /**< Mesh Provisioning Data Out. */ - BLE_ATT_CHAR_MESH_PROX_DATA_IN = BLE_ATT_UUID_16(0X2ADD), - /**< Mesh Proxy Data In. */ - BLE_ATT_CHAR_MESH_PROX_DATA_OUT = BLE_ATT_UUID_16(0X2ADE), - /**< Mesh Proxy Data Out. */ - BLE_ATT_CHAR_AVG_CURRENT = BLE_ATT_UUID_16(0X2AE0), - /**< Average Current. */ - BLE_ATT_CHAR_AVG_VOLTAGE = BLE_ATT_UUID_16(0X2AE1), - /**< Average Voltage. */ - BLE_ATT_CHAR_BOOLEAN = BLE_ATT_UUID_16(0X2AE2), - /**< Boolean. */ - BLE_ATT_CHAR_CHROM_DIST_FROM_PLANCKIAN = BLE_ATT_UUID_16(0X2AE3), - /**< Chromatic Distance From Planckian. */ - BLE_ATT_CHAR_CHROM_COORD = BLE_ATT_UUID_16(0X2AE4), - /**< Chromaticity Coordinates. */ - BLE_ATT_CHAR_CHORM_IN_CCT_AND_DUV_VAL = BLE_ATT_UUID_16(0X2AE5), - /**< Chromaticity in CCT And Duv Values. */ - BLE_ATT_CHAR_CHROM_TOLERANCE = BLE_ATT_UUID_16(0X2AE6), - /**< Chromaticity Tolerance. */ - BLE_ATT_CHAR_CIE_COLOR_REND_IDX = BLE_ATT_UUID_16(0X2AE7), - /**< CIE 13.3-1995 Color Rendering Index. */ - BLE_ATT_CHAR_COEFFICIENT = BLE_ATT_UUID_16(0X2AE8), - /**< Coefficient. */ - BLE_ATT_CHAR_CORRELA_COLOR_TEMP = BLE_ATT_UUID_16(0X2AE9), - /**< Correlated Color Temperature. */ - BLE_ATT_CHAR_COUNT_SIXTEEN = BLE_ATT_UUID_16(0X2AEA), - /**< Count 16. */ - BLE_ATT_CHAR_COUNT_TWENTY_FOUR = BLE_ATT_UUID_16(0X2AEB), - /**< Count 24. */ - BLE_ATT_CHAR_COUNTRY_CODE = BLE_ATT_UUID_16(0X2AEC), - /**< Country Code. */ - BLE_ATT_CHAR_DATE_UTC = BLE_ATT_UUID_16(0X2AED), - /**< Date UTC. */ - BLE_ATT_CHAR_ELEC_CURRENT = BLE_ATT_UUID_16(0X2AEE), - /**< Electric Current. */ - BLE_ATT_CHAR_ELEC_CURRENT_RANGE = BLE_ATT_UUID_16(0X2AEF), - /**< Electric Current Range. */ - BLE_ATT_CHAR_ELEC_CURRENT_SPEC = BLE_ATT_UUID_16(0X2AF0), - /**< Electric Current Specification. */ - BLE_ATT_CHAR_ELEC_CURRENT_STATIS = BLE_ATT_UUID_16(0X2AF1), - /**< Electric Current Statistics. */ - BLE_ATT_CHAR_ENERGY = BLE_ATT_UUID_16(0X2AF2), - /**< Energy. */ - BLE_ATT_CHAR_ENERGY_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2AF3), - /**< Energy In A Period Of Day. */ - BLE_ATT_CHAR_EVENT_STATIC = BLE_ATT_UUID_16(0X2AF4), - /**< Event Statistics. */ - BLE_ATT_CHAR_FIXED_STR_SIXTEEN = BLE_ATT_UUID_16(0X2AF5), - /**< Fixed String 16. */ - BLE_ATT_CHAR_FIXED_STR_TWENTY_FOUR = BLE_ATT_UUID_16(0X2AF6), - /**< Fixed String 24. */ - BLE_ATT_CHAR_FIXED_STR_THIRTY_SIX = BLE_ATT_UUID_16(0X2AF7), - /**< Fixed String 36. */ - BLE_ATT_CHAR_FIXED_STR_EIGHT = BLE_ATT_UUID_16(0X2AF8), - /**< Fixed String 8. */ - BLE_ATT_CHAR_GENERIC_LEVEL = BLE_ATT_UUID_16(0X2AF9), - /**< Generic Level. */ - BLE_ATT_CHAR_GLOB_TRADE_ITEM_NUM = BLE_ATT_UUID_16(0X2AFA), - /**< Global Trade Item Number. */ - BLE_ATT_CHAR_ILLUMINANCE = BLE_ATT_UUID_16(0X2AFB), - /**< Illuminance. */ - BLE_ATT_CHAR_LUMI_EFFICACY = BLE_ATT_UUID_16(0X2AFC), - /**< Luminous Efficacy. */ - BLE_ATT_CHAR_LUMI_ENERGY = BLE_ATT_UUID_16(0X2AFD), - /**< Luminous Energy. */ - BLE_ATT_CHAR_LUMI_EXPOSURE = BLE_ATT_UUID_16(0X2AFE), - /**< Luminous Exposure. */ - BLE_ATT_CHAR_LUMI_FLUX = BLE_ATT_UUID_16(0X2AFE), - /**< Luminous Flux. */ - BLE_ATT_CHAR_LUMI_FLUX_RANGE = BLE_ATT_UUID_16(0X2B00), - /**< Luminous Flux Range. */ - BLE_ATT_CHAR_LUMI_INTENS = BLE_ATT_UUID_16(0X2B01), - /**< Luminous Intensity. */ - BLE_ATT_CHAR_MASS_FLOW = BLE_ATT_UUID_16(0X2B02), - /**< Mass Flow. */ - BLE_ATT_CHAR_PERCEIVED_LIGHT = BLE_ATT_UUID_16(0X2B03), - /**< Perceived Lightness. */ - BLE_ATT_CHAR_PERC_EIGHT = BLE_ATT_UUID_16(0X2B04), - /**< Percentage 8. */ - BLE_ATT_CHAR_POWER = BLE_ATT_UUID_16(0X2B05), - /**< Power. */ - BLE_ATT_CHAR_POWER_SPEC = BLE_ATT_UUID_16(0X2B06), - /**< Power Specification. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_CUR_RANGE = BLE_ATT_UUID_16(0X2B07), - /**< Relative Runtime In A Current Range. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_GEN_LEVEL_RANGE = BLE_ATT_UUID_16(0X2B08), - /**< Relative Runtime In A Generic Level Range. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_VOLT_RANGE = BLE_ATT_UUID_16(0X2B09), - /**< Relative Value In A Voltage Range. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_ILLUM_RANGE = BLE_ATT_UUID_16(0X2B0A), - /**< Relative Value In An Illuminance Range. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2B0B), - /**< Relative Value In A Period Of Day. */ - BLE_ATT_CHAR_RELAT_RUNTIME_IN_TEMP_RANGE = BLE_ATT_UUID_16(0X2B0C), - /**< Relative Value In A Temperature Range. */ - BLE_ATT_CHAR_TEMP_EIGHT = BLE_ATT_UUID_16(0X2B0D), - /**< Temperature 8. */ - BLE_ATT_CHAR_TEMP_EIGHT_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2B0E), - /**< Temperature 8 In A Period Of Day. */ - BLE_ATT_CHAR_TEMP_EIGHT_STATIS = BLE_ATT_UUID_16(0X2B0F), - /**< Temperature 8 Statistics. */ - BLE_ATT_CHAR_TEMP_RANGE = BLE_ATT_UUID_16(0X2B10), - /**< Temperature Range. */ - BLE_ATT_CHAR_TEMP_STATIS = BLE_ATT_UUID_16(0X2B11), - /**< Temperature Statistics. */ - BLE_ATT_CHAR_TIME_DECI_EIGHT = BLE_ATT_UUID_16(0X2B12), - /**< Time Decihour 8. */ - BLE_ATT_CHAR_TIME_EXPON_EIGHT = BLE_ATT_UUID_16(0X2B13), - /**< Time Exponential 8. */ - BLE_ATT_CHAR_TIME_HOUR_TWENTY_FOUR = BLE_ATT_UUID_16(0X2B14), - /**< Time Hour 24. */ - BLE_ATT_CHAR_TIME_MS_TWENTY_FOUR = BLE_ATT_UUID_16(0X2B15), - /**< Time Millisecond 24. */ - BLE_ATT_CHAR_TIME_SEC_SIXTEEN = BLE_ATT_UUID_16(0X2B16), - /**< Time Second 16. */ - BLE_ATT_CHAR_TIME_SEC_EIGHT = BLE_ATT_UUID_16(0X2B17), - /**< Time Second 8. */ - BLE_ATT_CHAR_VOLTAGE = BLE_ATT_UUID_16(0X2B18), - /**< Voltage. */ - BLE_ATT_CHAR_VOLTAGE_SPEC = BLE_ATT_UUID_16(0X2B19), - /**< Voltage Specification. */ - BLE_ATT_CHAR_VOLTAGE_STATIS = BLE_ATT_UUID_16(0X2B1A), - /**< Voltage Statistics. */ - BLE_ATT_CHAR_VOLUME_FLOW = BLE_ATT_UUID_16(0X2B1B), - /**< Volume Flow. */ - BLE_ATT_CHAR_CHROM_COORDINATE = BLE_ATT_UUID_16(0X2B1C), - /**< Chromaticity Coordinate. */ - - BLE_ATT_CHAR_RC_FEAT = BLE_ATT_UUID_16(0x2B1D), - /**< RC Feature. */ - BLE_ATT_CHAR_RC_SETTINGS = BLE_ATT_UUID_16(0x2B1E), - /**< RC Settings. */ - BLE_ATT_CHAR_RECONNEC_CONFIG_CNTL_PT = BLE_ATT_UUID_16(0x2B1F), - /**< Reconnection Configuration Control Point. */ - BLE_ATT_CHAR_IDD_STATUS_CHANGED = BLE_ATT_UUID_16(0x2B20), - /**< IDD Status Changed. */ - BLE_ATT_CHAR_IDD_STATUS = BLE_ATT_UUID_16(0x2B21), - /**< IDD Status. */ - BLE_ATT_CHAR_IDD_ANNU_STATUS = BLE_ATT_UUID_16(0x2B22), - /**< IDD Annunciation Status. */ - BLE_ATT_CHAR_IDD_FEAT = BLE_ATT_UUID_16(0x2B23), - /**< IDD Features. */ - BLE_ATT_CHAR_IDD_STATUS_READER_CNTL_PT = BLE_ATT_UUID_16(0x2B24), - /**< IDD Status Reader Control Point. */ - BLE_ATT_CHAR_IDD_COMMAND_CNTL_PT = BLE_ATT_UUID_16(0x2B25), - /**< IDD Command Control Point. */ - BLE_ATT_CHAR_IDD_COMMAND_DATA = BLE_ATT_UUID_16(0x2B26), - /**< IDD Command Data. */ - BLE_ATT_CHAR_IDD_RECORD_ACCESS_CNTL_PT = BLE_ATT_UUID_16(0x2B27), - /**< IDD Record Access Control Point. */ - BLE_ATT_CHAR_IDD_HISTORY_DATA = BLE_ATT_UUID_16(0x2B28), - /**< IDD History Data. */ - BLE_ATT_CHAR_CLI_SUP_FEAT = BLE_ATT_UUID_16(0x2B29), - /**< Client Supported Features. */ - BLE_ATT_CHAR_DB_HASH = BLE_ATT_UUID_16(0x2B2A), - /**< Database Hash. */ - BLE_ATT_CHAR_BSS_CNTL_PT = BLE_ATT_UUID_16(0x2B2B), - /**< BSS Control Point. */ - BLE_ATT_CHAR_BSS_RESPONSE = BLE_ATT_UUID_16(0x2B2C), - /**< BSS Response. */ - BLE_ATT_CHAR_EMERGENCY_ID = BLE_ATT_UUID_16(0x2B2D), - /**< Emergency ID. */ - BLE_ATT_CHAR_EMERGENCY_TEXT = BLE_ATT_UUID_16(0x2B2E), - /**< Emergency Text. */ - - BLE_ATT_CHAR_REGISTERED_USER = BLE_ATT_UUID_16(0x2B37), - /**< Registered User Characterisitc. */ - BLE_ATT_CHAR_SRV_SUP_FEAT = BLE_ATT_UUID_16(0x2B3A), - /**< Server Supported Features. */ -} att_uuid_t; + BLE_ATT_CHAR_DEVICE_NAME = BLE_ATT_UUID_16(0x2A00), /**< Device name. */ + BLE_ATT_CHAR_APPEARANCE = BLE_ATT_UUID_16(0x2A01), /**< Appearance. */ + BLE_ATT_CHAR_PRIVACY_FLAG = BLE_ATT_UUID_16(0x2A02), /**< Privacy flag. */ + BLE_ATT_CHAR_RECONNECTION_ADDR = BLE_ATT_UUID_16(0x2A03), /**< Reconnection address. */ + BLE_ATT_CHAR_PERIPH_PREF_CON_PARAM = BLE_ATT_UUID_16(0x2A04), /**< Peripheral preferred connection parameters. */ + BLE_ATT_CHAR_SERVICE_CHANGED = BLE_ATT_UUID_16(0x2A05), /**< Service handles changed. */ + BLE_ATT_CHAR_ALERT_LEVEL = BLE_ATT_UUID_16(0x2A06), /**< Alert Level characteristic. */ + BLE_ATT_CHAR_TX_POWER_LEVEL = BLE_ATT_UUID_16(0x2A07), /**< Tx Power Level. */ + BLE_ATT_CHAR_DATE_TIME = BLE_ATT_UUID_16(0x2A08), /**< Date Time. */ + BLE_ATT_CHAR_DAY_WEEK = BLE_ATT_UUID_16(0x2A09), /**< Day of Week. */ + BLE_ATT_CHAR_DAY_DATE_TIME = BLE_ATT_UUID_16(0x2A0A), /**< Day Date Time. */ + BLE_ATT_CHAR_EXACT_TIME_256 = BLE_ATT_UUID_16(0x2A0C), /**< Exact time 256. */ + BLE_ATT_CHAR_DST_OFFSET = BLE_ATT_UUID_16(0x2A0D), /**< DST Offset. */ + BLE_ATT_CHAR_TIME_ZONE = BLE_ATT_UUID_16(0x2A0E), /**< Time zone. */ + BLE_ATT_CHAR_LOCAL_TIME_INFO = BLE_ATT_UUID_16(0x2A0F), /**< Local time Information. */ + BLE_ATT_CHAR_TIME_WITH_DST = BLE_ATT_UUID_16(0x2A11), /**< Time with DST. */ + BLE_ATT_CHAR_TIME_ACCURACY = BLE_ATT_UUID_16(0x2A12), /**< Time Accuracy. */ + BLE_ATT_CHAR_TIME_SOURCE = BLE_ATT_UUID_16(0x2A13), /**< Time Source. */ + BLE_ATT_CHAR_REFERENCE_TIME_INFO = BLE_ATT_UUID_16(0x2A14), /**< Reference Time Information. */ + BLE_ATT_CHAR_TIME_UPDATE_CNTL_POINT = BLE_ATT_UUID_16(0x2A16), /**< Time Update Control Point. */ + BLE_ATT_CHAR_TIME_UPDATE_STATE = BLE_ATT_UUID_16(0x2A17), /**< Time Update State. */ + BLE_ATT_CHAR_GLUCOSE_MEAS = BLE_ATT_UUID_16(0x2A18), /**< Glucose Measurement. */ + BLE_ATT_CHAR_BATTERY_LEVEL = BLE_ATT_UUID_16(0x2A19), /**< Battery Level. */ + BLE_ATT_CHAR_TEMPERATURE_MEAS = BLE_ATT_UUID_16(0x2A1C), /**< Temperature Measurement. */ + BLE_ATT_CHAR_TEMPERATURE_TYPE = BLE_ATT_UUID_16(0x2A1D), /**< Temperature Type. */ + BLE_ATT_CHAR_INTERMED_TEMPERATURE = BLE_ATT_UUID_16(0x2A1E), /**< Intermediate Temperature. */ + BLE_ATT_CHAR_MEAS_INTERVAL = BLE_ATT_UUID_16(0x2A21), /**< Measurement Interval. */ + BLE_ATT_CHAR_BOOT_KB_IN_REPORT = BLE_ATT_UUID_16(0x2A22), /**< Boot Keyboard Input Report. */ + BLE_ATT_CHAR_SYS_ID = BLE_ATT_UUID_16(0x2A23), /**< System ID. */ + BLE_ATT_CHAR_MODEL_NB = BLE_ATT_UUID_16(0x2A24), /**< Model Number String. */ + BLE_ATT_CHAR_SERIAL_NB = BLE_ATT_UUID_16(0x2A25), /**< Serial Number String. */ + BLE_ATT_CHAR_FW_REV = BLE_ATT_UUID_16(0x2A26), /**< Firmware Revision String. */ + BLE_ATT_CHAR_HW_REV = BLE_ATT_UUID_16(0x2A27), /**< Hardware revision String. */ + BLE_ATT_CHAR_SW_REV = BLE_ATT_UUID_16(0x2A28), /**< Software Revision String. */ + BLE_ATT_CHAR_MANUF_NAME = BLE_ATT_UUID_16(0x2A29), /**< Manufacturer Name String. */ + BLE_ATT_CHAR_IEEE_CERTIF = BLE_ATT_UUID_16(0x2A2A), /**< IEEE Regulatory Certification Data List. */ + BLE_ATT_CHAR_CT_TIME = BLE_ATT_UUID_16(0x2A2B), /**< CT Time. */ + BLE_ATT_CHAR_MAGN_DECLINE = BLE_ATT_UUID_16(0x2A2C), /**< Magnetic Declination. */ + BLE_ATT_CHAR_SCAN_REFRESH = BLE_ATT_UUID_16(0x2A31), /**< Scan Refresh. */ + BLE_ATT_CHAR_BOOT_KB_OUT_REPORT = BLE_ATT_UUID_16(0x2A32), /**< Boot Keyboard Output Report. */ + BLE_ATT_CHAR_BOOT_MOUSE_IN_REPORT = BLE_ATT_UUID_16(0x2A33), /**< Boot Mouse Input Report. */ + BLE_ATT_CHAR_GLUCOSE_MEAS_CTX = BLE_ATT_UUID_16(0x2A34), /**< Glucose Measurement Context. */ + BLE_ATT_CHAR_BLOOD_PRESSURE_MEAS = BLE_ATT_UUID_16(0x2A35), /**< Blood Pressure Measurement. */ + BLE_ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE = BLE_ATT_UUID_16(0x2A36), /**< Intermediate Cuff Pressure. */ + BLE_ATT_CHAR_HEART_RATE_MEAS = BLE_ATT_UUID_16(0x2A37), /**< Heart Rate Measurement. */ + BLE_ATT_CHAR_BODY_SENSOR_LOCATION = BLE_ATT_UUID_16(0x2A38), /**< Body Sensor Location. */ + BLE_ATT_CHAR_HEART_RATE_CNTL_POINT = BLE_ATT_UUID_16(0x2A39), /**< Heart Rate Control Point. */ + BLE_ATT_CHAR_ALERT_STATUS = BLE_ATT_UUID_16(0x2A3F), /**< Alert Status. */ + BLE_ATT_CHAR_RINGER_CNTL_POINT = BLE_ATT_UUID_16(0x2A40), /**< Ringer Control Point. */ + BLE_ATT_CHAR_RINGER_SETTING = BLE_ATT_UUID_16(0x2A41), /**< Ringer Setting. */ + BLE_ATT_CHAR_ALERT_CAT_ID_BIT_MASK = BLE_ATT_UUID_16(0x2A42), /**< Alert Category ID Bit Mask. */ + BLE_ATT_CHAR_ALERT_CAT_ID = BLE_ATT_UUID_16(0x2A43), /**< Alert Category ID. */ + BLE_ATT_CHAR_ALERT_NTF_CTNL_PT = BLE_ATT_UUID_16(0x2A44), /**< Alert Notification Control Point. */ + BLE_ATT_CHAR_UNREAD_ALERT_STATUS = BLE_ATT_UUID_16(0x2A45), /**< Unread Alert Status. */ + BLE_ATT_CHAR_NEW_ALERT = BLE_ATT_UUID_16(0x2A46), /**< New Alert. */ + BLE_ATT_CHAR_SUP_NEW_ALERT_CAT = BLE_ATT_UUID_16(0x2A47), /**< Supported New Alert Category. */ + BLE_ATT_CHAR_SUP_UNREAD_ALERT_CAT = BLE_ATT_UUID_16(0x2A48), /**< Supported Unread Alert Category. */ + BLE_ATT_CHAR_BLOOD_PRESSURE_FEATURE = BLE_ATT_UUID_16(0x2A49), /**< Blood Pressure Feature. */ + BLE_ATT_CHAR_HID_INFO = BLE_ATT_UUID_16(0x2A4A), /**< HID Information. */ + BLE_ATT_CHAR_REPORT_MAP = BLE_ATT_UUID_16(0x2A4B), /**< Report Map. */ + BLE_ATT_CHAR_HID_CTNL_PT = BLE_ATT_UUID_16(0x2A4C), /**< HID Control Point. */ + BLE_ATT_CHAR_REPORT = BLE_ATT_UUID_16(0x2A4D), /**< Report. */ + BLE_ATT_CHAR_PROTOCOL_MODE = BLE_ATT_UUID_16(0x2A4E), /**< Protocol Mode. */ + BLE_ATT_CHAR_SCAN_INTV_WD = BLE_ATT_UUID_16(0x2A4F), /**< Scan Interval Window. */ + BLE_ATT_CHAR_PNP_ID = BLE_ATT_UUID_16(0x2A50), /**< PnP ID. */ + BLE_ATT_CHAR_GLUCOSE_FEATURE = BLE_ATT_UUID_16(0x2A51), /**< Glucose Feature. */ + BLE_ATT_CHAR_REC_ACCESS_CTRL_PT = BLE_ATT_UUID_16(0x2A52), /**< Record access control point. */ + BLE_ATT_CHAR_RSC_MEAS = BLE_ATT_UUID_16(0x2A53), /**< RSC Measurement. */ + BLE_ATT_CHAR_RSC_FEAT = BLE_ATT_UUID_16(0x2A54), /**< RSC Feature. */ + BLE_ATT_CHAR_SC_CNTL_PT = BLE_ATT_UUID_16(0x2A55), /**< SC Control Point. */ + BLE_ATT_CHAR_CSC_MEAS = BLE_ATT_UUID_16(0x2A5B), /**< CSC Measurement. */ + BLE_ATT_CHAR_CSC_FEAT = BLE_ATT_UUID_16(0x2A5C), /**< CSC Feature. */ + BLE_ATT_CHAR_SENSOR_LOC = BLE_ATT_UUID_16(0x2A5D), /**< Sensor Location. */ + BLE_ATT_CHAR_PLX_SPOT_CHECK_MEASUREMENT_LOC = BLE_ATT_UUID_16(0x2A5E), /**< PLX Spot-Check Measurement. */ + BLE_ATT_CHAR_PLX_CONTINUOUS_MEASUREMENT_LOC = BLE_ATT_UUID_16(0x2A5F), /**< PLX Continuous Measurement. */ + BLE_ATT_CHAR_PLX_FEATURES_LOC = BLE_ATT_UUID_16(0x2A60), /**< PLX Features. */ + BLE_ATT_CHAR_CP_MEAS = BLE_ATT_UUID_16(0x2A63), /**< CP Measurement. */ + BLE_ATT_CHAR_CP_VECTOR = BLE_ATT_UUID_16(0x2A64), /**< CP Vector. */ + BLE_ATT_CHAR_CP_FEAT = BLE_ATT_UUID_16(0x2A65), /**< CP Feature. */ + BLE_ATT_CHAR_CP_CNTL_PT = BLE_ATT_UUID_16(0x2A66), /**< CP Control Point. */ + BLE_ATT_CHAR_LOC_SPEED = BLE_ATT_UUID_16(0x2A67), /**< Location and Speed. */ + BLE_ATT_CHAR_NAVIGATION = BLE_ATT_UUID_16(0x2A68), /**< Navigation. */ + BLE_ATT_CHAR_POS_QUALITY = BLE_ATT_UUID_16(0x2A69), /**< Position Quality. */ + BLE_ATT_CHAR_LN_FEAT = BLE_ATT_UUID_16(0x2A6A), /**< LN Feature. */ + BLE_ATT_CHAR_LN_CNTL_PT = BLE_ATT_UUID_16(0x2A6B), /**< LN Control Point. */ + BLE_ATT_CHAR_ELEVATION = BLE_ATT_UUID_16(0x2A6C), /**< Elevation. */ + BLE_ATT_CHAR_PRESSURE = BLE_ATT_UUID_16(0x2A6D), /**< Pressure. */ + BLE_ATT_CHAR_TEMPERATURE = BLE_ATT_UUID_16(0x2A6E), /**< Temperature. */ + BLE_ATT_CHAR_HUMIDITY = BLE_ATT_UUID_16(0x2A6F), /**< Humidity. */ + BLE_ATT_CHAR_TRUE_WIND_SPEED = BLE_ATT_UUID_16(0x2A70), /**< True Wind Speed. */ + BLE_ATT_CHAR_TRUE_WIND_DIR = BLE_ATT_UUID_16(0x2A71), /**< True Wind Direction. */ + BLE_ATT_CHAR_APRNT_WIND_SPEED = BLE_ATT_UUID_16(0x2A72), /**< Apparent Wind Speed. */ + BLE_ATT_CHAR_APRNT_WIND_DIRECTION = BLE_ATT_UUID_16(0x2A73), /**< Apparent Wind Direction. */ + BLE_ATT_CHAR_GUST_FACTOR = BLE_ATT_UUID_16(0x2A74), /**< Gust Factor. */ + BLE_ATT_CHAR_POLLEN_CONC = BLE_ATT_UUID_16(0x2A75), /**< Pollen Concentration. */ + BLE_ATT_CHAR_UV_INDEX = BLE_ATT_UUID_16(0x2A76), /**< UV Index. */ + BLE_ATT_CHAR_IRRADIANCE = BLE_ATT_UUID_16(0x2A77), /**< Irradiance. */ + BLE_ATT_CHAR_RAINFALL = BLE_ATT_UUID_16(0x2A78), /**< Rainfall. */ + BLE_ATT_CHAR_WIND_CHILL = BLE_ATT_UUID_16(0x2A79), /**< Wind Chill. */ + BLE_ATT_CHAR_HEAT_INDEX = BLE_ATT_UUID_16(0x2A7A), /**< Heat Index. */ + BLE_ATT_CHAR_DEW_POINT = BLE_ATT_UUID_16(0x2A7B), /**< Dew Point. */ + BLE_ATT_CHAR_DESCRIPTOR_VALUE_CHANGED = BLE_ATT_UUID_16(0x2A7D), /**< Descriptor Value Changed. */ + BLE_ATT_CHAR_AEROBIC_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A7E), /**< Aerobic Heart Rate Lower Limit. */ + BLE_ATT_CHAR_AEROBIC_THRESHOLD = BLE_ATT_UUID_16(0x2A7F), /**< Aerobic Threshold. */ + BLE_ATT_CHAR_AGE = BLE_ATT_UUID_16(0x2A80), /**< Age. */ + BLE_ATT_CHAR_ANAEROBIC_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A81), /**< Anaerobic Heart Rate Lower Limit. */ + BLE_ATT_CHAR_ANAEROBIC_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A82), /**< Anaerobic Heart Rate Upper Limit. */ + BLE_ATT_CHAR_ANAEROBIC_THRESHHOLD = BLE_ATT_UUID_16(0x2A83), /**< Anaerobic Threshhold. */ + BLE_ATT_CHAR_AEROBIC_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A84), /**< Aerobic Heart Rate Upper Limit. */ + BLE_ATT_CHAR_DATE_OF_BIRTH = BLE_ATT_UUID_16(0x2A85), /**< Date of Birth. */ + BLE_ATT_CHAR_DATE_OF_THRESHOLD_ASSESSMENT = BLE_ATT_UUID_16(0x2A86), /**< Date of Threshold Assessment. */ + BLE_ATT_CHAR_EMAIL_ADDRESS = BLE_ATT_UUID_16(0x2A87), /**< Email Address. */ + BLE_ATT_CHAR_FAT_BURN_HEART_RATE_LOWER_LIMIT = BLE_ATT_UUID_16(0x2A88), /**< Fat Burn Heart Rate Lower Limit. */ + BLE_ATT_CHAR_FAT_BURN_HEART_RATE_UPPER_LIMIT = BLE_ATT_UUID_16(0x2A89), /**< Fat Burn Heart Rate Upper Limit. */ + BLE_ATT_CHAR_FIRST_NAME = BLE_ATT_UUID_16(0x2A8A), /**< First Name. */ + BLE_ATT_CHAR_FIVE_ZONE_HEART_RATE_LIMITS = BLE_ATT_UUID_16(0x2A8B), /**< Five Zone Heart Rate Limits. */ + BLE_ATT_CHAR_GENDER = BLE_ATT_UUID_16(0x2A8C), /**< Gender. */ + BLE_ATT_CHAR_MAX_HEART_RATE = BLE_ATT_UUID_16(0x2A8D), /**< Max Heart Rate. */ + BLE_ATT_CHAR_HEIGHT = BLE_ATT_UUID_16(0x2A8E), /**< Height. */ + BLE_ATT_CHAR_HIP_CIRCUMFERENCE = BLE_ATT_UUID_16(0x2A8F), /**< Hip Circumference. */ + BLE_ATT_CHAR_LAST_NAME = BLE_ATT_UUID_16(0x2A90), /**< Last Name. */ + BLE_ATT_CHAR_MAXIMUM_RECOMMENDED_HEART_RATE = BLE_ATT_UUID_16(0x2A91), /**< Maximum Recommended Heart Rate. */ + BLE_ATT_CHAR_RESTING_HEART_RATE = BLE_ATT_UUID_16(0x2A92), /**< Resting Heart Rate. */ + BLE_ATT_CHAR_SPORT_TYPE_FOR_AEROBIC_AND_ANAEROBIC_THRESHOLDS = BLE_ATT_UUID_16(0x2A93), /**< Sport Type For Aerobic And Anaerobic Thresholds. */ + BLE_ATT_CHAR_THREE_ZONE_HEART_RATE_LIMITS = BLE_ATT_UUID_16(0x2A94), /**< Three Zone Heart Rate Limits. */ + BLE_ATT_CHAR_TWO_ZONE_HEART_RATE_LIMIT = BLE_ATT_UUID_16(0x2A95), /**< Two Zone Heart Rate Limits. */ + BLE_ATT_CHAR_VO2_MAX = BLE_ATT_UUID_16(0x2A96), /**< Vo2 Max. */ + BLE_ATT_CHAR_WAIST_CIRCUMFERENCE = BLE_ATT_UUID_16(0x2A97), /**< Waist Circumference. */ + BLE_ATT_CHAR_WEIGHT = BLE_ATT_UUID_16(0x2A98), /**< Weight. */ + BLE_ATT_CHAR_DATABASE_CHANGE_INCREMENT = BLE_ATT_UUID_16(0x2A99), /**< Database Change Increment. */ + BLE_ATT_CHAR_USER_INDEX = BLE_ATT_UUID_16(0x2A9A), /**< User Index. */ + BLE_ATT_CHAR_BODY_COMPOSITION_FEATURE = BLE_ATT_UUID_16(0x2A9B), /**< Body Composition Feature. */ + BLE_ATT_CHAR_BODY_COMPOSITION_MEASUREMENT = BLE_ATT_UUID_16(0x2A9C), /**< Body Composition Measurement. */ + BLE_ATT_CHAR_WEIGHT_MEASUREMENT = BLE_ATT_UUID_16(0x2A9D), /**< Weight Measurement. */ + BLE_ATT_CHAR_WEIGHT_SCALE_FEATURE = BLE_ATT_UUID_16(0x2A9E), /**< Weight Scale Feature. */ + BLE_ATT_CHAR_USER_CONTROL_POINT = BLE_ATT_UUID_16(0x2A9F), /**< User Control Point. */ + BLE_ATT_CHAR_MAGN_FLUX_2D = BLE_ATT_UUID_16(0x2AA0), /**< Flux Density - 2D. */ + BLE_ATT_CHAR_MAGN_FLUX_3D = BLE_ATT_UUID_16(0x2AA1), /**< Magnetic Flux Density - 3D. */ + BLE_ATT_CHAR_LANGUAGE = BLE_ATT_UUID_16(0x2AA2), /**< Language string. */ + BLE_ATT_CHAR_BAR_PRES_TREND = BLE_ATT_UUID_16(0x2AA3), /**< Barometric Pressure Trend. */ + BLE_ATT_CHAR_CTL_ADDR_RESOL_SUPP = BLE_ATT_UUID_16(0x2AA6), /**< Central Address Resolution Support. */ + BLE_ATT_CHAR_OTS_FEATURES = BLE_ATT_UUID_16(0x2ABD), /**< OTS Service Feature. */ + BLE_ATT_CHAR_OTS_OBJECT_NAME = BLE_ATT_UUID_16(0x2ABE), /**< Object Name. */ + BLE_ATT_CHAR_OTS_OBJECT_TYPE = BLE_ATT_UUID_16(0x2ABF), /**< Object Type. */ + BLE_ATT_CHAR_OTS_OBJECT_SIZE = BLE_ATT_UUID_16(0x2AC0), /**< Object Size. */ + BLE_ATT_CHAR_OTS_OBJECT_FIRST_CREATED = BLE_ATT_UUID_16(0x2AC1), /**< Object First Created. */ + BLE_ATT_CHAR_OTS_OBJECT_LAST_MODIFIED = BLE_ATT_UUID_16(0x2AC2), /**< Object Last Modified. */ + BLE_ATT_CHAR_OTS_OBJECT_ID = BLE_ATT_UUID_16(0x2AC3), /**< Object ID. */ + BLE_ATT_CHAR_OTS_OBJECT_PROPERTIES = BLE_ATT_UUID_16(0x2AC4), /**< Object Properties. */ + BLE_ATT_CHAR_OTS_OACP = BLE_ATT_UUID_16(0x2AC5), /**< Object Action Control Point. */ + BLE_ATT_CHAR_OTS_OLCP = BLE_ATT_UUID_16(0x2AC6), /**< Object List Control Point. */ + BLE_ATT_CHAR_OTS_LF = BLE_ATT_UUID_16(0x2AC7), /**< Object List Filter. */ + BLE_ATT_CHAR_OTS_OBJECT_CHANGED = BLE_ATT_UUID_16(0x2AC8), /**< Object Changed. */ + BLE_ATT_CHAR_RSLV_PRIV_ADDR_ONLY = BLE_ATT_UUID_16(0x2AC9), /**< Resolvable Private Address only. */ + + BLE_ATT_CHAR_UNSPECIFIED = BLE_ATT_UUID_16(0X2ACA), /**< Unspecified. */ + BLE_ATT_CHAR_DIRE_LISTING = BLE_ATT_UUID_16(0X2ACB), /**< Directory Listing. */ + BLE_ATT_CHAR_FIT_MACH_FEAT = BLE_ATT_UUID_16(0X2ACC), /**< Fitness Machine Feature. */ + BLE_ATT_CHAR_TREADMILL_DATA = BLE_ATT_UUID_16(0X2ACD), /**< Treadmill Data. */ + BLE_ATT_CHAR_CROSS_TRAINER_DATA = BLE_ATT_UUID_16(0X2ACE), /**< Cross Trainer Data. */ + BLE_ATT_CHAR_STEP_CLIMBER_DATA = BLE_ATT_UUID_16(0X2ACF), /**< Step Climber Data. */ + BLE_ATT_CHAR_STSIR_CLIMBER_DATA = BLE_ATT_UUID_16(0X2AD0), /**< Stair Climber Data. */ + BLE_ATT_CHAR_ROWER_DATA = BLE_ATT_UUID_16(0X2AD1), /**< Rower Data. */ + BLE_ATT_CHAR_INDOOR_BIKE_DATA = BLE_ATT_UUID_16(0X2AD2), /**< Indoor Bike Data. */ + BLE_ATT_CHAR_TRAIN_STATUS = BLE_ATT_UUID_16(0X2AD3), /**< Training Status. */ + BLE_ATT_CHAR_SUP_SPEED_RANGE = BLE_ATT_UUID_16(0X2AD4), /**< Supported Speed Range. */ + BLE_ATT_CHAR_SUP_INCL_RANGE = BLE_ATT_UUID_16(0X2AD5), /**< Supported Inclination Range. */ + BLE_ATT_CHAR_SUP_RESIST_LEVEL_RANGE = BLE_ATT_UUID_16(0X2AD6), /**< Supported Resistance Level Range. */ + BLE_ATT_CHAR_SUP_HEART_RATE_RANGE = BLE_ATT_UUID_16(0X2AD7), /**< Supported Heart Rate Range. */ + BLE_ATT_CHAR_SUP_POWER_RANGE = BLE_ATT_UUID_16(0X2AD8), /**< Supported Power Range. */ + BLE_ATT_CHAR_FIT_MACH_CNTL_PT = BLE_ATT_UUID_16(0X2AD9), /**< Fitness Machine Control Point. */ + BLE_ATT_CHAR_FIT_MACH_STATUS = BLE_ATT_UUID_16(0X2ADA), /**< Fitness Machine Status. */ + BLE_ATT_CHAR_MESH_PROV_DATA_IN = BLE_ATT_UUID_16(0X2ADB), /**< Mesh Provisioning Data In. */ + BLE_ATT_CHAR_MESH_PROV_DATA_OUT = BLE_ATT_UUID_16(0X2ADC), /**< Mesh Provisioning Data Out. */ + BLE_ATT_CHAR_MESH_PROX_DATA_IN = BLE_ATT_UUID_16(0X2ADD), /**< Mesh Proxy Data In. */ + BLE_ATT_CHAR_MESH_PROX_DATA_OUT = BLE_ATT_UUID_16(0X2ADE), /**< Mesh Proxy Data Out. */ + BLE_ATT_CHAR_AVG_CURRENT = BLE_ATT_UUID_16(0X2AE0), /**< Average Current. */ + BLE_ATT_CHAR_AVG_VOLTAGE = BLE_ATT_UUID_16(0X2AE1), /**< Average Voltage. */ + BLE_ATT_CHAR_BOOLEAN = BLE_ATT_UUID_16(0X2AE2), /**< Boolean. */ + BLE_ATT_CHAR_CHROM_DIST_FROM_PLANCKIAN = BLE_ATT_UUID_16(0X2AE3), /**< Chromatic Distance From Planckian. */ + BLE_ATT_CHAR_CHROM_COORD = BLE_ATT_UUID_16(0X2AE4), /**< Chromaticity Coordinates. */ + BLE_ATT_CHAR_CHORM_IN_CCT_AND_DUV_VAL = BLE_ATT_UUID_16(0X2AE5), /**< Chromaticity in CCT And Duv Values. */ + BLE_ATT_CHAR_CHROM_TOLERANCE = BLE_ATT_UUID_16(0X2AE6), /**< Chromaticity Tolerance. */ + BLE_ATT_CHAR_CIE_COLOR_REND_IDX = BLE_ATT_UUID_16(0X2AE7), /**< CIE 13.3-1995 Color Rendering Index. */ + BLE_ATT_CHAR_COEFFICIENT = BLE_ATT_UUID_16(0X2AE8), /**< Coefficient. */ + BLE_ATT_CHAR_CORRELA_COLOR_TEMP = BLE_ATT_UUID_16(0X2AE9), /**< Correlated Color Temperature. */ + BLE_ATT_CHAR_COUNT_SIXTEEN = BLE_ATT_UUID_16(0X2AEA), /**< Count 16. */ + BLE_ATT_CHAR_COUNT_TWENTY_FOUR = BLE_ATT_UUID_16(0X2AEB), /**< Count 24. */ + BLE_ATT_CHAR_COUNTRY_CODE = BLE_ATT_UUID_16(0X2AEC), /**< Country Code. */ + BLE_ATT_CHAR_DATE_UTC = BLE_ATT_UUID_16(0X2AED), /**< Date UTC. */ + BLE_ATT_CHAR_ELEC_CURRENT = BLE_ATT_UUID_16(0X2AEE), /**< Electric Current. */ + BLE_ATT_CHAR_ELEC_CURRENT_RANGE = BLE_ATT_UUID_16(0X2AEF), /**< Electric Current Range. */ + BLE_ATT_CHAR_ELEC_CURRENT_SPEC = BLE_ATT_UUID_16(0X2AF0), /**< Electric Current Specification. */ + BLE_ATT_CHAR_ELEC_CURRENT_STATIS = BLE_ATT_UUID_16(0X2AF1), /**< Electric Current Statistics. */ + BLE_ATT_CHAR_ENERGY = BLE_ATT_UUID_16(0X2AF2), /**< Energy. */ + BLE_ATT_CHAR_ENERGY_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2AF3), /**< Energy In A Period Of Day. */ + BLE_ATT_CHAR_EVENT_STATIC = BLE_ATT_UUID_16(0X2AF4), /**< Event Statistics. */ + BLE_ATT_CHAR_FIXED_STR_SIXTEEN = BLE_ATT_UUID_16(0X2AF5), /**< Fixed String 16. */ + BLE_ATT_CHAR_FIXED_STR_TWENTY_FOUR = BLE_ATT_UUID_16(0X2AF6), /**< Fixed String 24. */ + BLE_ATT_CHAR_FIXED_STR_THIRTY_SIX = BLE_ATT_UUID_16(0X2AF7), /**< Fixed String 36. */ + BLE_ATT_CHAR_FIXED_STR_EIGHT = BLE_ATT_UUID_16(0X2AF8), /**< Fixed String 8. */ + BLE_ATT_CHAR_GENERIC_LEVEL = BLE_ATT_UUID_16(0X2AF9), /**< Generic Level. */ + BLE_ATT_CHAR_GLOB_TRADE_ITEM_NUM = BLE_ATT_UUID_16(0X2AFA), /**< Global Trade Item Number. */ + BLE_ATT_CHAR_ILLUMINANCE = BLE_ATT_UUID_16(0X2AFB), /**< Illuminance. */ + BLE_ATT_CHAR_LUMI_EFFICACY = BLE_ATT_UUID_16(0X2AFC), /**< Luminous Efficacy. */ + BLE_ATT_CHAR_LUMI_ENERGY = BLE_ATT_UUID_16(0X2AFD), /**< Luminous Energy. */ + BLE_ATT_CHAR_LUMI_EXPOSURE = BLE_ATT_UUID_16(0X2AFE), /**< Luminous Exposure. */ + BLE_ATT_CHAR_LUMI_FLUX = BLE_ATT_UUID_16(0X2AFE), /**< Luminous Flux. */ + BLE_ATT_CHAR_LUMI_FLUX_RANGE = BLE_ATT_UUID_16(0X2B00), /**< Luminous Flux Range. */ + BLE_ATT_CHAR_LUMI_INTENS = BLE_ATT_UUID_16(0X2B01), /**< Luminous Intensity. */ + BLE_ATT_CHAR_MASS_FLOW = BLE_ATT_UUID_16(0X2B02), /**< Mass Flow. */ + BLE_ATT_CHAR_PERCEIVED_LIGHT = BLE_ATT_UUID_16(0X2B03), /**< Perceived Lightness. */ + BLE_ATT_CHAR_PERC_EIGHT = BLE_ATT_UUID_16(0X2B04), /**< Percentage 8. */ + BLE_ATT_CHAR_POWER = BLE_ATT_UUID_16(0X2B05), /**< Power. */ + BLE_ATT_CHAR_POWER_SPEC = BLE_ATT_UUID_16(0X2B06), /**< Power Specification. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_CUR_RANGE = BLE_ATT_UUID_16(0X2B07), /**< Relative Runtime In A Current Range. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_GEN_LEVEL_RANGE = BLE_ATT_UUID_16(0X2B08), /**< Relative Runtime In A Generic Level Range. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_VOLT_RANGE = BLE_ATT_UUID_16(0X2B09), /**< Relative Value In A Voltage Range. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_ILLUM_RANGE = BLE_ATT_UUID_16(0X2B0A), /**< Relative Value In An Illuminance Range. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2B0B), /**< Relative Value In A Period Of Day. */ + BLE_ATT_CHAR_RELAT_RUNTIME_IN_TEMP_RANGE = BLE_ATT_UUID_16(0X2B0C), /**< Relative Value In A Temperature Range. */ + BLE_ATT_CHAR_TEMP_EIGHT = BLE_ATT_UUID_16(0X2B0D), /**< Temperature 8. */ + BLE_ATT_CHAR_TEMP_EIGHT_IN_PERIOD_OF_DAY = BLE_ATT_UUID_16(0X2B0E), /**< Temperature 8 In A Period Of Day. */ + BLE_ATT_CHAR_TEMP_EIGHT_STATIS = BLE_ATT_UUID_16(0X2B0F), /**< Temperature 8 Statistics. */ + BLE_ATT_CHAR_TEMP_RANGE = BLE_ATT_UUID_16(0X2B10), /**< Temperature Range. */ + BLE_ATT_CHAR_TEMP_STATIS = BLE_ATT_UUID_16(0X2B11), /**< Temperature Statistics. */ + BLE_ATT_CHAR_TIME_DECI_EIGHT = BLE_ATT_UUID_16(0X2B12), /**< Time Decihour 8. */ + BLE_ATT_CHAR_TIME_EXPON_EIGHT = BLE_ATT_UUID_16(0X2B13), /**< Time Exponential 8. */ + BLE_ATT_CHAR_TIME_HOUR_TWENTY_FOUR = BLE_ATT_UUID_16(0X2B14), /**< Time Hour 24. */ + BLE_ATT_CHAR_TIME_MS_TWENTY_FOUR = BLE_ATT_UUID_16(0X2B15), /**< Time Millisecond 24. */ + BLE_ATT_CHAR_TIME_SEC_SIXTEEN = BLE_ATT_UUID_16(0X2B16), /**< Time Second 16. */ + BLE_ATT_CHAR_TIME_SEC_EIGHT = BLE_ATT_UUID_16(0X2B17), /**< Time Second 8. */ + BLE_ATT_CHAR_VOLTAGE = BLE_ATT_UUID_16(0X2B18), /**< Voltage. */ + BLE_ATT_CHAR_VOLTAGE_SPEC = BLE_ATT_UUID_16(0X2B19), /**< Voltage Specification. */ + BLE_ATT_CHAR_VOLTAGE_STATIS = BLE_ATT_UUID_16(0X2B1A), /**< Voltage Statistics. */ + BLE_ATT_CHAR_VOLUME_FLOW = BLE_ATT_UUID_16(0X2B1B), /**< Volume Flow. */ + BLE_ATT_CHAR_CHROM_COORDINATE = BLE_ATT_UUID_16(0X2B1C), /**< Chromaticity Coordinate. */ + + BLE_ATT_CHAR_RC_FEAT = BLE_ATT_UUID_16(0x2B1D), /**< RC Feature. */ + BLE_ATT_CHAR_RC_SETTINGS = BLE_ATT_UUID_16(0x2B1E), /**< RC Settings. */ + BLE_ATT_CHAR_RECONNEC_CONFIG_CNTL_PT = BLE_ATT_UUID_16(0x2B1F), /**< Reconnection Configuration Control Point. */ + BLE_ATT_CHAR_IDD_STATUS_CHANGED = BLE_ATT_UUID_16(0x2B20), /**< IDD Status Changed. */ + BLE_ATT_CHAR_IDD_STATUS = BLE_ATT_UUID_16(0x2B21), /**< IDD Status. */ + BLE_ATT_CHAR_IDD_ANNU_STATUS = BLE_ATT_UUID_16(0x2B22), /**< IDD Annunciation Status. */ + BLE_ATT_CHAR_IDD_FEAT = BLE_ATT_UUID_16(0x2B23), /**< IDD Features. */ + BLE_ATT_CHAR_IDD_STATUS_READER_CNTL_PT = BLE_ATT_UUID_16(0x2B24), /**< IDD Status Reader Control Point. */ + BLE_ATT_CHAR_IDD_COMMAND_CNTL_PT = BLE_ATT_UUID_16(0x2B25), /**< IDD Command Control Point. */ + BLE_ATT_CHAR_IDD_COMMAND_DATA = BLE_ATT_UUID_16(0x2B26), /**< IDD Command Data. */ + BLE_ATT_CHAR_IDD_RECORD_ACCESS_CNTL_PT = BLE_ATT_UUID_16(0x2B27), /**< IDD Record Access Control Point. */ + BLE_ATT_CHAR_IDD_HISTORY_DATA = BLE_ATT_UUID_16(0x2B28), /**< IDD History Data. */ + BLE_ATT_CHAR_CLI_SUP_FEAT = BLE_ATT_UUID_16(0x2B29), /**< Client Supported Features. */ + BLE_ATT_CHAR_DB_HASH = BLE_ATT_UUID_16(0x2B2A), /**< Database Hash. */ + BLE_ATT_CHAR_BSS_CNTL_PT = BLE_ATT_UUID_16(0x2B2B), /**< BSS Control Point. */ + BLE_ATT_CHAR_BSS_RESPONSE = BLE_ATT_UUID_16(0x2B2C), /**< BSS Response. */ + BLE_ATT_CHAR_EMERGENCY_ID = BLE_ATT_UUID_16(0x2B2D), /**< Emergency ID. */ + BLE_ATT_CHAR_EMERGENCY_TEXT = BLE_ATT_UUID_16(0x2B2E), /**< Emergency Text. */ + + BLE_ATT_CHAR_REGISTERED_USER = BLE_ATT_UUID_16(0x2B37), /**< Registered User Characterisitc. */ + BLE_ATT_CHAR_SRV_SUP_FEAT = BLE_ATT_UUID_16(0x2B3A), /**< Server Supported Features. */ +} ble_att_uuid_t; /** * @brief Format for Characteristic Presentation. */ -typedef enum { +typedef enum +{ BLE_ATT_FORMAT_BOOL = 0x01, /**< Unsigned 1-bit: true or false. */ BLE_ATT_FORMAT_2BIT, /**< Unsigned 2-bit integer. */ BLE_ATT_FORMAT_NIBBLE, /**< Unsigned 4-bit integer. */ @@ -984,7 +568,7 @@ typedef enum { BLE_ATT_FORMAT_UTF16S, /**< UTF-16 string. */ BLE_ATT_FORMAT_STRUCT, /**< Opaque structure. */ BLE_ATT_FORMAT_LAST /**< Last format. */ -} att_format_t; +} ble_att_format_t; /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_audio.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_audio.h new file mode 100644 index 0000000..934c09b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_audio.h @@ -0,0 +1,252 @@ +/** + **************************************************************************************** + * + * @file ble_audio.h + * + * @brief BLE Audio API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __BLE_AUDIO_H__ +#define __BLE_AUDIO_H__ + +#if (CFG_SNIFFER) + + /** + * @addtogroup BLE + * @{ + * @brief Definitions and prototypes for the BLE SDK interface. + */ + + /** + * @addtogroup BLE_AUDIO Audio Library + * @{ + * @brief Definitions and prototypes for the Audio Application interface. + */ + +#include "ble_gapc.h" +#include "ble_error.h" + +#include // Standard Integer +#include +#include + +/** + * @defgroup BLE_AUDIO_ENUM Enumerations + * @{ + */ +/** @brief Switch role type */ +typedef enum +{ + AUDIO_SWITCH_ROLE_SINK_TYPE = 1 << 0, /**< Switch role for sink link. */ + AUDIO_SWITCH_ROLE_SNIFFER_TYPE = 1 << 1, /**< Switch role for sniffer link. */ +} audio_switch_role_type_t; + +/** + * @brief Definition of operation code used in the asynchronous operations + */ + typedef enum +{ + AUDIO_OPCODE_SWITCH_ROLE, /**< Switch Role. */ + AUDIO_OPCODE_TIME_SYNC, /**< Time Sync. */ + AUDIO_OPCODE_CREATE_SNIFFER, /** + +/**@addtogroup BLE_ERROR_CODES Defines + * @{ */ /**@defgroup SDK_ERROR_CODES SDK Specific Error Codes -* @{ +* @{ */ -#define SDK_SUCCESS 0x0000 /**< Successful. */ -#define SDK_ERR_INVALID_PARAM 0x0001 /**< Invalid parameter supplied. */ -#define SDK_ERR_POINTER_NULL 0x0002 /**< Invalid pointer supplied. */ -#define SDK_ERR_INVALID_CONN_IDX 0x0003 /**< Invalid connection index supplied. */ -#define SDK_ERR_INVALID_HANDLE 0x0004 /**< Invalid handle supplied. */ -#define SDK_ERR_PROFILE_COUNT 0x0005 /**< Maximum SDK profile count exceeded. */ -#define SDK_ERR_BUSY 0x0006 /**< SDK is busy internally. */ -#define SDK_ERR_TIMER_INSUFFICIENT 0x0007 /**< Timer is insufficient. */ -#define SDK_ERR_NVDS_NOT_INIT 0x0008 /**< NVDS is not initiated. */ -#define SDK_ERR_LIST_ITEM_NOT_FOUND 0x0009 /**< Item not found in list. */ -#define SDK_ERR_LIST_ITEM_ALREADY_EXISTED 0x000a /**< Item already exists in list. */ -#define SDK_ERR_LIST_FULL 0x000b /**< List is full. */ -#define SDK_ERR_SDK_INTERNAL 0x000c /**< Internal SDK error. */ -#define SDK_ERR_INVALID_BUFF_LENGTH 0x000d /**< The buffer's length is not enough. */ -#define SDK_ERR_INVALID_DATA_LENGTH 0x000e /**< Invalid data length supplied. */ -#define SDK_ERR_DISALLOWED 0x000f /**< Operation is disallowed. */ -#define SDK_ERR_NO_RESOURCES 0x0010 /**< Not enough resources for operation. */ -#define SDK_ERR_REQ_NOT_SUPPORTED 0x0011 /**< Request not supported. */ -#define SDK_ERR_INVALID_OFFSET 0x0012 /**< Offset exceeds the current attribute value length. */ -#define SDK_ERR_INVALID_ATT_VAL_LEN 0x0013 /**< Invalid length of the attribute value. */ -#define SDK_ERR_INVALID_PERM 0x0014 /**< Permission set in service/attribute is invalid. */ -#define SDK_ERR_INVALID_ADV_IDX 0x0015 /**< Invalid advertising index supplied. */ -#define SDK_ERR_INVALID_ADV_DATA_TYPE 0x0016 /**< Invalid advertising data type supplied. */ -#define SDK_ERR_INVALID_PSM_NUM 0x0017 /**< Invalid PSM number. */ -#define SDK_ERR_INVALID_PSM_ALREADY_REGISTERED 0x0018 /**< The PSM number has been registered. */ -#define SDK_ERR_INVALID_PSM_EXCEEDED_MAX_PSM_NUM 0x0019 /**< The maximum PSM number limit is exceeded. */ -#define SDK_ERR_NTF_DISABLED 0x001A /**< Notification is NOT enabled. */ -#define SDK_ERR_IND_DISABLED 0x001B /**< Indication is NOT enabled. */ -#define SDK_ERR_DISCONNECTED 0x001C /**< Disconnection occurs. */ -#define SDK_ERR_INVALID_ADDRESS 0x001D /**< Invalid address supplied. */ -#define SDK_ERR_INVALID_ADV_INTERVAL 0x001F /**< Invalid advertising interval supplied. */ -#define SDK_ERR_INVALID_DISVCOVERY_MODE 0x0020 /**< Invalid discovery mode supplied. */ -#define SDK_ERR_INVALID_ADV_PARAM 0x0021 /**< Invalid advertising parameters supplied. */ -#define SDK_ERR_INVALID_ADV_PEER_ADDR 0x0022 /**< Invalid peer address supplied. */ -#define SDK_ERR_ADV_DATA_NOT_SET 0x0023 /**< Legacy advertising data not set. */ -#define SDK_ERR_PER_ADV_DATA_NOT_SET 0x0024 /**< Periodic advertising data not set. */ -#define SDK_ERR_EXT_SCAN_RSP_DATA_NOT_SET 0x0025 /**< Extended scan response data not set. */ -#define SDK_ERR_INVALID_DURATION_PARAM 0x0026 /**< Invalid duration parameter supplied. */ -#define SDK_ERR_INVALID_PER_SYNC_IDX 0x0027 /**< Invalid periodic synchronization index supplied. */ -#define SDK_ERR_INVALID_CID 0x0028 /**< Invalid CID supplied. */ -#define SDK_ERR_INVALID_CHL_NUM 0x0029 /**< Invalid channel number supplied. */ -#define SDK_ERR_NOT_ENOUGH_CREDITS 0x002A /**< Not enough credits. */ +#define SDK_SUCCESS 0x0000 /**< Successful. */ +#define SDK_ERR_INVALID_PARAM 0x0001 /**< Invalid parameter supplied. */ +#define SDK_ERR_POINTER_NULL 0x0002 /**< Invalid pointer supplied. */ +#define SDK_ERR_INVALID_CONN_IDX 0x0003 /**< Invalid connection index supplied. */ +#define SDK_ERR_INVALID_HANDLE 0x0004 /**< Invalid handle supplied. */ +#define SDK_ERR_PROFILE_COUNT 0x0005 /**< Maximum SDK profile count exceeded. */ +#define SDK_ERR_BUSY 0x0006 /**< SDK is busy internally. */ +#define SDK_ERR_TIMER_INSUFFICIENT 0x0007 /**< Timer is insufficient. */ +#define SDK_ERR_NVDS_NOT_INIT 0x0008 /**< NVDS is not initiated. */ +#define SDK_ERR_LIST_ITEM_NOT_FOUND 0x0009 /**< Item not found in list. */ +#define SDK_ERR_LIST_ITEM_ALREADY_EXISTED 0x000a /**< Item already exists in list. */ +#define SDK_ERR_LIST_FULL 0x000b /**< List is full. */ +#define SDK_ERR_SDK_INTERNAL 0x000c /**< Internal SDK error. */ +#define SDK_ERR_INVALID_BUFF_LENGTH 0x000d /**< The buffer's length is not enough. */ +#define SDK_ERR_INVALID_DATA_LENGTH 0x000e /**< Invalid data length supplied. */ +#define SDK_ERR_DISALLOWED 0x000f /**< Operation is disallowed. */ +#define SDK_ERR_NO_RESOURCES 0x0010 /**< Not enough resources for operation. */ +#define SDK_ERR_REQ_NOT_SUPPORTED 0x0011 /**< Request not supported. */ +#define SDK_ERR_INVALID_OFFSET 0x0012 /**< Offset exceeds the current attribute value length. */ +#define SDK_ERR_INVALID_ATT_VAL_LEN 0x0013 /**< Invalid length of the attribute value. */ +#define SDK_ERR_INVALID_PERM 0x0014 /**< Permission set in service/attribute is invalid. */ +#define SDK_ERR_INVALID_ADV_IDX 0x0015 /**< Invalid advertising index supplied. */ +#define SDK_ERR_INVALID_ADV_DATA_TYPE 0x0016 /**< Invalid advertising data type supplied. */ +#define SDK_ERR_INVALID_PSM_NUM 0x0017 /**< Invalid PSM number. */ +#define SDK_ERR_INVALID_PSM_ALREADY_REGISTERED 0x0018 /**< The PSM number has been registered. */ +#define SDK_ERR_INVALID_PSM_EXCEEDED_MAX_PSM_NUM 0x0019 /**< The maximum PSM number limit is exceeded. */ +#define SDK_ERR_NTF_DISABLED 0x001A /**< Notification is NOT enabled. */ +#define SDK_ERR_IND_DISABLED 0x001B /**< Indication is NOT enabled. */ +#define SDK_ERR_DISCONNECTED 0x001C /**< Disconnection occurs. */ +#define SDK_ERR_INVALID_ADDRESS 0x001D /**< Invalid address supplied. */ +#define SDK_ERR_FEATURE_NOT_ENABLE 0x001E /**< Feature not enable in ble feature config. */ -#define SDK_ERR_APP_ERROR 0x0080 /**< Application error. */ +#define SDK_ERR_INVALID_ADV_INTERVAL 0x001F /**< Invalid advertising interval supplied. */ +#define SDK_ERR_INVALID_DISVCOVERY_MODE 0x0020 /**< Invalid discovery mode supplied. */ +#define SDK_ERR_INVALID_ADV_PARAM 0x0021 /**< Invalid advertising parameters supplied. */ +#define SDK_ERR_INVALID_ADV_PEER_ADDR 0x0022 /**< Invalid peer address supplied. */ +#define SDK_ERR_ADV_DATA_NOT_SET 0x0023 /**< Legacy advertising data not set. */ +#define SDK_ERR_PER_ADV_DATA_NOT_SET 0x0024 /**< Periodic advertising data not set. */ +#define SDK_ERR_EXT_SCAN_RSP_DATA_NOT_SET 0x0025 /**< Extended scan response data not set. */ +#define SDK_ERR_INVALID_DURATION_PARAM 0x0026 /**< Invalid duration parameter supplied. */ +#define SDK_ERR_INVALID_PER_SYNC_IDX 0x0027 /**< Invalid periodic synchronization index supplied. */ +#define SDK_ERR_INVALID_CID 0x0028 /**< Invalid CID supplied. */ +#define SDK_ERR_INVALID_CHL_NUM 0x0029 /**< Invalid channel number supplied. */ +#define SDK_ERR_NOT_ENOUGH_CREDITS 0x002A /**< Not enough credits. */ +#define SDK_ERR_REPEAT_CID 0x002B /**< Invalid repeat CID. */ +#define SDK_ERR_CACHE_NOT_ENABLE 0x002C /**< Cache feature is not enabled. */ +#define SDK_ERR_CACHE_INVALID 0x002D /**< Cache data is invalid. */ + +#define SDK_ERR_APP_ERROR 0x0080 /**< Application error. */ /**@} */ /**@defgroup BLE_STACK_ERROR_CODES BLE Stack specific error codes -* @{ +* @{ */ -#define BLE_SUCCESS 0x00 /**< Operation is Successful. */ +#define BLE_SUCCESS 0x00 /**< Operation is Successful. */ /**@brief ATT Specific Error. */ -#define BLE_ATT_ERR_INVALID_HANDLE 0x01 /**< The given attribute handle was not valid - on this server. */ -#define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02 /**< The attribute cannot be read. */ -#define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03 /**< The attribute cannot be written. */ -#define BLE_ATT_ERR_INVALID_PDU 0x04 /**< The attribute PDU was invalid. */ -#define BLE_ATT_ERR_INSUFF_AUTHEN 0x05 /**< The attribute requires authentication before - it can be read or written. */ -#define BLE_ATT_ERR_REQUEST_NOT_SUPPORTED 0x06 /**< Attribute server does not support the request received - from the client. */ -#define BLE_ATT_ERR_INVALID_OFFSET 0x07 /**< Offset specified was past the end of the attribute. */ -#define BLE_ATT_ERR_INSUFF_AUTHOR 0x08 /**< The attribute requires authorization before - it can be read or written. */ -#define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09 /**< Too many prepare writes have been queued. */ -#define BLE_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0A /**< No attribute found within the given - attribute handle range. */ -#define BLE_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0B /**< The attribute cannot be read using - the Read Blob Request. */ -#define BLE_ATT_ERR_INSUFF_ENC_KEY_SIZE 0x0C /**< The Encryption Key Size used for encrypting - this link is insufficient. */ -#define BLE_ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN 0x0D /**< The attribute value length is invalid - for the operation. */ -#define BLE_ATT_ERR_UNLIKELY_ERR 0x0E /**< The attribute request has encountered an unlikely error, - so the request could not be completed as requested. */ -#define BLE_ATT_ERR_INSUFF_ENC 0x0F /**< The attribute requires encryption before - it can be read or written. */ -#define BLE_ATT_ERR_UNSUPP_GRP_TYPE 0x10 /**< The attribute type is not a supported grouping attribute - as defined by a higher layer specification. */ -#define BLE_ATT_ERR_INSUFF_RESOURCE 0x11 /**< Insufficient resources to complete the request. */ +#define BLE_ATT_ERR_INVALID_HANDLE 0x01 /**< The given attribute handle was not valid on this server. */ +#define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02 /**< The attribute cannot be read. */ +#define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03 /**< The attribute cannot be written. */ +#define BLE_ATT_ERR_INVALID_PDU 0x04 /**< The attribute PDU was invalid. */ +#define BLE_ATT_ERR_INSUFF_AUTHEN 0x05 /**< The attribute requires authentication before it can be read or written. */ +#define BLE_ATT_ERR_REQUEST_NOT_SUPPORTED 0x06 /**< Attribute server does not support the request received from the client. */ +#define BLE_ATT_ERR_INVALID_OFFSET 0x07 /**< Offset specified was past the end of the attribute. */ +#define BLE_ATT_ERR_INSUFF_AUTHOR 0x08 /**< The attribute requires authorization before it can be read or written. */ +#define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09 /**< Too many prepare writes have been queued. */ +#define BLE_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0A /**< No attribute found within the given attribute handle range. */ +#define BLE_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0B /**< The attribute cannot be read using the Read Blob Request. */ +#define BLE_ATT_ERR_INSUFF_ENC_KEY_SIZE 0x0C /**< The Encryption Key Size used for encrypting this link is insufficient. */ +#define BLE_ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN 0x0D /**< The attribute value length is invalid for the operation. */ +#define BLE_ATT_ERR_UNLIKELY_ERR 0x0E /**< The attribute request has encountered an unlikely error, so the request could not be completed as requested. */ +#define BLE_ATT_ERR_INSUFF_ENC 0x0F /**< The attribute requires encryption before it can be read or written. */ +#define BLE_ATT_ERR_UNSUPP_GRP_TYPE 0x10 /**< The attribute type is not a supported grouping attribute as defined by a higher layer specification. */ +#define BLE_ATT_ERR_INSUFF_RESOURCE 0x11 /**< Insufficient resources to complete the request. */ +#define BLE_ATT_ERR_DB_OUT_OF_SYNC 0x12 /**< The server requests the client to rediscover the database. */ +#define BLE_ATT_ERR_VALUE_NOT_ALLOWED 0x13 /**< The attribute parameter value was not allowed. */ /**@brief L2CAP Specific Error. */ -#define BLE_L2C_ERR_CONNECTION_LOST 0x30 /**< Message cannot be sent because connection - is lost (disconnected). */ -#define BLE_L2C_ERR_INVALID_MTU_EXCEED 0x31 /**< Invalid PDU length exceeds MTU. */ -#define BLE_L2C_ERR_INVALID_MPS_EXCEED 0x32 /**< Invalid PDU length exceeds MPS. */ -#define BLE_L2C_ERR_INVALID_CID 0x33 /**< Invalid Channel ID. */ -#define BLE_L2C_ERR_INVALID_PDU 0x34 /**< Invalid PDU. */ -#define BLE_L2C_ERR_NO_RES_AVAIL 0x35 /**< Connection refused because no resources are available. */ -#define BLE_L2C_ERR_INSUFF_AUTHEN 0x36 /**< Connection refused because of - insufficient authentication. */ -#define BLE_L2C_ERR_INSUFF_AUTHOR 0x37 /**< Connection refused because of - insufficient authorization. */ -#define BLE_L2C_ERR_INSUFF_ENC_KEY_SIZE 0x38 /**< Connection refused because of - insufficient encryption key size. */ -#define BLE_L2C_ERR_INSUFF_ENC 0x39 /**< Connection refused because of insufficient encryption. */ -#define BLE_L2C_ERR_LEPSM_NOT_SUPP 0x3A /**< Connection refused because LE_PSM is not supported. */ -#define BLE_L2C_ERR_INSUFF_CREDIT 0x3B /**< No more credit. */ -#define BLE_L2C_ERR_NOT_UNDERSTOOD 0x3C /**< Command not understood by peer device. */ -#define BLE_L2C_ERR_CREDIT_ERROR 0x3D /**< Credit error: invalid number of credit received. */ -#define BLE_L2C_ERR_CID_ALREADY_ALLOC 0x3E /**< Channel identifier already allocated. */ +#define BLE_L2C_ENH_CB_RECONFIG_INVALID_MTU 0x2C /**< Reconfiguration failed - reduction in size of MTU not allowed. */ +#define BLE_L2C_ENH_CB_RECONFIG_INVALID_MPS 0x2D /**< Reconfiguration failed - reduction in size of MPS not allowed for more than one channel at a time. */ +#define BLE_L2C_ENH_CB_RECONFIG_INVALID_CID 0x2E /**< Reconfiguration failed - one or more Destination CIDs invalid. */ +#define BLE_L2C_ENH_CB_RECONFIG_UNACCEPT_PARAM 0x2F /**< Reconfiguration failed - other unacceptable parameters. */ +#define BLE_L2C_ERR_CONNECTION_LOST 0x30 /**< Message cannot be sent because connection is lost (disconnected). */ +#define BLE_L2C_ERR_INVALID_MTU_EXCEED 0x31 /**< Invalid PDU length exceeds MTU. */ +#define BLE_L2C_ERR_INVALID_MPS_EXCEED 0x32 /**< Invalid PDU length exceeds MPS. */ +#define BLE_L2C_ERR_INVALID_CID 0x33 /**< Invalid Channel ID. */ +#define BLE_L2C_ERR_INVALID_PDU 0x34 /**< Invalid PDU. */ +#define BLE_L2C_ERR_NO_RES_AVAIL 0x35 /**< Connection refused because no resources are available. */ +#define BLE_L2C_ERR_INSUFF_AUTHEN 0x36 /**< Connection refused because of insufficient authentication. */ +#define BLE_L2C_ERR_INSUFF_AUTHOR 0x37 /**< Connection refused because of insufficient authorization. */ +#define BLE_L2C_ERR_INSUFF_ENC_KEY_SIZE 0x38 /**< Connection refused because of insufficient encryption key size. */ +#define BLE_L2C_ERR_INSUFF_ENC 0x39 /**< Connection refused because of insufficient encryption. */ +#define BLE_L2C_ERR_LEPSM_NOT_SUPP 0x3A /**< Connection refused because LE_PSM is not supported. */ +#define BLE_L2C_ERR_INSUFF_CREDIT 0x3B /**< No more credit. */ +#define BLE_L2C_ERR_NOT_UNDERSTOOD 0x3C /**< Command not understood by peer device. */ +#define BLE_L2C_ERR_CREDIT_ERROR 0x3D /**< Credit error: invalid number of credit received. */ +#define BLE_L2C_ERR_CID_ALREADY_ALLOC 0x3E /**< Channel identifier already allocated. */ +#define BLE_L2C_ERR_UNKNOWN_PDU 0x3F /**< Unknown pdu. */ /**@brief GAP Specific Error. */ -#define BLE_GAP_ERR_INVALID_PARAM 0x40 /**< Invalid parameters set. */ -#define BLE_GAP_ERR_PROTOCOL_PROBLEM 0x41 /**< Problem with protocol exchange, - resulting in unexpected responses. */ -#define BLE_GAP_ERR_NOT_SUPPORTED 0x42 /**< Request not supported by software configuration. */ -#define BLE_GAP_ERR_COMMAND_DISALLOWED 0x43 /**< Request not allowed in current state. */ -#define BLE_GAP_ERR_CANCELED 0x44 /**< Requested operation canceled. */ -#define BLE_GAP_ERR_TIMEOUT 0x45 /**< Requested operation timeout. */ -#define BLE_GAP_ERR_DISCONNECTED 0x46 /**< Link connection is lost during operation. */ -#define BLE_GAP_ERR_NOT_FOUND 0x47 /**< Search algorithm finished, but no result found. */ -#define BLE_GAP_ERR_REJECTED 0x48 /**< Request rejected by peer device. */ -#define BLE_GAP_ERR_PRIVACY_CFG_PB 0x49 /**< Problem with privacy configuration. */ -#define BLE_GAP_ERR_ADV_DATA_INVALID 0x4A /**< Duplicate or invalid advertising data. */ -#define BLE_GAP_ERR_INSUFF_RESOURCES 0x4B /**< Insufficient resources. */ -#define BLE_GAP_ERR_UNEXPECTED 0x4C /**< Unexpected error. */ -#define BLE_GAP_ERR_MISMATCH 0x4D /**< Feature mismatch. */ +#define BLE_GAP_ERR_INVALID_PARAM 0x40 /**< Invalid parameters set. */ +#define BLE_GAP_ERR_PROTOCOL_PROBLEM 0x41 /**< Problem with protocol exchange, resulting in unexpected responses. */ +#define BLE_GAP_ERR_NOT_SUPPORTED 0x42 /**< Request not supported by software configuration. */ +#define BLE_GAP_ERR_COMMAND_DISALLOWED 0x43 /**< Request not allowed in current state. */ +#define BLE_GAP_ERR_CANCELED 0x44 /**< Requested operation canceled. */ +#define BLE_GAP_ERR_TIMEOUT 0x45 /**< Requested operation timeout. */ +#define BLE_GAP_ERR_DISCONNECTED 0x46 /**< Link connection is lost during operation. */ +#define BLE_GAP_ERR_NOT_FOUND 0x47 /**< Search algorithm finished, but no result found. */ +#define BLE_GAP_ERR_REJECTED 0x48 /**< Request rejected by peer device. */ +#define BLE_GAP_ERR_PRIVACY_CFG_PB 0x49 /**< Problem with privacy configuration. */ +#define BLE_GAP_ERR_ADV_DATA_INVALID 0x4A /**< Duplicate or invalid advertising data. */ +#define BLE_GAP_ERR_INSUFF_RESOURCES 0x4B /**< Insufficient resources. */ +#define BLE_GAP_ERR_UNEXPECTED 0x4C /**< Unexpected error. */ +#define BLE_GAP_ERR_MISMATCH 0x4D /**< Feature mismatch. */ /**@brief GATT Specific Error. */ -#define BLE_GATT_ERR_INVALID_ATT_LEN 0x50 /**< Problem with ATTC protocol response. */ -#define BLE_GATT_ERR_INVALID_TYPE_IN_SVC_SEARCH 0x51 /**< Error in service search. */ -#define BLE_GATT_ERR_WRITE 0x52 /**< Invalid write data. */ -#define BLE_GATT_ERR_SIGNED_WRITE 0x53 /**< Signed write error. */ -#define BLE_GATT_ERR_ATTRIBUTE_CLIENT_MISSING 0x54 /**< No attribute client defined. */ -#define BLE_GATT_ERR_ATTRIBUTE_SERVER_MISSING 0x55 /**< No attribute server defined. */ -#define BLE_GATT_ERR_INVALID_PERM 0x56 /**< Permission set in service/attribute is invalid. */ -#define BLE_GATT_ERR_BROWSE_NO_ANY_MORE 0x57 /**< GATT browses no any more contents. */ +#define BLE_GATT_ERR_INVALID_ATT_LEN 0x50 /**< Problem with ATTC protocol response. */ +#define BLE_GATT_ERR_INVALID_TYPE_IN_SVC_SEARCH 0x51 /**< Error in service search. */ +#define BLE_GATT_ERR_WRITE 0x52 /**< Invalid write data. */ +#define BLE_GATT_ERR_SIGNED_WRITE 0x53 /**< Signed write error. */ +#define BLE_GATT_ERR_ATTRIBUTE_CLIENT_MISSING 0x54 /**< No attribute client defined. */ +#define BLE_GATT_ERR_ATTRIBUTE_SERVER_MISSING 0x55 /**< No attribute server defined. */ +#define BLE_GATT_ERR_INVALID_PERM 0x56 /**< Permission set in service/attribute is invalid. */ +#define BLE_GATT_ERR_BROWSE_NO_ANY_MORE 0x57 /**< GATT browses no any more contents. */ +#define BLE_GATT_ERR_CACHE_UPDATING 0x58 /**< GATT Cache in updating process. */ +#define BLE_GATT_ERR_CACHE_FINISH 0x59 /**< GATT Cache is updated or checked. */ + +/**@brief SEC Specific Error. */ +#define BLE_SEC_ERR_PASSKEY_ENTRY_FAIL 0x61 /**< The user input of passkey failed. */ +#define BLE_SEC_ERR_OOB_NOT_AVAILBL 0x62 /**< The OOB data is not available. */ +#define BLE_SEC_ERR_AUTH_REQ 0x63 /**< The pairing procedure cannot be performed as authentication requirements cannot be met due to IO incapability of one or both devices. */ +#define BLE_SEC_ERR_CONFIRM_VAL_FAIL 0x64 /**< The confirm value does not match the calculated compare value. */ +#define BLE_SEC_ERR_PAIRING_NOT_SUPPORT 0x65 /**< Pairing is not supported by the device. */ +#define BLE_SEC_ERR_ENCRPT_KEY_SIZE 0x66 /**< The resultant encryption key size is insufficient for the security requirements of this device. */ +#define BLE_SEC_ERR_COMMAND_NOT_SUPPORT 0x67 /**< The SMP command received is not supported on this device. */ +#define BLE_SEC_ERR_UNSPECIFIED 0x68 /**< Pairing failed due to an unspecified reason. */ +#define BLE_SEC_ERR_REPEAT_ATTEMPT 0x69 /**< Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request. */ +#define BLE_SEC_ERR_INVALID_PARAM 0x6A /**< The Invalid Parameters error code indicates that the command length is invalid or that a parameter is outside of the specified range. */ +#define BLE_SEC_ERR_DHKEY_CHECK_FAIL 0x6B /**< Indicate to the remote device that the DHKey Check value received doesn't match the one calculated by the local device. */ +#define BLE_SEC_ERR_NUM_CMP_FAIL 0x6C /**< Indicate that the confirm values in the numeric comparison protocol do not match. */ +#define BLE_SEC_ERR_BR_EDR_IN_PROGRESS 0x6D /**< Indicate that the pairing over the LE transport failed due to a Pairing Request sent over the BR/EDR transport in process. */ +#define BLE_SEC_ERR_KEY_DRIV_GEN_NOT_ALLOW 0x6E /**< Indicate that the BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport. */ +#define BLE_SEC_ERR_LTK_MISSING 0x6F /**< Indicate the LTK of peer devices missing. */ /**@brief LL Specific Error. */ -#define BLE_LL_ERR_UNKNOWN_HCI_COMMAND 0x91 /**< Unknown HCI Command. */ -#define BLE_LL_ERR_UNKNOWN_CONNECTION_ID 0x92 /**< Unknown Connection Identifier. */ -#define BLE_LL_ERR_HARDWARE_FAILURE 0x93 /**< Hardware Failure. */ -#define BLE_LL_ERR_PAGE_TIMEOUT 0x94 /**< BT Page Timeout. */ -#define BLE_LL_ERR_AUTH_FAILURE 0x95 /**< Authentication failure. */ -#define BLE_LL_ERR_PIN_MISSING 0x96 /**< Pin code missing. */ -#define BLE_LL_ERR_MEMORY_CAPA_EXCEED 0x97 /**< Memory capacity exceeded. */ -#define BLE_LL_ERR_CON_TIMEOUT 0x98 /**< Connection Timeout. */ -#define BLE_LL_ERR_CON_LIMIT_EXCEED 0x99 /**< Connection limit Exceed. */ -#define BLE_LL_ERR_SYNC_CON_LIMIT_DEV_EXCEED 0x9A /**< Synchronous Connection limit exceeded. */ -#define BLE_LL_ERR_ACL_CON_EXISTS 0x9B /**< ACL Connection exits. */ -#define BLE_LL_ERR_COMMAND_DISALLOWED 0x9C /**< Command Disallowed. */ -#define BLE_LL_ERR_CONN_REJ_LIMITED_RESOURCES 0x9D /**< Connection rejected due to limited resources. */ -#define BLE_LL_ERR_CONN_REJ_SECURITY_REASONS 0x9E /**< Connection rejected due to insecurity issues. */ -#define BLE_LL_ERR_CONN_REJ_UNACCEPTABLE_BDADDR 0x9F /**< Connection rejected due to unacceptable BD Addr. */ -#define BLE_LL_ERR_CONN_ACCEPT_TIMEOUT_EXCEED 0xA0 /**< Connection rejected due to Accept connection timeout. */ -#define BLE_LL_ERR_UNSUPPORTED 0xA1 /**< Not Supported. */ -#define BLE_LL_ERR_INVALID_HCI_PARAM 0xA2 /**< Invalid parameters. */ -#define BLE_LL_ERR_REMOTE_USER_TERM_CON 0xA3 /**< Remote user terminates connection. */ -#define BLE_LL_ERR_REMOTE_DEV_TERM_LOW_RESOURCES 0xA4 /**< Remote device loses connection due to low resources. */ -#define BLE_LL_ERR_REMOTE_DEV_POWER_OFF 0xA5 /**< Remote device loses connection due to power failure. */ -#define BLE_LL_ERR_CON_TERM_BY_LOCAL_HOST 0xA6 /**< Connection terminated by local host. */ -#define BLE_LL_ERR_REPEATED_ATTEMPTS 0xA7 /**< Repeated attempts. */ -#define BLE_LL_ERR_PAIRING_NOT_ALLOWED 0xA8 /**< Pairing not allowed. */ -#define BLE_LL_ERR_UNKNOWN_LMP_PDU 0xA9 /**< Unknown PDU Error. */ -#define BLE_LL_ERR_UNSUPPORTED_REMOTE_FEATURE 0xAA /**< Unsupported remote feature. */ -#define BLE_LL_ERR_SCO_OFFSET_REJECTED 0xAB /**< SCO Offset rejected. */ -#define BLE_LL_ERR_SCO_INTERVAL_REJECTED 0xAC /**< SCO Interval Rejected. */ -#define BLE_LL_ERR_SCO_AIR_MODE_REJECTED 0xAD /**< SCO air mode Rejected. */ -#define BLE_LL_ERR_INVALID_LMP_PARAM 0xAE /**< Invalid LMP parameters. */ -#define BLE_LL_ERR_UNSPECIFIED_ERROR 0xAF /**< Unspecified error. */ -#define BLE_LL_ERR_UNSUPPORTED_LMP_PARAM_VALUE 0xB0 /**< Unsupported LMP Parameter value. */ -#define BLE_LL_ERR_ROLE_CHANGE_NOT_ALLOWED 0xB1 /**< Role Change not allowed. */ -#define BLE_LL_ERR_LMP_RSP_TIMEOUT 0xB2 /**< LMP Response timeout. */ -#define BLE_LL_ERR_LMP_COLLISION 0xB3 /**< LMP Collision. */ -#define BLE_LL_ERR_LMP_PDU_NOT_ALLOWED 0xB4 /**< LMP PDU not allowed. */ -#define BLE_LL_ERR_ENC_MODE_NOT_ACCEPT 0xB5 /**< Encryption mode not accepted. */ -#define BLE_LL_ERR_LINK_KEY_CANT_CHANGE 0xB6 /**< Link Key cannot be changed. */ -#define BLE_LL_ERR_QOS_NOT_SUPPORTED 0xB7 /**< Quality of Service not supported. */ -#define BLE_LL_ERR_INSTANT_PASSED 0xB8 /**< Error, instant passed. */ -#define BLE_LL_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUP 0xB9 /**< Pairing with unit key not supported. */ -#define BLE_LL_ERR_DIFF_TRANSACTION_COLLISION 0xBA /**< Transaction collision. */ -#define BLE_LL_ERR_QOS_UNACCEPTABLE_PARAM 0xBC /**< Quality of Service not supported. */ -#define BLE_LL_ERR_QOS_REJECTED 0xBD /**< Quality of Service rejected. */ -#define BLE_LL_ERR_CHANNEL_CLASS_NOT_SUP 0xBE /**< Channel class not supported. */ -#define BLE_LL_ERR_INSUFFICIENT_SECURITY 0xBF /**< Insufficient security. */ -#define BLE_LL_ERR_PARAM_OUT_OF_MAND_RANGE 0xC0 /**< Parameters out of mandatory range. */ -#define BLE_LL_ERR_ROLE_SWITCH_PEND 0xC2 /**< Role switch pending. */ -#define BLE_LL_ERR_RESERVED_SLOT_VIOLATION 0xC4 /**< Reserved slot violation. */ -#define BLE_LL_ERR_ROLE_SWITCH_FAIL 0xC5 /**< Role Switch failed. */ -#define BLE_LL_ERR_EIR_TOO_LARGE 0xC6 /**< Error: EIR too large. */ -#define BLE_LL_ERR_SP_NOT_SUPPORTED_HOST 0xC7 /**< Simple pairing not supported by host. */ -#define BLE_LL_ERR_HOST_BUSY_PAIRING 0xC8 /**< Host pairing is busy. */ -#define BLE_LL_ERR_CONTROLLER_BUSY 0xCA /**< Controller is busy. */ -#define BLE_LL_ERR_UNACCEPTABLE_CONN_INT 0xCB /**< Unacceptable connection initialization. */ -#define BLE_LL_ERR_ADV_TO 0xCC /**< Advertising Timeout. */ -#define BLE_LL_ERR_TERMINATED_MIC_FAILURE 0xCD /**< Connection Terminated due to a MIC failure. */ -#define BLE_LL_ERR_CONN_FAILED_TO_BE_EST 0xCE /**< Connection failed to be established. */ +#define BLE_LL_ERR_UNKNOWN_HCI_COMMAND 0x91 /**< Unknown HCI Command. */ +#define BLE_LL_ERR_UNKNOWN_CONNECTION_ID 0x92 /**< Unknown Connection Identifier. */ +#define BLE_LL_ERR_HARDWARE_FAILURE 0x93 /**< Hardware Failure. */ +#define BLE_LL_ERR_PAGE_TIMEOUT 0x94 /**< BT Page Timeout. */ +#define BLE_LL_ERR_AUTH_FAILURE 0x95 /**< Authentication failure. */ +#define BLE_LL_ERR_PIN_MISSING 0x96 /**< Pin code missing. */ +#define BLE_LL_ERR_MEMORY_CAPA_EXCEED 0x97 /**< Memory capacity exceeded. */ +#define BLE_LL_ERR_CON_TIMEOUT 0x98 /**< Connection Timeout. */ +#define BLE_LL_ERR_CON_LIMIT_EXCEED 0x99 /**< Connection limit Exceed. */ +#define BLE_LL_ERR_SYNC_CON_LIMIT_DEV_EXCEED 0x9A /**< Synchronous Connection limit exceeded. */ +#define BLE_LL_ERR_ACL_CON_EXISTS 0x9B /**< ACL Connection exits. */ +#define BLE_LL_ERR_COMMAND_DISALLOWED 0x9C /**< Command Disallowed. */ +#define BLE_LL_ERR_CONN_REJ_LIMITED_RESOURCES 0x9D /**< Connection rejected due to limited resources. */ +#define BLE_LL_ERR_CONN_REJ_SECURITY_REASONS 0x9E /**< Connection rejected due to insecurity issues. */ +#define BLE_LL_ERR_CONN_REJ_UNACCEPTABLE_BDADDR 0x9F /**< Connection rejected due to unacceptable BD Addr. */ +#define BLE_LL_ERR_CONN_ACCEPT_TIMEOUT_EXCEED 0xA0 /**< Connection rejected due to Accept connection timeout. */ +#define BLE_LL_ERR_UNSUPPORTED 0xA1 /**< Not Supported. */ +#define BLE_LL_ERR_INVALID_HCI_PARAM 0xA2 /**< Invalid parameters. */ +#define BLE_LL_ERR_REMOTE_USER_TERM_CON 0xA3 /**< Remote user terminates connection. */ +#define BLE_LL_ERR_REMOTE_DEV_TERM_LOW_RESOURCES 0xA4 /**< Remote device loses connection due to low resources. */ +#define BLE_LL_ERR_REMOTE_DEV_POWER_OFF 0xA5 /**< Remote device loses connection due to power failure. */ +#define BLE_LL_ERR_CON_TERM_BY_LOCAL_HOST 0xA6 /**< Connection terminated by local host. */ +#define BLE_LL_ERR_REPEATED_ATTEMPTS 0xA7 /**< Repeated attempts. */ +#define BLE_LL_ERR_PAIRING_NOT_ALLOWED 0xA8 /**< Pairing not allowed. */ +#define BLE_LL_ERR_UNKNOWN_LMP_PDU 0xA9 /**< Unknown PDU Error. */ +#define BLE_LL_ERR_UNSUPPORTED_REMOTE_FEATURE 0xAA /**< Unsupported remote feature. */ +#define BLE_LL_ERR_SCO_OFFSET_REJECTED 0xAB /**< SCO Offset rejected. */ +#define BLE_LL_ERR_SCO_INTERVAL_REJECTED 0xAC /**< SCO Interval Rejected. */ +#define BLE_LL_ERR_SCO_AIR_MODE_REJECTED 0xAD /**< SCO air mode Rejected. */ +#define BLE_LL_ERR_INVALID_LMP_PARAM 0xAE /**< Invalid LMP parameters. */ +#define BLE_LL_ERR_UNSPECIFIED_ERROR 0xAF /**< Unspecified error. */ +#define BLE_LL_ERR_UNSUPPORTED_LMP_PARAM_VALUE 0xB0 /**< Unsupported LMP Parameter value. */ +#define BLE_LL_ERR_ROLE_CHANGE_NOT_ALLOWED 0xB1 /**< Role Change not allowed. */ +#define BLE_LL_ERR_LMP_RSP_TIMEOUT 0xB2 /**< LMP Response timeout. */ +#define BLE_LL_ERR_LMP_COLLISION 0xB3 /**< LMP Collision. */ +#define BLE_LL_ERR_LMP_PDU_NOT_ALLOWED 0xB4 /**< LMP PDU not allowed. */ +#define BLE_LL_ERR_ENC_MODE_NOT_ACCEPT 0xB5 /**< Encryption mode not accepted. */ +#define BLE_LL_ERR_LINK_KEY_CANT_CHANGE 0xB6 /**< Link Key cannot be changed. */ +#define BLE_LL_ERR_QOS_NOT_SUPPORTED 0xB7 /**< Quality of Service not supported. */ +#define BLE_LL_ERR_INSTANT_PASSED 0xB8 /**< Error, instant passed. */ +#define BLE_LL_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUP 0xB9 /**< Pairing with unit key not supported. */ +#define BLE_LL_ERR_DIFF_TRANSACTION_COLLISION 0xBA /**< Transaction collision. */ +#define BLE_LL_ERR_QOS_UNACCEPTABLE_PARAM 0xBC /**< Quality of Service not supported. */ +#define BLE_LL_ERR_QOS_REJECTED 0xBD /**< Quality of Service rejected. */ +#define BLE_LL_ERR_CHANNEL_CLASS_NOT_SUP 0xBE /**< Channel class not supported. */ +#define BLE_LL_ERR_INSUFFICIENT_SECURITY 0xBF /**< Insufficient security. */ +#define BLE_LL_ERR_PARAM_OUT_OF_MAND_RANGE 0xC0 /**< Parameters out of mandatory range. */ +#define BLE_LL_ERR_ROLE_SWITCH_PEND 0xC2 /**< Role switch pending. */ +#define BLE_LL_ERR_RESERVED_SLOT_VIOLATION 0xC4 /**< Reserved slot violation. */ +#define BLE_LL_ERR_ROLE_SWITCH_FAIL 0xC5 /**< Role Switch failed. */ +#define BLE_LL_ERR_EIR_TOO_LARGE 0xC6 /**< Error: EIR too large. */ +#define BLE_LL_ERR_SP_NOT_SUPPORTED_HOST 0xC7 /**< Simple pairing not supported by host. */ +#define BLE_LL_ERR_HOST_BUSY_PAIRING 0xC8 /**< Host pairing is busy. */ +#define BLE_LL_ERR_CONTROLLER_BUSY 0xCA /**< Controller is busy. */ +#define BLE_LL_ERR_UNACCEPTABLE_CONN_INT 0xCB /**< Unacceptable connection initialization. */ +#define BLE_LL_ERR_ADV_TO 0xCC /**< Advertising Timeout. */ +#define BLE_LL_ERR_TERMINATED_MIC_FAILURE 0xCD /**< Connection Terminated due to a MIC failure. */ +#define BLE_LL_ERR_CONN_FAILED_TO_BE_EST 0xCE /**< Connection failed to be established. */ /**@} */ /** * @defgroup BLE_ERROR_TYPEDEF Typedefs * @{ */ - /**@brief Callback function error parameter type. */ -typedef unsigned char ble_err_t; +typedef uint8_t ble_err_t; /**@brief SDK API result type. */ -typedef unsigned short sdk_err_t; +typedef uint16_t sdk_err_t; /**@} */ /**@} */ + #endif /** @} */ /** @} */ + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_event.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_event.h new file mode 100644 index 0000000..1e3995a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_event.h @@ -0,0 +1,220 @@ +/** + **************************************************************************************** + * + * @file ble_event.h + * + * @brief BLE event header files + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + /** + * @addtogroup BLE + * @{ + */ + +/** + @addtogroup BLE_EVENT BLE Event + @{ + @brief BLE Event interface. + */ +#ifndef __BLE_EVENT_H__ +#define __BLE_EVENT_H__ + +#include "ble_gapm.h" +#include "ble_gapc.h" +#include "ble_gatts.h" +#include "ble_gattc.h" +#include "ble_sec.h" +#include "ble_l2cap.h" + +/** @addtogroup BLE_EVENT_DEFINES Defines + * @{ +*/ +/** @defgroup BLE_EVENT_BASE BLE Event Base + * @{ */ +#define BLE_COMMON_EVT_BASE 0x0100 /**< BLE Common Event base. */ +#define BLE_GAPM_EVT_BASE 0x0200 /**< BLE GAP Management Event base. */ +#define BLE_GAPC_EVT_BASE 0x0300 /**< BLE GAP Connection Control Event base. */ +#define BLE_GATTS_EVT_BASE 0x0400 /**< BLE GATTS Event base. */ +#define BLE_GATTC_EVT_BASE 0x0500 /**< BLE GATTC Event base. */ +#define BLE_GATT_COMMON_EVT_BASE 0x0600 /**< BLE GATT Event base. */ +#define BLE_SEC_EVT_BASE 0x0700 /**< BLE Security Event base. */ +#define BLE_L2CAP_EVT_BASE 0x0800 /**< BLE L2CAP Event base. */ +/** @} */ +/** @} */ + +/** + * @defgroup BLE_EVENT_ENUM Enumerations + * @{ + */ +/** + * @brief BLE Common Events. + */ +enum BLE_COMMON_EVTS +{ + BLE_COMMON_EVT_STACK_INIT = BLE_COMMON_EVT_BASE, /**< BLE Stack init complete event. */ + BLE_COMMON_EVT_MAX, +}; + +/**@brief BLE GAP Managerment Events. */ +enum BLE_GAPM_EVTS +{ + BLE_GAPM_EVT_CH_MAP_SET = BLE_GAPM_EVT_BASE, /**< Channel Map Set complete event. */ + BLE_GAPM_EVT_WHITELIST_SET, /**< Whitelist Set complete event. */ + BLE_GAPM_EVT_PER_ADV_LIST_SET, /**< Periodic Advertising List Set complete event. */ + BLE_GAPM_EVT_PRIVACY_MODE_SET, /**< Privacy Mode for Peer Device Set complete event. */ + BLE_GAPM_EVT_LEPSM_REGISTER, /**< LEPSM Register complete event. */ + BLE_GAPM_EVT_LEPSM_UNREGISTER, /**< LEPSM Unregister complete event. */ + BLE_GAPM_EVT_DEV_INFO_GOT, /**< Device Info Get event. */ + BLE_GAPM_EVT_ADV_START, /**< Advertising Start complete event. */ + BLE_GAPM_EVT_ADV_STOP, /**< Advertising Stop complete event. */ + BLE_GAPM_EVT_SCAN_REQUEST, /**< Scan Request event. */ + BLE_GAPM_EVT_ADV_DATA_UPDATE, /**< Advertising Data update event. */ + BLE_GAPM_EVT_SCAN_START, /**< Scan Start complete event. */ + BLE_GAPM_EVT_SCAN_STOP, /**< Scan Stop complete event. */ + BLE_GAPM_EVT_ADV_REPORT, /**< Advertising Report event. */ + BLE_GAPM_EVT_SYNC_ESTABLISH, /**< Periodic Advertising Synchronization Establish event. */ + BLE_GAPM_EVT_SYNC_STOP, /**< Periodic Advertising Synchronization Stop event. */ + BLE_GAPM_EVT_SYNC_LOST, /**< Periodic Advertising Synchronization Lost event. */ + BLE_GAPM_EVT_READ_RSLV_ADDR, /**< Read Resolvable Address event. */ + BLE_GAPM_EVT_MAX, +}; + +/**@brief BLE GAP Connection Control Events. */ +enum BLE_GAPC_EVTS +{ + BLE_GAPC_EVT_PHY_UPDATED = BLE_GAPC_EVT_BASE, /**< PHY Update event. */ + BLE_GAPC_EVT_CONNECTED, /**< Connected event. */ + BLE_GAPC_EVT_DISCONNECTED, /**< Disconnected event. */ + BLE_GAPC_EVT_CONNECT_CANCLE, /**< Connect Cancle event. */ + BLE_GAPC_EVT_AUTO_CONN_TIMEOUT, /**< Auto Connect Timeout event. */ + BLE_GAPC_EVT_CONN_PARAM_UPDATED, /**< Connect Parameter Updated event. */ + BLE_GAPC_EVT_CONN_PARAM_UPDATE_REQ, /**< Connect Parameter Request event. */ + BLE_GAPC_EVT_PEER_NAME_GOT, /**< peer Name Get event. */ + BLE_GAPC_EVT_CONN_INFO_GOT, /**< Connect Info Get event. */ + BLE_GAPC_EVT_PEER_INFO_GOT, /**< Peer Info Get event. */ + BLE_GAPC_EVT_DATA_LENGTH_UPDATED, /**< Data Length Updated event. */ + BLE_GAPC_EVT_MAX, +}; + +/**@brief BLE GATT Common Events. */ +enum BLE_GATT_COMMON_EVTS +{ + BLE_GATT_COMMON_EVT_MTU_EXCHANGE = BLE_GATT_COMMON_EVT_BASE, /**< MTU Exchange event. */ + BLE_GATT_COMMON_EVT_PRF_REGISTER, /**< Service Register event. */ + BLE_GATT_COMMON_EVT_MAX, +}; + +/**@brief BLE GATTS Events. */ +enum BLE_GATTS_EVTS +{ + BLE_GATTS_EVT_READ_REQUEST = BLE_GATTS_EVT_BASE, /**< GATTS Read Request event .*/ + BLE_GATTS_EVT_WRITE_REQUEST, /**< GATTS Write Request event .*/ + BLE_GATTS_EVT_PREP_WRITE_REQUEST, /**< GATTS Prepare Write Request event .*/ + BLE_GATTS_EVT_NTF_IND, /**< GATTS Notify or Indicate Complete event .*/ + BLE_GATTS_EVT_CCCD_RECOVERY, /**< GATTS CCCD Recovery event .*/ + BLE_GATTS_EVT_MAX, +}; + +/**@brief BLE GATTC Events. */ +enum BLE_GATTC_EVTS +{ + BLE_GATTC_EVT_SRVC_BROWSE = BLE_GATTC_EVT_BASE, /**< GATTC Service Browse event .*/ + BLE_GATTC_EVT_PRIMARY_SRVC_DISC, /**< GATTC Primary Service Discovery event .*/ + BLE_GATTC_EVT_INCLUDE_SRVC_DISC, /**< GATTC Include Service Discovery event .*/ + BLE_GATTC_EVT_CHAR_DISC, /**< GATTC Characteristic Discovery event .*/ + BLE_GATTC_EVT_CHAR_DESC_DISC, /**< GATTC Characteristic Descriptor Discovery event .*/ + BLE_GATTC_EVT_READ_RSP, /**< GATTC Read Response event. */ + BLE_GATTC_EVT_WRITE_RSP, /**< GATTC Write Response event. */ + BLE_GATTC_EVT_NTF_IND, /**< GATTC Notify or Indicate Receive event. */ + BLE_GATTC_EVT_MAX, +}; + +/**@brief BLE SEC Events. */ +enum BLE_SEC_EVTS +{ + BLE_SEC_EVT_LINK_ENC_REQUEST = BLE_SEC_EVT_BASE, /**< Link Encrypte Request event. */ + BLE_SEC_EVT_LINK_ENCRYPTED, /**< Link Encrypted event. */ + BLE_SEC_EVT_LTK_REQ, /**< LTK Request event. */ + BLE_SEC_EVT_KEY_PRESS_NTF, /**< Key Press event. */ + BLE_SEC_EVT_KEY_MISSING, /**< Key Missing event. */ + BLE_SEC_EVT_MAX, +}; + +/**@brief BLE L2CAP Events. */ +enum BLE_L2CAP_EVTS +{ + BLE_L2CAP_EVT_CONN_REQ = BLE_L2CAP_EVT_BASE, /**< L2cap Connect Request event. */ + BLE_L2CAP_EVT_CONN_IND, /**< L2cap Connected Indicate event. */ + BLE_L2CAP_EVT_ADD_CREDITS_IND, /**< L2cap Credits Add Indicate event. */ + BLE_L2CAP_EVT_DISCONNECTED, /**< L2cap Disconnected event. */ + BLE_L2CAP_EVT_SDU_RECV, /**< L2cap SDU Receive event. */ + BLE_L2CAP_EVT_SDU_SEND, /**< L2cap SDU Send event. */ + BLE_L2CAP_EVT_ADD_CREDITS_CPLT, /**< L2cap Credits Add Completed event. */ + BLE_L2CAP_EVT_MAX, +}; +/** @} */ + +/** @addtogroup BLE_COMMEN_STRUCTURES Structures + * @{ + */ +/**@brief BLE Event Information. */ +typedef struct +{ + uint16_t evt_id; /**< Event ID. */ + uint16_t evt_status; /**< Event Status. */ + union + { + ble_gapm_evt_t gapm_evt; /**< BLE GAP Management Event. */ + ble_gapc_evt_t gapc_evt; /**< BLE GAP Connection Control Event. */ + ble_gatts_evt_t gatts_evt; /**< BLE GATT Server Event. */ + ble_gattc_evt_t gattc_evt; /**< BLE GATT Client Event. */ + ble_gatt_common_evt_t gatt_common_evt; /**< BLE GATT Common Event. */ + ble_sec_evt_t sec_evt; /**< BLE Security Event. */ + ble_l2cap_evt_t l2cap_evt; /**< BLE L2CAP Event. */ + } evt; /**< BLE Event parameter. */ +} ble_evt_t; +/** @} */ + +/** @addtogroup BLE_EVENT_TYPEDEF Typedefs + * @{ + */ +/**@brief The BLE event handler type. */ +typedef void (*ble_evt_handler_t)(const ble_evt_t *p_evt); +/** @} */ + +#endif +/** @} */ +/** @} */ + + + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapc.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapc.h old mode 100755 new mode 100644 index 3c7bf34..552a314 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapc.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gapc.h @@ -35,142 +35,116 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -* @brief Definitions and prototypes for the BLE SDK interface. -*/ - -/** -* @addtogroup BLE_GAP Generic Access Profile (GAP) -* @{ -* @brief Definitions and prototypes for the GAP interface. -*/ - -/** -* @defgroup BLE_GAPC Generic Access Profile (GAP) Connection Control -* @{ -* @brief Definitions and prototypes for the GAP Connection Control interface. -*/ + /** + * @addtogroup BLE + * @{ + * @brief Definitions and prototypes for the BLE SDK interface. + */ + + /** + * @addtogroup BLE_GAP Generic Access Profile (GAP) + * @{ + * @brief Definitions and prototypes for the GAP interface. + */ + + /** + * @defgroup BLE_GAPC Generic Access Profile (GAP) Connection Control + * @{ + * @brief Definitions and prototypes for the GAP Connection Control interface. + */ #ifndef __BLE_GAPC_H__ #define __BLE_GAPC_H__ -#include // Standard Integer -#include +#include "ble_error.h" #include "gr55xx_sys_cfg.h" +#include // Standard Integer +#include +#include /** * @defgroup BLE_GAPC_DEFINES Defines * @{ */ -#define GAP_CHNL_MAP_LEN 0x05 /**< The length of channel map. */ -#define GAP_FEATS_LEN 0x08 /**< The length of features. */ -#define GAP_ADDR_LEN 0x06 /**< The length of address. */ -#define GAP_INVALID_CONN_INDEX 0xFF /**< Invalid connection index. */ +#define BLE_GAP_CHNL_MAP_LEN 0x05 /**< The length of channel map. */ +#define BLE_GAP_FEATS_LEN 0x08 /**< The length of features. */ +#define BLE_GAP_ADDR_LEN 0x06 /**< The length of address. */ +#define BLE_GAP_INVALID_CONN_INDEX 0xFF /**< Invalid connection index. */ /**@defgroup BLE_GAP_ADDR_TYPES GAP Address types * @{ */ -#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ /**@} */ /**@defgroup BLE_GAP_PHY_OPTIONS GAP PHY OPTIONS (bitmask) * @{ */ -#define PHY_OPT_NO_CODING 0x00 /**< The Host has no preferred coding when transmitting on the LE Coded PHY. */ -#define PHY_OPT_S2_CODING 0x01 /**< The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY. */ -#define PHY_OPT_S8_CODING 0x02 /**< The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY. */ +#define BLE_GAP_PHY_OPT_NO_CODING 0x00 /**< The Host has no preferred coding when transmitting on the LE Coded PHY. */ +#define BLE_GAP_PHY_OPT_S2_CODING 0x01 /**< The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY. */ +#define BLE_GAP_PHY_OPT_S8_CODING 0x02 /**< The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY. */ /**@} */ /** @} */ /** - * @defgroup BLE_SDK_GAP_ENUM Enumerations + * @defgroup BLE_GAPC_ENUM Enumerations * @{ */ /** @brief The operation code used to get connection info */ -typedef enum { - GAP_GET_CON_RSSI = 0, /**< Get connection RSSI info. */ - GAP_GET_CON_CHANNEL_MAP, /**< Get connection channel map. */ - GAP_GET_PHY, /**< Get connection PHY. */ - GAP_GET_CHAN_SEL_ALGO /**< Get selection algorithm for connection channel. */ -} gap_get_conn_info_op_t; +typedef enum +{ + BLE_GAP_GET_CON_RSSI = 0, /**< Get connection RSSI info. */ + BLE_GAP_GET_CON_CHANNEL_MAP, /**< Get connection channel map. */ + BLE_GAP_GET_PHY, /**< Get connection PHY. */ + BLE_GAP_GET_CHAN_SEL_ALGO /**< Get selection algorithm for connection channel. */ +} ble_gap_get_conn_info_op_t; /**@brief The operation code used to get peer device info. */ -typedef enum { - GAP_GET_PEER_VERSION = 0, /**< Get peer device version info. */ - GAP_GET_PEER_FEATURES /**< Get peer device features info. */ -} gap_get_peer_info_op_t; - -/** @brief Advertising report type. */ -typedef enum { - GAP_REPORT_TYPE_ADV_EXT = 0, /**< Extended advertising report. */ - GAP_REPORT_TYPE_ADV_LEG, /**< Legacy advertising report. */ - GAP_REPORT_TYPE_SCAN_RSP_EXT, /**< Extended scan response report. */ - GAP_REPORT_TYPE_SCAN_RSP_LEG, /**< Legacy scan response report. */ - GAP_REPORT_TYPE_PER_ADV, /**< Periodic advertising report. */ -} gap_adv_report_type_t; - -/** @brief Advertising report information. */ -typedef enum { - GAP_REPORT_INFO_COMPLETE_BIT = (1 << 0), /**< Report is complete. */ - GAP_REPORT_INFO_CONN_ADV_BIT = (1 << 1), /**< Connectable advertising. */ - GAP_REPORT_INFO_SCAN_ADV_BIT = (1 << 2), /**< Scannable advertising. */ - GAP_REPORT_INFO_DIR_ADV_BIT = (1 << 3), /**< Directed advertising. */ -} gap_adv_report_info_t; - -/** @brief Stop reason code. */ -typedef enum { - GAP_STOPPED_REASON_TIMEOUT = 0, /**< Stop with timeout. */ - GAP_STOPPED_REASON_ON_USER, /**< Stop with user stopping it actively. */ - GAP_STOPPED_REASON_CONN_EST /**< Stop with connection established. */ -} gap_stopped_reason_t; +typedef enum +{ + BLE_GAP_GET_PEER_VERSION = 0, /**< Get peer device version info. */ + BLE_GAP_GET_PEER_FEATURES /**< Get peer device features info. */ +} ble_gap_get_peer_info_op_t; /** @brief Device role of LL layer type */ -typedef enum { - GAP_LL_ROLE_MASTER = 0, /**< Master role. */ - GAP_LL_ROLE_SLAVE = 1, /**< Slave role. */ -} gap_ll_role_type_t; +typedef enum +{ + BLE_GAP_LL_ROLE_MASTER = 0, /**< Master role. */ + BLE_GAP_LL_ROLE_SLAVE = 1, /**< Slave role. */ +} ble_gap_ll_role_type_t; /** * @brief Operation code used to set param(s). */ -typedef enum { - GAP_OPCODE_CHNL_MAP_SET, /**< Set Channel Map. */ - GAP_OPCODE_WHITELIST_SET, /**< Set white list. */ - GAP_OPCODE_PER_ADV_LIST_SET, /**< Set periodic advertising list. */ - GAP_OPCODE_PRIVACY_MODE_SET, /**< Set privacy mode for peer device. */ -} gap_param_set_op_id_t; - -/** - * @brief Operation code used to read resolvable address. - */ -typedef enum { - GAP_OPCODE_LOCAL_RSLV_ADDR_READ, /**< Local resolvable address operation. */ - GAP_OPCODE_PEER_RSLV_ADDR_READ, /**< Peer resolvable address operation. */ -} gap_rslv_addr_read_op_id_t; +typedef enum +{ + BLE_GAP_OPCODE_CHNL_MAP_SET, /**< Set Channel Map. */ + BLE_GAP_OPCODE_WHITELIST_SET, /**< Set white list. */ + BLE_GAP_OPCODE_PER_ADV_LIST_SET, /**< Set periodic advertising list. */ + BLE_GAP_OPCODE_PRIVACY_MODE_SET, /**< Set privacy mode for peer device. */ +} ble_gap_param_set_op_id_t; /** * @brief Operation code used for LEPSM manager. */ -typedef enum { - GAP_OPCODE_LEPSM_REGISTER, /**< LEPSM register operation. */ - GAP_OPCODE_LEPSM_UNREGISTER, /**< LEPSM unregister operation. */ -} gap_psm_manager_op_id_t; +typedef enum +{ + BLE_GAP_OPCODE_LEPSM_REGISTER, /**< LEPSM register operation. */ + BLE_GAP_OPCODE_LEPSM_UNREGISTER, /**< LEPSM unregister operation. */ +} ble_gap_psm_manager_op_id_t; /** * @brief The specified reason for terminating a connection. */ -typedef enum { - GAP_HCI_AUTHENTICATION_FAILURE = 0x05, /**< Authentication Failure. */ - GAP_HCI_REMOTE_USER_TERMINATED_CONNECTION = 0x13, /**< Remote User Terminated Connection. */ - GAP_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to - Low Resources . */ - GAP_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to - Power Off. */ - GAP_HCI_UNSUPPORTED_REMOTE_FEATURE = 0x1A, /**< Unsupported Remote Feature. */ - GAP_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED = 0X29, /**< Pairing With Unit Key Not Supported. */ - GAP_HCI_CONN_INTERVAL_UNACCEPTABLE = 0x3B, /**< Unacceptable Connection Parameters. */ -} gap_disconn_reason_t; +typedef enum +{ + BLE_GAP_HCI_AUTHENTICATION_FAILURE = 0x05, /**< Authentication Failure. */ + BLE_GAP_HCI_REMOTE_USER_TERMINATED_CONNECTION = 0x13, /**< Remote User Terminated Connection. */ + BLE_GAP_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to Low Resources . */ + BLE_GAP_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to Power Off. */ + BLE_GAP_HCI_UNSUPPORTED_REMOTE_FEATURE = 0x1A, /**< Unsupported Remote Feature. */ + BLE_GAP_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED = 0X29, /**< Pairing With Unit Key Not Supported. */ + BLE_GAP_HCI_CONN_INTERVAL_UNACCEPTABLE = 0x3B, /**< Unacceptable Connection Parameters. */ +} ble_gap_disconn_reason_t; /** @} */ @@ -180,593 +154,312 @@ typedef enum { */ /** @brief The struct of device version. */ -typedef struct { - uint8_t hci_ver; /**< HCI version. */ - uint8_t lmp_ver; /**< LMP version. */ - uint8_t host_ver; /**< Host version. */ - uint16_t hci_subver; /**< HCI subversion. */ - uint16_t lmp_subver; /**< LMP subversion. */ - uint16_t host_subver; /**< Host subversion. */ - uint16_t manuf_name; /**< Manufacturer name. */ -} gap_dev_version_ind_t; +typedef struct +{ + uint8_t hci_ver; /**< HCI version. */ + uint8_t lmp_ver; /**< LMP version. */ + uint8_t host_ver; /**< Host version. */ + uint16_t hci_subver; /**< HCI subversion. */ + uint16_t lmp_subver; /**< LMP subversion. */ + uint16_t host_subver; /**< Host subversion. */ + uint16_t manuf_name; /**< Manufacturer name. */ +} ble_gap_dev_version_ind_t; /** @brief The struct of address. */ -typedef struct { - uint8_t addr[GAP_ADDR_LEN]; /**< 6-byte array address value. */ -} gap_addr_t; +typedef struct +{ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 6-byte array address value. */ +} ble_gap_addr_t; /** @brief The struct of broadcast address with broadcast type. */ -typedef struct { - gap_addr_t gap_addr; /**< Device BD Address. */ - uint8_t addr_type; /**< Address type of the device: 0=public/1=random. please @ref BLE_GAP_ADDR_TYPES. */ -} gap_bdaddr_t; +typedef struct +{ + ble_gap_addr_t gap_addr; /**< Device BD Address. */ + uint8_t addr_type; /**< Address type of the device: 0=public/1=random. please @ref BLE_GAP_ADDR_TYPES. */ +} ble_gap_bdaddr_t; /** @brief Get broadcast address struct. */ -typedef struct { - uint8_t index; /**< Advertsing index. The valid range is: 0 - 4. */ - gap_bdaddr_t bd_addr; /**< BD address. */ -} gap_get_bd_addr_t; +typedef struct +{ + uint8_t index; /**< Advertsing index. The valid range is: 0 - 4. */ + ble_gap_bdaddr_t bd_addr; /**< BD address. */ +} ble_gap_get_bd_addr_t; /** @brief TX power info struct. */ -typedef struct { - int8_t power_lvl; /**< Advertising channel TX power level. Range: -20 to 10. Unit: dBm. Accuracy: +/-4dB. */ -} gap_dev_adv_tx_power_t; +typedef struct +{ + int8_t power_lvl; /**< Advertising channel TX power level. Range: -20 to 10. Unit: dBm. Accuracy: +/-4dB. */ +} ble_gap_dev_adv_tx_power_t; /** @brief TX power info struct. */ -typedef struct { +typedef struct +{ int8_t min_tx_pwr; /**< MIN of TX power. Size: 1 octet (signed integer). Range: -127 to +126. Unit: dBm. */ int8_t max_tx_pwr; /**< MAX of TX power. Size: 1 octet (signed integer). Range: -127 to +126. Unit: dBm. */ -} gap_dev_tx_power_t; +} ble_gap_dev_tx_power_t; /** @brief Max data length info struct. */ -typedef struct { - uint16_t suppted_max_tx_octets; /**< Maximum number of payload octets that the local Controller supports - for transmission of a single Link Layer packet on a data connection. - Range: 0x001B-0x00FB (all other values reserved for future use). */ - uint16_t suppted_max_tx_time; /**< Maximum time, in microseconds, that the local Controller supports - for transmission of a single Link Layer packet on a data connection. - Range: 0x0148-0x4290 (all other values reserved for future use). */ - uint16_t suppted_max_rx_octets; /**< Maximum number of payload octets that the local Controller supports - for reception of a single Link Layer packet on a data connection. - Range: 0x001B-0x00FB (all other values reserved for future use). */ - uint16_t suppted_max_rx_time; /**< Maximum time, in microseconds, that the local Controller supports - for reception of a single Link Layer packet on a data connection. - Range: 0x0148-0x4290 (all other values reserved for future use). */ -} gap_max_data_len_t; +typedef struct +{ + uint16_t suppted_max_tx_octets; /**< Maximum number of payload octets that the local Controller supports for transmission of a single Link Layer packet on a data connection. + Range: 0x001B-0x00FB (all other values reserved for future use). */ + uint16_t suppted_max_tx_time; /**< Maximum time, in microseconds, that the local Controller supports for transmission of a single Link Layer packet on a data connection. + Range: 0x0148-0x4290 (all other values reserved for future use). */ + uint16_t suppted_max_rx_octets; /**< Maximum number of payload octets that the local Controller supports for reception of a single Link Layer packet on a data connection. + Range: 0x001B-0x00FB (all other values reserved for future use). */ + uint16_t suppted_max_rx_time; /**< Maximum time, in microseconds, that the local Controller supports for reception of a single Link Layer packet on a data connection. + Range: 0x0148-0x4290 (all other values reserved for future use). */ +} ble_gap_max_data_len_t; /** @brief Suggested default data length info. */ -typedef struct { - uint16_t suggted_max_tx_octets; /**< The Host's suggested value for the Controller's maximum transmitted number of - payload octets to be used for new connections. - Range: 0x001B-0x00FB (all other values reserved for future use), - default: 0x001B */ - uint16_t suggted_max_tx_time; /**< The Host's suggested value for the Controller's maximum packet - transmissiontime to be used for new connections. - Range: 0x0148-0x4290 (all other values reserved for future use), - default: 0x0148 */ -} gap_sugg_dflt_data_len_t; +typedef struct +{ + uint16_t suggted_max_tx_octets; /**< The Host's suggested value for the Controller's maximum transmitted number of payload octets to be used for new connections. + Range: 0x001B-0x00FB (all other values reserved for future use), default: 0x001B */ + uint16_t suggted_max_tx_time; /**< The Host's suggested value for the Controller's maximum packet transmission time to be used for new connections. + Range: 0x0148-0x4290 (all other values reserved for future use), default: 0x0148*/ +} ble_gap_sugg_dflt_data_len_t; /** @brief Number of available advertising sets info. */ -typedef struct { - uint8_t nb_adv_sets; /**< Number of available advertising sets. */ -} gap_nb_adv_sets_t; +typedef struct +{ + uint8_t nb_adv_sets; /**< Number of available advertising sets. */ +} ble_gap_nb_adv_sets_t; /** @brief Maximum advertising data length info. */ -typedef struct { - uint16_t length; /**< Maximum advertising data length supported by controller. */ -} gap_max_adv_data_len_ind_t; +typedef struct +{ + uint16_t length; /**< Maximum advertising data length supported by controller. */ +} ble_gap_max_adv_data_len_ind_t; /** @brief RF path compensation values info. */ -typedef struct { - uint16_t tx_path_comp; /**< RF TX path compensation. */ - uint16_t rx_path_comp; /**< RF RX path compensation. */ -} gap_dev_rf_path_comp_ind_t; +typedef struct +{ + uint16_t tx_path_comp; /**< RF TX path compensation. */ + uint16_t rx_path_comp; /**< RF RX path compensation. */ +} ble_gap_dev_rf_path_comp_ind_t; /** @brief Device info. */ -typedef union { - gap_dev_version_ind_t dev_version; /**< Version info. */ - gap_get_bd_addr_t get_bd_addr; /**< Device BD address info. */ - gap_dev_adv_tx_power_t adv_tx_power; /**< Advertising TX power info. */ - gap_sugg_dflt_data_len_t sugg_dflt_data_len; /**< Suggested default data length info. */ - gap_max_data_len_t max_data_len; /**< Suggested MAX data length info. */ - gap_nb_adv_sets_t nb_adv_sets; /**< Number of available advertising sets. */ - gap_max_adv_data_len_ind_t max_adv_data_len; /**< Maximum advertising data length info. */ - gap_dev_tx_power_t dev_tx_power; /**< Device TX power info. */ - gap_dev_rf_path_comp_ind_t dev_rf_path_comp; /**< RF path compensation values. */ -} gap_dev_info_t; - -/** @brief Get device info operation struct. */ -typedef struct { - uint8_t operation; /**< Operation code. @see enum gap_dev_info_get_type_t. */ - gap_dev_info_t dev_info; /**< Device info. */ -} gap_dev_info_get_t; - -/** @brief Read resolvable address info struct. */ -typedef struct { - uint8_t op_code; /**< Operation code. @see enum gap_rslv_addr_read_op_id_t. */ - gap_addr_t gap_addr; /**< Resolvable address info. */ -} gap_rslv_addr_read_t; - -/** @brief Sync established indication. */ -typedef struct { - uint8_t phy; /**< PHY on which synchronization has been established. @see gap_phy_type. */ - uint16_t intv; /**< Periodic advertising interval (in unit of 1.25ms, min is 7.5ms). */ - uint8_t adv_sid; /**< Advertising SID. */ - uint8_t clk_acc; /**< Advertiser clock accuracy. @see enum gapm_clk_acc. */ - gap_bdaddr_t bd_addr; /**< Advertiser address. */ - uint16_t sync_hdl; /**< Sync handle. */ -} gap_sync_established_ind_t; - -/** @brief APP receives the extended advertising report indication info struct. */ -typedef struct { - uint8_t adv_type; /**< Advertising type. @see enum gap_adv_report_type_t. */ - uint8_t adv_info; /**< Bit field providing information about the received report. - @see enum gap_adv_report_info_t. */ - gap_bdaddr_t broadcaster_addr; /**< Broadcaster device address. */ - gap_bdaddr_t direct_addr; /**< Target address (in case of a directed advertising report). */ - int8_t tx_pwr; /**< TX power (in dBm). */ - int8_t rssi; /**< RSSI (between -127 and +20 dBm). */ - uint8_t phy_prim; /**< Primary PHY on which advertising report has been received. */ - uint8_t phy_second; /**< Secondary PHY on which advertising report has been received. */ - uint8_t adv_sid; /**< Advertising SID , valid only for periodic advertising report. */ - uint16_t period_adv_intv; /**< Periodic advertising interval (in unit of 1.25ms, min is 7.5ms), - valid only for periodic advertising report. */ - uint8_t per_sync_idx; /**< Periodic syncronization index, - valid only for periodic advertising report. */ - uint16_t length; /**< Report length. */ - uint8_t data[ARRAY_EMPTY]; /**< Report. */ -} gap_ext_adv_report_ind_t; - -/** @brief Name of peer device indication. */ -typedef struct { - gap_addr_t peer_addr; /**< Peer device bd address. */ - uint8_t addr_type; /**< Peer device address type. */ - uint8_t name_len; /**< Peer device name length. */ - uint8_t name[ARRAY_EMPTY]; /**< Peer device name. */ -} gap_peer_name_ind_t; - -/** @brief Connection parameter used to update connection parameters. */ -typedef struct { - uint16_t interval; /**< Connection interval. Range: 0x0006 to 0x0C80. - Unit: 1.25 ms. Time range: 7.5 ms to 4 s. */ - uint16_t latency; /**< Latency for the connection in number of connection events. - Range: 0x0000 to 0x01F3. */ - uint16_t sup_timeout; /**< Supervision timeout for the LE link. Range: 0x000A to 0x0C80, - unit: 10 ms, time range: 100 ms to 32 s. */ -} gap_conn_update_cmp_t; +typedef union +{ + ble_gap_dev_version_ind_t dev_version; /**< Version info. */ + ble_gap_get_bd_addr_t get_bd_addr; /**< Device BD address info. */ + ble_gap_dev_adv_tx_power_t adv_tx_power; /**< Advertising TX power info. */ + ble_gap_sugg_dflt_data_len_t sugg_dflt_data_len; /**< Suggested default data length info. */ + ble_gap_max_data_len_t max_data_len; /**< Suggested MAX data length info. */ + ble_gap_nb_adv_sets_t nb_adv_sets; /**< Number of available advertising sets. */ + ble_gap_max_adv_data_len_ind_t max_adv_data_len; /**< Maximum advertising data length info. */ + ble_gap_dev_tx_power_t dev_tx_power; /**< Device TX power info. */ + ble_gap_dev_rf_path_comp_ind_t dev_rf_path_comp; /**< RF path compensation values. */ +} ble_gap_dev_info_t; /** @brief The parameter of connection. */ -typedef struct { - uint16_t interval_min; /**< Minimum value for the connection interval. - This shall be less than or equal to Conn_Interval_Max. - Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s */ - uint16_t interval_max; /**< Maximum value for the connection interval. - This shall be greater than or equal to Conn_Interval_Min. - Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s. */ - uint16_t slave_latency; /**< Slave latency for the connection in number of connection events. - Range: 0x0000 to 0x01F3. */ - uint16_t sup_timeout; /**< Supervision timeout for the LE link. Range: 0x000A to 0x0C80, - unit: 10 ms, time range: 100 ms to 32 s. */ -} gap_conn_param_t; +typedef struct +{ + uint16_t interval_min; /**< Minimum value for the connection interval. This shall be less than or equal to Conn_Interval_Max. + Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s*/ + uint16_t interval_max; /**< Maximum value for the connection interval. This shall be greater than or equal to Conn_Interval_Min. + Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s.*/ + uint16_t slave_latency; /**< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3. */ + uint16_t sup_timeout; /**< Supervision timeout for the LE link. Range: 0x000A to 0x0C80, unit: 10 ms, time range: 100 ms to 32 s. */ +} ble_gap_conn_param_t; /** @brief The parameter of update connection. */ -typedef struct { - uint16_t interval_min; /**< Minimum value for the connection interval. - This shall be less than or equal to Conn_Interval_Max. - Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s */ - uint16_t interval_max; /**< Maximum value for the connection interval. - This shall be greater than or equal to Conn_Interval_Min. - Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s. */ - uint16_t slave_latency; /**< Slave latency for the connection in number of connection events. - Range: 0x0000 to 0x01F3. */ - uint16_t sup_timeout; /**< Supervision timeout for the LE link. range: 0x000A to 0x0C80, - unit: 10 ms, Time range: 100 ms to 32 s. */ - uint16_t ce_len; /**< The length of connection event needed for this LE connection. - Range: 0x0002 to 0xFFFF, unit: 0.625 ms, time Range: 1.25 ms to 40.9 s. - recommended value: 0x0002 for 1M phy, 0x0006 for coded phy */ -} gap_conn_update_param_t; - -/** @brief Connection complete info. */ -typedef struct { - uint16_t - conhdl; /**< Connection_Handle. Range: 0x0000-0x0EFF (all other values reserved for future use). */ - uint16_t - con_interval; /**< Connection interval. Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s. */ - uint16_t - con_latency; /**< Latency for the connection in number of connection events. Range: 0x0000 to 0x01F3. */ - uint16_t - sup_to; /**< Connection supervision timeout. Range: 0x000A to 0x0C80, - unit: 10 ms, time range: 100 ms to 32 s. */ - uint8_t - clk_accuracy; /**< Clock accuracy (0x00: 500 ppm, 0x01: 250 ppm, 0x02: 150 ppm, 0x03: 100 ppm, 0x04: 75 ppm, - 0x05:50 ppm, 0x06:30 ppm, 0x07:20 ppm, others: reserved for future use). */ - uint8_t - peer_addr_type; /**< Peer address type(0x00: Public Device Address, 0x01 : Random Device Address, - others: reserved for future use). */ - gap_addr_t peer_addr; /**< Peer BT address. */ - gap_ll_role_type_t ll_role; /**< Device Role of LL Layer. */ -} gap_conn_cmp_t; +typedef struct +{ + uint16_t interval_min; /**< Minimum value for the connection interval. This shall be less than or equal to Conn_Interval_Max. + Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s*/ + uint16_t interval_max; /**< Maximum value for the connection interval. This shall be greater than or equal to Conn_Interval_Min. + Range: 0x0006 to 0x0C80, unit: 1.25 ms, time range: 7.5 ms to 4 s.*/ + uint16_t slave_latency; /**< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3. */ + uint16_t sup_timeout; /**< Supervision timeout for the LE link. range: 0x000A to 0x0C80, unit: 10 ms, Time range: 100 ms to 32 s. */ + uint16_t ce_len; /**< The length of connection event needed for this LE connection. Range: 0x0002 to 0xFFFF, unit: 0.625 ms, time Range: 1.25 ms to 40.9 s. + recommended value: 0x0002 for 1M phy, 0x0006 for coded phy */ +} ble_gap_conn_update_param_t; /** @brief Channel map structure. */ -typedef struct { - uint8_t map[GAP_CHNL_MAP_LEN]; /**< This parameter contains 37 1-bit fields. - The nth bit (n is in the range of 0 to 36) contains the value for - the link layer channel index n. - Channel n is unused = 0, channel n is used = 1. - The most significant bits are reserved for future use. */ -} gap_chnl_map_t; +typedef struct +{ + uint8_t map[BLE_GAP_CHNL_MAP_LEN]; /**< This parameter contains 37 1-bit fields. The nth bit (n is in the range of 0 to 36) contains the value for the link layer channel index n. + Channel n is unused = 0, channel n is used = 1. The most significant bits are reserved for future use.*/ +} ble_gap_chnl_map_t; /** @brief PHY info. */ -typedef struct { - uint8_t tx_phy; /**< LE PHY for data transmission. @see BLE_GAP_PHYS. */ - uint8_t rx_phy; /**< LE PHY for data reception. @see BLE_GAP_PHYS. */ -} gap_le_phy_ind_t; +typedef struct +{ + uint8_t tx_phy; /**< LE PHY for data transmission. @ref BLE_GAP_PHY_OPTIONS. */ + uint8_t rx_phy; /**< LE PHY for data reception. @ref BLE_GAP_PHY_OPTIONS. */ +} ble_gap_le_phy_ind_t; /** @brief Connection info. */ -typedef union { - int8_t rssi; /**< RSSI. */ - gap_chnl_map_t chnl_map; /**< channel map. */ - gap_le_phy_ind_t phy; /**< PHY indicaiton. */ - uint8_t chan_sel_algo; /**< Chanel Selection algorithm, 0x00: LE Channel Selection Algorithm #1 is used. - 0x01: LE Channel Selection Algorithm #2 is used.\n 0x02-0xFF: reserved. */ -} gap_conn_info_t; - -/** @brief The info of connecting operation. */ -typedef struct { - uint8_t opcode; /**< Operation code. See @ref gap_get_conn_info_op_t. */ - gap_conn_info_t info; /**< Connection info. */ -} gap_conn_info_param_t; +typedef union +{ + int8_t rssi; /**< RSSI. */ + ble_gap_chnl_map_t chnl_map; /**< channel map. */ + ble_gap_le_phy_ind_t phy; /**< PHY indicaiton. */ + uint8_t chan_sel_algo; /**< Chanel Selection algorithm, 0x00: LE Channel Selection Algorithm #1 is used. + 0x01: LE Channel Selection Algorithm #2 is used.\n 0x02-0xFF: reserved. */ +} ble_gap_conn_info_t; /** @brief Peer version info. */ -typedef struct { +typedef struct +{ uint16_t compid; /** // standard definitions +#include "ble_error.h" #include "ble_gapc.h" +#include +#include + /** @addtogroup BLE_GAPM Generic Access Profile (GAP) Management @{ @brief Definitions and prototypes for the GAP Management interface. */ + +/** @addtogroup BLE_GAPM_DEFINES Defines + * @{ */ -#define CO_BIT(pos) (1UL << (pos)) /**< Bit operation helper. */ -#define MAX_ADV_NUM 5 /**< Maximal advertising instance number. */ -#define MAX_PER_SYNC_NUM 5 /**< Maximal periodic syncronization instance number. */ -#define MAX_BOND_NUM 10 /**< Maximal bonding number. */ -#define MAX_WL_NUM 10 /**< Maximal white list number. */ +#define CO_BIT(pos)(1UL<<(pos)) /**< Bit operation helper. */ +#define BLE_GAP_MAX_ADV_NUM 5 /**< Maximal advertising instance number. */ +#define BLE_GAP_MAX_PER_SYNC_NUM 5 /**< Maximal periodic syncronization instance number. */ +#define BLE_GAP_MAX_BOND_NUM 10 /**< Maximal bonding number. */ +#define BLE_GAP_MAX_WL_NUM 10 /**< Maximal white list number. */ -#define MAX_PRD_ADV_NUM 4 /**< Maximal periodic advertising list number. */ -#define MAX_KEY_LEN 16 /**< The key length. */ -#define INVALID_ADV_IDX 0xFF /**< Invalid adv index. */ -#define BLE_GAP_DEVNAME_DEFAULT "GOODIX_BLE" /**< Default device name value. */ -#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximal length of device name. */ +#define BLE_GAP_MAX_PRD_ADV_NUM 4 /**< Maximal periodic advertising list number. */ +#define BLE_GAP_MAX_KEY_LEN 16 /**< The key length. */ +#define BLE_GAP_NVALID_ADV_IDX 0xFF /**< Invalid adv index. */ +#define BLE_GAP_DEVNAME_DEFAULT "GOODIX_BLE" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximal length of device name. */ #define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ #define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ @@ -119,310 +125,295 @@ #define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ #define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ #define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ -#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Event. */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device - (Outdoor Sports Event subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device - (Outdoor Sports Event subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports - Event subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports - Event subtype). */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ -/** @defgroup BLE_GAP_PHYS GAP PHYs (bitmask) +/**@defgroup BLE_GAP_PHYS GAP PHYs (bitmask) * @{ */ #define BLE_GAP_PHY_ANY 0x00 /**< No preferred PHY. */ #define BLE_GAP_PHY_LE_1MBPS (1 << 0) /**< LE 1M PHY preferred for an active link. */ #define BLE_GAP_PHY_LE_2MBPS (1 << 1) /**< LE 2M PHY preferred for an active link. */ #define BLE_GAP_PHY_LE_CODED (1 << 2) /**< LE Coded PHY preferred for an active link. */ -/** @} */ +/**@} */ -/** @defgroup BLE_GAP_ADV_CHANNEL GAP ADV CHANNEL (bitmask) +/**@defgroup BLE_GAP_ADV_CHANNEL GAP ADV CHANNEL (bitmask) * @{ */ -#define GAP_ADV_CHANNEL_37 0x01 /**< Advertising Channel 37 (2402MHz). */ -#define GAP_ADV_CHANNEL_38 0x02 /**< Advertising Channel 38 (2426MHz). */ -#define GAP_ADV_CHANNEL_39 0x04 /**< Advertising Channel 39 (2480MHz). */ -#define GAP_ADV_CHANNEL_37_38_39 0x07 /**< Advertising Channel 37, 38, 39. */ -/** @} */ -/** @} */ +#define BLE_GAP_ADV_CHANNEL_37 0x01 /**< Advertising Channel 37 (2402MHz). */ +#define BLE_GAP_ADV_CHANNEL_38 0x02 /**< Advertising Channel 38 (2426MHz). */ +#define BLE_GAP_ADV_CHANNEL_39 0x04 /**< Advertising Channel 39 (2480MHz). */ +#define BLE_GAP_ADV_CHANNEL_37_38_39 0x07 /**< Advertising Channel 37, 38, 39. */ +/**@} */ +/**@} */ /** @addtogroup BLE_GAPM_ENUMERATIONS Enumerations * @{ */ /** * @brief GAP role options */ -typedef enum { +typedef enum +{ BLE_GAP_ROLE_NONE = 0x00, /**< No role set yet. */ BLE_GAP_ROLE_OBSERVER = 0x01, /**< Observer role. */ BLE_GAP_ROLE_BROADCASTER = 0x02, /**< Broadcaster role. */ BLE_GAP_ROLE_CENTRAL = (0x04 | BLE_GAP_ROLE_OBSERVER), /**< Master/Central role. */ BLE_GAP_ROLE_PERIPHERAL = (0x08 | BLE_GAP_ROLE_BROADCASTER), /**< Peripheral/Slave role. */ - BLE_GAP_ROLE_ALL = (BLE_GAP_ROLE_CENTRAL | BLE_GAP_ROLE_PERIPHERAL), /**< Device has all roles, - both peripheral and central. */ -} gap_role_t; + BLE_GAP_ROLE_ALL = (BLE_GAP_ROLE_CENTRAL | BLE_GAP_ROLE_PERIPHERAL), /**< Device has all roles, both peripheral and central. */ +} ble_gap_role_t; /** * @brief Own BD address source of the device */ -typedef enum { - BLE_GAP_OWN_ADDR_STATIC = 0, /**< Public or Private Static Address according to device address configuration. */ - BLE_GAP_OWN_ADDR_GEN_RSLV, /**< Generated resolvable private random address. */ - BLE_GAP_OWN_ADDR_GEN_NON_RSLV, /**< Generated non-resolvable private random address. */ -} gap_own_addr_t; +typedef enum +{ + BLE_GAP_OWN_ADDR_STATIC = 0, /**< Public or Private Static Address according to device address configuration. */ + BLE_GAP_OWN_ADDR_GEN_RSLV, /**< Generated resolvable private random address. */ + BLE_GAP_OWN_ADDR_GEN_NON_RSLV, /**< Generated non-resolvable private random address. */ +} ble_gap_own_addr_t; /** * @brief Write permissions of the device name characteristic */ -typedef enum { - BLE_GAP_WRITE_PERM_DISABLE = 0, /**< Disable write access. */ - BLE_GAP_WRITE_PERM_NOAUTH, /**< LE Security Mode 1, Level 1. - Link does not need to be encrypted or authenticated. */ - BLE_GAP_WRITE_PERM_UNAUTH, /**< LE Security Mode 1, Level 2. - Link needs to be encrypted, but not to be authenticated. */ - BLE_GAP_WRITE_PERM_AUTH, /**< LE Security Mode 1, Level 3. - Link needs to be encrypted and authenticated (MITM). */ - BLE_GAP_WRITE_PERM_SEC_CON, /**< LE Security Mode 1, Level 4. - Link needs to be encrypted and authenticated (secure connections). */ -} gap_dev_name_write_perm_t; +typedef enum +{ + BLE_GAP_WRITE_PERM_DISABLE = 0, /**< Disable write access. */ + BLE_GAP_WRITE_PERM_NOAUTH, /**< LE Security Mode 1, Level 1. Link does not need to be encrypted or authenticated. */ + BLE_GAP_WRITE_PERM_UNAUTH, /**< LE Security Mode 1, Level 2. Link needs to be encrypted, but not to be authenticated. */ + BLE_GAP_WRITE_PERM_AUTH, /**< LE Security Mode 1, Level 3. Link needs to be encrypted and authenticated (MITM). */ + BLE_GAP_WRITE_PERM_SEC_CON, /**< LE Security Mode 1, Level 4. Link needs to be encrypted and authenticated (secure connections). */ +} ble_gap_dev_name_write_perm_t; /** * @brief Advertising data type */ -typedef enum { - BLE_GAP_ADV_DATA_TYPE_DATA = 0, /**< Advertising data. */ - BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, /**< Scan response data. */ - BLE_GAP_ADV_DATA_TYPE_PER_DATA, /**< Periodic advertising data. */ -} gap_adv_data_type_t; +typedef enum +{ + BLE_GAP_ADV_DATA_TYPE_DATA = 0, /**< Advertising data. */ + BLE_GAP_ADV_DATA_TYPE_SCAN_RSP, /**< Scan response data. */ + BLE_GAP_ADV_DATA_TYPE_PER_DATA, /**< Periodic advertising data. */ +} ble_gap_adv_data_type_t; -/** @brief Get device parameters operation code. */ -typedef enum { - BLE_GAP_GET_DEV_VERSION = 0, /**< Get version information for the local Controller. */ - BLE_GAP_GET_DEV_BDADDR, /**< Get local device BD Address. */ - // BLE_GAP_GET_DEV_ADV_TX_POWER, /**< Get the transmit power level used for LE advertising channel packets. */ +/**@brief Get device parameters operation code. */ +typedef enum +{ + BLE_GAP_GET_DEV_VERSION = 0, /**< Get version information for the local Controller. */ + BLE_GAP_GET_DEV_BDADDR, /**< Get local device BD Address. */ + //BLE_GAP_GET_DEV_ADV_TX_POWER, /**< Get the transmit power level used for LE advertising channel packets. */ BLE_GAP_GET_SUGGESTED_DFLT_LE_DATA_LEN, /**< Get suggested values (SuggestedMaxTxOctets and SuggestedMaxTxTime) - for the Controller's maximum transmitted number of payload octets - and maximum packet transmission time to be used for new connections. */ - BLE_GAP_GET_MAX_LE_DATA_LEN, /**< Get the Controller' maximum supported payload octets and packet - duration times for transmission and reception (supportedMaxTxOctets - and supportedMaxTxTime, supportedMaxRxOctets, - and supportedMaxRxTime). */ - BLE_GAP_GET_NB_ADV_SETS, /**< Read the maximum number of advertising sets currently supported - by the controller. */ + for the Controller's maximum transmitted number of payload octets + and maximum packet transmission time to be used for new connections. */ + BLE_GAP_GET_MAX_LE_DATA_LEN, /**< Get the Controller' maximum supported payload octets and packet duration + times for transmission and reception (supportedMaxTxOctets and supportedMaxTxTime, + supportedMaxRxOctets, and supportedMaxRxTime). */ + BLE_GAP_GET_NB_ADV_SETS, /**< Read the maximum number of advertising sets currently supported by the controller. */ BLE_GAP_GET_MAX_LE_ADV_DATA_LEN, /**< Get maximum data length for advertising data. */ - BLE_GAP_GET_DEV_TX_POWER, /**< Read the minimum and maximum transmit powers supported by the - Controller. */ + BLE_GAP_GET_DEV_TX_POWER, /**< Read the minimum and maximum transmit powers supported by the Controller. */ BLE_GAP_GET_DEV_RF_RF_PATH_COMP, /**< Get RF path compensation values. */ -} gap_dev_info_get_type_t; +} ble_gap_dev_info_get_type_t; -/** @brief GAP advertising modes. */ -typedef enum { - GAP_ADV_TYPE_ADV_IND = 0, /**< Undirected connectable and scannable mode. */ - GAP_ADV_TYPE_ADV_NONCONN_IND, /**< Non-connectable and non-scanable mode. */ - GAP_ADV_TYPE_ADV_SCAN_IND, /**< Undirected scannable mode. */ - GAP_ADV_TYPE_ADV_HIGH_DIRECT_IND, /**< Directed high duty cycle mode. */ - GAP_ADV_TYPE_ADV_LOW_DIRECT_IND, /**< Directed low duty cycle mode. */ -} gap_adv_mode_t; +/**@brief GAP advertising modes. */ +typedef enum +{ + BLE_GAP_ADV_TYPE_ADV_IND = 0, /**< Undirected connectable and scannable mode. */ + BLE_GAP_ADV_TYPE_ADV_NONCONN_IND, /**< Non-connectable and non-scanable mode. */ + BLE_GAP_ADV_TYPE_ADV_SCAN_IND, /**< Undirected scannable mode. */ + BLE_GAP_ADV_TYPE_ADV_HIGH_DIRECT_IND, /**< Directed high duty cycle mode. */ + BLE_GAP_ADV_TYPE_ADV_LOW_DIRECT_IND, /**< Directed low duty cycle mode. */ +} ble_gap_adv_mode_t; -/** @brief GAP discoverability modes. */ -typedef enum { - GAP_DISC_MODE_NON_DISCOVERABLE = 0, /**< Non-discoverable mode. */ - GAP_DISC_MODE_GEN_DISCOVERABLE, /**< General-discoverable mode. */ - GAP_DISC_MODE_LIM_DISCOVERABLE, /**< Limited-discoverable mode. */ - GAP_DISC_MODE_BROADCASTER, /**< Broadcaster mode. */ -} gap_disc_mode_t; +/**@brief GAP discoverability modes. */ +typedef enum +{ + BLE_GAP_DISC_MODE_NON_DISCOVERABLE = 0, /**< Non-discoverable mode. */ + BLE_GAP_DISC_MODE_GEN_DISCOVERABLE, /**< General-discoverable mode. */ + BLE_GAP_DISC_MODE_LIM_DISCOVERABLE, /**< Limited-discoverable mode. */ + BLE_GAP_DISC_MODE_BROADCASTER, /**< Broadcaster mode. */ +} ble_gap_disc_mode_t; /** * @brief Advertising filter policy */ -typedef enum { - GAP_ADV_ALLOW_SCAN_ANY_CON_ANY = 0, /**< Allow both scan and connection requests from anyone. */ - GAP_ADV_ALLOW_SCAN_WLST_CON_ANY, /**< Allow scan req from white-list devices only - and connection req from anyone. */ - GAP_ADV_ALLOW_SCAN_ANY_CON_WLST, /**< Allow scan req from anyone and connection req - from white-list devices only. */ - GAP_ADV_ALLOW_SCAN_WLST_CON_WLST, /**< Allow scan and connection requests from white-list devices only. */ -} gap_adv_filter_policy_t; +typedef enum +{ + BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_ANY = 0, /**< Allow both scan and connection requests from anyone. */ + BLE_GAP_ADV_ALLOW_SCAN_WLST_CON_ANY, /**< Allow scan req from white-list devices only and connection req from anyone. */ + BLE_GAP_ADV_ALLOW_SCAN_ANY_CON_WLST, /**< Allow scan req from anyone and connection req from white-list devices only. */ + BLE_GAP_ADV_ALLOW_SCAN_WLST_CON_WLST, /**< Allow scan and connection requests from white-list devices only. */ +} ble_gap_adv_filter_policy_t; /** * @brief Specify what PHY the Controller has changed for TX/RX. HCI:7.7.65.12 */ -typedef enum { - GAP_PHY_UNDEF_VALUE = 0, /**< Undefined LE PHY. */ - GAP_PHY_1MBPS_VALUE = 1, /**< LE 1M PHY. */ - GAP_PHY_2MBPS_VALUE = 2, /**< LE 2M PHY. */ - GAP_PHY_CODED_VALUE = 3, /**< LE Coded PHY. */ -} gap_le_phy_value_t; +typedef enum +{ + BLE_GAP_PHY_UNDEF_VALUE = 0, /**< Undefined LE PHY. */ + BLE_GAP_PHY_1MBPS_VALUE = 1, /**< LE 1M PHY. */ + BLE_GAP_PHY_2MBPS_VALUE = 2, /**< LE 2M PHY. */ + BLE_GAP_PHY_CODED_VALUE = 3, /**< LE Coded PHY. */ +} ble_gap_le_phy_value_t; /** * @brief Advertising type */ -typedef enum { - GAP_ADV_TYPE_LEGACY = 0, /**< Legacy advertising. */ - GAP_ADV_TYPE_EXTENDED, /**< Extended advertising. */ - GAP_ADV_TYPE_PERIODIC, /**< Periodic advertising. */ -} gap_adv_type_t; +typedef enum +{ + BLE_GAP_ADV_TYPE_LEGACY = 0, /**< Legacy advertising. */ + BLE_GAP_ADV_TYPE_EXTENDED, /**< Extended advertising. */ + BLE_GAP_ADV_TYPE_PERIODIC, /**< Periodic advertising. */ +} ble_gap_adv_type_t; /** * @brief Advertising properties bit field and bit positions */ -typedef enum { - GAP_ADV_PROP_CONNECTABLE_POS = 0, /**< Indicate that advertising is connectable, reception of CONNECT_REQ or +typedef enum +{ + BLE_GAP_ADV_PROP_CONNECTABLE_POS = 0, /**< Indicate that advertising is connectable, reception of CONNECT_REQ or UX_CONNECT_REQ PDUs is accepted. Not applicable for periodic advertising. */ - GAP_ADV_PROP_SCANNABLE_POS, /**< Indicate that advertising is scannable, reception of SCAN_REQ or - AUX_SCAN_REQ PDUs is accepted. */ - GAP_ADV_PROP_DIRECTED_POS, /**< Indicate that advertising targets at a specific device. - Only applicable in following cases: + BLE_GAP_ADV_PROP_SCANNABLE_POS, /**< Indicate that advertising is scannable, reception of SCAN_REQ or AUX_SCAN_REQ PDUs is accepted. */ + BLE_GAP_ADV_PROP_DIRECTED_POS, /**< Indicate that advertising targets at a specific device. Only applicable in following cases: - Legacy advertising: if connectable - - Extended advertising: connectable or - (non-connectable and non-discoverable). */ - GAP_ADV_PROP_HDC_POS, /**< Indicate that High Duty Cycle has to be used for advertising on primary channel, + - Extended advertising: connectable or (non-connectable and non-discoverable). */ + BLE_GAP_ADV_PROP_HDC_POS, /**< Indicate that High Duty Cycle has to be used for advertising on primary channel, applicable only if created advertising is not an extended advertising. */ - GAP_ADV_PROP_USE_LEGACY_PDUS_POS, /**< Use legacy advertising PDUs. */ - GAP_ADV_PROP_ANONYMOUS_POS, /**< Enable anonymous mode. Device address will not appear in sending PDUs. + BLE_GAP_ADV_PROP_USE_LEGACY_PDUS_POS, /**< Use legacy advertising PDUs. */ + BLE_GAP_ADV_PROP_ANONYMOUS_POS, /**< Enable anonymous mode. Device address will not appear in sending PDUs. Valid only if the created advertising is an extended advertising. */ - GAP_ADV_PROP_TX_PWR_POS, /**< Include TX power in the extended header of the advertising PDU. + BLE_GAP_ADV_PROP_TX_PWR_POS, /**< Include TX power in the extended header of the advertising PDU. Valid only if the created advertising is not a legacy advertising. */ - GAP_ADV_PROP_PER_TX_PWR_POS, /**< Include TX power in the periodic advertising PDU. + BLE_GAP_ADV_PROP_PER_TX_PWR_POS, /**< Include TX power in the periodic advertising PDU. Valid only if the created advertising is a periodic advertising. */ - GAP_ADV_PROP_SCAN_REQ_NTF_EN_POS, /**< Indicate if application must be informed - about receiving scan request PDUs. */ -} gap_adv_prop_pos_t; + BLE_GAP_ADV_PROP_SCAN_REQ_NTF_EN_POS, /**< Indicate if application must be informed about receiving scan request PDUs. */ +} ble_gap_adv_prop_pos_t; /** * @brief Advertising properties bit field bit value */ -typedef enum { - GAP_ADV_PROP_CONNECTABLE_BIT = CO_BIT(GAP_ADV_PROP_CONNECTABLE_POS), - GAP_ADV_PROP_SCANNABLE_BIT = CO_BIT(GAP_ADV_PROP_SCANNABLE_POS), - GAP_ADV_PROP_DIRECTED_BIT = CO_BIT(GAP_ADV_PROP_DIRECTED_POS), - GAP_ADV_PROP_HDC_BIT = CO_BIT(GAP_ADV_PROP_HDC_POS), - GAP_ADV_PROP_USE_LEGACY_PDUS_BIT = CO_BIT(GAP_ADV_PROP_USE_LEGACY_PDUS_POS), - GAP_ADV_PROP_ANONYMOUS_BIT = CO_BIT(GAP_ADV_PROP_ANONYMOUS_POS), - GAP_ADV_PROP_TX_PWR_BIT = CO_BIT(GAP_ADV_PROP_TX_PWR_POS), - GAP_ADV_PROP_PER_TX_PWR_BIT = CO_BIT(GAP_ADV_PROP_PER_TX_PWR_POS), - GAP_ADV_PROP_SCAN_REQ_NTF_EN_BIT = CO_BIT(GAP_ADV_PROP_SCAN_REQ_NTF_EN_POS), -} gap_adv_prop_t; +typedef enum +{ + BLE_GAP_ADV_PROP_CONNECTABLE_BIT = CO_BIT(BLE_GAP_ADV_PROP_CONNECTABLE_POS), + BLE_GAP_ADV_PROP_SCANNABLE_BIT = CO_BIT(BLE_GAP_ADV_PROP_SCANNABLE_POS), + BLE_GAP_ADV_PROP_DIRECTED_BIT = CO_BIT(BLE_GAP_ADV_PROP_DIRECTED_POS), + BLE_GAP_ADV_PROP_HDC_BIT = CO_BIT(BLE_GAP_ADV_PROP_HDC_POS), + BLE_GAP_ADV_PROP_USE_LEGACY_PDUS_BIT = CO_BIT(BLE_GAP_ADV_PROP_USE_LEGACY_PDUS_POS), + BLE_GAP_ADV_PROP_ANONYMOUS_BIT = CO_BIT(BLE_GAP_ADV_PROP_ANONYMOUS_POS), + BLE_GAP_ADV_PROP_TX_PWR_BIT = CO_BIT(BLE_GAP_ADV_PROP_TX_PWR_POS), + BLE_GAP_ADV_PROP_PER_TX_PWR_BIT = CO_BIT(BLE_GAP_ADV_PROP_PER_TX_PWR_POS), + BLE_GAP_ADV_PROP_SCAN_REQ_NTF_EN_BIT = CO_BIT(BLE_GAP_ADV_PROP_SCAN_REQ_NTF_EN_POS), +} ble_gap_adv_prop_t; /** * @brief Scanning types */ -typedef enum { - GAP_SCAN_ACTIVE = 0, /**< Active scan type. */ - GAP_SCAN_PASSIVE, /**< Passive scan type. */ -} gap_scan_type_t; +typedef enum +{ + BLE_GAP_SCAN_ACTIVE = 0, /**< Active scan type. */ + BLE_GAP_SCAN_PASSIVE, /**< Passive scan type. */ +} ble_gap_scan_type_t; /** * @brief Scanning modes */ -typedef enum { - GAP_SCAN_GEN_DISC_MODE = 0, /**< General discoverable mode. */ - GAP_SCAN_LIM_DISC_MODE, /**< Limited discoverable mode. */ - GAP_SCAN_OBSERVER_MODE, /**< Observer mode. */ -} gap_scan_mode_t; +typedef enum +{ + BLE_GAP_SCAN_GEN_DISC_MODE = 0, /**< General discoverable mode. */ + BLE_GAP_SCAN_LIM_DISC_MODE, /**< Limited discoverable mode. */ + BLE_GAP_SCAN_OBSERVER_MODE, /**< Observer mode. */ +} ble_gap_scan_mode_t; /** * @brief Duplicate filter policy */ -typedef enum { - GAP_SCAN_FILT_DUPLIC_DIS = 0, /**< Disable filtering of duplicate packets. */ - GAP_SCAN_FILT_DUPLIC_EN, /**< Enable filtering of duplicate packets. */ -} gap_scan_dup_filt_policy_t; +typedef enum +{ + BLE_GAP_SCAN_FILT_DUPLIC_DIS = 0, /**< Disable filtering of duplicate packets. */ + BLE_GAP_SCAN_FILT_DUPLIC_EN, /**< Enable filtering of duplicate packets. */ +} ble_gap_scan_dup_filt_policy_t; /** * @brief Extended scanning types */ -typedef enum { - GAP_EXT_SCAN_TYPE_GEN_DISC = 0, /**< General discovery. */ - GAP_EXT_SCAN_TYPE_LIM_DISC, /**< Limited discovery. */ - GAP_EXT_SCAN_TYPE_OBSERVER, /**< Observer. */ - GAP_EXT_SCAN_TYPE_SEL_OBSERVER, /**< Selective observer. */ - GAP_EXT_SCAN_TYPE_CONN_DISC, /**< Connectable discovery. */ - GAP_EXT_SCAN_TYPE_SEL_CONN_DISC, /**< Selective connectable discovery. */ -} gap_ext_scan_type_t; - -/** - * @brief Scanning properties bit field bit value - */ -typedef enum { - GAP_EXT_SCAN_PROP_PHY_1M_BIT = (1 << 0), /**< Scan advertisement on the LE 1M PHY. */ - GAP_EXT_SCAN_PROP_PHY_CODED_BIT = (1 << 1), /**< Scan advertisement on the LE Coded PHY. */ - GAP_EXT_SCAN_PROP_ACTIVE_1M_BIT = (1 << 2), /**< Active scan on LE 1M PHY (scan request PDUs may be sent). */ - GAP_EXT_SCAN_PROP_ACTIVE_CODED_BIT = (1 << 3), /**< Active scan on LE Coded PHY (scan request PDUs may be sent). */ - GAP_EXT_SCAN_PROP_ACCEPT_RPA_BIT = (1 << 4), /**< Accept directed advertising packets if the uesd RPA and - target address cannot be solved by the controller. */ - GAP_EXT_SCAN_PROP_FILT_TRUNC_BIT = (1 << 5), /**< Filter truncated advertising or scan response reports. */ -} gap_scan_prop_t; +typedef enum +{ + BLE_GAP_EXT_SCAN_TYPE_GEN_DISC = 0, /**< General discovery. */ + BLE_GAP_EXT_SCAN_TYPE_LIM_DISC, /**< Limited discovery. */ + BLE_GAP_EXT_SCAN_TYPE_OBSERVER, /**< Observer. */ + BLE_GAP_EXT_SCAN_TYPE_SEL_OBSERVER, /**< Selective observer. */ + BLE_GAP_EXT_SCAN_TYPE_CONN_DISC, /**< Connectable discovery. */ + BLE_GAP_EXT_SCAN_TYPE_SEL_CONN_DISC, /**< Selective connectable discovery. */ +} ble_gap_ext_scan_type_t; /** * @brief Filtering policy for duplicated packets */ -typedef enum { - GAP_EXT_DUP_FILT_DIS = 0, /**< Disable filtering of duplicated packets. */ - GAP_EXT_DUP_FILT_EN, /**< Enable filtering of duplicated packets. */ - GAP_EXT_DUP_FILT_EN_PERIOD, /**< Enable filtering of duplicated packets, reset for each scan period. */ -} gap_ext_scan_dup_filt_policy_t; +typedef enum +{ + BLE_GAP_EXT_DUP_FILT_DIS = 0, /**< Disable filtering of duplicated packets. */ + BLE_GAP_EXT_DUP_FILT_EN, /**< Enable filtering of duplicated packets. */ + BLE_GAP_EXT_DUP_FILT_EN_PERIOD, /**< Enable filtering of duplicated packets, reset for each scan period. */ +} ble_gap_ext_scan_dup_filt_policy_t; /** * @brief Initiating types */ -typedef enum { - GAP_INIT_TYPE_DIRECT_CONN_EST = 0, /**< Direct connection establishment: establish a connection with - an indicated device. */ - GAP_INIT_TYPE_AUTO_CONN_EST, /**< Automatic connection establishment: establish a connection with - all devices whose address is present in the white list. */ - GAP_INIT_TYPE_NAME_DISC, /**< Name discovery: establish a connection with an indicated device - in order to read content of its device name characteristic. - Connection is closed once this operation is stopped. */ -} gap_init_type_t; +typedef enum +{ + BLE_GAP_INIT_TYPE_DIRECT_CONN_EST = 0, /**< Direct connection establishment: establish a connection with an indicated device. */ + BLE_GAP_INIT_TYPE_AUTO_CONN_EST, /**< Automatic connection establishment: establish a connection with all devices whose address is present in the white list. */ + BLE_GAP_INIT_TYPE_NAME_DISC, /**< Name discovery: establish a connection with an indicated device in order to read content of its device name characteristic. Connection is closed once this operation is stopped. */ +} ble_gap_init_type_t; /** * @brief Initiating properties */ -typedef enum { - GAP_INIT_PROP_1M_BIT = (1 << 0), /**< Scan connectable advertisements on the LE 1M PHY. - Connection parameters for the LE 1M PHY are provided. */ - GAP_INIT_PROP_2M_BIT = (1 << 1), /**< Connection parameters for the LE 2M PHY are provided. */ - GAP_INIT_PROP_CODED_BIT = (1 << 2), /**< Scan connectable advertisements on the LE Coded PHY. - Connection parameters for the LE Coded PHY are provided. */ -} gap_init_prop_t; +typedef enum +{ + BLE_GAP_INIT_PROP_1M_BIT = (1 << 0), /**< Scan connectable advertisements on the LE 1M PHY. Connection parameters for the LE 1M PHY are provided. */ + BLE_GAP_INIT_PROP_2M_BIT = (1 << 1), /**< Connection parameters for the LE 2M PHY are provided. */ + BLE_GAP_INIT_PROP_CODED_BIT = (1 << 2), /**< Scan connectable advertisements on the LE Coded PHY. Connection parameters for the LE Coded PHY are provided. */ +} ble_gap_init_prop_t; /** * @brief Scanning properties bit field bit value */ -enum gap_scan_prop { - GAP_SCAN_PROP_PHY_1M_BIT = (1 << 0), /**< Scan advertisement on the LE 1M PHY. */ - GAP_SCAN_PROP_PHY_CODED_BIT = (1 << 1), /**< Scan advertisement on the LE Coded PHY. */ - GAP_SCAN_PROP_ACTIVE_1M_BIT = (1 << 2), /**< Active scan on LE 1M PHY (scan request PDUs may be sent). */ - GAP_SCAN_PROP_ACTIVE_CODED_BIT = (1 << 3), /**< Active scan on LE Coded PHY (scan request PDUs may be sent). */ - GAP_SCAN_PROP_ACCEPT_RPA_BIT = (1 << 4), /**< Accept directed advertising packets if the used RPA and - target address cannot be solved by the controller. */ - GAP_SCAN_PROP_FILT_TRUNC_BIT = (1 << 5), /**< Filter truncated advertising or scan response reports. */ -}; +typedef enum +{ + BLE_GAP_SCAN_PROP_PHY_1M_BIT = (1 << 0), /**< Scan advertisement on the LE 1M PHY. */ + BLE_GAP_SCAN_PROP_PHY_CODED_BIT = (1 << 1), /**< Scan advertisement on the LE Coded PHY. */ + BLE_GAP_SCAN_PROP_ACTIVE_1M_BIT = (1 << 2), /**< Active scan on LE 1M PHY (scan request PDUs may be sent). */ + BLE_GAP_SCAN_PROP_ACTIVE_CODED_BIT = (1 << 3), /**< Active scan on LE Coded PHY (scan request PDUs may be sent). */ + BLE_GAP_SCAN_PROP_ACCEPT_RPA_BIT = (1 << 4), /**< Accept directed advertising packets if the used RPA and target address cannot be solved by the controller. */ + BLE_GAP_SCAN_PROP_FILT_TRUNC_BIT = (1 << 5), /**< Filter truncated advertising or scan response reports. */ +} ble_gap_scan_prop_t; /** * @brief Periodic synchronization types */ -enum gap_per_sync_type { - GAP_PER_SYNC_TYPE_GENERAL = 0, /**< Do not use periodic advertiser list for synchronization. */ - GAP_PER_SYNC_TYPE_SELECTIVE, /**< Use periodic advertiser list for synchronization. */ -}; +typedef enum +{ + BLE_GAP_PER_SYNC_TYPE_GENERAL = 0, /**< Do not use periodic advertiser list for synchronization. */ + BLE_GAP_PER_SYNC_TYPE_SELECTIVE, /**< Use periodic advertiser list for synchronization. */ +} ble_gap_per_sync_type_t; /** * @brief Security level types */ -enum gap_sec_lvl_type { - GAP_SEC_LVL_NO_SECURITY = 0, /**< No encryption or auth. */ - GAP_SEC_LVL_ENC_NO_AUTH, /**< Encryption with no auth. */ - GAP_SEC_LVL_LE_ENC_AUTH, /**< Legacy encryption with auth. */ - GAP_SEC_LVL_SC_ENC_AUTH, /**< Security connection encryption with auth. */ -}; +typedef enum +{ + BLE_GAP_SEC_LVL_NO_SECURITY = 0, /**< No encryption or auth. */ + BLE_GAP_SEC_LVL_ENC_NO_AUTH, /**< Encryption with no auth. */ + BLE_GAP_SEC_LVL_LE_ENC_AUTH, /**< Legacy encryption with auth. */ + BLE_GAP_SEC_LVL_SC_ENC_AUTH, /**< Security connection encryption with auth. */ +} ble_gap_sec_lvl_type_t; /** * @brief GAP advertising types */ -typedef enum { +typedef enum +{ BLE_GAP_AD_TYPE_FLAGS = 0x01, /**< Flag. */ BLE_GAP_AD_TYPE_MORE_16_BIT_UUID = 0x02, /**< Use of more than 16-bit UUID. */ BLE_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID = 0x03, /**< Complete List of 16-bit UUID. */ @@ -456,330 +447,425 @@ typedef enum { BLE_GAP_AD_TYPE_3D_INFO = 0x3D, /**< 3D Information Data. */ BLE_GAP_AD_TYPE_MANU_SPECIFIC_DATA = 0xFF, /**< Manufacturer specific data. */ -} gap_ad_type_t; +} ble_gap_ad_type_t; /** * @brief AD Type Flag - Bit mask. */ -typedef enum { - GAP_ADV_FLAG_LE_LIMITED_DISC_MODE = 0x01, /**< Limited discovery flag: AD Flag. */ - GAP_ADV_FLAG_LE_GENERAL_DISC_MODE = 0x02, /**< General discovery flag: AD Flag. */ - GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED = 0x04, /**< Legacy BT not supported: AD Flag. */ - GAP_ADV_FLAG_SIMUL_BR_EDR_LE_CONTROLLER = 0x08, /**< Dual mode for controller supported (BR/EDR/LE): AD Flag. */ - GAP_ADV_FLAG_SIMUL_BR_EDR_LE_HOST = 0x10, /**< Dual mode for host supported (BR/EDR/LE): AD Flag. */ -} gap_adv_flags_t; +typedef enum +{ + BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE = 0x01, /**< Limited discovery flag: AD Flag. */ + BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE = 0x02, /**< General discovery flag: AD Flag. */ + BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED = 0x04, /**< Legacy BT not supported: AD Flag. */ + BLE_GAP_ADV_FLAG_SIMUL_BR_EDR_LE_CONTROLLER = 0x08, /**< Dual mode for controller supported (BR/EDR/LE): AD Flag. */ + BLE_GAP_ADV_FLAG_SIMUL_BR_EDR_LE_HOST = 0x10, /**< Dual mode for host supported (BR/EDR/LE): AD Flag. */ +} ble_gap_adv_flags_t; + +/** @brief Advertising report type. */ +typedef enum +{ + BLE_GAP_REPORT_TYPE_ADV_EXT = 0, /**< Extended advertising report. */ + BLE_GAP_REPORT_TYPE_ADV_LEG, /**< Legacy advertising report. */ + BLE_GAP_REPORT_TYPE_SCAN_RSP_EXT, /**< Extended scan response report. */ + BLE_GAP_REPORT_TYPE_SCAN_RSP_LEG, /**< Legacy scan response report. */ + BLE_GAP_REPORT_TYPE_PER_ADV, /**< Periodic advertising report. */ +} ble_gap_adv_report_type_t; + +/** @brief Advertising report information. */ +typedef enum +{ + BLE_GAP_REPORT_INFO_COMPLETE_BIT = (1 << 0), /**< Report is complete. */ + BLE_GAP_REPORT_INFO_CONN_ADV_BIT = (1 << 1), /**< Connectable advertising. */ + BLE_GAP_REPORT_INFO_SCAN_ADV_BIT = (1 << 2), /**< Scannable advertising. */ + BLE_GAP_REPORT_INFO_DIR_ADV_BIT = (1 << 3), /**< Directed advertising. */ +} ble_gap_adv_report_info_t; + +/** @brief Stop reason code. */ +typedef enum +{ + BLE_GAP_STOPPED_REASON_TIMEOUT = 0, /**< Stop with timeout. */ + BLE_GAP_STOPPED_REASON_ON_USER, /**< Stop with user stopping it actively. */ + BLE_GAP_STOPPED_REASON_CONN_EST /**< Stop with connection established. */ +} ble_gap_stopped_reason_t; /** * @brief Privacy mode. */ -typedef enum { - PRIVACY_MODE_NETWORK = 0x00, /**< Set to the network privacy mode for the peer device. */ - PRIVACY_MODE_DEVICE = 0x01, /**< Set to the device privacy mode for the peer device. */ -} privacy_mode_t; +typedef enum +{ + BLE_GAP_PRIVACY_MODE_NETWORK= 0x00, /**< Set to the network privacy mode for the peer device. */ + BLE_GAP_PRIVACY_MODE_DEVICE = 0x01, /**< Set to the device privacy mode for the peer device. */ +} ble_gap_privacy_mode_t; /** - * @brief Possible roles for the event. + * @brief Possible roles of the activity. */ -typedef enum { - GAP_EVENT_ROLE_ADV = 0, /**< Adertise role. */ - GAP_EVENT_ROLE_CON = 1, /**< Connect role. */ - GAP_EVENT_ROLE_SCAN_INIT = 2, /**< Scann role. */ - GAP_EVENT_ROLE_UNKNOWN = 0xf, /**< Unknown role. */ -} gap_event_role_t; +typedef enum +{ + BLE_GAP_ACTIVITY_ROLE_ADV = 0, /**< Adertise role. */ + BLE_GAP_ACTIVITY_ROLE_CON = 1, /**< Connect role. */ + BLE_GAP_ACTIVITY_ROLE_SCAN_INIT = 2, /**< Scann role. */ + BLE_GAP_ACTIVITY_ROLE_UNKNOWN = 0xf, /**< Unknown role. */ +} ble_gap_actv_role_t; /** - * @brief Event type. + * @brief Clock ACC error. */ -typedef enum { - TYPE_ADV = 0, - TYPE_SCAN, - TYPE_INIT, - TYPE_PER_SYNC, -} ble_actv_type_t; +typedef enum +{ + BLE_GAP_CLK_ACC_500 = 0, /**< 500 ppm. */ + BLE_GAP_CLK_ACC_250, /**< 250 ppm. */ + BLE_GAP_CLK_ACC_150, /**< 150 ppm. */ + BLE_GAP_CLK_ACC_100, /**< 10 ppm. */ + BLE_GAP_CLK_ACC_75, /**< 70 ppm. */ + BLE_GAP_CLK_ACC_50, /**< 50 ppm. */ + BLE_GAP_CLK_ACC_30, /**< 30 ppm. */ + BLE_GAP_CLK_ACC_20, /**< 20 ppm. */ +} ble_gap_clk_acc_t; + +/** + * @brief Activity type. + */ +typedef enum +{ + BLE_GAP_ACTV_TYPE_ADV = 0, + BLE_GAP_ACTV_TYPE_SCAN, + BLE_GAP_ACTV_TYPE_INIT, + BLE_GAP_ACTV_TYPE_PER_SYNC, +} ble_gap_actv_type_t; /** @} */ -/** @addtogroup BLE_GAPM_STRUCTURES Structures +/**@addtogroup BLE_GAPM_STRUCTURES Structures * @{ */ /** * @brief Advertising parameters for legacy advertising */ -typedef struct { - uint8_t adv_mode; /**< Advertising mode (see enum @ref gap_adv_mode_t). */ - uint8_t disc_mode; /**< Discovery mode (see enum @ref gap_disc_mode_t). */ - uint8_t filter_pol; /**< Advertising filtering policy (see enum @ref gap_adv_filter_policy_t). */ - gap_bdaddr_t - peer_addr; /**< Peer address configuration (only used in case of directed advertising, - or used to locate the IRK list). */ - uint16_t adv_intv_min; /**< Minimum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ - uint16_t - adv_intv_max; /**< Maximum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ - uint8_t chnl_map; /**< Advertising channel map. See @ref BLE_GAP_ADV_CHANNEL. */ - bool - scan_req_ind_en; /**< Indicate if the application should be informed when receiving - a scan request from the scanner. */ - int8_t - max_tx_pwr; /**< Maximum power level at which the advertising packets - have to be transmitted (between -20dbm and 7dbm). - For the real value, please refer to GR551x Datasheet. */ -} gap_adv_param_t; +typedef struct +{ + ble_gap_adv_mode_t adv_mode; /**< Advertising mode (see enum @ref ble_gap_adv_mode_t). */ + ble_gap_disc_mode_t disc_mode; /**< Discovery mode (see enum @ref ble_gap_disc_mode_t). */ + ble_gap_adv_filter_policy_t filter_pol; /**< Advertising filtering policy (see enum @ref ble_gap_adv_filter_policy_t). */ + ble_gap_bdaddr_t peer_addr; /**< Peer address configuration (only used in case of directed advertising, or used to locate the IRK list). */ + uint16_t adv_intv_min; /**< Minimum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ + uint16_t adv_intv_max; /**< Maximum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ + uint8_t chnl_map; /**< Advertising channel map. See @ref BLE_GAP_ADV_CHANNEL. */ + bool scan_req_ind_en; /**< Indicate if the application should be informed when receiving a scan request from the scanner. */ + int8_t max_tx_pwr; /**< Maximum power level at which the advertising packets have to be transmitted (between -20dbm and 7dbm).For the real value, please refer to Datasheet. */ +} ble_gap_adv_param_t; /** * @brief Configuration for advertising on primary channel */ -typedef struct { - uint32_t adv_intv_min; /**< Minimum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ - uint32_t adv_intv_max; /**< Maximum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ - uint8_t chnl_map; /**< Bit field indicating the channel map. See @ref BLE_GAP_ADV_CHANNEL. */ - gap_le_phy_value_t phy; /**< Indicate on which PHY primary advertising has to be performed. - See enum @ref gap_le_phy_value_t. Note that LE 2M PHY is not allowed and that - legacy advertising only supports LE 1M PHY. */ -} gap_adv_prim_cfg_t; +typedef struct +{ + uint32_t adv_intv_min; /**< Minimum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ + uint32_t adv_intv_max; /**< Maximum advertising interval (in unit of 625 us). Must be greater than 20 ms. */ + uint8_t chnl_map; /**< Bit field indicating the channel map. See @ref BLE_GAP_ADV_CHANNEL. */ + ble_gap_le_phy_value_t phy; /**< Indicate on which PHY primary advertising has to be performed. See enum @ref ble_gap_le_phy_value_t. Note that LE 2M PHY is not allowed and that legacy advertising only supports LE 1M PHY. */ +} ble_gap_adv_prim_cfg_t; /** * @brief Configuration for advertising on secondary channel */ -typedef struct { - uint8_t max_skip; /**< Maximum number of advertising events the controller can skip - before sending the AUX_ADV_IND packets. - The range is 0x00 to 0xFF. - 0x00 means that AUX_ADV_IND PDUs shall be sent prior to each advertising events. */ - gap_le_phy_value_t phy; /**< Indicate on which PHY secondary advertising has to be performed. - See enum @ref gap_le_phy_value_t. */ - uint8_t adv_sid; /**< Advertising SID. Allowed range is 0x00 to 0x0F. */ -} gap_adv_second_cfg_t; +typedef struct +{ + uint8_t max_skip; /**< Maximum number of advertising events the controller can skip before sending the AUX_ADV_IND packets. The range is 0x00 to 0xFF. 0x00 means that AUX_ADV_IND PDUs shall be sent prior to each advertising events. */ + ble_gap_le_phy_value_t phy; /**< Indicate on which PHY secondary advertising has to be performed. See enum @ref ble_gap_le_phy_value_t. */ + uint8_t adv_sid; /**< Advertising SID. Allowed range is 0x00 to 0x0F. */ +} ble_gap_adv_second_cfg_t; /** * @brief Configuration for periodic advertising */ -typedef struct { - uint16_t adv_intv_min; /**< Minimum advertising interval (in unit of 1.25 ms). Must be greater than 20 ms. */ - uint16_t - adv_intv_max; /**< Maximum advertising interval (in unit of 1.25 ms). Must be greater than 20 ms. */ -} gap_adv_period_cfg_t; +typedef struct +{ + uint16_t adv_intv_min; /**< Minimum advertising interval (in unit of 1.25 ms). Must be greater than 20 ms. */ + uint16_t adv_intv_max; /**< Maximum advertising interval (in unit of 1.25 ms). Must be greater than 20 ms. */ +} ble_gap_adv_period_cfg_t; /** * @brief Advertising parameters for extended advertising and periodic advertising */ -typedef struct { - uint8_t type; /**< Advertising type (see enum @ref gap_adv_type_t). */ - uint8_t disc_mode; /**< Discovery mode (see enum @ref gap_disc_mode_t). */ - uint16_t prop; /**< Bit field value provided by advertising properties. - See enum @ref gap_adv_prop_t for bit signification. */ - int8_t max_tx_pwr; /**< Maximum power level at which the advertising packets have to be transmitted - (between -20 and 7 dBm). */ - uint8_t filter_pol; /**< Advertising filtering policy (see enum @ref gap_adv_filter_policy_t). */ - gap_bdaddr_t peer_addr; /**< Peer address configuration (only used in case of directed advertising or - used to locate the IRK list). */ - gap_adv_prim_cfg_t prim_cfg; /**< Configuration for primary advertising. */ - gap_adv_second_cfg_t second_cfg; /**< Configuration for secondary advertising (valid only if advertising type is - GAP_ADV_TYPE_EXTENDED or GAP_ADV_TYPE_PERIODIC). */ - gap_adv_period_cfg_t period_cfg; /**< Configuration for periodic advertising - (valid only if advertising type is GAP_ADV_TYPE_PERIODIC). */ -} gap_ext_adv_param_t; +typedef struct +{ + ble_gap_adv_type_t type; /**< Advertising type (see enum @ref ble_gap_adv_type_t). */ + ble_gap_disc_mode_t disc_mode; /**< Discovery mode (see enum @ref ble_gap_disc_mode_t). */ + uint16_t prop; /**< Bit field value provided by advertising properties. See enum @ref ble_gap_adv_prop_t for bit signification. */ + int8_t max_tx_pwr; /**< Maximum power level at which the advertising packets have to be transmitted (between -20 and 7 dBm). */ + ble_gap_adv_filter_policy_t filter_pol; /**< Advertising filtering policy (see enum @ref ble_gap_adv_filter_policy_t). */ + ble_gap_bdaddr_t peer_addr; /**< Peer address configuration (only used in case of directed advertising or used to locate the IRK list). */ + ble_gap_adv_prim_cfg_t prim_cfg; /**< Configuration for primary advertising. */ + ble_gap_adv_second_cfg_t second_cfg; /**< Configuration for secondary advertising (valid only if advertising type is GAP_ADV_TYPE_EXTENDED or GAP_ADV_TYPE_PERIODIC). */ + ble_gap_adv_period_cfg_t period_cfg; /**< Configuration for periodic advertising (valid only if advertising type is GAP_ADV_TYPE_PERIODIC). */ +} ble_gap_ext_adv_param_t; /** * @brief Advertising timing parameter */ -typedef struct { - uint16_t duration; /**< Advertising duration (in unit of 10ms). - 0 means that advertising continues until the host disables it. - If Advertising discovery mode is GAP_DISC_MODE_LIM_DISCOVERABLE - (see enum @ref gap_disc_mode_t), the setting duration range is [1, 18000]. - If adv mode is high duty, duration time range is [1, 128]. */ - uint8_t max_adv_evt; /**< Maximum number of extended advertising events. - The controller shall attempt to send prior to terminating the extending advertising. - The range is [0, 255]. 0 means no maximum number of advertising events. - Valid only if the created advertising is an extended advertising. */ -} gap_adv_time_param_t; +typedef struct +{ + uint16_t duration; /**< Advertising duration (in unit of 10ms). 0 means that advertising continues until the host disables it. If Advertising discovery mode is GAP_DISC_MODE_LIM_DISCOVERABLE (see enum @ref ble_gap_disc_mode_t), the setting duration range is [1, 18000]. If adv mode is high duty, duration time range is [1, 128]. */ + uint8_t max_adv_evt; /**< Maximum number of extended advertising events. The controller shall attempt to send prior to terminating the extending advertising. The range is [0, 255]. 0 means no maximum number of advertising events. Valid only if the created advertising is an extended advertising. */ +} ble_gap_adv_time_param_t; /** * @brief Security key */ -typedef struct { - uint8_t key[MAX_KEY_LEN]; /**< Key value MSB -> LSB (MSB followed by LSB). */ -} gap_sec_key_t; +typedef struct +{ + uint8_t key[BLE_GAP_MAX_KEY_LEN]; /**< Key value MSB -> LSB (MSB followed by LSB). */ +} ble_gap_sec_key_t; /** * @brief Parameters for legacy scanning */ -typedef struct { - gap_scan_type_t scan_type; /**< Active scanning or passive scanning. */ - gap_scan_mode_t scan_mode; /**< Scan mode. */ - gap_scan_dup_filt_policy_t scan_dup_filt; /**< Duplicate filter policy. */ - bool use_whitelist; /**< Filter policy. */ - uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms (range: 2.5 ms to 10.24s). */ - uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms (range: 2.5 ms to 10.24s). */ - uint16_t timeout; /**< Scan timeout should be a value between 0x0001 and 0xFFFF(unit: 10 ms). - 0x0000 indicates that the timeout has no effect. */ -} gap_scan_param_t; +typedef struct +{ + ble_gap_scan_type_t scan_type; /**< Active scanning or passive scanning. */ + ble_gap_scan_mode_t scan_mode; /**< Scan mode. */ + ble_gap_scan_dup_filt_policy_t scan_dup_filt; /**< Duplicate filter policy. */ + bool use_whitelist; /**< Filter policy. */ + uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms (range: 2.5 ms to 10.24s). */ + uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms (range: 2.5 ms to 10.24s). */ + uint16_t timeout; /**< Scan timeout should be a value between 0x0001 and 0xFFFF(unit: 10 ms). 0x0000 indicates that the timeout has no effect. */ +} ble_gap_scan_param_t; /** * @brief Scan Window operation parameters */ -typedef struct { +typedef struct +{ uint16_t scan_intv; /**< Scan interval between 0x0004 and 0xFFFF in 0.625 ms (range: 2.5 ms to 40.959375s). */ uint16_t scan_wd; /**< Scan window between 0x0004 and 0xFFFF in 0.625 ms (range: 2.5 ms to 40.959375s). */ -} gap_scan_wd_op_param_t; +} ble_gap_scan_wd_op_param_t; /** * @brief Parameters for extended scanning */ -typedef struct { - uint8_t type; /**< Type of scanning to be started (see enum @ref gap_ext_scan_type_t). */ - uint8_t prop; /**< Properties for the scan procedure (see enum @ref gap_scan_prop for bit signification). */ - uint8_t dup_filt_pol; /**< Duplicate packet filtering policy (see enum @ref gap_ext_scan_dup_filt_policy_t). */ - uint8_t rsvd; /**< Reserved for future use. */ - gap_scan_wd_op_param_t scan_param_1m; /**< Scan window opening parameters for LE 1M PHY. */ - gap_scan_wd_op_param_t scan_param_coded; /**< Scan window opening parameters for LE Coded PHY. */ - uint16_t duration; /**< Scan duration (in unit of 10ms). 0 means that the controller will scan continuously - until receiving a stop command from the application (10 ms to 655.35s). */ - uint16_t period; /**< Scan period, which is the time interval between two consequent starts of a scan duration - by the controller. - 0 means that the scan procedure is not periodic, in unit of 1.28s (1.28s to 83,884.8s). */ -} gap_ext_scan_param_t; +typedef struct +{ + ble_gap_ext_scan_type_t type; /**< Type of scanning to be started (see enum ble_gap_ext_scan_type_t). */ + uint8_t prop; /**< Properties for the scan procedure (see enum ble_gap_scan_prop for bit signification). */ + ble_gap_ext_scan_dup_filt_policy_t dup_filt_pol; /**< Duplicate packet filtering policy (see enum ble_gap_ext_scan_dup_filt_policy_t). */ + uint8_t rsvd; /**< Reserved for future use. */ + ble_gap_scan_wd_op_param_t scan_param_1m; /**< Scan window opening parameters for LE 1M PHY. */ + ble_gap_scan_wd_op_param_t scan_param_coded; /**< Scan window opening parameters for LE Coded PHY. */ + uint16_t duration; /**< Scan duration (in unit of 10ms). 0 means that the controller will scan continuously until receiving a stop command from the application (10 ms to 655.35s). */ + uint16_t period; /**< Scan period, which is the time interval between two consequent starts of a scan duration by the controller. 0 means that the scan procedure is not periodic, in unit of 1.28s (1.28s to 83,884.8s). */ +} ble_gap_ext_scan_param_t; /** * @brief Periodic advertising information */ -typedef struct { - gap_bdaddr_t bd_addr; /**< Advertiser address information. */ - uint8_t adv_sid; /**< Advertising SID. */ -} gap_period_adv_addr_cfg_t; +typedef struct +{ + ble_gap_bdaddr_t bd_addr; /**< Advertiser address information. */ + uint8_t adv_sid; /**< Advertising SID. */ +} ble_gap_period_adv_addr_cfg_t; /** * @brief Periodic advertising synchronization parameters */ -typedef struct { - uint16_t skip; /**< Number of periodic advertising that can be skipped after a successful reception. - Maximum authorized value is 499. */ - uint16_t sync_to; /**< Synchronization timeout for the periodic advertising - (in unit of 10ms between 100ms and 163.84s). */ - uint8_t type; /**< Periodic synchronization type (see enum @ref gap_per_sync_type). */ - uint8_t rsvd; /**< Reserved for future use.*/ - gap_period_adv_addr_cfg_t adv_addr; /**< Address of advertiser with which synchronization has to be established - (used only if use_pal is false). */ -} gap_per_sync_param_t; +typedef struct +{ + uint16_t skip; /**< Number of periodic advertising that can be skipped after a successful reception. Maximum authorized value is 499. */ + uint16_t sync_to; /**< Synchronization timeout for the periodic advertising (in unit of 10ms between 100ms and 163.84s). */ + ble_gap_per_sync_type_t type; /**< Periodic synchronization type (see enum @ref ble_gap_per_sync_type_t). */ + uint8_t rsvd; /**< Reserved for future use.*/ + ble_gap_period_adv_addr_cfg_t adv_addr; /**< Address of advertiser with which synchronization has to be established(used only if use_pal is false). */ +} ble_gap_per_sync_param_t; /** * @brief Legacy initiating parameters */ -typedef struct { - uint8_t type; /**< Initiating type (see enum @ref gap_init_type_t). */ - gap_bdaddr_t peer_addr; /**< Peer device address. */ - uint16_t interval_min; /**< Minimum value for the connection interval (in unit of 1.25ms). - Shall be less than or equal to interval_max value. - Allowed range is 7.5 ms to 4s. */ - uint16_t interval_max; /**< Maximum value for the connection interval (in unit of 1.25ms). - Shall be greater than or equal to interval_min value. - Allowed range is 7.5 ms to 4s. */ - uint16_t slave_latency; /**< Slave latency. Number of events that can be missed by a connected slave device. */ - uint16_t sup_timeout; /**< Link supervision timeout (in unit of 10ms). Allowed range is 100 ms to 32s. */ - uint16_t conn_timeout; /**< Timeout for connection establishment (in unit of 10ms). - Cancel the procedure if connection has not been connected when the timeout occurs. - 0 means there is no timeout. */ -} gap_init_param_t; +typedef struct +{ + ble_gap_init_type_t type; /**< Initiating type (see enum @ref ble_gap_init_type_t). */ + ble_gap_bdaddr_t peer_addr; /**< Peer device address. */ + uint16_t interval_min; /**< Minimum value for the connection interval (in unit of 1.25ms). Shall be less than or equal to interval_max value. Allowed range is 7.5 ms to 4s. */ + uint16_t interval_max; /**< Maximum value for the connection interval (in unit of 1.25ms). Shall be greater than or equal to interval_min value. Allowed range is 7.5 ms to 4s. */ + uint16_t slave_latency; /**< Slave latency. Number of events that can be missed by a connected slave device. */ + uint16_t sup_timeout; /**< Link supervision timeout (in unit of 10ms). Allowed range is 100 ms to 32s. */ + uint16_t conn_timeout; /**< Timeout for connection establishment (in unit of 10ms). Cancel the procedure if connection has not been connected when the timeout occurs. 0 means there is no timeout. */ +} ble_gap_init_param_t; /** * @brief Connection parameters */ -typedef struct { - uint16_t conn_intv_min; /**< Minimum value for the connection interval (in unit of 1.25ms). - Shall be less than or equal to conn_intv_max value. - Allowed range is 7.5 ms to 4s. */ - uint16_t conn_intv_max; /**< Maximum value for the connection interval (in unit of 1.25ms). - Shall be greater than or equal to conn_intv_min value. - Allowed range is 7.5 ms to 4s. */ - uint16_t conn_latency; /**< Slave latency. Number of events that can be missed by a connected slave device. */ - uint16_t supervision_to; /**< Link supervision timeout (in unit of 10ms). Allowed range is 100 ms to 32s. */ - uint16_t ce_len; /**< The length of connection event needed for this LE connection. - Range: 0x0002 to 0xFFFF, Unit:0.625 ms, Time Range: 1.25 ms to 40.9s. */ -} gap_ext_conn_param_t; +typedef struct +{ + uint16_t conn_intv_min; /**< Minimum value for the connection interval (in unit of 1.25ms). Shall be less than or equal to conn_intv_max value. Allowed range is 7.5 ms to 4s. */ + uint16_t conn_intv_max; /**< Maximum value for the connection interval (in unit of 1.25ms). Shall be greater than or equal to conn_intv_min value. Allowed range is 7.5 ms to 4s. */ + uint16_t conn_latency; /**< Slave latency. Number of events that can be missed by a connected slave device. */ + uint16_t supervision_to; /**< Link supervision timeout (in unit of 10ms). Allowed range is 100 ms to 32s. */ + uint16_t ce_len; /**< The length of connection event needed for this LE connection. Range: 0x0002 to 0xFFFF, Unit:0.625 ms, Time Range: 1.25 ms to 40.9s. */ +} ble_gap_ext_conn_param_t; /** * @brief Extended initiating parameters */ -typedef struct { - uint8_t type; /**< Initiating type (see enum @ref gap_init_type_t). */ - uint8_t prop; /**< Properties for the initiating procedure - (see enum @ref gap_init_prop_t for bit signification). */ - uint16_t conn_to; /**< Timeout for automatic connection establishment (in unit of 10ms). - Cancel the procedure if connection has not been connected when the timeout occurs. - 0 means there is no timeout. */ - gap_scan_wd_op_param_t scan_param_1m; /**< Scan window opening parameters for LE 1M PHY. */ - gap_scan_wd_op_param_t scan_param_coded; /**< Scan window opening parameters for LE Coded PHY. */ - gap_ext_conn_param_t conn_param_1m; /**< Connection parameters for LE 1M PHY. */ - gap_ext_conn_param_t conn_param_2m; /**< Connection parameters for LE 2M PHY. */ - gap_ext_conn_param_t conn_param_coded; /**< Connection parameters for LE Coded PHY. */ - gap_bdaddr_t peer_addr; /**< Address of peer device in case white list is not used for connection. */ -} gap_ext_init_param_t; +typedef struct +{ + ble_gap_init_type_t type; /**< Initiating type (see enum @ref ble_gap_init_type_t). */ + uint8_t prop; /**< Properties for the initiating procedure (see enum @ref ble_gap_init_prop_t for bit signification). */ + uint16_t conn_to; /**< Timeout for automatic connection establishment (in unit of 10ms). Cancel the procedure if connection has not been connected when the timeout occurs.0 means there is no timeout. */ + ble_gap_scan_wd_op_param_t scan_param_1m; /**< Scan window opening parameters for LE 1M PHY. */ + ble_gap_scan_wd_op_param_t scan_param_coded; /**< Scan window opening parameters for LE Coded PHY. */ + ble_gap_ext_conn_param_t conn_param_1m; /**< Connection parameters for LE 1M PHY. */ + ble_gap_ext_conn_param_t conn_param_2m; /**< Connection parameters for LE 2M PHY. */ + ble_gap_ext_conn_param_t conn_param_coded; /**< Connection parameters for LE Coded PHY. */ + ble_gap_bdaddr_t peer_addr; /**< Address of peer device in case white list is not used for connection. */ +} ble_gap_ext_init_param_t; /** * @brief LE Protocol/Service Multiplexer information */ -typedef struct { - uint16_t le_psm; /**< LE Protocol/Service Multiplexer (range: 1 to 255), PSMs should be odd. */ - uint8_t sec_lvl; /**< Security level requirement, see @ref gap_sec_lvl_type. */ - bool mks_flag; /**< Whether to use maximum-size key (16 bytes) or not. */ -} gap_lepsm_register_t; +typedef struct +{ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer (range: 1 to 255), PSMs should be odd. */ + ble_gap_sec_lvl_type_t sec_lvl; /**< Security level requirement, see @ref ble_gap_sec_lvl_type_t. */ + bool mks_flag; /**< Whether to use maximum-size key (16 bytes) or not. */ +} ble_gap_lepsm_register_t; /** * @brief Bonded device list */ -typedef struct { - uint8_t num; /**< Number of bonded device. */ - gap_bdaddr_t items[MAX_BOND_NUM]; /**< Bonded device addr info. */ -} bond_dev_list_t; +typedef struct +{ + uint8_t num; /**< Number of bonded device. */ + ble_gap_bdaddr_t items[BLE_GAP_MAX_BOND_NUM]; /**< Bonded device addr info. */ +} ble_gap_bond_dev_list_t; /** - * @brief White list + * @brief White list */ -typedef struct { - uint8_t num; /**< Number of available items. */ - gap_bdaddr_t items[MAX_WL_NUM]; /**< Content of each item. */ -} white_list_t; +typedef struct +{ + uint8_t num; /**< Number of available items. */ + ble_gap_bdaddr_t items[BLE_GAP_MAX_WL_NUM]; /**< Content of each item. */ +} ble_gap_white_list_t; /** * @brief Periodic advertising list */ -typedef struct { - uint8_t num; /**< Number of available items. */ - gap_period_adv_addr_cfg_t items[MAX_PRD_ADV_NUM]; /**< Content of each item. */ -} period_adv_list_t; +typedef struct +{ + uint8_t num; /**< Number of available items. */ + ble_gap_period_adv_addr_cfg_t items[BLE_GAP_MAX_PRD_ADV_NUM]; /**< Content of each item. */ +} ble_gap_period_adv_list_t; /** - * @brief RPA list item info + * @brief RPA list item info */ -typedef struct { - gap_bdaddr_t bd_addr; /**< Peer device identity. */ - uint8_t priv_mode; /**< Privacy mode, see enum @ref privacy_mode_t. */ - uint8_t peer_irk[MAX_KEY_LEN]; /**< Peer IRK. */ - uint8_t local_irk[MAX_KEY_LEN]; /**< Local IRK. */ -} gap_ral_dev_info_t; +typedef struct +{ + ble_gap_bdaddr_t bd_addr; /**< Peer device identity. */ + ble_gap_privacy_mode_t priv_mode; /**< Privacy mode, see enum @ref ble_gap_privacy_mode_t. */ + uint8_t peer_irk[BLE_GAP_MAX_KEY_LEN]; /**< Peer IRK. */ + uint8_t local_irk[BLE_GAP_MAX_KEY_LEN]; /**< Local IRK. */ +} ble_gap_ral_dev_info_t; /** - * @brief RPA list info + * @brief RPA list info */ -typedef struct { - uint8_t num; /**< Number of RPA list. */ - gap_ral_dev_info_t items[MAX_BOND_NUM]; /**< RPA list item info. */ -} ral_dev_list_t; +typedef struct +{ + uint8_t num; /**< Number of RPA list. */ + ble_gap_ral_dev_info_t items[BLE_GAP_MAX_BOND_NUM]; /**< RPA list item info. */ +} ble_gap_ral_dev_list_t; /** - * @brief The BLE reslove rpa address callback. + * @brief Operation code used to read resolvable address. */ -typedef void (*reslv_rpa_addr_callback_t) (uint8_t status, gap_bdaddr_t *iden_addr, - uint8_t src_info); +typedef enum +{ + BLE_GAP_OPCODE_LOCAL_RSLV_ADDR_READ, /**< Local resolvable address operation. */ + BLE_GAP_OPCODE_PEER_RSLV_ADDR_READ, /**< Peer resolvable address operation. */ +} ble_gap_rslv_addr_read_op_id_t; -/** - * @brief The BLE rpa address report callback. +/** @brief Advertising Stop info. */ +typedef struct +{ + ble_gap_stopped_reason_t reason; /**< Advertising Stop info. */ +} ble_gap_evt_adv_stop_t; + +/** @brief Scan request info. */ +typedef struct +{ + ble_gap_bdaddr_t peer_addr; /**< Scan request info. */ +} ble_gap_evt_scan_req_t; + +/** @brief Scan Stop info struct. */ +typedef struct +{ + ble_gap_stopped_reason_t reason; /**< Scan Stop info. */ +} ble_gap_evt_scan_stop_t; + +/** @brief Advertising report event for @ref BLE_GAPM_EVT_ADV_REPORT. */ +typedef struct +{ + ble_gap_adv_report_type_t adv_type; /**< Advertising type. @ref ble_gap_adv_report_type_t. */ + ble_gap_adv_report_info_t adv_info; /**< Bit field providing information about the received report. @ref ble_gap_adv_report_info_t. */ + ble_gap_bdaddr_t broadcaster_addr; /**< Broadcaster device address. */ + ble_gap_bdaddr_t direct_addr; /**< Target address (in case of a directed advertising report). */ + int8_t tx_pwr; /**< TX power (in dBm). */ + int8_t rssi; /**< RSSI (between -127 and +20 dBm). */ + uint8_t phy_prim; /**< Primary PHY on which advertising report has been received. */ + uint8_t phy_second; /**< Secondary PHY on which advertising report has been received. */ + uint8_t adv_sid; /**< Advertising SID , valid only for periodic advertising report. */ + uint16_t period_adv_intv; /**< Periodic advertising interval (in unit of 1.25ms, min is 7.5ms), valid only for periodic advertising report. */ + uint8_t per_sync_idx; /**< Periodic syncronization index, valid only for periodic advertising report. */ + uint16_t length; /**< Report length. */ + uint8_t *data; /**< Report. */ +} ble_gap_evt_adv_report_t; + +/** @brief Sync established event for @ref BLE_GAPM_EVT_SYNC_ESTABLISH. */ +typedef struct +{ + uint8_t phy; /**< PHY on which synchronization has been established. */ + uint16_t intv; /**< Periodic advertising interval (in unit of 1.25ms, min is 7.5ms). */ + uint8_t adv_sid; /**< Advertising SID. */ + uint8_t clk_acc; /**< Advertiser clock accuracy. @ref ble_gap_clk_acc_t. */ + ble_gap_bdaddr_t bd_addr; /**< Advertiser address. */ + uint16_t sync_hdl; /**< Sync handle. */ +} ble_gap_evt_sync_established_t; + +/** @brief Read resolvable address event for @ref BLE_GAPM_EVT_READ_RSLV_ADDR. */ +typedef struct +{ + uint8_t op_code; /**< Operation code. @ref ble_gap_rslv_addr_read_op_id_t. */ + ble_gap_addr_t gap_addr; /**< Resolvable address info. */ + } ble_gap_evt_rslv_addr_read_t; + +/**@brief BLE GAPM event structure. */ +typedef struct +{ + uint8_t index; /**< Index of connection or advertising. */ + union + { + ble_gap_evt_dev_info_get_t dev_info; /**< Device info parameters. */ + ble_gap_evt_adv_stop_t adv_stop; /**< Advertising stop parameter. */ + ble_gap_evt_scan_req_t scan_req; /**< Scan Request parameter. */ + ble_gap_evt_scan_stop_t scan_stop; /**< Scan Stop parameter. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report parameter. */ + ble_gap_evt_sync_established_t sync_established; /**< Periodic Advertising Synchronization Established parameter. */ + ble_gap_evt_rslv_addr_read_t rslv_addr; /**< Read Resolvable Address parameter. */ + } params; /**< Event Parameters. */ +} ble_gapm_evt_t; +/** @} */ + +/** @addtogroup BLE_GAPM_TYPEDEF Typedefs + * @{ */ -typedef void (*rpa_addr_report_callback_t) (ble_actv_type_t type, uint8_t index, - const uint8_t *rpa_addr); +/** @brief The BLE reslove rpa address callback. */ +typedef void (*ble_gap_reslv_rpa_addr_callback_t) (uint8_t status, ble_gap_bdaddr_t *iden_addr, uint8_t src_info); +/** @brief The BLE rpa address report callback. */ +typedef void (*ble_gap_rpa_addr_report_callback_t) (ble_gap_actv_type_t type, uint8_t index, const uint8_t *rpa_addr); /** @} */ @@ -807,7 +893,7 @@ void ble_gap_pair_enable(bool enable); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gap_addr_set(gap_bdaddr_t const *p_addr); +uint16_t ble_gap_addr_set(ble_gap_bdaddr_t const *p_addr); /** **************************************************************************************** @@ -819,16 +905,16 @@ uint16_t ble_gap_addr_set(gap_bdaddr_t const *p_addr); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_addr_get(gap_bdaddr_t *p_addr); +uint16_t ble_gap_addr_get(ble_gap_bdaddr_t *p_addr); /** **************************************************************************************** * @brief Set the tx power * - * @param[in] role: Select the role to set tx power. @ref gap_event_role_t for possible roles. + * @param[in] role: Select the role to set tx power. @ref ble_gap_actv_role_t for possible roles. * @param[in] index: The idx parameter is interpreted on role. - * -If the role is @ref GAP_EVENT_ROLE_ADV, it's the index of Advertising. - * -If the role is @ref GAP_EVENT_ROLE_CON, it's the index of connection. + * -If role is @ref BLE_GAP_ACTIVITY_ROLE_ADV, it's the index of Advertising. + * -If role is @ref BLE_GAP_ACTIVITY_ROLE_CON, it's the index of connection. * -For all other roles, it should be ignored. * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. * @@ -838,17 +924,17 @@ uint16_t ble_gap_addr_get(gap_bdaddr_t *p_addr); * @retval ::SDK_ERR_INVALID_HANDLE: Invalid handle supplied. **************************************************************************************** */ -uint16_t ble_gap_tx_power_set(gap_event_role_t role, uint8_t index, int8_t txpwr_dbm); +uint16_t ble_gap_tx_power_set(ble_gap_actv_role_t role, uint8_t index, int8_t txpwr_dbm); /** **************************************************************************************** * @brief Get the tx power * - * @param[in] role: Select the role to Get tx power. @ref gap_event_role_t for possible roles. + * @param[in] role: Select the role to Get tx power. @ref ble_gap_actv_role_t for possible roles. * @param[in] index: The idx parameter is interpreted on role. - * -If the role is @ref GAP_EVENT_ROLE_ADV, it's the index of Advertising. - * -If the role is @ref GAP_EVENT_ROLE_CON, it's the index of connection. - * -For all other roles, it should be ignored. + * -If role is @ref BLE_GAP_ACTIVITY_ROLE_ADV, it's the index of Advertising. + * -If role is @ref BLE_GAP_ACTIVITY_ROLE_CON, it's the index of connection. + * -For all other roles, it should be ignored. * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. * * @retval ::SDK_SUCCESS: Operation is Success. @@ -857,32 +943,7 @@ uint16_t ble_gap_tx_power_set(gap_event_role_t role, uint8_t index, int8_t txpwr * @retval ::SDK_ERR_INVALID_HANDLE: Invalid handle supplied. **************************************************************************************** */ -uint16_t ble_gap_tx_power_get(gap_event_role_t role, uint8_t index, int8_t *txpwr_dbm); - -/** - **************************************************************************************** - * @brief Set the default tx power for all roles. - * - * @note This function should be called before BLE stack init. - * - * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. - * - * @retval ::SDK_SUCCESS: Operation is Success. - **************************************************************************************** - */ -uint16_t ble_gap_default_tx_power_set(int8_t txpwr_dbm); - -/** - **************************************************************************************** - * @brief Get the default tx power for all roles. - * - * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. - * - * @retval ::SDK_SUCCESS: Operation is Success. - **************************************************************************************** - */ -uint16_t ble_gap_default_tx_power_get(int8_t *txpwr_dbm); - +uint16_t ble_gap_tx_power_get(ble_gap_actv_role_t role, uint8_t index, int8_t *txpwr_dbm); /** **************************************************************************************** @@ -894,13 +955,13 @@ uint16_t ble_gap_default_tx_power_get(int8_t *txpwr_dbm); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_irk_set(gap_sec_key_t* p_irk); +uint16_t ble_gap_irk_set(ble_gap_sec_key_t* p_irk); /** **************************************************************************************** * @brief Set privacy related parameters. - * @param[in] renew_dur: Duration before regenerating a device address when privacy is enabled in seconds. - * Range: 0x0001 (1s) ~ 0xA1B8 (11.5 hr). The suggested time is 900s(15 minutes). + * @param[in] renew_dur: Duration before regenerating a device address when privacy is enabled in seconds. Range: 0x0001 (1s) ~ 0xA1B8 (11.5 hr). + * The suggested time is 900s(15 minutes). * @param[in] enable_flag: Indicate the controller privacy is enabled or disabled. * * @retval ::SDK_SUCCESS: Operation is successful. @@ -913,16 +974,14 @@ uint16_t ble_gap_privacy_params_set(uint16_t renew_dur, bool enable_flag); **************************************************************************************** * @brief Set suggested default LE data length. * - * @param[in] sugg_max_tx_octet: Suggested value for the Controller's maximum transmitted number of - * payload octets to be used, the range is 27~251. - * @param[in] sugg_max_tx_time: Suggested value for the Controller's maximum packet transmission time to be used, - * the range is 328~2120. + * @param[in] sugg_max_tx_octet: Suggested value for the Controller's maximum transmitted number of payload octets to be used, the range is 27~251. + * @param[in] sugg_max_tx_time: Suggested value for the Controller's maximum packet transmission time to be used, the range is 328~2120. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. **************************************************************************************** */ -uint16_t ble_gap_data_length_set(uint16_t sugg_max_tx_octet, uint16_t sugg_max_tx_time); +uint16_t ble_gap_data_length_set(uint16_t sugg_max_tx_octet,uint16_t sugg_max_tx_time); /** **************************************************************************************** @@ -930,34 +989,30 @@ uint16_t ble_gap_data_length_set(uint16_t sugg_max_tx_octet, uint16_t sugg_max_t * * @param[in] max_mtu: Maximal MTU acceptable for device, the range is 65~512. * @param[in] max_mps: Maximal MPS Packet size acceptable for device (for COC SDU), the range is 65~max_mtu. - * @param[in] max_nb_lecb: Maximum number of LE Credit based connection that can be established, - * this range is 0x00~0x20. The actual number is decided by resource available. + * @param[in] max_nb_lecb: Maximum number of LE Credit based connection that can be established, this range is 0x00~0x20. + * The actual number is decided by resource available. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * - * @note If these parameters are not set, the stack will config the default value as - * (max_mtu = 512, max_mps = 512 and max_nb_lecb = 10). + * @note If these parameters are not set, the stack will config the default value as (max_mtu = 512, max_mps = 512 and max_nb_lecb = 10). **************************************************************************************** */ -uint16_t ble_gap_l2cap_params_set(uint16_t max_mtu, uint16_t max_mps, uint8_t max_nb_lecb); +uint16_t ble_gap_l2cap_params_set(uint16_t max_mtu,uint16_t max_mps,uint8_t max_nb_lecb); /** **************************************************************************************** * @brief Set the preferred values for the transmitter PHY and receiver PHY. * - * @param[in] tx_pref_phy: A bit field that indicates the transmitter PHYs - * that the Host prefers the Controller to use(see @ref BLE_GAP_PHYS). - * @param[in] rx_pref_phy: A bit field that indicates the receiver PHYs that the Host prefers the - * Controller to use(see @ref BLE_GAP_PHYS). + * @param[in] tx_pref_phy: A bit field that indicates the transmitter PHYs that the Host prefers the Controller to use(see @ref BLE_GAP_PHY_OPTIONS). + * @param[in] rx_pref_phy: A bit field that indicates the receiver PHYs that the Host prefers the Controller to use(see @ref BLE_GAP_PHY_OPTIONS). **************************************************************************************** */ void ble_gap_pref_phy_set(uint8_t tx_pref_phy, uint8_t rx_pref_phy); /** **************************************************************************************** - * @brief Set the RF path gain or loss between the RF transceiver and the antenna - * contributed by intermediate components. + * @brief Set the RF path gain or loss between the RF transceiver and the antenna contributed by intermediate components. * * @param[in] tx_path_comp: RF TX Path Compensation value (from -128dB to 128dB, unit is 0.1dB). * @param[in] rx_path_comp: RF RX Path Compensation value (from -128dB to 128dB, unit is 0.1dB). @@ -972,18 +1027,25 @@ uint16_t ble_gap_path_compensation_set(int16_t tx_path_comp, int16_t rx_path_com **************************************************************************************** * @brief Set advertising channel map before advertising starts. * - * @param[in] p_chnl_map: Bitmask of LE channel map. See enum @ref gap_chnl_map_t for BT Core Spec version <= 4.2. + * @param[in] p_chnl_map: Bitmask of LE channel map. See enum @ref ble_gap_chnl_map_t for BT Core Spec version <= 4.2. * - * @retval ::SDK_SUCCESS: Operation is successful. + * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_CHNL_MAP_SET - will be called once the operation has completed. **************************************************************************************** */ -uint16_t ble_gap_chnl_map_set(gap_chnl_map_t* p_chnl_map); +uint16_t ble_gap_chnl_map_set(ble_gap_chnl_map_t* p_chnl_map); + +/** + **************************************************************************************** + * @brief Set ble channel map update timer enable or disable. + * + * @param[in] enable_flag: timer enable flag . true is enable,false is disable. + * + * @retval ::SDK_SUCCESS: Operation is successful. + **************************************************************************************** + */ +uint16_t ble_gap_chnl_map_timer_set(bool enable_flag); /** **************************************************************************************** @@ -997,7 +1059,7 @@ uint16_t ble_gap_chnl_map_set(gap_chnl_map_t* p_chnl_map); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_bond_devs_get(bond_dev_list_t *p_bond_list); +uint16_t ble_gap_bond_devs_get(ble_gap_bond_dev_list_t *p_bond_list); /** **************************************************************************************** @@ -1011,7 +1073,7 @@ uint16_t ble_gap_bond_devs_get(bond_dev_list_t *p_bond_list); * @retval ::SDK_ERR_INVALID_PARAM: The parameter is invalid. **************************************************************************************** */ -uint16_t ble_gap_bond_dev_addr_get(uint8_t conn_idx, gap_bdaddr_t *p_peer_addr); +uint16_t ble_gap_bond_dev_addr_get(uint8_t conn_idx, ble_gap_bdaddr_t *p_peer_addr); /** **************************************************************************************** @@ -1040,7 +1102,7 @@ uint16_t ble_gap_bond_devs_clear(void); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_bond_dev_del(const gap_bdaddr_t *p_peer_addr); +uint16_t ble_gap_bond_dev_del(const ble_gap_bdaddr_t *p_peer_addr); /** **************************************************************************************** @@ -1052,14 +1114,13 @@ uint16_t ble_gap_bond_dev_del(const gap_bdaddr_t *p_peer_addr); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_whitelist_get(white_list_t *p_whitelist); +uint16_t ble_gap_whitelist_get(ble_gap_white_list_t *p_whitelist); /** **************************************************************************************** - * @brief Add the devices into current white list. If white list is full or there are duplicated entries, - * it will return error. + * @brief Add the devices into current white list. If white list is full or there are duplicated entries, it will return error. * - * @param[in] p_whitelist: Pointer to input white list. + * @param[in] p_whitelist: Pointer to input white list. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. @@ -1067,20 +1128,15 @@ uint16_t ble_gap_whitelist_get(white_list_t *p_whitelist); * @retval ::SDK_ERR_LIST_FULL: List is full. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_WHITELIST_SET - * will be called once the operation has completed. **************************************************************************************** */ -uint16_t ble_gap_whitelist_add(const white_list_t *p_whitelist); +uint16_t ble_gap_whitelist_add(const ble_gap_white_list_t *p_whitelist); /** **************************************************************************************** - * @brief Delete the devices out of current white list. If the entries do not exist in the current white list, - * it will return error. + * @brief Delete the devices out of current white list. If the entries do not exist in the current white list, it will return error. * - * @param[in] p_whitelist: Pointer to input white list. + * @param[in] p_whitelist: Pointer to input white list. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. @@ -1088,13 +1144,9 @@ uint16_t ble_gap_whitelist_add(const white_list_t *p_whitelist); * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_WHITELIST_SET - * will be called once the operation has completed. **************************************************************************************** */ -uint16_t ble_gap_whitelist_del(const white_list_t *p_whitelist); +uint16_t ble_gap_whitelist_del(const ble_gap_white_list_t *p_whitelist); /** **************************************************************************************** @@ -1103,10 +1155,6 @@ uint16_t ble_gap_whitelist_del(const white_list_t *p_whitelist); * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_WHITELIST_SET - * will be called once the operation has completed. **************************************************************************************** */ uint16_t ble_gap_whitelist_clear(void); @@ -1121,7 +1169,7 @@ uint16_t ble_gap_whitelist_clear(void); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_per_adv_list_get(period_adv_list_t *p_pal_list); +uint16_t ble_gap_per_adv_list_get(ble_gap_period_adv_list_t *p_pal_list); /** **************************************************************************************** @@ -1136,18 +1184,13 @@ uint16_t ble_gap_per_adv_list_get(period_adv_list_t *p_pal_list); * @retval ::SDK_ERR_LIST_FULL: List is full. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_PER_ADV_LIST_SET - * will be called once the operation has completed. **************************************************************************************** */ -uint16_t ble_gap_per_adv_list_add(const period_adv_list_t *p_pal_list); +uint16_t ble_gap_per_adv_list_add(const ble_gap_period_adv_list_t *p_pal_list); /** **************************************************************************************** - * @brief Delete the devices out of periodic advertising list. If the entries do not exist in the current list, - * an error will be returned. + * @brief Delete the devices out of periodic advertising list. If the entries do not exist in the current list, an error will be returned. * * @param[in] p_pal_list: Pointer to input periodic advertising list. * @@ -1157,22 +1200,14 @@ uint16_t ble_gap_per_adv_list_add(const period_adv_list_t *p_pal_list); * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_PER_ADV_LIST_SET - * will be called once the operation has completed. **************************************************************************************** */ -uint16_t ble_gap_per_adv_list_del(const period_adv_list_t *p_pal_list); +uint16_t ble_gap_per_adv_list_del(const ble_gap_period_adv_list_t *p_pal_list); /** **************************************************************************************** * @brief Clear all the entries in the current periodic advertising list. * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_param_set_cb with op_id: @ref GAP_OPCODE_PER_ADV_LIST_SET - * will be called once the operation has completed. - * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. **************************************************************************************** @@ -1188,7 +1223,7 @@ uint16_t ble_gap_per_adv_list_clear(void); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_rpa_list_get(ral_dev_list_t *p_rpa_list); +uint16_t ble_gap_rpa_list_get(ble_gap_ral_dev_list_t *p_rpa_list); /** **************************************************************************************** @@ -1199,13 +1234,9 @@ uint16_t ble_gap_rpa_list_get(ral_dev_list_t *p_rpa_list); * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_dev_info_get_cb with the specified op_id (see @ref gap_dev_info_get_type_t) - * will be called once the requested parameters has been got. **************************************************************************************** */ -uint16_t ble_gap_dev_info_get(gap_dev_info_get_type_t type); +uint16_t ble_gap_dev_info_get(ble_gap_dev_info_get_type_t type); /** **************************************************************************************** @@ -1219,14 +1250,13 @@ uint16_t ble_gap_dev_info_get(gap_dev_info_get_type_t type); * @retval ::SDK_ERR_INVALID_ADV_IDX: Invalid advertising index supplied. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * + * - * @note Discovery mode param contains Flags AD type, setting adv data should not set the Flags AD type. + * @note Discovery mode param contains Flags AD type, setting adv data should not set the Flags AD type. * @note This API is for legacy advertsing (BT Core Spec version <= 4.2). **************************************************************************************** */ -uint16_t ble_gap_adv_param_set(uint8_t adv_idx, gap_own_addr_t own_addr_type, - gap_adv_param_t* p_adv_param); +uint16_t ble_gap_adv_param_set(uint8_t adv_idx, ble_gap_own_addr_t own_addr_type, ble_gap_adv_param_t* p_adv_param); /** **************************************************************************************** @@ -1244,13 +1274,11 @@ uint16_t ble_gap_adv_param_set(uint8_t adv_idx, gap_own_addr_t own_addr_type, * @note This API is for extended and periodic advertising (BT Core Spec version >= 5.0). **************************************************************************************** */ -uint16_t ble_gap_ext_adv_param_set(uint8_t adv_idx, gap_own_addr_t own_addr_type, - gap_ext_adv_param_t* p_adv_param); +uint16_t ble_gap_ext_adv_param_set(uint8_t adv_idx, ble_gap_own_addr_t own_addr_type, ble_gap_ext_adv_param_t* p_adv_param); /** **************************************************************************************** - * @brief Set Advertising Data, Scan Response Data and Periodic Advertising Data. See ENUM @ref gap_ad_type_t - for ADV Type definitions. See ENUM @ref gap_adv_flags_t for ADV flag definitions. + * @brief Set Advertising Data, Scan Response Data and Periodic Advertising Data. * * @param[in] adv_idx: Advertising index, range is 0 to 4. * @param[in] type: Data type. @@ -1266,13 +1294,11 @@ uint16_t ble_gap_ext_adv_param_set(uint8_t adv_idx, gap_own_addr_t own_addr_type * @note User should not add extra Flags AD type as the BLE Stack has added the Flags AD type already. **************************************************************************************** */ -uint16_t ble_gap_adv_data_set(uint8_t adv_idx, gap_adv_data_type_t type, const uint8_t* p_data, - uint16_t length); +uint16_t ble_gap_adv_data_set(uint8_t adv_idx, ble_gap_adv_data_type_t type, const uint8_t* p_data, uint16_t length); /** **************************************************************************************** - * @brief Update Advertising Data, Scan Response Data and Periodic Advertising Data. See ENUM @ref gap_ad_type_t - * for ADV Type definitions. See ENUM @ref gap_adv_flags_t for ADV flag definitions. + * @brief Update Advertising Data, Scan Response Data and Periodic Advertising Data. * * @param[in] adv_idx: Advertising index, range is 0 to 4. * @param[in] type: Data type. @@ -1288,8 +1314,7 @@ uint16_t ble_gap_adv_data_set(uint8_t adv_idx, gap_adv_data_type_t type, const u * @note User should not add extra Flags AD type as the BLE Stack has added the Flags AD type already. **************************************************************************************** */ -uint16_t ble_gap_update_adv_data(uint8_t adv_idx, gap_adv_data_type_t type, const uint8_t* p_data, - uint16_t length); +uint16_t ble_gap_update_adv_data(uint8_t adv_idx, ble_gap_adv_data_type_t type, const uint8_t* p_data, uint16_t length); /** **************************************************************************************** @@ -1304,17 +1329,10 @@ uint16_t ble_gap_update_adv_data(uint8_t adv_idx, gap_adv_data_type_t type, cons * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. * - * @note If advertising mode is directed high duty cycle mode, - * duration should be set nonzero and not be greater than 1.28s. - * @note This API is asynchronous. - * @note If the field scan_req_ind_en in @ref gap_adv_param_t is TRUE passed in @ref ble_gap_adv_param_set function, - or if the GAP_ADV_PROP_SCAN_REQ_NTF_EN_BIT is set in @ref gap_adv_prop_t and - passed in @ref ble_gap_ext_adv_param_set function, - @ref gap_cb_fun_t::app_gap_scan_req_ind_cb will be called once a scan request has been received. - * @note @ref gap_cb_fun_t::app_gap_adv_start_cb will be called once the operation has completed. + * @note If advertising mode is directed high duty cycle mode, duration should be set nonzero and not be greater than 1.28s. **************************************************************************************** */ -uint16_t ble_gap_adv_start(uint8_t adv_idx, gap_adv_time_param_t* p_timeout); +uint16_t ble_gap_adv_start(uint8_t adv_idx, ble_gap_adv_time_param_t* p_timeout); /** **************************************************************************************** @@ -1324,10 +1342,6 @@ uint16_t ble_gap_adv_start(uint8_t adv_idx, gap_adv_time_param_t* p_timeout); * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_ADV_IDX: Invalid advertising index supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_adv_stop_cb will be called once the operation has completed - * or advertising has been stopped. **************************************************************************************** */ uint16_t ble_gap_adv_stop(uint8_t adv_idx); @@ -1342,11 +1356,9 @@ uint16_t ble_gap_adv_stop(uint8_t adv_idx); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is for legacy scanning (BT Core Spec version <= 4.2). **************************************************************************************** */ -uint16_t ble_gap_scan_param_set(gap_own_addr_t own_addr_type, gap_scan_param_t* p_scan_param); +uint16_t ble_gap_scan_param_set(ble_gap_own_addr_t own_addr_type, ble_gap_scan_param_t* p_scan_param); /** **************************************************************************************** @@ -1359,13 +1371,12 @@ uint16_t ble_gap_scan_param_set(gap_own_addr_t own_addr_type, gap_scan_param_t* * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. * * @note This API is for extended scanning (BT Core Spec version >= 5.0). - * The Scan window in p_scan_param should be enough to recieve one packet. For example. - * If you want to recieve packects with 1270 bytes on coded phy(S8), the scan_wd should be greater than 82ms. - * If you want to recieve packects with 1270 bytes on coded phy(S2), the scan_wd should be greater than 21ms. + * The Scan window in p_scan_param should be enough to recieve one packet. For example. + * If you want to recieve packects with 1270 bytes on coded phy(S8), the scan_wd should be greater than 82ms. + * If you want to recieve packects with 1270 bytes on coded phy(S2), the scan_wd should be greater than 21ms. **************************************************************************************** */ -uint16_t ble_gap_ext_scan_param_set(gap_own_addr_t own_addr_type, - gap_ext_scan_param_t* p_scan_param); +uint16_t ble_gap_ext_scan_param_set(ble_gap_own_addr_t own_addr_type, ble_gap_ext_scan_param_t* p_scan_param); /** **************************************************************************************** @@ -1374,11 +1385,6 @@ uint16_t ble_gap_ext_scan_param_set(gap_own_addr_t own_addr_type, * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_adv_report_ind_cb will be called once the advertising report has been received. - * @note @ref gap_cb_fun_t::app_gap_scan_stop_cb will be called once the scanning has been stopped. - * @note @ref gap_cb_fun_t::app_gap_scan_start_cb will be called once the operation has completed. **************************************************************************************** */ uint16_t ble_gap_scan_start(void); @@ -1389,10 +1395,6 @@ uint16_t ble_gap_scan_start(void); * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_scan_stop_cb will be called once the operation has completed - * or the scanning has been stopped. **************************************************************************************** */ uint16_t ble_gap_scan_stop(void); @@ -1409,22 +1411,17 @@ uint16_t ble_gap_scan_stop(void); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gap_per_sync_param_set(uint8_t per_sync_idx, gap_per_sync_param_t* p_per_sync_param); +uint16_t ble_gap_per_sync_param_set(uint8_t per_sync_idx, ble_gap_per_sync_param_t* p_per_sync_param); /** **************************************************************************************** - * @brief Start to synchronize with periodic advertising from an advertiser - * and begin receiving periodic advertising packets. + * @brief Start to synchronize with periodic advertising from an advertiser and begin receiving periodic advertising packets. * @param[in] per_sync_idx: Periodic synchronization index (range is 0 to 4). * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_INVALID_PER_SYNC_IDX: Invalid periodic syncronization index supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_sync_establish_cb will be called - * once the periodic advertising synchronization has been established. **************************************************************************************** */ uint16_t ble_gap_per_sync_start(uint8_t per_sync_idx); @@ -1437,9 +1434,6 @@ uint16_t ble_gap_per_sync_start(uint8_t per_sync_idx); * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PER_SYNC_IDX: Invalid periodic syncronization index supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_stop_sync_cb will be called once the operation has completed. **************************************************************************************** */ uint16_t ble_gap_per_sync_stop(uint8_t per_sync_idx); @@ -1454,17 +1448,11 @@ uint16_t ble_gap_per_sync_stop(uint8_t per_sync_idx); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * + * * @note This API is for legacy connection (BT Core Spec version <= 4.2). - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_connect_cb will be called once the operation has completed - * or the connection has been completed. - * @note @ref gap_cb_fun_t::app_gap_peer_name_ind_cb will be called once the peer name has been got for the - Name Discovery Procedure. See enum @ref GAP_INIT_TYPE_NAME_DISC of type @ref gap_init_type_t. **************************************************************************************** */ -uint16_t ble_gap_connect(gap_own_addr_t own_addr_type, gap_init_param_t* p_init_param); +uint16_t ble_gap_connect(ble_gap_own_addr_t own_addr_type, ble_gap_init_param_t* p_init_param); /** **************************************************************************************** @@ -1476,15 +1464,11 @@ uint16_t ble_gap_connect(gap_own_addr_t own_addr_type, gap_init_param_t* p_init_ * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * + * * @note This API is for extended connection (BT Core Spec version >= 5.0). - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_connect_cb will be called once\ - * the operation has completed or the connection has been completed. **************************************************************************************** */ -uint16_t ble_gap_ext_connect(gap_own_addr_t own_addr_type, gap_ext_init_param_t* p_init_param); +uint16_t ble_gap_ext_connect(ble_gap_own_addr_t own_addr_type, ble_gap_ext_init_param_t* p_init_param); /** **************************************************************************************** @@ -1492,9 +1476,6 @@ uint16_t ble_gap_ext_connect(gap_own_addr_t own_addr_type, gap_ext_init_param_t* * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. - * - * @note This API is asynchronous. - * @note @ref gap_cb_fun_t::app_gap_connect_cancel_cb will be called once the operation has completed. **************************************************************************************** */ uint16_t ble_gap_connect_cancel(void); @@ -1536,7 +1517,7 @@ void ble_gap_ppcp_present_set(bool present_flag); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_ppcp_set(gap_conn_param_t const *p_conn_params); +uint16_t ble_gap_ppcp_set(ble_gap_conn_param_t const *p_conn_params); /** **************************************************************************************** @@ -1547,22 +1528,20 @@ uint16_t ble_gap_ppcp_set(gap_conn_param_t const *p_conn_params); * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. **************************************************************************************** */ -uint16_t ble_gap_ppcp_get(gap_conn_param_t *p_conn_params); +uint16_t ble_gap_ppcp_get(ble_gap_conn_param_t *p_conn_params); /** **************************************************************************************** * @brief Set GAP device name. * @param[in] write_perm: Write permissions of the device name characteristic. - * @param[in] p_dev_name: The pointer to device name value. If p_dev_name is NULL, - this function will only set write permissions of the device name. + * @param[in] p_dev_name: The pointer to device name value. If p_dev_name is NULL, this function will only set write permissions of the device name. * @param[in] length: Device name length. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. **************************************************************************************** */ -uint16_t ble_gap_device_name_set(gap_dev_name_write_perm_t write_perm, uint8_t const *p_dev_name, - uint16_t length); +uint16_t ble_gap_device_name_set(ble_gap_dev_name_write_perm_t write_perm, uint8_t const *p_dev_name, uint16_t length); /** **************************************************************************************** @@ -1575,9 +1554,9 @@ uint16_t ble_gap_device_name_set(gap_dev_name_write_perm_t write_perm, uint8_t c * @retval ::SDK_ERR_INVALID_DATA_LENGTH: Invalid data size(s) supplied. * * @note If device name was not set, the default device name "GOODIX_BLE" will be available. - * @note If the device name is longer than the size of the supplied buffer,p_len will return - * the complete device name length, and not the number of bytes actually returned in p_dev_name. - * The application may use this information to allocate a suitable buffer size. + * @note If the device name is longer than the size of the supplied buffer,p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. **************************************************************************************** */ uint16_t ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_length); @@ -1592,12 +1571,9 @@ uint16_t ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_length); * @retval ::SDK_ERR_INVALID_PSM_NUM: Invalid psm number. * @retval ::SDK_ERR_INVALID_PSM_EXCEEDED_MAX_PSM_NUM: The maximum psm number limit is exceeded. * @retval ::SDK_ERR_INVALID_PSM_ALREADY_REGISTERED: The psm number has been registered. - * - * @note This API is asynchronous. - * @ref gap_cb_fun_t::app_gap_psm_manager_cb callback with op_id: @ref GAP_OPCODE_LEPSM_REGISTER will be called. **************************************************************************************** */ -uint16_t ble_gap_lepsm_register(gap_lepsm_register_t* p_lepsm); +uint16_t ble_gap_lepsm_register(ble_gap_lepsm_register_t* p_lepsm); /** **************************************************************************************** @@ -1607,10 +1583,6 @@ uint16_t ble_gap_lepsm_register(gap_lepsm_register_t* p_lepsm); * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PSM_NUM: Invalid psm number. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * - * @note This API is asynchronous. - * @note app_gap_psm_manager_cb will be called once the operation has completed, - * @ref gap_cb_fun_t::app_gap_psm_manager_cb callback with op_id: @ref GAP_OPCODE_LEPSM_UNREGISTER will be called. **************************************************************************************** */ uint16_t ble_gap_lepsm_unregister(uint16_t le_psm); @@ -1619,29 +1591,28 @@ uint16_t ble_gap_lepsm_unregister(uint16_t le_psm); **************************************************************************************** * @brief Set privacy mode for peer device. * @param[in] peer_addr: The peer address. - * @param[in] mode: Privacy mode (see @ref privacy_mode_t). + * @param[in] mode: Privacy mode. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_DISALLOWED: Operation is disallowed. * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - * **************************************************************************************** */ -uint16_t ble_gap_privacy_mode_set(gap_bdaddr_t peer_addr, privacy_mode_t mode); +uint16_t ble_gap_privacy_mode_set(ble_gap_bdaddr_t peer_addr, ble_gap_privacy_mode_t mode); /** **************************************************************************************** * @brief Read peer or local resolvable address. - * @param[in] op_code: The operation code (see @ref gap_rslv_addr_read_op_id_t). - * @param[in] peer_iden_addr: The peer identity address. + * @param[in] op_code: The operation code (see @ref ble_gap_rslv_addr_read_op_id_t). + * @param[in] peer_iden_addr: The peer identity address. * * @retval ::SDK_SUCCESS: Operation is successful. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * **************************************************************************************** */ -uint16_t ble_gap_rslv_addr_read(gap_rslv_addr_read_op_id_t op_code, gap_bdaddr_t peer_iden_addr); +uint16_t ble_gap_rslv_addr_read(ble_gap_rslv_addr_read_op_id_t op_code, ble_gap_bdaddr_t peer_iden_addr); /** ***************************************************************************************** @@ -1655,8 +1626,7 @@ uint16_t ble_gap_rslv_addr_read(gap_rslv_addr_read_op_id_t op_code, gap_bdaddr_t * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. ***************************************************************************************** */ -uint16_t ble_gap_reslv_rpa_addr(uint8_t *reslv_addr, uint8_t src_info, - reslv_rpa_addr_callback_t cb); +uint16_t ble_gap_reslv_rpa_addr(uint8_t *reslv_addr, uint8_t src_info, ble_gap_reslv_rpa_addr_callback_t cb); /** ***************************************************************************************** @@ -1679,7 +1649,7 @@ uint16_t ble_gap_update_conn_param_method_set(uint8_t conn_idx, bool use_l2cap_f * ***************************************************************************************** */ -void ble_gap_rpa_addr_report_cb_register(rpa_addr_report_callback_t cb); +void ble_gap_rpa_addr_report_cb_register(ble_gap_rpa_addr_report_callback_t cb); /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatt.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatt.h old mode 100755 new mode 100644 index 7db12bb..4f9a5e6 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatt.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatt.h @@ -35,16 +35,16 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -*/ - -/** -* @addtogroup BLE_GATT Generic Attribute Profile (GATT) -* @{ -* @brief Definitions and prototypes for the GATT interface. -*/ + /** + * @addtogroup BLE + * @{ + */ + + /** + * @addtogroup BLE_GATT Generic Attribute Profile (GATT) + * @{ + * @brief Definitions and prototypes for the GATT interface. + */ /** @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Common @@ -54,6 +54,7 @@ #ifndef __BLE_GATT_H__ #define __BLE_GATT_H__ +#include "ble_error.h" #include /** @addtogroup BLE_GATT_COMMON Enumerations @@ -62,10 +63,12 @@ /** * @brief GATT common events. */ -typedef enum { +typedef enum +{ BLE_GATT_NOTIFICATION = 0x00, /**< Handle Value Notification. */ BLE_GATT_INDICATION, /**< Handle Value Indication. */ -} gatt_evt_type_t; +} ble_gatt_evt_type_t; + /** @} */ /** @addtogroup BLE_GATT_COMMON_STRUCTURES Structures @@ -74,22 +77,38 @@ typedef enum { /** * @brief GATT UUID structure. */ -typedef struct { +typedef struct +{ uint8_t uuid_len; /**< UUID length. */ uint8_t *uuid; /**< UUID value. */ } ble_uuid_t; /** - * @brief GATT common callback function description. + * @brief GATT MTU Exchange event for @ref BLE_GATT_COMMON_EVT_MTU_EXCHANGE. */ -typedef struct { - /**< Exchange MTU callback function. */ - void (*app_gatt_mtu_exchange_cb)(uint8_t conn_idx, uint8_t status, uint16_t mtu); - /**< Profile register callback function. @note prf_index range is from 0 to profile count - 1. - prf_index is current profile index. */ - void (*app_gatt_prf_register_cb)(uint8_t status, uint8_t prf_index); -} gatt_common_cb_fun_t; +typedef struct +{ + uint16_t mtu; /**< MTU Exchanged value. */ + } ble_gatt_common_evt_mtu_exchange_t; + /** + * @brief GATT Server Profile Register event for @ref BLE_GATT_COMMON_EVT_PRF_REGISTER. + */ +typedef struct +{ + uint8_t prf_index; /**< Profile Index. */ + } ble_gatt_common_evt_prf_reg_t; + +/**@brief GATT Common structure. */ +typedef struct +{ + uint8_t index; /**< Index of connection. */ + union + { + ble_gatt_common_evt_mtu_exchange_t mtu_exchange; /**< MTU exchanged event. */ + ble_gatt_common_evt_prf_reg_t prf_reg; /**< Server Profile Register event. */ + } params; /**< Event Parameters. */ +} ble_gatt_common_evt_t; /** @} */ /** @addtogroup BLE_GATT_FUNCTIONS Functions @@ -98,9 +117,9 @@ typedef struct { /** **************************************************************************************** * @brief Set ATT_MTU size. - * + * * @param[in] mtu: ATT_MTU size. - * + * * @note This function should be called before exchange MTU operation. This MTU size is used to all connections. * If not set these parameters, the stack will config the default value as (max_mtu = 512). * diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gattc.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gattc.h old mode 100755 new mode 100644 index ca98364..a6e3583 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gattc.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gattc.h @@ -35,16 +35,16 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -*/ - -/** -* @addtogroup BLE_GATT Generic Attribute Profile (GATT) -* @{ -* @brief Definitions and prototypes for the GATT interface. -*/ + /** + * @addtogroup BLE + * @{ + */ + + /** + * @addtogroup BLE_GATT Generic Attribute Profile (GATT) + * @{ + * @brief Definitions and prototypes for the GATT interface. + */ /** @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client @@ -69,13 +69,14 @@ /** * @brief GATT Client Service Discover Attribute type IDs. */ -typedef enum { +typedef enum +{ BLE_GATTC_BROWSE_NONE, /**< No Attribute Information. */ BLE_GATTC_BROWSE_INC_SRVC, /**< Included Service information. */ BLE_GATTC_BROWSE_ATTR_CHAR, /**< Characteristic Declaration. */ BLE_GATTC_BROWSE_ATTR_VAL, /**< Attribute Value definition. */ BLE_GATTC_BROWSE_ATTR_DESC, /**< Attribute Descriptor. */ -} gatt_attr_t; +} ble_gattc_attr_type_t; /** @} */ @@ -85,114 +86,108 @@ typedef enum { /** * @brief GATTC discovery characteristic structure. */ -typedef struct { +typedef struct +{ uint16_t start_hdl; /**< Start handle. */ uint16_t end_hdl; /**< End handle. */ ble_uuid_t *p_uuid; /**< Characteristic UUID. */ -} gattc_disc_char_t; +} ble_gattc_disc_char_t; /** * @brief GATTC read by characteristic UUID structure. */ -typedef struct { +typedef struct +{ uint16_t start_hdl; /**< Start handle. */ uint16_t end_hdl; /**< End handle. */ ble_uuid_t *p_uuid; /**< Characteristic UUID. */ -} gattc_read_by_uuid_t; +} ble_gattc_read_by_uuid_t; /** * @brief GATTC write attribute value structure. */ -typedef struct { +typedef struct +{ uint16_t handle; /**< Attribute handle. */ uint16_t offset; /**< value offset to start with. */ uint16_t length; /**< Write length. */ uint8_t *p_value; /**< Value to write. */ -} gattc_write_attr_value_t; +} ble_gattc_write_attr_value_t; /** * @brief GATTC write without response structure. */ -typedef struct { +typedef struct +{ bool signed_write; /**< True if signed write should be used when possible/applicable. */ uint16_t handle; /**< Attribute handle. */ uint16_t length; /**< Write length. */ uint8_t *p_value; /**< Value to write. */ -} gattc_write_no_resp_t; +} ble_gattc_write_no_resp_t; -/** @brief Read Multiple Handles. */ -typedef struct { +/**@brief Read Multiple Handles. */ +typedef struct +{ uint16_t handle; /**< Attribute handle. */ uint16_t len; /**< Known value: length of the handle (len shall not be set to 0). */ -} read_multiple_t; +} ble_gattc_multiple_att_t; -/** @brief GATTC Read Multiple. */ -typedef struct { - uint16_t handle_count; /**< Handle count of the multiple attributes to be read. */ - read_multiple_t *p_read_multiple; /**< Pointer to the multiple attributes to be read. */ -} gattc_read_multiple_t; +/**@brief GATTC Read Multiple. */ +typedef struct +{ + uint16_t handle_count; /**< Handle count of the multiple attributes to be read. */ + ble_gattc_multiple_att_t *p_read_multiple; /**< Pointer to the multiple attributes to be read. */ + } ble_gattc_read_multiple_t; +/**@brief GATTC Browse information about Characteristic. */ +typedef struct +{ + ble_gattc_attr_type_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_ATTR_CHAR for Characteristic Declaration. */ + uint8_t prop; /**< Value property. */ + uint16_t handle; /**< Value handle. */ + uint8_t uuid_len; /**< Characteristic UUID length. */ + uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Characteristic UUID. */ +} ble_gattc_browse_attr_char_t; -/** @brief GATTC Browse information about Characteristic. */ -typedef struct { - uint8_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_ATTR_CHAR for Characteristic Declaration. */ - uint8_t prop; /**< Value property. */ - uint16_t handle; /**< Value handle. */ - uint8_t uuid_len; /**< Characteristic UUID length. */ - uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Characteristic UUID. */ -} gattc_browse_attr_char_t; +/**@brief GATTC Browse information about Included Service. */ +typedef struct +{ + ble_gattc_attr_type_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_INC_SRVC for Included Service Information. */ + uint8_t uuid_len; /**< Included Service UUID length. */ + uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Included Service UUID. */ + uint16_t start_hdl; /**< Included Service start handle. */ + uint16_t end_hdl; /**< Included Service end handle. */ +} ble_gattc_browse_inc_srvc_t; -/** @brief GATTC Browse information about Included Service. */ -typedef struct { - uint8_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_INC_SRVC for Included Service Information. */ - uint8_t uuid_len; /**< Included Service UUID length. */ - uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Included Service UUID. */ - uint16_t start_hdl; /**< Included Service start handle. */ - uint16_t end_hdl; /**< Included Service end handle. */ -} gattc_browse_inc_srvc_t; +/**@brief GATTC Browse information about Attribute. */ +typedef struct +{ + ble_gattc_attr_type_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_ATTR_VAL for Attribute Value. See @ref BLE_GATTC_BROWSE_ATTR_DESC for Attribute Descriptor. */ + uint8_t uuid_len; /**< Attribute UUID length. */ + uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Characteristic UUID or Characteristic Descriptor UUID. */ +} ble_gattc_browse_attr_t; -/** @brief GATTC Browse information about Attribute. */ -typedef struct { - uint8_t attr_type; /**< Attribute type. See @ref BLE_GATTC_BROWSE_ATTR_VAL for Attribute Value. - See @ref BLE_GATTC_BROWSE_ATTR_DESC for Attribute Descriptor. */ - uint8_t uuid_len; /**< Attribute UUID length. */ - uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Characteristic UUID or Characteristic Descriptor UUID. */ -} gattc_browse_attr_t; - -/** @brief GATTC Browse attribute information. */ -union gattc_browse_attr_info { - uint8_t attr_type; /**< Attribute type. See @ref gatt_attr_t. */ - gattc_browse_attr_char_t attr_char; /**< Information about Characteristic. - When union attr_type is @ref BLE_GATTC_BROWSE_ATTR_CHAR */ - gattc_browse_inc_srvc_t inc_srvc; /**< Information about Included Service. - When union attr_type is @ref BLE_GATTC_BROWSE_INC_SRVC */ - gattc_browse_attr_t attr; /**< Information about Attribute. When union attr_type is - @ref BLE_GATTC_BROWSE_ATTR_VAL or @ref BLE_GATTC_BROWSE_ATTR_DESC. */ +/**@brief GATTC Browse attribute information. */ +union ble_gattc_browse_attr_info +{ + ble_gattc_attr_type_t attr_type; /**< Attribute type. See @ref ble_gattc_attr_type_t. */ + ble_gattc_browse_attr_char_t attr_char; /**< Information about Characteristic. When union attr_type is @ref BLE_GATTC_BROWSE_ATTR_CHAR */ + ble_gattc_browse_inc_srvc_t inc_srvc; /**< Information about Included Service. When union attr_type is @ref BLE_GATTC_BROWSE_INC_SRVC */ + ble_gattc_browse_attr_t attr; /**< Information about Attribute. When union attr_type is @ref BLE_GATTC_BROWSE_ATTR_VAL or @ref BLE_GATTC_BROWSE_ATTR_DESC. */ }; -/** @brief GATTC Browse service(s) indication. */ -typedef struct { - uint8_t uuid_len; /**< Service UUID length. */ - uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Service UUID. */ - uint16_t start_hdl; /**< Service start handle. */ - uint16_t end_hdl; /**< Service end handle. */ - union gattc_browse_attr_info info[ARRAY_EMPTY]; /**< Attribute information presented in the service - (array length = end_hdl - start_hdl); - If attr_type is equal to BLE_GATTC_BROWSE_NONE,the last - attribute information has been found in previous one, - although not reach the service end handle. */ -} ble_gattc_browse_srvc_t; - -/** @brief GATT service. */ -typedef struct { +/**@brief GATT service. */ +typedef struct +{ uint16_t start_hdl; /**< Start handle. */ uint16_t end_hdl; /**< End handle. */ uint8_t uuid_len; /**< Service UUID length. */ uint8_t *p_uuid; /**< Service UUID. */ } ble_gattc_service_t; -/** @brief GATT include. */ -typedef struct { +/**@brief GATT include. */ +typedef struct +{ uint16_t attr_hdl; /**< Attribute handle. */ uint16_t start_hdl; /**< Start handle. */ uint16_t end_hdl; /**< End handle. */ @@ -200,96 +195,111 @@ typedef struct { uint8_t *p_uuid; /**< Service UUID. */ } ble_gattc_include_t; -/** @brief GATT characteristic. */ -typedef struct { +/**@brief GATT characteristic. */ +typedef struct +{ uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ uint16_t handle_value; /**< Handle of the Characteristic Value. */ uint8_t prop; /**< Properties. */ - uint8_t uuid_len; /**< Characteristic UUID length. */ + uint8_t uuid_len; /**< Characteristic UUID length. */ uint8_t *p_uuid; /**< Characteristic UUID. */ } ble_gattc_char_t; -/** @brief GATT descriptor. */ -typedef struct { +/**@brief GATT descriptor. */ +typedef struct +{ uint16_t attr_hdl; /**< Attribute handle. */ uint8_t uuid_len; /**< Descriptor UUID length. */ uint8_t *p_uuid; /**< Descriptor UUID. */ } ble_gattc_desc_t; -/** @brief GATT service discovery. */ -typedef struct { - uint16_t count; /**< Service count. */ - ble_gattc_service_t services[ARRAY_EMPTY]; /**< Service data. */ -} ble_gattc_srvc_disc_t; - -/** @brief GATT include discovery. */ -typedef struct { - uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[ARRAY_EMPTY]; /**< Include data. */ -} ble_gattc_incl_disc_t; - -/** @brief GATT characteristic discovery. */ -typedef struct { - uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[ARRAY_EMPTY]; /**< Characteristic data. */ -} ble_gattc_char_disc_t; - -/** @brief GATT characteristic descriptor discovery. */ -typedef struct { - uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t char_descs[ARRAY_EMPTY]; /**< Descriptor data. */ -} ble_gattc_char_desc_disc_t; - -/** @brief GATT Client Read value. */ -typedef struct { +/**@brief GATT Client Read value. */ +typedef struct +{ uint16_t handle; /**< Attribute handle. */ uint16_t offset; /**< Offset of the attribute value. */ uint16_t length; /**< Attribute value length. */ uint8_t *p_value; /**< Pointer to the attribute value data. */ } ble_gattc_read_value_t; -/** @brief GATT value Read response. */ -typedef struct { - uint16_t count; /**< Value Count. */ - ble_gattc_read_value_t vals[ARRAY_EMPTY]; /**< Value(s) list. */ -} ble_gattc_read_rsp_t; +/**@brief GATTC Browse service(s) event for @ref BLE_GATTC_EVT_SRVC_BROWSE. */ +typedef struct +{ + uint8_t uuid_len; /**< Service UUID length. */ + uint8_t uuid[BLE_ATT_UUID_128_LEN]; /**< Service UUID. */ + uint16_t start_hdl; /**< Service start handle. */ + uint16_t end_hdl; /**< Service end handle. */ + union ble_gattc_browse_attr_info *info; /**< Attribute information presented in the service(array length = end_hdl - start_hdl);If attr_type is equal to BLE_GATTC_BROWSE_NONE, the last attribute information has been found in previous one, although not reach the service end handle. */ +} ble_gattc_evt_browse_srvc_t; + +/**@brief GATT service discovery event for @ref BLE_GATTC_EVT_PRIMARY_SRVC_DISC. */ +typedef struct +{ + uint16_t count; /**< Service count. */ + ble_gattc_service_t *services; /**< Service data. */ +}ble_gattc_evt_srvc_disc_t; + +/**@brief GATT include discovery event for @ref BLE_GATTC_EVT_INCLUDE_SRVC_DISC. */ +typedef struct +{ + uint16_t count; /**< Include count. */ + ble_gattc_include_t *includes; /**< Include data. */ +}ble_gattc_evt_incl_disc_t; + +/**@brief GATT characteristic discovery event for @ref BLE_GATTC_EVT_CHAR_DISC. */ +typedef struct +{ + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t *chars; /**< Characteristic data. */ +}ble_gattc_evt_char_disc_t; + +/**@brief GATT characteristic descriptor discovery event for @ref BLE_GATTC_EVT_CHAR_DESC_DISC. */ +typedef struct +{ + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t *char_descs; /**< Descriptor data. */ +}ble_gattc_evt_char_desc_disc_t; + +/**@brief GATT Client Read response event for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct +{ + uint16_t count; /**< Value Count. */ + ble_gattc_read_value_t *value; /**< Value(s) list. */ +}ble_gattc_evt_read_t; -/** @brief GATT Client Write. */ -typedef struct { +/**@brief GATT Client Write Response event for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct +{ uint16_t handle; /**< Attribute handle. */ -} ble_gattc_write_t; +} ble_gattc_evt_write_t; -/** @brief GATTC Notification and Indication value indication. */ -typedef struct { - gatt_evt_type_t type; /**< Event type. */ - uint16_t length; /**< Attribute value length. */ - uint16_t handle; /**< Attribute handle. */ - uint8_t *p_value; /**< Pointer to the attribute value data. */ -} ble_gattc_ntf_ind_t; +/**@brief GATTC Notification and Indication event for @ref BLE_GATTC_EVT_NTF_IND. */ +typedef struct +{ + ble_gatt_evt_type_t type; /**< Event type. */ + uint16_t length; /**< Attribute value length. */ + uint16_t handle; /**< Attribute handle. */ + uint8_t *p_value; /**< Pointer to the attribute value data. */ +} ble_gattc_evt_ntf_ind_t; -/** @brief GATTC Event callback Structures. */ -typedef struct { - /**< Primary Service Discovery Response callback. */ - void (*app_gattc_srvc_disc_cb)(uint8_t conn_idx, uint8_t status, const ble_gattc_srvc_disc_t *p_prim_srvc_disc); - /**< Relationship Discovery Response callback. */ - void (*app_gattc_inc_srvc_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_incl_disc_t *p_inc_srvc_disc); - /**< Characteristic Discovery Response callback. */ - void (*app_gattc_char_disc_cb)(uint8_t conn_idx, uint8_t status, const ble_gattc_char_disc_t *p_char_disc); - /**< Descriptor Discovery Response callback. */ - void (*app_gattc_char_desc_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_char_desc_disc_t *p_char_desc_disc); - /**< Read Response callback. */ - void (*app_gattc_read_cb)(uint8_t conn_idx, uint8_t status, const ble_gattc_read_rsp_t *p_read_rsp); - /**< Write complete callback. */ - void (*app_gattc_write_cb)(uint8_t conn_idx, uint8_t status, uint16_t handle); - /**< Handle Value Notification/Indication Event callback. */ - void (*app_gattc_ntf_ind_cb)(uint8_t conn_idx, const ble_gattc_ntf_ind_t *p_ntf_ind); - /**< Service found callback during browsing procedure. */ - void (*app_gattc_srvc_browse_cb)(uint8_t conn_idx, uint8_t status, const ble_gattc_browse_srvc_t *p_browse_srvc); -} gattc_cb_fun_t; +/**@brief BLE GATTC event structure. */ +typedef struct +{ + uint8_t index; /**< Index of connection. */ + union + { + ble_gattc_evt_browse_srvc_t srvc_browse; /**< Browce service discovery response event. */ + ble_gattc_evt_srvc_disc_t prim_srvc_disc; /**< Primary service discovery response event. */ + ble_gattc_evt_incl_disc_t inc_srvc_disc; /**< Include service discovery response event. */ + ble_gattc_evt_char_disc_t char_disc; /**< Characteristic discovery response event. */ + ble_gattc_evt_char_desc_disc_t char_desc_disc; /**< Characteristic descriptor discovery response event. */ + ble_gattc_evt_read_t read_rsp; /**< Read response event. */ + ble_gattc_evt_write_t write_rsp; /**< Write response event. */ + ble_gattc_evt_ntf_ind_t ntf_ind; /**< Handle value Notification/Indication response. */ + } params; /**< Event Parameters. */ +} ble_gattc_evt_t; /** @} */ /** @addtogroup BLE_GATTC_FUNCTIONS Functions @@ -299,9 +309,6 @@ typedef struct { **************************************************************************************** * @brief Perform MTU Exchange. * - * @note MTU Exchange Callback @ref gatt_common_cb_fun_t::app_gatt_mtu_exchange_cb will be called to - * indicate to APP once receiving the peer response. - * * @param[in] conn_idx: Current connection index. * * @retval ::SDK_SUCCESS: Successfully send an MTU Exchange request. @@ -315,15 +322,11 @@ uint16_t ble_gattc_mtu_exchange(uint8_t conn_idx); **************************************************************************************** * @brief Browse all Primary Services or specific Primary Service information on remote GATT server. * - * @note This discovery automatically searches for Primary Services, Included Services, - * Characteristics and Descriptors of each service. + * @note This discovery automatically searches for Primary Services, Included Services, Characteristics and Descriptors of each service. * To discover one or more services only, use ble_gattc_primary_services_discover() instead. * This discovery is able to search all Primary Services or a specific one. * If srvc_uuid is NULL, all services are returned. * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_srvc_browse_cb will be called for - * all attributes of each service found. - * * @param[in] conn_idx: Current connection index. * @param[in] p_srvc_uuid: Pointer to Service UUID. If it is NULL, all services will be returned. * @@ -337,9 +340,7 @@ uint16_t ble_gattc_services_browse(uint8_t conn_idx, const ble_uuid_t *p_srvc_uu /** **************************************************************************************** * @brief Discover Primary Services on remote GATT server. - * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_srvc_disc_cb will be called for service(s) found. - * + * * @param[in] conn_idx: Current connection index. * @param[in] p_srvc_uuid: Pointer to Service UUID. If it is NULL, all Primary Services will be returned. * @@ -354,7 +355,6 @@ uint16_t ble_gattc_primary_services_discover(uint8_t conn_idx, const ble_uuid_t **************************************************************************************** * @brief Discover Included Services on remote GATT server. * - * @note Function callback @ref gattc_cb_fun_t:app_gattc_inc_srvc_disc_cb will be called for Included Service(s) found. * @param[in] conn_idx: Current connection index. * @param[in] start_hdl: Start handle. * @param[in] end_hdl: End handle. @@ -369,8 +369,7 @@ uint16_t ble_gattc_included_services_discover(uint8_t conn_idx, uint16_t start_h /** **************************************************************************************** * @brief Discover Characteristics on remote GATT server. - * @note Function callback @ref gattc_cb_fun_t::app_gattc_char_disc_cb will be called - * for Characteristic Declaration(s) found. + * * @param[in] conn_idx: Current connection index. * @param[in] start_hdl: Start handle. * @param[in] end_hdl: End handle. @@ -381,18 +380,12 @@ uint16_t ble_gattc_included_services_discover(uint8_t conn_idx, uint16_t start_h * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gattc_char_discover(uint8_t conn_idx, uint16_t start_hdl, - uint16_t end_hdl, const ble_uuid_t *p_char_uuid); +uint16_t ble_gattc_char_discover(uint8_t conn_idx, uint16_t start_hdl, uint16_t end_hdl, const ble_uuid_t *p_char_uuid); /** **************************************************************************************** * @brief Discover Characteristics Descriptors on remote GATT server. * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_char_desc_disc_cb will be called - * for Characteristic Descriptor(s) found. - * If the last Descriptor has not been reached, this function must be called again with an updated handle - * range to continue the discovery. - * * @param[in] conn_idx: Current connection index. * @param[in] start_hdl: Start handle. * @param[in] end_hdl: End handle. @@ -413,7 +406,6 @@ uint16_t ble_gattc_char_desc_discover(uint8_t conn_idx, uint16_t start_hdl, uint * attribute length is larger than the MTU, the "Read Long Characteristic Value" procedure or the * "Read Long Characteristic Descriptor" procedure will be used respectively. * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_read_cb will be called when Read is finished. * @param[in] conn_idx: Current connection index. * @param[in] handle: Attribute handle. * @param[in] offset: Value offset to start with. @@ -429,7 +421,6 @@ uint16_t ble_gattc_read(uint8_t conn_idx, uint16_t handle, uint16_t offset); **************************************************************************************** * @brief Read Attribute by UUID. * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_read_cb will be called when Read is finished. * @param[in] conn_idx: Current connection index. * @param[in] start_hdl: Start handle. * @param[in] end_hdl: End handle. @@ -442,14 +433,12 @@ uint16_t ble_gattc_read(uint8_t conn_idx, uint16_t handle, uint16_t offset); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gattc_read_by_uuid(uint8_t conn_idx, uint16_t start_hdl, - uint16_t end_hdl, const ble_uuid_t *p_char_uuid); +uint16_t ble_gattc_read_by_uuid(uint8_t conn_idx, uint16_t start_hdl, uint16_t end_hdl, const ble_uuid_t *p_char_uuid); /** **************************************************************************************** * @brief Initiate a Read Multiple Characteristic Values procedure * - * @note Function callback @ref gattc_cb_fun_t::app_gattc_read_cb will be called for each handle value which is read. * @param[in] conn_idx: Current connection index. * @param[in] p_param: Pointer to the parameters of the value. * @@ -459,7 +448,7 @@ uint16_t ble_gattc_read_by_uuid(uint8_t conn_idx, uint16_t start_hdl, * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gattc_read_multiple(uint8_t conn_idx, const gattc_read_multiple_t *p_param); +uint16_t ble_gattc_read_multiple(uint8_t conn_idx, const ble_gattc_read_multiple_t *p_param); /** **************************************************************************************** @@ -470,8 +459,6 @@ uint16_t ble_gattc_read_multiple(uint8_t conn_idx, const gattc_read_multiple_t * * or the attribute length is larger than the MTU, the "Write Long Characteristic Value" procedure * or the "Write Long Characteristic Descriptor" procedure will be used respectively. * - * @note Once completed @ref gattc_cb_fun_t::app_gattc_write_cb will be called. - * * @param[in] conn_idx: Current connection index. * @param[in] handle: The handle of the attribute to be written. * @param[in] offset: Offset into the attribute value to be written. @@ -490,8 +477,6 @@ uint16_t ble_gattc_write(uint8_t conn_idx, uint16_t handle, uint16_t offset, uin **************************************************************************************** * @brief Prepare Long/Reliable Write to remote GATT server. * - * @note When this function completes, @ref gattc_cb_fun_t::app_gattc_write_cb will be called. - * * @param[in] conn_idx: Current connection index. * @param[in] handle: Attribute handle. * @param[in] offset: Value offset to start with. @@ -504,15 +489,12 @@ uint16_t ble_gattc_write(uint8_t conn_idx, uint16_t handle, uint16_t offset, uin * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gattc_write_prepare(uint8_t conn_idx, uint16_t handle, uint16_t offset, uint16_t length, - const uint8_t *p_value); +uint16_t ble_gattc_write_prepare(uint8_t conn_idx, uint16_t handle, uint16_t offset, uint16_t length, const uint8_t *p_value); /** **************************************************************************************** * @brief Execute Reliable/Long Write to remote GATT server. * - * @note When this function completes, @ref gattc_cb_fun_t::app_gattc_write_cb will be called. - * * @param[in] conn_idx: Current connection index. * @param[in] execute: True if data shall be written; false if cancel all prepared writes. * @@ -529,9 +511,8 @@ uint16_t ble_gattc_write_execute(uint8_t conn_idx, bool execute); * * @note If signed_write is set to false, the "Write Without Response" procedure will be used. * If signed_write is set to true, the "Signed Write Without Response" procedure will be used on - * a link which is not encrypted. If a link is already encrypted, - * "Write Without Response" procedure shall be used instead of "Signed Write Without Response". - * @note Once completed @ref gattc_cb_fun_t::app_gattc_write_cb will be called. + * a link which is not encrypted. + * If a link is already encrypted, "Write Without Response" procedure shall be used instead of "Signed Write Without Response". * * @param[in] conn_idx: Current connection index. * @param[in] handle: Attribute handle. @@ -545,8 +526,7 @@ uint16_t ble_gattc_write_execute(uint8_t conn_idx, bool execute); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gattc_write_no_resp(uint8_t conn_idx, bool signed_write, uint16_t handle, uint16_t length, - const uint8_t *p_value); +uint16_t ble_gattc_write_no_resp(uint8_t conn_idx, bool signed_write, uint16_t handle, uint16_t length, const uint8_t *p_value); /** **************************************************************************************** diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatts.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatts.h old mode 100755 new mode 100644 index 0089d70..f544fac --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatts.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_gatts.h @@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************************** */ - + /** * @addtogroup BLE * @{ @@ -52,90 +52,68 @@ @brief Definitions and prototypes for the GATT server interface. */ - + #ifndef __BLE_GATTS_H__ #define __BLE_GATTS_H__ -#include +#include "ble_error.h" +#include "ble_att.h" #include "ble_gatt.h" +#include "ble_gapc.h" + +#include /** @addtogroup BLE_GATTS_DEFINES Defines * @{ */ /** @defgroup BLE_GATTS_MAX_INC_SRVC_NUM Max Number of Included Services * @{ */ -#define MAX_INC_SRVC_NUM (5) /**< The max number of Included Services a Primary/Secondary service - can have. Used by @ref gatts_create_db_t. */ +#define BLE_GATTS_MAX_INC_SRVC_NUM (5) /**< The max number of Included Services a Primary/Secondary service can have. Used by @ref ble_gatts_create_db_t. */ /** @} */ - + /** @defgroup BLE_GATTS_ATTR_PERM_BIT Attribute Permission Bit * @{ */ -#define BROADCAST (0x01) /**< In one byte, bit0 means: Broadcast bit. - Used by @ref BROADCAST_ENABLE. */ -#define READ (0x02) /**< In one byte, bit1 means: Read bit. - Used by @ref READ_PERM_UNSEC, @ref READ_PERM */ -#define WRITE_CMD (0x04) /**< In one byte, bit2 means: Write_cmd bit. - Used by @ref WRITE_CMD_PERM_UNSEC, @ref WRITE_CMD_PERM. */ -#define WRITE_REQ (0x08) /**< In one byte, bit3 means: Write_req bit. - Used by @ref WRITE_REQ_PERM_UNSEC, @ref WRITE_REQ_PERM. */ -#define NOTIFY (0x10) /**< In one byte, bit4 means: Notify bit. - Used by @ref NOTIFY_PERM_UNSEC, @ref NOTIFY_PERM. */ -#define INDICATE (0x20) /**< In one byte, bit5 means: Indicate bit. - Used by @ref INDICATE_PERM_UNSEC, @ref INDICATE_PERM */ -#define WRITE_SIGNED (0x40) /**< In one byte, bit6 means: Write_signed bit. - Used by @ref WRITE_SIGNED_PERM_UNSEC, @ref WRITE_SIGNED_PERM. */ -#define EXT_PROP (0x80) /**< In one byte, bit7 means: Ext_property bit. - Used by @ref EXT_PROP_ENABLE. */ +#define BLE_GATTS_BROADCAST (0x01) /**< In one byte, bit0 means: Broadcast bit. Used by @ref BLE_GATTS_BROADCAST_ENABLE. */ +#define BLE_GATTS_READ (0x02) /**< In one byte, bit1 means: Read bit. Used by @ref BLE_GATTS_READ_PERM_UNSEC, @ref BLE_GATTS_READ_PERM */ +#define BLE_GATTS_WRITE_CMD (0x04) /**< In one byte, bit2 means: Write_cmd bit. Used by @ref BLE_GATTS_WRITE_CMD_PERM_UNSEC, @ref BLE_GATTS_WRITE_CMD_PERM. */ +#define BLE_GATTS_WRITE_REQ (0x08) /**< In one byte, bit3 means: Write_req bit. Used by @ref BLE_GATTS_WRITE_REQ_PERM_UNSEC, @ref BLE_GATTS_WRITE_REQ_PERM. */ +#define BLE_GATTS_NOTIFY (0x10) /**< In one byte, bit4 means: Notify bit. Used by @ref BLE_GATTS_NOTIFY_PERM_UNSEC, @ref BLE_GATTS_NOTIFY_PERM. */ +#define BLE_GATTS_INDICATE (0x20) /**< In one byte, bit5 means: Indicate bit. Used by @ref BLE_GATTS_INDICATE_PERM_UNSEC, @ref BLE_GATTS_INDICATE_PERM */ +#define BLE_GATTS_WRITE_SIGNED (0x40) /**< In one byte, bit6 means: Write_signed bit. Used by @ref BLE_GATTS_WRITE_SIGNED_PERM_UNSEC, @ref BLE_GATTS_WRITE_SIGNED_PERM. */ +#define BLE_GATTS_EXT_PROP (0x80) /**< In one byte, bit7 means: Ext_property bit. Used by @ref BLE_GATTS_EXT_PROP_ENABLE. */ /** @} */ /** @defgroup BLE_GATTS_ATTR_PERM_POS Attribute Permission Value Position * @{ */ -#define READ_POS (0x00) /**< Bit position of read permission. Used by @ref READ_PERM. */ -#define WRITE_POS (0x02) /**< Bit position of write permission. Used by @ref WRITE_CMD_PERM, - @ref WRITE_REQ_PERM, @ref WRITE_SIGNED_PERM. */ -#define INDICATE_POS (0x04) /**< Bit position of indicate bit. Used by @ref INDICATE_PERM. */ -#define NOTIFY_POS (0x06) /**< Bit position of notify bit. Used by @ref NOTIFY_PERM. */ +#define BLE_GATTS_READ_POS (0x00) /**< Bit position of read permission. Used by @ref BLE_GATTS_READ_PERM. */ +#define BLE_GATTS_WRITE_POS (0x02) /**< Bit position of write permission. Used by @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM. */ +#define BLE_GATTS_INDICATE_POS (0x04) /**< Bit position of indicate bit. Used by @ref BLE_GATTS_INDICATE_PERM. */ +#define BLE_GATTS_NOTIFY_POS (0x06) /**< Bit position of notify bit. Used by @ref BLE_GATTS_NOTIFY_PERM. */ /** @} */ /** @defgroup BLE_GATTS_SEC_LEVEL Attribute and Service Access Rights * @{ */ - -#define NOAUTH (0x00) /**< LE security mode 1, level 1. - Link does not need to be encrypted or authenticated. - Parameter of @ref SRVC_PERM, @ref READ_PERM, - @ref WRITE_REQ_PERM, @ref WRITE_CMD_PERM, - @ref WRITE_SIGNED_PERM, @ref INDICATE_PERM, @ref NOTIFY_PERM. */ -#define UNAUTH (0x01) /**< LE security mode 1, level 2. - Link needs to be encrypted, but not to be authenticated. - Parameter of @ref SRVC_PERM, @ref READ_PERM, @ref WRITE_REQ_PERM, - @ref WRITE_CMD_PERM, @ref WRITE_SIGNED_PERM, @ref INDICATE_PERM, - @ref NOTIFY_PERM. */ -#define AUTH (0x02) /**< LE security mode 1, level 3. - Link needs to be encrypted and authenticated (MITM). - Parameter of @ref SRVC_PERM, @ref READ_PERM, @ref WRITE_REQ_PERM, - @ref WRITE_CMD_PERM, @ref WRITE_SIGNED_PERM, @ref INDICATE_PERM, - @ref NOTIFY_PERM. */ -#define SEC_CON (0x03) /**< LE security mode 1, level 4. - Link needs to be encrypted and authenticated (secure connections). - Parameter of @ref SRVC_PERM, @ref READ_PERM, @ref WRITE_REQ_PERM, - @ref WRITE_CMD_PERM, @ref WRITE_SIGNED_PERM, @ref INDICATE_PERM, - @ref NOTIFY_PERM. */ + +#define BLE_GATTS_NOAUTH (0x00) /**< LE security mode 1, level 1. Link does not need to be encrypted or authenticated. + Parameter of @ref BLE_GATTS_SRVC_PERM, @ref BLE_GATTS_READ_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM, @ref BLE_GATTS_INDICATE_PERM, @ref BLE_GATTS_NOTIFY_PERM. */ +#define BLE_GATTS_UNAUTH (0x01) /**< LE security mode 1, level 2. Link needs to be encrypted, but not to be authenticated. + Parameter of @ref BLE_GATTS_SRVC_PERM, @ref BLE_GATTS_READ_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM, @ref BLE_GATTS_INDICATE_PERM, @ref BLE_GATTS_NOTIFY_PERM. */ +#define BLE_GATTS_AUTH (0x02) /**< LE security mode 1, level 3. Link needs to be encrypted and authenticated (MITM). + Parameter of @ref BLE_GATTS_SRVC_PERM, @ref BLE_GATTS_READ_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM, @ref BLE_GATTS_INDICATE_PERM, @ref BLE_GATTS_NOTIFY_PERM. */ +#define BLE_GATTS_SEC_CON (0x03) /**< LE security mode 1, level 4. Link needs to be encrypted and authenticateBLE_GATTS_d (secure connections). + Parameter of @ref BLE_GATTS_SRVC_PERM, @ref BLE_GATTS_READ_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM, @ref BLE_GATTS_INDICATE_PERM, @ref BLE_GATTS_NOTIFY_PERM. */ /** @} */ /** @defgroup BLE_GATTS_SEC_LEVEL_MASK Attribute and Service Security Level Mask * @{ */ -#define SEC_LEVEL_MASK (0x03) /**< Security level mask. - Used by @ref SRVC_PERM, @ref READ_PERM, @ref WRITE_REQ_PERM, - @ref WRITE_CMD_PERM, @ref WRITE_SIGNED_PERM, @ref INDICATE_PERM, - @ref NOTIFY_PERM. */ +#define BLE_GATTS_SEC_LEVEL_MASK (0x03) /**< Security level mask. + Used by @ref BLE_GATTS_SRVC_PERM, @ref BLE_GATTS_READ_PERM, @ref BLE_GATTS_WRITE_REQ_PERM, @ref BLE_GATTS_WRITE_CMD_PERM, @ref BLE_GATTS_WRITE_SIGNED_PERM, @ref BLE_GATTS_INDICATE_PERM, @ref BLE_GATTS_NOTIFY_PERM. */ /** @} */ /** @defgroup BLE_GATTS_UUID_TYPE Attribute and Service UUID Type * @{ */ -#define UUID_TYPE_16 (0x00) /**< 16-bit UUID length. - Parameter of @ref SRVC_UUID_TYPE_SET, @ref ATT_UUID_TYPE_SET. */ -#define UUID_TYPE_128 (0x02) /**< 128-bit UUID length. - Parameter of @ref SRVC_UUID_TYPE_SET, @ref ATT_UUID_TYPE_SET. */ +#define BLE_GATTS_UUID_TYPE_16 (0x00) /**< 16-bit UUID length. */ +#define BLE_GATTS_UUID_TYPE_128 (0x02) /**< 128-bit UUID length. */ /** @} */ /** @@ -155,16 +133,12 @@ /** @defgroup BLE_GATTS_SRVC_PERM Service Permission * @{ */ -#define SRVC_SECONDARY_SET (0x80) /**< Secondary service set. */ -#define SRVC_DISABLE (0x10) /**< Service disable. */ -#define SRVC_ENCRP_KEY_SIZE_16 (0x02) /**< 16 bytes service encryption key size . */ -#define SRVC_MULTI_ENABLE (0x01) /**< Service is multi-instantiated. */ - -/**< Service UUID length set. See @ref BLE_GATTS_UUID_TYPE. */ -#define SRVC_UUID_TYPE_SET(uuid_len) ((uuid_len) << 5) - -/**< Service permission authentication. See @ref BLE_GATTS_SEC_LEVEL. */ -#define SRVC_PERM(sec_level) (((sec_level) & SEC_LEVEL_MASK) << 2) +#define BLE_GATTS_SRVC_SECONDARY_SET (0x80) /**< Secondary service set. */ +#define BLE_GATTS_SRVC_UUID_TYPE_SET(uuid_len) ((uuid_len) << 5) /**< Service UUID length set. See @ref BLE_GATTS_UUID_TYPE. */ +#define BLE_GATTS_SRVC_DISABLE (0x10) /**< Service disable. */ +#define BLE_GATTS_SRVC_PERM(sec_level) (((sec_level) & SEC_LEVEL_MASK) << 2) /**< Service permission authentication. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_SRVC_ENCRP_KEY_SIZE_16 (0x02) /**< 16 bytes service encryption key size . */ +#define BLE_GATTS_SRVC_MULTI_ENABLE (0x01) /**< Service is multi-instantiated. */ /** @} */ /** @@ -191,34 +165,20 @@ /** @defgroup BLE_GATTS_ATTR_PERM Attribute Permission * @{ */ -/**< Default Read permission. */ -#define READ_PERM_UNSEC (READ << 8) -/**< Read permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define READ_PERM(sec_level) (READ << 8 | (((sec_level) & SEC_LEVEL_MASK) << READ_POS)) -/**< Default Write Permission. */ -#define WRITE_REQ_PERM_UNSEC (WRITE_REQ << 8) -/**< Write permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define WRITE_REQ_PERM(sec_level) (WRITE_REQ << 8 | (((sec_level) & SEC_LEVEL_MASK) << WRITE_POS)) -/**< Default Write without Response Permission. */ -#define WRITE_CMD_PERM_UNSEC (WRITE_CMD << 8) -/**< Write without Response permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define WRITE_CMD_PERM(sec_level) (WRITE_CMD << 8 | (((sec_level) & SEC_LEVEL_MASK) << WRITE_POS)) -/**< Default Authenticated Signed Write Permission. */ -#define WRITE_SIGNED_PERM_UNSEC (WRITE_SIGNED << 8) -/**< Authenticated Signed Write permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define WRITE_SIGNED_PERM(sec_level) (WRITE_SIGNED << 8 | (((sec_level) & SEC_LEVEL_MASK) << WRITE_POS)) -/**< Default Indicate Permission. */ -#define INDICATE_PERM_UNSEC (INDICATE << 8) -/**< Indicate permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define INDICATE_PERM(sec_level) (INDICATE << 8 | (((sec_level) & SEC_LEVEL_MASK) << INDICATE_POS)) -/**< Default Notify Permission. */ -#define NOTIFY_PERM_UNSEC (NOTIFY << 8) -/**< Notify permission set. See @ref BLE_GATTS_SEC_LEVEL. */ -#define NOTIFY_PERM(sec_level) (NOTIFY << 8 | (((sec_level) & SEC_LEVEL_MASK) << NOTIFY_POS)) -/**< Broadcast enable. */ -#define BROADCAST_ENABLE (BROADCAST << 8) -/**< Extended Properties enable. */ -#define EXT_PROP_ENABLE (EXT_PROP << 8) +#define BLE_GATTS_READ_PERM_UNSEC (BLE_GATTS_READ << 8) /**< Default Read permission. */ +#define BLE_GATTS_READ_PERM(sec_level) (BLE_GATTS_READ << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_READ_POS)) /**< Read permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_WRITE_REQ_PERM_UNSEC (BLE_GATTS_WRITE_REQ << 8) /**< Default Write Permission. */ +#define BLE_GATTS_WRITE_REQ_PERM(sec_level) (BLE_GATTS_WRITE_REQ << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_WRITE_POS)) /**< Write permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_WRITE_CMD_PERM_UNSEC (BLE_GATTS_WRITE_CMD << 8) /**< Default Write without Response Permission. */ +#define BLE_GATTS_WRITE_CMD_PERM(sec_level) (BLE_GATTS_WRITE_CMD << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_WRITE_POS)) /**< Write without Response permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_WRITE_SIGNED_PERM_UNSEC (BLE_GATTS_WRITE_SIGNED << 8) /**< Default Authenticated Signed Write Permission. */ +#define BLE_GATTS_WRITE_SIGNED_PERM(sec_level) (BLE_GATTS_WRITE_SIGNED << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_WRITE_POS)) /**< Authenticated Signed Write permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_INDICATE_PERM_UNSEC (BLE_GATTS_INDICATE << 8) /**< Default Indicate Permission. */ +#define BLE_GATTS_INDICATE_PERM(sec_level) (BLE_GATTS_INDICATE << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_INDICATE_POS)) /**< Indicate permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_NOTIFY_PERM_UNSEC (BLE_GATTS_NOTIFY << 8) /**< Default Notify Permission. */ +#define BLE_GATTS_NOTIFY_PERM(sec_level) (BLE_GATTS_NOTIFY << 8 | (((sec_level) & BLE_GATTS_SEC_LEVEL_MASK) << BLE_GATTS_NOTIFY_POS)) /**< Notify permission set. See @ref BLE_GATTS_SEC_LEVEL. */ +#define BLE_GATTS_BROADCAST_ENABLE (BLE_GATTS_BROADCAST << 8) /**< Broadcast enable. */ +#define BLE_GATTS_EXT_PROP_ENABLE (BLE_GATTS_EXT_PROP << 8) /**< Extended Properties enable. */ /** @} */ /** @@ -236,15 +196,13 @@ /** @defgroup BLE_GATTS_ATTR_EXT_PERM Attribute Extend Permission * @{ */ -#define ATT_VAL_LOC_USER (1 << 15) /**< Value location which means value saved in user space, - the profile's read/write callback will be called. */ -#define ATT_VAL_LOC_STACK (0 << 15) /**< Value location which means value saved in BLE Stack. */ -#define ATT_ENC_KEY_SIZE_16 (0x1000) /**< 16 bytes attribute encryption key size . */ - -/**< Attribute UUID length set. See @ref BLE_GATTS_UUID_TYPE */ -#define ATT_UUID_TYPE_SET(uuid_len) ((uuid_len) << 13) +#define BLE_GATTS_ATT_VAL_LOC_USER (1 << 15) /**< Value location which means value saved in user space, the profile's read/write callback will be called. */ +#define BLE_GATTS_ATT_VAL_LOC_STACK (0 << 15) /**< Value location which means value saved in BLE Stack. */ +#define BLE_GATTS_ATT_UUID_TYPE_SET(uuid_len) ((uuid_len) << 13) /**< Attribute UUID length set. See @ref BLE_GATTS_UUID_TYPE */ +#define BLE_GATTS_ATT_ENC_KEY_SIZE_16 (0x1000) /**< 16 bytes attribute encryption key size . */ /** @} */ + /** @} */ /** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations @@ -253,137 +211,193 @@ /** * @brief Service table type. */ -typedef enum { - SERVICE_TABLE_TYPE_16 = 0x00, /**< 16-bit service table type. */ - SERVICE_TABLE_TYPE_128, /**< 128-bit service table type. */ -} gatts_service_type_t; +typedef enum +{ + BLE_GATTS_SERVICE_TABLE_TYPE_16 = 0x00, /**< 16-bit service table type. */ + BLE_GATTS_SERVICE_TABLE_TYPE_128, /**< 128-bit service table type. */ +} ble_gatts_service_type_t; + /** @} */ + /** @addtogroup BLE_GATTS_STRUCTURES Structures * @{ */ /** * @brief Service(16-bit UUID) description. */ -typedef struct { - uint16_t uuid; /**< 16-bit LSB-first UUID */ - uint16_t perm; /**< Attribute permissions, see @ref BLE_GATTS_ATTR_PERM. \n - - For Primary/Secondary/Included Services, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Declaration, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Extended Properties, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Presentation Format, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Aggregate Format, must be @ref READ_PERM_UNSEC. */ - - uint16_t ext_perm; /**< Attribute extended permissions, see @ref BLE_GATTS_ATTR_EXT_PERM. \n - - For Primary/Secondary/Included Services, this field is not used and should be set to 0.\n - - For Characteristic Declaration, this field is not used and should be set to 0. \n - - For Characteristic Extended Properties, this field is not used and should be set to 0. \n - - For Client Characteristic Configuration and Server Characteristic Configuration, - value must be saved in user space, user needn't to set this value location bit. - The UUID length type must be set to 0. */ - - uint16_t max_size; /**< Attribute max size. \n - - For Primary/Secondary/Included Services, this field is not used, set to 0. \n - - For Characteristic Declaration, this field is not used, set to 0. \n - - For Characteristic Extended Properties, this field contains 2-byte value. \n - - For Client Characteristic Configuration and Server Characteristic Configuration, - this field is not used, set to 0. \n - - For others, this field is attribute max size. */ -} attm_desc_t; - -/** - * @brief Service(128 bits UUID) description. - */ -typedef struct { - uint8_t uuid[16]; /**< 128 bits UUID LSB First. */ +typedef struct +{ + uint16_t uuid; /**< 16-bit LSB-first UUID */ uint16_t perm; /**< Attribute permissions, see @ref BLE_GATTS_ATTR_PERM. \n - - For Primary/Secondary/Included Services, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Declaration, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Extended Properties, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Presentation Format, must be @ref READ_PERM_UNSEC. \n - - For Characteristic Aggregate Format, must be @ref READ_PERM_UNSEC. */ - + - For Primary/Secondary/Included Services, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Declaration, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Extended Properties, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Presentation Format, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Aggregate Format, must be @ref BLE_GATTS_READ_PERM_UNSEC. */ + uint16_t ext_perm; /**< Attribute extended permissions, see @ref BLE_GATTS_ATTR_EXT_PERM. \n - - For Primary/Secondary/Included Services, this field is not used, set to 0. \n - - For Characteristic Declaration, this field is not used, set to 0. \n - - For Characteristic Extended Properties, this field is not used, set to 0. \n - - For Client Characteristic Configuration and Server Characteristic Configuration, - value must be saved in user space, user needn't to set this value location bit. - The UUID length type must be set to 0. */ - + - For Primary/Secondary/Included Services, this field is not used and should be set to 0. \n + - For Characteristic Declaration, this field is not used and should be set to 0. \n + - For Characteristic Extended Properties, this field is not used and should be set to 0. \n + - For Client Characteristic Configuration and Server Characteristic Configuration, value must be saved in user space, + user needn't to set this value location bit. The UUID length type must be set to 0.*/ + uint16_t max_size; /**< Attribute max size. \n - For Primary/Secondary/Included Services, this field is not used, set to 0. \n - For Characteristic Declaration, this field is not used, set to 0. \n - For Characteristic Extended Properties, this field contains 2-byte value. \n - - For Client Characteristic Configuration and Server Characteristic Configuration, - this field is not used, set to 0. \n + - For Client Characteristic Configuration and Server Characteristic Configuration, this field is not used, set to 0. \n - For others, this field is attribute max size. */ -} attm_desc_128_t; +} ble_gatts_attm_desc_t; + +/** + * @brief Service(128 bits UUID) description. + */ +typedef struct +{ + uint8_t uuid[16]; /**< 128 bits UUID LSB First. */ + uint16_t perm; /**< Attribute permissions, see @ref BLE_GATTS_ATTR_PERM. \n + - For Primary/Secondary/Included Services, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Declaration, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Extended Properties, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Presentation Format, must be @ref BLE_GATTS_READ_PERM_UNSEC. \n + - For Characteristic Aggregate Format, must be @ref BLE_GATTS_READ_PERM_UNSEC. */ + + uint16_t ext_perm; /**< Attribute extended permissions, see @ref BLE_GATTS_ATTR_EXT_PERM. \n + - For Primary/Secondary/Included Services, this field is not used, set to 0. \n + - For Characteristic Declaration, this field is not used, set to 0. \n + - For Characteristic Extended Properties, this field is not used, set to 0. \n + - For Client Characteristic Configuration and Server Characteristic Configuration, value must be saved in user space, + user needn't to set this value location bit. The UUID length type must be set to 0.*/ + + uint16_t max_size; /**< Attribute max size. \n + - For Primary/Secondary/Included Services, this field is not used, set to 0. \n + - For Characteristic Declaration, this field is not used, set to 0. \n + - For Characteristic Extended Properties, this field contains 2-byte value. \n + - For Client Characteristic Configuration and Server Characteristic Configuration, this field is not used, set to 0. \n + - For others, this field is attribute max size. */ +} ble_gatts_attm_desc_128_t; /** * @brief Parameter of Added service description. */ -typedef struct { - uint16_t *shdl; /**< Service start handle pointer. - If *shdl = 0, it returns a handle using the first available handle (*shdl is modified); - otherwise it verifies if the given start handle can be used to allocate handle range. */ - const uint8_t *uuid; /**< Service UUID pointer. The pointer points to the Service UUID LSB. */ - uint8_t *attr_tab_cfg; /**< Attribute table selector pointer. It can be set to NULL to select all items of - attribute table. Each bit matches with an attribute of attribute table. \n - EXAMPLE:if attr_tab_cfg points to array {0x3F, 0x03},it means that - the 0.1.2.3.4.5.8.9 items of attribute table will be added to database. */ +typedef struct +{ - uint8_t max_nb_attr; /**< Number of attributes in attribute table. */ - union attribute_table { /**< Attribute table. */ - const attm_desc_t *attr_tab_16; /**< 16 bits service description. The pointer point to attribute - table of 16 bits service. See @ref attm_desc_t. */ - const attm_desc_128_t *attr_tab_128; /**< 128 bits service description. The pointer point to attribute - table of 128 bits service. See @ref attm_desc_128_t. */ - } attr_tab; /**< Attribute table. */ - uint16_t *inc_srvc_handle[MAX_INC_SRVC_NUM]; /**< Pointer array of Included Service start handle's address. */ - uint16_t inc_srvc_num; /**< Included Service number for this service. */ - uint8_t srvc_perm; /**< Service permission. See @ref BLE_GATTS_SRVC_PERM. */ - gatts_service_type_t attr_tab_type; /**< Service table type. See @ref gatts_service_type_t. */ -} gatts_create_db_t; + uint16_t *shdl; /**< Service start handle pointer. If *shdl = 0, it returns a handle using the first available handle (*shdl is modified); otherwise it verifies if the given start handle can be used to allocate handle range. */ + const uint8_t *uuid; /**< Service UUID pointer. The pointer points to the Service UUID LSB. */ + uint8_t *attr_tab_cfg; /**< Attribute table selector pointer. It can be set to NULL to select all items of attribute table. Each bit matches with an attribute of attribute table. \n EXAMPLE:if attr_tab_cfg points to array {0x3F, 0x03}, it means that the 0.1.2.3.4.5.8.9 items of attribute table will be added to database. */ + uint8_t max_nb_attr; /**< Number of attributes in attribute table. */ + union attribute_table /**< Attribute table. */ + { + const ble_gatts_attm_desc_t *attr_tab_16; /**< 16 bits service description. The pointer point to attribute table of 16 bits service. See @ref ble_gatts_attm_desc_t. */ + const ble_gatts_attm_desc_128_t *attr_tab_128; /**< 128 bits service description. The pointer point to attribute table of 128 bits service. See @ref ble_gatts_attm_desc_128_t. */ + } attr_tab; /**< Attribute table. */ + uint16_t *inc_srvc_handle[BLE_GATTS_MAX_INC_SRVC_NUM]; /**< Pointer array of Included Service start handle's address. */ + uint16_t inc_srvc_num; /**< Included Service number for this service. */ + uint8_t srvc_perm; /**< Service permission. See @ref BLE_GATTS_SRVC_PERM. */ + ble_gatts_service_type_t attr_tab_type; /**< Service table type. See @ref ble_gatts_service_type_t. */ +} ble_gatts_create_db_t; /** * @brief GATT read attribute result description. */ -typedef struct { +typedef struct +{ uint16_t handle; /**< Handle of the read attribute. */ uint16_t length; /**< Length of read data. */ uint8_t status; /**< Status of read operation by upper layers. See @ref BLE_STACK_ERROR_CODES.*/ uint8_t *value; /**< Attribute value pointer. */ -} gatts_read_cfm_t; +} ble_gatts_read_cfm_t; /** * @brief GATT write attribute result description. */ -typedef struct { +typedef struct +{ uint16_t handle; /**< Handle of the attribute written. */ uint8_t status; /**< Status of write operation by upper layers. See @ref BLE_STACK_ERROR_CODES.*/ -} gatts_write_cfm_t; +} ble_gatts_write_cfm_t; /** * @brief GATT prepare write result description. */ -typedef struct { +typedef struct +{ uint16_t handle; /**< Handle of the attribute in prepare write operation. */ uint16_t length; /**< Current length of the attribute. */ uint8_t status; /**< Status of prepare write operation by upper layers. See @ref BLE_STACK_ERROR_CODES.*/ -} gatts_prep_write_cfm_t; +} ble_gatts_prep_write_cfm_t; /** * @brief GATT sending Notification or Indication event param description. */ -typedef struct { - gatt_evt_type_t type; /**< Request type (Notification/Indication). see @ref gatt_evt_type_t. */ +typedef struct +{ + ble_gatt_evt_type_t type; /**< Request type (Notification/Indication). see @ref ble_gatt_evt_type_t. */ uint16_t handle; /**< Characteristic Value handle to be notified or indicated. */ uint16_t length; /**< Length of Characteristic Value to be sent. */ uint8_t *value; /**< Characteristic Value pointer. */ -} gatts_noti_ind_t; +} ble_gatts_noti_ind_t; + +/** + * @brief GATT read request event for @ref BLE_GATTS_EVT_READ_REQUEST. + */ +typedef struct +{ + uint16_t handle; /**< Handle of the attribute to be read. */ +} ble_gatts_evt_read_t; + +/** + * @brief GATT write request event for @ref BLE_GATTS_EVT_WRITE_REQUEST. + */ +typedef struct +{ + uint16_t handle; /**< Handle of the attribute to be written. */ + uint16_t offset; /**< Offset at which the data has to be written. */ + uint16_t length; /**< Data length to be written. */ + uint8_t *value; /**< Data to be written to characteristic value. */ +} ble_gatts_evt_write_t; + +/** + * @brief GATT prepare write request event for @ref BLE_GATTS_EVT_PREP_WRITE_REQUEST. + */ +typedef struct +{ + uint16_t handle; /**< Handle of the attribute for whose value is requested. */ +} ble_gatts_evt_prep_write_t; + +/**@brief Gatt Notification or indication event for @ref BLE_GATTS_EVT_NTF_IND. */ +typedef struct +{ + ble_gatt_evt_type_t type; /**< Notification or indication event type. */ + uint16_t handle; /**< Handle of the write operation, or notification/indication operation. */ +} ble_gatts_evt_ntf_ind_t; + +/**@brief Gatt cccd recovery event for @ref BLE_GATTS_EVT_CCCD_RECOVERY. */ +typedef struct +{ + ble_gap_bdaddr_t peer_addr; /**< Pointer to peer address. */ + uint16_t handle; /**< Handle of attribute. */ + uint16_t cccd_val; /**< CCCD value. */ +} ble_gatts_evt_cccd_rec_t; + +/**@brief BLE GATTS event structure. */ +typedef struct +{ + uint8_t index; /**< Index of connection. */ + union + { + ble_gatts_evt_read_t read_req; /**< Read request event. */ + ble_gatts_evt_write_t write_req; /**< Write request event. */ + ble_gatts_evt_prep_write_t prep_wr_req; /**< Prepare write request event. */ + ble_gatts_evt_ntf_ind_t ntf_ind_sended; /**< Notification or indication sened event. */ + ble_gatts_evt_cccd_rec_t cccd_recovery; /**< Gatt cccd recovery event . */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; /** @} */ @@ -394,18 +408,17 @@ typedef struct { **************************************************************************************** * @brief Register a service's attribute list. * - * @param[in, out] p_param: Pointer to the parameter used in creating databases. see @ref gatts_create_db_t. + * @param[in] p_param: Pointer to the parameter used in creating databases. see @ref ble_gatts_create_db_t. * * @retval ::SDK_SUCCESS: Database has been registered successfully. * @retval ::SDK_ERR_POINTER_NULL: Param is NULL or param's members are NULL. * @retval ::SDK_ERR_INVALID_PARAM: The member of param is invalid. * @retval ::SDK_ERR_INVALID_HANDLE: The service handles can not be allocated. * @retval ::SDK_ERR_NO_RESOURCES: There is not enough memory to allocate service buffer. - * @retval ::SDK_ERR_INVALID_PERM: Permissions of Client Characteristic Configuration or - * Server Characteristic Configuration are not set correctly. - **************************************************************************************** + * @retval ::SDK_ERR_INVALID_PERM: Permissions of Client Characteristic Configuration or Server Characteristic Configuration are not set correctly. + **************************************************************************************** */ -uint16_t ble_gatts_srvc_db_create(gatts_create_db_t *p_param); +uint16_t ble_gatts_srvc_db_create(ble_gatts_create_db_t *p_param); /** **************************************************************************************** @@ -414,16 +427,15 @@ uint16_t ble_gatts_srvc_db_create(gatts_create_db_t *p_param); * @param[in] handle: Attribute handle. * @param[in] length: Size of the value to set. * @param[in] offset: Data offset of the value in attribute value. - * @param[in] p_value: The value to set. If offset = 0, the value is the new attribute value; otherwise, - * the value is part of the new attribute value. + * @param[in] p_value: The value to set. If offset = 0, the value is the new attribute value; otherwise, the value is part of the new attribute value. * * @retval ::SDK_SUCCESS: Successfully update the attribute value. * @retval ::SDK_ERR_POINTER_NULL: Value is NULL. * @retval ::SDK_ERR_INVALID_HANDLE: Handle not exist in database. - * @retval ::SDK_ERR_REQ_NOT_SUPPORTED: Attribute data is not present in database or cannot be modified. - * @retval ::SDK_ERR_INVALID_ATT_VAL_LEN: New value length exceeds maximum attribute value length. + * @retval ::SDK_ERR_REQ_NOT_SUPPORTED: Attribute data is not present in database or cannot be modified. + * @retval ::SDK_ERR_INVALID_ATT_VAL_LEN: New value length exceeds maximum attribute value length. * @retval ::SDK_ERR_INVALID_OFFSET: Offset exceeds current attribute value length. - **************************************************************************************** + **************************************************************************************** */ uint16_t ble_gatts_value_set(uint16_t handle, uint16_t length, uint16_t offset, const uint8_t* p_value); @@ -441,17 +453,15 @@ uint16_t ble_gatts_value_set(uint16_t handle, uint16_t length, uint16_t offset, * @retval ::SDK_ERR_REQ_NOT_SUPPORTED: Attribute data is not present in database. * @retval ::SDK_ERR_INVALID_ATT_VAL_LEN: Attribute data value size is bigger than buffer size. * @retval ::SDK_ERR_APP_ERROR: Database is not correctly initialized by application. - **************************************************************************************** + **************************************************************************************** */ uint16_t ble_gatts_value_get(uint16_t handle, uint16_t* p_length, uint8_t* p_value); /** **************************************************************************************** * @brief Update attribute permission. - * @note The modifications of attribute permission to - * service/character/include/character_extended_properties_descriptor declaration: not supported. \n - * The modifications of attribute permission to others: perm can be updated and EKS of ext_perm can be updated. - * See @ref BLE_GATTS_ATTR_PERM. + * @note The modifications of attribute permission to service/character/include/character_extended_properties_descriptor declaration: not supported. \n + * The modifications of attribute permission to others: perm can be updated and EKS of ext_perm can be updated.See @ref BLE_GATTS_ATTR_PERM. * * @param[in] handle: Attribute handle. * @param[in] perm: New attribute permission. @@ -481,15 +491,13 @@ uint16_t ble_gatts_attr_permission_get(uint16_t handle, uint16_t *p_perm, uint16 /** **************************************************************************************** - * @brief Respond to an attribute read request. It is used in profile read callback function - * @ref gatts_prf_cbs_t::app_gatts_read_cb - * to send attribute value to stack which is saved in user space. + * @brief Respond to an attribute read request.. * * @note The status member gatts_read_cfm_t::status should be set to @ref BLE_ATT_ERR_INSUFF_AUTHOR * to control the authorization of particular read operations of a client. * * @param[in] conn_idx: Current connection index. - * @param[in] p_param: Pointer to the parameters filled by profile. See @ref gatts_read_cfm_t. + * @param[in] p_param: Pointer to the parameters filled by profile. See @ref ble_gatts_read_cfm_t. * * @retval ::SDK_SUCCESS: Send read confirm value to stack successfully. * @retval ::SDK_ERR_POINTER_NULL: Param is NULL. @@ -497,18 +505,17 @@ uint16_t ble_gatts_attr_permission_get(uint16_t handle, uint16_t *p_perm, uint16 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gatts_read_cfm(uint8_t conn_idx, const gatts_read_cfm_t *p_param); +uint16_t ble_gatts_read_cfm(uint8_t conn_idx, const ble_gatts_read_cfm_t *p_param); /** **************************************************************************************** - * @brief Respond to an attribute write request. It is used in profile write callback function - * @ref gatts_prf_cbs_t::app_gatts_write_cb to send write operation status to stack. + * @brief Respond to an attribute write request. * * @note The status member gatts_write_cfm_t::status should be set to @ref BLE_ATT_ERR_INSUFF_AUTHOR * to control the authorization of particular client's write operation. * * @param[in] conn_idx: Current connection index. - * @param[in] p_param: Pointer to the parameters filled by profile. see @ref gatts_write_cfm_t. + * @param[in] p_param: Pointer to the parameters filled by profile. see @ref ble_gatts_write_cfm_t. * * @retval ::SDK_SUCCESS: Send write confirm status to stack successfully. * @retval ::SDK_ERR_POINTER_NULL: Param is NULL. @@ -516,18 +523,17 @@ uint16_t ble_gatts_read_cfm(uint8_t conn_idx, const gatts_read_cfm_t *p_param); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gatts_write_cfm(uint8_t conn_idx, const gatts_write_cfm_t *p_param); +uint16_t ble_gatts_write_cfm(uint8_t conn_idx, const ble_gatts_write_cfm_t *p_param); /** **************************************************************************************** - * @brief Respond to an attribute prepare write request. It is used in profile prepare write callback - * function @ref gatts_prf_cbs_t::app_gatts_prep_write_cb to send prepare write operation status to stack. + * @brief Respond to an attribute prepare write request. * * @note The status member gatts_prep_write_cfm_t::status should be set to @ref BLE_ATT_ERR_INSUFF_AUTHOR * to control the authorization of particular client's write operation. * * @param[in] conn_idx: Current connection index. - * @param[in] p_param: Pointer to the parameters filled by profile. see @ref gatts_prep_write_cfm_t. + * @param[in] p_param: Pointer to the parameters filled by profile. see @ref ble_gatts_prep_write_cfm_t. * * @retval ::SDK_SUCCESS: Send prepare write confirm status to stack successfully. * @retval ::SDK_ERR_POINTER_NULL: Param is NULL. @@ -535,18 +541,17 @@ uint16_t ble_gatts_write_cfm(uint8_t conn_idx, const gatts_write_cfm_t *p_param) * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gatts_prepare_write_cfm(uint8_t conn_idx, const gatts_prep_write_cfm_t *p_param); +uint16_t ble_gatts_prepare_write_cfm(uint8_t conn_idx, const ble_gatts_prep_write_cfm_t *p_param); /** **************************************************************************************** - * @brief Send out a notification or an indication. The execution status of sending notification or - * indication will be retrieved in the complete callback function @ref gatts_prf_cbs_t::app_gatts_ntf_ind_cb. + * @brief Send out a notification or an indication. * * @note Check whether the relevant Client Characteristic Configuration Descriptor is enabled before using this API. * * @param[in] conn_idx: Current connection index. - * @param[in] p_param: Pointer to the parameters filled by profile. see @ref gatts_noti_ind_t. - * + * @param[in] p_param: Pointer to the parameters filled by profile. see @ref ble_gatts_noti_ind_t. + * * @retval ::SDK_SUCCESS: Send Notification or Indication event to stack successfully. * @retval ::SDK_ERR_POINTER_NULL: Param is NULL. * @retval ::SDK_ERR_INVALID_CONN_IDX: Conidx is invalid. @@ -555,7 +560,7 @@ uint16_t ble_gatts_prepare_write_cfm(uint8_t conn_idx, const gatts_prep_write_cf * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_gatts_noti_ind(uint8_t conn_idx, const gatts_noti_ind_t *p_param); +uint16_t ble_gatts_noti_ind(uint8_t conn_idx, const ble_gatts_noti_ind_t *p_param); /** **************************************************************************************** diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_l2cap.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_l2cap.h old mode 100755 new mode 100644 index 9b4bf01..30c7443 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_l2cap.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_l2cap.h @@ -35,167 +35,173 @@ ***************************************************************************************** */ -/** -* @addtogroup BLE -* @{ -*/ - -/** - @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) - @{ - @brief Definitions and prototypes for the L2CAP interface. -*/ - + /** + * @addtogroup BLE + * @{ + */ + + /** + @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + #ifndef __BLE_L2CAP_H__ #define __BLE_L2CAP_H__ -#include -#include +#include "ble_error.h" #include "gr55xx_sys_cfg.h" +#include +#include -/** @addtogroup BLE_L2CAP_ENUMERATIONS Enumerations +/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations * @{ */ -/** @brief LE credit based disconnection reasons. */ -typedef enum { - REMOTE_USER_TERM_CON = 0x00, /**< Remote user terminates the connection. */ - LOCAL_USER_TERM_CON = 0x01, /**< Local user terminates the connection. */ -} lecb_disconnect_reason_t; +/**@brief LE credit based disconnection reasons. */ +typedef enum +{ + BLE_L2CAP_REMOTE_USER_TERM_CON = 0x00, /**< Remote user terminates the connection. */ + BLE_L2CAP_LOCAL_USER_TERM_CON = 0x01, /**< Local user terminates the connection. */ +} ble_l2cap_lecb_disconn_reason_t; /** @} */ /** @addtogroup BLE_L2CAP_STRUCTURES Structures * @{ */ -/** @brief The parameter of LE credit based connection request packet sending. - * @note The le_psm should be registered by the peer device, otherwise the peer device will reject - * this request with result of LE_PSM not supported. - * @note The local_cid should be 0x0040-0x007F. If the local_cid is set to 0, the stack will assign it dynamically. - * @note The local_credit is required to be sure that at least one SDU can be received, - * otherwise the stack will use the default value: (MTU + MPS + 1) /MPS + 1. +/** @brief The parameter of LE credit based connection request packet sending. + * @note The le_psm should be registered by the peer device, otherwise the peer device will reject this request with result of LE_PSM not supported. + * @note The local_cid should be 0x0040-0x007F. If the local_cid is set to 0, the stack will assign it dynamically. + * @note The local_credit is required to be sure that at least one SDU can be received, otherwise the stack will use the default value: (MTU + MPS + 1) /MPS + 1. * @note The MTU range is [23~max_mtu]. * @note The MPS range is [23~max_mps]. - * @note About max_mtu and max_mps config, please see @ref ble_gap_l2cap_params_set. + * @note About max_mtu and max_mps config, please see @ref ble_gap_l2cap_params_set. */ -typedef struct { +typedef struct +{ uint16_t le_psm; /**< The le_psm number. */ uint16_t local_cid; /**< The local CID. */ - uint16_t local_credits; /**< The local credits indicate the number of LE-frames that the peer devicecan send - to the L2CAP layer entity sending the LE Credit Based Connection Request. */ - uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer - entity sending the LE Credit Based Connection Request - can receive on this channel. */ - uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that - the L2CAP layer entity sending the LE Credit Based Connection Request - is capable of receiving on this channel. */ -} lecb_conn_req_t; + uint16_t local_credits; /**< The local credits indicate the number of LE-frames that the peer device can send to the L2CAP layer entity sending the LE Credit Based Connection Request. */ + uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit Based Connection Request can receive on this channel. */ + uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit Based Connection Request is capable of receiving on this channel. */ +} ble_l2cap_lecb_conn_req_t; -/** @brief LE credit based connection confirm parameter. +/** @brief LE credit based connection confirm parameter. * @note The accept flag indicates whether the App accepts the LE Credit Based connection request. * @note The peer_cid represents the channel endpoint on the peer device. * @note The local_cid should be 0x0040-0x007F. If the local_cid is set to 0, the stack will assign it dynamically. - * @note The local_credits required to be sure that at least one SDU can be received, otherwise the stack - * will use the default value: (MTU + MPS + 1) /MPS + 1. + * @note The local_credits required to be sure that at least one SDU can be received, otherwise the stack will use the default value: (MTU + MPS + 1) /MPS + 1. * @note The MTU range is [23~max_mtu]. * @note The MPS range is [23~max_mps]. * @note About the max_mtu and max_mps config, please see @ref ble_gap_l2cap_params_set. */ -typedef struct { - bool accept; /**< Whether to accept the connection request. */ - uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request - and receiving the response. */ - uint16_t local_cid; /**< Local CID. */ - uint16_t local_credits; /**< It indicates the number of LE-frames that the peer device can send to the - L2CAP layer entity sending the LE Credit Based Connection Respone. */ - uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity - sending the LE Credit Based Connection Request can receive on this channel. */ - uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that the L2CAP layer - entity sending the LE Credit Based Connection Request is capable of receiving - on this channel. */ -} lecb_cfm_conn_t; +typedef struct +{ + bool accept; /**< Whether to accept the connection request. */ + uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request and receiving the response. */ + uint16_t local_cid; /**< Local CID. */ + uint16_t local_credits; /**< It indicates the number of LE-frames that the peer device can send to the L2CAP layer entity sending the LE Credit Based Connection Respone. */ + uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending + the LE Credit Based Connection Request can receive on this channel. */ + uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending + the LE Credit Based Connection Request is capable of receiving on this channel. */ +} ble_l2cap_lecb_cfm_conn_t; /** @brief LE flow control credit packet parameter. */ -typedef struct { +typedef struct +{ uint16_t local_cid; /**< The local source channel ID. */ uint16_t credits; /**< Number of credits that the receiving device can increment. */ -} lecb_add_credits_t; +} ble_l2cap_lecb_add_credits_t; -/** @brief SDU packet parameter. +/** @brief SDU packet parameter. * @note The length should be less than peer_mtu when sending sdu packet. - * @note The credits is 0 if this packet is being sent, or it represents the number of credits consumed - * by this sdu if this packet is received. - * @note When the application receives a sdu, it should firstly copy this sdu packet before handling it, - * because the stack will free it after invoking the callback function. - * @note Similarly, the application should free the packet if it is malloced - * after invoking the function to send sdu packet. + * @note The credits is 0 if this packet is being sent, or it represents the number of credits consumed by this sdu if this packet is received. + * @note When the application receives a sdu, it should firstly copy this sdu packet before handling it, because the stack will free it after invoking the callback function. + * @note Similarly, the application should free the packet if it is malloced after invoking the function to send sdu packet. */ -typedef struct { - uint16_t cid; /**< The local source channel. */ - uint16_t credits; /**< The credits is 0 if this packet is being sent, - otherwise it represents the number of credits consumed by the sdu. */ - uint16_t length; /**< The lenght of data. */ - uint8_t data[ARRAY_EMPTY]; /**< The data of this sdu packet. */ -} lecb_sdu_t; +typedef struct +{ + uint16_t cid; /**< The local source channel. */ + uint16_t credits; /**< The credits is 0 if this packet is being sent, otherwise it represents the number of credits consumed by the sdu. */ + uint16_t length; /**< The lenght of data. */ + uint8_t *data; /**< The data of this sdu packet. */ +} ble_l2cap_lecb_sdu_t; -/** @brief Receive LE credit based connection request packet indication. */ -typedef struct { +/** @brief L2cap Connect Request event for @ref BLE_L2CAP_EVT_CONN_REQ. */ +typedef struct +{ uint16_t le_psm; /**< Le_psm number that should be registered by local device. */ - uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request - and receiving the response. */ - uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending - the LE Credit Based Connection Request can receive on this channel. */ - uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending - the LE Credit Based Connection Request is capable of receiving on this channe. */ -} lecb_conn_req_ind_t; + uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request and receiving the response. */ + uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit + Based Connection Request can receive on this channel. */ + uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit + Based Connection Request is capable of receiving on this channe. */ +} ble_l2cap_evt_conn_req_t; -/** @brief LE credit based connection created indication. */ -typedef struct { +/** @brief L2cap Connected Indicate event for @ref BLE_L2CAP_EVT_CONN_IND. */ +typedef struct +{ uint16_t le_psm; /**< Le_psm number. */ uint16_t local_cid; /**< The local source channel ID. */ uint16_t local_credits; /**< It indicates the number of LE-frames that the local device can receive. */ uint16_t peer_credits; /**< It indicates the number of LE-frames that the peer device can receive. */ - uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending - the LE Credit Based Connection Request can receive on this channel. */ - uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending - the LE Credit Based Connection Request is capable of receiving on this channe. */ -} lecb_conn_ind_t; + uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit + Based Connection Request can receive on this channel. */ + uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit + Based Connection Request is capable of receiving on this channe. */ +} ble_l2cap_evt_conn_ind_t; -/** @brief LE credit based disconnect indication. */ -typedef struct { - uint16_t local_cid; /**< The local source channel ID. */ - uint8_t reason; /**< The reason for disconnection, see @ref lecb_disconnect_reason_t . */ -} lecb_disconn_ind_t; - -/** @brief LE credit based connection addition indication. */ -typedef struct { +/** @brief L2cap Credits Add Indicate event for @ref BLE_L2CAP_EVT_ADD_CREDITS_IND. */ +typedef struct +{ uint16_t local_cid; /**< The local source channel ID. */ uint16_t peer_added_credits; /**< Represent number of credits the receiving device can increment. */ -} lecb_add_credits_ind_t; +} ble_l2cap_evt_add_credits_ind_t; -/** @brief LE credit based SDU sending complete event. */ -typedef struct { +/** @brief L2cap disconnect event for @ref BLE_L2CAP_EVT_DISCONNECTED. */ +typedef struct +{ + uint16_t local_cid; /**< The local source channel ID. */ + ble_l2cap_lecb_disconn_reason_t reason; /**< The reason for disconnection, see @ref ble_l2cap_lecb_disconn_reason_t . */ +} ble_l2cap_evt_disconnect_t; + +/**@brief L2cap SDU Receive event for @ref BLE_L2CAP_EVT_SDU_RECV. */ +typedef struct +{ + uint16_t cid; /**< The local source channel. */ + uint16_t credits; /**< The credits is 0 if this packet is being sent, otherwise it represents the number of credits consumed by the sdu. */ + uint16_t length; /**< The lenght of data. */ + uint8_t *data; /**< The data of this sdu packet. */ +} ble_l2cap_evt_sdu_recv_t; + +/**@brief L2cap SDU Send event for @ref BLE_L2CAP_EVT_SDU_SEND. */ +typedef struct +{ uint16_t cid; /**< Channel ID that is the local CID. */ uint16_t credits; /**< Number of peer credit used. */ -} lecb_sdu_send_evt_t; - -/** @brief Callback registered by APP. */ -typedef struct { - /**< Callback for receiving LE credit based connection request. */ - void (*app_l2cap_lecb_conn_req_cb)(uint8_t conn_idx, lecb_conn_req_ind_t *p_conn_req); - /**< Callback for receiving LE credit based connection created indication. */ - void (*app_l2cap_lecb_conn_cb)(uint8_t conn_idx, uint8_t status, lecb_conn_ind_t *p_conn_ind); - /**< Callback for receiving LE credit based connection addition indication. */ - void (*app_l2cap_lecb_add_credits_ind_cb)(uint8_t conn_idx, lecb_add_credits_ind_t *p_add_credits_ind); - /**< Callback for receiving LE credit based disconnection indication. */ - void (*app_l2cap_lecb_disconn_cb)(uint8_t conn_idx, uint8_t status, lecb_disconn_ind_t *p_disconn_ind); - /**< Callback for receiving SDU packet. */ - void (*app_l2cap_lecb_sdu_recv_cb)(uint8_t conn_idx, lecb_sdu_t *p_sdu); - /**< Callback for sending SDU operation complete event. */ - void (*app_l2cap_lecb_sdu_send_cb)(uint8_t conn_idx, uint8_t status, lecb_sdu_send_evt_t *p_sdu_send_evt); - /**< Callback for LE credit add complete event. */ - void (*app_l2cap_lecb_credit_add_cmp_cb)(uint8_t conn_idx, uint8_t status, uint16_t local_cid); -} l2cap_lecb_cb_fun_t; +}ble_l2cap_evt_sdu_send_t; +/**@brief L2cap Credits Add Completed event for @ref BLE_GATTC_EVT_NTF_IND. */ +typedef struct +{ + uint16_t local_cid; /**< Channel ID that is the local CID. */ +}ble_l2cap_evt_add_credits_cplt_t; +/**@brief BLE L2cap event structure. */ +typedef struct +{ + uint8_t index; /**< Index of connection or advertising. */ + union + { + ble_l2cap_evt_conn_req_t conn_req; /**< L2cap Connect Request event. */ + ble_l2cap_evt_conn_ind_t conn_ind; /**< L2cap Connected Indicate event. */ + ble_l2cap_evt_add_credits_ind_t add_credits_ind; /**< L2cap Credits Add Indicate event. */ + ble_l2cap_evt_disconnect_t disconnected; /**< L2cap Disconnected event. */ + ble_l2cap_evt_sdu_recv_t sdu_recv; /**< L2cap SDU Receive event. */ + ble_l2cap_evt_sdu_send_t sdu_send; /**< L2cap SDU Send event. */ + ble_l2cap_evt_add_credits_cplt_t add_credits_cplt; /**< L2cap Credits Add Completed event. */ + } params; /**< Event Parameters. */ +} ble_l2cap_evt_t; /** @} */ /** @addtogroup BLE_L2CAP_FUNCTIONS Functions @@ -203,10 +209,8 @@ typedef struct { /** **************************************************************************************** * @brief Create the LE credit based connection. - * @note After the COC created, the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_conn_cb will be called. * - * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0, - * and the index will be increased one by one. + * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0, and the index will be increased one by one. * @param[in] p_conn_req: Pointer to the LE Credit Based Connection Request structure. * * @retval ::SDK_SUCCESS: The LE Credit Based connection request is successfully set to the BLE stack. @@ -215,15 +219,13 @@ typedef struct { * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_l2cap_lecb_conn_create(uint8_t conn_idx, const lecb_conn_req_t *p_conn_req); +uint16_t ble_l2cap_lecb_conn_create(uint8_t conn_idx, const ble_l2cap_lecb_conn_req_t *p_conn_req); /** **************************************************************************************** * @brief Confirm the LE credit based connection after receiving the connection request packet from the peer device. - * @note This function should be invoked in the handle of callback @ref l2cap_lecb_cb_fun_t:app_l2cap_lecb_conn_req_cb. - * And after the COC created, the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_conn_cb should be called. - * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and - * the index will be increased one by one. + * + * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one. * @param[in] p_cfm_conn: Pointer to the LE Credit Based Connection Confirm structure. * * @retval ::SDK_SUCCESS: The LE Credit Based connection confirmation is successfully set to the BLE stack. @@ -233,15 +235,13 @@ uint16_t ble_l2cap_lecb_conn_create(uint8_t conn_idx, const lecb_conn_req_t *p_c * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_l2cap_lecb_conn_cfm(uint8_t conn_idx, const lecb_cfm_conn_t *p_cfm_conn); +uint16_t ble_l2cap_lecb_conn_cfm(uint8_t conn_idx, const ble_l2cap_lecb_cfm_conn_t *p_cfm_conn); /** **************************************************************************************** * @brief Disconnect the LE credit based connection. - * @note After COC disconnected, the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_disconn_cb should be called. * - * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and - * the index will be increased one by one. + * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one. * @param[in] local_cid: The local source channel ID. * * @retval ::SDK_SUCCESS: LE Credit Based disconnection request is successfully set to the BLE stack. @@ -253,8 +253,7 @@ uint16_t ble_l2cap_lecb_disconnect(uint8_t conn_idx, uint16_t local_cid); /** **************************************************************************************** - * @brief Send a LE Flow Control Credit packet when the device is capable of receiving additional LE-frames - * (for example after the device has processed the sdu). + * @brief Send a LE Flow Control Credit packet when the device is capable of receiving additional LE-frames (for example after the device has processed the sdu). * * @param[in] conn_idx: ACL connection index, the first ACL connection index is 0, and increased one by one. * @param[in] p_add_credits: Pointer to the LE Flow Control Credit structure. @@ -265,14 +264,13 @@ uint16_t ble_l2cap_lecb_disconnect(uint8_t conn_idx, uint16_t local_cid); * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_l2cap_lecb_credits_add(uint8_t conn_idx, const lecb_add_credits_t *p_add_credits); +uint16_t ble_l2cap_lecb_credits_add(uint8_t conn_idx, const ble_l2cap_lecb_add_credits_t *p_add_credits); /** **************************************************************************************** * @brief Send an SDU packet to the peer device. * - * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and - * the index will be increased one by one. + * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one. * @param[in] p_sdu: Pointer to the sdu packet structure. * * @retval ::SDK_SUCCESS: The sdu packet is successfully set to the BLE stack. @@ -281,22 +279,20 @@ uint16_t ble_l2cap_lecb_credits_add(uint8_t conn_idx, const lecb_add_credits_t * * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. **************************************************************************************** */ -uint16_t ble_l2cap_lecb_sdu_send(uint8_t conn_idx, const lecb_sdu_t *p_sdu); +uint16_t ble_l2cap_lecb_sdu_send(uint8_t conn_idx, const ble_l2cap_lecb_sdu_t *p_sdu); /** **************************************************************************************** - * @brief Register the callback for the PSM. + * @brief Register PSM. * * @param[in] le_psm: The le_psm number. - * @param[in] p_cb: Pointer to the callback structure. * * @retval ::SDK_SUCCESS: The callback is successfully registered to the BLE stack. * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. * @retval ::SDK_ERR_INVALID_PSM_EXCEEDED_MAX_PSM_NUM: The maximum PSM number limit is exceeded. **************************************************************************************** */ -uint16_t ble_l2cap_lecb_cb_register(uint16_t le_psm, const l2cap_lecb_cb_fun_t *p_cb); - +uint16_t ble_l2cap_lecb_psm_register(uint16_t le_psm); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_lcp.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_lcp.h new file mode 100644 index 0000000..74994ad --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_lcp.h @@ -0,0 +1,230 @@ +/** + **************************************************************************************** + * + * @file ble_lcp.h + * + * @brief LCP SDK API + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + + /** + * @addtogroup BLE + * @{ + * @brief Definitions and prototypes for the BLE SDK interface. + */ + + /** + * @addtogroup BLE_LCP Light Communication Protocol (LCP) + * @{ + * @brief Definitions and prototypes for the LCP interface. + */ + +#ifndef _BLE_LCP_H_ +#define _BLE_LCP_H_ + + +/**@addtogroup BLE_LCP_TYPEDEFS Typedefs + * @{ */ +/**@brief RX handler callback function. */ +typedef uint16_t (*rx_handler_cb_t) (uint8_t header, uint8_t length, uint8_t *p_payload); +/** @} */ + +/**@addtogroup BLE_LCP_ENUMERATIONS Enumerations + * @{ */ +/**@brief Protocol Mode. */ +enum PROTOCOL_MODE +{ + BLE_ADV, /**< BLE ADV mode. */ + BLE_SCAN, /**< BLE SCAN mode. */ + LCP_TX, /**< LCP TX mode. */ + LCP_RX, /**< LCP RX mode. */ +}; +/** @} */ + +/**@addtogroup BLE_LCP_STRUCTURES Structures + * @{ */ +/**@brief LCP Parameter. */ +typedef struct +{ + uint8_t mode; /**< Set protocol mode, see @ref PROTOCOL_MODE. */ + int8_t txpwr_dbm; /**< The value of the tx power(range: -20-7), uint: dBm. */ + uint8_t ch_idx; /**< The value of the channel index(range: 0-39). */ + uint32_t freq; /**< The value of the frequency(range: 2360-2520), uint: MHz. */ + uint32_t access_address; /**< The value of the access address. */ + uint32_t crc_init; /**< The initial value of the crc. */ + rx_handler_cb_t rx_handler_cb; /**< The callback function of rx. */ +} gdx_lcp_config_t; +/** @} */ + +/** @addtogroup BLE_LCP_FUNCTIONS Functions + * @{ */ +/** + **************************************************************************************** + * @brief Initialize LCP. + * + * @param[in] gdx_lcp_config: Configure the parameter of LCP, @ref gdx_lcp_config_t. + * + * @retval ::SDK_SUCCESS: The LCP parameter is successfully configured. + * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. + * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_init(gdx_lcp_config_t *gdx_lcp_config); + +/** + **************************************************************************************** + * @brief Deinitialize LCP. + * + * @retval ::SDK_SUCCESS: The LCP is successfully Deinitialized. + **************************************************************************************** + */ +uint16_t gdx_lcp_deinit(void); + +/** + **************************************************************************************** + * @brief Set the tx power of LCP. + * + * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. + * + * @retval ::SDK_SUCCESS: Operation is Success. + * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_tx_power_set(int8_t txpwr_dbm); + +/** + **************************************************************************************** + * @brief Get the tx power of LCP. + * + * @param[in] txpwr_dbm: The value of the tx power, Range: -20dbm to 7dbm. + * + * @retval ::SDK_SUCCESS: Operation is Success. + * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_tx_power_get(int8_t *txpwr_dbm); + +/** + **************************************************************************************** + * @brief Set the channel of LCP. + * + * @param[in] freq: The value of the frequency, Range: 2360MHz to 2520MHz. + * @param[in] ch_idx: The value of the channel index, Range: 0 to 39. + * + * @retval ::SDK_SUCCESS: Operation is Success. + * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_channel_set(uint32_t freq, uint8_t ch_idx); + +/** + **************************************************************************************** + * @brief Get the channel of LCP. + * + * @param[in] freq: The value of the frequency, Range: 2360MHz to 2520MHz. + * @param[in] ch_idx: The value of the channel index, Range: 0 to 39. + * + * @retval ::SDK_SUCCESS: Operation is Success. + * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_channel_get(uint32_t *freq, uint8_t *ch_idx); + +/** + **************************************************************************************** + * @brief Set the rate of LCP. + * + * @param[in] rate: The phy rate of LCP communication. Should be called before gdx_lcp_init + * + * @retval :void. + **************************************************************************************** + */ +void gdx_lcp_rate_set(bool rate); + +/** + **************************************************************************************** + * @brief Get the rate of LCP. + * + * + * @retval ::0: 1Mbps. + * @retval ::1: 2Mbps. + **************************************************************************************** + */ +bool gdx_lcp_rate_get(void); + +/** + **************************************************************************************** + * @brief Get the rssi of LCP. + * + * + * @retval ::Rssi of current channel. Should be called after gdx_lcp_rx_start + **************************************************************************************** + */ +int8_t gdx_lcp_rssi_get(void); + +/** + **************************************************************************************** + * @brief Transmmit a packet. + * + * @param[in] header: The header of the packet. + * @param[in] length: The length of the packet payload. + * @param[in] p_payload: The pointer of the packet payload. + * + * @retval ::SDK_SUCCESS: Operation is Success. + * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied. + **************************************************************************************** + */ +uint16_t gdx_lcp_data_tx(uint8_t header, uint8_t length, uint8_t *p_payload); + +/** + **************************************************************************************** + * @brief Start receiving packets + * + * @retval ::SDK_SUCCESS: Operation is Success. + **************************************************************************************** + */ +uint16_t gdx_lcp_rx_start(void); + +/** + **************************************************************************************** + * @brief Stop receiving packets + * + * @retval ::SDK_SUCCESS: Operation is Success. + **************************************************************************************** + */ +uint16_t gdx_lcp_rx_stop(void); + +/** @} */ + +#endif + +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_prf.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_prf.h old mode 100755 new mode 100644 index eb3713e..6016517 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_prf.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_prf.h @@ -49,574 +49,43 @@ #ifndef __BLE_PRF_H__ #define __BLE_PRF_H__ +#include "ble_error.h" +#include "ble_att.h" #include "ble_gatts.h" #include "ble_gattc.h" #include "ble_gatt.h" - -/** - @addtogroup BLE_PRF_COMMON Profile Common - @{ - @brief Definitions and prototypes for Profile Common interface. - */ - -/** @addtogroup BLE_PRF_MANAGER_TYPEDEFS Typedefs - * @{ */ -/** -**************************************************************************************** -* @brief Initialization of the Profile module. -* @note This function performs all the initializations of the Profile module, and it will be automatically -* called after the ble_server_prf_add() or ble_client_prf_add() function. -* - Creation of database (if it's a service) and ble_gatts_srvc_db_create should be called. -* - Allocation of profile-required memory. -* -* @retval status code to know if profile initialization succeeds or not. - **************************************************************************************** - */ -typedef uint8_t (*prf_init_func_t)(void); - -/** -**************************************************************************************** -* @brief Handles Connection creation. There is no need to recovery CCCD because stack will do that. -* -* @param[in] conn_idx: Connection index. - **************************************************************************************** - */ -typedef void (*prf_on_connect_func_t)(uint8_t conn_idx); - -/** -**************************************************************************************** -* @brief Handles Disconnection. There is no need to recovery CCCD because stack will do that. -* -* @param[in] conn_idx: Connection index. -* @param[in] reason: Disconnection reason. - **************************************************************************************** - */ -typedef void (*prf_on_disconnect_func_t)(uint8_t conn_idx, uint8_t reason); - -/** @addtogroup BLE_PRF_MANAGER_STRUCTURES Structures -* @{ */ -/** -* @brief Profile manager callbacks. -*/ -/** @} */ -typedef struct { - prf_init_func_t init; /**< Initialization callback. See @ref prf_init_func_t. */ - prf_on_connect_func_t on_connect; /**< Connection callback. See @ref prf_on_connect_func_t. */ - prf_on_disconnect_func_t on_disconnect; /**< Disconnection callback. See @ref prf_on_disconnect_func_t. */ -} ble_prf_manager_cbs_t; - -/** @} */ - -/** @} */ - -/** - @addtogroup BLE_PRF_SERVER Profile Server - @{ - @brief Definitions and prototypes for Profile Server interface. - */ - -/** @addtogroup BLE_PRF_SERVER_STRUCTURES Structures - * @{ */ -/** - * @brief GATT read request struct. - */ -typedef struct { - uint16_t handle; /**< Handle of the attribute to be read. */ -} gatts_read_req_cb_t; - -/** - * @brief GATT write request struct. - */ -typedef struct { - uint16_t handle; /**< Handle of the attribute to be written. */ - uint16_t offset; /**< Offset at which the data has to be written. */ - uint16_t length; /**< Data length to be written. */ - uint8_t value[ARRAY_EMPTY]; /**< Data to be written to characteristic value. */ -} gatts_write_req_cb_t; - -/** - * @brief GATT prepare write request struct. - */ -typedef struct { - uint16_t handle; /**< Handle of the attribute for whose value is requested. */ -} gatts_prep_write_req_cb_t; - -/** - * @brief GATTS Operation Complete event structure. - */ -typedef struct { - gatt_evt_type_t type; /**< Notification or indication event type. */ - uint16_t handle; /**< Handle of the write operation, or notification/indication operation. */ -} ble_gatts_ntf_ind_t; - -/** - * @brief GATT server callback function in relation to a profile. - */ -typedef struct { - /**< Read attribute value callback which is used when value is present in user space. - Function @ref ble_gatts_read_cfm should be called to send attribute value to stack. */ - void (*app_gatts_read_cb)(uint8_t conidx, const gatts_read_req_cb_t *p_read_req); - /**< Write attribute value callback. Function @ref ble_gatts_write_cfm should be called to - send write attribute value status to stack no matter the value is in user's zone or BLE stack. */ - void (*app_gatts_write_cb)(uint8_t conidx, const gatts_write_req_cb_t *p_write_req); - /**< Prepare write value callback function.Function @ref ble_gatts_prepare_write_cfm should be called to - send prepare write attribute value status to stack no matter the value is in user's zone or BLE stack. */ - void (*app_gatts_prep_write_cb)(uint8_t conidx, const gatts_prep_write_req_cb_t *p_prep_req); - /**< Notification or indication callback function. */ - void (*app_gatts_ntf_ind_cb)(uint8_t conidx, uint8_t status, const ble_gatts_ntf_ind_t *p_ntf_ind); - /**< Set CCCD value callback is called when connected with peer device. If bonded, recovery CCCD; - otherwise, set default value(0x0000) for CCCD. */ - void (*app_gatts_cccd_set_cb)(uint8_t conidx, uint16_t handle, uint16_t cccd_val); -} gatts_prf_cbs_t; - -/** - * @brief Profile server register information structure. - */ -typedef struct { - uint16_t max_connection_nb; /**< Maximum connections the profile supports. */ - ble_prf_manager_cbs_t* manager_cbs; /**< Profile manager callbacks. */ - gatts_prf_cbs_t *gatts_prf_cbs; /**< GATT server callback function in relation to the specific profile. */ -} prf_server_info_t; - -/** @} */ +#include "ble_event.h" /** @addtogroup BLE_PRF_FUNCTIONS Functions * @{ */ /** **************************************************************************************** - * @brief Add a server profile by providing its detailed information, including manager callback functions and - * GATT server callback functions. - * This API should be called in application initialization function. + * @brief Add a server profile by providing its detailed information.. * - * @param[in] p_server_prf_info: Pointer to the prf_info. See @ref prf_server_info_t. + * @param[in] p_gatts_db: Pointer to the prf_info. See @ref ble_gatts_create_db_t. + * @param[in] evt_handler: Pointer to ble events handler. * - * @note If there are several profiles which need to be added, this function should be called corresponding times. + * @retval ::SDK_SUCCESS: The profile info is recorded successfully, and the database will be created in profile initialization callback function. + * @retval ::SDK_ERR_POINTER_NULL: The parameter p_gatts_db or evt_handler is NULL. + * @retval ::SDK_ERR_NO_RESOURCES: The profile number is up to the maximum number the system can support. + **************************************************************************************** + */ +uint16_t ble_gatts_prf_add(ble_gatts_create_db_t *p_gatts_db, ble_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief Add a client profile by providing its detail information. * - * @retval ::SDK_SUCCESS: The profile info is recorded successfully, and the database will be created in profile - * initialization callback function. - * @retval ::SDK_ERR_POINTER_NULL: The parameter prf_info is NULL, or input parameters that prf_info points - * to are invalid. + * @param[in] p_uuid: Pointer to the target service uuid. See @ref ble_uuid_t. + * @param[out] evt_handler: Pointer to ble events handler.. + * + * @retval ::SDK_SUCCESS: The profile info is recorded successfully, and the profile ENV will be initialized in profile initialization callback function. + * @retval ::SDK_ERR_POINTER_NULL: The parameter p_uuid or evt_handler is NULL, or input parameters that prf_info points to are invalid. * @retval ::SDK_ERR_NO_RESOURCES: The profile number is up to the maximum number the system can support. **************************************************************************************** */ -uint16_t ble_server_prf_add(const prf_server_info_t *p_server_prf_info); -/** @} */ - -/** @} */ - -/** - @addtogroup BLE_PRF_CLIENT Profile Client - @{ - @brief Definitions and prototypes for Profile Client interface. - */ - -/** @addtogroup BLE_PRF_CLIENT_STRUCTURES Structures - * @{ */ - -/** - * @brief GATTC profile register to peer event info structure. - */ -typedef struct { - uint16_t start_hdl; /**< Attribute start handle. */ - uint16_t end_hdl; /**< Attribute end handle. */ -} gattc_prf_reg_peer_evt_t; - -/** - * @brief GATTC profile register enumeration. - */ -typedef enum { - GATTC_EVT_REGISTER, /**< GATT client event register. */ - GATTC_EVT_UNREGISTER, /**< GATT client event unregister. */ -} gattc_prf_reg_evt_t; - -/** @brief GATTC Profile callback Structures. */ -typedef struct { - /**< Primary Service Discovery Response callback. */ - void (*app_gattc_srvc_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_srvc_disc_t *p_prim_srvc_disc); - /**< Relationship Discovery Response callback. */ - void (*app_gattc_inc_srvc_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_incl_disc_t *p_inc_srvc_disc); - /**< Characteristic Discovery Response callback. */ - void (*app_gattc_char_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_char_disc_t *p_char_disc); - /**< Descriptor Discovery Response callback. */ - void (*app_gattc_char_desc_disc_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_char_desc_disc_t *p_char_desc_disc); - /**< Read Response callback. */ - void (*app_gattc_read_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_read_rsp_t *p_read_rsp); - /**< Write complete callback. */ - void (*app_gattc_write_cb)(uint8_t conn_idx, uint8_t status, - uint16_t handle); - /**< Handle Value Notification/Indication Event callback. */ - void (*app_gattc_ntf_ind_cb)(uint8_t conn_idx, - const ble_gattc_ntf_ind_t *p_ntf_ind); - /**< Service found callback during browsing procedure. */ - void (*app_gattc_srvc_browse_cb)(uint8_t conn_idx, uint8_t status, - const ble_gattc_browse_srvc_t *p_browse_srvc); - /**< GATT client event register complete callback. */ - void (*app_gattc_prf_reg_cb)(uint8_t conn_idx, uint8_t status, - gattc_prf_reg_evt_t reg_evt); -} gattc_prf_cbs_t; - -/** - * @brief Profile client register information structure. - */ -typedef struct { - uint16_t max_connection_nb; /**< Maximum connections the profile supports. */ - ble_prf_manager_cbs_t *manager_cbs; /**< Profile manager callbacks. */ - gattc_prf_cbs_t *gattc_prf_cbs; /**< GATT client callback function in relation to - the specific profile. */ -} prf_client_info_t; - -/** @} */ - -/** - @addtogroup BLE_PRF_CLIENT_FUNCTIONS Functions - @{ - @brief Definitions and prototypes for Profile Client interface. - */ -/** - **************************************************************************************** - * @brief Add a client profile by providing its detail information, - * including manager callback functions and GATT client callback functions. - * This API should be called in application initialization function. - * - * @param[in] p_client_prf_info: Pointer to the p_client_prf_info. See @ref prf_client_info_t. - * @param[out] p_client_prf_id: Pointer to the client profile id. - * - * @note If there are several profiles which need to be added, this function should be called corresponding times. - * - * @retval ::SDK_SUCCESS: The profile info is recorded successfully, and the profile ENV will be - * initialized in profile initialization callback function. - * @retval ::SDK_ERR_POINTER_NULL: The parameter p_client_prf_info or p_client_prf_id is NULL, - * or input parameters that prf_info points to are invalid. - * @retval ::SDK_ERR_NO_RESOURCES: The profile number is up to the maximum number the system can support. - **************************************************************************************** - */ -uint16_t ble_client_prf_add(const prf_client_info_t *p_client_prf_info, uint8_t *p_client_prf_id); - -/** - **************************************************************************************** - * @brief Profile client Browse Specific Primary Service information on remote GATT server. - * - * @note This discovery automatically searches for Primary Services, Included Services, - * Characteristics and Descriptors of each service. - * To discover one or more services only, use ble_gattc_primary_services_discover() instead. - * This discovery is able to search a specific Primary Service. - * If p_srvc_uuid is NULL, the invalid pointer error code will be returned immediately. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_srvc_browse_cb will be called for all attributes - * of each service found. After completed service handle range registeration for receiving peer device - * indication/notification will be executed internally. Because secondary service can't be browsed, - * so handle range registeration for receiving peer device indication/notification to this client - * profile may be necessary. App can call function ble_gattc_prf_evt_handle_register for registeration, - * it depends on user app. If user don't call this function, user shall call ble_gattc_prf_evt_handle_register to - * register handle range for receiving peer device indication/notification in specific client profile callback. - * - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_srvc_uuid: Pointer to Service UUID. - * - * @retval ::SDK_SUCCESS: Successfully start the Browse Service(s) procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_services_browse(uint8_t prf_id, uint8_t conn_idx, const ble_uuid_t *p_srvc_uuid); - -/** - **************************************************************************************** - * @brief Profile client Discover Primary Services on remote GATT server. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_srvc_disc_cb will be called for service(s) found. - * If p_srvc_uuid is NULL, the invalid pointer error code will be returned immediately. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_srvc_uuid: Pointer to Service UUID. - * - * @retval ::SDK_SUCCESS: Successfully start the Primary Service Discovery procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_primary_services_discover(uint8_t prf_id, uint8_t conn_idx, const ble_uuid_t *p_srvc_uuid); - -/** - **************************************************************************************** - * @brief Profile client Discover Included Services on remote GATT server. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_inc_srvc_disc_cb will be called - * for Included Service(s) found. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] start_hdl: Start handle. - * @param[in] end_hdl: End handle. - * - * @retval ::SDK_SUCCESS: Successfully start the Relationship Discovery procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_included_services_discover(uint8_t prf_id, uint8_t conn_idx, uint16_t start_hdl, - uint16_t end_hdl); - -/** - **************************************************************************************** - * @brief Profile client Discover Characteristics on remote GATT server. - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_char_disc_cb will be called for Characteristic\ - * Declaration(s) found. If p_disc_char is NULL, the invalid pointer error code will be returned immediately. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_disc_char: Pointer to discover by characteristic UUID info. - * - * @retval ::SDK_SUCCESS: Successfully start the Characteristic Discovery procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_char_discover(uint8_t prf_id, uint8_t conn_idx, gattc_disc_char_t *p_disc_char); - -/** - **************************************************************************************** - * @brief Profile client Discover Characteristics Descriptors on remote GATT server. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_char_desc_disc_cb will be called for - * Characteristic Descriptor(s) found. If the last Descriptor has not been reached, this function must be called - * again with an updated handle range to continue the discovery. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] start_hdl: Start handle. - * @param[in] end_hdl: End handle. - * - * @retval ::SDK_SUCCESS: Successfully start the Descriptor Discovery procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_char_desc_discover(uint8_t prf_id, uint8_t conn_idx, uint16_t start_hdl, uint16_t end_hdl); - -/** - **************************************************************************************** - * @brief Profile client Read Attribute from remote GATT server. - * - * @note This uses either the "Read Characteristic Value" procedure or the "Read Characteristic Descriptor" - * procedure, depending on the attribute pointed by handle. If offset is non-zero or the - * attribute length is larger than the MTU, the "Read Long Characteristic Value" procedure or the - * "Read Long Characteristic Descriptor" procedure will be used respectively. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_read_cb will be called when Read is finished. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] handle: Attribute handle. - * @param[in] offset: Value offset to start with. - * - * @retval ::SDK_SUCCESS: Successfully start the Read (Long) procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_read(uint8_t prf_id, uint8_t conn_idx, uint16_t handle, uint16_t offset); - -/** - **************************************************************************************** - * @brief Profile client Read Attribute by UUID. - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_read_cb will be called when Read is finished. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_read_by_uuid: Pointer to Read by Characteristic UUID info. - * - * @retval ::SDK_SUCCESS: Successfully start the Read Using Characteristic UUID procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_read_by_uuid(uint8_t prf_id, uint8_t conn_idx, gattc_read_by_uuid_t *p_read_by_uuid); - -/** - **************************************************************************************** - * @brief Profile client Initiate a Read Multiple Characteristic Values procedure - * - * @note Function callback @ref gattc_prf_cbs_t::app_gattc_read_cb will be called for each handle value which is read. - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_param: Pointer to the parameters of the value. - * - * @retval ::SDK_SUCCESS: Successfully start the Read Multiple Characteristic Values procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_read_multiple(uint8_t prf_id, uint8_t conn_idx, const gattc_read_multiple_t *p_param); - -/** - **************************************************************************************** - * @brief Profile client Write (Long) Characteristic (Descriptor) Value. - * - * @note This uses either the "Write Characteristic Value" procedure or the "Write Characteristic - * Descriptor" procedure, depending on the attribute pointed by handle. If offset is non-zero - * or the attribute length is larger than the MTU, the "Write Long Characteristic Value" procedure - * or the "Write Long Characteristic Descriptor" procedure will be used respectively. - * - * @note Once completed @ref gattc_prf_cbs_t::app_gattc_write_cb will be called. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_write_attr_value: Pointer to the write attribue value info. - * - * @retval ::SDK_SUCCESS: Successfully start the Write procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_write(uint8_t prf_id, uint8_t conn_idx, gattc_write_attr_value_t *p_write_attr_value); - -/** - **************************************************************************************** - * @brief Profile client Prepare Long/Reliable Write to remote GATT server. - * @note Once completed @ref gattc_prf_cbs_t::app_gattc_write_cb will be called. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_write_attr_value: Pointer to the write attribue value info. - * - * @retval ::SDK_SUCCESS: Successfully send prepare write request. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_write_prepare(uint8_t prf_id, uint8_t conn_idx, gattc_write_attr_value_t *p_write_attr_value); - -/** - **************************************************************************************** - * @brief Profile client Execute Reliable/Long Write to remote GATT server. - * - * @note Once completed @ref gattc_prf_cbs_t::app_gattc_write_cb will be called. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] execute: True if data shall be written; False if cancel all prepared writes. - * - * @retval ::SDK_SUCCESS: Successfully send an Execute Write request. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_write_execute(uint8_t prf_id, uint8_t conn_idx, bool execute); - -/** - **************************************************************************************** - * @brief Profile client Write Attribute to remote GATT server (without response). - * - * @note If signed_write is set to false, the "Write Without Response" procedure will be used. - * If signed_write is set to true, the "Signed Write Without Response" procedure will be used on - * a link which is not encrypted. If a link is already encrypted, "Write Without Response" - * procedure shall be used instead of "Signed Write Without Response". - * @note Once completed @ref gattc_prf_cbs_t::app_gattc_write_cb will be called. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] p_write_no_resp: Pointer to the write without response info. - * - * @retval ::SDK_SUCCESS Successfully: start the (Signed) Write Without Response procedure. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_write_no_resp(uint8_t prf_id, uint8_t conn_idx, gattc_write_no_resp_t *p_write_no_resp); - -/** - **************************************************************************************** - * @brief Profile client Confirm Reception of Indication. - * - * @note Confirm indication which has been correctly received from the peer. - * - * @param[in] prf_id Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] handle: Value handle. - * - * @retval ::SDK_SUCCESS: Successfully send a Confirm Reception of Indication request. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_indicate_cfm(uint8_t prf_id, uint8_t conn_idx, uint16_t handle); - - -/** - **************************************************************************************** - * @brief Profile client Register Indication/Notification event. - * - * @note Registration to peer device events (Indication/Notification) for specific client profile. - * Once completed @ref gattc_prf_cbs_t::app_gattc_prf_reg_cb with type: @ref GATTC_EVT_UNREGISTER will be called. - * If user don't call ble_gattc_prf_services_browse, user shall call this function to register handle range - * for receiving peer device indication/notification in specific client profile callback. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] env: Pointer to the profile registeration event info. - * - * @retval ::SDK_SUCCESS: Successfully register Indication/Notification event. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_evt_handle_register(uint8_t prf_id, uint8_t conn_idx, gattc_prf_reg_peer_evt_t *env); - -/** - **************************************************************************************** - * @brief Profile client Unregister Indication/Notification event. - * - * @note Unregistration to peer device events (Indication/Notification) for specific client profile. - * Once completed @ref gattc_prf_cbs_t::app_gattc_prf_reg_cb with type: @ref GATTC_EVT_UNREGISTER will be called. - * - * @param[in] prf_id: Profile id. - * @param[in] conn_idx: Current connection index. - * @param[in] env: Pointer to the profile registeration event info. - * - * @retval ::SDK_SUCCESS: Successfully unregister Indication/Notification event. - * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied. - * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied. - * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter(s) supplied. - * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources. - **************************************************************************************** - */ -uint16_t ble_gattc_prf_evt_handle_unregister(uint8_t prf_id, uint8_t conn_idx, gattc_prf_reg_peer_evt_t *env); - -/** @} */ +uint16_t ble_gattc_prf_add(ble_uuid_t *p_uuid, ble_evt_handler_t evt_handler); /** @} */ #endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_sec.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_sec.h old mode 100755 new mode 100644 index 4b5c86f..ba6a7eb --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_sec.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/ble_sec.h @@ -40,196 +40,201 @@ * @{ */ -/** -@addtogroup BLE_SEC Security Manager(SM) -@{ -@brief Definitions and prototypes for the BLE_SEC interface. -*/ + /** + @addtogroup BLE_SEC Security Manager(SM) + @{ + @brief Definitions and prototypes for the BLE_SEC interface. + */ #ifndef __BLE_SEC_H__ #define __BLE_SEC_H__ +#include "ble_error.h" #include -/** @addtogroup BLE_SM_DEFINES Defines +/**@addtogroup BLE_SM_DEFINES Defines * @{ */ -/** @defgroup SEC_AUTH_FLAG SEC Auth Flag +/**@defgroup BLE_SEC_AUTH_FLAG SEC Auth Flag * @{ */ -#define AUTH_NONE 0 /**< No auth requirement. */ -#define AUTH_BOND (1 << 0) /**< Bond flag. */ -#define AUTH_MITM (1 << 2) /**< MITM flag. */ -#define AUTH_SEC_CON (1 << 3) /**< Security connection flag. */ -#define AUTH_KEY_PRESS_NOTIFY (1 << 4) /**< Key press notify flag. */ -#define AUTH_ALL (AUTH_BOND | AUTH_MITM | AUTH_SEC_CON | AUTH_KEY_PRESS_NOTIFY) /**< All authentication - flags are on. */ -/** @} */ +#define BLE_SEC_AUTH_NONE 0 /**< No auth requirement. */ +#define BLE_SEC_AUTH_BOND (1 << 0) /**< Bond flag. */ +#define BLE_SEC_AUTH_MITM (1 << 2) /**< MITM flag. */ +#define BLE_SEC_AUTH_SEC_CON (1 << 3) /**< Security connection flag. */ +#define BLE_SEC_AUTH_KEY_PRESS_NOTIFY (1 << 4) /**< Key press notify flag. */ +#define BLE_SEC_AUTH_ALL (AUTH_BOND | AUTH_MITM | AUTH_SEC_CON | AUTH_KEY_PRESS_NOTIFY) /**< All authentication flags are on. */ +/**@} */ -/** @defgroup SEC_KEY_DIST_FLAG SEC Key Distribution Flag -* @{ +/**@defgroup BLE_SEC_KEY_DIST_FLAG SEC Key Distribution Flag +* @{ */ -#define KDIST_NONE 0 /**< No key needs to be distributed. */ -#define KDIST_ENCKEY (1 << 0) /**< Distribute encryption and master identification info. */ -#define KDIST_IDKEY (1 << 1) /**< Distribute identity and address info. */ -#define KDIST_SIGNKEY (1 << 2) /**< Distribute signing info. */ -#define KDIST_ALL (KDIST_ENCKEY | KDIST_IDKEY | KDIST_SIGNKEY) /**< Distribute all info. */ +#define BLE_SEC_KDIST_NONE 0 /**< No key needs to be distributed. */ +#define BLE_SEC_KDIST_ENCKEY (1 << 0) /**< Distribute encryption and master identification info. */ +#define BLE_SEC_KDIST_IDKEY (1 << 1) /**< Distribute identity and address info. */ +#define BLE_SEC_KDIST_SIGNKEY (1 << 2) /**< Distribute signing info. */ +#define BLE_SEC_KDIST_LINKKEY (1 << 3) /**< Distribute link key info. */ +#define BLE_SEC_KDIST_ALL (BLE_SEC_KDIST_ENCKEY | BLE_SEC_KDIST_IDKEY | BLE_SEC_KDIST_SIGNKEY ) /**< Distribute all info. */ +#define BLE_BT_SEC_KDIST_ALL (BLE_SEC_KDIST_ENCKEY | BLE_SEC_KDIST_IDKEY | BLE_SEC_KDIST_SIGNKEY | BLE_SEC_KDIST_LINKKEY) /**< Distribute all info inlcude link key. */ -/** @} */ -/** @} */ +/**@} */ +/**@} */ -/** @addtogroup BLE_SEC_ENUMERATIONS Enumerations +/**@addtogroup BLE_SEC_ENUMERATIONS Enumerations * @{ */ -/** @brief SEC IO Capability. */ -typedef enum { - IO_DISPLAY_ONLY = 0x00, /**< Display only. */ - IO_DISPLAY_YES_NO = 0x01, /**< Display and input yes or no. */ - IO_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ - IO_NO_INPUT_NO_OUTPUT = 0x03, /**< No input and no output. */ - IO_KEYBOARD_DISPLAY = 0x04 /**< Keyboard and display. */ -} sec_io_cap_t; +/**@brief SEC IO Capability. */ +typedef enum +{ + BLE_SEC_IO_DISPLAY_ONLY = 0x00, /**< Display only. */ + BLE_SEC_IO_DISPLAY_YES_NO = 0x01, /**< Display and input yes or no. */ + BLE_SEC_IO_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ + BLE_SEC_IO_NO_INPUT_NO_OUTPUT = 0x03, /**< No input and no output. */ + BLE_SEC_IO_KEYBOARD_DISPLAY = 0x04 /**< Keyboard and display. */ +} ble_sec_io_cap_t; -/** @brief SEC Encryption Request Type. - * @note These types indicate some operations need to interact with app during pair process. +/**@brief SEC Encryption Request Type. + *@note These types indicate some operations need to interact with app during pair process. */ -typedef enum { - PAIR_REQ, /**< Pair request. Apps need to decide whether to accept this request. */ - TK_REQ, /**< TK request. Apps need to set the TK value. */ - OOB_REQ, /**< OOB request. Apps need to set the OOB value. */ - NC_REQ /**< Number comparison request. - Apps need to check if it is the same number displayed in Master and Slave. */ -} sec_enc_req_type_t; +typedef enum +{ + BLE_SEC_PAIR_REQ, /**< Pair request. Apps need to decide whether to accept this request. */ + BLE_SEC_TK_REQ, /**< TK request. Apps need to set the TK value. */ + BLE_SEC_OOB_REQ, /**< OOB request. Apps need to set the OOB value. */ + BLE_SEC_NC_REQ /**< Number comparison request. Apps need to check if it is the same number displayed in Master and Slave. */ +} ble_sec_enc_req_type_t; -/** @brief SEC Key Press Notify. */ -typedef enum { - KEY_PRESS_STARTED = 0x00, /**< Passkey entry started. */ - KEY_PRESS_ENTERED = 0x01, /**< Passkey digit entered. */ - KEY_PRESS_ERASED = 0x02, /**< Passkey digit erased. */ - KEY_PRESS_CLEARED = 0x03, /**< Passkey cleared. */ - KEY_PRESS_COMPLETED = 0x04 /**< Passkey entry completed. */ -} sec_keypress_notify_t; +/**@brief SEC Key Press Notify. */ +typedef enum +{ + BLE_SEC_KEY_PRESS_STARTED = 0x00, /**< Passkey entry started. */ + BLE_SEC_KEY_PRESS_ENTERED = 0x01, /**< Passkey digit entered. */ + BLE_SEC_KEY_PRESS_ERASED = 0x02, /**< Passkey digit erased. */ + BLE_SEC_KEY_PRESS_CLEARED = 0x03, /**< Passkey cleared. */ + BLE_SEC_KEY_PRESS_COMPLETED = 0x04 /**< Passkey entry completed. */ +} ble_sec_keypress_notify_t; -/** @brief SEC pair result. */ -typedef enum { - ENC_SUCCESS = 0x00, /**< Encrypt success. */ - ENC_FAIL_PASSKEY_ENTRY_FAIL = 0x01, /**< The user input of passkey failed, for example, - the user cancelled the operation. */ - ENC_FAIL_OOB_NOT_AVAILBL = 0x02, /**< The OOB data is not available. */ - ENC_FAIL_AUTH_REQ = 0x03, /**< The pairing procedure cannot be performed as authentication - requirements cannot be met due to IO incapability of - one or both devices. */ - ENC_FAIL_CONFIRM_VAL_FAIL = 0x04, /**< The confirm value does not match the calculated compare value. */ - ENC_FAIL_PAIRING_NOT_SUPPORT = 0x05, /**< Pairing is not supported by the device. */ - ENC_FAIL_ENCRPT_KEY_SIZE = 0x06, /**< The resultant encryption key size is insufficient for the security - requirements of this device. */ - ENC_FAIL_COMMAND_NOT_SUPPORT = 0x07, /**< The SMP command received is not supported on this device. */ - ENC_FAIL_UNSPECIFIED = 0x08, /**< Pairing failed due to an unspecified reason. */ - ENC_FAIL_REPEAT_ATTEMPT = 0x09, /**< Pairing or authentication procedure is disallowed because too little - time has elapsed since last pairing request or security request. */ - ENC_FAIL_INVALID_PARAM = 0x0A, /**< The Invalid Parameters error code indicates that the command length is - invalid or that a parameter is outside of the specified range. */ - ENC_FAIL_DHKEY_CHECK_FAIL = 0x0B, /**< Indicate to the remote device that the DHKey Check value received - doesn't match the one calculated by the local device. */ - ENC_FAIL_NUM_CMP_FAIL = 0x0C, /**< Indicate that the confirm values in the numeric comparison protocol - do not match. */ - ENC_FAIL_BR_EDR_IN_PROGRESS = 0x0D, /**< Indicate that the pairing over the LE transport failed due to - a Pairing Request sent over the BR/EDR transport in process. */ - ENC_FAIL_KEY_DRIV_GEN_NOT_ALLOW = 0x0E, /**< Indicate that the BR/EDR Link Key generated on the BR/EDR transport - cannot be used to derive and distribute keys for the LE transport. */ - ENC_FAIL_LTK_MISSING = 0x0F, /**< Indicate the LTK of peer devices missing. */ -} sec_enc_ind_t; +/**@brief SEC mode and level. */ +typedef enum +{ + BLE_SEC_MODE1_LEVEL1 = 0x00, /**< No security is needed. */ + BLE_SEC_MODE1_LEVEL2 = 0x01, /**< Encrypted link is required. Unnecessary: MITM and SC. */ + BLE_SEC_MODE1_LEVEL3 = 0x02, /**< Encrypted link is required. Necessary: MITM; unnecessary: SC. */ + BLE_SEC_MODE1_LEVEL4 = 0x03, /**< Encrypted link is required. Necessary: MITM and SC. */ + BLE_SEC_MODE2_LEVEL1 = 0x04, /**< Data signing is required. Unnecessary: MITM and SC. */ + BLE_SEC_MODE2_LEVEL2 = 0x05, /**< Data signing is required. Necessary: MITM; unnecessary: SC. */ +} ble_sec_mode_level_t; -/** @brief SEC mode and level. */ -typedef enum { - SEC_MODE1_LEVEL1 = 0x00, /**< No security is needed. */ - SEC_MODE1_LEVEL2 = 0x01, /**< Encrypted link is required. Unnecessary: MITM and SC. */ - SEC_MODE1_LEVEL3 = 0x02, /**< Encrypted link is required. Necessary: MITM; unnecessary: SC. */ - SEC_MODE1_LEVEL4 = 0x03, /**< Encrypted link is required. Necessary: MITM and SC. */ - SEC_MODE2_LEVEL1 = 0x04, /**< Data signing is required. Unnecessary: MITM and SC. */ - SEC_MODE2_LEVEL2 = 0x05, /**< Data signing is required. Necessary: MITM; unnecessary: SC. */ -} sec_mode_level_t; +/**@brief SEC TK type. */ +typedef enum +{ + BLE_SEC_TK_OOB = 0x00, /** UART0_TXD(MUX0),GPIO0_PIN4 -> UART0_RXD(MUX0)*/ - DFU_UART_PIN_GROUP_1, /**< GPIO0_PIN10 -> UART0_TXD(MUX2),GPIO0_PIN11 -> UART0_RXD(MUX2)*/ - DFU_UART_PIN_GROUP_2, /**< GPIO0_PIN0 -> UART0_TXD(MUX4),GPIO0_PIN1 -> UART0_RXD(MUX4)*/ - DFU_UART_PIN_GROUP_3, /**< GPIO1_PIN14 -> UART0_TXD(MUX5),GPIO1_PIN10 -> UART0_RXD(MUX5)*/ - DFU_UART_PIN_GROUP_4, /**< GPIO0_PIN7 -> UART1_TXD(MUX3),GPIO0_PIN6 -> UART1_RXD(MUX3)*/ - DFU_UART_PIN_GROUP_5, /**< GPIO0_PIN9 -> UART1_TXD(MUX3),GPIO0_PIN8 -> UART1_RXD(MUX3)*/ -} dfu_uart_pin_group_t; - -/** @brief DFU informatica status. */ -typedef enum { - DFU_INFO_DISABLE = 0x5775, /**< DFU Config Info Disable. */ - DFU_INFO_ENABLE = 0x7ff7, /**< DFU Config Info Enable. */ - DFU_INFO_DEFAULT = 0x4774, /**< DFU Config Info DEFAULT */ -} dfu_info_state; -/** @} */ - -/** @addtogroup DFU_STRUCTURES Structures - * @{ */ - -/** @brief BootLoader information definition. */ -typedef struct { - uint32_t bin_size; /**< Firmware Size. */ - uint32_t check_sum; /**< Firmware Check Sum Value. */ - uint32_t load_addr; /**< Firmware Load Address. */ - uint32_t run_addr ; /**< Firmware Run Address. */ - uint32_t xqspi_xip_cmd; /**< XIP Read Mode. 0x03: Read mode, 0x0B: Fast Read mode, - 0x3B: DualOut Fast Read mode, - 0xBB: DualIO Fast Read mode, - 0x6B: QuadOut Fast Read mode, - 0xEB: QuadIO Fast Read mode */ - uint32_t xqspi_speed : 4; /**< Bit: 0-3 clock speed. 0 :64 MHz, 1:48 MHz, - 2:32 MHz, 3:24 MHz, 4:16 MHz. */ - uint32_t code_copy_mode : 1; /**< Bit: 4 code copy mode. 0:XIP,1:QSPI. */ - uint32_t system_clk : 3; /**< Bit: 5-7 system clock. 0:64 MHz, 1:48 MHz, 2:32 MHz(xo), - 3:24 MHz, 4:16 MHz, 5:32 MHz(cpll). */ - uint32_t check_image : 1; /**< Bit: 8 check image. */ - uint32_t boot_delay : 1; /**< Bit: Boot delay flag. */ - uint32_t is_dap_boot : 1; /**< Bit: 11 check if boot dap mode. */ - uint32_t reserved : 21; /**< Bit: 24 reserved. */ -} boot_info_t; +/**@brief Image information definition. */ +typedef struct +{ + uint16_t pattern; /**< Image info pattern. */ + uint16_t version; /**< Image version. */ + dfu_boot_info_t boot_info; /**< Image boot info. */ + uint8_t comments[12]; /**< Image comments. */ +} dfu_image_info_t; -/** @brief DFU uart config definition. */ -typedef struct { - dfu_info_state state; /**< DFU UART Enable or Disable. This parameter can be a value of - @ref dfu_info_state. */ - dfu_uart_baudrate_t baud_rate; /**< UART communication baudrate. This parameter can be a value of - @ref dfu_uart_baudrate_t. */ - dfu_uart_data_bit_t data_bit; /**< The number of data bits transmitted or received in a frame. - This parameter can be a value of @ref dfu_uart_data_bit_t. */ - dfu_uart_stop_bit_t stop_bits; /**< The number of stop bits transmitted. - This parameter can be a value of @ref dfu_uart_stop_bit_t. */ - dfu_uart_parity_bit_t parity; /**< Specify the parity mode. This parameter can be a value of - @ref dfu_uart_parity_bit_t. */ - dfu_uart_pin_group_t pin_group; /**< Uart pin group. This parameter can be a value of - @ref dfu_uart_pin_group_t. */ -} dfu_uart_info_t; - -/** @brief DFU Advertisement name config definition. */ -typedef struct { - dfu_info_state state; /**< If a set name is used, this parameter can be a value of - @ref dfu_info_state. */ - uint8_t adv_name[DFU_ADV_MAX_LENGTH]; /**< Adv name data. */ - uint16_t adv_name_length; /**< The length of the name. */ -} dfu_adv_name_info_t; - -/** @brief DFU NVDS init info definition. */ -typedef struct { - dfu_info_state state; /**< If NVDS init is required, this parameter can be a value of - @ref dfu_info_state. */ - uint16_t page_size; /**< NVDS page size. */ - uint32_t start_address; /**< NVDS start address. */ -} dfu_nvds_info_t; - -/** @brief DFU cmd disable info definition. */ -typedef struct { - dfu_info_state state; /**< If DFU cmd disable config is required, this parameter can be a value of - @ref dfu_info_state. */ - uint16_t cmd_bit_map; /**< NVDS start address. */ -} dfu_cmd_disable_t; - - -/** @brief DFU used functions config definition. */ -typedef struct { - /**< The function is used to send data to master by BLE. */ - void (*dfu_ble_send_data)(uint8_t *p_data, uint16_t length); - /**< The function is used to send data to master by UART. */ - void (*dfu_uart_send_data)(uint8_t *p_data, uint16_t length); - /**< The function is used to read data from flash. */ - uint32_t (*dfu_flash_read)(const uint32_t addr, uint8_t *p_buf, const uint32_t size); - /**< The function is used to write data to flash. */ - uint32_t (*dfu_flash_write)(const uint32_t addr, const uint8_t *p_buf, const uint32_t size); - /**< The function is used to erase flash by address. */ - bool (*dfu_flash_erase)(const uint32_t addr, const uint32_t size); - /**< The function is used to erase flash chip. */ - bool (*dfu_flash_erase_chip)(void); - /**< The function is used to set the flash security mode as Enable or Disable. */ - void (*dfu_flash_set_security)(bool enable); - /**< The function is used to get the flash security mode (Enable or Disable). */ - bool (*dfu_flash_get_security)(void); - /**< The function is used to get the flash id and size. */ - void (*dfu_flash_get_info)(uint32_t *id, uint32_t *size); +/**@brief DFU used functions config definition. */ +typedef struct +{ + void (*dfu_ble_send_data)(uint8_t *p_data, uint16_t length); /**< The function is used to send data to master by BLE. */ + void (*dfu_uart_send_data)(uint8_t *p_data, uint16_t length); /**< The function is used to send data to master by UART. */ + uint32_t (*dfu_flash_read)(const uint32_t addr, uint8_t *p_buf, const uint32_t size); /**< The function is used to read data from flash. */ + uint32_t (*dfu_flash_write)(const uint32_t addr, const uint8_t *p_buf, const uint32_t size); /**< The function is used to write data to flash. */ + bool (*dfu_flash_erase)(const uint32_t addr, const uint32_t size); /**< The function is used to erase flash by address. */ + bool (*dfu_flash_erase_chip)(void); /**< The function is used to erase flash chip. */ + void (*dfu_flash_set_security)(bool enable); /**< The function is used to set the flash security mode as Enable or Disable. */ + bool (*dfu_flash_get_security)(void); /**< The function is used to get the flash security mode (Enable or Disable). */ + void (*dfu_flash_get_info)(uint32_t *id, uint32_t *size); /**< The function is used to get the flash id and size. */ } dfu_func_t; -/** @brief SPI used functions config definition. */ -typedef struct { - /**< The function is used to config flash spi. */ - void (*dfu_spi_flash_init)(uint8_t *p_data); - /**< The function is used to read external flash . */ - uint32_t (*dfu_spi_flash_read)(uint32_t addr, uint8_t *buf, uint32_t size); - /**< The function is used to write external flash. */ - uint32_t (*dfu_spi_flash_write)(uint32_t addr, uint8_t *buf, uint32_t size); - /**< The function is used to erase external flash by address. */ - bool (*dfu_spi_flash_erase)(uint32_t addr, uint32_t size); - /**< The function is used to erase exteral flash chip. */ - bool (*dfu_spi_flash_erase_chip)(void); - /**< The function is used to get external flash id and size. */ - void (*dfu_spi_flash_get_info)(uint32_t *id, uint32_t *size); -} dfu_spi_flash_func_t; +/**@brief SPI used functions config definition. */ +typedef struct +{ + void (*dfu_spi_flash_init)(uint8_t *p_data); /**< The function is used to config flash spi. */ + uint32_t (*dfu_spi_flash_read)(uint32_t addr, uint8_t *buf, uint32_t size); /**< The function is used to read external flash . */ + uint32_t (*dfu_spi_flash_write)(uint32_t addr, uint8_t *buf, uint32_t size); /**< The function is used to write external flash. */ + bool (*dfu_spi_flash_erase)(uint32_t addr, uint32_t size); /**< The function is used to erase external flash by address. */ + bool (*dfu_spi_flash_erase_chip)(void); /**< The function is used to erase exteral flash chip. */ + void (*dfu_spi_flash_get_info)(uint32_t *id, uint32_t *size); /**< The function is used to get external flash id and size. */ +}dfu_spi_flash_func_t; -/** @brief DFU program state callback definition. */ -typedef struct { +/**@brief DFU program state callback definition. */ +typedef struct +{ void (*dfu_program_start_callback)(void); /** +#include +#include /** - * @addtogroup GR55XX_FPB_ENUMERATIONS Enumerations + *@addtogroup GR55XX_FPB_ENUMERATIONS Enumerations * @{ */ -/** @brief FPB mode. */ -typedef enum { +/**@brief FPB mode. */ +typedef enum +{ FPB_MODE_PATCH_ONLY = 0, /**< FPB MODE ENABLE FOR PATCH ONLY*/ FPB_MODE_DEBUG_ONLY, /**< FPB MODE ENABLE FOR DEBUG ONLY*/ FPB_MODE_PATCH_AND_DEBUG, /**< FPB MODE ENABLE FOR PATCH AND DEBUG*/ } fpb_mode_t ; -/** @brief FPB state. */ -typedef enum { +/**@brief FPB state. */ +typedef enum +{ FPB_PATCH_OFF = 0, /**< FPB patch disable */ FPB_PATCH_ON, /**< FPB patch enable */ } fpb_state_t; -/** @brief FPB register. */ -typedef struct { - volatile uint32_t CTRL; /**< Offset: 0x000 (R/W) Data */ +/**@brief FPB register. */ +typedef struct +{ + volatile uint32_t CTRL; /**< Offset: 0x000 (R/W) Data */ volatile uint32_t REMAP; /**< Offset: 0x004 (R/W) Data */ volatile uint32_t COMP[8]; /**< Offset: 0x008 (R) Data */ } FPB_REG_TypeDef; @@ -85,7 +90,7 @@ typedef struct { * @defgroup GR55XX_FPB_TYPEDEF Typedefs * @{ */ -/** @brief FPB function.*/ +/**@brief FPB function.*/ typedef void(*fun_t)(void); /** @} */ @@ -93,15 +98,14 @@ typedef void(*fun_t)(void); * @defgroup GR55XX_FPB_FUNCTION Functions * @{ */ -/** -**************************************************************************************** -* @brief Enabling patch function -* @param[in] index_start : Start Index Number -* @param[in] index_end : End Index Number -* @retval : void -**************************************************************************************** -*/ -void fpb_enable(uint8_t index_start, uint8_t index_end); + /** + **************************************************************************************** + * @brief Enabling patch function + * @param[in] index_start : Start Index Number + * @param[in] index_end : End Index Number + **************************************************************************************** + */ +void fpb_enable(uint8_t index_start ,uint8_t index_end); /** **************************************************************************************** @@ -109,81 +113,75 @@ void fpb_enable(uint8_t index_start, uint8_t index_end); * @param[in] ori_func : primitive function address * @param[in] rep_func : replacement function address * @param[in] patch_table_num : group number - * @retval : void + * @return -1: Error Otherwise: Patch table number **************************************************************************************** */ int fun_replace_by_svc(uint32_t ori_func, uint32_t rep_func, uint8_t patch_table_num); -/** -**************************************************************************************** -* @brief SVC handler process function -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief SVC handler process function + * @return 0: Function not found in SVc table, Otherwise: Function address for hardware patching + **************************************************************************************** + */ uint32_t SVC_handler_proc(uint32_t *svc_args); - -/** -**************************************************************************************** -* @brief Register FPB patch enable function -* @param[in] patch_enable_func : pointer of function -* @retval : void -**************************************************************************************** -*/ + + /** + **************************************************************************************** + * @brief Register FPB patch enable function + * @param[in] patch_enable_func : pointer of function + **************************************************************************************** + */ void fpb_register_patch_init_func(fun_t patch_enable_func); -/** -**************************************************************************************** -* @brief FPB init function -* @param[in] fpb_mode : the mode of FPB -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief FPB init function + * @param[in] fpb_mode : the mode of FPB + **************************************************************************************** + */ void fpb_init(fpb_mode_t fpb_mode); -/** -**************************************************************************************** -* @brief svc sub-function register -* @param[in] svc_num : the number of svc -* @param[in] func : sub-function callback -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief svc sub-function register + * @param[in] svc_num : the number of svc + * @param[in] func : sub-function callback + **************************************************************************************** + */ void svc_func_register(uint8_t svc_num, uint32_t func); -/** -**************************************************************************************** -* @brief register sve table function -* @param[in] p_svc_table : the pointer of sve table -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief register sve table function + * @param[in] p_svc_table : the pointer of sve table + **************************************************************************************** + */ void svc_table_register(uint32_t *p_svc_table); /** **************************************************************************************** * @brief register fpb space from user layer * @param[in] user_fpb_space : the pointer of fpb user space - * @retval : void **************************************************************************************** */ void fpb_register_user_space(uint32_t *user_fpb_space); -/** -**************************************************************************************** -* @brief save the FPB state -* -* @retval : FPB state -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief save the FPB state + * + * @returns FPB state ::fpb_state_t + **************************************************************************************** + */ fpb_state_t fpb_save_state(void); -/** -**************************************************************************************** -* @brief load the FPB state -* @param[in] state : the FPB state that needs to be loaded -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief load the FPB state + * @param[in] state : the FPB state that needs to be loaded + **************************************************************************************** + */ void fpb_load_state(fpb_state_t state); /** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_nvds.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_nvds.h old mode 100755 new mode 100644 index 1d95918..3066467 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_nvds.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_nvds.h @@ -39,11 +39,11 @@ * @addtogroup SYSTEM * @{ */ -/** - @addtogroup NVDS Non-Volatile Data Storage - @{ - @brief Definitions and prototypes for the NVDS interface. -*/ + /** + @addtogroup NVDS Non-Volatile Data Storage + @{ + @brief Definitions and prototypes for the NVDS interface. + */ #ifndef __GR55XX_NVDS_H__ #define __GR55XX_NVDS_H__ @@ -55,22 +55,18 @@ * @{ */ #define NV_TAGCAT_APP 0x4000 /**< NVDS tag mask for user application. */ -/** @brief Get NVDS tag for user application. +/**@brief Get NVDS tag for user application. * The values of Tag 0x0000 and 0xFFFF are invalid. idx should not be used * as the parameter of NVDS APIs directly. The range of idx is 0x0001~0x3FFF. */ -static inline uint32_t ble_nv_tag_app(uint32_t idx) -{ - return (NV_TAGCAT_APP | ((idx) & 0x3FFF)); -} - -#define NV_TAG_APP(idx) ble_nv_tag_app(idx) +#define NV_TAG_APP(idx) (NV_TAGCAT_APP | ((idx) & 0x3FFF)) /** @} */ -/** @addtogroup NVDS_ENUMERATIONS Enumerations +/**@addtogroup NVDS_ENUMERATIONS Enumerations * @{ */ -/** @brief NVDS Returned Status. */ -enum NVDS_STATUS { +/**@brief NVDS Returned Status. */ +enum NVDS_STATUS +{ NVDS_SUCCESS, /**< NVDS succeeds. */ NVDS_FAIL, /**< NVDS failed. */ NVDS_TAG_NOT_EXISTED, /**< NVDS tag does not exist. */ @@ -80,17 +76,17 @@ enum NVDS_STATUS { NVDS_INVALID_START_ADDR, /**< NVDS invalid start address. */ NVDS_INVALID_SECTORS, /**< NVDS invalid sector. */ NVDS_COMPACT_FAILED, /**< NVDS failed to compact sectors. */ - NVDS_STORAGE_ACCESS_FAILED, /**< NVDS failed to access storage. */ + NVDS_STORAGE_ACCESS_FAILED , /**< NVDS failed to access storage. */ NVDS_GC_COMPLETE, /**< NVDS garbage collection complete. */ NVDS_NOT_INIT, /**< NVDS not initialize. */ NVDS_POINTER_NULL /**< NVDS or driver function repalce error: NULL. */ }; /** @} */ -/** @addtogroup NVDS_STRUCTURES Structures +/**@addtogroup NVDS_STRUCTURES Structures * @{ */ -/** @brief NVDS Item tag. */ -typedef unsigned short NvdsTag_t; +/**@brief NVDS Item tag. */ +typedef uint16_t NvdsTag_t; /** @} */ /** @addtogroup NVDS_FUNCTIONS Functions @@ -113,6 +109,24 @@ typedef unsigned short NvdsTag_t; */ uint8_t nvds_init(uint32_t start_addr, uint8_t sectors); +/** @addtogroup NVDS_FUNCTIONS Functions + * @{ */ +/** + **************************************************************************************** + * @brief De-initialize the sectors for NVDS. + * + * @note nvds_deinit will erase the flash sectors. + * + * @param[in] start_addr: Start address of NVDS area. If the value does not equal zero, + it must be sector-aligned. If the value equals zero, + NVDS area will locate in the last sector(s) in flash memory. + * @param[in] sectors: The number of sectors. + * + * @return Result of nvds deinit. + **************************************************************************************** + */ +uint8_t nvds_deinit(uint32_t start_addr, uint8_t sectors); + /** **************************************************************************************** * @brief Read data from NVDS. @@ -132,7 +146,7 @@ uint8_t nvds_get(NvdsTag_t tag, uint16_t *p_len, uint8_t *p_buf); * @brief Write data to NVDS. If the tag does not exist, create one. * * @param[in] tag: Valid NVDS item tag. - * @param[in] len: Length of data to be written. + * @param[in] len: Length of data to be written, the max length of data is 1024 bytes. * @param[in] p_buf: Data to be written. * * @return ::NVDS_SUCCESS: if successful. @@ -168,7 +182,7 @@ uint16_t nvds_tag_length(NvdsTag_t tag); /** @addtogroup LOCAL_FLASH_FUNCTIONS Local Flash Functions * @{ */ -/** @brief Flash operation API based on hal flash.*/ +/**@brief Flash operation API based on hal flash.*/ /** **************************************************************************************** * @brief Erase flash chip. @@ -257,7 +271,7 @@ void local_hal_flash_set_security(bool enable); /** ******************************************************************************* - * @brief Write flash Memory reliably. + * @brief Write flash Memory reliably. * * @note It's possible that the data was not written into Flash Memory * successfully. This function reads the data from Flash Memory to check diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_pwr.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_pwr.h old mode 100755 new mode 100644 index 840f5d0..54bbed1 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_pwr.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_pwr.h @@ -39,7 +39,7 @@ * @addtogroup SYSTEM * @{ */ - + /** * @addtogroup PWR Power Manager * @{ @@ -61,108 +61,114 @@ * @{ */ -/** @brief power manager setting parameter. - * Use pwr_mgmt_var_set to transfer the parameters in the structure to PMU, +/**@brief power manager setting parameter. + * Use pwr_mgmt_var_set to transfer the parameters in the structure to PMU, * and then the pwr_mgmt_mode_set function will use the new parameters for * power management. - * Note that this is an advanced API, the wrong setting of parameters may + * Note that this is an advanced API, the wrong setting of parameters may * lead to abnormal power management, so please use it carefully. */ -typedef struct { +typedef struct +{ uint32_t pwr_mgmt_app_timer_thrd; /**< App timer threshold. */ uint32_t pwr_mgmt_ble_core_thrd; /**< BLE timer threshold. */ uint32_t pwr_mgmt_rtc_timer_thrd; /**< RTC timer threshold. */ } pwr_mgmt_var_box_t; -/** @brief power manager boot type. */ -typedef enum { +/**@brief power manager boot type. */ +typedef enum +{ COLD_BOOT = 0, /**< Cold boot state. */ WARM_BOOT, /**< Warm boot state. */ } boot_mode_t; -/** @brief power manager model. */ -typedef enum { +/**@brief power manager model. */ +typedef enum +{ PMR_MGMT_ACTIVE_MODE = 0x0, /**< Full speed state. */ PMR_MGMT_IDLE_MODE, /**< Idle state. */ PMR_MGMT_SLEEP_MODE, /**< Deep sleep state. */ } pwr_mgmt_mode_t; -/** @brief power manager device work state. */ -typedef enum { +/**@brief power manager device work state. */ +typedef enum +{ DEVICE_BUSY = 0x0, /**< Device busy state. */ DEVICE_IDLE, /**< Device idle state. */ } pwr_mgmt_dev_state_t; -/** @brief power manager app timer work state. */ -typedef enum { +/**@brief power manager app timer work state. */ +typedef enum +{ EVENT_APP_TIMER_START = 0, /**< App-timer start state. */ EVENT_APP_TIMER_STOP, /**< App-timer stop state. */ } notify_timer_event_t; -/** @brief PMU Tracking*/ -enum { - TRC_PWR_WFE_MODE = 0, /**< WFE mode. */ - TRC_PWR_DSLEEP_MODE, /**< Deep sleep mode. */ - TRC_PWR_ACTIVE_MODE, /**< Active mode. */ - TRC_PWR_BLE_RET_DSLEEP, /**< BLE return deep sleep. */ - TRC_PWR_APP_TIMER_REFUSE, /**< App timer refuse. */ - TRC_PWR_APP_TIMER_PASS, /**< App timer pass. */ - TRC_PWR_BLE_TIMER_PASS, /**< BLE timer pass. */ +/**@brief PMU Tracking*/ +enum +{ + TRC_PWR_WFE_MODE = 0, /**< WFE mode. */ + TRC_PWR_DSLEEP_MODE, /**< Deep sleep mode. */ + TRC_PWR_ACTIVE_MODE, /**< Active mode. */ + TRC_PWR_BLE_RET_DSLEEP, /**< BLE return deep sleep. */ + TRC_PWR_APP_TIMER_REFUSE, /**< App timer refuse. */ + TRC_PWR_APP_TIMER_PASS, /**< App timer pass. */ + TRC_PWR_BLE_TIMER_PASS, /**< BLE timer pass. */ }; -/** @brief parameter configuration table. */ -typedef struct { - uint16_t pwr_dur; /**< Duration. */ - uint16_t pwr_ext; /**< External wake-up. */ - uint16_t pwr_osc; /**< OSC. */ - uint8_t pwr_delay_hslot; /**< Delay half slot. */ - uint16_t pwr_delay_hus; /**< Delay half us. */ - uint16_t pwr_push_hus; /**< Push half us. */ - uint32_t pwr_timer_ths; /**< APP timer threshold. */ - uint32_t pwr_ble_ths; /**< BLE timer threshold. */ -} pwr_table_t; +/**@brief parameter configuration table. */ +typedef struct +{ + uint16_t pwr_dur; /**< Duration. */ + uint16_t pwr_ext; /**< External wake-up. */ + uint16_t pwr_osc; /**< OSC. */ + uint8_t pwr_delay_hslot; /**< Delay half slot. */ + uint16_t pwr_delay_hus; /**< Delay half us. */ + uint16_t pwr_push_hus; /**< Push half us. */ + uint32_t pwr_timer_ths; /**< APP timer threshold. */ + uint32_t pwr_ble_ths; /**< BLE timer threshold. */ +} pwr_table_t; -/** @brief Trace function type. */ +/**@brief Trace function type. */ typedef void (*trace_func_t)(uint8_t); -/** @brief Peripheral function type. */ +/**@brief Peripheral function type. */ typedef void (*periph_func_t)(void); -/** @brief Before sleep function type. */ +/**@brief Before sleep function type. */ typedef void (*pwr_before_sleep_func_t)(void); -/** @brief Device check function type. */ +/**@brief Device check function type. */ typedef pwr_mgmt_dev_state_t (*pwr_dev_check_func_t)(void); -/** @brief function registered to dump io configuration. */ +/**@brief function registered to dump io configuration. */ typedef void (*io_dump_func_t)(void); -/** @brief mem check process type. */ +/**@brief mem check process type. */ typedef void (*mem_check_proc_t)(void); -/** @brief pwr table. */ -#define MAX_PWR_TABLE_LEN 12 -extern pwr_table_t pwr_table[MAX_PWR_TABLE_LEN]; - +/**@brief pwr table. */ +extern pwr_table_t pwr_table[]; + /** @} */ /** @addtogroup GR55XX_PWR_FUNCTIONS Functions * @{ */ /** ***************************************************************************************** - * @brief This function allows ARM to enter deep sleep mode, but users should not use this + * @brief This function allows ARM to enter deep sleep mode, but users should not use this * function directly. - * Note that this function is only available in environments where non-RTOS is used, + * Note that this function is only available in environments where non-RTOS is used, * and that users can only execute it while in main.c. - * @retval : pwr_mgmt_mode_t + * @return Power Management Mode :: pwr_mgmt_mode_t ***************************************************************************************** */ pwr_mgmt_mode_t pwr_mgmt_shutdown(void); /** **************************************************************************************** - * @brief Get the current boot mode. - * @retval : cold boot or warm boot. + * @brief Get the current boot mode. + * @return Boot Mode ::boot_mode_t **************************************************************************************** */ boot_mode_t pwr_mgmt_get_wakeup_flag(void); @@ -171,7 +177,6 @@ boot_mode_t pwr_mgmt_get_wakeup_flag(void); **************************************************************************************** * @brief Mark the mode of next boot, cold boot or warm boot. * @param[in] boot_mode : cold boot or warm boot. - * @retval : void **************************************************************************************** */ void pwr_mgmt_set_wakeup_flag(boot_mode_t boot_mode); @@ -179,45 +184,45 @@ void pwr_mgmt_set_wakeup_flag(boot_mode_t boot_mode); /** **************************************************************************************** * @brief Set the specified sleep mode. When the setting is completed, the system will - * automatically enter the specified sleep mode through the strategy. + * automatically enter the specified sleep mode through the strategy. * @param[in] pm_mode : sleep level - * @retval : void **************************************************************************************** */ void pwr_mgmt_mode_set(pwr_mgmt_mode_t pm_mode); /** **************************************************************************************** - * @brief Get the specified sleep mode. - * @retval : pwr_mgmt_mode_t + * @brief Get the specified sleep mode. + * @return Power Management Mode :: pwr_mgmt_mode_t **************************************************************************************** */ pwr_mgmt_mode_t pwr_mgmt_mode_get(void); /** **************************************************************************************** - * @brief Get the power state of baseband. - * @retval : pwr_mgmt_mode_t + * @brief Get the power state of baseband. + * @return Power Management Mode :: pwr_mgmt_mode_t **************************************************************************************** */ pwr_mgmt_mode_t pwr_mgmt_baseband_state_get(void); /** **************************************************************************************** - * @brief Get the state of extenal timer. - * @retval : pwr_mgmt_mode_t + * @brief Get the state of extenal timer. + * @return Power Management Mode :: pwr_mgmt_mode_t **************************************************************************************** */ pwr_mgmt_mode_t pwr_mgmt_check_ext_timer(void); + + /** **************************************************************************************** * @brief Sleep Policy Scheduling Function. * Note that: - * 1. This function shall only be used in non-RTOS environments; + * 1. This function shall only be used in non-RTOS environments; * 2. This function shall only be used in main function; * 3. Local variables shall not be used in main function when this api used. - * @retval : void **************************************************************************************** */ void pwr_mgmt_schedule(void); @@ -225,12 +230,10 @@ void pwr_mgmt_schedule(void); /** **************************************************************************************** * @brief Wake the BLE core via an external request. - * @return status - * @retval The status of the requested operation. - * - * false, if the BLE core is not sleeping. - * true, if the BLE core was woken up successfully. - * + * @return The status of the requested operation. + * @retval False The BLE core is not sleeping. + * @retval True The BLE core was woken up successfully. + * **************************************************************************************** */ bool pwr_mgmt_ble_wakeup(void); @@ -239,18 +242,17 @@ bool pwr_mgmt_ble_wakeup(void); /** **************************************************************************************** * @brief Check whether there are ble events in the queue, and if so, handle them immediately. - * @retval : void **************************************************************************************** */ void pwr_mgmt_check_ble_event(void); + /** **************************************************************************************** - * @brief This function is used to push startup information in app timer. - * This information will optimize power management strategy. + * @brief This function is used to push startup information in app timer. + * This information will optimize power management strategy. * Note that this function is an advanced API and users should not use it directly. * @param[in] timer_event : EVENT_APP_TIMER_START or EVENT_APP_TIMER_STOP - * @retval : void **************************************************************************************** */ void pwr_mgmt_notify_timer_event(notify_timer_event_t timer_event); @@ -258,36 +260,34 @@ void pwr_mgmt_notify_timer_event(notify_timer_event_t timer_event); /** **************************************************************************************** * @brief Query the sleep mode that the current system can access. - * @retval : void + * @return Power Management Mode :: pwr_mgmt_mode_t **************************************************************************************** */ pwr_mgmt_mode_t pwr_mgmt_get_sleep_mode(void); + /** **************************************************************************************** * @brief Update wakeup param. - * @retval : void **************************************************************************************** */ void pwr_mgmt_update_wkup_param(void); /** **************************************************************************************** - * @brief Execution of this function allows ARM to enter the WFE state and exit the WFE + * @brief Execution of this function allows ARM to enter the WFE state and exit the WFE * state when an event or interrupt occurs. - * @retval : void **************************************************************************************** */ void pwr_mgmt_wfe_sleep(void); /** **************************************************************************************** - * @brief Execution of this function allows ARM to enter the ultra sleep state and wakeup + * @brief Execution of this function allows ARM to enter the ultra sleep state and wakeup * the chip when an event occurs. * @param time_ms : Specifies the wake-up time during ultra sleep. If time_ms is equal to 0, then sleep timer will not be enabled. This parameter must be a number between min_value = 0 and max_value = 131071 - * @retval : void **************************************************************************************** */ void pwr_mgmt_ultra_sleep(uint32_t time_ms); @@ -297,16 +297,14 @@ void pwr_mgmt_ultra_sleep(uint32_t time_ms); * @brief PMU Initialization Function. * @param p_pwr_table : PMU parameter configuration table. * @param sys_clk : the clock of system - * @return void **************************************************************************************** */ -void pwr_mgmt_init(pwr_table_t *p_pwr_table, mcu_clock_type_t sys_clk); +void pwr_mgmt_init( pwr_table_t *p_pwr_table, mcu_clock_type_t sys_clk); /** **************************************************************************************** * @brief Peripheral Controller Initialization Register interface. * @param p_periph_init : the pointer of device init function. - * @return void **************************************************************************************** */ void pwr_mgmt_dev_init(periph_func_t p_periph_init); @@ -314,7 +312,6 @@ void pwr_mgmt_dev_init(periph_func_t p_periph_init); /** **************************************************************************************** * @brief Device config resume interface. - * @return void **************************************************************************************** */ void pwr_mgmt_dev_resume(void); @@ -322,7 +319,7 @@ void pwr_mgmt_dev_resume(void); /** **************************************************************************************** * @brief Device config suspend interface. - * @return void + * @return Power Management Device state ::pwr_mgmt_dev_state_t **************************************************************************************** */ pwr_mgmt_dev_state_t pwr_mgmt_dev_suspend(void); @@ -332,7 +329,6 @@ pwr_mgmt_dev_state_t pwr_mgmt_dev_suspend(void); * @brief Mem state control under deep sleep & work state. * @param mem_sleep_state : control in deep sleep. * @param mem_work_state : control in work state. - * @return void **************************************************************************************** */ void pwr_mgmt_mem_ctl_set(uint32_t mem_sleep_state, uint32_t mem_work_state); @@ -342,69 +338,62 @@ void pwr_mgmt_mem_ctl_set(uint32_t mem_sleep_state, uint32_t mem_work_state); * @brief Set PMU callback function. * @param dev_check_fun : Device check callback function. * @param before_sleep_fun : Pre-execution callback function for deep sleep. - * @return void **************************************************************************************** */ void pwr_mgmt_set_callback(pwr_dev_check_func_t dev_check_fun, pwr_before_sleep_func_t before_sleep_fun); -/** -**************************************************************************************** -* @brief Set the wakeup source. -* @param[in] wakeup_source : -* PWR_WKUP_COND_EXT -* PWR_WKUP_COND_TIMER -* PWR_WKUP_COND_BLE -* PWR_WKUP_COND_CALENDAR -* PWR_WKUP_COND_BOD_FEDGE -* PWR_WKUP_COND_MSIO_COMP -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief Set the wakeup source. + * @param[in] wakeup_source : + * PWR_WKUP_COND_EXT + * PWR_WKUP_COND_TIMER + * PWR_WKUP_COND_BLE + * PWR_WKUP_COND_CALENDAR + * PWR_WKUP_COND_BOD_FEDGE + * PWR_WKUP_COND_MSIO_COMP + **************************************************************************************** + */ void pwr_mgmt_wakeup_source_setup(uint32_t wakeup_source); -/** -**************************************************************************************** -* @brief Clear the wakeup source. -* @param[in] wakeup_source : -* PWR_WKUP_COND_EXT -* PWR_WKUP_COND_TIMER -* PWR_WKUP_COND_BLE -* PWR_WKUP_COND_CALENDAR -* PWR_WKUP_COND_BOD_FEDGE -* PWR_WKUP_COND_MSIO_COMP -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief Clear the wakeup source. + * @param[in] wakeup_source : + * PWR_WKUP_COND_EXT + * PWR_WKUP_COND_TIMER + * PWR_WKUP_COND_BLE + * PWR_WKUP_COND_CALENDAR + * PWR_WKUP_COND_BOD_FEDGE + * PWR_WKUP_COND_MSIO_COMP + **************************************************************************************** + */ void pwr_mgmt_wakeup_source_clear(uint32_t wakeup_source); -/** -**************************************************************************************** -* @brief Save context function. -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief Save context function. + **************************************************************************************** + */ void pwr_mgmt_save_context(void); -/** -**************************************************************************************** -* @brief Load context function. -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief Load context function. + **************************************************************************************** + */ void pwr_mgmt_load_context(void); -/** -**************************************************************************************** -* @brief Disable nvic irq. -* @retval : void -**************************************************************************************** -*/ + /** + **************************************************************************************** + * @brief Disable nvic irq. + **************************************************************************************** + */ void pwr_mgmt_disable_nvic_irq(void); /** **************************************************************************************** * @brief Enable nvic irq. - * @retval : void **************************************************************************************** */ void pwr_mgmt_enable_nvic_irq(void); @@ -412,7 +401,6 @@ void pwr_mgmt_enable_nvic_irq(void); /** **************************************************************************************** * @brief Check nvic irq. - * @retval : void **************************************************************************************** */ bool pwr_mgmt_check_pend_irq(void); @@ -420,8 +408,7 @@ bool pwr_mgmt_check_pend_irq(void); /** **************************************************************************************** * @brief Trace function register. - * @param[in] trace_func: Trace function. - * @retval : void + * @param[in] trace_func: Trace function. **************************************************************************************** */ void pwr_mgmt_register_trace_func(trace_func_t trace_func); @@ -429,7 +416,7 @@ void pwr_mgmt_register_trace_func(trace_func_t trace_func); /** **************************************************************************************** * @brief function registered to dump io configuration. - * @retval : void + * @param[in] dump_func Pointer to IO configuration dump function **************************************************************************************** */ void pwr_mgmt_register_io_dump_func(io_dump_func_t dump_func); diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys.h old mode 100755 new mode 100644 index adabee8..41e0851 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys.h @@ -46,11 +46,14 @@ * @brief Definitions and prototypes for the system SDK interface. */ + + #ifndef __GR55XX_SYS_H__ #define __GR55XX_SYS_H__ #include "gr55xx_sys_cfg.h" #include "gr55xx_nvds.h" +#include "gr55xx_dfu.h" #include "gr55xx_pwr.h" #include "gr55xx_fpb.h" #include "ble.h" @@ -63,94 +66,95 @@ /** @addtogroup GR55XX_SYS_DEFINES Defines * @{ */ -#define SYS_INVALID_TIMER_ID 0xFF /**< Invalid system Timer ID. */ -#define SYS_BD_ADDR_LEN GAP_ADDR_LEN /**< Length of Bluetoth Device Address. */ -#define SYS_CHIP_UID_LEN 0x10 /**< Length of Bluetoth Chip UID. */ - -static inline uint8_t ble_sys_set_bd_addr(uint8_t *BD_ADDR_ARRAY) -{ - return nvds_put(0xC001, SYS_BD_ADDR_LEN, BD_ADDR_ARRAY); -} - -#define SYS_SET_BD_ADDR(BD_ADDR_ARRAY) ble_sys_set_bd_addr(BD_ADDR_ARRAY) /**< NVDS put BD address. */ +#define SYS_INVALID_TIMER_ID 0xFF /**< Invalid system Timer ID. */ +#define SYS_BD_ADDR_LEN BLE_GAP_ADDR_LEN /**< Length of Bluetoth Device Address. */ +#define SYS_CHIP_UID_LEN 0x10 /**< Length of Bluetoth Chip UID. */ +#define SYS_SET_BD_ADDR(BD_ADDR_ARRAY) nvds_put(0xC001, SYS_BD_ADDR_LEN, BD_ADDR_ARRAY) /**< NVDS put BD address. */ +#define SYS_ROM_VERSION_ADDR 0x45000 /**< The rom version address. */ /** @} */ /** * @defgroup GR55XX_SYS_TYPEDEF Typedefs * @{ */ -/** @brief The function pointers to register event callback. */ +/**@brief The function pointers to register event callback. */ typedef void (*callback_t)(int); /** @brief Timer callback type. */ typedef void (*timer_callback_t)(uint8_t timer_id); -/** @brief Printf callback type. */ +/**@brief Printf callback type. */ typedef int (*vprintf_callback_t) (const char *fmt, va_list argp); -/** @brief Low power clock update function type. */ +/**@brief Low power clock update function type. */ typedef void (*void_func_t)(void); -/** @brief Low power clock update function type with resturn. */ +/**@brief Low power clock update function type with resturn. */ typedef int (*int_func_t)(void); -/** @brief Function type for saving user context before deep sleep. */ +/**@brief Function type for saving user context before deep sleep. */ typedef void (*sys_context_func_t)(void); -/** @brief Error assert callback type. */ +/**@brief Error assert callback type. */ typedef void (*assert_err_cb_t)(const char *expr, const char *file, int line); -/** @brief Parameter assert callback type. */ +/**@brief Parameter assert callback type. */ typedef void (*assert_param_cb_t)(int param0, int param1, const char *file, int line); -/** @brief Warning assert callback type. */ +/**@brief Warning assert callback type. */ typedef void (*assert_warn_cb_t)(int param0, int param1, const char *file, int line); /** @} */ /** @addtogroup GR55XX_SYS_ENUMERATIONS Enumerations * @{ */ -/** @brief Definition of Device SRAM Size Enumerations. */ -typedef enum { +/**@brief Definition of Device SRAM Size Enumerations. */ +typedef enum +{ SYS_DEV_SRAM_64K = 0x02, /**< Supported 64K SRAM. */ SYS_DEV_SRAM_128K = 0x01, /**< Supported 128K SRAM. */ SYS_DEV_SRAM_256K = 0x00, /**< Supported 256K SRAM. */ } sram_size_t; -/** @brief package type. */ -typedef enum { +/**@brief package type. */ +typedef enum +{ PACKAGE_NONE = 0, /**< Package unused. */ PACKAGE_GR5515RGBD = 1, /**< BGA68 package. */ PACKAGE_GR5515GGBD = 2, /**< BGA55 package. */ - PACKAGE_GR5515IGND = 3, /**< QFN56 + 1024K flash package. */ - PACKAGE_GR5515I0ND = 4, /**< QFN56 + no flash package, support external high voltage flash only */ + PACKAGE_GR5515IGND = 3, /**< QFN56 + 1024KB flash package. */ + PACKAGE_GR5515I0ND = 4, /**< QFN56 + no flash package, support external high voltage flash only*/ PACKAGE_GR5513BEND = 5, /**< QFN40 + 128KB RAM + 512KB flash packet. */ PACKAGE_GR5515BEND = 6, /**< QFN40 + 256KB RAM + 512KB flash packet. */ - PACKAGE_GR5513BENDU = 7, /**< QFN40 + 256KB RAM + 512KB flash packet @1.7V ~ 3.6V. */ + PACKAGE_GR5513BENDU = 7, /**< QFN40 + 128KB RAM + 512KB flash packet @1.7V ~ 3.6V. */ PACKAGE_GR5515I0NDA = 8, /**< QFN56 + no flash package, support external high/low voltage flash */ + PACKAGE_GR5515IENDU = 9, /**< QFN56 + 512KB flash package */ } package_type_t; /** @} */ /** @addtogroup GR55XX_SYS_STRUCTURES Structures * @{ */ -/** @brief SDK version definition. */ -typedef struct { +/**@brief SDK version definition. */ +typedef struct +{ uint8_t major; /**< Major version. */ uint8_t minor; /**< Minor version. */ uint16_t build; /**< Build number. */ uint32_t commit_id; /**< commit ID. */ -} sdk_version_t; +}sdk_version_t; -/** @brief Assert callbacks.*/ -typedef struct { +/**@brief Assert callbacks.*/ +typedef struct +{ assert_err_cb_t assert_err_cb; /**< Assert error type callback. */ assert_param_cb_t assert_param_cb; /**< Assert parameter error type callback. */ assert_warn_cb_t assert_warn_cb; /**< Assert warning type callback. */ -} sys_assert_cb_t; +}sys_assert_cb_t; -/** @brief Link RX information definition. */ -typedef struct { +/**@brief Link RX information definition. */ +typedef struct +{ uint32_t rx_total_cnt; /**< Counts of RX times. */ uint32_t rx_sync_err_cnt; /**< Counts of RX sync error times. */ uint32_t rx_crc_err_cnt; /**< Counts of RX crc error times. */ @@ -160,34 +164,37 @@ typedef struct { uint32_t rx_normal_cnt; /**< Counts of RX normal times. */ } link_rx_info_t; -/** @brief RF trim parameter information definition. */ -typedef struct { +/**@brief RF trim parameter information definition. */ +typedef struct +{ int8_t rssi_cali; /**< RSSI calibration. */ int8_t tx_power; /**< TX power. */ } rf_trim_info_t; -/** @brief ADC trim parameter information definition. */ -typedef struct { - uint16_t adc_temp; /** < ADC TEMP. */ - uint16_t slope_int_0p8; /** < Internal reference 0.8v. */ - uint16_t offset_int_0p8; /** < Internal reference 0.8v. */ - uint16_t slope_int_1p2; /** < Internal reference 1.2v. */ - uint16_t offset_int_1p2; /** < Internal reference 1.2v. */ - uint16_t slope_int_1p6; /** < Internal reference 1.6v. */ - uint16_t offset_int_1p6; /** < Internal reference 1.6v. */ - uint16_t slope_int_2p0; /** < Internal reference 2.0v. */ - uint16_t offset_int_2p0; /** < Internal reference 2.0v. */ - uint16_t slope_ext_1p0; /** < External reference 1.0v. */ - uint16_t offset_ext_1p0; /** < External reference 1.0v. */ +/**@brief ADC trim parameter information definition. */ +typedef struct +{ + uint16_t adc_temp; /**< ADC TEMP. */ + uint16_t slope_int_0p8; /**< Internal reference 0.8v. */ + uint16_t offset_int_0p8; /**< Internal reference 0.8v. */ + uint16_t slope_int_1p2; /**< Internal reference 1.2v. */ + uint16_t offset_int_1p2; /**< Internal reference 1.2v. */ + uint16_t slope_int_1p6; /**< Internal reference 1.6v. */ + uint16_t offset_int_1p6; /**< Internal reference 1.6v. */ + uint16_t slope_int_2p0; /**< Internal reference 2.0v. */ + uint16_t offset_int_2p0; /**< Internal reference 2.0v. */ + uint16_t slope_ext_1p0; /**< External reference 1.0v. */ + uint16_t offset_ext_1p0; /**< External reference 1.0v. */ } adc_trim_info_t; -/** @brief PMU trim parameter information definition. */ -typedef struct { - uint8_t io_ldo_bypass; /** < IO LDO bypass */ - uint8_t io_ldo_vout; /** < IO LDO Vout. */ - uint8_t dig_ldo_64m; /** < DIG LDO 64m. */ - uint8_t dig_ldo_16m; /** < DIG LDO 16m */ - uint8_t dcdc_vout; /** < DCDC Vout */ +/**@brief PMU trim parameter information definition. */ +typedef struct +{ + uint8_t io_ldo_bypass; /**< IO LDO bypass */ + uint8_t io_ldo_vout; /**< IO LDO Vout. */ + uint8_t dig_ldo_64m; /**< DIG LDO 64m. */ + uint8_t dig_ldo_16m; /**< DIG LDO 16m */ + uint8_t dcdc_vout; /**< DCDC Vout */ } pmu_trim_info_t; /** @} */ @@ -240,7 +247,7 @@ void *sys_malloc(uint32_t size); * @param[in] p_mem: Pointer to memory block. ***************************************************************************************** */ -void sys_free(uint8_t *p_mem); +void sys_free(void *p_mem); /** ***************************************************************************************** @@ -376,12 +383,28 @@ uint16_t sys_crystal_trim_get(uint16_t *p_crystal_trim); /** ***************************************************************************************** - * @brief Jump to firmware and run. + * @brief app boot project turn on the encrypt clock. * - * @param[in] fw_addr: Firmware run address. ***************************************************************************************** */ -void sys_firmware_jump(uint32_t fw_addr); +void app_boot_turn_on_encrypt_clock(void); + +/** + ***************************************************************************************** + * @brief app boot project set the security clock. + * + ***************************************************************************************** + */ +void app_boot_security_clock_set(void); + +/** + ***************************************************************************************** + * @brief jump to app firmware. 69 + * + * @param[in] p_boot_info: Firmware system firmware information 71 + ***************************************************************************************** + */ +void sys_firmware_jump(dfu_boot_info_t *p_boot_info); /** ***************************************************************************************** @@ -449,9 +472,6 @@ uint16_t sys_device_sram_get(sram_size_t *p_sram_size); */ uint16_t sys_device_package_get(package_type_t *p_package_type); - -#if defined(GR5515_D) - /** ***************************************************************************************** * @brief Get the chip's IO LDO voltage. @@ -465,8 +485,6 @@ uint16_t sys_device_package_get(package_type_t *p_package_type); */ uint16_t sys_get_efuse_io_ldo(uint16_t *io_ldo); -#endif - /** ***************************************************************************************** * @brief Set low power CLK frequency. @@ -478,12 +496,12 @@ void sys_lpclk_set(uint32_t user_lpclk); /** **************************************************************************************** - * @brief Convert a duration in μs into a duration in lp cycles. + * @brief Convert a duration in us into a duration in lp cycles. * - * The function converts a duration in μs into a duration in lp cycles, according to the + * The function converts a duration in us into a duration in lp cycles, according to the * low power clock frequency (32768Hz or 32000Hz). * - * @param[in] us: Duration in μs. + * @param[in] us: Duration in us. * * @return Duration in lpcycles. **************************************************************************************** @@ -492,41 +510,50 @@ uint32_t sys_us_2_lpcycles(uint32_t us); /** **************************************************************************************** - * @brief Convert a duration in lp cycles into a duration in half μs. + * @brief Convert a duration in lp cycles into a duration in half us. * - * The function converts a duration in lp cycles into a duration in half μs, according to the + * The function converts a duration in lp cycles into a duration in half us, according to the * low power clock frequency (32768Hz or 32000Hz). * @param[in] lpcycles: Duration in lp cycles. - * @param[in,out] error_corr: Insert and retrieve error created by truncating the LP Cycle - * Time to a half μs (in half μs). + * @param[in,out] error_corr: Insert and retrieve error created by truncating the LP Cycle Time to a half us (in half us). * - * @return Duration in half μs + * @return Duration in half us **************************************************************************************** */ uint32_t sys_lpcycles_2_hus(uint32_t lpcycles, uint32_t *error_corr); +/** + ***************************************************************************************** + * @brief Reverse the policy for static address created by chip uuid . + * @note After sdk_v1.6.10, this policy has been updated. + * + ***************************************************************************************** + */ +void sys_ble_static_addr_policy_reverse(void); + /** ***************************************************************************************** * @brief Set BLE Sleep HeartBeat Period. * @note The BLE Sleep HeartBeat Period is used to Wakeup BLE Periodically when BLE is IDLE. * * @param[in] period_hus: The wake up duration of BLE when BLE is IDEL. - * Range 0x00000000-0xFFFFFFFF (in unit of μs). - * - * @retval SDK_SUCCESS: Operation is Success. + * Range 0x00000000-0xFFFFFFFF (in unit of us). + * + * @retval ::SDK_SUCCESS Operation is Success. ***************************************************************************************** */ uint16_t sys_ble_heartbeat_period_set(uint32_t period_hus); + /** ***************************************************************************************** * @brief Get BLE Sleep HeartBeat Period. * @note The BLE Sleep HeartBeat Period is used to Wakeup BLE Periodically when BLE is IDLE. * * @param[in] p_period_hus: Pointer to the wake up duration. - * Range 0x00000000-0xFFFFFFFF (in unit of μs). - * - * @retval SDK_SUCCESS: Operation is Success. + * Range 0x00000000-0xFFFFFFFF (in unit of us). + * + * @retval ::SDK_SUCCESS Operation is Success. ***************************************************************************************** */ uint16_t sys_ble_heartbeat_period_get(uint32_t* p_period_hus); @@ -700,7 +727,6 @@ void sys_swd_disable(void); /** **************************************************************************************** * @brief RTC calibration function. - * @retval : void **************************************************************************************** */ void rtc_calibration(void); @@ -709,7 +735,6 @@ void rtc_calibration(void); **************************************************************************************** * @brief RNG calibration function. * @note The function will call between platform_init_push and platform_init_pop. - * @retval : void **************************************************************************************** */ void rng_calibration(void); @@ -717,7 +742,7 @@ void rng_calibration(void); /** **************************************************************************************** * @brief Reverse byte order (32 bit). For example, 0x12345678 becomes 0x78563412. - * @retval : Reversed value + * @return Byte Reversed value **************************************************************************************** */ uint32_t sys_reverse_word(uint32_t value); @@ -725,7 +750,7 @@ uint32_t sys_reverse_word(uint32_t value); /** **************************************************************************************** * @brief Reverse byte order (16 bit). For example, 0x1234 becomes 0x3412. - * @retval : Reversed value + * @return Byte Reversed value **************************************************************************************** */ uint16_t sys_reverse_hword(uint16_t value); diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys_cfg.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys_cfg.h old mode 100755 new mode 100644 index 54ece0b..8fac421 --- a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys_cfg.h +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr55xx_sys_cfg.h @@ -35,17 +35,17 @@ ***************************************************************************************** */ -/** -* @addtogroup SYSTEM -* @{ -*/ - + /** + * @addtogroup SYSTEM + * @{ + */ + /** * @addtogroup SYS_CFG System Configuration * @{ * @brief Definitions and prototypes for SYS_CFG interface. */ - + #ifndef __GR55XX_SYS_CFG_H__ #define __GR55XX_SYS_CFG_H__ @@ -54,31 +54,33 @@ /** @addtogroup GR55XX_SYS_CFG_DEFINES Defines * @{ */ -#define ARRAY_EMPTY /** < Empty Array. */ +#define __ARRAY_EMPTY /**< Empty Array. */ /** @} */ /** * @defgroup GR55XX_SYS_CFG_STRUCT Structures * @{ */ -/** @brief BLE Sleep configure defination. */ -typedef struct { +/**@brief BLE Sleep configure defination. */ +typedef struct +{ uint8_t sleep_enable; /**< Sleep enable flag. */ uint8_t ext_wakeup_enable; /**< External wake-up support. */ uint16_t twosc; /**< Twosc delay. */ uint16_t twext; /**< Twext delay. */ uint16_t twrm; /**< Twrm delay. */ - uint16_t sleep_algo_dur; /**< Duration of sleep and wake-up algorithm - (depends on CPU speed) expressed in half us.. */ + uint16_t sleep_algo_dur; /**< Duration of sleep and wake-up algorithm (depends on CPU speed) expressed in half us.. */ } ble_slp_config_t ; -/** @brief BLE Scheduler configure defination. */ -typedef struct { +/**@brief BLE Scheduler configure defination. */ +typedef struct +{ uint8_t prog_delay; /**< Programme delay. */ } ble_sch_config_t; -/** @brief GR55XX Chip configure defination */ -typedef struct { +/**@brief GR55XX Chip configure defination */ +typedef struct +{ ble_slp_config_t ble_slp_cfg; /**< BLE Sleep configure. */ ble_sch_config_t ble_sch_cfg; /**< BLE Sch configure. */ } gr55xx_chip_config_t; diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr_includes.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr_includes.h new file mode 100644 index 0000000..4195d9e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/gr_includes.h @@ -0,0 +1,66 @@ +/** + ******************************************************************************* + * + * @file gr_includes.h + * + * @brief Include Files API + * + ******************************************************************************* + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/** + @addtogroup SYSTEM + @{ + */ + +/** + * @addtogroup SYS System SDK + * @{ + * @brief Definitions and prototypes for the system SDK interface. +*/ + +#ifndef __GR_INCLUDES_H__ +#define __GR_INCLUDES_H__ + + +#include "ble_cfg.h" +#include "ble.h" +#include "grx_soc_reg.h" +#include "grx_hal.h" +#include "grx_sys.h" +#include +#include +#include + + +/** @} */ +#endif + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/grx_sys.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/grx_sys.h new file mode 100644 index 0000000..acae82b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/grx_sys.h @@ -0,0 +1,67 @@ +/** + ******************************************************************************* + * + * @file gr55xx_sys.h + * + * @brief GR55XX System API + * + ******************************************************************************* + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/** + @addtogroup SYSTEM + @{ + */ + +/** + * @addtogroup SYS System SDK + * @{ + * @brief Definitions and prototypes for the system SDK interface. +*/ + +#ifndef __GRX_SYS_H__ +#define __GRX_SYS_H__ + +#include "gr55xx.h" +#include "gr55xx_hal.h" +#include "gr55xx_sys.h" +#include "gr55xx_fpb.h" +#include "gr55xx_nvds.h" +#include "gr55xx_pwr.h" +#include "gr55xx_dfu.h" + +#include +#include +#include + +/** @} */ +#endif + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/sdk/patch.h b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/patch.h new file mode 100644 index 0000000..528f008 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/sdk/patch.h @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * + * @file patch.h + * + * @brief offer the interface for the patch function based on the FPB of the cortex arm-m4; + * + ****************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +#ifndef __PATCH_H_ +#define __PATCH_H_ + +/* + * ENUMERATIONS + **************************************************************************************** + */ +enum +{ + BIT_HCI_SEND_2_CONTROLLER, + BIT_HAL_XQSPI_SET_XIP_PRESENT_STATUS, + BIT_LL_XQSPI_INIT, + BIT_HAL_EXFLASH_WRITE, + BIT_HAL_EXFLASH_ERASE, + BIT_HAL_EXFLASH_READ, + BIT_BLE_BM_SET_SEC_INFO, + BIT_KE_TASK_SCHEDULE, +}; + + +/* + * MACRO DECLARATIONS + **************************************************************************************** + */ +#define PATCH_ENABLE_FLAG(BIT) (1< +#include "grx_hal.h" +#include "app_io.h" +#include "app_qspi.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) +#include "app_qspi_user_config.h" +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_QSPI_MODULE_ENABLED +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_GRAPHICS_QSPI_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Read data block in Memory mapped Mode(XIP Mode), The Data is ordered by the order in flash/psram device + * + * @param[in] id : QSPI module ID. + * @param[in] address : the address of device connected to QSPI, start from 0x000000 + * @param[in] buffer : memory pointer to save the read data + * @param[in] length : the read length in byte + * @return true/false + **************************************************************************************** + */ +bool app_qspi_dma_mmap_read_block(app_qspi_id_t id, uint32_t address, uint8_t * buffer, uint32_t length); + +/** + **************************************************************************************** + * @brief Special Async API to write QuadSPI Screen from memory mapped device(flash or psram) + * Must enable the two micro-defines to enable this API: + * QSPI_ASYNC_SCROLL_DRAW_SCREEN_SUPPORT + * + * @param[in] screen_id: QSPI module ID for screen, MUST config screen qspi to register mode. + * @param[in] storage_id: QSPI module ID for storage, MUST config storage qspi to mmap(xip) mode. + * @param[in] p_screen_cmd: pointer to the screen control command + * @param[in] p_screen_info: pointer to the screen information + * @param[in] p_scroll_config: pointer to the scrolling-config + * @param[in] is_first_call: When called in foreground task, please set true + * @return true/false + **************************************************************************************** + */ +bool app_qspi_async_draw_screen(app_qspi_id_t screen_id, + app_qspi_id_t storage_id, + const app_qspi_screen_command_t * const p_screen_cmd, + const app_qspi_screen_info_t * const p_screen_info, + app_qspi_screen_scroll_t * p_scroll_config, + bool is_first_call); + +/** + **************************************************************************************** + * @brief Special Async API to write Screen in vertical direction, and veritical lines are organized in linked list. + * Must enable the two micro-defines to enable this API: + * QSPI_ASYNC_VERI_LINK_DRAW_SCREEN_SUPPORT + * + * @param[in] screen_id: QSPI module ID for screen, MUST config screen qspi to register mode. + * @param[in] storage_id: QSPI module ID for storage, MUST config storage qspi to mmap(xip) mode. + * @param[in] p_screen_cmd: pointer to the screen control command + * @param[in] p_screen_info: pointer to the screen information + * @param[in] p_link_scroll: pointer to the linked list structure + * @param[in] is_first_call: When called in foreground task, please set true + * @return true/false + **************************************************************************************** + */ +bool app_qspi_async_veri_draw_screen(app_qspi_id_t screen_id, + app_qspi_id_t storage_id, + const app_qspi_screen_command_t * const p_screen_cmd, + const app_qspi_screen_info_t * const p_screen_info, + app_qspi_screen_veri_link_scroll_t * p_link_scroll, + bool is_first_call); + +/** + **************************************************************************************** + * @brief Special Async API to write one block of the Screen by DMA-LLP, every line of the block is organized in linked list. + * Must enable the micro-defines to enable this API: + * QSPI_ASYNC_VERI_LINK_DRAW_SCREEN_SUPPORT + * + * @param[in] screen_id: QSPI module ID for screen, MUST config screen qspi to register mode. + * @param[in] storage_id: QSPI module ID for storage, MUST config storage qspi to mmap(xip) mode. + * @param[in] p_screen_cmd: pointer to the screen control command + * @param[in] p_screen_info: pointer to the screen information + * @param[in] p_block_info: pointer to the block information structure + * @param[in] is_first_call: When first call, please set true(used this flag to decide whether send cmd or not) + * @return true/false + * @NOTE You need to control the CS outsize if (is_one_take_cs) is set true + * @NOTE It will generate APP_QSPI_EVT_TX_CPLT event when finish transmission. + **************************************************************************************** + */ +bool app_qspi_async_llp_draw_block(app_qspi_id_t screen_id, + app_qspi_id_t storage_id, + const app_qspi_screen_command_t *const p_screen_cmd, + const app_qspi_screen_info_t *const p_screen_info, + app_qspi_screen_block_t *p_block_info, + bool is_first_call); +/** + **************************************************************************************** + * @brief Special API to Blit Image from memory mapped device to RAM Buffer + * Must enable the two micro-defines to enable this API: + * QSPI_BLIT_RECT_IMAGE_SUPPORT + * + * @param[in] storage_id : QSPI module ID for storage, MUST config storage qspi to mmap(xip) mode. + * @param[in] p_blit_config : pointer to blit config + * @param[in] xfer_type : pointer to the scrolling-config + * @return true/false + **************************************************************************************** + */ +bool app_qspi_mmap_blit_image(app_qspi_id_t storage_id, blit_image_config_t * p_blit_config, blit_xfer_type_e xfer_type); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif +#endif +#endif +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c.h new file mode 100644 index 0000000..745c370 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c.h @@ -0,0 +1,457 @@ +/** + **************************************************************************************** + * + * @file app_i2c.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2C app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_IIC IIC + * @brief IIC APP module driver. + * @{ + */ + + +#ifndef _APP_I2C_H_ +#define _APP_I2C_H_ + +#include "grx_hal.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_I2C_MODULE_ENABLED + +/** @addtogroup APP_I2C_ENUM Enumerations + * @{ + */ + +/** + * @brief I2C module Enumerations definition + */ +typedef enum +{ + APP_I2C_ID_0, /**< I2C module 0. */ + APP_I2C_ID_1, /**< I2C module 1. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + APP_I2C_ID_2, /**< I2C module 2. */ + APP_I2C_ID_3, /**< I2C module 3. */ +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + APP_I2C_ID_4, /**< I2C module 4. */ + APP_I2C_ID_5, /**< I2C module 5. */ +#endif + APP_I2C_ID_MAX /**< Only for check parameter, not used as input parameters. */ +} app_i2c_id_t; + +/** + * @brief I2C role Enumerations definition + */ +typedef enum +{ + APP_I2C_ROLE_MASTER, /**< I2C master device. */ + APP_I2C_ROLE_SLAVE, /**< I2C slave device. */ + APP_I2C_ROLE_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_i2c_role_t; + +/** + * @brief I2C event Enumerations definition + */ +typedef enum +{ + APP_I2C_EVT_ERROR, /**< Error reported by I2C peripheral. */ + APP_I2C_EVT_TX_CPLT, /**< Requested TX transfer completed. */ + APP_I2C_EVT_RX_DATA, /**< Requested RX transfer completed. */ + APP_I2C_ABORT, /**< abort reported by I2C peripheral. */ +} app_i2c_evt_type_t; +/** @} */ + +/** @addtogroup APP_I2C_STRUCTURES Structures + * @{ + */ +/** + * @brief I2C pins Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of SPI IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ +} app_i2c_pin_t; + +/** + * @brief I2C pins config Structures + */ +typedef struct +{ + app_i2c_pin_t scl; /**< Set the configuration of I2C SCL pin. */ + app_i2c_pin_t sda; /**< Set the configuration of I2C SDA pin. */ +} app_i2c_pin_cfg_t; + +/** + * @brief I2C operate mode Enumerations definition + */ +typedef struct +{ + dma_regs_t *tx_dma_instance;/**< Specifies the TX DMA instance.*/ + dma_regs_t *rx_dma_instance;/**< Specifies the RX DMA instance.*/ + dma_channel_t tx_dma_channel; /**< Specifies the dma channel of I2C TX. */ + dma_channel_t rx_dma_channel; /**< Specifies the dma channel of I2C RX. */ +} app_i2c_dma_cfg_t; + +/** + * @brief I2C event structure definition + */ +typedef struct +{ + app_i2c_evt_type_t type; /**< Type of event. */ + union + { + uint32_t error_code; /**< I2C Error code . */ + uint16_t size; /**< I2C transmitted/received counter. */ + } data; /**< Data of event. */ + uint16_t slave_addr; /**< I2C slave address. */ +} app_i2c_evt_t; + +/**@brief App i2c state types. */ +typedef enum +{ + APP_I2C_INVALID = 0, + APP_I2C_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_I2C_SLEEP, +#endif +} app_i2c_state_t; + +/**@brief App i2c dma state types. */ +typedef enum +{ + APP_I2C_DMA_INVALID = 0, + APP_I2C_DMA_ACTIVITY, +} app_i2c_dma_state_t; + +/** + * @brief I2C event callback definition + */ +typedef void (*app_i2c_evt_handler_t)(app_i2c_evt_t *p_evt); + +/** @} */ + +/** + * @brief I2C device structure definition + */ +typedef struct +{ + app_i2c_evt_handler_t evt_handler; /**< I2C event callback definition. */ + i2c_handle_t handle; /**< I2C handle definition. */ + app_i2c_role_t role; /**< I2C role Enumerations definition. */ + app_i2c_pin_cfg_t *p_pin_cfg; /**< I2C pins config Structures. */ + dma_id_t dma_id[2]; /**< DMA id definition. */ + app_i2c_state_t i2c_state; /**< I2C state types. */ + app_i2c_dma_state_t i2c_dma_state; /**< I2C dma state types. */ + volatile bool start_flag; /**< Start flag definition. */ + uint16_t slv_dev_addr; /**< I2C Slave address. */ +} i2c_env_t; + +/** + * @brief I2C parameters structure definition + */ +typedef struct +{ + app_i2c_id_t id; /**< specified I2C module ID. */ + app_i2c_role_t role; /**< specified the role of I2C. */ + app_i2c_pin_cfg_t pin_cfg; /**< the pin configuration information for the specified I2C module. */ + app_i2c_dma_cfg_t dma_cfg; /**< I2C operate mode. */ + i2c_init_t init; /**< I2C communication parameters. */ + i2c_env_t i2c_dev; /**< I2C device structure definition. */ +} app_i2c_params_t; + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_I2C_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP I2C DRIVER according to the specified parameters + * in the app_i2c_params_t and app_i2c_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_i2c_params_t parameter which contains the + * configuration information for the specified I2C module. + * @param[in] evt_handler: I2C user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_i2c_init(app_i2c_params_t *p_params, app_i2c_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP I2C DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_i2c_deinit(app_i2c_id_t id); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which I2C module want to receive. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_receive_sync(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] id: which I2C module want to receive. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_receive_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which I2C module want to transmit. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_transmit_sync(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] id: which I2C module want to transmit. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_transmit_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data in blocking mode from a specific memory address + * + * @param[in] id: which I2C module want to read. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_mem_read_sync(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Read an amount of data in non-blocking mode with Interrupt/DMA from a specific memory address + * + * @param[in] id: which I2C module want to read. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_mem_read_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Write an amount of data in blocking mode to a specific memory address + * + * @param[in] id: which I2C module want to write. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_mem_write_sync(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Write an amount of data in non-blocking mode with Interrupt/DMA to a specific memory address + * + * @param[in] id: which I2C module want to write. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_mem_write_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Return the I2C handle. + * + * @param[in] id: I2C Channel ID. + * + * @return Pointer to the specified ID's I2C handle. + **************************************************************************************** + */ +i2c_handle_t *app_i2c_get_handle(app_i2c_id_t id); + +/** + **************************************************************************************** + * @brief Abort a master I2C IT or DMA process communication with Interrupt + * + * @param[in] id: I2C Channel ID. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_master_abort_it(app_i2c_id_t id); + +/** + **************************************************************************************** + * @brief Adjust I2C timing value to adapt to real load. + * + * @param[in] id: I2C Channel ID. + * @param[in] timing_type: Timing type. See I2C_Timing_type. + * @param[in] delta: timing change value(unit: I2C work clock cycles). + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_timing_adjust(app_i2c_id_t id, uint32_t timing_type, int32_t delta); + +/** + **************************************************************************************** + * @brief Get I2C timing value. + * + * @param[in] id: I2C Channel ID. + * @param[in] timing_type: Timing type. See I2C_Timing_type. + * @param[in] p_timing_value: Pointer of I2C timing value(unit: I2C work clock cycles). + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_timing_get(app_i2c_id_t id, uint32_t timing_type, uint32_t *p_timing_value); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Transmits than receives in master mode or receives than transmits in slave mode with only one stop bit. + * + * @param[in] id: which I2C module want to transmit. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_tdata: Pointer to transmited data buffer + * @param[in] tsize: Amount of data to be sent + * @param[in] p_rdata: Pointer to received data buffer + * @param[in] rsize: Amount of data to be receive + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_transmit_receive_sync(app_i2c_id_t id, uint16_t dev_address, uint8_t *p_tdata, uint16_t tsize, uint8_t *p_rdata, uint16_t rsize, uint32_t timeout); +#endif + +/** @} */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c_dma.h new file mode 100644 index 0000000..0374048 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2c_dma.h @@ -0,0 +1,179 @@ +/** + **************************************************************************************** + * + * @file app_i2c_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2C app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_IIC IIC + * @brief IIC APP module driver. + * @{ + */ + + +#ifndef _APP_I2C_DMA_H_ +#define _APP_I2C_DMA_H_ + +#include "grx_hal.h" +#include "app_io.h" +#include "app_i2c.h" +#include "app_drv_error.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_I2C_MODULE_ENABLED + +/** @addtogroup APP_I2C_ENUM Enumerations + * @{ + */ + + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_I2C_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP I2C DRIVER according to the specified parameters + * in the app_i2c_params_t and app_i2c_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_i2c_params_t parameter which contains the + * configuration information for the specified I2C module. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_i2c_dma_init(app_i2c_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize the APP I2C DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_i2c_dma_deinit(app_i2c_id_t id); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] id: which I2C module want to receive. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_dma_receive_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] id: which I2C module want to transmit. + * @param[in] target_address: Target device address: The device 7 bits address value in datasheet + must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_dma_transmit_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data in non-blocking mode with Interrupt/DMA from a specific memory address + * + * @param[in] id: which I2C module want to read. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_dma_mem_read_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Write an amount of data in non-blocking mode with Interrupt/DMA to a specific memory address + * + * @param[in] id: which I2C module want to write. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2c_dma_mem_write_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** @} */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s.h new file mode 100644 index 0000000..12d31b3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s.h @@ -0,0 +1,431 @@ +/** + **************************************************************************************** + * + * @file app_i2s.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2S app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_I2S I2S + * @brief I2S APP module driver. + * @{ + */ + + +#ifndef _APP_I2S_H_ +#define _APP_I2S_H_ + +#include +#include "grx_hal.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_drv_error.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_I2S_MODULE_ENABLED + +/** @addtogroup APP_I2S_ENUM Enumerations + * @{ + */ + +/** + * @brief I2S module Enumerations definition + */ +typedef enum +{ + APP_I2S_ID_SLAVE, /**< I2S slave module. */ + APP_I2S_ID_MASTER, /**< I2S master module. */ + APP_I2S_ID_MAX /**< Only for check parameter, not used as input parameters. */ +} app_i2s_id_t; + +/** + * @brief I2S event Enumerations definition + */ +typedef enum +{ + APP_I2S_EVT_ERROR, /**< Error reported by UART peripheral. */ + APP_I2S_EVT_TX_CPLT, /**< Requested TX transfer completed. */ + APP_I2S_EVT_RX_DATA, /**< Requested RX transfer completed. */ + APP_I2S_EVT_TX_RX, /**< Requested TX/RX transfer completed. */ +} app_i2s_evt_type_t; +/** @} */ + + +/** @addtogroup APP_I2S_STRUCTURES Structures + * @{ + */ + +/** + * @brief I2S pins Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of I2S IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ +} app_i2s_pin_t; + +/** + * @brief I2S pins config Structures + */ +typedef struct +{ + app_i2s_pin_t ws; /**< Set the configuration of I2S WS pin. */ + app_i2s_pin_t sdo; /**< Set the configuration of I2S SDO pin. */ + app_i2s_pin_t sdi; /**< Set the configuration of I2S SDI pin. */ + app_i2s_pin_t sclk; /**< Set the configuration of I2S SCLK pin. */ +} app_i2s_pin_cfg_t; + +/** + * @brief I2S operate mode Enumerations definition + */ +typedef struct +{ + dma_regs_t *tx_dma_instance;/**< Specifies the TX DMA inistall.*/ + dma_regs_t *rx_dma_instance;/**< Specifies the RX DMA inistall.*/ + dma_channel_t tx_dma_channel; /**< Specifies the dma channel of I2S TX. */ + dma_channel_t rx_dma_channel; /**< Specifies the dma channel of I2S RX. */ +} app_i2s_dma_cfg_t; + +/** + * @brief I2S event structure definition + */ +typedef struct +{ + app_i2s_evt_type_t type; /**< Type of event. */ + union + { + uint32_t error_code; /**< I2S Error code . */ + uint16_t size; /**< I2S transmitted/received counter. */ + } data; /**< Data of event. */ +} app_i2s_evt_t; + +/**@brief App i2s state types. */ +typedef enum +{ + APP_I2S_INVALID = 0, + APP_I2S_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_I2S_SLEEP, +#endif +} app_i2s_state_t; + + +/**@brief App i2s dma state types. */ +typedef enum +{ + APP_I2S_DMA_INVALID = 0, + APP_I2S_DMA_ACTIVITY, +} app_i2s_dma_state_t; + +/** + * @brief I2S event callback definition + */ +typedef void (*app_i2s_evt_handler_t)(app_i2s_evt_t *p_evt); + +/** @} */ + +/** + * @brief I2S device structure definition + */ +typedef struct +{ + app_i2s_evt_handler_t evt_handler; /**< I2S event callback definition. */ + i2s_handle_t handle; /**< I2S handle definition. */ + app_i2s_pin_cfg_t *p_pin_cfg; /**< I2S pins config Structures. */ + dma_id_t dma_id[2]; /**< DMA id definition. */ + app_i2s_state_t i2s_state; /**< I2S state types. */ + app_i2s_dma_state_t i2s_dma_state; /**< I2S dma state types.. */ + bool start_flag; /**< Start flag definition. */ +} i2s_env_t; + +/** + * @brief I2S parameters structure definition + */ +typedef struct +{ + app_i2s_id_t id; /**< specified I2S module ID. */ + app_i2s_pin_cfg_t pin_cfg; /**< the pin configuration information for the specified I2S module. */ + app_i2s_dma_cfg_t dma_cfg; /**< I2S operate mode Enumerations definition. */ + i2s_init_t init; /**< I2S communication parameters. */ + i2s_env_t i2s_env; /**< I2S device structure definition. */ +} app_i2s_params_t; + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_I2S_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the APP I2S DRIVER according to the specified parameters + * in the app_i2s_params_t and app_i2s_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_i2s_params_t parameter which contains the + * configuration information for the specified I2S module. + * @param[in] evt_handler: I2S user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_i2s_init(app_i2s_params_t *p_params, app_i2s_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP I2S DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_i2s_deinit(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which I2S module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_receive_sync(app_i2s_id_t id, uint16_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which I2S module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_receive_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which I2S module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_transmit_sync(app_i2s_id_t id, uint16_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which I2S module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_transmit_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Enable the I2S moudle. + * + * @param[in] id: The I2S module id. + * + * @return Result of operation. + **************************************************************************************** + */ + +uint16_t app_i2s_enable(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Disable the I2S moudle. + * + * @param[in] id: The I2S module id. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_disable(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Enable the master I2S clock. + * + * @param[in] id: The I2S master module id. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_enable_clock(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Disable the master I2S clock. + * + * @param[in] id: The I2S master module id. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_disable_clock(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Flush the I2S transmitter FIFO. + * + * @param[in] id: which I2S module want to flush. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_flush_tx_fifo(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Flush the I2S receiver FIFO. + * + * @param[in] id: which I2S module want to flush. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_flush_rx_fifo(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Return the I2S handle. + * + * @param[in] id: I2S Channel ID. + * + * @return Pointer to the specified ID's I2S handle. + **************************************************************************************** + */ +i2s_handle_t *app_i2s_get_handle(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (blocking mode). + * @param id I2S ID + * @note This procedure is executed in blocking mode: When exiting + * function, Abort is considered as completed. + * @retval ::APP_DRV_SUCCESS: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + * @retval ::APP_DRV_ERR_INVALID_PARAM: Parameter error. + **************************************************************************************** + */ +uint16_t app_i2s_abort(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in blocking mode. + * @param id I2S ID + * @param p_tx_data Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @param[in] timeout: Timeout duration + * @retval ::APP_DRV_SUCCESS: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + * @retval ::APP_DRV_ERR_INVALID_PARAM: Parameter error. + * @retval ::APP_DRV_ERR_BUSY: Driver is busy. + **************************************************************************************** + */ +uint16_t app_i2s_transmit_receive_sync(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length, + uint32_t timeout); +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] id: I2S ID + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @retval ::APP_DRV_SUCCESS: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + * @retval ::APP_DRV_ERR_INVALID_PARAM: Parameter error. + * @retval ::APP_DRV_ERR_BUSY: Driver is busy. + **************************************************************************************** + */ +uint16_t app_i2s_transmit_receive_async(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length); + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ +/** @} */ +/** @} */ + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s_dma.h new file mode 100644 index 0000000..77ba0d5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_i2s_dma.h @@ -0,0 +1,157 @@ +/** + **************************************************************************************** + * + * @file app_i2s_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2S app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_I2S I2S + * @brief I2S APP module driver. + * @{ + */ + + +#ifndef _APP_I2S_DMA_PUB_H_ +#define _APP_I2S_DMA_PUB_H_ + +#include "grx_hal.h" +#include "app_io.h" +#include "app_i2s.h" +#include "app_drv_error.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_I2S_MODULE_ENABLED + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_I2S_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the APP I2S DRIVER according to the specified parameters + * in the app_i2s_params_t and app_i2s_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_i2s_params_t parameter which contains the + * configuration information for the specified I2S module. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_i2s_dma_init(app_i2s_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize the APP I2S DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_i2s_dma_deinit(app_i2s_id_t id); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which I2S module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_dma_receive_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which I2S module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_i2s_dma_transmit_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] id: I2S ID + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @retval ::APP_DRV_SUCCESS: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + * @retval ::APP_DRV_ERR_INVALID_PARAM: Parameter error. + * @retval ::APP_DRV_ERR_BUSY: Driver is busy. + **************************************************************************************** + */ +uint16_t app_i2s_dma_transmit_receive_async(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length); + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ +/** @} */ +/** @} */ + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_io.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_io.h new file mode 100644 index 0000000..2c9bece --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_io.h @@ -0,0 +1,485 @@ +/** + **************************************************************************************** + * + * @file app_io.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of GPIO app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_GPIO GPIO + * @brief GPIO APP module driver. + * @{ + */ + + +#ifndef _APP_IO_H_ +#define _APP_IO_H_ + +#include "app_drv_error.h" +#include "app_drv_config.h" +#include + +/** @addtogroup APP_GPIO_PIN_DEFINES Defines + * @{ + */ +/** @addtogroup GR5xxx_pins Defines + * @{ + */ + +/** +* @brief APP_GPIO_DEFINE IO pins +*/ +#define APP_IO_PIN_0 ((uint32_t)0x00000001U) /**< Pin 0 selected */ +#define APP_IO_PIN_1 ((uint32_t)0x00000002U) /**< Pin 1 selected */ +#define APP_IO_PIN_2 ((uint32_t)0x00000004U) /**< Pin 2 selected */ +#define APP_IO_PIN_3 ((uint32_t)0x00000008U) /**< Pin 3 selected */ +#define APP_IO_PIN_4 ((uint32_t)0x00000010U) /**< Pin 4 selected */ +#define APP_IO_PIN_5 ((uint32_t)0x00000020U) /**< Pin 5 selected */ +#define APP_IO_PIN_6 ((uint32_t)0x00000040U) /**< Pin 6 selected */ +#define APP_IO_PIN_7 ((uint32_t)0x00000080U) /**< Pin 7 selected */ +#define APP_IO_PIN_8 ((uint32_t)0x00000100U) /**< Pin 8 selected */ +#define APP_IO_PIN_9 ((uint32_t)0x00000200U) /**< Pin 9 selected */ +#define APP_IO_PIN_10 ((uint32_t)0x00000400U) /**< Pin 10 selected */ +#define APP_IO_PIN_11 ((uint32_t)0x00000800U) /**< Pin 11 selected */ +#define APP_IO_PIN_12 ((uint32_t)0x00001000U) /**< Pin 12 selected */ +#define APP_IO_PIN_13 ((uint32_t)0x00002000U) /**< Pin 13 selected */ +#define APP_IO_PIN_14 ((uint32_t)0x00004000U) /**< Pin 14 selected */ +#define APP_IO_PIN_15 ((uint32_t)0x00008000U) /**< Pin 15 selected */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define APP_IO_PIN_16 ((uint32_t)0x00010000U) /**< Pin 16 selected */ +#define APP_IO_PIN_17 ((uint32_t)0x00020000U) /**< Pin 17 selected */ +#define APP_IO_PIN_18 ((uint32_t)0x00040000U) /**< Pin 18 selected */ +#define APP_IO_PIN_19 ((uint32_t)0x00080000U) /**< Pin 19 selected */ +#define APP_IO_PIN_20 ((uint32_t)0x00100000U) /**< Pin 20 selected */ +#define APP_IO_PIN_21 ((uint32_t)0x00200000U) /**< Pin 21 selected */ +#define APP_IO_PIN_22 ((uint32_t)0x00400000U) /**< Pin 22 selected */ +#define APP_IO_PIN_23 ((uint32_t)0x00800000U) /**< Pin 23 selected */ +#define APP_IO_PIN_24 ((uint32_t)0x01000000U) /**< Pin 24 selected */ +#define APP_IO_PIN_25 ((uint32_t)0x02000000U) /**< Pin 25 selected */ +#define APP_IO_PIN_26 ((uint32_t)0x04000000U) /**< Pin 26 selected */ +#define APP_IO_PIN_27 ((uint32_t)0x08000000U) /**< Pin 27 selected */ +#define APP_IO_PIN_28 ((uint32_t)0x10000000U) /**< Pin 28 selected */ +#define APP_IO_PIN_29 ((uint32_t)0x20000000U) /**< Pin 29 selected */ +#define APP_IO_PIN_30 ((uint32_t)0x40000000U) /**< Pin 30 selected */ +#define APP_IO_PIN_31 ((uint32_t)0x80000000U) /**< Pin 31 selected */ +#endif + +#define APP_IO_PINS_0_7 ((uint32_t)0x000000FFU) /**< 0~7 pins selected */ +#define APP_IO_PINS_0_15 ((uint32_t)0x0000FFFFU) /**< 0~15 pins selected */ +#define APP_IO_PINS_16_31 ((uint32_t)0xFFFF0000U) /**< 16~31 pins selected */ +#define APP_IO_PIN_ALL ((uint32_t)0x0000FFFFU) /**< All pins selected */ +#define APP_AON_IO_PIN_ALL ((uint32_t)0x000000FFU) /**< All AON pins selected */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +#define APP_MSIO_IO_PIN_ALL ((uint32_t)0x000003FFU) /**< All MISO pins selected */ +#else +#define APP_MSIO_IO_PIN_ALL ((uint32_t)0x000000FFU) /**< All MISO pins selected */ +#endif +#define APP_IO_PIN_MASK ((uint32_t)0xFFFFFFFFU) /**< PIN mask for assert test */ + +/** + * @brief GR5xxx_APP_GPIO_default_config initStruct default configuart APP_GPIOn + */ +#define APP_IO_DEFAULT_CONFIG \ +{ \ + .pin = APP_IO_PIN_ALL, \ + .mode = APP_IO_MODE_INPUT, \ + .pull = APP_IO_PULLDOWN, \ +} + +/** @} */ + + +/** @addtogroup APP_GPIO_ENUMERATIONS Enumerations + * @{ + */ +/** + * @brief GPIO state Enumerations definition + */ +typedef enum +{ + APP_IO_PIN_RESET, /**< IO pin low level. */ + APP_IO_PIN_SET, /**< IO pin high level. */ +} app_io_pin_state_t; + +/** + * @brief GPIO type Enumerations definition + */ +typedef enum +{ + APP_IO_TYPE_GPIOA, /**< General Purpose Input/Output. */ + APP_IO_TYPE_GPIOB, /**< General Purpose Input/Output. */ + APP_IO_TYPE_GPIOC, /**< General Purpose Input/Output. */ +// #if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + APP_IO_TYPE_NORMAL, /**< General Purpose Input/Output. */ +// #endif + APP_IO_TYPE_AON, /**< Always-on Input/Output. */ + APP_IO_TYPE_MSIO, /**< Mixed Signal I/O. */ + APP_IO_TYPE_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_io_type_t; + +/** + * @brief GPIO mode Enumerations definition + */ +typedef enum +{ + APP_IO_MODE_NONE, + APP_IO_MODE_INPUT, /**< Input Mode. */ + APP_IO_MODE_OUTPUT, /**< Output Mode. */ + APP_IO_MODE_MUX, /**< Mux Mode. */ + APP_IO_MODE_IT_RISING, /**< Interrupt Mode with Rising edge trigger detection. */ + APP_IO_MODE_IT_FALLING, /**< Interrupt Mode with Falling edge trigger detection. */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + APP_IO_MODE_IT_BOTH_EDGE, /**< Interrupt Mode with Rising and Falling edge trigger detection */ +#endif + APP_IO_MODE_IT_HIGH, /**< Interrupt Mode with High-level trigger detection. */ + APP_IO_MODE_IT_LOW, /**< Interrupt Mode with Low-level trigger detection. */ + APP_IO_MODE_ANALOG, /**< Analog IO Mode. */ + APP_IO_MODE_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_io_mode_t; + +/** + * @brief GPIO pull Enumerations definition + */ +typedef enum +{ + APP_IO_NOPULL, /**< No Pull-up or Pull-down activation. */ + APP_IO_PULLUP, /**< Pull-up activation. */ + APP_IO_PULLDOWN, /**< Pull-down activation. */ + APP_IO_PULL_MAX /**< Only for check parameter, not used as input parameters. */ +} app_io_pull_t; + +/** + * @brief GPIO mux Enumerations definition + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +typedef enum +{ + APP_IO_MUX_0, /**< IO_MUX_GPIO. */ + APP_IO_MUX_1, /**< IO_MUX_I2C0_SCL. */ + APP_IO_MUX_2, /**< IO_MUX_I2C0_SDA. */ + APP_IO_MUX_3, /**< IO_MUX_I2C1_SCL. */ + APP_IO_MUX_4, /**< IO_MUX_I2C1_SDA. */ + APP_IO_MUX_5, /**< IO_MUX_UART0_CTS. */ + APP_IO_MUX_6, /**< IO_MUX_UART0_RTS. */ + APP_IO_MUX_7, /**< IO_MUX_UART0_TX. */ + APP_IO_MUX_8, /**< IO_MUX_UART0_RX. */ + APP_IO_MUX_9, /**< IO_MUX_UART1_CTS. */ + APP_IO_MUX_10, /**< IO_MUX_UART1_RTS. */ + APP_IO_MUX_11, /**< IO_MUX_UART1_TX. */ + APP_IO_MUX_12, /**< IO_MUX_UART1_RX.*/ + APP_IO_MUX_13, /**< IO_MUX_PWM0. */ + APP_IO_MUX_14, /**< IO_MUX_PWM1. */ + APP_IO_MUX_15, /**< IO_MUX_PWM2. */ + APP_IO_MUX_16, /**< IO_MUX_PWM3. */ + APP_IO_MUX_17, /**< IO_MUX_PWM4. */ + APP_IO_MUX_18, /**< IO_MUX_PWM5. */ + APP_IO_MUX_19, /**< IO_MUX_df_ant_sw_0.*/ + APP_IO_MUX_20, /**< IO_MUX_df_ant_sw_1.*/ + APP_IO_MUX_21, /**< IO_MUX_df_ant_sw_2.*/ + APP_IO_MUX_22, /**< IO_MUX_df_ant_sw_3.*/ + APP_IO_MUX_23, /**< IO_MUX_df_ant_sw_4.*/ + APP_IO_MUX_24, /**< IO_MUX_df_ant_sw_5.*/ + APP_IO_MUX_25, /**< IO_MUX_df_ant_sw_6.*/ + APP_IO_MUX_26, /**< IO_MUX_ferp_gpio_trig_0.*/ + APP_IO_MUX_27, /**< IO_MUX_SWO.*/ + APP_IO_MUX_28, /**< IO_MUX_coex_ble_rx.*/ + APP_IO_MUX_29, /**< IO_MUX_coex_ble_tx.*/ + APP_IO_MUX_30, /**< IO_MUX_coex_wlan_rx.*/ + APP_IO_MUX_31, /**< IO_MUX_coex_wlan_tx.*/ + APP_IO_MUX_32, /**< IO_MUX_coex_ble_in_process.*/ + APP_IO_MUX_33, /**< IO_MUX_SWD_CLK.*/ + APP_IO_MUX_34, /**< IO_MUX_SWD_DATA.*/ + APP_IO_MUX_35, /**< IO_MUX_reserve3.*/ + APP_IO_MUX_36, /**< IO_MUX_reserve4.*/ + APP_IO_MUX_37, /**< IO_MUX_reserve5.*/ + APP_IO_MUX_38, /**< IO_MUX_SPI_S_MOSI.*/ + APP_IO_MUX_39, /**< IO_MUX_SPI_S_CS_N.*/ + APP_IO_MUX_40, /**< IO_MUX_SPI_S_CLK.*/ + APP_IO_MUX_41, /**< IO_MUX_SPI_S_MISO.*/ + APP_IO_MUX_42, /**< IO_MUX_SPI_M_CLK.*/ + APP_IO_MUX_43, /**< IO_MUX_SPI_M_CS0_N.*/ + APP_IO_MUX_44, /**< IO_MUX_SPI_M_CS1_N.*/ + APP_IO_MUX_45, /**< IO_MUX_SPI_M_MISO.*/ + APP_IO_MUX_46, /**< IO_MUX_SPI_M_MOSIss*/ + APP_IO_MUX_47, /**< RESERVED */ + APP_IO_MUX_48, /**< RESERVED */ + APP_IO_MUX_49, /**< IO_MUX_DUAL_TIMER0_A */ + APP_IO_MUX_50, /**< IO_MUX_DUAL_TIMER0_B */ + APP_IO_MUX_51, /**< IO_MUX_DUAL_TIMER0_C */ + APP_IO_MUX_52, /**< IO_MUX_DUAL_TIMER1_A */ + APP_IO_MUX_53, /**< IO_MUX_DUAL_TIMER1_B */ + APP_IO_MUX_54, /**< IO_MUX_DUAL_TIMER1_C */ + APP_IO_MUX_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_io_mux_t; +#else +typedef enum +{ + APP_IO_MUX_0, /**< IO mux mode 0. */ + APP_IO_MUX_1, /**< IO mux mode 1. */ + APP_IO_MUX_2, /**< IO mux mode 2. */ + APP_IO_MUX_3, /**< IO mux mode 3. */ + APP_IO_MUX_4, /**< IO mux mode 4. */ + APP_IO_MUX_5, /**< IO mux mode 5. */ + APP_IO_MUX_6, /**< IO mux mode 6. */ + APP_IO_MUX_7, /**< IO mux mode 7. */ + APP_IO_MUX_8, /**< IO mux mode 8. */ + APP_IO_MUX_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_io_mux_t; +#endif + +/** +* @brief GPIO mux for different APP_DRIVER_CHIP_TYPE +*/ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +#define APP_IO_MUX APP_IO_MUX_0 /**< IO mux for GR5332X. */ +#elif (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#define APP_IO_MUX APP_IO_MUX_8 /**< IO mux for GR5525X. */ +#else +#define APP_IO_MUX APP_IO_MUX_7 /**< IO mux for others. */ +#endif + +/** @} */ + +/** @addtogroup APP_GPIO_STRUCT Structures + * @{ + */ +/** + * @brief GPIO parameter structure definition + */ +typedef struct +{ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins */ + app_io_mode_t mode; /**< Specifies the operating mode for the selected pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ +} app_io_init_t; +/** @} */ + +/** + * @brief GPIO Interrupt event Structure definition + */ +typedef struct +{ + app_io_type_t type; /**< Type of event. */ + uint32_t pin; /**< Specifies the IO pins to be configured. */ + void *arg; /**< User parameters */ +} app_io_evt_t; + +/** + * @brief GPIO Speed Structure definition + */ +typedef enum { + APP_IO_SPPED_MEDIUM, /**< Select medium speed. */ + APP_IO_SPPED_HIGH, /**< Select high speed. */ + APP_IO_SPPED_MAX /**< Only for check parameter, not used as input parameters. */ +} app_io_speed_t; + + +/** + * @brief GPIO Input type Structure definition + */ +typedef enum { + APP_IO_INPUT_TYPE_CMOS, /**< Select CMOS input. */ + APP_IO_INPUT_TYPE_SCHMITT, /**< Select Schmitt input. */ + APP_IO_INPUT_TYPE_MAX /**< Only for check parameter, not used as input parameters. */ +} app_io_input_type_t; + +/** + * @brief GPIO Strength Structure definition + */ +typedef enum { + APP_IO_STRENGTH_LOW, /**< Select low output driver strength */ + APP_IO_STRENGTH_MEDIUM, /**< Select medium output driver strength */ + APP_IO_STRENGTH_HIGH, /**< Select high output driver strength */ + APP_IO_STRENGTH_ULTRA, /**< Select high output driver strength */ + APP_IO_STRENGTH_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_io_strength_t; + +/** + * @brief GPIO callback type. + */ +typedef void (*app_io_callback_t)(app_io_evt_t *p_evt); + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_GPIO_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP GPIO DRIVER according to the specified parameters + * in the app_io_type_t and app_io_init_t. + * + * @param[in] type: GPIO type. + * @param[in] p_init: Pointer to app_io_init_t parameter which contains the + * configuration information for the specified GPIO. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_io_init(app_io_type_t type, app_io_init_t *p_init); + +/** + **************************************************************************************** + * @brief De-initialize the GPIOx peripheral. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to De-initialization. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_io_deinit(app_io_type_t type, uint32_t pin); + +/** + **************************************************************************************** + * @brief Read the specified input port pin.. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to read. + * + * @return The GPIO state. + **************************************************************************************** + */ +app_io_pin_state_t app_io_read_pin(app_io_type_t type, uint32_t pin); + +/** + **************************************************************************************** + * @brief Set or clear the selected data port bit. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to set or clear. + * @param[in] pin_state: Specifies the value to be written to the selected bit. + * + * @return Result of write. + **************************************************************************************** + */ +uint16_t app_io_write_pin(app_io_type_t type, uint32_t pin, app_io_pin_state_t pin_state); + +/** + **************************************************************************************** + * @brief Toggle the specified GPIO pin. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to toggle. + * + * @return Result of toggle. + **************************************************************************************** + */ +uint16_t app_io_toggle_pin(app_io_type_t type, uint32_t pin); + +/** + **************************************************************************************** + * @brief Set the speed of the GPIO. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to set. + * @param[in] speed: GPIO speed type, See app_io_speed_t. + * + * @return Result of seting. + **************************************************************************************** + */ +uint16_t app_io_set_speed(app_io_type_t type, uint32_t pin, app_io_speed_t speed); + +/** + **************************************************************************************** + * @brief Set the strength of the GPIO. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to set. + * @param[in] strength: GPIO strength type, See app_io_strength_t. + * + * @return Result of seting. + **************************************************************************************** + */ +uint16_t app_io_set_strength(app_io_type_t type, uint32_t pin, app_io_strength_t strength); + +/** + **************************************************************************************** + * @brief Set the input type of the GPIO. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to toggle. + * @param[in] input_type: GPIO input type, See app_io_input_type_t. + * + * @return Result of seting. + **************************************************************************************** + */ +uint16_t app_io_set_intput_type(app_io_type_t type, uint32_t pin, app_io_input_type_t input_type); + +/** + **************************************************************************************** + * @brief Initialize GPIO to interrupt mode and register interrupt callback function. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] p_init: Pointer to app_io_init_t parameter which contains the + * configuration information for the specified GPIO. + * @param[in] io_evt_cb: Interrupt callback function. + * @param[in] arg: User parameters. + * + * @return Result of register. + **************************************************************************************** + */ +uint16_t app_io_event_register_cb(app_io_type_t type, app_io_init_t *p_init, app_io_callback_t io_evt_cb, void *arg); + +/** + **************************************************************************************** + * @brief Deinitialize GPIO to normal mode and unregister interrupt. + * + * @param[in] type: GPIO type, See app_io_type_t. + * @param[in] pin: The pin want to unregister. + * + * @return Result of unregister. + **************************************************************************************** + */ +uint16_t app_io_event_unregister(app_io_type_t type, uint32_t pin); + +/** @} */ +#endif + +/** @} */ + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_iso7816.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_iso7816.h new file mode 100644 index 0000000..dcc8059 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_iso7816.h @@ -0,0 +1,429 @@ +/** + **************************************************************************************** + * + * @file app_iso7816.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ISO7816 app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_ISO7816 ISO7816 + * @brief ISO7816 APP module driver. + * @{ + */ + + +#ifndef _APP_ISO7816_H_ +#define _APP_ISO7816_H_ + +#include "grx_hal.h" +#include "app_io.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_ISO7816_MODULE_ENABLED +/** @addtogroup APP_ISO7816_DEFINE Defines + * @{ + */ + +/** @defgroup APP_ISO7816_ACTION Action state + * @{ + */ +#define APP_ISO7816_ACTION_NONE HAL_ISO7816_ACTION_NONE /**< Do Nothing. */ +#define APP_ISO7816_ACTION_OFF HAL_ISO7816_ACTION_OFF /**< Switch Off. */ +#define APP_ISO7816_ACTION_STOPCLK HAL_ISO7816_ACTION_STOPCLK /**< Stop the clock. */ +#define APP_ISO7816_ACTION_ON HAL_ISO7816_ACTION_ON /**< Switch on and receive ATR. */ +#define APP_ISO7816_ACTION_WARMRST HAL_ISO7816_ACTION_WARMRST /**< Trigger warm reset and receive ATR.*/ +#define APP_ISO7816_ACTION_RX HAL_ISO7816_ACTION_RX /**< Receive. */ +#define APP_ISO7816_ACTION_TX HAL_ISO7816_ACTION_TX /**< Transmit. */ +#define APP_ISO7816_ACTION_TXRX HAL_ISO7816_ACTION_TXRX /**< Transmit, followed by RX. */ +/** @} */ + +/** @defgroup APP_ISO7816_Interrupt_definition ISO7816 Interrupt Definition + * @{ + */ +#define APP_ISO7816_INTR_PRESENCE HAL_ISO7816_INTR_PRESENCE /**< Source presence interrupt */ +#define APP_ISO7816_INTR_STATE_ERR HAL_ISO7816_INTR_STATE_ERR /**< Source state error interrupt */ +#define APP_ISO7816_INTR_DMA_ERR HAL_ISO7816_INTR_DMA_ERR /**< Source dma error interrupt */ +#define APP_ISO7816_INTR_RETRY_ERR HAL_ISO7816_INTR_RETRY_ERR /**< Source retry error interrupt */ +#define APP_ISO7816_INTR_RX_ERR HAL_ISO7816_INTR_RX_ERR /**< Source rx error interrupt */ +#define APP_ISO7816_INTR_DONE HAL_ISO7816_INTR_DONE /**< Source done error interrupt */ +/** @} */ + + +/** @defgroup APP_ISO7816_CARD_PRESENCE Card Presence Defines + * @{ + */ +#define APP_ISO7816_CARD_ABSENT HAL_ISO7816_CARD_ABSENT /**< SIM Card is absent. */ +#define APP_ISO7816_CARD_PRESENT HAL_ISO7816_CARD_PRESENT /**< SIM Card is present. */ +/** @} */ + +/** @defgroup APP_ISO7816_IO_STATES IO States Defines + * @{ + */ +#define APP_ISO7816_IO_STATE_OFF HAL_ISO7816_IO_STATE_OFF /**< Off */ +#define APP_ISO7816_IO_STATE_IDLE HAL_ISO7816_IO_STATE_IDLE /**< Idle */ +#define APP_ISO7816_IO_STATE_RX_WAIT HAL_ISO7816_IO_STATE_RX_WAIT /**< Receive Wait */ +#define APP_ISO7816_IO_STATE_RX HAL_ISO7816_IO_STATE_RX /**< Receive */ +#define APP_ISO7816_IO_STATE_TX HAL_ISO7816_IO_STATE_TX /**< Transmit */ +#define APP_ISO7816_IO_STATE_TX_GUARD HAL_ISO7816_IO_STATE_TX_GUARD /**< Transmit Guard */ +/** @} */ + +/** @defgroup APP_ISO7816_PWR_STATES Power States Defines + * @{ + */ +#define APP_ISO7816_PWR_STATE_OFF HAL_ISO7816_PWR_STATE_OFF /**< Off */ +#define APP_ISO7816_PWR_STATE_PWRUP_VCC HAL_ISO7816_PWR_STATE_PWRUP_VCC /**< Power up VCC */ +#define APP_ISO7816_PWR_STATE_PWRUP_RST HAL_ISO7816_PWR_STATE_PWRUP_RST /**< Power up reset */ +#define APP_ISO7816_PWR_STATE_PWRDN_RST HAL_ISO7816_PWR_STATE_PWRDN_RST /**< Power Down reset */ +#define APP_ISO7816_PWR_STATE_PWRDN_VCC HAL_ISO7816_PWR_STATE_PWRDN_VCC /**< Power Down VCC */ +#define APP_ISO7816_PWR_STATE_STOP_PRE HAL_ISO7816_PWR_STATE_STOP_PRE /**< Preparing Clock Stop */ +#define APP_ISO7816_PWR_STATE_STOP HAL_ISO7816_PWR_STATE_STOP /**< Clock Stopped */ +#define APP_ISO7816_PWR_STATE_STOP_POST HAL_ISO7816_PWR_STATE_STOP_POST /**< Exiting Clock Stop */ +#define APP_ISO7816_PWR_STATE_IDLE HAL_ISO7816_PWR_STATE_IDLE /**< Idle */ +#define APP_ISO7816_PWR_STATE_RX_TS0 HAL_ISO7816_PWR_STATE_RX_TS0 /**< RX TS Character */ +#define APP_ISO7816_PWR_STATE_RX_TS1 HAL_ISO7816_PWR_STATE_RX_TS1 /**< RX TS Character */ +#define APP_ISO7816_PWR_STATE_RX HAL_ISO7816_PWR_STATE_RX /**< Receive */ +#define APP_ISO7816_PWR_STATE_TX HAL_ISO7816_PWR_STATE_TX /**< Transmit */ +#define APP_ISO7816_PWR_STATE_TX_RX HAL_ISO7816_PWR_STATE_TX_RX /**< Transmit and Receive */ +/** @} */ + +/** @} */ + +/** @addtogroup APP_ISO7816_ENUM Enumerations + * @{ + */ + +/** + * @brief ISO7816 operating mode Enumerations definition + */ +typedef enum +{ + APP_ISO7816_TYPE_INTERRUPT, /**< Interrupt operation mode */ + APP_ISO7816_TYPE_POLLING, /**< Polling operation mode */ + APP_ISO7816_TYPE_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_iso7816_mode_t; + +/** + * @brief ISO7816 event Enumerations definition + */ +typedef enum +{ + APP_ISO7816_EVT_ERROR, /**< Error reported by ISO7816 peripheral. */ + APP_ISO7816_EVT_ABORT, /**< Error reported by ISO7816 peripheral. */ + APP_ISO7816_EVT_PRESENCE, /**< Requested RX transfer completed. */ + APP_ISO7816_EVT_ATR_CPLT, /**< Requested TX transfer completed. */ + APP_ISO7816_EVT_TX_CPLT, /**< Requested TX transfer completed. */ + APP_ISO7816_EVT_RX_CPLT, /**< Requested RX transfer completed. */ + APP_ISO7816_EVT_TX_RX_CPLT, /**< Requested RX transfer completed. */ +} app_iso7816_evt_type_t; +/** @} */ + +/** @addtogroup APP_ISO7816_STRUCTURES Structures + * @{ + */ + +/** + * @brief ISO7816 IO configuration Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ +} app_iso7816_pin_t; + +/** + * @brief ISO7816 pin configure structure definition + */ +typedef struct +{ + app_iso7816_pin_t clk; /**< Set the configuration of ISO7816 clock pin. */ + app_iso7816_pin_t rst; /**< Set the configuration of ISO7816 reset pin. */ + app_iso7816_pin_t io; /**< Set the configuration of ISO7816 io pin. */ + app_iso7816_pin_t presence; /**< Set the configuration of ISO7816 presence pin.*/ +} app_iso7816_pin_cfg_t; + +/** + * @brief ISO7816 event structure definition + */ +typedef struct +{ + app_iso7816_evt_type_t type; /**< Type of event. */ + union + { + uint32_t error_code; /**< ISO7816 Error code. */ + uint16_t size; /**< ISO7816 transmitted/received counter. */ + } data; /**< ISO7816 union data. */ +} app_iso7816_evt_t; + +/** @} */ + +/** @addtogroup APP_ISO7816_TYPEDEFS Type definitions + * @{ + */ + +/** + * @brief ISO7816 event callback definition + */ +typedef void (*app_iso7816_evt_handler_t)(app_iso7816_evt_t *p_evt); + +/** @} */ + +/** @addtogroup APP_ISO7816_ENUM Enumerations + * @{ + */ + +/**@brief App iso7816 state types. */ +typedef enum +{ + APP_ISO7816_INVALID = 0, + APP_ISO7816_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_ISO7816_SLEEP, +#endif +} app_iso7816_state_t; + +/** @} */ + +/** @addtogroup APP_ISO7816_STRUCTURES Structures + * @{ + */ +/** + * @brief ISO7816 device structure definition + */ +typedef struct +{ + app_iso7816_evt_handler_t evt_handler; /**< ISO7816 event callback. */ + iso7816_handle_t handle; /**< ISO7816 handle Structure. */ + app_iso7816_mode_t use_mode; /**< ISO7816 operating mode Enumerations. */ + app_iso7816_pin_cfg_t *p_pin_cfg; /**< ISO7816 pin configure structure. */ + app_iso7816_state_t iso7816_state; /**< ISO7816 state configure structure. */ + bool start_flag; /**< ISO7816 start_flage. */ +}iso7816_env_t; + +/** + * @brief ISO7816 parameters structure definition + */ +typedef struct +{ + app_iso7816_mode_t use_mode; /**< Specifies the operation mode of ISO7816. */ + app_iso7816_pin_cfg_t pin_cfg; /**< The pin configuration information for the ISO7816. */ + iso7816_init_t init; /**< ISO7816 communication parameters. */ + iso7816_env_t iso7816_env; /**< ISO7816 device structure definition. */ +} app_iso7816_params_t; + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_ISO7816_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP ISO7816 DRIVER according to the specified parameters + * in the app_iso7816_params_t and app_iso7816_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_iso7816_params_t parameter which contains the + * configuration information for the specified ISO7816 module. + * @param[in] evt_handler: ISO7816 user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_iso7816_init(app_iso7816_params_t *p_params, app_iso7816_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP ISO7816 DRIVER peripheral. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_iso7816_deinit(void); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_receive_sync(uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_receive_async(uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits an amount of data in blocking mode. + * + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_transmit_sync(uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits an amount of data in non-blocking mode with Interrupt/DMA. + * + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_transmit_async(uint16_t size); + +/** + **************************************************************************************** + * @brief Transmit and receive in master mode an amount of data in blocking mode. + * + * @param[in] tx_size: Amount of data to be sent + * @param[in] rx_size: Amount of data to be receive + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_transmit_receive_sync(uint16_t tx_size, uint16_t rx_size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit and receive in master mode an amount of data in non-blocking mode. + * + * @param[in] tx_size: Amount of data to be sent + * @param[in] rx_size: Amount of data to be receive + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_iso7816_transmit_receive_async(uint16_t tx_size, uint16_t rx_size); + +/** + * @brief Request ISO7816 to go to the next action. + * @param action: This parameter can be one of the following values: + * @arg @ref APP_ISO7816_ACTION_NONE + * @arg @ref APP_ISO7816_ACTION_OFF + * @arg @ref APP_ISO7816_ACTION_STOPCLK + * @arg @ref APP_ISO7816_ACTION_ON + * @arg @ref APP_ISO7816_ACTION_WARMRST + * @arg @ref APP_ISO7816_ACTION_RX + * @arg @ref APP_ISO7816_ACTION_TX + * @arg @ref APP_ISO7816_ACTION_TXRX + * + * @return Result of operation. + */ +uint16_t app_iso7816_set_action(uint32_t action); + +/** + * @brief Get ISO7816 Power States. + * @return Returned value can be one of the following values: + * @arg @ref APP_ISO7816_PWR_STATE_OFF + * @arg @ref APP_ISO7816_PWR_STATE_PWRUP_VCC + * @arg @ref APP_ISO7816_PWR_STATE_PWRUP_RST + * @arg @ref APP_ISO7816_PWR_STATE_PWRDN_RST + * @arg @ref APP_ISO7816_PWR_STATE_PWRDN_VCC + * @arg @ref APP_ISO7816_PWR_STATE_STOP_PRE + * @arg @ref APP_ISO7816_PWR_STATE_STOP + * @arg @ref APP_ISO7816_PWR_STATE_STOP_POST + * @arg @ref APP_ISO7816_PWR_STATE_IDLE + * @arg @ref APP_ISO7816_PWR_STATE_RX_TS0 + * @arg @ref APP_ISO7816_PWR_STATE_RX_TS1 + * @arg @ref APP_ISO7816_PWR_STATE_RX + * @arg @ref APP_ISO7816_PWR_STATE_TX + * @arg @ref APP_ISO7816_PWR_STATE_TX_RX + */ +uint32_t app_iso7816_get_power_states(void); + +/** + * @brief Set divide ISO7816 clock. + * @note Divide SIM clock by this value+1 to define ETU length. The reset value + * is the one, needed for theATR. + * @param divide This parameter should range between 0x0 and 0x3FF. + * + * @return Result of operation. + */ +uint16_t app_iso7816_set_etudiv(uint32_t divide); + +/** + **************************************************************************************** + * @brief Return the ISO7816 handle. + * + * @return Pointer to the specified ID's ISO7816 handle. + **************************************************************************************** + */ +iso7816_handle_t *app_iso7816_get_handle(void); + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _APP_ISO7816_H_ */ + +/** @} */ +/** @} */ +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm.h new file mode 100644 index 0000000..2fa0c2c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm.h @@ -0,0 +1,437 @@ +/** + **************************************************************************************** + * + * @file app_pwm.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWM app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_PWM PWM + * @brief PWM APP module driver. + * @{ + */ +#ifndef _APP_PWM_H_ +#define _APP_PWM_H_ + +#include "grx_hal.h" +#include "app_io.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +#include "app_dma.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_PWM_MODULE_ENABLED + +/** @addtogroup APP_PWM_DEFINE Defines + * @{ + */ + +#define APP_PWM_PIN_ENABLE 1 /**< PWM pin enable */ +#define APP_PWM_PIN_DISABLE 0 /**< PWM pin disable */ + +/** @} */ + +/** @addtogroup APP_PWM_ENUM Enumerations + * @{ + */ + +/** + * @brief PWM module Enumerations definition + */ +typedef enum +{ + APP_PWM_ID_0, /**< PWM module 0 */ + APP_PWM_ID_1, /**< PWM module 1 */ + APP_PWM_ID_MAX /**< Only for check parameter, not used as input parameters. */ +} app_pwm_id_t; + +/** + * @brief PWM active channel Enumerations definition + */ +typedef enum +{ + APP_PWM_ACTIVE_CHANNEL_A = 0x01, /**< The active channel is A */ + APP_PWM_ACTIVE_CHANNEL_B = 0x02, /**< The active channel is B */ + APP_PWM_ACTIVE_CHANNEL_C = 0x04, /**< The active channel is C */ + APP_PWM_ACTIVE_CHANNEL_ALL = 0x07, /**< The active channels are ALL */ + APP_PWM_ACTIVE_CHANNEL_CLEARED = 0x00 /**< All active channels are cleared */ +} app_pwm_active_channel_t; + +/**@brief App pwm state types. */ +typedef enum +{ + APP_PWM_INVALID = 0, + APP_PWM_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_PWM_SLEEP, +#endif + +} app_pwm_state_t; + +/**@brief App pwm module state types. */ +typedef enum +{ + APP_PWM_STOP = 0, + APP_PWM_START, +} app_pwm_module_state_t; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + * @brief PWM event Enumerations definition + */ +typedef enum +{ + APP_PWM_CHANNEL_A_ERROR, /**< Channel A error in coding mode. */ + APP_PWM_CHANNEL_B_ERROR, /**< Channel B error in coding mode. */ + APP_PWM_CHANNEL_C_ERROR, /**< Channel C error in coding mode. */ + APP_PWM_CODING_DONE, /**< Coding done in coding mode. */ + APP_PWM_CODING_LOAD, /**< Coding load in coding mode. */ +} app_pwm_evt_type_t; +#endif + +/** @} */ + +/** @addtogroup APP_PWM_STRUCTURES Structures + * @{ + */ + +/** + * @brief PWM IO configuration Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of PWM IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ + uint8_t enable; /**< Enable or disable the pin. */ +} app_pwm_pin_t; + +/** + * @brief PWM configuration Structures + */ +typedef struct +{ + app_pwm_pin_t channel_a; /**< Set the configuration of PWM channel A pin. */ + app_pwm_pin_t channel_b; /**< Set the configuration of PWM channel B pin. */ + app_pwm_pin_t channel_c; /**< Set the configuration of PWM channel C pin. */ +} app_pwm_pin_cfg_t; + +/** + * @brief PWM Channel init Structure definition + */ +typedef struct +{ + uint8_t duty; /**< Specifies the duty in PWM output mode. + This parameter must be a number between 0 ~ 100.*/ + + uint8_t drive_polarity; /**< Specifies the drive polarity in PWM output mode. + This parameter can be a value of @ref PWM_Drive_Polarity.*/ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + uint32_t fstoplvl; /**< Specifies the PWM io level when stop. + This parameter can be a value of @ref PWM_STOP_LVL */ +#endif +} app_pwm_channel_init_t; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + * @brief PWM operate mode Enumerations definition + */ +typedef struct +{ + dma_regs_t *pwm_dma_instance; /**< Specifies the DMA instance.*/ + dma_channel_t pwm_dma_channel; /**< Specifies the dma channel of PWM. */ +} app_pwm_mode_t; + +/** + * @brief PWM event structure definition + */ +typedef struct +{ + app_pwm_evt_type_t type; /**< Type of event. */ + uint32_t error_code; /**< Error code */ +} app_pwm_evt_t; + +/** + * @brief PWM event callback definition + */ +typedef void (*app_pwm_evt_handler_t)(app_pwm_evt_t *p_evt); +#endif + +/** + * @brief PWM device structure definition + */ +typedef struct +{ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + app_pwm_evt_handler_t evt_handler; +#endif + app_pwm_pin_cfg_t *p_pin_cfg; /**< PWM configuration Structures. */ + app_pwm_state_t pwm_state; /**< App pwm state types. */ + app_pwm_module_state_t pwm_module_state; /**< App pwm module state types. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + app_pwm_mode_t use_mode; + dma_id_t dma_id[1]; +#endif + pwm_handle_t handle; /**< PWM handle Structure. */ +} pwm_env_t; + +/** + * @brief PWM parameters structure definition + */ +typedef struct +{ + app_pwm_id_t id; /**< specified PWM module ID. */ + app_pwm_pin_cfg_t pin_cfg; /**< the pin configuration information for the specified PWM module. */ + app_pwm_active_channel_t active_channel; /**< PWM operate mode. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + app_pwm_mode_t use_mode; /**< PWM operate mode. */ +#endif + pwm_init_t init; /**< PWM communication parameters. */ + pwm_env_t pwm_env; /**< PWM device structure definition. */ +} app_pwm_params_t; +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_PWM_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the pwm peripheral. + * + * @param[in] p_params: Pointer to app_pwm_params_t parameter which contains the + * configuration information for the specified PWM module. + * + * @return Result of initialization. + **************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +uint16_t app_pwm_init(app_pwm_params_t *p_params, app_pwm_evt_handler_t evt_handler); +#else +uint16_t app_pwm_init(app_pwm_params_t *p_params); +#endif + +/** + **************************************************************************************** + * @brief De-initialize the pwm peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_pwm_deinit(app_pwm_id_t id); + + +/** + **************************************************************************************** + * @brief Starts the PWM signal generation on the output. + * + * @param[in] id: which PWM module want to output. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_start(app_pwm_id_t id); + + +/** + **************************************************************************************** + * @brief Stops the PWM signal generation on the output. + * + * @param[in] id: which PWM module want to stop output. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_stop(app_pwm_id_t id); + +/** + **************************************************************************************** + * @brief Update the PWM frequency on the output. + * + * @param[in] id: which PWM module want to config. + * @param[in] freq: This parameter ranges between min = 0 and max = SystemFreq / 2. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_update_freq(app_pwm_id_t id, uint32_t freq); + +/** + **************************************************************************************** + * @brief Initialize the PWM channels according to the specified parameters. + * + * @param[in] id: which PWM module want to config. + * @param[in] channel: PWM Channels to be configured. + * @param[in] p_config: PWM Channels configuration structure. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_config_channel(app_pwm_id_t id, app_pwm_active_channel_t channel, app_pwm_channel_init_t *p_config); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + **************************************************************************************** + * @brief Resume the PWM signal generation on the output. + * + * @param[in] id: which PWM module want to output. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_resume(app_pwm_id_t id); + +/** + **************************************************************************************** + * @brief Pause the PWM signal generation on the output. + * + * @param[in] id: which PWM module want to stop output. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_pause(app_pwm_id_t id); +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Set the specified PWM channel inactive + * + * @param[in] id: PWM ID. + * @param[in] channel: PWM Channels to be configured. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_inactive_channel(app_pwm_id_t id, app_pwm_active_channel_t channel); +#endif + +/** + **************************************************************************************** + * @brief Return the PWM handle. + * + * @param[in] id: PWM ID. + * + * @return Pointer to the specified ID's PWM handle. + **************************************************************************************** + */ +pwm_handle_t *app_pwm_get_handle(app_pwm_id_t id); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + **************************************************************************************** + * @brief Set coding data in one channel mode + * + * @param[in] id: which PWM module want to config. + * @param[in] coding_data: every bit represent compa0 or compa1 in coding data. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_set_coding_data_in_one_channel(app_pwm_id_t id, uint32_t coding_data); + +/** + **************************************************************************************** + * @brief Set coding data in three channels mode + * + * @param[in] id: which PWM module want to config. + * @param[in] coding_data0: every bit represent compa0 or compa1 in coding data0. + * @param[in] coding_data1: every bit represent compb0 or compb1 in coding data1. + * @param[in] coding_data2: every bit represent compc0 or compc1 in coding data2. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_set_coding_data_in_three_channels(app_pwm_id_t id, uint32_t coding_data0, uint32_t coding_data1, uint32_t coding_data2); + +/** + **************************************************************************************** + * @brief Start generate one channel wave form in Interrupt mode + * + * @param[in] id: which PWM module want to config. + * @param[in] coding_data: every bit represent compa0 or compa1 in coding data. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_start_coding_in_one_channel(app_pwm_id_t id, uint32_t coding_data); + +/** + **************************************************************************************** + * @brief Start generate three channels wave form in Interrupt mode + * + * @param[in] id: which PWM module want to config. + * @param[in] coding_data0: every bit represent compa0 or compa1 in coding data0. + * @param[in] coding_data1: every bit represent compb0 or compb1 in coding data1. + * @param[in] coding_data2: every bit represent compc0 or compc1 in coding data2. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_start_coding_in_three_channels(app_pwm_id_t id, uint32_t coding_data0, uint32_t coding_data1, uint32_t coding_data2); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm_dma.h new file mode 100644 index 0000000..8dc7d3c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwm_dma.h @@ -0,0 +1,125 @@ +/** + **************************************************************************************** + * + * @file app_pwm_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWM app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +#ifndef _APP_PWM_DMA_H_ +#define _APP_PWM_DMA_H_ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_PWM PWM + * @brief PWM APP module driver. + * @{ + */ + + +#include "app_io.h" +#include "app_dma.h" +#include "app_pwm.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_PWM_MODULE_ENABLED +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_PWM_DMA_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP PWM DMA DRIVER according to the specified parameters + * in the app_pwm_params_t and app_pwm_evt_handler_t. + * + * @param[in] p_params: Pointer to app_pwm_params_t parameter which contains the + * configuration information for the specified PWM module. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_pwm_dma_init(app_pwm_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize the APP PWM DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_pwm_dma_deinit(app_pwm_id_t id); + +/** + **************************************************************************************** + * @brief Start generate wave form in DMA mode + * + * @param[in] id: which PWM module want to config. + * @param[in] p_data: the coding data address. + * @param[in] size: coding data size. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_pwm_start_coding_with_dma(app_pwm_id_t id, uint32_t *p_data, uint16_t size); + +/** @} */ + + +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwr_mgmt.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwr_mgmt.h new file mode 100644 index 0000000..7bb92a8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_pwr_mgmt.h @@ -0,0 +1,131 @@ +/** + **************************************************************************************** + * + * @file app_pwr_mgmt.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of UART PWR library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_PWR_MGMT PWR MGMT + * @brief PWR MGMT APP module driver. + * @{ + */ + + +#ifndef _APP_PWR_MGMT_H_ +#define _APP_PWR_MGMT_H_ + +#include "grx_sys.h" +#include "app_drv_config.h" +#include +#include + +/** @addtogroup APP_PWR_DEFINE Defines + * @{ + */ +/** + * @brief PWR MAX value for sleep check + */ +#define APP_SLEEP_CB_MAX 16 +/** @} */ + +/** @addtogroup APP_PWR_STRUCTURES Structures + * @{ + */ +/** + * @brief PWR id + */ +typedef int16_t pwr_id_t; + +/** + * @brief PWR sleep check function Structure + */ +typedef struct +{ + bool (*app_prepare_for_sleep)(void); /** +#include "grx_hal.h" +#include "app_io.h" +#include "app_qspi.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#include "app_qspi_user_config.h" +#endif +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_QSPI_MODULE_ENABLED + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_APP_QSPI_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP QSPI DRIVER according to the specified parameters + * in the app_qspi_params_t and app_qspi_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_qspi_params_t parameter which contains the + * configuration information for the specified QSPI module. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_qspi_dma_init(app_qspi_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize the APP QSPI DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_qspi_dma_deinit(app_qspi_id_t id); + +/** + **************************************************************************************** + * @brief Receive an amount of data with the specified instruction, address and dummy cycles in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Read Mode. + * @param[in] id: which QSPI module want to receive. + * @param[in] p_cmd: Pointer to a app_qspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_command_receive_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Receive an amount of data with the specified instruction, address and dummy cycles in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Read Mode. + * @param[in] id: which QSPI module want to transmit. + * @param[in] p_cmd: Pointer to a app_qspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_command_transmit_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Transmit instruction in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Write Mode. + * @param[in] id: which QSPI module want to transmit command. + * @param[in] p_cmd: Pointer to a app_qspi_command_t structure that contains the instruction and address for data transfer. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_command_async(app_qspi_id_t id, app_qspi_command_t *p_cmd); + +/** + **************************************************************************************** + * @brief Transmit data without command, support std/dual/quad mode + * + * @param[in] id : QSPI module ID. + * @param[in] qspi_mode : @ref QSPI_DATA_MODE_SPI + * @ref QSPI_DATA_MODE_DUALSPI + * @ref QSPI_DATA_MODE_QUADSPI + * @param[in] data_width :@ref QSPI_DATASIZE_08_BITS + * @ref QSPI_DATASIZE_16_BITS + * @ref QSPI_DATASIZE_32_BITS + * @param[in] p_data : data Pointer to transmit + * @param[in] length : byte length of data + * + * @return true/false + **************************************************************************************** + */ +uint16_t app_qspi_dma_transmit_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode at standard SPI with Interrupt. + * @note This function is used only in Indirect Write Mode. + * @param[in] id: which QSPI module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_transmit_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length); +#endif + +/** + **************************************************************************************** + * @brief Receive data without command, support std/dual/quad mode + * + * @param[in] id : QSPI module ID. + * @param[in] qspi_mode : @ref QSPI_DATA_MODE_SPI + * @ref QSPI_DATA_MODE_DUALSPI + * @ref QSPI_DATA_MODE_QUADSPI + * @param[in] data_width :@ref QSPI_DATASIZE_08_BITS + * @ref QSPI_DATASIZE_16_BITS + * @ref QSPI_DATASIZE_32_BITS + * @param[in] p_data : data Pointer to transmit + * @param[in] length : byte length of data + * + * @return true/false + **************************************************************************************** + */ +uint16_t app_qspi_dma_receive_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode at standard SPI with Interrupt. + * @note This function is used only in Indirect Read Mode. + * @param[in] id: which QSPI module want to receive. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_receive_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Transmit an amount of data in QPI mode (Async Mode). + * @param[in] id: Which QSPI module want to Transmit. + * @param[in] data_width: Just support @ref QSPI_DATASIZE_08_BITS @ref QSPI_DATASIZE_16_BITS @ref QSPI_DATASIZE_32_BITS + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be transmitted in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_qspi_dma_transmit_in_qpi_async(app_qspi_id_t id, uint32_t data_width, uint8_t *p_data, uint32_t length); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rng.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rng.h new file mode 100644 index 0000000..6362c63 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rng.h @@ -0,0 +1,219 @@ +/** + **************************************************************************************** + * + * @file app_rng.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of RNG app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_RNG RNG + * @brief RNG APP module driver. + * @{ + */ + + +#ifndef _APP_RNG_H_ +#define _APP_RNG_H_ + +#include "grx_hal.h" +#include "app_drv_error.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_RNG_MODULE_ENABLED + +/** @addtogroup APP_RNG_ENUM Enumerations + * @{ + */ + +/** + * @brief RNG operating mode Enumerations definition + */ +typedef enum +{ + APP_RNG_TYPE_INTERRUPT, /**< Interrupt operation mode */ + APP_RNG_TYPE_POLLING, /**< Polling operation mode */ + APP_RNG_TYPE_MAX /**< Only for check parameter, not used as input parameters. */ +} app_rng_type_t; + +/** + * @brief RNG event Enumerations definition + */ +typedef enum +{ + APP_RNG_EVT_DONE, /**< Generated random by UART peripheral. */ + APP_RNG_EVT_ERROR, /**< Error reported by UART peripheral. */ +} app_rng_evt_type_t; +/** @} */ + +/** @addtogroup HAL_APP_RNG_STRUCTURES Structures + * @{ + */ +/** + * @brief RNG event structure definition + */ +typedef struct +{ + app_rng_evt_type_t type; /**< Type of event. */ + uint32_t random_data; /**< Random number. */ +} app_rng_evt_t; + +/** + * @brief RNG event callback definition + */ +typedef void (*app_rng_evt_handler_t)(app_rng_evt_t *p_evt); + +/**@brief App rng state types. */ +typedef enum +{ + APP_RNG_INVALID = 0, + APP_RNG_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_RNG_SLEEP, +#endif +} app_rng_state_t; + +/** + * @brief RNG device structure definition + */ +typedef struct +{ + app_rng_evt_handler_t evt_handler; /**< RNG event callback. */ + rng_handle_t handle; /**< RNG handle Structure. */ + app_rng_type_t use_type; /**< RNG operating mode. */ + app_rng_state_t rng_state; /**< App rng state types. */ +} rng_env_t; +/** + * @brief RNG parameters structure definition + */ +typedef struct +{ + app_rng_type_t use_type; /**< Specifies the operation mode of RNG. */ + rng_init_t init; /**< RNG required parameters. */ + rng_env_t rng_env; /**< RNG device structure definition. */ +} app_rng_params_t; + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_RNG_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the APP RNG DRIVER according to the specified parameters + * in the app_rng_params_t and app_rng_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_rng_params_t parameter which contains the + * configuration information for the specified RNG module. + * @param[in] evt_handler: RNG user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_rng_init(app_rng_params_t *p_params, app_rng_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP RNG DRIVER peripheral. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_rng_deinit(void); + +/** + **************************************************************************************** + * @brief Generate a 32-bit random number. + * + * @param[in] p_seed: user configured seeds. the seed is valid when seed_mode member of + * rng_init_t is configured as RNG_SEED_USER. If 59-bit random number is + * selected, the seed need to provide [0~58] bit spaces. If 128-bit random + * number is selected, the seed need to provide [0~127] bit spaces. + * @param[out] p_random32bit: Pointer to generated random number variable if successful. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rng_gen_sync(uint16_t *p_seed, uint32_t *p_random32bit); + +/** + **************************************************************************************** + * @brief Generate a 32-bit random number in interrupt mode. + * + * @param[in] p_seed: user configured seeds. the seed is valid when seed_mode member of + * rng_init_t is configured as RNG_SEED_USER. If 59-bit random number is + * selected, the seed need to provide [0~58] bit spaces. If 128-bit random + * number is selected, the seed need to provide [0~127] bit spaces. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rng_gen_async(uint16_t *p_seed); + +/** + **************************************************************************************** + * @brief Return the RNG handle. + * + * @return Pointer to the RNG handle. + **************************************************************************************** + */ +rng_handle_t *app_rng_get_handle(void); + +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtc.h new file mode 100644 index 0000000..008924a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtc.h @@ -0,0 +1,232 @@ +/** + **************************************************************************************** + * + * @file app_rtc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of RTC app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_RTC RTC + * @brief RTC APP module driver. + * @{ + */ + + +#ifndef _APP_RTC_H_ +#define _APP_RTC_H_ + +#include "grx_hal.h" +#include "app_drv_error.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_CALENDAR_MODULE_ENABLED + +/** @addtogroup APP_RTC_DEFINE Defines + * @{ + */ + +/** + * @brief App rtc time disable macro definition + */ + +#define APP_RTC_ALARM_DISABLE_DATE CALENDAR_ALARM_DISABLE_DATE /**< Disable rtc date alarm */ +#define APP_RTC_ALARM_DISABLE_TICK CALENDAR_ALARM_DISABLE_TICK /**< Disable rtc tick alarm */ +#define APP_RTC_ALARM_DISABLE_ALL CALENDAR_ALARM_DISABLE_ALL /**< Disable rtc all alarm */ +/** @} */ + +/** @addtogroup APP_RTC_ENUM Enumerations + * @{ + */ +/** + * @brief RTC event Enumerations definition + */ +typedef enum +{ + APP_RTC_EVT_DATE_ALARM, /**< Date alarm event. */ + APP_RTC_EVT_TICK_ALARM, /**< Tick alarm event. */ + APP_RTC_EVT_OVERFLOW, /**< Overflow event. */ +} app_rtc_evt_type_t; +/** @} */ + +/** @addtogroup APP_RTC_STRUCTURES Structures + * @{ + */ +/** + * @brief App time structure definition + */ +typedef calendar_time_t app_rtc_time_t; + +/** + * @brief App alarm structure definition + */ +typedef calendar_alarm_t app_rtc_alarm_t; + + +/** + * @brief RTC event structure definition + */ +typedef struct +{ + app_rtc_evt_type_t type; /**< Type of event. */ +} app_rtc_evt_t; + +/** + * @brief RTC event callback definition + */ +typedef void (*app_rtc_evt_handler_t)(app_rtc_evt_t *p_evt); + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_RTC_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP RTC DRIVER. + * + * @param[in] evt_handler: RTC user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_rtc_init(app_rtc_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the app rtc. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_rtc_deinit(void); + +/** + **************************************************************************************** + * @brief Initialize the rtc time. + * + * @param[in] p_time: Pointer to a app_rtc_time_t time struction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rtc_init_time(app_rtc_time_t *p_time); + +/** + **************************************************************************************** + * @brief Get current rtc time. + * + * @param[in] p_time: Pointer to a app_rtc_time_t time struction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rtc_get_time(app_rtc_time_t *p_time); + +/** + **************************************************************************************** + * @brief Set a rtc date alarm. + * + * @param[in] p_alarm: After seconds will generate an date alarm interrupt. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rtc_setup_alarm(app_rtc_alarm_t *p_alarm); + +/** + **************************************************************************************** + * @brief Set a rtc tick alarm. + * + * @param[in] interval: After milliseconds will generate an tick alarm interrupt. + * The value of interval is greater than or equal to 10ms. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rtc_setup_tick(uint32_t interval); + +/** + **************************************************************************************** + * @brief Disable rtc alarm event. + * + * @param[in] disable_mode: Disable specified CALENDAR alarm mode. + * This parameter can be the following values: + * @arg @ref APP_RTC_ALARM_DISABLE_DATE + * @arg @ref APP_RTC_ALARM_DISABLE_TICK + * @arg @ref APP_RTC_ALARM_DISABLE_ALL + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_rtc_disable_event(uint32_t disable_mode); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + **************************************************************************************** + * @brief Synchronous RTC low speed clock. + * + * @param[in] SlowClockFreq: Number of slow clocks + * + * @return None. + **************************************************************************************** + */ +void app_rtc_time_sync(uint16_t SlowClockFreq); +#endif +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ +/** @} */ +/** @} */ + + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtos_cfg.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtos_cfg.h new file mode 100644 index 0000000..e2909e3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_rtos_cfg.h @@ -0,0 +1,280 @@ +/** + **************************************************************************************** + * + * @file app_rtos_cfg.h + * @author BLE Driver Team + * @brief Header file of app rtos config code. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_RTOS_CONFIG RTOS CONFIG + * @brief ADC RTOS CONFIG + * @{ + */ + + +#ifndef __APP_RTOS_ADAPTER_H +#define __APP_RTOS_ADAPTER_H +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include + +#ifdef ENV_USE_FREERTOS + +#include "FreeRTOS.h" +#include "semphr.h" + +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define ENV_USE_RTOS +/** @} */ + +/** + * @defgroup APP_RTOS_CONFIG_TYPEDEF Typedefs + * @{ + */ + +/** + * @brief Semaphore type definition + */ +typedef SemaphoreHandle_t sem_t; + +/** + * @brief mutex type definition + */ +typedef SemaphoreHandle_t mutex_t; + +/** @} */ + +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define OS_WAIT_FOREVER portMAX_DELAY /**< Block forever until get resource */ + +#define SEM_WAIT_FOREVER portMAX_DELAY /**< Wait for the semaphore forever */ +#define SEM_NO_WAIT (0) /**< Non-block */ + +#define MUTEX_WAIT_FOREVER portMAX_DELAY /**< Wait for the mutex forever */ +#define MUTEX_NO_WAIT (0) /**< Non-block */ +/** @} */ + +#else + +/** + * @defgroup APP_RTOS_CONFIG_TYPEDEF Typedefs + * @{ + */ + +/** + * @brief Semaphore type definition + */ +typedef void * sem_t; + +/** + * @brief mutex type definition + */ +typedef void * mutex_t; +/** @} */ + +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define SEM_WAIT_FOREVER (0xFFFFUL) /**< Wait for the semaphore forever. */ +#define SEM_NO_WAIT (0) /**< Non-block */ + +#define MUTEX_WAIT_FOREVER (0xFFFFUL) /**< Wait for the mutex forever */ +#define MUTEX_NO_WAIT (0) /**< Non-block */ +/** @} */ + +#endif + +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define APP_DRV_SEM_DECL(sem) sem_t sem /**< Define a semaphore instance */ +#define APP_DRV_MUTEX_DECL(mutex) mutex_t mutex /**< Define a mutex instance */ + +#define APP_DRV_SEM_STATIC(sem) static APP_DRV_SEM_DECL(sem) /**< Define a static semaphore instance */ +#define APP_DRV_MUTEX_STATIC(mutex) static APP_DRV_MUTEX_DECL(mutex) /**< Define a static mutex instance */ +/** @} */ + +#ifdef ENV_USE_RTOS +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define ENV_RTOS_USE_SEMP 1 /**< Enable semaphore in app driver */ +//#define ENV_RTOS_USE_MUTEX 1 /**< Enable mutex in app driver */ +/** @} */ + +/** @addtogroup APP_RTOS_CONFIG_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize a semaphore. + * + * @param[in] sem: Pointer to a sem_t parameter which contains the address of the semaphore object. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_driver_sem_init(sem_t *sem); + +/** + **************************************************************************************** + * @brief De-initialize a semaphore. + * + * @param[in] sem: the semaphore object. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +void app_driver_sem_deinit(sem_t sem); + +/** + **************************************************************************************** + * @brief This function will take a semaphore, if the semaphore is unavailable, the + thread shall wait for a specified time. + * + * @param[in] sem: The semaphore object. + * @param[in] time_out: The waiting time in milliseconds. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_driver_sem_pend(sem_t sem, uint32_t time_out); + +/** + **************************************************************************************** + * @brief This function will release a semaphore, if there are threads suspended on + * semaphore, it will be waked up. + * + * @param[in] sem: The semaphore object. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_driver_sem_post(sem_t sem); + +/** + **************************************************************************************** + * @brief This function will release a semaphore, it is used in interrupt service function, + * if there are threads suspended on semaphore, it will be waked up. + * + * @param[in] sem: The semaphore object. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_driver_sem_post_from_isr(sem_t sem); + +/** + **************************************************************************************** + * @brief Initialize a mutex. + * + * @param[in] mutex: Pointer to mutex_t parameter which contains the address of the mutex object. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_driver_mutex_init(mutex_t *mutex); + +/** + **************************************************************************************** + * @brief De-initialize a mutex. + * + * @param[in] mutex: the mutex object. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +void app_driver_mutex_deinit(mutex_t mutex); + +/** + **************************************************************************************** + * @brief This function will take a mutex, if the mutex is unavailable, the thread shall + * wait for a specified time. + * + * @param[in] mutex: The mutex object. + * @param[in] time_out: The waiting time in milliseconds. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_driver_mutex_pend(mutex_t mutex, uint32_t time_out); + +/** + **************************************************************************************** + * @brief This function will release a mutex, if there are threads suspended on mutex, + * it will be waked up. + * + * @param[in] mutex: The mutex object. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_driver_mutex_post(mutex_t mutex); +/** @} */ + +#else +/** @addtogroup APP_RTOS_CONFIG_DEFINES Defines + * @{ + */ +#define app_driver_sem_init(x) (0) /**< Initialize the semaphore. */ +#define app_driver_sem_deinit(x) /**< Deinitialize the semphore. */ +#define app_driver_sem_pend(x, y) (0) /**< Pend the semaphore. */ +#define app_driver_sem_post(x) /**< Post the semaphore. */ +#define app_driver_sem_post_from_isr(x) /**< Post the semaphore from interrupt. */ + +#define app_driver_mutex_init(x) (0) /**< Initialize the mutex. */ +#define app_driver_mutex_deinit(x) /**< Deinitialize the mutex. */ +#define app_driver_mutex_pend(x, y) /**< Pend the mutex. */ +#define app_driver_mutex_post(x) /**< Post the mutex. */ +/** @} */ + +#endif + +#endif +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_soft_encoder.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_soft_encoder.h new file mode 100644 index 0000000..8ca487a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_soft_encoder.h @@ -0,0 +1,141 @@ +/** + **************************************************************************************** + * + * @file app_soft_encoder.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of TIM app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_SOFT_ENCODER SOFT ENCODER + * @brief SOFT ENCODER APP module driver. + * @{ + */ + + +#ifndef _APP_SOFT_ENCODER_H_ +#define _APP_SOFT_ENCODER_H_ + +#include "app_drv_error.h" +#include "app_drv_config.h" +#include "app_io.h" +#include "app_gpiote.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup APP_SOFT_ENCODER_ENUM Enumerations + * @{ + */ + +/** + * @brief SOFT_ENCODER module Enumerations definition + */ +typedef enum +{ + APP_SOFT_ENCODER_SIGNAL_A = 0, + APP_SOFT_ENCODER_SIGNAL_B, + APP_SOFT_ENCODER_SINGAL_NUMBER, +} app_soft_encoder_signal_t; + +/** + * @brief SOFT_ENCODER module DIRECTION definition + */ +typedef enum +{ + APP_SOFT_ENCODER_STOP, + APP_SOFT_ENCODER_POSITIVE, + APP_SOFT_ENCODER_REVERSE, +} app_soft_encoder_direction_t; + +/** @} */ + +/** @addtogroup APP_SOFT_ENCODER_STRUCTURES Structures + * @{ + */ + +/** + * @brief SOFT_ENCODER io config + */ +typedef struct +{ + app_io_type_t type; + uint32_t pin; + app_io_mode_t mode; + app_io_pull_t pull; +} app_soft_encoder_io_param_t; + +/** + * @brief SOFT_ENCODER event callback definition + */ +typedef void (*app_soft_encoder_callback)(app_soft_encoder_direction_t direction,int distance); + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_SOFT_ENODER_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP TIM DRIVER according to the specified parameters + * in the app_soft_encoder_params_t and app_soft_encoder_evt_handler_t. + * + * @param[in] p_params: Pointer to app_soft_encoder_params_t parameter which contains the + * configuration information for the specified SOFT_ENODER module. + * @param[in] evt_handler: SOFT_ENODER user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_soft_encoder_init(app_soft_encoder_io_param_t *p_a_params, + app_soft_encoder_io_param_t *p_b_params, + app_soft_encoder_callback evt_handler); +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ +/** @} */ +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi.h new file mode 100644 index 0000000..fbaf861 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi.h @@ -0,0 +1,486 @@ +/** + **************************************************************************************** + * + * @file app_spi.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of SPI app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_SPI SPI + * @brief SPI APP module driver. + * @{ + */ + + +#ifndef _APP_SPI_H_ +#define _APP_SPI_H_ + +#include "app_io.h" +#include "app_dma.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#include +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_SPI_MODULE_ENABLED + +/** @addtogroup APP_SPI_DEFINE Defines + * @{ + */ + +#define APP_SPI_PIN_ENABLE 1 /**< SPI pin enable */ +#define APP_SPI_PIN_DISABLE 0 /**< SPI pin disable */ + +/** @} */ + +/** @addtogroup APP_SPI_ENUM Enumerations + * @{ + */ + +/** + * @brief SPI module Enumerations definition + */ +typedef enum +{ + APP_SPI_ID_SLAVE, /**< SPI slave module. */ + APP_SPI_ID_MASTER, /**< SPI master module. */ + APP_SPI_ID_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_spi_id_t; + + +/** + * @brief SPI event Enumerations definition + */ +typedef enum +{ + APP_SPI_EVT_ERROR, /**< Error reported by UART peripheral. */ + APP_SPI_EVT_TX_CPLT, /**< Requested TX transfer completed. */ + APP_SPI_EVT_RX_CPLT, /**< Requested RX transfer completed. */ + APP_SPI_EVT_TX_RX_CPLT, /**< Requested TX/RX transfer completed. */ + APP_SPI_EVT_ABORT, /**< Abort reported by SPI peripheral. */ +} app_spi_evt_type_t; +/** @} */ + +/** @addtogroup APP_SPI_STRUCTURES Structures + * @{ + */ +/** + * @brief SPI IO Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of SPI IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_mode_t mode; /**< Specifies the mode for the selected pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ + uint8_t enable; /**< Enable or disable the pin. */ +} app_spi_pin_t; + +/** + * @brief SPI IO configuration Structures + */ +typedef struct +{ + app_spi_pin_t cs; /**< Set the configuration of SPI CS pin. */ + app_spi_pin_t clk; /**< Set the configuration of SPI CLK pin. */ + app_spi_pin_t mosi; /**< Set the configuration of SPI MOSI pin. */ + app_spi_pin_t miso; /**< Set the configuration of SPI MISO pin. */ +} app_spi_pin_cfg_t; + +/** + * @brief SPI configuration definition. + */ +typedef struct +{ + dma_regs_t * tx_dma_instance; /**< Specifies the TX DMA inistall. */ + dma_regs_t * rx_dma_instance; /**< Specifies the RX DMA inistall. */ + dma_channel_t tx_dma_channel; /**< Specifies the dma channel of SPI TX. */ + dma_channel_t rx_dma_channel; /**< Specifies the dma channel of SPI RX. */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + uint32_t wait_timeout_ms; /**< Specifies timout time of polling and dead wait, ms. */ + uint32_t extend; /**< Specifies extend segment, to use */ +#endif +} app_spi_dma_cfg_t; + +/** + * @brief SPI event structure definition + */ +typedef struct +{ + app_spi_evt_type_t type; /**< Type of event. */ + union + { + uint32_t error_code; /**< SPI Error code . */ + uint16_t size; /**< SPI transmitted/received counter. */ + } data; /**< SPI data. */ +} app_spi_evt_t; +/** + * @brief SPI event callback definition + */ +typedef void (*app_spi_evt_handler_t)(app_spi_evt_t *p_evt); + +/**@brief App spi state types. */ +typedef enum +{ + APP_SPI_INVALID = 0, + APP_SPI_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_SPI_SLEEP, +#endif +} app_spi_state_t; + +/**@brief App spi dma state types. */ +typedef enum +{ + APP_SPI_DMA_INVALID = 0, + APP_SPI_DMA_ACTIVITY, +} app_spi_dma_state_t; + +/** + * @brief SPI device structure definition + */ +typedef struct +{ + app_spi_evt_handler_t evt_handler; /**< SPI event callback. */ + spi_handle_t handle; /**< SPI handle Structure. */ + app_spi_pin_cfg_t *p_pin_cfg; /**< SPI IO configuration Structures. */ + dma_id_t dma_id[2]; /**< DMA id. */ + app_spi_state_t spi_state; /**< App spi state types. */ + app_spi_dma_state_t spi_dma_state; /**< App spi dma state types. */ + volatile bool start_flag; /**< start flag. */ + volatile bool is_soft_cs; /**< soft cs. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + volatile uint8_t rx_done; /**< rx done. */ + volatile uint8_t tx_done; /**< tx done. */ +#endif +} spi_env_t; + +/** + * @brief SPI parameters structure definition + */ +typedef struct +{ + app_spi_id_t id; /**< specified SPI module ID. */ + app_spi_pin_cfg_t pin_cfg; /**< the pin configuration information for the specified SPI module. */ + app_spi_dma_cfg_t dma_cfg; /**< SPI DMA configuration. */ + spi_init_t init; /**< SPI communication parameters. */ + bool is_soft_cs; /**< config whether to control CS signal by software */ + spi_env_t spi_env; /**< SPI device structure definition. */ +} app_spi_params_t; + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_SPI_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP SPI DRIVER according to the specified parameters + * in the app_spi_params_t and app_spi_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_spi_params_t parameter which contains the + * configuration information for the specified SPI module. + * @param[in] evt_handler: SPI user callback function. + * + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_spi_init(app_spi_params_t *p_params, app_spi_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP SPI DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_spi_deinit(app_spi_id_t id); + +/** + **************************************************************************************** + * @brief Abort spi communication with Interrupt. + * + * @param[in] id: SPI module ID. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_abort(app_spi_id_t id); + +/** + **************************************************************************************** + * @brief SPI master transmit with 1-byte inst and 3-byte addr, can use to write flash/display/eeprom, etc + * @note DO NOT Support interrupt mode + * @param[in] id : just support APP_SPI_ID_MASTER + * @param[in] instruction : 1-byte instruction phase + * @param[in] address : 3-byte address phase + * @param[in] p_data : pointer to transmit buffer + * @param[in] data_length : length of buffer, unit in byte + * + * @return APP_DRV_* in app_drv_error.h + **************************************************************************************** + */ +uint16_t app_spim_transmit_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t * p_data, uint16_t data_length); + +/** + **************************************************************************************** + * @brief SPI master receive with 1-byte inst and 3-byte addr and 0~4 dummy Byte, can use to read flash/display/eeprom, etc + * + * @param[in] id : just support APP_SPI_ID_MASTER + * @param[in] instruction : 1-byte instruction phase + * @param[in] address : 3-byte address phase + * @param[in] dummy_bytes : dummy bytes, 0 ~ 4 + * @param[in] p_data : pointer to transmit buffer + * @param[in] data_length : length of buffer, unit in byte + * + * @return APP_DRV_* in app_drv_error.h + **************************************************************************************** + */ +uint16_t app_spim_receive_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t dummy_bytes, uint8_t * p_data, uint16_t data_length); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_receive_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_receive_async(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_transmit_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_transmit_async(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits and receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to tx data buffer + * @param[in] p_rx_data: Pointer to rx data buffer + * @param[in] size: Amount of data to be sent and receive + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_transmit_receive_sync(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits and receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to tx data buffer + * @param[in] p_rx_data: Pointer to rx data buffer + * @param[in] size: Amount of data to be sent and receive + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_transmit_receive_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in blocking mode. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_size: Amount of data to be sent in bytes + * @param[in] rx_size: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_read_eeprom_sync(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with Interrupt. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_size: Amount of data to be sent in bytes + * @param[in] rx_size: Amount of data to be received in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_read_eeprom_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size); + +/** + **************************************************************************************** + * @brief Return the SPI handle. + * + * @param[in] id: SPI Channel ID. + * + * @return Pointer to the specified ID's SPI handle. + **************************************************************************************** + */ +spi_handle_t *app_spi_get_handle(app_spi_id_t id); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with DMA + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_cmd_data: Pointer to command data buffer + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[in] cmd_size: Amount of command data to be sent in bytes + * @param[in] tx_size: Amount of data to be sent in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_write_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_tx_data, uint32_t cmd_size, uint32_t tx_size); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with DMA. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_cmd_data: Pointer to command data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] cmd_size: Amount of command data to be sent in bytes + * @param[in] rx_size: Amount of data to be received in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_read_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_rx_data, uint32_t cmd_size, uint32_t rx_size); + +/** + **************************************************************************************** + * @brief [High speed] Receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_receive_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief [High speed] Transmit in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_transmit_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi_dma.h new file mode 100644 index 0000000..7d2ed9c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_spi_dma.h @@ -0,0 +1,256 @@ +/** + **************************************************************************************** + * + * @file app_spi_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of SPI app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_SPI SPI + * @brief SPI APP module driver. + * @{ + */ + + +#ifndef _APP_SPI_DMA_H_ +#define _APP_SPI_DMA_H_ + +#include "app_io.h" +#include "app_dma.h" +#include "app_spi.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#include +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_SPI_MODULE_ENABLED + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_SPI_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP SPI DRIVER according to the specified parameters + * in the app_spi_params_t and app_spi_evt_handler_t. + * @note If interrupt mode is set, you can use blocking mode. Conversely, if blocking mode + * is set, you can't use interrupt mode. + * + * @param[in] p_params: Pointer to app_spi_params_t parameter which contains the + * configuration information for the specified SPI module. + * + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_spi_dma_init(app_spi_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize the APP SPI DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_spi_dma_deinit(app_spi_id_t id); +/** + **************************************************************************************** + * @brief SPI master transmit with 1-byte inst and 3-byte addr, can use to write flash/display/eeprom, etc + * @note DO NOT Support interrupt mode + * @param[in] id : just support APP_SPI_ID_MASTER + * @param[in] instruction : 1-byte instruction phase + * @param[in] address : 3-byte address phase + * @param[in] p_data : pointer to transmit buffer + * @param[in] data_length : length of buffer, unit in byte + * + * @return APP_DRV_* in app_drv_error.h + **************************************************************************************** + */ +uint16_t app_spim_dma_transmit_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t * p_data, uint16_t data_length); + +/** + **************************************************************************************** + * @brief SPI master receive with 1-byte inst and 3-byte addr and 0~4 dummy Byte, can use to read flash/display/eeprom, etc + * + * @param[in] id : just support APP_SPI_ID_MASTER + * @param[in] instruction : 1-byte instruction phase + * @param[in] address : 3-byte address phase + * @param[in] dummy_bytes : dummy bytes, 0 ~ 4 + * @param[in] p_data : pointer to transmit buffer + * @param[in] data_length : length of buffer, unit in byte + * + * @return APP_DRV_* in app_drv_error.h + **************************************************************************************** + */ +uint16_t app_spim_dma_receive_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t dummy_bytes, uint8_t * p_data, uint16_t data_length); + +/** + **************************************************************************************** + * @brief Receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_receive_async(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_transmit_async(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmits and receive in master or slave mode an amount of data in non-blocking mode with Interrupt + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to tx data buffer + * @param[in] p_rx_data: Pointer to rx data buffer + * @param[in] size: Amount of data to be sent and receive + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_transmit_receive_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with Interrupt. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_size: Amount of data to be sent in bytes + * @param[in] rx_size: Amount of data to be received in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_read_eeprom_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/** + **************************************************************************************** + * @brief Transmits in master or slave mode an amount of data in non-blocking mode with DMA + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_cmd_data: Pointer to command data buffer + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[in] cmd_size: Amount of command data to be sent in bytes + * @param[in] tx_size: Amount of data to be sent in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_write_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_tx_data, uint32_t cmd_size, uint32_t tx_size); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with DMA. + * + * @param[in] id: which SPI module want to transmit. + * @param[in] p_cmd_data: Pointer to command data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] cmd_size: Amount of command data to be sent in bytes + * @param[in] rx_size: Amount of data to be received in bytes + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_read_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_rx_data, uint32_t cmd_size, uint32_t rx_size); + +/** + **************************************************************************************** + * @brief [High speed] Receive in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_receive_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief [High speed] Transmit in master or slave mode an amount of data in blocking mode. + * + * @param[in] id: which SPI module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_spi_dma_transmit_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_tim.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_tim.h new file mode 100644 index 0000000..199e614 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_tim.h @@ -0,0 +1,256 @@ +/** + **************************************************************************************** + * + * @file app_tim.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of TIM app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_TIMER TIMER + * @brief TIMER APP module driver. + * @{ + */ + + +#ifndef _APP_TIM_H_ +#define _APP_TIM_H_ + +#include "grx_hal.h" +#include "app_drv_error.h" +#include "app_drv_config.h" +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_TIMER_MODULE_ENABLED + +/** @addtogroup APP_TIM_ENUM Enumerations + * @{ + */ + +/** + * @brief TIM module Enumerations definition + */ +typedef enum +{ + APP_TIM_ID_0, /**< TIMER module 0 */ + APP_TIM_ID_1, /**< TIMER module 1 */ + APP_TIM_ID_MAX /**< Only for check parameter, not used as input parameters. */ +} app_tim_id_t; + +/** + * @brief TIM event Enumerations definition + */ +typedef enum +{ + APP_TIM_EVT_ERROR, /**< Error reported by TIMER peripheral. */ + APP_TIM_EVT_DONE, /**< Countdone event by TIMER peripheral. */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + APP_TIM_EVT_CHANNEL0, /**< Channle0 event by TIMER peripheral. */ + APP_TIM_EVT_CHANNEL1, /**< Channle1 event by TIMER peripheral. */ + APP_TIM_EVT_CHANNEL2, /**< Channle2 event by TIMER peripheral. */ + APP_TIM_EVT_CHANNEL3, /**< Channle3 event by TIMER peripheral. */ +#endif +} app_tim_evt_t; +/** @} */ + +/** @addtogroup APP_TIM_STRUCTURES Structures + * @{ + */ + +/** + * @brief TIM event callback definition + */ +typedef void (*app_tim_evt_handler_t)(app_tim_evt_t *p_evt); + +/**@brief App tim state types. */ +typedef enum +{ + APP_TIM_INVALID = 0, + APP_TIM_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_TIM_SLEEP, +#endif +} app_tim_state_t; + +/** + * @brief TIM device structure definition + */ +typedef struct +{ + app_tim_evt_handler_t evt_handler; /**< TIM event callback. */ + timer_handle_t handle; /**< TIMER handle Structure. */ + app_tim_state_t tim_state; /**< App tim state types. */ +}tim_env_t; + +/** + * @brief TIM parameters structure definition + */ +typedef struct +{ + app_tim_id_t id; /**< specified TIMER module ID. */ + timer_init_t init; /**< TIMER Base required parameters. */ + tim_env_t tim_env; /**< TIM device structure definition. */ +} app_tim_params_t; + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_TIM_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP TIM DRIVER according to the specified parameters + * in the app_tim_params_t and app_tim_evt_handler_t. + * + * @param[in] p_params: Pointer to app_tim_params_t parameter which contains the + * configuration information for the specified TIM module. + * @param[in] evt_handler: TIM user callback function. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_tim_init(app_tim_params_t *p_params, app_tim_evt_handler_t evt_handler); + +/** + **************************************************************************************** + * @brief De-initialize the APP TIM DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_tim_deinit(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Starts the TIM counter in interrupt mode. + * @param[in] id: which TIM module want to start. + * + * @return Result of initialization. + * + **************************************************************************************** + */ +uint16_t app_tim_start(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Stops the TIM counter in interrupt mode. + * @param[in] id: which TIM module want to stop. + * + * @return Result of initialization. + * + **************************************************************************************** + */ +uint16_t app_tim_stop(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Return the TIM handle. + * + * @param[in] id: TIM Channel ID. + * + * @return Pointer to the specified ID's TIM handle. + **************************************************************************************** + */ +timer_handle_t *app_tim_get_handle(app_tim_id_t id); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +/** + **************************************************************************************** + * @brief Return channel0 value. + * + * @param[in] id: TIM Channel ID. + * + * @return Current value when channel0 captured. + **************************************************************************************** + */ +uint32_t app_tim_get_channel0_val(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Return channel1 value. + * + * @param[in] id: TIM Channel ID. + * + * @return Current value when channel1 captured. + **************************************************************************************** + */ +uint32_t app_tim_get_channel1_val(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Return channel2 value. + * + * @param[in] id: TIM Channel ID. + * + * @return Current value when channel2 captured. + **************************************************************************************** + */ +uint32_t app_tim_get_channel2_val(app_tim_id_t id); + +/** + **************************************************************************************** + * @brief Return channel3 value. + * + * @param[in] id: TIM Channel ID. + * + * @return Current value when channel3 captured. + **************************************************************************************** + */ +uint32_t app_tim_get_channel3_val(app_tim_id_t id); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ +/** @} */ +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart.h new file mode 100644 index 0000000..94f1c6f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart.h @@ -0,0 +1,395 @@ +/** + **************************************************************************************** + * + * @file app_uart.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of UART app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_UART UART + * @brief UART APP module driver. + * @{ + */ + + +#ifndef _APP_UART_H_ +#define _APP_UART_H_ + +#include "grx_hal.h" +#include "ring_buffer.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_UART_MODULE_ENABLED + +/** @addtogroup APP_UART_MACRO Defines + * @{ + */ + +#define TX_ONCE_MAX_SIZE 128 /**< UART max bytes size transmitted at one time */ + +/** @} */ + +/** @addtogroup APP_UART_ENUMERATIONS Enumerations + * @{ + */ + +/** + * @brief UART module Enumerations definition + */ +typedef enum +{ + APP_UART_ID_0, /**< UART module 0 */ + APP_UART_ID_1, /**< UART module 1 */ +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) + APP_UART_ID_2, /**< UART module 2 */ + APP_UART_ID_3, /**< UART module 3 */ +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + APP_UART_ID_4, /**< UART module 4 */ + APP_UART_ID_5, /**< UART module 5 */ +#endif + APP_UART_ID_MAX, /**< Only for check parameter, not used as input parameters. */ +} app_uart_id_t; + +/** + * @brief UART event Enumerations definition + */ +typedef enum +{ + APP_UART_EVT_ERROR, /**< Error reported by UART peripheral. */ + APP_UART_EVT_TX_CPLT, /**< Requested TX transfer completed. */ + APP_UART_EVT_RX_DATA, /**< Requested RX transfer completed. */ + APP_UART_EVT_ABORT_TX, /**< Requested TX abort completed. */ + APP_UART_EVT_ABORT_RX, /**< Requested RX abort completed. */ + APP_UART_EVT_ABORT_TXRX, /**< Requested TX, RX abort completed. */ +} app_uart_evt_type_t; + +/**@brief App uart state types. */ +typedef enum +{ + APP_UART_INVALID = 0, + APP_UART_ACTIVITY, +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + APP_UART_SLEEP, +#endif +} app_uart_state_t; + +/** @} */ + +/** @addtogroup APP_UART_STRUCTURES Structures + * @{ + */ + +/** + * @brief UART pins Structures + */ +typedef struct +{ + app_io_type_t type; /**< Specifies the type of UART IO. */ + app_io_mux_t mux; /**< Specifies the Peripheral to be connected to the selected pins. */ + uint32_t pin; /**< Specifies the IO pins to be configured. + This parameter can be any value of @ref GR5xxx_pins. */ + app_io_pull_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. */ + +} app_uart_pin_t; + +/** + * @brief UART pins config Structures + */ +typedef struct +{ + app_uart_pin_t tx; /**< Set the configuration of UART TX pin. */ + app_uart_pin_t rx; /**< Set the configuration of UART RX pin. */ + app_uart_pin_t cts; /**< Set the configuration of UART CTS pin. */ + app_uart_pin_t rts; /**< Set the configuration of UART RTS pin. */ +} app_uart_pin_cfg_t; + +/** + * @brief UART DMA configuration structure definition + */ +typedef struct +{ + dma_regs_t *tx_dma_instance;/**< Specifies the TX DMA inistall.*/ + dma_regs_t *rx_dma_instance;/**< Specifies the RX DMA inistall.*/ + dma_channel_t tx_dma_channel; /**< Specifies the dma channel of UART TX. */ + dma_channel_t rx_dma_channel; /**< Specifies the dma channel of UART RX. */ +} app_uart_dma_cfg_t; + + +/**@brief App uart dma state types. */ +typedef enum +{ + APP_UART_DMA_INVALID = 0, + APP_UART_DMA_ACTIVITY, +} app_uart_dma_state_t; + +/** + * @brief UART event structure definition + */ +typedef struct +{ + app_uart_evt_type_t type; /**< Type of event. */ + union + { + uint32_t error_code; /**< UART Error code . */ + uint16_t size; /**< UART transmitted/received counter. */ + } data; /**< Data of event. */ +} app_uart_evt_t; + +/** @} */ + +/** @addtogroup APP_UART_TYPEDEFS Type definitions + * @{ + */ + +/** + * @brief UART event callback definition + */ +typedef void (*app_uart_evt_handler_t)(app_uart_evt_t *p_evt); + +/** @} */ + +/** @addtogroup APP_UART_STRUCTURES Structures + * @{ + */ + + +/** + * @brief UART device structure definition + */ +typedef struct +{ + app_uart_evt_handler_t evt_handler; /**< UART event callback. */ + uart_handle_t handle; /**< UART handle Structure. */ + app_uart_pin_cfg_t *p_pin_cfg; /**< UART pins config Structures. */ + dma_id_t dma_id[2]; /**< DMA id. */ + app_uart_state_t uart_state; /**< App uart state types. */ + app_uart_dma_state_t uart_dma_state; /**< App uart dma state types. */ + ring_buffer_t tx_ring_buffer; /**< RING_BUFFER_STRUCT Structures. */ + uint8_t tx_send_buf[TX_ONCE_MAX_SIZE]; /**< tx send buf. */ + volatile bool start_tx_flag; /**< start tx flag. */ + volatile bool start_flush_flag; /**< start flush flag. */ + bool tx_abort_flag; /**< tx abort flag. */ + bool rx_abort_flag; /**< rx abort flag. */ + bool is_dma_tx_mode; /**< dma tx mode. */ +} uart_env_t; + +/** + * @brief UART parameters structure definition + */ +typedef struct +{ + app_uart_id_t id; /**< specified UART module ID. */ + app_uart_pin_cfg_t pin_cfg; /**< the pin configuration information for the specified UART module. */ + app_uart_dma_cfg_t dma_cfg; /**< UART DMA configuration. */ + uart_init_t init; /**< UART communication parameters. */ + uart_env_t uart_dev; /**< UART event data. */ +} app_uart_params_t; + +/** + * @brief UART buffer structure definition + */ +typedef struct +{ + uint8_t * tx_buf; /**< Pointer to the TX buffer. */ + uint32_t tx_buf_size; /**< Size of the TX buffer. */ +} app_uart_tx_buf_t; +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_UART_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Initialize the APP UART DRIVER according to the specified parameters + * in the app_uart_params_t and app_uart_evt_handler_t. + * + * @param[in] p_params: Pointer to app_uart_params_t parameter which contains the + * configuration information for the specified UART module. + * @param[in] evt_handler: UART user callback function. + * @param[in] tx_buffer: Pointer to tx send buffer. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_uart_init(app_uart_params_t *p_params, app_uart_evt_handler_t evt_handler, app_uart_tx_buf_t *tx_buffer); + +/** + **************************************************************************************** + * @brief De-initialize the APP UART DRIVER peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_uart_deinit(app_uart_id_t id); + +/** + **************************************************************************************** + * @brief Send an amount of data in interrupt mode. + * + * @param[in] id: which UART module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_transmit_async(app_uart_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Send an amount of data in blocking mode. + * + * @param[in] id: which UART module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_transmit_sync(app_uart_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in interrupt mode. + * + * @param[in] id: which UART module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_receive_async(app_uart_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * + * @param[in] id: which UART module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_receive_sync(app_uart_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Return the UART handle. + * + * @param[in] id: UART Channel ID. + * + * @return Pointer to the specified ID's UART handle. + **************************************************************************************** + */ +uart_handle_t *app_uart_get_handle(app_uart_id_t id); + +/** + ***************************************************************************************** + * @brief Flush all log entries from the buffer + * + * @param[in] id: UART Channel ID. + * + ***************************************************************************************** + */ +void app_uart_flush(app_uart_id_t id); + +/** + **************************************************************************************** + * @brief Abort transmit and receive process and generate abort callback. + * + * @param[in] id: which UART module want to use. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_abort(app_uart_id_t id); + +/** + **************************************************************************************** + * @brief Abort transmit process and generate abort transmit callback. + * + * @param[in] id: which UART module want to use. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_abort_transmit(app_uart_id_t id); + +/** + **************************************************************************************** + * @brief Abort receive process and generate abort receive callback. + * + * @param[in] id: which UART module want to use. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_abort_receive(app_uart_id_t id); + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart_dma.h new file mode 100644 index 0000000..1564870 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/app_uart_dma.h @@ -0,0 +1,165 @@ +/** + **************************************************************************************** + * + * @file app_uart_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of UART app library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup APP_DRIVER APP DRIVER + * @{ + */ + +/** @defgroup APP_UART UART + * @brief UART APP module driver. + * @{ + */ + + +#ifndef _APP_UART_DMA_H_ +#define _APP_UART_DMA_H_ + +#include "app_uart.h" +#include "grx_hal.h" +#include "app_drv_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAL_UART_MODULE_ENABLED + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup APP_DMA_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize dma mode of the APP UART DRIVER according to the specified parameters + * in the app_uart_params_t. + * + * @param[in] p_params: Pointer to app_uart_params_t parameter which contains the + * configuration information for the specified UART module. + * + * @return Result of initialization. + **************************************************************************************** + */ +uint16_t app_uart_dma_init(app_uart_params_t *p_params); + +/** + **************************************************************************************** + * @brief De-initialize dma mode of the APP UART peripheral. + * + * @param[in] id: De-initialize for a specific ID. + * + * @return Result of De-initialization. + **************************************************************************************** + */ +uint16_t app_uart_dma_deinit(app_uart_id_t id); + +/** + **************************************************************************************** + * @brief Receive an amount of data in dma mode. + * + * @param[in] id: which UART module want to receive. + * @param[in] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to receive. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_dma_receive_async(app_uart_id_t id, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Send an amount of data in dma mode. + * + * @param[in] id: which UART module want to send. + * @param[in] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be sent. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_dma_transmit_async(app_uart_id_t id, uint8_t *p_data, uint16_t size); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +/** + **************************************************************************************** + * @brief Send an amount of data in DMA mode with DMA sg and llp function. + * + * @param[in] id: which UART module want to receive. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] sg_llp_config: The config of source and destination's sg and llp fuction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_transmit_dma_sg_llp(app_uart_id_t id, uint8_t *p_data, uint16_t size, dma_sg_llp_config_t *sg_llp_config); + +/** + **************************************************************************************** + * @brief Receive an amount of data in in dma_sg_llp mode. + * + * @param[in] id: which UART module want to transmit. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] sg_llp_config: The config of source and destination's sg and llp fuction. + * + * @return Result of operation. + **************************************************************************************** + */ +uint16_t app_uart_receive_dma_sg_llp(app_uart_id_t id, uint8_t *p_data, uint16_t size, dma_sg_llp_config_t *sg_llp_config); +#endif + +/** @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_delay.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_delay.h new file mode 100644 index 0000000..7e37dd5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_delay.h @@ -0,0 +1,328 @@ +/** + **************************************************************************************** + * + * @file gr55xx_delay.h + * @author BLE Driver Team + * @brief PERIPHERAL API DELAY DRIVER + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +#ifndef __GR55xx_DELAY_H__ +#define __GR55xx_DELAY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gr55xx.h" + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_DELAY DELAY + * @brief Delay HAL module driver. + * @{ + */ +/** @addtogroup HAL_DELAY_DEFINES Defines + * @{ + */ +#define DELAY_US_DWT /**< dealy us dwt define */ + +#if defined ( __CC_ARM ) + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE static __forceinline /**< Static inline define */ +#endif + +#elif defined ( __GNUC__ ) + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline /**< Static inline define */ +#endif + +#else + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __STATIC_INLINE /**< Static inline define */ +#endif + +#endif +/** @} */ + +#ifndef DELAY_US_DWT +/** @addtogroup HAL_DELAY_TYPEDEFS Typedefs + * @{ + */ +/** + * @brief Pointer to a function for delaying execution + */ +typedef void (* delay_func_t)(uint32_t); +/** @} */ +#endif + +#ifdef DELAY_US_DWT +/** @addtogroup HAL_DELAY_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Enable the DWT. + * @param _demcr_initial: demcr initial. + * @param _dwt_ctrl_initial: dwt ctrl initial. + **************************************************************************************** + */ +void hal_dwt_enable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial); + +/** + **************************************************************************************** + * @brief Disable the DWT. + * @param _demcr_initial: demcr initial. + * @param _dwt_ctrl_initial: dwt ctrl initial. + **************************************************************************************** + */ +void hal_dwt_disable(uint32_t _demcr_initial, uint32_t _dwt_ctrl_initial); +/** @} */ + +/** @addtogroup HAL_DELAY_DEFINES Defines + * @{ + */ +/** + * @brief Timeout module init. This macro must be used in + * conjunction with the @ref HAL_TIMEOUT_DEINIT macro + */ +#define HAL_TIMEOUT_INIT() \ + uint32_t _demcr_initial = CoreDebug->DEMCR; \ + uint32_t _dwt_ctrl_initial = DWT->CTRL; \ +do { \ + hal_dwt_enable(_demcr_initial, _dwt_ctrl_initial); \ +} while (0) + +/** + * @brief Timeout module deinit. This macro must be used in + * conjunction with the @ref HAL_TIMEOUT_INIT macro + */ +#define HAL_TIMEOUT_DEINIT() \ +do { \ + hal_dwt_disable(_demcr_initial, _dwt_ctrl_initial); \ +} while(0) +/** @} */ + +/** @addtogroup HAL_DELAY_FUNCTIONS Functions + * @{ + */ +/** + **************************************************************************************** + * @brief Function for delaying execution for number of us. + * @note GR55xxx is based on ARM Cortex-M4, and this fuction is based on Data Watchpoint and Trace (DWT) unit so delay is precise. + * @param number_of_us: The maximum delay time is about 67 seconds in 64M system clock. + * The faster the system clock, the shorter the maximum delay time. + **************************************************************************************** + */ +__STATIC_FORCEINLINE void delay_us(uint32_t number_of_us) +{ + const uint8_t clocks[] = {64, 48, 16, 24, 16, 32}; + uint32_t cycles = number_of_us * (clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL]); + + if (number_of_us == 0) + { + return; + } + + HAL_TIMEOUT_INIT(); + + // Get start value of the cycle counter. + uint32_t cyccnt_initial = DWT->CYCCNT; + + // Wait time end + while ((DWT->CYCCNT - cyccnt_initial) < cycles) + {} + + HAL_TIMEOUT_DEINIT(); +} +/** @} */ +#endif + +#ifndef DELAY_US_DWT + +#if defined ( __CC_ARM ) + +#pragma push +#pragma O2 +/** @addtogroup HAL_DELAY_FUNCTIONS Functions + * @{ + */ + /** + **************************************************************************************** + * @brief Function for delaying execution for number of us. + * @note GR55xxx is based on ARM Cortex-M4, and this fuction is based on Data Watchpoint and Trace (DWT) unit so delay is precise. + * @param number_of_us: The maximum delay time is about 67 seconds in 64M system clock. + * The faster the system clock, the shorter the maximum delay time. + **************************************************************************************** + */ +__STATIC_FORCEINLINE void delay_us(uint32_t number_of_us) +{ + uint32_t pc = (unsigned int)__current_pc(); + uint8_t clocks[] = {64, 48, 16, 24, 16, 32}; + + if (number_of_us == 0) + { + return; + } + + static const uint16_t delay_ramcode[] = { + 0x3809, // SUBS r0, #9 + 0xd8fd, // BHI .-2 + 0x4770 // BX LR + }; + // Set LSB to 1 to execute code in Thumb mode. + const delay_func_t delay_ram_cycles = (delay_func_t)((((uint32_t)delay_ramcode) | 1)); + + static const uint16_t delay_flashcode[] = { + 0x3803, // SUBS r0, #3 + 0xd8fd, // BHI .-2 + 0x4770 // BX LR + }; + // Set LSB to 1 to execute code in Thumb mode. + const delay_func_t delay_flash_cycles = (delay_func_t)((((uint32_t)delay_flashcode) | 1)); + + static const uint16_t delay_aliascode[] = { + 0x3803, // SUBS r0, #3 + 0xd8fd, // BHI .-2 + 0x4770 // BX LR + }; + // Set LSB to 1 to execute code in Thumb mode. + const delay_func_t delay_alias_cycles = (delay_func_t)((((uint32_t)delay_aliascode) | 1)); + + uint32_t cycles = number_of_us * (clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL]); + + if(pc & GR55XX_RAM_ADDRESS) + delay_ram_cycles(cycles); + else if(pc & GR55XX_FLASH_ADDRESS) + delay_flash_cycles(cycles); + else if(pc & GR55XX_ALIAS_ADDRESS) + delay_alias_cycles(cycles); + else + { + cycles = cycles / 4; + __asm + { + loop: + NOP + SUBS cycles, #1 + BNE loop + } + } +} +#pragma pop + +#elif defined ( _WIN32 ) || defined ( __unix ) || defined ( __APPLE__ ) + +#ifndef CUSTOM_DELAY_US +/** + **************************************************************************************** + * @brief Function for delaying execution for number of us. + * @param number_of_us: The maximum delay time is about 67 seconds in 64M system clock. + * The faster the system clock, the shorter the maximum delay time. + **************************************************************************************** + */ +__STATIC_FORCEINLINE void delay_us(uint32_t number_of_us) +{ +} +#endif + +#elif defined ( __GNUC__ ) || ( __ICCARM__ ) +/** + **************************************************************************************** + * @brief Function for delaying execution for number of us. + * @param number_of_us: The maximum delay time is about 67 seconds in 64M system clock. + * The faster the system clock, the shorter the maximum delay time. + **************************************************************************************** + */ +__STATIC_FORCEINLINE void delay_us(uint32_t number_of_us) +{ + uint8_t clocks[] = {64, 48, 16, 24, 16, 32}; + + if (number_of_us) + { + uint32_t cycles; + cycles = number_of_us*(clocks[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL])/6; + __asm__ volatile ("1:\n" + "NOP\n" + "NOP\n" + "NOP\n" + "SUBS %[cycles], %[cycles], #1\n" + "BNE.N 1b\n" + : [cycles] "=r" (cycles) + : "[cycles]" "r" (cycles) + ); + } +} +/** @} */ +#endif + +#endif + +/** @addtogroup HAL_DELAY_FUNCTIONS Functions + * @{ + */ +/** + * @brief Function for delaying execution for number of milliseconds. + * + * @note GR55xx is based on ARM Cortex-M4, and this fuction is based on Data Watchpoint and Trace (DWT) unit so delay is precise. + * + * @note Function internally calls @ref delay_us so the maximum delay is the + * same as in case of @ref delay_us. + * + * @param number_of_ms: The maximum delay time is about 67 seconds in 64M system clock. + * The faster the system clock, the shorter the maximum delay time. + * + */ +__STATIC_FORCEINLINE void delay_ms(uint32_t number_of_ms) +{ + delay_us(1000 * number_of_ms); + return; +} +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_DELAY_H__ */ +/** @} */ +/** @} */ +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal.h new file mode 100644 index 0000000..99ec139 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal.h @@ -0,0 +1,376 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal.h + * @author BLE Driver Team + * @brief This file contains all the functions prototypes for the HAL + * module driver. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_HAL HAL + * @brief HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_H__ +#define __GR55xx_HAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" +#include "gr55xx_hal_conf.h" +#include "gr55xx_delay.h" + +/** @addtogroup HAL_HAL_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_HAL_Callback Callback + * @{ + */ + +/** + * @brief HAL_HAL Callback function definition + */ + +typedef struct _hal_callback +{ + void (*msp_init)(void); /**< HAL init MSP callback */ + void (*msp_deinit)(void); /**< HAL de-init MSP callback */ +} hal_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_MACRO Defines + * @{ + */ + +/* Private macros ------------------------------------------------------------*/ +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup HAL_Exported_Constants HAL Exported Constants + * @{ + */ + +/** @brief compare if a > b + * @sa CO_MAX + */ +#define CO_MAX(a,b) ((a) > (b) ? (a) : (b)) + +/** @brief Disable BLE_IRQn and BLESLP_IRQn. + * @sa BLE_INT_DISABLE + */ +#define BLE_INT_DISABLE() \ +do { \ + volatile uint32_t __ble_l_irq_rest = __get_PRIMASK(); \ + volatile bool __ble_int_status = NVIC_GetEnableIRQ(BLE_IRQn) || NVIC_GetEnableIRQ(BLESLP_IRQn); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_DisableIRQ(BLE_IRQn); \ + NVIC_DisableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); + +/** @brief Restore BLE_IRQn and BLESLP_IRQn. + * @sa BLE_INT_RESTORE + */ +#define BLE_INT_RESTORE() \ + __ble_l_irq_rest = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_EnableIRQ(BLE_IRQn); \ + NVIC_EnableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); \ +} while(0) + +/** @brief Disable interrupts globally in the system. + * This macro must be used in conjunction with the @ref GLOBAL_INT_RESTORE macro + * since this last one will close the brace that the current macro opens. This + * means that both macros must be located at the same scope level. + */ +#define GLOBAL_INT_DISABLE() \ +do { \ + volatile uint32_t __nvic_iser0 = 0xFFFFFFFF; \ + volatile uint32_t __nvic_iser1 = 0xFFFFFFFF; \ + volatile uint32_t __ret_pri = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + if( (NVIC->ICER[0] != 0xFFFFFFFF) || (NVIC->ICER[1] != 0xFFFFFFFF) ) \ + { \ + __nvic_iser0 = NVIC->ISER[0]; \ + __nvic_iser1 = NVIC->ISER[1]; \ + NVIC->ICER[0] = 0xFFFFFFFF; \ + NVIC->ICER[1] = 0xFFFFFFFF; \ + } \ + __set_PRIMASK(__ret_pri); \ + __DSB(); \ + __ISB(); \ + +/** @brief Restore external interrupts(Exception Type: 16~255) from the previous disable. + * @sa GLOBAL_INT_RESTORE + */ +#define GLOBAL_INT_RESTORE() \ + __ret_pri = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + if( (__nvic_iser0 != 0xFFFFFFFF) || (__nvic_iser1 != 0xFFFFFFFF) ) \ + { \ + NVIC->ISER[0] = __nvic_iser0; \ + NVIC->ISER[1] = __nvic_iser1; \ + } \ + __set_PRIMASK(__ret_pri); \ +} while(0) + +/** @brief Disable external interrupts with a priority lower than IRQn_Type in the system. + * This macro must be used in conjunction with the @ref LOCAL_INT_RESTORE macro + * since this last one will close the brace that the current macro opens. This + * means that both macros must be located at the same scope level. + */ +#define LOCAL_INT_DISABLE(IRQn_Type) \ +do { \ + uint32_t __l_irq_rest = __get_BASEPRI(); \ + __set_BASEPRI(NVIC_GetPriority(IRQn_Type) + \ + (1 << (NVIC_GetPriorityGrouping() + 1))); \ + +/** @brief Restore external interrupts(apart from the BLE) from the previous disable. + * @sa EXP_BLE_INT_RESTORE + */ +#define LOCAL_INT_RESTORE() \ + __set_BASEPRI(__l_irq_rest); \ +} while(0) + + +/** @brief Check if the program is running on the FPGA platform. + */ +#define CHECK_IS_ON_FPGA() (AON->FPGA_CTRL & AON_REG_FPGA_CTRL_EXIST) + +#define SYSTICK_RELOAD_VALUE (SysTick->LOAD) /**< SysTick Reload value. */ +#define SYSTICK_CURRENT_VALUE (SysTick->VAL) /**< SysTick Current value. */ + +/** @} */ + +/** @} */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_HAL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup HAL_Exported_Functions_Group1 Initialization and De-initialization Functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the Flash interface, the NVIC allocation and initial clock + configuration. It also initializes the source of time base when timeout + is needed. + (+) De-initialize common part of the HAL. + (+) Configure The time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) SysTick timer is used by default as source of time base, but user can + eventually implement his or her proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept as 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + (++) Time base configuration function (hal_init_tick()) is called automatically + at the beginning of the program after reset by hal_init(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if hal_delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) Functions affecting time base configurations are declared as __Weak + to make override possible in case of other implementations in user file. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief This function configures time base source, NVIC and Low level hardware. + * + * @note This function is called at the beginning of program after reset and before + * the clock configuration. + * The SysTick configuration is based on AHB clock and the NVIC configuration + * is set to Priority group 4. + * When the time base configuration is done, time base tick starts incrementing. + * In the default implementation, SysTick is used as source of time base. + * The tick variable is incremented each 1ms in its ISR. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_init(void); + +/** + **************************************************************************************** + * @brief This function de-initializes common part of the HAL and stops the source + * of time base. + * + * @note This function is optional. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_deinit(void); + +/** + **************************************************************************************** + * @brief Initialize the MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_msp_init could be implemented in the user file. + **************************************************************************************** + */ +void hal_msp_init(void); + +/** + **************************************************************************************** + * @brief De-initialize the MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_msp_deinit could be implemented in the user file. + **************************************************************************************** + */ +void hal_msp_deinit(void); + +/** + **************************************************************************************** + * @brief This function configures the source of the time base. + * + * @param[in] tick_priority: Tick interrupt priority. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_init_tick (uint32_t tick_priority); + +/** @} */ + +/** @addtogroup HAL_Exported_Functions_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Suspend Tick increment. + * + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once hal_suspend_tick() + * is called, the SysTick interrupt will be disabled so Tick increment + * is suspended. + * This function is declared as __WEAK to be overwritten in case of other + * implementations in user file. + **************************************************************************************** + */ +void hal_suspend_tick(void); + +/** + **************************************************************************************** + * @brief Resume Tick increment. + * + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once hal_resume_tick() + * is called, the SysTick interrupt will be enabled so Tick increment + * is resumed. + * The function is declared as __WEAK to be overwritten in case of other + * implementations in user file. + **************************************************************************************** + */ +void hal_resume_tick(void); + +/** + **************************************************************************************** + * @brief This function returns the HAL revision + * + * @return version: 0xXYZR (8 bits for each decimal, R for RC) + **************************************************************************************** + */ +uint32_t hal_get_hal_version(void); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc.h new file mode 100644 index 0000000..dd81b67 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc.h @@ -0,0 +1,608 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_adc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ADC HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_ADC ADC + * @brief ADC HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_ADC_H__ +#define __GR55xx_HAL_ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_adc.h" +#include "gr55xx_hal_def.h" +#include "gr55xx_hal_dma.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_ADC_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_ADC_state HAL ADC State + * @{ + */ + +/** + * @brief HAL ADC State Enumerations definition + */ +typedef enum +{ + HAL_ADC_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_ADC_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_ADC_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_ADC_STATE_ERROR = 0x04 /**< Peripheral in error */ + +} hal_adc_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_ADC_STRUCTURES Structures + * @{ + */ + +/** @defgroup ADC_Configuration ADC Configuration + * @{ + */ + +/** + * @brief ADC init structure definition + */ +typedef ll_adc_init_t adc_init_t; +/** @} */ + +/** @defgroup ADC_handle ADC Handle + * @{ + */ + +/** + * @brief ADC handle Structure definition + */ +typedef struct _adc_handle +{ + adc_init_t init; /**< ADC configuration parameters */ + + uint16_t *p_buffer; /**< Pointer to ADC conversion buffer */ + + __IO uint32_t buff_size; /**< Conversion buffer size */ + + __IO uint32_t buff_count; /**< Conversion buffer counter */ + + dma_handle_t *p_dma; /**< ADC DMA Handle parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_adc_state_t state; /**< ADC communication state */ + + __IO uint32_t error_code; /**< ADC error code */ + + uint32_t retention[2]; /**< ADC important register information. */ + +} adc_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_ADC_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup ADC_Callback ADC Callback + * @{ + */ + +/** + * @brief HAL ADC Callback function definition + */ +typedef struct _adc_callback +{ + void (*adc_msp_init)(adc_handle_t *p_adc); /**< ADC init MSP callback */ + void (*adc_msp_deinit)(adc_handle_t *p_adc); /**< ADC de-init MSP callback */ + void (*adc_conv_cplt_callback)(adc_handle_t *p_adc); /**< ADC conversion completed callback */ +} adc_callback_t; + +/** @} */ + +/** @} */ + +/** + * @brief ADC init structure definition + */ + +/** + * @defgroup HAL_ADC_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_Error_Code ADC Error Code + * @{ + */ +#define HAL_ADC_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_ADC_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_ADC_ERROR_DMA ((uint32_t)0x00000004) /**< DMA transfer error */ +#define HAL_ADC_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameter error */ +/** @} */ + +/** @defgroup ADC_CLK ADC Clock Select + * @{ + */ +#define ADC_CLK_16M LL_ADC_CLK_16 /**< ADC Clock = 16 MHz */ +#define ADC_CLK_1P6M LL_ADC_CLK_1P6 /**< ADC Clock = 1.6 MHz */ +#define ADC_CLK_8M LL_ADC_CLK_8 /**< ADC Clock = 8 MHz */ +#define ADC_CLK_4M LL_ADC_CLK_4 /**< ADC Clock = 4 MHz */ +#define ADC_CLK_2M LL_ADC_CLK_2 /**< ADC Clock = 2 MHz */ +#define ADC_CLK_1M LL_ADC_CLK_1 /**< ADC Clock = 1 MHz */ +/** @} */ + +/** @defgroup ADC_REFERENCE ADC Reference Value Select + * @{ + */ +#define ADC_REF_VALUE_0P8 LL_ADC_REF_VALUE_0P8 /**< Reference = 0.85 V */ +#define ADC_REF_VALUE_1P2 LL_ADC_REF_VALUE_1P2 /**< Reference = 1.28 V */ +#define ADC_REF_VALUE_1P6 LL_ADC_REF_VALUE_1P6 /**< Reference = 1.60 V */ +/** @} */ + +/** @defgroup ADC_INPUT_MODE ADC Input Mode + * @brief Single or Differential mode + * @{ + */ +#define ADC_INPUT_SINGLE LL_ADC_INPUT_SINGLE /**< Single ended mode */ +#define ADC_INPUT_DIFFERENTIAL LL_ADC_INPUT_DIFFERENTIAL/**< Differential mode */ +/** @} */ + +/** @defgroup ADC_INPUT_SOURCE ADC Input Channel Select + * @{ + */ +#define ADC_INPUT_SRC_IO0 LL_ADC_INPUT_SRC_IO0 /**< Select MSIO0 as input */ +#define ADC_INPUT_SRC_IO1 LL_ADC_INPUT_SRC_IO1 /**< Select MSIO1 as input */ +#define ADC_INPUT_SRC_IO2 LL_ADC_INPUT_SRC_IO2 /**< Select MSIO2 as input */ +#define ADC_INPUT_SRC_IO3 LL_ADC_INPUT_SRC_IO3 /**< Select MSIO3 as input */ +#define ADC_INPUT_SRC_IO4 LL_ADC_INPUT_SRC_IO4 /**< Select MSIO4 as input */ +#define ADC_INPUT_SRC_TMP LL_ADC_INPUT_SRC_TMP /**< Select temperature as input */ +#define ADC_INPUT_SRC_BAT LL_ADC_INPUT_SRC_BAT /**< Select Vbattery as input */ +#define ADC_INPUT_SRC_REF LL_ADC_INPUT_SRC_REF /**< Select reference as input */ + +/** @} */ + +/** @defgroup ADC_REFERENCE_SOURCE ADC Reference Source Select + * @{ + */ +#define ADC_REF_SRC_BUF_INT LL_ADC_REF_SRC_BUF_INT /**< Select buffered internal reference as reference */ +#define ADC_REF_SRC_IO0 LL_ADC_REF_SRC_IO0 /**< Select MSIO0 as reference */ +#define ADC_REF_SRC_IO1 LL_ADC_REF_SRC_IO1 /**< Select MSIO1 as reference */ +#define ADC_REF_SRC_IO2 LL_ADC_REF_SRC_IO2 /**< Select MSIO2 as reference */ +#define ADC_REF_SRC_IO3 LL_ADC_REF_SRC_IO3 /**< Select MSIO3 as reference */ +/** @} */ + +/** + * @brief ADC_default_config initStruct default configuartion + */ +#define ADC_DEFAULT_CONFIG LL_ADC_DEFAULT_CONFIG +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @brief Reset ADC handle states. + * @param __HANDLE__ ADC handle. + * @retval None + */ +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_ADC_STATE_RESET) + +/** @brief Enable the specified ADC peripheral. + * @param __HANDLE__ Specify the ADC Handle. + * @retval None + */ +#define __HAL_ADC_ENABLE(__HANDLE__) ll_adc_enable() + +/** @brief Disable the specified ADC peripheral. + * @param __HANDLE__ Specify the ADC Handle. + * @retval None + */ +#define __HAL_ADC_DISABLE(__HANDLE__) ll_adc_disable() + +/** @brief Enable the specified ADC clock. + * @param __HANDLE__ Specify the ADC Handle. + * @retval None + */ +#define __HAL_ADC_ENABLE_CLOCK(__HANDLE__) ll_adc_enable_clock() + +/** @brief Disable the specified ADC clock. + * @param __HANDLE__ Specify the ADC Handle. + * @retval None + */ +#define __HAL_ADC_DISABLE_CLOCK(__HANDLE__) ll_adc_disable_clock() + +/** @brief Check the FIFO is not empty. + * @param __HANDLE__ Specify the ADC Handle. + * @retval The new state of notempty flag (TRUE or FALSE). + */ +#define __HAL_ADC_GET_FLAG_NOTEMPTY(__HANDLE__) ll_adc_is_fifo_notempty() + +/** @brief Flush the FIFO. + * @param __HANDLE__ Specify the ADC Handle. + * @retval None + */ +#define __HAL_ADC_FLUSH_FIFO(__HANDLE__) do { \ + while(ll_adc_is_fifo_notempty()) \ + { \ + ll_adc_read_fifo(); \ + } \ + } while(0) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup ADC_Private_Macros ADC Private Macros + * @{ + */ + +/** + * @brief Check if ADC input source is valid. + * @param __INPUT__ ADC input source. + * @retval SET (__INPUT__ is valid) or RESET (__INPUT__ is invalid) + */ +#define IS_ADC_INPUT(__INPUT__) (((__INPUT__) == ADC_INPUT_SRC_IO0) || \ + ((__INPUT__) == ADC_INPUT_SRC_IO1) || \ + ((__INPUT__) == ADC_INPUT_SRC_IO2) || \ + ((__INPUT__) == ADC_INPUT_SRC_IO3) || \ + ((__INPUT__) == ADC_INPUT_SRC_IO4) || \ + ((__INPUT__) == ADC_INPUT_SRC_TMP) || \ + ((__INPUT__) == ADC_INPUT_SRC_BAT) || \ + ((__INPUT__) == ADC_INPUT_SRC_REF)) + +/** + * @brief Check if ADC input mode is valid. + * @param __MODE__ ADC input mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_ADC_INPUT_MODE(__MODE__) (((__MODE__) == ADC_INPUT_SINGLE) || \ + ((__MODE__) == ADC_INPUT_DIFFERENTIAL) + +/** + * @brief Check if ADC reference source is valid. + * @param __INPUT__ ADC reference source. + * @retval SET (__INPUT__ is valid) or RESET (__INPUT__ is invalid) + */ +#define IS_ADC_REF(__INPUT__) (((__INPUT__) == ADC_REF_SRC_BUF_INT) || \ + ((__INPUT__) == ADC_REF_SRC_INT) || \ + ((__INPUT__) == ADC_REF_SRC_IO0) || \ + ((__INPUT__) == ADC_REF_SRC_IO1) || \ + ((__INPUT__) == ADC_REF_SRC_IO2) || \ + ((__INPUT__) == ADC_REF_SRC_IO3)) + +/** + * @brief Check if ADC reference value is valid. + * @param __VALUE__ ADC reference value. + * @retval SET (__VALUE__ is valid) or RESET (__VALUE__ is invalid) + */ +#define IS_ADC_REF_VALUE(__VALUE__) (((__VALUE__) >= ADC_REF_VALUE_0P8) && \ + ((__VALUE__) <= ADC_REF_VALUE_1P6)) + +/** + * @brief Check if ADC clock is valid. + * @param __CLOCK__ ADC clock. + * @retval SET (__CLOCK__ is valid) or RESET (__CLOCK__ is invalid) + */ +#define IS_ADC_CLOCK(__CLOCK__) (((__CLOCK__) == ADC_CLK_16M) || \ + ((__CLOCK__) == ADC_CLK_8M) || \ + ((__CLOCK__) == ADC_CLK_4M) || \ + ((__CLOCK__) == ADC_CLK_2M) || \ + ((__CLOCK__) == ADC_CLK_1M) || \ + ((__CLOCK__) == ADC_CLK_1P6M)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_ADC_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup ADC_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and Configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the ADC according to the specified parameters + * in the adc_init_t and initialize the associated handle. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_init(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief De-initialize the ADC peripheral. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_deinit(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Initialize the ADC MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_adc_msp_deinit can be implemented in the user file. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + **************************************************************************************** + */ +void hal_adc_msp_init(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief De-initialize the ADC MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_adc_msp_deinit can be implemented in the user file. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + **************************************************************************************** + */ +void hal_adc_msp_deinit(adc_handle_t *p_adc); + +/** @} */ + +/** @addtogroup ADC_Exported_Functions_Group2 IO Operation Functions + * @brief ADC polling and DMA conversion management functions. + * @{ + */ + + /** + **************************************************************************************** + * @brief Set the FIFO threshold for DMA trigger. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * @param[in] threshold: FIFO threshold value ranging bwtween 0x0U ~ 0x64U. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_set_dma_threshold(adc_handle_t *p_adc, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Get the FIFO threshold for DMA trigger. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * + * @return FIFO threshold + **************************************************************************************** + */ +uint32_t hal_adc_get_dma_threshold(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Polling for conversion. + * + * @param[in] p_adc: Pointer to an ADC handle. + * @param[in] p_data: Pointer to data buffer which to store ADC conversion results. + * @param[in] length: Length of data buffer. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_poll_for_conversion(adc_handle_t *p_adc, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief DMA for conversion. + * + * @param[in] p_adc: Pointer to an ADC handle. + * @param[in] p_data: Pointer to data buffer which to store ADC conversion results. + * @param[in] length: Length of data buffer, ranging between 0 and 4095. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_start_dma(adc_handle_t *p_adc, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Abort ongoing conversion (blocking mode). + * + * @note This procedure could be only used for aborting conversion started in DMA mode. + * This procedure performs following operations: + * - Disable ADC clock, stop conversion + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY. + * This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * + * @param[in] p_adc: ADC handle. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_stop_dma(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Conversion completed callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_adc_msp_deinit can be implemented in the user file. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + **************************************************************************************** + */ +void hal_adc_conv_cplt_callback(adc_handle_t* p_adc); + +/** @} */ + +/** @defgroup ADC_Exported_Functions_Group3 Peripheral State and Errors Functions + * @brief ADC control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the ADC. + (+) hal_adc_get_state() API can be helpful to check in run-time the state of the ADC peripheral. + (+) hal_adc_get_error() check in run-time Errors occurring during communication. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the ADC handle state. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * + * @retval ::HAL_ADC_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_ADC_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_ADC_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_ADC_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_adc_state_t hal_adc_get_state(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Return the ADC error code. + * + * @param[in] p_adc: Pointer to an ADC handle which contains the configuration information for + * the specified ADC module. + * + * @return ADC error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_adc_get_error(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Suspend some registers related to ADC configuration before sleep. + * @param[in] p_adc: Pointer to a ADC handle which contains the configuration + * information for the specified ADC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_suspend_reg(adc_handle_t *p_adc); + +/** + **************************************************************************************** + * @brief Restore some registers related to ADC configuration after sleep. + * This function must be used in conjunction with the hal_adc_suspend_reg(). + * @param[in] p_adc: Pointer to a ADC handle which contains the configuration + * information for the specified ADC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_adc_resume_reg(adc_handle_t *p_adc); + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_ADC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_temp_api.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_temp_api.h new file mode 100644 index 0000000..138fc6d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_temp_api.h @@ -0,0 +1,75 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_adc_temp_api.h + * + * @brief Header file - GR55xx temperature module. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __GR55XX_HAL_ADC_TEMP_API_H__ +#define __GR55XX_HAL_ADC_TEMP_API_H__ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize ADC temperature detection. + * + **************************************************************************************** + */ +void hal_adc_temp_init(void); + +/** + **************************************************************************************** + * @brief Get the chip internal temperature. + * + * @return The value of temperature. Unit (Centigrade). + **************************************************************************************** + */ +double hal_adc_temp_read(void); + +#ifdef __cplusplus +} +#endif + +#endif // __GR55XX_HAL_ADC_TEMP_API_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_vbat_api.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_vbat_api.h new file mode 100644 index 0000000..2cffde5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_vbat_api.h @@ -0,0 +1,75 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_adc_vbat_api.h + * + * @brief Header file - GR55xx battery module. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __GR55XX_HAL_ADC_VBAT_API_H__ +#define __GR55XX_HAL_ADC_VBAT_API_H__ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize ADC battery voltage detection. + * + **************************************************************************************** + */ +void hal_adc_vbat_init(void); + +/** + **************************************************************************************** + * @brief Get the battery voltage. + * + * @return The volatge of battery. Unit (volt). + **************************************************************************************** + */ +double hal_adc_vbat_read(void); + +#ifdef __cplusplus +} +#endif + +#endif // __GR55XX_HAL_ADC_VBAT_API_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_voltage_api.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_voltage_api.h new file mode 100644 index 0000000..d57a823 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_adc_voltage_api.h @@ -0,0 +1,90 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_adc_voltage_api.h + * + * @brief Header file - GR55xx ADC voltage module. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __GR55XX_HAL_ADC_VOLTAGE_API_H__ +#define __GR55XX_HAL_ADC_VOLTAGE_API_H__ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "gr55xx_hal_adc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Convert the ADC conversion results to a voltage value(internal reference). + * + * @param[in] hadc: Pointer to a ADC handle which contains the configuration information for + * the specified ADC module. + * @param[in] inbuf: Pointer to data buffer which storage ADC conversion results. + * @param[out] outbuf: Pointer to data buffer which to storage voltage results. + * @param[in] buflen: Length of data buffer, ranging between 0 and 4095. + * + * @return Result of operation. + **************************************************************************************** + */ +void hal_adc_voltage_intern(adc_handle_t *hadc, uint16_t *inbuf, double *outbuf, uint32_t buflen); + +/** + **************************************************************************************** + * @brief Convert the ADC conversion results to a voltage value(external reference). + * + * @param[in] hadc: Pointer to a ADC handle which contains the configuration information for + * the specified ADC module. + * @param[in] vref: slope of ADC. + * @param[in] inbuf: Pointer to data buffer which storage ADC conversion results. + * @param[out] outbuf: Pointer to data buffer which to storage voltage results. + * @param[in] buflen: Length of data buffer, ranging between 0 and 4095. + * + * @return Result of operation. + **************************************************************************************** + */ +void hal_adc_voltage_extern(adc_handle_t *hadc, double vref, uint16_t *inbuf, double *outbuf, uint32_t buflen); + +#ifdef __cplusplus +} +#endif + +#endif // __GR55XX_HAL_ADC_VOLTAGE_API_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aes.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aes.h new file mode 100644 index 0000000..d5fdcac --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aes.h @@ -0,0 +1,851 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_aes.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AES HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_AES AES + * @brief AES HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_AES_H__ +#define __GR55xx_HAL_AES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_aes.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_AES_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_AES_state HAL AES State + * @{ + */ + +/** + * @brief HAL AES State Enumerations definition + */ +typedef enum +{ + HAL_AES_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_AES_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_AES_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_AES_STATE_ERROR = 0x03, /**< Peripheral in error */ + HAL_AES_STATE_TIMEOUT = 0x04, /**< Peripheral in timeout */ + HAL_AES_STATE_SUSPENDED = 0x05, /**< Peripheral in suspended */ +} hal_aes_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_AES_STRUCTURES Structures + * @{ + */ + +/** @defgroup AES_Configuration AES Configuration + * @{ + */ + +/** + * @brief AES Init Structure definition + */ +typedef struct _aes_init +{ + uint32_t key_size; /**< 128, 192 or 256-bits key length. + This parameter can be a value of @ref AES_Key_Size */ + + uint32_t operation_mode; /**< AES operating mode. + This parameter can be a value of @ref AES_OPERATION_MODE */ + + uint32_t chaining_mode; /**< AES chaining mode. + This parameter can be a value of @ref AES_CHAININGMODE */ + + uint32_t *p_key; /**< Encryption/Decryption Key. + Normally, it should be a global pointer. */ + + uint32_t *p_init_vector; /**< Initialization Vector used for CBC modes */ + + uint32_t dpa_mode; /**< DPA Mode */ + + uint32_t *p_seed; /**< Random seeds */ + +} aes_init_t; +/** @} */ + +/** @defgroup AES_handle AES Handle + * @{ + */ + +/** + * @brief AES handle Structure definition + */ +typedef struct _aes_handle +{ + aes_regs_t *p_instance; /**< AES registers base address */ + + aes_init_t init; /**< AES operation parameters */ + + uint32_t *p_cryp_input_buffer; /**< Pointer to CRYP processing (encryption or decryption) input buffer */ + + uint32_t *p_cryp_output_buffer; /**< Pointer to CRYP processing (encryption or decryption) output buffer */ + + uint32_t block_size; /**< Data size in blocks (16 bytes per block) */ + + uint32_t block_count; /**< Blocks count */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_aes_state_t state; /**< AES operation state */ + + __IO uint32_t error_code; /**< AES Error code */ + + uint32_t timeout; /**< Timeout for the AES operation */ + + uint32_t retention[18]; /**< AES important register information. */ + +} aes_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_AES_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup AES_Callback AES Callback + * @{ + */ + +/** + * @brief HAL AES Callback function definition + */ +typedef struct _aes_callback +{ + void (*aes_msp_init)(aes_handle_t *p_aes); /**< AES init MSP callback */ + void (*aes_msp_deinit)(aes_handle_t *p_aes); /**< AES de-init MSP callback */ + void (*aes_error_callback)(aes_handle_t *p_aes); /**< AES error callback */ + void (*aes_done_callback)(aes_handle_t *p_aes); /**< AES encrypt or decrypt done callback */ +} aes_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_AES_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup AES_Exported_Constants AES Exported Constants + * @{ + */ + +/** @defgroup AES_Error_Code AES Error Code + * @{ + */ +#define HAL_AES_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_AES_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_AES_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_AES_ERROR_INVALID_PARAM ((uint32_t)0x00000004) /**< Invalid parameters error */ +/** @} */ + +/** @defgroup AES_Key_Size AES Key Size + * @{ + */ +#define AES_KEYSIZE_128BITS LL_AES_KEY_SIZE_128 /**< 128 bits */ +#define AES_KEYSIZE_192BITS LL_AES_KEY_SIZE_192 /**< 192 bits */ +#define AES_KEYSIZE_256BITS LL_AES_KEY_SIZE_256 /**< 256 bits */ +/** @} */ + +/** @defgroup AES_Block_Size AES Block Size + * @{ + */ +#define AES_BLOCK_MAX (2048) /**< Block max size */ +#define AES_BLOCKSIZE_BITS (128) /**< Block size in bits */ +#define AES_BLOCKSIZE_BYTES (AES_BLOCKSIZE_BITS >> 3) /**< Block size in bytes */ +#define AES_BLOCKSIZE_WORDS (AES_BLOCKSIZE_BYTES >> 2) /**< Block size in words */ +/** @} */ + +/** @defgroup AES_OPERATION_MODE AES Operation Mode + * @{ + */ +#define AES_OPERATION_MODE_ENCRYPT (1) /**< Encrypt operation mode */ +#define AES_OPERATION_MODE_DECRYPT (0) /**< Decrypt operation mode */ +/** @} */ + +/** @defgroup AES_CHAININGMODE AES Chaining Mode + * @{ + */ +#define AES_CHAININGMODE_ECB LL_AES_OPERATION_MODE_ECB /**< ECB chaining mode */ +#define AES_CHAININGMODE_CBC LL_AES_OPERATION_MODE_CBC /**< CBC chaining mode */ +/** @} */ + +/** @defgroup AES_Flags_definition AES Flags Definition + * @{ + */ +#define AES_FLAG_DATAREADY LL_AES_FLAG_DATAREADY /**< Data ready flag */ +#define AES_FLAG_DMA_DONE LL_AES_FLAG_DMA_DONE /**< DMA transfer done flag */ +#define AES_FLAG_DMA_ERR LL_AES_FLAG_DMA_ERR /**< DMA transfer error flag */ +#define AES_FLAG_KEY_VALID LL_AES_FLAG_KEY_VALID /**< Key valid flag */ +/** @} */ + +/** @defgroup AES_Interrupt_definition AES Interrupt definition + * @{ + */ +#define AES_IT_DONE ((uint32_t)0x00000001) /**< AES Encrypted or Decrypted Data Done Interrupt source */ +/** @} */ + +/** @defgroup AES_Timeout_definition AES Timeout definition + * @{ + */ +#define HAL_AES_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup AES_Exported_Macros AES Exported Macros + * @{ + */ + +/** @brief Reset AES handle states. + * @param __HANDLE__ AES handle. + * @retval None + */ +#define __HAL_AES_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_AES_STATE_RESET) + +/** @brief Enable the specified AES peripheral. + * @param __HANDLE__ Specifies the AES Handle. + * @retval None + */ +#define __HAL_AES_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, AES_CTRL_ENABLE) + +/** @brief Disable the specified AES peripheral. + * @param __HANDLE__ Specifies the AES Handle. + * @retval None + */ +#define __HAL_AES_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, AES_CTRL_ENABLE) + +/** @brief Enable the AES interrupt. + * @param __HANDLE__ Specifies the AES Handle. + * @retval None + */ +#define __HAL_AES_ENABLE_IT(__HANDLE__) ll_aes_enable_it_done((__HANDLE__)->p_instance) + +/** @brief Disable the AES interrupt. + * @param __HANDLE__ Specifies the AES Handle. + * @retval None + */ +#define __HAL_AES_DISABLE_IT(__HANDLE__) ll_aes_disable_it_done((__HANDLE__)->p_instance) + +/** @brief Check whether the specified AES interrupt flag is set or not. + * @param __HANDLE__ Specifies the AES Handle. + * @param __FLAG__ Specifies the interrupt flag to check. + * This parameter can be the following value: + * @arg @ref AES_IT_DONE Encrypted or Decrypted Data Done Interrupt + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_AES_GET_FLAG_IT(__HANDLE__, __FLAG__) (READ_BITS((__HANDLE__)->p_instance->INTERRUPT, (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified AES interrupt flag. + * @param __HANDLE__ Specifies the AES interrupt Handle. + * @param __FLAG__ Specifies the flag to clear. + * This parameter can be the following value: + * @arg @ref AES_IT_DONE Encrypted or Decrypted Data Done Interrupt + * @retval None + */ +#define __HAL_AES_CLEAR_FLAG_IT(__HANDLE__, __FLAG__) SET_BITS((__HANDLE__)->p_instance->INTERRUPT, (__FLAG__)) + +/** @brief Check whether the specified AES flag is set or not. + * @param __HANDLE__ Specifies the AES Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref AES_FLAG_DATAREADY Data ready flag + * @arg @ref AES_FLAG_DMA_DONE DMA transfer done flag + * @arg @ref AES_FLAG_DMA_ERR DMA transfer error flag + * @arg @ref AES_FLAG_KEY_VALID Key valid flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_AES_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->STATUS, (__FLAG__)) != 0) ? SET : RESET) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup AES_Private_Macro AES Private Macros + * @{ + */ + +/** @brief Check if AES Key Size is valid. + * @param __SIZE__ AES Key Size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_AES_KEY_SIZE(__SIZE__) (((__SIZE__) == AES_KEYSIZE_128BITS) || \ + ((__SIZE__) == AES_KEYSIZE_192BITS) || \ + ((__SIZE__) == AES_KEYSIZE_256BITS)) + +/** @brief Check if AES Operation Mode is valid. + * @param __MODE__ AES Operation Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_AES_OPERATION_MODE(__MODE__) (((__MODE__) == AES_OPERATION_MODE_ENCRYPT) || \ + ((__MODE__) == AES_OPERATION_MODE_DECRYPT)) + +/** @brief Check if AES Chaining Mode is valid. + * @param __MODE__ AES Chaining Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_AES_CHAININGMODE(__MODE__) (((__MODE__) == AES_CHAININGMODE_ECB) || \ + ((__MODE__) == AES_CHAININGMODE_CBC)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_AES_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup AES_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the AESx peripheral: + + (+) User must implement hal_aes_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_aes_init() to configure the selected device with + the selected configuration: + (++) Key Size + (++) operation_mode + (++) ChainingMode + (++) key + (++) init_vector + (++) DPAMode + (++) Seed + + (+) Call the function hal_aes_deinit() to restore the default configuration + of the selected AESx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the AES according to the specified parameters + * in the aes_init_t and initialize the associated handle. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration + * information for the specified AES module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_init(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief De-initialize the AES peripheral. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration + * information for the specified AES module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_deinit(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief Initialize the AES MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_aes_msp_deinit can be implemented in the user file. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration + * information for the specified AES module. + **************************************************************************************** + */ +void hal_aes_msp_init(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief De-initialize the AES MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_aes_msp_deinit can be implemented in the user file. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration + * information for the specified AES module. + **************************************************************************************** + */ +void hal_aes_msp_deinit(aes_handle_t *p_aes); + +/** @} */ + +/** @addtogroup AES_Exported_Functions_Group2 IO operation functions + * @brief AES Encrypt/Decrypt functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the AES encrypt or decrypt. + + (#) There are two mode of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing are returned by the same function + after finishing transfer. + (++) Non-Blocking mode: The communication is performed using Interrupts + or DMA. These API return the HAL status. + The end of the data processing will be indicated through the + dedicated AES IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_aes_done_callback() user callbacks will be executed respectively + at the end of the encrypt or decrypt process + The hal_aes_error_callback() user callback will be executed when a error is detected + + (#) Blocking mode API's are : + (++) hal_aes_ecb_encrypt() + (++) hal_aes_ecb_decrypt() + (++) hal_aes_cbc_encrypt() + (++) hal_aes_cbc_decrypt() + + (#) Non-Blocking mode API's with Interrupt are : + (++) hal_aes_ecb_encrypt_it() + (++) hal_aes_ecb_decrypt_it() + (++) hal_aes_cbc_encrypt_it() + (++) hal_aes_cbc_decrypt_it() + + (#) Non-Blocking mode API's with DMA are : + (++) hal_aes_ecb_encrypt_dma() + (++) hal_aes_ecb_decrypt_dma() + (++) hal_aes_cbc_encrypt_dma() + (++) hal_aes_cbc_decrypt_dma() + + (#) A set of encrypt or decrypt Callbacks are provided in Non_Blocking mode: + (++) hal_aes_done_callback() + (++) hal_aes_error_callback() + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in blocking mode in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_encrypt(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in blocking mode in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_decrypt(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in blocking mode in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_encrypt(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in blocking mode in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_decrypt(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in non-blocking mode with Interrupt in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_encrypt_it(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in non-blocking mode with Interrupt in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_decrypt_it(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data); + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in non-blocking mode with Interrupt in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_encrypt_it(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in non-blocking mode with Interrupt in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_decrypt_it(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data); + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in non-blocking mode with DMA in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_encrypt_dma(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in non-blocking mode with DMA in ECB mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_ecb_decrypt_dma(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data); + +/** + **************************************************************************************** + * @brief Encrypted an amount of data in non-blocking mode with DMA in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_plain_data: Pointer to plain data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_cypher_data: Pointer to cypher data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_encrypt_dma(aes_handle_t *p_aes, uint32_t *p_plain_data, uint32_t number, uint32_t *p_cypher_data); + +/** + **************************************************************************************** + * @brief Decrypted an amount of data in non-blocking mode with DMA in CBC mode. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] p_cypher_data: Pointer to cypher data buffer + * @param[in] number: Amount of data to be decrypted in bytes + * @param[out] p_plain_data: Pointer to plain data buffer + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_cbc_decrypt_dma(aes_handle_t *p_aes, uint32_t *p_cypher_data, uint32_t number, uint32_t *p_plain_data); + +/** @} */ + +/** @addtogroup AES_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle AES interrupt request. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified the specified AES module. + **************************************************************************************** + */ +void hal_aes_irq_handler(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief Encrypt or decrypt Done callback. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + **************************************************************************************** + */ +void hal_aes_done_callback(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief AES error callback. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + **************************************************************************************** + */ +void hal_aes_error_callback(aes_handle_t *p_aes); + +/** @} */ + +/** @defgroup AES_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief AES control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the AES. + (+) hal_aes_get_state() API can be helpful to check in run-time the state of the AES peripheral. + (+) hal_aes_get_error() check in run-time Errors occurring during communication. + (+) hal_aes_set_timeout() set the timeout during internal process. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the AES handle state. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * + * @retval ::HAL_AES_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_AES_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_AES_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_AES_STATE_ERROR: Peripheral in error. + * @retval ::HAL_AES_STATE_TIMEOUT: Peripheral in timeout. + * @retval ::HAL_AES_STATE_SUSPENDED: Peripheral in suspended. + **************************************************************************************** + */ +hal_aes_state_t hal_aes_get_state(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief Return the AES error code. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * + * @return AES error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_aes_get_error(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief Set the AES internal process timeout value. + * + * @param[in] p_aes: Pointer to an AES handle which contains the configuration information for + * the specified AES module. + * @param[in] timeout: Internal process timeout value. + **************************************************************************************** + */ +void hal_aes_set_timeout(aes_handle_t *p_aes, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Suspend some registers related to AES configuration before sleep. + * @param[in] p_aes: Pointer to a AES handle which contains the configuration + * information for the specified AES module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_suspend_reg(aes_handle_t *p_aes); + +/** + **************************************************************************************** + * @brief Restore some registers related to AES configuration after sleep. + * This function must be used in conjunction with the hal_aes_suspend_reg(). + * @param[in] p_aes: Pointer to a AES handle which contains the configuration + * information for the specified AES module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aes_resume_reg(aes_handle_t *p_aes); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_AES_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio.h new file mode 100644 index 0000000..c186db0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio.h @@ -0,0 +1,419 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_aon_gpio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AON GPIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_AON_GPIO AON_GPIO + * @brief AON_GPIO HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_AON_GPIO_H__ +#define __GR55xx_HAL_AON_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_aon_gpio.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_AON_GPIO_ENUMERATIONS Enumerations + * @{ + */ + +/** + * @brief AON_GPIO Bit SET and Bit RESET enumerations + */ +typedef enum +{ + AON_GPIO_PIN_RESET = 0U, /**< AON GPIO pin low level.*/ + AON_GPIO_PIN_SET /**< AON GPIO pin high level.*/ +} aon_gpio_pin_state_t; + +/** @} */ + +/** @addtogroup HAL_AON_GPIO_STRUCTURES Structures + * @{ + */ + +/** + * @brief AON_GPIO init structure definition + */ +typedef struct _aon_gpio_init +{ + uint32_t pin; /**< Specifies the AON_GPIO pins to be configured. + This parameter can be any value of @ref AON_GPIO_Pins */ + + uint32_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref AON_GPIO_Mode */ + + uint32_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref AON_GPIO_Pull */ + + uint32_t mux; /**< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIOEx_Mux_Function_Selection. */ +} aon_gpio_init_t; + +/** @} */ + +/** @addtogroup HAL_AON_GPIO_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup AON_GPIO_Callback AON_GPIO Callback + * @{ + */ + +/** + * @brief HAL AON_GPIO Callback function definition + */ +typedef struct _aon_gpio_callback +{ + void (*aon_gpio_callback)(uint16_t aon_gpio_pin); /**< AON GPIO pin detection callback */ +} aon_gpio_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_AON_GPIO_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup AON_GPIO_Exported_Constants AON_GPIO Exported Constants + * @{ + */ + +/** @defgroup AON_GPIO_Pins AON_GPIO pins + * @{ + */ +#define AON_GPIO_PIN_0 ((uint16_t)0x0001U) /**< Pin 0 selected */ +#define AON_GPIO_PIN_1 ((uint16_t)0x0002U) /**< Pin 1 selected */ +#define AON_GPIO_PIN_2 ((uint16_t)0x0004U) /**< Pin 2 selected */ +#define AON_GPIO_PIN_3 ((uint16_t)0x0008U) /**< Pin 3 selected */ +#define AON_GPIO_PIN_4 ((uint16_t)0x0010U) /**< Pin 4 selected */ +#define AON_GPIO_PIN_5 ((uint16_t)0x0020U) /**< Pin 5 selected */ +#define AON_GPIO_PIN_6 ((uint16_t)0x0040U) /**< Pin 6 selected */ +#define AON_GPIO_PIN_7 ((uint16_t)0x0080U) /**< Pin 7 selected */ + +#define AON_GPIO_PIN_ALL ((uint16_t)0x00FFU) /**< All pins selected */ + +#define AON_GPIO_PIN_MASK (0x000000FFU) /**< PIN mask for assert test */ +/** @} */ + +/** @defgroup AON_GPIO_Mode AON_GPIO mode + * @brief AON_GPIO Configuration Mode + * Elements values convention: 0x000000YX + * - X : IO Direction mode (Input, Output, Mux) + * - Y : IT trigger detection + * @{ + */ +#define AON_GPIO_MODE_INPUT (LL_AON_GPIO_MODE_INPUT << 0) /**< Input Mode */ +#define AON_GPIO_MODE_OUTPUT (LL_AON_GPIO_MODE_OUTPUT << 0) /**< Output Mode */ +#define AON_GPIO_MODE_MUX (LL_GPIO_MODE_MUX << 0) /**< Mux Mode */ +#define AON_GPIO_MODE_IT_RISING (LL_AON_GPIO_TRIGGER_RISING << 4) /**< Interrupt Mode with Rising edge trigger detection */ +#define AON_GPIO_MODE_IT_FALLING (LL_AON_GPIO_TRIGGER_FALLING << 4) /**< Interrupt Mode with Falling edge trigger detection */ +#define AON_GPIO_MODE_IT_HIGH (LL_AON_GPIO_TRIGGER_HIGH << 4) /**< Interrupt Mode with High-level trigger detection */ +#define AON_GPIO_MODE_IT_LOW (LL_AON_GPIO_TRIGGER_LOW << 4) /**< Interrupt Mode with Low-level trigger detection */ +/** @} */ + + +/** @defgroup AON_GPIO_Pull AON_GPIO pull + * @brief AON_GPIO Pull-Up or Pull-Down activation + * @{ + */ +#define AON_GPIO_NOPULL LL_AON_GPIO_PULL_NO /**< No Pull-up or Pull-down activation */ +#define AON_GPIO_PULLUP LL_AON_GPIO_PULL_UP /**< Pull-up activation */ +#define AON_GPIO_PULLDOWN LL_AON_GPIO_PULL_DOWN /**< Pull-down activation */ +/** @} */ + +/** + * @brief AON_GPIO_default_config initStruct default configuartion + */ +#define AON_GPIO_DEFAULT_CONFIG \ +{ \ + .pin = AON_GPIO_PIN_ALL, \ + .mode = AON_GPIO_MODE_INPUT, \ + .pull = AON_GPIO_PULLDOWN, \ + .mux = AON_GPIO_MUX_7, \ +} +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup AON_GPIO_Exported_Macros AON_GPIO Exported Macros + * @{ + */ + +/** + * @brief Check whether the specified AON_GPIO pin is asserted or not. + * @param __AON_GPIO_PIN__ specifies the AON_GPIO pin to be checked. + * This parameter can be AON_GPIO_PIN_x where x can be (0..15). + * @retval The new state of __AON_GPIO_PIN__ (SET or RESET). + */ +#define __HAL_AON_GPIO_IT_GET_IT(__AON_GPIO_PIN__) ll_aon_gpio_read_flag_it(__AON_GPIO_PIN__) + +/** + * @brief Clear the AON_GPIO pin pending bits. + * @param __AON_GPIO_PIN__ specifies the AON_GPIO pins to be cleared. + * This parameter can be any combination of AON_GPIO_PIN_x where x can be (0..15). + * @retval None + */ +#define __HAL_AON_GPIO_IT_CLEAR_IT(__AON_GPIO_PIN__) ll_aon_gpio_clear_flag_it(__AON_GPIO_PIN__) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup AON_GPIO_Private_Macros AON_GPIO Private Macros + * @{ + */ + +/** + * @brief Check if AON GPIO pin action is valid. + * @param __ACTION__ AON GPIO pin action. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_AON_GPIO_PIN_ACTION(__ACTION__) (((__ACTION__) == AON_GPIO_PIN_RESET) || ((__ACTION__) == AON_GPIO_PIN_SET)) + +/** + * @brief Check if AON GPIO pins are valid. + * @param __PIN__ AON GPIO pins. + * @retval SET (__PIN__ is valid) or RESET (__PIN__ is invalid) + */ +#define IS_AON_GPIO_PIN(__PIN__) ((((__PIN__) & AON_GPIO_PIN_MASK) != 0x00U) &&\ + (((__PIN__) & ~AON_GPIO_PIN_MASK) == 0x00U)) + +/** + * @brief Check if AON GPIO mode is valid. + * @param __MODE__ AON GPIO mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_AON_GPIO_MODE(__MODE__) (((__MODE__) == AON_GPIO_MODE_INPUT) ||\ + ((__MODE__) == AON_GPIO_MODE_OUTPUT) ||\ + ((__MODE__) == AON_GPIO_MODE_MUX) ||\ + ((__MODE__) == AON_GPIO_MODE_IT_RISING) ||\ + ((__MODE__) == AON_GPIO_MODE_IT_FALLING) ||\ + ((__MODE__) == AON_GPIO_MODE_IT_HIGH) ||\ + ((__MODE__) == AON_GPIO_MODE_IT_LOW)) + +/** + * @brief Check if AON GPIO pull type is valid. + * @param __PULL__ AON GPIO pull type. + * @retval SET (__PULL__ is valid) or RESET (__PULL__ is invalid) + */ +#define IS_AON_GPIO_PULL(__PULL__) (((__PULL__) == AON_GPIO_NOPULL) ||\ + ((__PULL__) == AON_GPIO_PULLUP) || \ + ((__PULL__) == AON_GPIO_PULLDOWN)) + +/** @} */ + +/** @} */ + +/* Include AON GPIO HAL Extended module */ +#include "gr55xx_hal_aon_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_AON_GPIO_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup AON_GPIO_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the AON_GPIOx peripheral according to the specified parameters in the @ref aon_gpio_init_t. + * + * @param[in] p_aon_gpio_init: Pointer to an @ref aon_gpio_init_t structure that contains + * the configuration information for the specified AON_GPIO peripheral port. + **************************************************************************************** + */ +void hal_aon_gpio_init(aon_gpio_init_t *p_aon_gpio_init); + +/** + **************************************************************************************** + * @brief De-initialize the AON_GPIOx peripheral registers to their default reset values. + * + * @param[in] aon_gpio_pin: Specifies the port bit to be written. + * This parameter can be a combination of the following values: + * @arg @ref AON_GPIO_PIN_0 + * @arg @ref AON_GPIO_PIN_1 + * @arg @ref AON_GPIO_PIN_2 + * @arg @ref AON_GPIO_PIN_3 + * @arg @ref AON_GPIO_PIN_4 + * @arg @ref AON_GPIO_PIN_5 + * @arg @ref AON_GPIO_PIN_6 + * @arg @ref AON_GPIO_PIN_7 + * @arg @ref AON_GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_aon_gpio_deinit(uint32_t aon_gpio_pin); + +/** @} */ + +/** @addtogroup AON_GPIO_Exported_Functions_Group2 IO operation functions + * @brief AON_GPIO Read, Write, Toggle, Lock and EXTI management functions. + * @{ + */ + +/** + **************************************************************************************** + * @brief Read the specified input port pin. + * + * @param[in] aon_gpio_pin: Specifies the port bit to be read. + * This parameter can be one of the following values: + * @arg @ref AON_GPIO_PIN_0 + * @arg @ref AON_GPIO_PIN_1 + * @arg @ref AON_GPIO_PIN_2 + * @arg @ref AON_GPIO_PIN_3 + * @arg @ref AON_GPIO_PIN_4 + * @arg @ref AON_GPIO_PIN_5 + * @arg @ref AON_GPIO_PIN_6 + * @arg @ref AON_GPIO_PIN_7 + * + * @return The input port pin value. + **************************************************************************************** + */ +aon_gpio_pin_state_t hal_aon_gpio_read_pin(uint16_t aon_gpio_pin); + +/** + **************************************************************************************** + * @brief Set or clear the selected data port bit. + * + * @param[in] aon_gpio_pin: Specifies the port bit to be written. + * This parameter can be a combination of the following values: + * @arg @ref AON_GPIO_PIN_0 + * @arg @ref AON_GPIO_PIN_1 + * @arg @ref AON_GPIO_PIN_2 + * @arg @ref AON_GPIO_PIN_3 + * @arg @ref AON_GPIO_PIN_4 + * @arg @ref AON_GPIO_PIN_5 + * @arg @ref AON_GPIO_PIN_6 + * @arg @ref AON_GPIO_PIN_7 + * @arg @ref AON_GPIO_PIN_ALL + * @param[in] pin_state: Specifies the value to be written to the selected bit. + * This parameter can be one of the AON_GPIO_PinState enum values: + * @arg AON_GPIO_PIN_RESET: to clear the port pin + * @arg AON_GPIO_PIN_SET: to set the port pin + **************************************************************************************** + */ +void hal_aon_gpio_write_pin(uint16_t aon_gpio_pin, aon_gpio_pin_state_t pin_state); + +/** + **************************************************************************************** + * @brief Toggle the specified AON_GPIO pin. + * + * @param[in] aon_gpio_pin: Specifies the pin to be toggled. + * This parameter can be a combination of the following values: + * @arg @ref AON_GPIO_PIN_0 + * @arg @ref AON_GPIO_PIN_1 + * @arg @ref AON_GPIO_PIN_2 + * @arg @ref AON_GPIO_PIN_3 + * @arg @ref AON_GPIO_PIN_4 + * @arg @ref AON_GPIO_PIN_5 + * @arg @ref AON_GPIO_PIN_6 + * @arg @ref AON_GPIO_PIN_7 + * @arg @ref AON_GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_aon_gpio_toggle_pin(uint16_t aon_gpio_pin); + +/** @} */ + +/** @addtogroup AON_GPIO_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle AON_GPIO interrupt request. + **************************************************************************************** + */ +void hal_aon_gpio_irq_handler(void); + +/** + **************************************************************************************** + * @brief AON GPIO pin detection callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_aon_gpio_callback can be implemented in the user file. + * + * @param[in] aon_gpio_pin: Indicate the port pin whose interrupt was triggered. + * This parameter can be a combination of the following values: + * @arg @ref AON_GPIO_PIN_0 + * @arg @ref AON_GPIO_PIN_1 + * @arg @ref AON_GPIO_PIN_2 + * @arg @ref AON_GPIO_PIN_3 + * @arg @ref AON_GPIO_PIN_4 + * @arg @ref AON_GPIO_PIN_5 + * @arg @ref AON_GPIO_PIN_6 + * @arg @ref AON_GPIO_PIN_7 + * @arg @ref AON_GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_aon_gpio_callback(uint16_t aon_gpio_pin); + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_AON_GPIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio_ex.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio_ex.h new file mode 100644 index 0000000..9e76eb3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_gpio_ex.h @@ -0,0 +1,181 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_aon_gpio_ex.h + * @author BLE Driver Team + * @brief Header file containing extended macro of AON GPIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_AON_GPIOEx AON_GPIOEx + * @brief AON_GPIOEx HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_AON_GPIO_EX_H__ +#define __GR55xx_HAL_AON_GPIO_EX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_gpio.h" + +/* Exported types ------------------------------------------------------------*/ + +/** + * @defgroup HAL_AON_GPIOEX_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup AON_GPIOEx_Exported_Constants AON_GPIOEx Exported Constants + * @{ + */ + +/** @defgroup AON_GPIOEx_Mux_Mode AON_GPIOEx Mux Mode definition + * @{ + */ +#define AON_GPIO_MUX_0 LL_AON_GPIO_MUX_0 /**< AON GPIO Mux mode 0 */ +#define AON_GPIO_MUX_1 LL_AON_GPIO_MUX_1 /**< AON GPIO Mux mode 1 */ +#define AON_GPIO_MUX_2 LL_AON_GPIO_MUX_2 /**< AON GPIO Mux mode 2 */ +#define AON_GPIO_MUX_3 LL_AON_GPIO_MUX_3 /**< AON GPIO Mux mode 3 */ +#define AON_GPIO_MUX_4 LL_AON_GPIO_MUX_4 /**< AON GPIO Mux mode 4 */ +#define AON_GPIO_MUX_5 LL_AON_GPIO_MUX_5 /**< AON GPIO Mux mode 5 */ +#define AON_GPIO_MUX_6 LL_AON_GPIO_MUX_6 /**< AON GPIO Mux mode 6 */ +#define AON_GPIO_MUX_7 LL_AON_GPIO_MUX_7 /**< AON GPIO Mux mode 7 */ +/** @} */ + +/** @defgroup AON_GPIOEx_Mux_Function_Selection AON_GPIOEx Mux function selection + * @{ + */ + +#if defined (GR551xx) +/*---------------------------------- GR551xx ------------------------------*/ + +/** @defgroup AON_GPIOEx_Common_Selection AON_GPIO PIN common MUX selection(Available for all AON GPIO pins) + * @{ + */ + +#define AON_GPIO_PIN_MUX_GPIO AON_GPIO_MUX_7 /**< AON GPIO PIN x Mux Select GPIO */ + +/** @} */ + +/** @defgroup AON_GPIOEx_PIN0_Mux_Selection AON_GPIO_PIN1 MUX selection + * @{ + */ +#define AON_GPIO_PIN1_MUX_QSPIM0_CS_N AON_GPIO_MUX_5 /**< AON_GPIO_PIN1 Mux Select QSPIM0_CS_N */ +#define AON_GPIO_PIN1_MUX_COEX_BLE_TX AON_GPIO_MUX_6 /**< AON_GPIO_PIN1 Mux Select COEX_BLE_TX */ +/** @} */ + +/** @defgroup AON_GPIOEx_PIN2_Mux_Selection AON_GPIO_PIN2 MUX selection + * @{ + */ +#define AON_GPIO_PIN2_MUX_SIM_PRESENCE AON_GPIO_MUX_0 /**< AON_GPIO_PIN2 Mux Select SIM_PRESENCE */ +#define AON_GPIO_PIN2_MUX_QSPIM1_CS_N AON_GPIO_MUX_1 /**< AON_GPIO_PIN2 Mux Select QSPIM1_CS_N */ +#define AON_GPIO_PIN2_MUX_I2S_WS AON_GPIO_MUX_2 /**< AON_GPIO_PIN2 Mux Select I2S_WS */ +#define AON_GPIO_PIN2_MUX_I2S_S_WS AON_GPIO_MUX_3 /**< AON_GPIO_PIN2 Mux Select I2S_S_WS */ +#define AON_GPIO_PIN2_MUX_PWM0_C AON_GPIO_MUX_5 /**< AON_GPIO_PIN2 Mux Select PWM0_C */ +#define AON_GPIO_PIN2_MUX_COEX_BLE_PROC AON_GPIO_MUX_6 /**< AON_GPIO_PIN2 Mux Select COEX_BLE_PROC */ +/** @} */ + +/** @defgroup AON_GPIOEx_PIN3_Mux_Selection AON_GPIO_PIN3 MUX selection + * @{ + */ +#define AON_GPIO_PIN3_MUX_SIM_RST_N AON_GPIO_MUX_0 /**< AON_GPIO_PIN3 Mux Select SIM_RST_N */ +#define AON_GPIO_PIN3_MUX_QSPIM1_IO_0 AON_GPIO_MUX_1 /**< AON_GPIO_PIN3 Mux Select QSPIM1_IO_0 */ +#define AON_GPIO_PIN3_MUX_I2S_TX_SDO AON_GPIO_MUX_2 /**< AON_GPIO_PIN3 Mux Select I2S_TX_SDO */ +#define AON_GPIO_PIN3_MUX_I2S_S_TX_SDO AON_GPIO_MUX_3 /**< AON_GPIO_PIN3 Mux Select I2S_S_TX_SDO */ +#define AON_GPIO_PIN3_MUX_PWM1_A AON_GPIO_MUX_5 /**< AON_GPIO_PIN3 Mux Select PWM1_A */ +#define AON_GPIO_PIN3_MUX_COEX_WLAN_RX AON_GPIO_MUX_6 /**< AON_GPIO_PIN3 Mux Select COEX_WLAN_RX */ +/** @} */ + +/** @defgroup AON_GPIOEx_PIN4_Mux_Selection AON_GPIO_PIN4 MUX selection + * @{ + */ +#define AON_GPIO_PIN4_MUX_SIM_IO AON_GPIO_MUX_0 /**< AON_GPIO_PIN4 Mux Select SIM_IO */ +#define AON_GPIO_PIN4_MUX_QSPIM1_IO_1 AON_GPIO_MUX_1 /**< AON_GPIO_PIN4 Mux Select QSPIM1_IO_1 */ +#define AON_GPIO_PIN4_MUX_I2S_RX_SDI AON_GPIO_MUX_2 /**< AON_GPIO_PIN4 Mux Select I2S_RX_SDI */ +#define AON_GPIO_PIN4_MUX_I2S_S_RX_SDI AON_GPIO_MUX_3 /**< AON_GPIO_PIN4 Mux Select I2S_S_RX_SDI */ +#define AON_GPIO_PIN4_MUX_PWM1_B AON_GPIO_MUX_5 /**< AON_GPIO_PIN4 Mux Select PWM1_B */ +#define AON_GPIO_PIN4_MUX_COEX_BLE_RX AON_GPIO_MUX_6 /**< AON_GPIO_PIN4 Mux Select COEX_BLE_RX */ +/** @} */ + +/** @defgroup AON_GPIOEx_PIN5_Mux_Selection AON_GPIO_PIN5 MUX selection + * @{ + */ +#define AON_GPIO_PIN5_MUX_SIM_CLK AON_GPIO_MUX_0 /**< AON_GPIO_PIN5 Mux Select SIM_CLK */ +#define AON_GPIO_PIN5_MUX_QSPIM1_CLK AON_GPIO_MUX_1 /**< AON_GPIO_PIN5 Mux Select QSPIM1_CLK */ +#define AON_GPIO_PIN5_MUX_I2S_SCLK AON_GPIO_MUX_2 /**< AON_GPIO_PIN5 Mux Select I2S_SCLK */ +#define AON_GPIO_PIN5_MUX_I2S_S_SCLK AON_GPIO_MUX_3 /**< AON_GPIO_PIN5 Mux Select I2S_S_SCLK */ +#define AON_GPIO_PIN5_MUX_PWM1_C AON_GPIO_MUX_5 /**< AON_GPIO_PIN5 Mux Select PWM1_C */ +#define AON_GPIO_PIN5_MUX_COEX_WLAN_TX AON_GPIO_MUX_6 /**< AON_GPIO_PIN5 Mux Select COEX_WLAN_TX */ +/** @} */ + +/** + * @brief Check if AON GPIO Mux mode is valid. + * @param __MUX__ AON GPIO Mux mode. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_AON_GPIO_MUX(__MUX__) (((__MUX__) <= AON_GPIO_MUX_7)) + +/*------------------------------------------------------------------------------------------*/ +#endif /* GR551xx */ + +/** @} */ + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_AON_GPIO_EX_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_wdt.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_wdt.h new file mode 100644 index 0000000..6883000 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_aon_wdt.h @@ -0,0 +1,267 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_aon_wdt.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AON WDT HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_AON_WDT AON_WDT + * @brief WDT HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_AON_WDT_H__ +#define __GR55xx_HAL_AON_WDT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_aon_wdt.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_AON_WDT_STRUCTURES Structures + * @{ + */ + +/** @defgroup AON_WDT_Configuration AON_WDT Configuration + * @{ + */ + +/** + * @brief AON_WDT_Configuration init structure definition + */ +typedef struct _aon_wdt_init +{ + uint32_t counter; /**< Specifies the AON_WDT free-running downcounter value. + This parameter can be a number ranging between 0x0U ~ 0xFFFFFFFFU. */ + + uint32_t alarm_counter; /**< Specifies the AON_WDT downcounter alarm value before system reset. + When counter counts down to the alarm value, AON_WDT will generate + an interrupt. After counter counts down to 0, AON_WDT will then + request a SoC Reset. + + This parameter can be a number ranging between 0x0U ~ 0x1FU, and the default value is 20U. */ + +} aon_wdt_init_t; + +/** @} */ + +/** @defgroup AON_WDT_handle AON_WDT handle + * @{ + */ + +/** + * @brief AON_WDT handle Structure definition + */ +typedef struct _aon_wdt_handle +{ + aon_wdt_init_t init; /**< AON_WDT required parameters */ + + hal_lock_t lock; /**< AON_WDT locking object */ + +} aon_wdt_handle_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_AON_WDT_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_AON_WDT_Callback Callback + * @{ + */ + +/** + * @brief HAL_AON_WDT Callback function definition + */ + +typedef struct _aon_wdt_callback +{ + void (*aon_wdt_alarm_callback)(aon_wdt_handle_t *p_aon_wdt); /**< AON_WDT count complete callback */ +} hal_aon_wdt_callback_t; + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_AON_WDT_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup AON_WDT_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and start the AON_WDT according to the specified parameters + in the wdt_init_t of associated handle. + (+) Initialize the AON_WDT MSP. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the AON_WDT according to the specified parameters in the wdt_init_t + * of associated handle. + * + * @param[in] p_aon_wdt: Pointer to a AON_WDT handle which contains the configuration + * information for the specified AON_WDT module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aon_wdt_init(aon_wdt_handle_t *p_aon_wdt); + +/** + **************************************************************************************** + * @brief De-initialize the AON_WDT peripheral. + * + * @param[in] p_aon_wdt: AON_WDT handle. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aon_wdt_deinit(aon_wdt_handle_t *p_aon_wdt); + +/** @} */ + +/** @addtogroup AON_WDT_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Refresh the AON_WDT. + (+) Handle AON_WDT interrupt request and associated function callback. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Refresh the AON_WDT. + * + * @param[in] p_aon_wdt: Pointer to a AON_WDT handle which contains the configuration + * information for the specified AON_WDT module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_aon_wdt_refresh(aon_wdt_handle_t *p_aon_wdt); + +/** @} */ + + +/** @addtogroup AON_WDT_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle AON_WDT interrupt request. + * + * @note The count completed can be used if specific safety operations + * or data logging must be performed before the actual reset is generated. + * When RESET Mode is enabled, AON_WDT will generate an interrupt on first timeout. + * If interrupt has not been cleared before the second timeout, AON_WDT will then + * request a SoC Reset. + * + * @param[in] p_aon_wdt: Pointer to a AON_WDT handle which contains the configuration + * information for the specified AON_WDT module. + **************************************************************************************** + */ +void hal_aon_wdt_irq_handler(aon_wdt_handle_t *p_aon_wdt); + +/** + **************************************************************************************** + * @brief AON_WDT count complete (counter reaches to 0) callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_wdt_count_cplt_callback can be implemented in the user file. + * + * @param[in] p_aon_wdt: Pointer to a AON_WDT handle which contains the configuration + * information for the specified AON_WDT module. + **************************************************************************************** + */ +void hal_aon_wdt_alarm_callback(aon_wdt_handle_t *p_aon_wdt); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_AON_WDT_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_bod.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_bod.h new file mode 100644 index 0000000..a791db6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_bod.h @@ -0,0 +1,297 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_bod.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ADC HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_BOD BOD + * @brief BOD HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_BOD_H__ +#define __GR55xx_HAL_BOD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_bod.h" +#include "gr55xx_hal_def.h" +#include + +/* Exported types ------------------------------------------------------------*/ + + +/** @addtogroup HAL_BOD_TYPEDEFS Structures + * @{ + */ +/** + * @brief BOD init structure definition + */ +typedef ll_bod_init_t bod_init_t; +/** + * @brief BOD handle Structure definition + */ +typedef struct _bod_handle +{ + bod_init_t init; /**< BOD configuration parameters */ + __IO hal_lock_t lock; /**< Locking object */ +} bod_handle_t; +/** @} */ + +/** + * @defgroup HAL_BOD_MACRO Defines + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup BOD_Exported_Constants BOD Exported Constants + * @{ + */ + +/** @defgroup BOD_HAL_ENABLE BOD ENABLE + * @{ + */ +#define HAL_BOD_ENABLE LL_BOD_ENABLE /**< BOD enable */ +#define HAL_BOD_DISABLE LL_BOD_DISABLE /**< BOD disable */ +/** @} */ + +/** @defgroup BOD2_HAL_ENABLE BOD2 ENABLE + * @{ + */ +#define HAL_BOD2_ENABLE LL_BOD2_ENABLE /**< BOD2 enable */ +#define HAL_BOD2_DISABLE LL_BOD2_DISABLE /**< BOD2 disable */ +/** @} */ + +/** @defgroup BOD_HAL_STATIC_ENABLE BOD STATIC ENABLE + * @{ + */ +#define HAL_BOD_STATIC_ENABLE LL_BOD_STATIC_ENABLE /**< BOD STATIC enable */ +#define HAL_BOD_STATIC_DISABLE LL_BOD_STATIC_DISABLE /**< BOD STATIC disable */ +/** @} */ + +/** @defgroup BOD2_HAL_LEVEL BOD2 LVEVL + * @{ + */ +#define HAL_BOD2_LEVEL_0 LL_BOD2_LEVEL_0 /**< BOD2 Level 0 */ +#define HAL_BOD2_LEVEL_1 LL_BOD2_LEVEL_1 /**< BOD2 Level 1 */ +#define HAL_BOD2_LEVEL_2 LL_BOD2_LEVEL_2 /**< BOD2 Level 2 */ +#define HAL_BOD2_LEVEL_3 LL_BOD2_LEVEL_3 /**< BOD2 Level 3 */ +#define HAL_BOD2_LEVEL_4 LL_BOD2_LEVEL_4 /**< BOD2 Level 4 */ +#define HAL_BOD2_LEVEL_5 LL_BOD2_LEVEL_5 /**< BOD2 Level 5 */ +#define HAL_BOD2_LEVEL_6 LL_BOD2_LEVEL_6 /**< BOD2 Level 6 */ +#define HAL_BOD2_LEVEL_7 LL_BOD2_LEVEL_7 /**< BOD2 Level 7 */ +/** @} */ +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_BOD_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup BOD_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and Configuration functions + * @{ + */ +/* Exported functions --------------------------------------------------------*/ + +/** + **************************************************************************************** + * @brief Initialize the BOD according to the specified parameters + * in the bod_init_t and initialize the associated handle. + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_bod_init(bod_handle_t *p_bod); + +/** + **************************************************************************************** + * @brief De-initialize the BOD peripheral. + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_bod_deinit(bod_handle_t *p_bod); + +/** + **************************************************************************************** + * @brief Initialize the BOD MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_bod_msp_init could be implemented in the user file + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + **************************************************************************************** + */ +void hal_bod_msp_init(bod_handle_t *p_bod); + +/** + **************************************************************************************** + * @brief De-initialize the BOD MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_bod_msp_deinit could be implemented in the user file + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + **************************************************************************************** + */ +void hal_bod_msp_deinit(bod_handle_t *p_bod); + +/** + **************************************************************************************** + * @brief BOD fall edge callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_bod_fedge_callback can be implemented in the user file. + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + **************************************************************************************** + */ +void hal_bod_fedge_callback(bod_handle_t *p_bod); + +/** + **************************************************************************************** + * @brief Handle BOD fall edge interrupt request. + * + * @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for + * the specified BOD module. + **************************************************************************************** + */ +void hal_bod_fedge_irq_handler(bod_handle_t *p_bod); + +/** +**************************************************************************************** +* @brief enable bod +* +* @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for +* the specified BOD module. +* @param[in] enable: bod enable flag. the value can be HAL_BOD_ENABLE or HAL_BOD_DISABLE +* +* @retval ::HAL_OK: Operation is OK. +* @retval ::HAL_ERROR: Parameter error or operation not supported. +* @retval ::HAL_BUSY: Driver is busy. +* @retval ::HAL_TIMEOUT: Timeout occurred. +**************************************************************************************** +*/ +hal_status_t hal_bod_enable(bod_handle_t *p_bod, uint8_t enable); + +/** +**************************************************************************************** +* @brief enable bod2 +* +* @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for +* the specified BOD module. +* @param[in] enable: bod2 enable flag. the value can be HAL_BOD2_ENABLE or HAL_BOD2_DISABLE +* +* @retval ::HAL_OK: Operation is OK. +* @retval ::HAL_ERROR: Parameter error or operation not supported. +* @retval ::HAL_BUSY: Driver is busy. +* @retval ::HAL_TIMEOUT: Timeout occurred. +**************************************************************************************** +*/ +hal_status_t hal_bod2_enable(bod_handle_t *p_bod, uint8_t enable); + +/** +**************************************************************************************** +* @brief Set BOD2 control level. +* +* @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for +* the specified BOD module. +* @param[in] level: the level of bod2 control.the value range between 0x0 ~ 0xF +* +* @retval ::HAL_OK: Operation is OK. +* @retval ::HAL_ERROR: Parameter error or operation not supported. +* @retval ::HAL_BUSY: Driver is busy. +* @retval ::HAL_TIMEOUT: Timeout occurred. +**************************************************************************************** +*/ +hal_status_t hal_bod2_set_level(bod_handle_t *p_bod, uint8_t level); + +/** +**************************************************************************************** +* @brief enable/disable static mode +* +* @param[in] p_bod: Pointer to an BOD handle which contains the configuration information for +* the specified BOD module. +* @param[in] enable: static enable flag. the value can be HAL_BOD_STATIC_ENABLE or HAL_BOD_STATIC_DISABLE +* +* @retval ::HAL_OK: Operation is OK. +* @retval ::HAL_ERROR: Parameter error or operation not supported. +* @retval ::HAL_BUSY: Driver is busy. +* @retval ::HAL_TIMEOUT: Timeout occurred. +**************************************************************************************** +*/ +hal_status_t hal_bod_static_mode_enable(bod_handle_t *p_bod, uint8_t enable); +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_BOD_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_calendar.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_calendar.h new file mode 100644 index 0000000..f34a768 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_calendar.h @@ -0,0 +1,575 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_calendar.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of CALENDAR HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_CALENDAR CALENDAR + * @brief CALENDAR HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_CALENDAR_H__ +#define __GR55xx_HAL_CALENDAR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_calendar.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_CALENDAR_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_CALENDAR_STATE HAL CALENDAR state + * @{ + */ +/** + * @brief HAL CALENDAR State Enumerations definition + */ +typedef enum +{ + HAL_CALENDAR_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_CALENDAR_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_CALENDAR_STATE_ERROR = 0x04 /**< Peripheral in error */ +} hal_calender_state_t; + +/** @} */ +/** @} */ + + +/** @addtogroup HAL_CALENDAR_STRUCTURES Structures + * @{ + */ +/** @defgroup CALENDAR_Time CALENDAR Time + * @{ + */ + +/** + * @brief CALENDAR_Time calendar time structure definition + */ +typedef struct _calendar_time +{ + uint8_t sec; /**< Specifies the Calendar time seconds. + This parameter must be a number between min_value = 0 and max_value = 59. */ + + uint8_t min; /**< Specifies the Calendar time minutes. + This parameter must be a number between min_value = 0 and max_value = 59. */ + + uint8_t hour; /**< Specifies the Calendar time hour. + This parameter must be a number between min_value = 0 and max_value = 23. */ + + uint8_t date; /**< Specifies the Calendar date. + This parameter must be a number between min_value = 1 and max_value = 31. */ + + uint8_t mon; /**< Specifies the Calendar month. + This parameter must be a number between min_value = 1 and max_value = 12. */ + + uint8_t year; /**< Specifies the Calendar year which stars from 2010. + This parameter must be a number between min_value = 10 and max_value = 99. */ + + uint8_t week; /**< Specifies the Calendar weekday. + This parameter must be a number between min_value = 0 and max_value = 6. */ + + uint16_t ms; /**< The Calendar time milliseconds. + This parameter must be a number between min_value = 0 and max_value = 999. + Note: This parameter is used for internal calculation, the user does not need to care*/ +} calendar_time_t; + +/** + * @brief CALENDAR_Alarm calendar alarm structure definition + */ +typedef struct _calendar_alarm +{ + uint8_t min; /**< Specifies the alarm time minutes. + This parameter must be a number between min_value = 0 and max_value = 59. */ + + uint8_t hour; /**< Specifies the alarm time hour. + This parameter must be a number between min_value = 0 and max_value = 23. */ + + uint8_t alarm_sel; /**< Specifies the alarm is on date or weekday. + This parameter can be a value of @ref CALENDAR_ALARM_SEL. */ + + uint8_t alarm_date_week_mask; /**< Specifies the alarm date/weekday. + If the alarm date is selected, this parameter must be set to a value in the 1 ~ 31 range. + If the alarm weekday is selected, this parameter must be a value of @ref CALENDAR_ALARM_WEEKDAY. */ + +} calendar_alarm_t; + +/** @} */ + +/** @defgroup CALENDAR_handle CALENDAR handle + * @{ + */ + +/** + * @brief CALENDAR handle Structure definition + */ +typedef struct _calendar_handle +{ + calendar_time_t time_init; /**< Specifies the Calendar inital time. */ + + calendar_alarm_t alarm; /**< Specifies the Calendar date alarm. */ + + hal_lock_t lock; /**< Specifies the Calendar locking object. */ + + uint32_t prev_ms; /**< Accumulated millisecond count .*/ + + uint32_t interval; /**< Specifies the Calendar milliseconds alarm. */ + + uint8_t mode; /**< Specifies the Calendar alarm mode. */ + + uint8_t sec; /**< The seconds for the date alarm. */ + + uint16_t ms; /**< The milliseconds for the date alarm. */ + + hal_calender_state_t state; /**< Calendar state */ +} calendar_handle_t; + +/** @} */ +/** @} */ + + +/** @addtogroup HAL_CALENDAR_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_CALENDAR_Callback Callback + * @{ + */ + +/** + * @brief HAL_CALENDAR Callback function definition + */ + +typedef struct _hal_calendar_callback +{ + void (*calendar_alarm_callback)(calendar_handle_t *p_calendar); /**< CALENDAR date count complete callback */ + void (*calendar_tick_callback)(calendar_handle_t *p_calendar); /**< CALENDAR tick count complete callback */ + void (*calendar_overflow_callback)(calendar_handle_t *p_calendar); /**< CALENDAR count overflow callback */ +} hal_calendar_callback_t; + +/** @} */ + +/** @} */ + + +/** + * @defgroup HAL_CALENDAR_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CALENDAR_Exported_Constants CALENDAR Exported Constants + * @{ + */ + +/** @defgroup CALENDAR_Interrupts CALENDAR Interrupts + * @{ + */ +#define CALENDAR_IT_ALARM AON_CALENDAR_TIMER_CTL_ALARM_INT_EN /**< Alarm interrupt */ +#define CALENDAR_IT_WARP AON_CALENDAR_TIMER_CTL_WRAP_INT_EN /**< Warp interrupt */ +/** @} */ + +/** @defgroup CALENDAR_Flags CALENDAR Flags + * @{ + */ +#define CALENDAR_FLAG_ALARM AON_SLP_EVENT_CALENDAR_TIMER_ALARM /**< Alarm interrupt flag */ +#define CALENDAR_FLAG_WARP AON_SLP_EVENT_CALENDAR_TIMER_WRAP /**< Warp interrupt flag */ +/** @} */ + +/** @defgroup CALENDAR_ALARM_SEL CALENDAR Alarm type select + * @{ + */ +#define CALENDAR_ALARM_SEL_DATE (0UL) /**< Alarm in date */ +#define CALENDAR_ALARM_SEL_WEEKDAY (1UL) /**< Alarm in weekday */ +/** @} */ + +/** @defgroup CALENDAR_ALARM_WEEKDAY CALENDAR Alarm weekday + * @{ + */ +#define CALENDAR_ALARM_WEEKDAY_SUN (0x01ul) /**< Alarm weekday mask Sunday */ +#define CALENDAR_ALARM_WEEKDAY_MON (0x02ul) /**< Alarm weekday mask Monday */ +#define CALENDAR_ALARM_WEEKDAY_TUE (0x04ul) /**< Alarm weekday mask Tuesday */ +#define CALENDAR_ALARM_WEEKDAY_WED (0x08ul) /**< Alarm weekday mask Wednesday */ +#define CALENDAR_ALARM_WEEKDAY_THU (0x10ul) /**< Alarm weekday mask Thursday */ +#define CALENDAR_ALARM_WEEKDAY_FRI (0x20ul) /**< Alarm weekday mask Friday */ +#define CALENDAR_ALARM_WEEKDAY_SAT (0x40ul) /**< Alarm weekday mask Saturday */ +/** @} */ + +/** @defgroup CALENDAR_ALARM_DISABLE CALENDAR Alarm mdoe + * @{ + */ +#define CALENDAR_ALARM_DISABLE_DATE (1UL) /**< Disable date alarm */ +#define CALENDAR_ALARM_DISABLE_TICK (2UL) /**< Disable tick alarm */ +#define CALENDAR_ALARM_DISABLE_ALL ((CALENDAR_ALARM_DISABLE_DATE) | CALENDAR_ALARM_DISABLE_TICK) /**< Disable all alarm */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CALENDAR_Exported_Macros CALENDAR Exported Macros + * @{ + */ + +/** @brief Enable the specified CALENDAR peripheral. + * @retval None + */ +#define __HAL_CALENDAR_ENABLE() SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_EN) + +/** @brief Disable the specified CALENDAR peripheral. + * @retval None + */ +#define __HAL_CALENDAR_DISABLE() CLEAR_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_EN) + +/** @brief Enable the specified CALENDAR interrupts. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref CALENDAR_IT_ALARM Alarm Interrupt + * @arg @ref CALENDAR_IT_WARP Warp Interrupt + * @retval None + */ +#define __HAL_CALENDAR_ENABLE_IT(__INTERRUPT__) SET_BITS(AON->CALENDAR_TIMER_CTL, (__INTERRUPT__)) + +/** @brief Disable the specified CALENDAR interrupts. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref CALENDAR_IT_ALARM Alarm Interrupt + * @arg @ref CALENDAR_IT_WARP Warp Interrupt + * @retval None + */ +#define __HAL_CALENDAR_DISABLE_IT(__INTERRUPT__) CLEAR_BITS(AON->CALENDAR_TIMER_CTL, (__INTERRUPT__)) + +/** @brief Check whether the specified CALENDAR interrupt flag is set or not. + * @param __FLAG__ Specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref CALENDAR_FLAG_ALARM Alarm Interrupt event + * @arg @ref CALENDAR_FLAG_WARP Warp Interrupt event + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_CALENDAR_GET_IT_SOURCE(__FLAG__) (READ_BITS(AON->SLP_EVENT, (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified CALENDAR flag. + * @param __FLAG__ Specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref CALENDAR_FLAG_ALARM Alarm Interrupt event + * @arg @ref CALENDAR_FLAG_WARP Warp Interrupt event + * @retval None + */ +#define __HAL_CALENDAR_CLEAR_FLAG(__FLAG__) WRITE_REG(AON->SLP_EVENT, ~(__FLAG__)) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CALENDAR_Private_Macro CALENDAR Private Macros + * @{ + */ + +/** @brief Check if CALENDAR Alarm Type is valid. + * @param __TYPE__ CALENDAR Alarm Type. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_CALENDAR_ALARM_TYPE(__TYPE__) (((__TYPE__) == CALENDAR_ALARM_SEL_DATE) || \ + ((__TYPE__) == CALENDAR_ALARM_SEL_WEEKDAY)) + +/** @brief Check if CALENDAR Date is valid. + * @param __DATE__ CALENDAR Date. + * @retval SET (__DATE__ is valid) or RESET (__DATE__ is invalid) + */ +#define IS_CALENDAR_DATE(__DATE__) (((__DATE__) > 0) && ((__DATE__) <= 31)) + +/** @brief Check if CALENDAR Weekday is valid. + * @param __WEEKDAY__ CALENDAR Weekday. + * @retval SET (__WEEKDAY__ is valid) or RESET (__WEEKDAY__ is invalid) + */ +#define IS_CALENDAR_WEEKDAY(__WEEKDAY__) (((__WEEKDAY__) >= 0) && ((__WEEKDAY__) <= 6)) + +/** @brief Check if CALENDAR year is leap year. + * @param __YEAR__ CALENDAR Year. + * @retval SET (__YEAR__ is leap year) or RESET (__YEAR__ is nonleap year) + */ +#define IS_CALENDAR_LEAP_YEAR(__YEAR__) ((((__YEAR__) % 4) == 0 && ((__YEAR__) % 100) != 0) || \ + ((__YEAR__) % 400) == 0) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_CALENDAR_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup CALENDAR_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and start the CALENDAR according to the specified parameters + in the cslendar_init_t of associated handle. + (+) Initialize the CALENDAR MSP. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the CALENDAR according to the specified parameters in the + * calendar_init_t of associated handle. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_init(calendar_handle_t *p_calendar); + +/** + **************************************************************************************** + * @brief De-initialize the CALENDAR peripheral. + * + * @param[in] p_calendar: CALENDAR handle. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_deinit(calendar_handle_t *p_calendar); + +/** @} */ + +/** @addtogroup CALENDAR_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Init the CALENDAR time. + (+) Get the CALENDAR time. + (+) Set the CALENDAR alarm. + (+) Disable the CALENDAR alarm. + (+) Handle CALENDAR interrupt request and associated function callback. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the CALENDAR time. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * @param[in] p_time: Pointer to a CALENDAR time struction. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_init_time(calendar_handle_t *p_calendar, calendar_time_t *p_time); + +/** + **************************************************************************************** + * @brief Get current CALENDAR time. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * @param[in] p_time: Pointer to a CALENDAR time struction. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_get_time(calendar_handle_t *p_calendar, calendar_time_t *p_time); + +/** + **************************************************************************************** + * @brief Set a CALENDAR date alarm. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * @param[in] p_alarm: After seconds will generate an date alarm interrupt. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_set_alarm(calendar_handle_t *p_calendar, calendar_alarm_t *p_alarm); + +/** + **************************************************************************************** + * @brief Set a CALENDAR tick alarm. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * @param[in] interval: After milliseconds will generate an milliseconds alarm interrupt. + * The value of interval is greater than or equal to 5ms.(Max: 3600*1000 ms) + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_set_tick(calendar_handle_t *p_calendar, uint32_t interval); + +/** + **************************************************************************************** + * @brief Disable CALENDAR alarm event. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + * @param[in] disable_mode: Disable specified CALENDAR alarm mode. + * This parameter can be the following values: + * @arg @ref CALENDAR_ALARM_DISABLE_DATE + * @arg @ref CALENDAR_ALARM_DISABLE_TICK + * @arg @ref CALENDAR_ALARM_DISABLE_ALL + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_calendar_disable_event(calendar_handle_t *p_calendar, uint32_t disable_mode); + +/** @} */ + + +/** @addtogroup CALENDAR_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle CALENDAR interrupt request. + * + * @note When alarm is enabled, CALENDAR will generate an interrupt on conter match alarm value. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + **************************************************************************************** + */ +void hal_calendar_irq_handler(calendar_handle_t *p_calendar); + +/** + **************************************************************************************** + * @brief CALENDAR date count complete callback. + * + * @note This function should not be modified. when the callback is needed, + * the hal_calendar_alarm_callback can be implemented in the user file. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + **************************************************************************************** + */ +void hal_calendar_alarm_callback(calendar_handle_t *p_calendar); + +/** + **************************************************************************************** + * @brief CALENDAR milliseconds count complete callback. + * + * @note This function should not be modified. when the callback is needed, + * the hal_calendar_tick_callback can be implemented in the user file. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + **************************************************************************************** + */ +void hal_calendar_tick_callback(calendar_handle_t *p_calendar); + +/** + **************************************************************************************** + * @brief CALENDAR overflow callback. + * + * @note This function should not be modified. when the callback is needed, + * the hal_calendar_overflow_callback can be implemented in the user file. + * + * @note The overflow time is about 36 hours. + * + * @param[in] p_calendar: Pointer to a CALENDAR handle which contains the configuration + * information for the specified CALENDAR module. + **************************************************************************************** + */ +void hal_calendar_overflow_callback(calendar_handle_t *p_calendar); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_CALENDAR_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cgc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cgc.h new file mode 100644 index 0000000..9bfcbf3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cgc.h @@ -0,0 +1,362 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_cgc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of CGC HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_CGC CGC + * @brief CGC HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_CGC_H__ +#define __GR55xx_HAL_CGC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_cgc.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_CGC_ENUMERATIONS Enumerations + * @{ + */ + +/** + * @brief CGC Bit Open and Bit Close Enumerations + */ +typedef enum +{ + CGC_CLK_ON = 0U, /**< Turn on the clock.*/ + CGC_CLK_OFF = 1U, /**< Turn off the clock.*/ +} cgc_clk_state_t; + +/** @} */ + +/** @addtogroup HAL_CGC_STRUCTURES Structures + * @{ + */ + +/** + * @brief CGC init structure definition + */ +typedef struct _cgc_init +{ + uint32_t wfi_clk; /**< Specifies the blocks that automatically closes the clock. + This parameter can be a combination of group CGC_LL_EC_WFI_CLK0 */ + + uint32_t force_clk; /**< Specifies the blocks to forcibly turn off the clock. + This parameter can be a combination of group CGC_LL_EC_FRC_CLK0 */ +} cgc_init_t; + +/** @} */ + + +/** + * @defgroup HAL_CGC_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CGC_Exported_Constants CGC Exported Constants + * @{ + */ + +/** @defgroup CGC_auto_clk Automatic Turn off clocks + * @{ + */ +#define CGC_WFI_SECU_HCLK ((uint32_t)0x00000001U) /**< Hclk for all security blocks */ +#define CGC_WFI_SIM_HCLK ((uint32_t)0x00000002U) /**< Hclk for sim card interface */ +#define CGC_WFI_HTB_HCLK ((uint32_t)0x00000004U) /**< Hclk for hopping table */ +#define CGC_WFI_PWM_HCLK ((uint32_t)0x00000008U) /**< Hclk for PWM */ +#define CGC_WFI_ROM_HCLK ((uint32_t)0x00000010U) /**< Hclk for ROM */ +#define CGC_WFI_SNSADC_HCLK ((uint32_t)0x00000020U) /**< Hclk for sense ADC */ +#define CGC_WFI_GPIO_HCLK ((uint32_t)0x00000040U) /**< Hclk for GPIOs */ +#define CGC_WFI_DMA_HCLK ((uint32_t)0x00000080U) /**< Hclk for DMA engine */ +#define CGC_WFI_BLE_BRG_HCLK ((uint32_t)0x00000100U) /**< Hclk for BLE MCU bridge */ +#define CGC_WFI_APB_SUB_HCLK ((uint32_t)0x00000200U) /**< Hclk for APB subsystem */ +#define CGC_WFI_SERIAL_HCLK ((uint32_t)0x00000400U) /**< Hclk for serial blocks */ +#define CGC_WFI_I2S_S_HCLK ((uint32_t)0x00000800U) /**< Hclk for I2S slave */ +#define CGC_WFI_AON_MCUSUB_HCLK ((uint32_t)0x00001000U) /**< Hclk for Always-on register */ +#define CGC_WFI_XF_XQSPI_HCLK ((uint32_t)0x00002000U) /**< Hclk for cache top */ +#define CGC_WFI_SRAM_HCLK ((uint32_t)0x00004000U) /**< Hclk for SRAMs */ +#define CGC_WFI_SECU_DIV4_PCLK ((uint32_t)0x00008000U) /**< Div4 clk for security blocks */ +#define CGC_WFI_XQSPI_DIV4_PCLK ((uint32_t)0x00020000U) /**< Div4 clk for xf qspi */ + +#define CGC_WFI_ALL_CLK ((uint32_t)0x0002FFFFU) /**< All clocks */ +/** @} */ + +/** @defgroup CGC_force_clk Force cloks off + * @{ + */ +#define CGC_FRC_SECU_HCLK ((uint32_t)0x00000001U) /**< Hclk for all security blocks */ +#define CGC_FRC_SIM_HCLK ((uint32_t)0x00000002U) /**< Hclk for sim card interface */ +#define CGC_FRC_HTB_HCLK ((uint32_t)0x00000004U) /**< Hclk for hopping table */ +#define CGC_FRC_PWM_HCLK ((uint32_t)0x00000008U) /**< Hclk for PWM */ +#define CGC_FRC_ROM_HCLK ((uint32_t)0x00000010U) /**< Hclk for ROM */ +#define CGC_FRC_SNSADC_HCLK ((uint32_t)0x00000020U) /**< Hclk for sense ADC */ +#define CGC_FRC_GPIO_HCLK ((uint32_t)0x00000040U) /**< Hclk for GPIOs */ +#define CGC_FRC_DMA_HCLK ((uint32_t)0x00000080U) /**< Hclk for DMA engine */ +#define CGC_FRC_BLE_BRG_HCLK ((uint32_t)0x00000100U) /**< Hclk for BLE MCU bridge */ +#define CGC_FRC_APB_SUB_HCLK ((uint32_t)0x00000200U) /**< Hclk for APB subsystem */ +#define CGC_FRC_SERIAL_HCLK ((uint32_t)0x00000400U) /**< Hclk for serial blocks */ +#define CGC_FRC_I2S_S_HCLK ((uint32_t)0x00000800U) /**< Hclk for I2S slave */ +#define CGC_FRC_AON_MCUSUB_HCLK ((uint32_t)0x00001000U) /**< Hclk for Always-on register */ +#define CGC_FRC_XF_XQSPI_HCLK ((uint32_t)0x00002000U) /**< Hclk for cache top */ +#define CGC_FRC_SRAM_HCLK ((uint32_t)0x00004000U) /**< Hclk for SRAMs */ +#define CGC_FRC_UART0_HCLK ((uint32_t)0x00008000U) /**< Hclk for uart0 */ +#define CGC_FRC_UART1_HCLK ((uint32_t)0x00010000U) /**< Hclk for uart1 */ +#define CGC_FRC_I2C0_HCLK ((uint32_t)0x00020000U) /**< Hclk for i2c0 */ +#define CGC_FRC_I2C1_HCLK ((uint32_t)0x00040000U) /**< Hclk for i2c1 */ +#define CGC_FRC_SPIM_HCLK ((uint32_t)0x00080000U) /**< Hclk for spim */ +#define CGC_FRC_SPIS_HCLK ((uint32_t)0x00100000U) /**< Hclk for spis */ +#define CGC_FRC_QSPI0_HCLK ((uint32_t)0x00200000U) /**< Hclk for qspi0 */ +#define CGC_FRC_QSPI1_HCLK ((uint32_t)0x00400000U) /**< Hclk for qspi1 */ +#define CGC_FRC_I2S_HCLK ((uint32_t)0x00800000U) /**< Hclk for i2s */ +#define CGC_FRC_SECU_DIV4_PCLK ((uint32_t)0x01000000U) /**< Div4 clk for security blocks */ +#define CGC_FRC_XQSPI_DIV4_PCLK ((uint32_t)0x04000000U) /**< Div4 clk for xf qspi */ + +#define CGC_FRC_ALL_CLK ((uint32_t)0x05FFFFFFU) /**< All clocks */ +/** @} */ + + + +/** + * @brief CGC_default_config init Struct default configuartion + */ +#define CGC_DEFAULT_CONFIG \ +{ \ + .wfi_clk = ~CGC_WFI_ALL_CLK, \ + .force_clk = ~CGC_FRC_ALL_CLK, \ +} +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_CGC_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup CGC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the CGC registers according to the specified parameters in the @ref cgc_init_t. + * @param[in] p_cgc_init: Pointer to a @ref cgc_init_t structure that contains + * the configuration information for the specified CGC registers. + **************************************************************************************** + */ +void hal_cgc_init(cgc_init_t *p_cgc_init); + +/** + **************************************************************************************** + * @brief De-initialize the CGC registers to their default reset values. + **************************************************************************************** + */ +void hal_cgc_deinit(void); + +/** @} */ + +/** @addtogroup CGC_Exported_Functions_Group2 Peripheral Control functions. + * @brief Clock Gate Open and Closemanagement functions. + * @{ + */ + +/** + **************************************************************************************** + * @brief Configure the clock state for a specified block during WFI. + * @param[in] blocks: Specifies the peripheral blocks. + * This parameter can be a combiantion of the following values: + * @arg @ref CGC_WFI_SECU_HCLK + * @arg @ref CGC_WFI_SIM_HCLK + * @arg @ref CGC_WFI_HTB_HCLK + * @arg @ref CGC_WFI_PWM_HCLK + * @arg @ref CGC_WFI_ROM_HCLK + * @arg @ref CGC_WFI_SNSADC_HCLK + * @arg @ref CGC_WFI_GPIO_HCLK + * @arg @ref CGC_WFI_DMA_HCLK + * @arg @ref CGC_WFI_BLE_BRG_HCLK + * @arg @ref CGC_WFI_APB_SUB_HCLK + * @arg @ref CGC_WFI_SERIAL_HCLK + * @arg @ref CGC_WFI_I2S_S_HCLK + * @arg @ref CGC_WFI_AON_MCUSUB_HCLK + * @arg @ref CGC_WFI_XF_XQSPI_HCLK + * @arg @ref CGC_WFI_SRAM_HCLK + * @arg @ref CGC_WFI_SECU_DIV4_PCLK + * @arg @ref CGC_WFI_XQSPI_DIV4_PCLK + * @param[in] clk_state: Specifies the clock state during WFI. + * This parameter can be one of the following values: + * @arg @ref CGC_CLK_ON + * @arg @ref CGC_CLK_OFF + **************************************************************************************** + */ +void hal_cgc_config_wfi_clk(uint32_t blocks, cgc_clk_state_t clk_state); + +/** + **************************************************************************************** + * @brief Get the clock state for a specified block during WFI. + * @param[in] block: Specifies the peripheral blocks. + * This parameter can be one of the following values: + * @arg @ref CGC_WFI_SECU_HCLK + * @arg @ref CGC_WFI_SIM_HCLK + * @arg @ref CGC_WFI_HTB_HCLK + * @arg @ref CGC_WFI_PWM_HCLK + * @arg @ref CGC_WFI_ROM_HCLK + * @arg @ref CGC_WFI_SNSADC_HCLK + * @arg @ref CGC_WFI_GPIO_HCLK + * @arg @ref CGC_WFI_DMA_HCLK + * @arg @ref CGC_WFI_BLE_BRG_HCLK + * @arg @ref CGC_WFI_APB_SUB_HCLK + * @arg @ref CGC_WFI_SERIAL_HCLK + * @arg @ref CGC_WFI_I2S_S_HCLK + * @arg @ref CGC_WFI_AON_MCUSUB_HCLK + * @arg @ref CGC_WFI_XF_XQSPI_HCLK + * @arg @ref CGC_WFI_SRAM_HCLK + * @arg @ref CGC_WFI_SECU_DIV4_PCLK + * @arg @ref CGC_WFI_XQSPI_DIV4_PCLK + * @retval ::CGC_CLK_ON: Clock On. + * @retval ::CGC_CLK_OFF: Clock Off. + **************************************************************************************** + */ +cgc_clk_state_t hal_cgc_get_wfi_clk(uint32_t block); + +/** + **************************************************************************************** + * @brief Forced to Configure the clock state for a specified block. + * @param[in] blocks: Specifies the peripheral blocks. + * This parameter can be a combiantion of the following values: + * @arg @ref CGC_FRC_SECU_HCLK + * @arg @ref CGC_FRC_SIM_HCLK + * @arg @ref CGC_FRC_HTB_HCLK + * @arg @ref CGC_FRC_PWM_HCLK + * @arg @ref CGC_FRC_ROM_HCLK + * @arg @ref CGC_FRC_SNSADC_HCLK + * @arg @ref CGC_FRC_GPIO_HCLK + * @arg @ref CGC_FRC_DMA_HCLK + * @arg @ref CGC_FRC_BLE_BRG_HCLK + * @arg @ref CGC_FRC_APB_SUB_HCLK + * @arg @ref CGC_FRC_SERIAL_HCLK + * @arg @ref CGC_FRC_I2S_S_HCLK + * @arg @ref CGC_FRC_AON_MCUSUB_HCLK + * @arg @ref CGC_FRC_XF_XQSPI_HCLK + * @arg @ref CGC_FRC_SRAM_HCLK + * @arg @ref CGC_FRC_UART0_HCLK + * @arg @ref CGC_FRC_UART1_HCLK + * @arg @ref CGC_FRC_I2C0_HCLK + * @arg @ref CGC_FRC_I2C1_HCLK + * @arg @ref CGC_FRC_SPIM_HCLK + * @arg @ref CGC_FRC_SPIS_HCLK + * @arg @ref CGC_FRC_QSPI0_HCLK + * @arg @ref CGC_FRC_QSPI1_HCLK + * @arg @ref CGC_FRC_I2S_HCLK + * @arg @ref CGC_FRC_SECU_DIV4_PCLK + * @arg @ref CGC_FRC_XQSPI_DIV4_PCLK + * @param[in] clk_state: Specifies the clock state. + * This parameter can be one of the following values: + * @arg @ref CGC_CLK_ON + * @arg @ref CGC_CLK_OFF + **************************************************************************************** + */ +void hal_cgc_config_force_clk(uint32_t blocks, cgc_clk_state_t clk_state); + +/** + **************************************************************************************** + * @brief Get the clock status of the currently specified block. + * @param[in] block: Specifies the peripheral blocks. + * This parameter can be one of the following values: + * @arg @ref CGC_FRC_SECU_HCLK + * @arg @ref CGC_FRC_SIM_HCLK + * @arg @ref CGC_FRC_HTB_HCLK + * @arg @ref CGC_FRC_PWM_HCLK + * @arg @ref CGC_FRC_ROM_HCLK + * @arg @ref CGC_FRC_SNSADC_HCLK + * @arg @ref CGC_FRC_GPIO_HCLK + * @arg @ref CGC_FRC_DMA_HCLK + * @arg @ref CGC_FRC_BLE_BRG_HCLK + * @arg @ref CGC_FRC_APB_SUB_HCLK + * @arg @ref CGC_FRC_SERIAL_HCLK + * @arg @ref CGC_FRC_I2S_S_HCLK + * @arg @ref CGC_FRC_AON_MCUSUB_HCLK + * @arg @ref CGC_FRC_XF_XQSPI_HCLK + * @arg @ref CGC_FRC_SRAM_HCLK + * @arg @ref CGC_FRC_UART0_HCLK + * @arg @ref CGC_FRC_UART1_HCLK + * @arg @ref CGC_FRC_I2C0_HCLK + * @arg @ref CGC_FRC_I2C1_HCLK + * @arg @ref CGC_FRC_SPIM_HCLK + * @arg @ref CGC_FRC_SPIS_HCLK + * @arg @ref CGC_FRC_QSPI0_HCLK + * @arg @ref CGC_FRC_QSPI1_HCLK + * @arg @ref CGC_FRC_I2S_HCLK + * @arg @ref CGC_FRC_SECU_DIV4_PCLK + * @arg @ref CGC_FRC_XQSPI_DIV4_PCLK + * @retval ::CGC_CLK_ON: Clock On. + * @retval ::CGC_CLK_OFF: Clock Off. + **************************************************************************************** + */ +cgc_clk_state_t hal_cgc_get_force_clk(uint32_t block); + + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_CGC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_comp.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_comp.h new file mode 100644 index 0000000..1c69696 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_comp.h @@ -0,0 +1,448 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_comp.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of COMP HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_COMP COMP + * @brief COMP HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_COMP_H__ +#define __GR55xx_HAL_COMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_comp.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_COMP_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_COMP_state HAL COMP state + * @{ + */ + +/** + * @brief HAL COMP State Enumerations definition + */ +typedef enum +{ + HAL_COMP_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_COMP_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_COMP_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_COMP_STATE_ERROR = 0x04 /**< Peripheral in error */ +} hal_comp_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_COMP_STRUCTURES Structures + * @{ + */ + +/** @defgroup COMP_Configuration COMP Configuration + * @{ + */ + +/** + * @brief COMP init structure definition + */ +typedef ll_comp_init_t comp_init_t; +/** @} */ + +/** @defgroup COMP_handle COMP handle + * @{ + */ + +/** + * @brief COMP handle Structure definition + */ +typedef struct _comp_handle +{ + comp_init_t init; /**< COMP configuration parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_comp_state_t state; /**< COMP communication state */ + + __IO uint32_t error_code; /**< COMP error code */ + + uint32_t retention[1]; /**< COMP important register information. */ + +} comp_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_COMP_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup COMP_Callback COMP Callback + * @{ + */ + +/** + * @brief HAL COMP Callback function definition + */ +typedef struct _comp_callback +{ + void (*comp_msp_init)(comp_handle_t *p_comp); /**< COMP init MSP callback */ + void (*comp_msp_deinit)(comp_handle_t *p_comp); /**< COMP de-init MSP callback */ + void (*comp_trigger_callback)(comp_handle_t *p_comp); /**< COMP comparator callback */ +} comp_callback_t; + +/** @} */ + +/** @} */ + + +/** + * @defgroup HAL_COMP_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup COMP_Exported_Constants COMP Exported Constants + * @{ + */ + +/** @defgroup COMP_Error_Code COMP Error Code + * @{ + */ +#define HAL_COMP_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_COMP_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_COMP_ERROR_INVALID_PARAM ((uint32_t)0x00000002) /**< Invalid parameters error */ +/** @} */ + + +/** @defgroup COMP_INPUT_SOURCE COMP Input Channel Select + * @{ + */ +#define COMP_INPUT_SRC_IO0 LL_COMP_INPUT_SRC_IO0 /**< Set MSIO_0 as inputs for the comparator */ +#define COMP_INPUT_SRC_IO1 LL_COMP_INPUT_SRC_IO1 /**< Set MSIO_1 as inputs for the comparator */ +#define COMP_INPUT_SRC_IO2 LL_COMP_INPUT_SRC_IO2 /**< Set MSIO_2 as inputs for the comparator */ +#define COMP_INPUT_SRC_IO3 LL_COMP_INPUT_SRC_IO3 /**< Set MSIO_3 as inputs for the comparator */ +#define COMP_INPUT_SRC_IO4 LL_COMP_INPUT_SRC_IO4 /**< Set MSIO_4 as inputs for the comparator */ +/** @} */ + +/** @defgroup COMP_REFERENCE_SOURCE COMP Reference Source Select + * @{ + */ +#define COMP_REF_SRC_IO0 LL_COMP_REF_SRC_IO0 /**< Set MSIO_0 as references for the comparator */ +#define COMP_REF_SRC_IO1 LL_COMP_REF_SRC_IO1 /**< Set MSIO_1 as references for the comparator */ +#define COMP_REF_SRC_IO2 LL_COMP_REF_SRC_IO2 /**< Set MSIO_2 as references for the comparator */ +#define COMP_REF_SRC_IO3 LL_COMP_REF_SRC_IO3 /**< Set MSIO_3 as references for the comparator */ +#define COMP_REF_SRC_IO4 LL_COMP_REF_SRC_IO4 /**< Set MSIO_4 as references for the comparator */ +#define COMP_REF_SRC_VBAT LL_COMP_REF_SRC_VBAT /**< Set VBATT as references for the comparator */ +#define COMP_REF_SRC_VREF LL_COMP_REF_SRC_VREF /**< Set VREF as references for the comparator */ +/** @} */ + +/** + * @brief Default configuartion for initializing structure + */ +#define COMP_DEFAULT_CONFIG LL_COMP_DEFAULT_CONFIG +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup COMP_Private_Macros COMP Private Macros + * @{ + */ + +/** + * @brief Check if COMP input source is valid. + * @param __INPUT__ COMP input source. + * @retval SET (__INPUT__ is valid) or RESET (__INPUT__ is invalid) + */ +#define IS_COMP_INPUT(__INPUT__) (((__INPUT__) == COMP_INPUT_SRC_IO0) || \ + ((__INPUT__) == COMP_INPUT_SRC_IO1) || \ + ((__INPUT__) == COMP_INPUT_SRC_IO2) || \ + ((__INPUT__) == COMP_INPUT_SRC_IO3) || \ + ((__INPUT__) == COMP_INPUT_SRC_IO4)) + +/** + * @brief Check if COMP reference source is valid. + * @param __INPUT__ COMP reference source. + * @retval SET (__INPUT__ is valid) or RESET (__INPUT__ is invalid) + */ +#define IS_COMP_REF(__INPUT__) (((__INPUT__) == COMP_REF_SRC_IO0) || \ + ((__INPUT__) == COMP_REF_SRC_IO1) || \ + ((__INPUT__) == COMP_REF_SRC_IO2) || \ + ((__INPUT__) == COMP_REF_SRC_IO3) || \ + ((__INPUT__) == COMP_REF_SRC_IO4) || \ + ((__INPUT__) == COMP_REF_SRC_VBAT) || \ + ((__INPUT__) == COMP_REF_SRC_VREF)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_COMP_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup COMP_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the COMP according to the specified parameters + * in the comp_init_t and initialize the associated handle. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_init(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief De-initialize the COMP peripheral. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_deinit(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief Initialize the COMP MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_comp_msp_deinit can be implemented in the user file. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + **************************************************************************************** + */ +void hal_comp_msp_init(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief De-initialize the COMP MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_comp_msp_deinit can be implemented in the user file. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + **************************************************************************************** + */ +void hal_comp_msp_deinit(comp_handle_t *p_comp); + +/** @} */ + +/** @addtogroup COMP_Exported_Functions_Group2 IO operation functions + * @brief COMP polling and DMA conversion management functions. + * @{ + */ + + /** + **************************************************************************************** + * @brief Start the comparator. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_start(comp_handle_t *p_comp); + + /** + **************************************************************************************** + * @brief Stop the comparator. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_stop(comp_handle_t *p_comp); + +/** @} */ + +/** @addtogroup COMP_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle COMP interrupt request. + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information + * for the specified COMP module. + **************************************************************************************** + */ +void hal_comp_irq_handler(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief comparator callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_comp_trigger_callback can be implemented in the user file. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + **************************************************************************************** + */ +void hal_comp_trigger_callback(comp_handle_t *p_comp); + +/** @} */ + +/** @defgroup COMP_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief COMP control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the COMP. + (+) hal_comp_get_state() API can be helpful to check in run-time the state of the COMP peripheral. + (+) hal_comp_get_error() check in run-time Errors occurring during communication. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the COMP handle state. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @retval ::HAL_COMP_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_COMP_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_COMP_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_COMP_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_comp_state_t hal_comp_get_state(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief Return the COMP error code. + * + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration information for + * the specified COMP module. + * + * @return COMP error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_comp_get_error(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief Suspend some registers related to COMP configuration before sleep. + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration + * information for the specified COMP module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_suspend_reg(comp_handle_t *p_comp); + +/** + **************************************************************************************** + * @brief Restore some registers related to COMP configuration after sleep. + * This function must be used in conjunction with the hal_comp_suspend_reg(). + * @param[in] p_comp: Pointer to a COMP handle which contains the configuration + * information for the specified COMP module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_comp_resume_reg(comp_handle_t *p_comp); + +/** @} */ + +/** @} */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_COMP_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_conf.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_conf.h new file mode 100644 index 0000000..2f98e0f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_conf.h @@ -0,0 +1,254 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_conf.h + * @author BLE Driver Team + * @brief HAL configuration file. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_CONF_H__ +#define __GR55xx_HAL_CONF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED /**< Enable HAL module driver */ +#define HAL_ADC_MODULE_ENABLED /**< Enable ADC HAL module driver */ +#define HAL_AON_GPIO_MODULE_ENABLED /**< Enable AON GPIO HAL module driver */ +#define HAL_CORTEX_MODULE_ENABLED /**< Enable CORTEX HAL module driver */ +#define HAL_DMA_MODULE_ENABLED /**< Enable DMA HAL module driver */ +#define HAL_DUAL_TIMER_MODULE_ENABLED /**< Enable DUAL TIM module driver */ +#define HAL_EXFLASH_MODULE_ENABLED /**< Enable EXFLASH module driver */ +#define HAL_GPIO_MODULE_ENABLED /**< Enable GPIO module driver */ +#define HAL_I2C_MODULE_ENABLED /**< Enable I2C module driver */ +#define HAL_MSIO_MODULE_ENABLED /**< Enable MSIO module driver */ +#define HAL_PKC_MODULE_ENABLED /**< Enable PKC module driver */ +#define HAL_PWM_MODULE_ENABLED /**< Enable PWM module driver */ +#define HAL_PWR_MODULE_ENABLED /**< Enable PWR module driver */ +#define HAL_QSPI_MODULE_ENABLED /**< Enable QSPI module driver */ +#define HAL_SPI_MODULE_ENABLED /**< Enable SPI module driver */ +//#define HAL_SPI_V2_MODULE_ENABLED /**< Enable SPI.v2 module driver */ +#define HAL_TIMER_MODULE_ENABLED /**< Enable TIM module driver */ +#define HAL_UART_MODULE_ENABLED /**< Enable UART module driver */ +#define HAL_WDT_MODULE_ENABLED /**< Enable WDT module driver */ +#define HAL_XQSPI_MODULE_ENABLED /**< Enable XQSPI module driver */ +#define HAL_AON_WDT_MODULE_ENABLED /**< Enable AON WDT module driver */ +#define HAL_CALENDAR_MODULE_ENABLED /**< Enable CALENDAR module driver */ +#define HAL_HMAC_MODULE_ENABLED /**< Enable HMAC module driver */ +#define HAL_I2S_MODULE_ENABLED /**< Enable I2S module driver */ +#define HAL_AES_MODULE_ENABLED /**< Enable AES module driver */ +#define HAL_EFUSE_MODULE_ENABLED /**< Enable EFUSE module driver */ +#define HAL_ISO7816_MODULE_ENABLED /**< Enable ISO7816 module driver */ +#define HAL_CGC_MODULE_ENABLED /**< Enable CGC module driver */ +#define HAL_RNG_MODULE_ENABLED /**< Enable RNG module driver */ +#define HAL_COMP_MODULE_ENABLED /**< Enable COMP module driver */ +#define HAL_SLEEP_TIMER_MODULE_ENABLED /**< Enable SLEPP TIMER module driver */ +#define HAL_BOD_MODULE_ENABLED /**< Enable BOD module driver */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define TICK_INT_PRIORITY ((uint32_t)(1U<<(__NVIC_PRIO_BITS - 4)) - 1U) /*!< tick interrupt priority (lowest by default) by group priority 4. */ +#define USE_RTOS 0U /*!< use rtos */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "gr_assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" +/** + * @brief Include module's header file + */ +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "gr55xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "gr55xx_hal_adc.h" +#include "gr55xx_hal_adc_voltage_api.h" +#include "gr55xx_hal_adc_temp_api.h" +#include "gr55xx_hal_adc_vbat_api.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_AES_MODULE_ENABLED +#include "gr55xx_hal_aes.h" +#endif /* HAL_AES_MODULE_ENABLED */ + +#ifdef HAL_AON_GPIO_MODULE_ENABLED +#include "gr55xx_hal_aon_gpio.h" +#endif /* HAL_AON_GPIO_MODULE_ENABLED */ + +#ifdef HAL_AON_WDT_MODULE_ENABLED +#include "gr55xx_hal_aon_wdt.h" +#endif /* HAL_AON_WDT_MODULE_ENABLED */ + +#ifdef HAL_CALENDAR_MODULE_ENABLED +#include "gr55xx_hal_calendar.h" +#endif /* HAL_CALENDAR_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "gr55xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DUAL_TIMER_MODULE_ENABLED +#include "gr55xx_hal_dual_tim.h" +#endif /* HAL_DUAL_TIMER_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "gr55xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_HMAC_MODULE_ENABLED +#include "gr55xx_hal_hmac.h" +#endif /* HAL_HMAC_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "gr55xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "gr55xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_MSIO_MODULE_ENABLED +#include "gr55xx_hal_msio.h" +#endif /* HAL_MSIO_MODULE_ENABLED */ + +#ifdef HAL_PKC_MODULE_ENABLED +#include "gr55xx_hal_pkc.h" +#endif /* HAL_PKC_MODULE_ENABLED */ + +#ifdef HAL_PWM_MODULE_ENABLED +#include "gr55xx_hal_pwm.h" +#endif /* HAL_PWM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "gr55xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "gr55xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "gr55xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SPI_V2_MODULE_ENABLED +#include "gr55xx_hal_spi_v2.h" +#endif /* HAL_SPI_V2_MODULE_ENABLED */ + +#ifdef HAL_TIMER_MODULE_ENABLED +#include "gr55xx_hal_tim.h" +#endif /* HAL_TIMER_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "gr55xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_WDT_MODULE_ENABLED +#include "gr55xx_hal_wdt.h" +#endif /* HAL_WDT_MODULE_ENABLED */ + +#ifdef HAL_XQSPI_MODULE_ENABLED +#include "gr55xx_hal_xqspi.h" +#endif /* HAL_XQSPI_MODULE_ENABLED */ + +#ifdef HAL_EXFLASH_MODULE_ENABLED +#include "gr55xx_hal_exflash.h" +#endif /* HAL_EXFLASH_MODULE_ENABLED */ + +#ifdef HAL_EFUSE_MODULE_ENABLED +#include "gr55xx_hal_efuse.h" +#endif /* HAL_EFUSE_MODULE_ENABLED */ + +#ifdef HAL_CGC_MODULE_ENABLED +#include "gr55xx_hal_cgc.h" +#endif /* HAL_CGC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "gr55xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "gr55xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_ISO7816_MODULE_ENABLED +#include "gr55xx_hal_iso7816.h" +#endif /* HAL_ISO7816_MODULE_ENABLED */ + +#ifdef HAL_SLEEP_TIMER_MODULE_ENABLED +#include "gr55xx_hal_sleep_timer.h" +#endif /* HAL_SLEEP_TIMER_MODULE_ENABLED */ + +#ifdef HAL_BOD_MODULE_ENABLED +#include "gr55xx_hal_bod.h" +#endif /* HAL_BOD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The gr_assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define gr_assert_param(expr) ((expr) ? (void)0U : assert_failed((char *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(char *file, uint32_t line); +#else +#define gr_assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_CONF_H__ */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cortex.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cortex.h new file mode 100644 index 0000000..1482e82 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_cortex.h @@ -0,0 +1,770 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_cortex.h + * @author BLE Driver Team + * @brief Header file of CORTEX HAL module. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_CORTEX CORTEX + * @brief CORTEX HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_CORTEX_H__ +#define __GR55xx_HAL_CORTEX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ + +/** @addtogroup HAL_CORTEX_STRUCTURES Structures + * @{ + */ + +#if (__MPU_PRESENT == 1U) + +/** @defgroup CORTEX_MPU_Region_Configuration MPU Region Configuration + * @{ + */ + +/** + * @brief MPU Region initialization structure + */ +typedef struct _mpu_region_init_t +{ + uint8_t enable; /**< Specifies the status of the region. + This parameter can be a value of @ref CORTEX_MPU_Region_Enable */ + + uint8_t number; /**< Specifies the number of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Number */ + + uint32_t base_address; /**< Specifies the base address of the region to protect. */ + + uint8_t size; /**< Specifies the size of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Size */ + + uint8_t subregion_disable; /**< Specifies the number of the subregion protection to disable. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + + uint8_t type_tex_field; /**< Specifies the TEX field level. + This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */ + + uint8_t access_permission; /**< Specifies the region access permission type. + This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */ + + uint8_t disable_exec; /**< Specifies the instruction access status. + This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */ + + uint8_t is_shareable; /**< Specifies the shareability status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */ + + uint8_t is_cacheable; /**< Specifies the cacheable status of the region protected. + This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */ + + uint8_t is_bufferable; /**< Specifies the bufferable status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */ + +} mpu_region_init_t; + +/** @} */ + +#endif /* __MPU_PRESENT */ + +/** @} */ + + +/** + * @defgroup HAL_CORTEX_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group + * @{ + */ +#define NVIC_PRIORITYGROUP_0 (0x00000007U) /**< 0 bit for pre-emption priority, + 8 bits for subpriority */ +#define NVIC_PRIORITYGROUP_1 (0x00000006U) /**< 1 bit for pre-emption priority, + 7 bits for subpriority */ +#define NVIC_PRIORITYGROUP_2 (0x00000005U) /**< 2 bits for pre-emption priority, + 6 bits for subpriority */ +#define NVIC_PRIORITYGROUP_3 (0x00000004U) /**< 3 bits for pre-emption priority, + 5 bits for subpriority */ +#define NVIC_PRIORITYGROUP_4 (0x00000003U) /**< 4 bits for pre-emption priority, + 4 bits for subpriority */ +#define NVIC_PRIORITYGROUP_5 (0x00000002U) /**< 5 bits for pre-emption priority, + 3 bits for subpriority */ +#define NVIC_PRIORITYGROUP_6 (0x00000001U) /**< 6 bits for pre-emption priority, + 2 bits for subpriority */ +#define NVIC_PRIORITYGROUP_7 (0x00000000U) /**< 7 bits for pre-emption priority, + 1 bit for subpriority */ +/** @} */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_REFCLK (0x00000000U) /**< SYSTICK clock source External Reference Clock */ +#define SYSTICK_CLKSOURCE_HCLK (0x00000004U) /**< SYSTICK clock source HCLK */ +/** @} */ + +#if (__MPU_PRESENT == 1U) +/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define MPU_HFNMI_PRIVDEF_NONE (0x00000000U) /**< HFNMIENA disable, PRIVDEFENA disable */ +#define MPU_HARDFAULT_NMI (0x00000002U) /**< HFNMIENA enable, PRIVDEFENA disable */ +#define MPU_PRIVILEGED_DEFAULT (0x00000004U) /**< HFNMIENA disable, PRIVDEFENA enable */ +#define MPU_HFNMI_PRIVDEF (0x00000006U) /**< HFNMIENA enable, PRIVDEFENA enable */ +/** @} */ + +/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable + * @{ + */ +#define MPU_REGION_ENABLE ((uint8_t)0x01U) /**< MPU Region Enable */ +#define MPU_REGION_DISABLE ((uint8_t)0x00U) /**< MPU Region Disable */ +/** @} */ + +/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access + * @{ + */ +#define MPU_INSTRUCTION_ACCESS_ENABLE ((uint8_t)0x00U) /**< MPU Instruction Access Enable */ +#define MPU_INSTRUCTION_ACCESS_DISABLE ((uint8_t)0x01U) /**< MPU Instruction Access Disable */ +/** @} */ + +/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable + * @{ + */ +#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01U) /**< MPU Instruction Access Shareable */ +#define MPU_ACCESS_NOT_SHAREABLE ((uint8_t)0x00U) /**< MPU Instruction Access Not Shareable */ +/** @} */ + +/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable + * @{ + */ +#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01U) /**< MPU Instruction Access Cacheable */ +#define MPU_ACCESS_NOT_CACHEABLE ((uint8_t)0x00U) /**< MPU Instruction Access Not Cacheable */ +/** @} */ + +/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable + * @{ + */ +#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01U) /**< MPU Instruction Access Bufferable */ +#define MPU_ACCESS_NOT_BUFFERABLE ((uint8_t)0x00U) /**< MPU Instruction Access Not Bufferable */ +/** @} */ + +/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels + * @{ + */ +#define MPU_TEX_LEVEL0 ((uint8_t)0x00U) /**< MPU TEX Level 0 */ +#define MPU_TEX_LEVEL1 ((uint8_t)0x01U) /**< MPU TEX Level 1 */ +#define MPU_TEX_LEVEL2 ((uint8_t)0x02U) /**< MPU TEX Level 2 */ +/** @} */ + +/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size + * @{ + */ +#define MPU_REGION_SIZE_32B ((uint8_t)0x04U) /**< MPU Region Size 32B */ +#define MPU_REGION_SIZE_64B ((uint8_t)0x05U) /**< MPU Region Size 64B */ +#define MPU_REGION_SIZE_128B ((uint8_t)0x06U) /**< MPU Region Size 128B */ +#define MPU_REGION_SIZE_256B ((uint8_t)0x07U) /**< MPU Region Size 256B */ +#define MPU_REGION_SIZE_512B ((uint8_t)0x08U) /**< MPU Region Size 512B */ +#define MPU_REGION_SIZE_1KB ((uint8_t)0x09U) /**< MPU Region Size 1KB */ +#define MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) /**< MPU Region Size 2KB */ +#define MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) /**< MPU Region Size 4KB */ +#define MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) /**< MPU Region Size 8KB */ +#define MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) /**< MPU Region Size 16KB */ +#define MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) /**< MPU Region Size 32KB */ +#define MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) /**< MPU Region Size 64KB */ +#define MPU_REGION_SIZE_128KB ((uint8_t)0x10U) /**< MPU Region Size 128KB */ +#define MPU_REGION_SIZE_256KB ((uint8_t)0x11U) /**< MPU Region Size 256KB */ +#define MPU_REGION_SIZE_512KB ((uint8_t)0x12U) /**< MPU Region Size 512KB */ +#define MPU_REGION_SIZE_1MB ((uint8_t)0x13U) /**< MPU Region Size 1MB */ +#define MPU_REGION_SIZE_2MB ((uint8_t)0x14U) /**< MPU Region Size 2MB */ +#define MPU_REGION_SIZE_4MB ((uint8_t)0x15U) /**< MPU Region Size 4MB */ +#define MPU_REGION_SIZE_8MB ((uint8_t)0x16U) /**< MPU Region Size 8MB */ +#define MPU_REGION_SIZE_16MB ((uint8_t)0x17U) /**< MPU Region Size 16MB */ +#define MPU_REGION_SIZE_32MB ((uint8_t)0x18U) /**< MPU Region Size 32MB */ +#define MPU_REGION_SIZE_64MB ((uint8_t)0x19U) /**< MPU Region Size 64MB */ +#define MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) /**< MPU Region Size 128MB */ +#define MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) /**< MPU Region Size 256MB */ +#define MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) /**< MPU Region Size 512MB */ +#define MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) /**< MPU Region Size 1GB */ +#define MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) /**< MPU Region Size 2GB */ +#define MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) /**< MPU Region Size 4GB */ +/** @} */ + +/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes + * @{ + */ +#define MPU_REGION_NO_ACCESS ((uint8_t)0x00U) /**< All accesses generate a permission fault */ +#define MPU_REGION_PRIV_RW ((uint8_t)0x01U) /**< Access from privileged software only */ +#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02U) /**< Writes by unprivileged software generate a permission fault */ +#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03U) /**< Full access */ +#define MPU_REGION_PRIV_RO ((uint8_t)0x05U) /**< Reads by privileged software only */ +#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06U) /**< Read only, by privileged or unprivileged software */ +/** @} */ + +/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number + * @{ + */ +#define MPU_REGION_NUMBER0 ((uint8_t)0x00U) /**< MPU Region Number 0 */ +#define MPU_REGION_NUMBER1 ((uint8_t)0x01U) /**< MPU Region Number 1 */ +#define MPU_REGION_NUMBER2 ((uint8_t)0x02U) /**< MPU Region Number 2 */ +#define MPU_REGION_NUMBER3 ((uint8_t)0x03U) /**< MPU Region Number 3 */ +#define MPU_REGION_NUMBER4 ((uint8_t)0x04U) /**< MPU Region Number 4 */ +#define MPU_REGION_NUMBER5 ((uint8_t)0x05U) /**< MPU Region Number 5 */ +#define MPU_REGION_NUMBER6 ((uint8_t)0x06U) /**< MPU Region Number 6 */ +#define MPU_REGION_NUMBER7 ((uint8_t)0x07U) /**< MPU Region Number 7 */ +/** @} */ +#endif /* __MPU_PRESENT */ + +/** @} */ + +/* Exported Macros -----------------------------------------------------------*/ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ + +/** + * @brief Check if NVIC priority group is valid. + * @param __GROUP__ NVIC priority group. + * @retval SET (__GROUP__ is valid) or RESET (__GROUP__ is invalid) + */ +#define IS_NVIC_PRIORITY_GROUP(__GROUP__) (((__GROUP__) == NVIC_PRIORITYGROUP_0) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_1) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_2) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_3) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_4) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_5) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_6) || \ + ((__GROUP__) == NVIC_PRIORITYGROUP_7)) + +/** + * @brief Check if NVIC priority group is valid. + * @param __PRIORITY__ NVIC priority group. + * @retval SET (__PRIORITY__ is valid) or RESET (__PRIORITY__ is invalid) + */ +#define IS_NVIC_PREEMPTION_PRIORITY(__PRIORITY__) ((__PRIORITY__) < 0x80U) + +/** + * @brief Check if NVIC sub priority is valid. + * @param __PRIORITY__ NVIC sub priority. + * @retval SET (__PRIORITY__ is valid) or RESET (__PRIORITY__ is invalid) + */ +#define IS_NVIC_SUB_PRIORITY(__PRIORITY__) ((__PRIORITY__) <= 0xFFU) + +/** + * @brief Check if NVIC deivce IRQ is valid. + * @param __IRQ__ NVIC device IRQ. + * @retval SET (__IRQ__ is valid) or RESET (__IRQ__ is invalid) + */ +#define IS_NVIC_DEVICE_IRQ(__IRQ__) ((__IRQ__) >= 0x00) + +/** + * @brief Check if SYSTICK clock source is valid. + * @param __SOURCE__ SYSTICK clock source. + * @retval SET (__SOURCE__ is valid) or RESET (__SOURCE__ is invalid) + */ +#define IS_SYSTICK_CLK_SOURCE(__SOURCE__) (((__SOURCE__) == SYSTICK_CLKSOURCE_HCLK) || \ + ((__SOURCE__) == SYSTICK_CLKSOURCE_REFCLK)) + +#if (__MPU_PRESENT == 1U) + +/** + * @brief Check if MPU enable state is valid. + * @param __STATE__ Enable state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is not invalid) + */ +#define IS_MPU_REGION_ENABLE(__STATE__) (((__STATE__) == MPU_REGION_ENABLE) || \ + ((__STATE__) == MPU_REGION_DISABLE)) + +/** + * @brief Check if MPU instruction access state is valid. + * @param __STATE__ MPU instruction access state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is not invalid) + */ +#define IS_MPU_INSTRUCTION_ACCESS(__STATE__) (((__STATE__) == MPU_INSTRUCTION_ACCESS_ENABLE) || \ + ((__STATE__) == MPU_INSTRUCTION_ACCESS_DISABLE)) + +/** + * @brief Check if MPU access shareable state is valid. + * @param __STATE__ MPU access shareable state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is not invalid) + */ +#define IS_MPU_ACCESS_SHAREABLE(__STATE__) (((__STATE__) == MPU_ACCESS_SHAREABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_SHAREABLE)) + +/** + * @brief Check if MPU access cacheable state is valid. + * @param __STATE__ MPU access cacheable state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is not invalid) + */ +#define IS_MPU_ACCESS_CACHEABLE(__STATE__) (((__STATE__) == MPU_ACCESS_CACHEABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_CACHEABLE)) + +/** + * @brief Check if MPU access bufferable state is valid. + * @param __STATE__ MPU access bufferable state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is not invalid) + */ +#define IS_MPU_ACCESS_BUFFERABLE(__STATE__) (((__STATE__) == MPU_ACCESS_BUFFERABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_BUFFERABLE)) + +/** + * @brief Check if MPU Tex level is valid. + * @param __TYPE__ MPU Tex level. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_MPU_TEX_LEVEL(__TYPE__) (((__TYPE__) == MPU_TEX_LEVEL0) || \ + ((__TYPE__) == MPU_TEX_LEVEL1) || \ + ((__TYPE__) == MPU_TEX_LEVEL2)) + +/** + * @brief Check if MPU region permission attribute type is valid. + * @param __TYPE__ MPU region permission attribute type. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(__TYPE__) (((__TYPE__) == MPU_REGION_NO_ACCESS) || \ + ((__TYPE__) == MPU_REGION_PRIV_RW) || \ + ((__TYPE__) == MPU_REGION_PRIV_RW_URO) || \ + ((__TYPE__) == MPU_REGION_FULL_ACCESS) || \ + ((__TYPE__) == MPU_REGION_PRIV_RO) || \ + ((__TYPE__) == MPU_REGION_PRIV_RO_URO)) + +/** + * @brief Check if MPU region number is valid. + * @param __NUMBER__ MPU region number. + * @retval SET (__NUMBER__ is valid) or RESET (__NUMBER__ is invalid) + */ +#define IS_MPU_REGION_NUMBER(__NUMBER__) (((__NUMBER__) == MPU_REGION_NUMBER0) || \ + ((__NUMBER__) == MPU_REGION_NUMBER1) || \ + ((__NUMBER__) == MPU_REGION_NUMBER2) || \ + ((__NUMBER__) == MPU_REGION_NUMBER3) || \ + ((__NUMBER__) == MPU_REGION_NUMBER4) || \ + ((__NUMBER__) == MPU_REGION_NUMBER5) || \ + ((__NUMBER__) == MPU_REGION_NUMBER6) || \ + ((__NUMBER__) == MPU_REGION_NUMBER7)) + +/** + * @brief Check if MPU region size is valid. + * @param __SIZE__ MPU region size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_MPU_REGION_SIZE(__SIZE__) (((__SIZE__) == MPU_REGION_SIZE_32B) || \ + ((__SIZE__) == MPU_REGION_SIZE_64B) || \ + ((__SIZE__) == MPU_REGION_SIZE_128B) || \ + ((__SIZE__) == MPU_REGION_SIZE_256B) || \ + ((__SIZE__) == MPU_REGION_SIZE_512B) || \ + ((__SIZE__) == MPU_REGION_SIZE_1KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_8KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_16KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_32KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_64KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_128KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_256KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_512KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_1MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_8MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_16MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_32MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_64MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_128MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_256MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_512MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_1GB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2GB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4GB)) + + +/** + * @brief Check if MPU sub region is valid. + * @param __SUBREGION__ MPU sub region. + * @retval SET (__SUBREGION__ is valid) or RESET (__SUBREGION__ is invalid) + */ +#define IS_MPU_SUB_REGION_DISABLE(__SUBREGION__) ((__SUBREGION__) < (uint16_t)0x00FFU) +#endif /* __MPU_PRESENT */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_CORTEX_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure Interrupts + Systick functionalities + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Set the priority grouping field (pre-emption priority and subpriority) + * using the required unlock sequence. + * + * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * + * @param[in] priority_group: The priority grouping bits length. + * This parameter can be one of the following values: + * @arg @ref NVIC_PRIORITYGROUP_0 0 bit for pre-emption priority, + * 8 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_1 1 bit for pre-emption priority, + * 7 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_2 2 bits for pre-emption priority, + * 6 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_3 3 bits for pre-emption priority, + * 5 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_4 4 bits for pre-emption priority, + * 4 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_5 5 bits for pre-emption priority, + * 3 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_6 6 bits for pre-emption priority, + * 2 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_7 7 bits for pre-emption priority, + * 1 bit for subpriority + **************************************************************************************** + */ +void hal_nvic_set_priority_grouping(uint32_t priority_group); + +/** + **************************************************************************************** + * @brief Set the priority of an interrupt. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + * @param[in] preempt_priority: The pre-emption priority for the IRQn channel. + * This parameter can be a value between 0 and 127 as described in the table CORTEX_NVIC_Priority_Table. + * A lower priority value indicates a higher priority + * @param[in] sub_priority: The subpriority level for the IRQ channel. + * This parameter can be a value between 0 and 255 as described in the table CORTEX_NVIC_Priority_Table. + * A lower priority value indicates a higher priority. + **************************************************************************************** + */ +void hal_nvic_set_priority(IRQn_Type IRQn, uint32_t preempt_priority, uint32_t sub_priority); + +/** + **************************************************************************************** + * @brief Enable a device specific interrupt in the NVIC interrupt controller. + * + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + **************************************************************************************** + */ +void hal_nvic_enable_irq(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Disable a device specific interrupt in the NVIC interrupt controller. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + **************************************************************************************** + */ +void hal_nvic_disable_irq(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Initiate a system reset request to reset the MCU. + **************************************************************************************** + */ +void hal_nvic_system_reset(void); + + +/** + **************************************************************************************** + * @brief Initialize the System Timer and its interrupt, and start the System Tick Timer. + * Counter is in free running mode to generate periodic interrupts. + * + * @param[in] ticks_number: Specifies the number of ticks between two interrupts. + * + * @retval status + * - 0 Function succeeded. + * - 1 Function failed. + **************************************************************************************** + */ +uint32_t hal_systick_config(uint32_t ticks_number); + +/** @} */ + +/** @addtogroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions. + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK, MPU) functionalities. + + +@endverbatim + * @{ + */ + +#if (__MPU_PRESENT == 1U) +/** + **************************************************************************************** + * @brief Initialize and configures the Region and the memory to be protected. + * + * @param[in] p_mpu_init: Pointer to a mpu_region_init_t structure that contains + * the initialization and configuration information. + **************************************************************************************** + */ +void hal_mpu_config_region(mpu_region_init_t *p_mpu_init); +#endif /* __MPU_PRESENT */ + +/** + **************************************************************************************** + * @brief Get the priority grouping field from the NVIC Interrupt Controller. + * + * @return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field) + **************************************************************************************** + */ +uint32_t hal_nvic_get_priority_grouping(void); + +/** + **************************************************************************************** + * @brief Get the priority of an interrupt. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration. + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + * @param[in] priority_group: The priority grouping bits length. + * This parameter can be one of the following values: + * @arg @ref NVIC_PRIORITYGROUP_0 0 bit for pre-emption priority, + * 8 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_1 1 bit for pre-emption priority, + * 7 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_2 2 bits for pre-emption priority, + * 6 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_3 3 bits for pre-emption priority, + * 5 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_4 4 bits for pre-emption priority, + * 4 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_5 5 bits for pre-emption priority, + * 3 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_6 6 bits for pre-emption priority, + * 2 bits for subpriority + * @arg @ref NVIC_PRIORITYGROUP_7 7 bits for pre-emption priority, + * 1 bit for subpriority + * @param[in] p_preempt_priority: Pointer on the Preemptive priority value (starting from 0). + * @param[in] p_sub_priority: Pointer on the Subpriority value (starting from 0). + **************************************************************************************** + */ +void hal_nvic_get_priority(IRQn_Type IRQn, uint32_t priority_group, uint32_t *p_preempt_priority, uint32_t *p_sub_priority); + +/** + **************************************************************************************** + * @brief Set Pending bit of an external interrupt. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + **************************************************************************************** + */ +void hal_nvic_set_pending_irq(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Get Pending Interrupt (reads the pending register in the NVIC + * and returns the pending bit for the specified interrupt). + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + * + * @return status + * - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + **************************************************************************************** + */ +uint32_t hal_nvic_get_pending_irq(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Clear the pending bit of an external interrupt. + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + **************************************************************************************** + */ +void hal_nvic_clear_pending_irq(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Get active interrupt (reads the active register in NVIC and returns the active bit). + * + * @param[in] IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete GR55xx Devices IRQ Channels list, please refer to the appropriate CMSIS device file (gr55xxxx.h)) + * + * @return status + * - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + **************************************************************************************** + */ +uint32_t hal_nvic_get_active(IRQn_Type IRQn); + +/** + **************************************************************************************** + * @brief Configure the SysTick clock source. + * + * @param[in] clk_source: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg @ref SYSTICK_CLKSOURCE_REFCLK External Reference Clock as SysTick clock source. + * @arg @ref SYSTICK_CLKSOURCE_HCLK AHB clock selected as SysTick clock source. + **************************************************************************************** + */ +void hal_systick_clk_source_config(uint32_t clk_source); + +/** @} */ + +/** @addtogroup CORTEX_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions. + * @{ + */ + +/** + **************************************************************************************** + * @brief This function handles SYSTICK interrupt request. + **************************************************************************************** + */ +void hal_systick_irq_handler(void); + +/** + **************************************************************************************** + * @brief SYSTICK callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_systick_callback can be implemented in the user file. + **************************************************************************************** + */ +void hal_systick_callback(void); + +/** @} */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Functions CORTEX Private Functions + * @brief CORTEX private functions + * @{ + */ + +#if (__MPU_PRESENT == 1U) + +/** + **************************************************************************************** + * @brief Disables the MPU and clears the HFNMIENA bit (ARM recommendation) + **************************************************************************************** + */ +void hal_mpu_disable(void); + +/** + **************************************************************************************** + * @brief Enable the MPU + * + * @param[in] mpu_control: Specifies the control mode of the MPU during hard fault, + * NMI, FAULTMASK and privileged access to the default memory. + * This parameter can be one of the following values: + * @arg @ref MPU_HFNMI_PRIVDEF_NONE + * @arg @ref MPU_HARDFAULT_NMI + * @arg @ref MPU_PRIVILEGED_DEFAULT + * @arg @ref MPU_HFNMI_PRIVDEF + **************************************************************************************** + */ +void hal_mpu_enable(uint32_t mpu_control); + +#endif /* __MPU_PRESENT */ + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_CORTEX_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_def.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_def.h new file mode 100644 index 0000000..17b0527 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_def.h @@ -0,0 +1,234 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_def.h + * @author BLE Driver Team + * @brief This file contains HAL common definitions, enumeration, macros and structures definitions. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_DEF HAL DEFINE + * @brief HAL common definitions. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_DEF__ +#define __GR55xx_HAL_DEF__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" +#include + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_ENUMERATIONS Enumerations + * @{ */ +/** + * @brief HAL Status structures definition + */ +typedef enum +{ + HAL_OK = 0x00U, /**< Operation is OK. */ + HAL_ERROR = 0x01U, /**< Parameter error or operation is not supported. */ + HAL_BUSY = 0x02U, /**< Driver is busy. */ + HAL_TIMEOUT = 0x03 /**< Timeout occurred. */ +} hal_status_t; + +/** + * @brief HAL Lock structures definition + */ +typedef enum +{ + HAL_UNLOCKED = 0x00U, /**< Object is unlocked. */ + HAL_LOCKED = 0x01 /**< Object is locked. */ +} hal_lock_t; +/** @} */ + +/** + * @defgroup HAL_DEF_MACRO Defines + * @{ + */ + +/* Exported macro ------------------------------------------------------------*/ +/** + * @brief HAL max delay definition + */ +#define HAL_MAX_DELAY (0xFFFFFFFFU) + +/** + * @brief Check whether the bits of register are set. + * @param REG specifies the register. + * @param BIT specifies the bits will be checked. + * @retval SET (BIT is set) or RESET (BIT is not set) + */ +#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET) +/** + * @brief Check whether the bits of register are clear. + * @param REG specifies the register. + * @param BIT specifies the bits will be checked. + * @retval SET (BIT is clear) or RESET (BIT is not clear) + */ +#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == RESET) + +/** + * @brief Link DMA handle and peripheral handle. + * @param __HANDLE__ specifies the peripheral handle. + * @param __PPP_DMA_FIELD_ specifies the DMA pointer in struction of peripheral handle. + * @param __DMA_HANDLE_ specifies the DMA handle. + * @retval None + */ +#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD_, __DMA_HANDLE_) \ + do{ \ + (__HANDLE__)->__PPP_DMA_FIELD_ = &(__DMA_HANDLE_); \ + (__DMA_HANDLE_).p_parent = (__HANDLE__); \ + } while(0U) + +/** @brief Reset the Handle's State field. + * @param __HANDLE__ specifies the Peripheral Handle. + * @note This macro can be used for the following purposes: + * - When the Handle is declared as local variable; before passing it as parameter + * to hal_ppp_init() for the first time, it is mandatory to use this macro + * to set the Handle's "State" field to 0. + * Otherwise, "State" field may have any random value and the first time the function + * hal_ppp_init() is called, the low level hardware initialization will be missed + * (i.e. hal_ppp_msp_init() will not be executed). + * - When there is a need to reconfigure the low level hardware: instead of calling + * hal_ppp_deinit() then hal_ppp_init(), user can make a call to this macro then hal_ppp_init(). + * In this later function, when the Handle's "State" field is set to 0, it will execute the function + * hal_ppp_msp_init which will reconfigure the low level hardware. + * @retval None + */ +#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = 0U) + +#if (USE_RTOS == 1U) +#error " USE_RTOS should be 0 in the current HAL release " +#else +/** + * @brief Lock peripheral handle. + * @param __HANDLE__ specifies the peripheral handle. + * @retval HAL_BUSY If handle is locked. + */ +#define __HAL_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->lock == HAL_LOCKED) \ + { \ + return HAL_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->lock = HAL_LOCKED; \ + } \ + }while (0U) + +/** + * @brief Unlock peripheral handle. + * @param __HANDLE__ specifies the peripheral handle. + * @retval None + */ +#define __HAL_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->lock = HAL_UNLOCKED; \ + }while (0U) +#endif /* USE_RTOS */ + + +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + + +/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__((aligned(4))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END /**< ALIGN END */ +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined(__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4) +#elif defined(__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + +/** + * @brief __NOINLINE definition + */ +#if defined(__CC_ARM) || defined(__GNUC__) +/* ARM & GNUCompiler + ---------------- +*/ +#define __NOINLINE __attribute__((noinline)) + +#elif defined(__ICCARM__) +/* ICCARM Compiler + --------------- +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ___GR55xx_HAL_DEF__ */ +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dma.h new file mode 100644 index 0000000..2463ec8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dma.h @@ -0,0 +1,736 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of DMA HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_DMA DMA + * @brief DMA HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_DMA_H__ +#define __GR55xx_HAL_DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_dma.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_DMA_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_DMA_state HAL DMA state + * @{ + */ + +/** + * @brief HAL DMA State Enumerations definition + */ +typedef enum +{ + HAL_DMA_STATE_RESET = 0x00U, /**< DMA not yet initialized or disabled */ + HAL_DMA_STATE_READY = 0x01U, /**< DMA process success and ready for use */ + HAL_DMA_STATE_BUSY = 0x02U, /**< DMA process is ongoing */ + HAL_DMA_STATE_TIMEOUT = 0x03U, /**< DMA timeout state */ + HAL_DMA_STATE_ERROR = 0x04U, /**< DMA error state */ +} hal_dma_state_t; +/** @} */ + +/** @defgroup HAL_DMA_channel HAL DMA channel + * @{ + */ + +/** + * @brief HAL DMA Channel Enumerations definition + */ +typedef enum +{ + DMA_Channel0 = 0U, /**< Channel 0 */ + DMA_Channel1 = 1U, /**< Channel 1 */ + DMA_Channel2 = 2U, /**< Channel 2 */ + DMA_Channel3 = 3U, /**< Channel 3 */ + DMA_Channel4 = 4U, /**< Channel 4 */ + DMA_Channel5 = 5U, /**< Channel 5 */ + DMA_Channel6 = 6U, /**< Channel 6 */ + DMA_Channel7 = 7U, /**< Channel 7 */ +} dma_channel_t; +/** @} */ + +/** @defgroup HAL_DMA_callback_ID HAL DMA callback ID + * @{ + */ + +/** + * @brief HAL DMA Callback ID Enumerations definition + */ +typedef enum +{ + HAL_DMA_XFER_TFR_CB_ID = 0x00, /**< Full transfer */ + HAL_DMA_XFER_BLK_CB_ID = 0x01, /**< Block transfer */ + HAL_DMA_XFER_ERROR_CB_ID = 0x02, /**< Error */ + HAL_DMA_XFER_ABORT_CB_ID = 0x03, /**< Abort */ + HAL_DMA_XFER_ALL_CB_ID = 0x04 /**< All */ +} hal_dma_callback_id_t; +/** @} */ + +/** @} */ + + +/** @addtogroup HAL_DMA_STRUCTURES Structures + * @{ + */ + +/** @defgroup DMA_Configuration DMA Configuration + * @{ + */ + +/** + * @brief DMA Configuration Structure definition + */ +typedef struct _dma_init +{ + uint32_t src_request; /**< Specifies the source request selected for the specified channel. + This parameter can be a value of @ref DMA_request */ + + uint32_t dst_request; /**< Specifies the destination request selected for the specified channel. + This parameter can be a value of @ref DMA_request */ + + uint32_t direction; /**< Specifies if the data will be transferred from memory to peripheral, + from memory to memory or from peripheral to memory. + This parameter can be a value of @ref DMA_Data_transfer_direction */ + + uint32_t src_increment; /**< Specifies whether the srouce address register should be incremented or decrement or not. + This parameter can be a value of @ref DMA_Source_incremented_mode */ + + uint32_t dst_increment; /**< Specifies whether the destination address register should be incremented or decrement or not. + This parameter can be a value of @ref DMA_Destination_incremented_mode */ + + uint32_t src_data_alignment; /**< Specifies the source data width. + This parameter can be a value of @ref DMA_Source_data_size */ + + uint32_t dst_data_alignment; /**< Specifies the destination data width. + This parameter can be a value of @ref DMA_Destination_data_size */ + + uint32_t mode; /**< Specifies the operation mode of the DMA Channel(Normal or Circular). + This parameter can be a value of @ref DMA_mode + @note The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Channel */ + + uint32_t priority; /**< Specifies the software priority for the DMA Channel. + This parameter can be a value of @ref DMA_Priority_level */ +} dma_init_t; + +/** @} */ + +/** @defgroup DMA_handle DMA handle + * @{ + */ + +/** + * @brief DMA handle Structure definition + */ +typedef struct _dma_handle +{ + dma_channel_t channel; /**< DMA Channel Number */ + + dma_init_t init; /**< DMA communication parameters */ + + hal_lock_t lock; /**< DMA locking object */ + + __IO hal_dma_state_t state; /**< DMA transfer state */ + + void *p_parent; /**< Parent object state */ + + void (* xfer_tfr_callback)(struct _dma_handle *p_dma); /**< DMA transfer complete callback */ + + void (* xfer_blk_callback)(struct _dma_handle *p_dma); /**< DMA block complete callback */ + + void (* xfer_error_callback)(struct _dma_handle *p_dma); /**< DMA transfer error callback */ + + void (* xfer_abort_callback)(struct _dma_handle *p_dma); /**< DMA transfer abort callback */ + + __IO uint32_t error_code; /**< DMA Error code */ + + uint32_t retention[5]; /**< DMA important register information. */ +} dma_handle_t; + +/** @} */ + +/** @} */ + + +/** + * @defgroup HAL_DMA_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA_Exported_Constants DMA Exported Constants + * @{ + */ + +/** @defgroup DMA_Error_Code DMA Error Code + * @{ + */ +#define HAL_DMA_ERROR_NONE ((uint32_t)0x00000000U) /**< No error */ +#define HAL_DMA_ERROR_TE ((uint32_t)0x00000001U) /**< Transfer error */ +#define HAL_DMA_ERROR_NO_XFER ((uint32_t)0x00000004U) /**< no ongoing transfer */ +#define HAL_DMA_ERROR_TIMEOUT ((uint32_t)0x00000020U) /**< Timeout error */ +/** @} */ + +/** @defgroup DMA_request DMA request definitions + * @{ + */ +#define DMA_REQUEST_SPIM_TX LL_DMA_PERIPH_SPIM_TX /**< DMA SPIM transmit request */ +#define DMA_REQUEST_SPIM_RX LL_DMA_PERIPH_SPIM_RX /**< DMA SPIM receive request */ +#define DMA_REQUEST_SPIS_TX LL_DMA_PERIPH_SPIS_TX /**< DMA SPIS transmit request */ +#define DMA_REQUEST_SPIS_RX LL_DMA_PERIPH_SPIS_RX /**< DMA SPIS receive request */ +#define DMA_REQUEST_QSPI0_TX LL_DMA_PERIPH_QSPI0_TX /**< DMA QSPI0 transmit request */ +#define DMA_REQUEST_QSPI0_RX LL_DMA_PERIPH_QSPI0_RX /**< DMA QSPI0 receive request */ +#define DMA_REQUEST_I2C0_TX LL_DMA_PERIPH_I2C0_TX /**< DMA I2C0 transmit request */ +#define DMA_REQUEST_I2C0_RX LL_DMA_PERIPH_I2C0_RX /**< DMA I2C0 receive request */ +#define DMA_REQUEST_I2C1_TX LL_DMA_PERIPH_I2C1_TX /**< DMA I2C1 transmit request */ +#define DMA_REQUEST_I2C1_RX LL_DMA_PERIPH_I2C1_RX /**< DMA I2C1 receive request */ +#define DMA_REQUEST_I2S_S_TX LL_DMA_PERIPH_I2S_S_TX /**< DMA I2S_S transmit request */ +#define DMA_REQUEST_I2S_S_RX LL_DMA_PERIPH_I2S_S_RX /**< DMA I2S_S receive request */ +#define DMA_REQUEST_UART0_TX LL_DMA_PERIPH_UART0_TX /**< DMA UART0 transmit request */ +#define DMA_REQUEST_UART0_RX LL_DMA_PERIPH_UART0_RX /**< DMA UART0 receive request */ +#define DMA_REQUEST_QSPI1_TX LL_DMA_PERIPH_QSPI1_TX /**< DMA QSPI1 transmit request */ +#define DMA_REQUEST_QSPI1_RX LL_DMA_PERIPH_QSPI1_RX /**< DMA QSPI1 receive request */ +#define DMA_REQUEST_I2S_M_TX LL_DMA_PERIPH_I2S_M_TX /**< DMA I2S_M transmit request */ +#define DMA_REQUEST_I2S_M_RX LL_DMA_PERIPH_I2S_M_RX /**< DMA I2S_M receive request */ +#define DMA_REQUEST_SNSADC LL_DMA_PERIPH_SNSADC /**< DMA SenseADC request */ +#define DMA_REQUEST_MEM LL_DMA_PERIPH_MEM /**< DMA Memory request */ + +#define DMA0_REQUEST_SPIM_TX DMA_REQUEST_SPIM_TX /**< DMA SPIM transmit request */ +#define DMA0_REQUEST_SPIM_RX DMA_REQUEST_SPIM_RX /**< DMA SPIM receive request */ +#define DMA0_REQUEST_SPIS_TX DMA_REQUEST_SPIS_TX /**< DMA SPIS transmit request */ +#define DMA0_REQUEST_SPIS_RX DMA_REQUEST_SPIS_RX /**< DMA SPIS receive request */ +#define DMA0_REQUEST_QSPI0_TX DMA_REQUEST_QSPI0_TX /**< DMA QSPI0 transmit request */ +#define DMA0_REQUEST_QSPI0_RX DMA_REQUEST_QSPI0_RX /**< DMA QSPI0 receive request */ +#define DMA0_REQUEST_I2C0_TX DMA_REQUEST_I2C0_TX /**< DMA I2C0 transmit request */ +#define DMA0_REQUEST_I2C0_RX DMA_REQUEST_I2C0_RX /**< DMA I2C0 receive request */ +#define DMA0_REQUEST_I2C1_TX DMA_REQUEST_I2C1_TX /**< DMA I2C1 transmit request */ +#define DMA0_REQUEST_I2C1_RX DMA_REQUEST_I2C1_RX /**< DMA I2C1 receive request */ +#define DMA0_REQUEST_I2S_S_TX DMA_REQUEST_I2S_S_TX /**< DMA I2S_S transmit request */ +#define DMA0_REQUEST_I2S_S_RX DMA_REQUEST_I2S_S_RX /**< DMA I2S_S receive request */ +#define DMA0_REQUEST_UART0_TX DMA_REQUEST_UART0_TX /**< DMA UART0 transmit request */ +#define DMA0_REQUEST_UART0_RX DMA_REQUEST_UART0_RX /**< DMA UART0 receive request */ +#define DMA0_REQUEST_QSPI1_TX DMA_REQUEST_QSPI1_TX /**< DMA QSPI1 transmit request */ +#define DMA0_REQUEST_QSPI1_RX DMA_REQUEST_QSPI1_RX /**< DMA QSPI1 receive request */ +#define DMA0_REQUEST_I2S_M_TX DMA_REQUEST_I2S_M_TX /**< DMA I2S_M transmit request */ +#define DMA0_REQUEST_I2S_M_RX DMA_REQUEST_I2S_M_RX /**< DMA I2S_M receive request */ +#define DMA0_REQUEST_SNSADC DMA_REQUEST_SNSADC /**< DMA SenseADC request */ +#define DMA0_REQUEST_MEM DMA_REQUEST_MEM /**< DMA Memory request */ +/** @} */ + +/** @defgroup DMA_Data_transfer_direction DMA Data Transfer directions + * @{ + */ +#define DMA_MEMORY_TO_MEMORY LL_DMA_DIRECTION_MEMORY_TO_MEMORY /**< Memory to memory direction */ +#define DMA_MEMORY_TO_PERIPH LL_DMA_DIRECTION_MEMORY_TO_PERIPH /**< Memory to peripheral direction */ +#define DMA_PERIPH_TO_MEMORY LL_DMA_DIRECTION_PERIPH_TO_MEMORY /**< Peripheral to memory direction */ +#define DMA_PERIPH_TO_PERIPH LL_DMA_DIRECTION_PERIPH_TO_PERIPH /**< Peripheral to Peripheral direction */ +/** @} */ + +/** @defgroup DMA_Source_incremented_mode DMA Source Incremented Mode + * @{ + */ +#define DMA_SRC_INCREMENT LL_DMA_SRC_INCREMENT /**< Source increment mode */ +#define DMA_SRC_DECREMENT LL_DMA_SRC_DECREMENT /**< Source decrement mode */ +#define DMA_SRC_NO_CHANGE LL_DMA_SRC_NO_CHANGE /**< Source no change mode */ +/** @} */ + +/** @defgroup DMA_Destination_incremented_mode DMA Destination Incremented Mode + * @{ + */ +#define DMA_DST_INCREMENT LL_DMA_DST_INCREMENT /**< Destination increment mode */ +#define DMA_DST_DECREMENT LL_DMA_DST_DECREMENT /**< Destination decrement mode */ +#define DMA_DST_NO_CHANGE LL_DMA_DST_NO_CHANGE /**< Destination no change mode */ +/** @} */ + +/** @defgroup DMA_Source_data_size DMA Source Data Size Alignment + * @{ + */ +#define DMA_SDATAALIGN_BYTE LL_DMA_SDATAALIGN_BYTE /**< Source data alignment : Byte */ +#define DMA_SDATAALIGN_HALFWORD LL_DMA_SDATAALIGN_HALFWORD /**< Source data alignment : HalfWord */ +#define DMA_SDATAALIGN_WORD LL_DMA_SDATAALIGN_WORD /**< Source data alignment : Word */ +/** @} */ + +/** @defgroup DMA_Destination_data_size DMA Destination Data Size Alignment + * @{ + */ +#define DMA_DDATAALIGN_BYTE LL_DMA_DDATAALIGN_BYTE /**< Destination data alignment : Byte */ +#define DMA_DDATAALIGN_HALFWORD LL_DMA_DDATAALIGN_HALFWORD /**< Destination data alignment : HalfWord */ +#define DMA_DDATAALIGN_WORD LL_DMA_DDATAALIGN_WORD /**< Destination data alignment : Word */ +/** @} */ + +/** @defgroup DMA_mode DMA Mode + * @{ + */ +#define DMA_NORMAL LL_DMA_MODE_SINGLE_BLOCK /**< Normal Mode */ +#define DMA_CIRCULAR LL_DMA_MODE_MULTI_BLOCK_ALL_RELOAD /**< Circular Mode */ + +/** @} */ + +/** @defgroup DMA_Priority_level DMA Priority Level + * @{ + */ +#define DMA_PRIORITY_LOW LL_DMA_PRIORITY_0 /**< Priority level : Low */ +#define DMA_PRIORITY_MEDIUM LL_DMA_PRIORITY_2 /**< Priority level : Medium */ +#define DMA_PRIORITY_HIGH LL_DMA_PRIORITY_5 /**< Priority level : High */ +#define DMA_PRIORITY_VERY_HIGH LL_DMA_PRIORITY_7 /**< Priority level : Very High */ +/** @} */ + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DMA_Private_Macro DMA Private Macros + * @{ + */ + +/** @brief Check if DMA channel instance is valid. + * @param __instance__ DMA channel instance. + * @retval SET (__instance__ is valid) or RESET (__instance__ is invalid) + */ +#define IS_DMA_ALL_INSTANCE(__instance__) (((__instance__) == DMA_Channel0) || \ + ((__instance__) == DMA_Channel1) || \ + ((__instance__) == DMA_Channel2) || \ + ((__instance__) == DMA_Channel3) || \ + ((__instance__) == DMA_Channel4) || \ + ((__instance__) == DMA_Channel5) || \ + ((__instance__) == DMA_Channel6) || \ + ((__instance__) == DMA_Channel7)) + +/** @brief Check if DMA request is valid. + * @param __REQUEST__ DMA request. + * @retval SET (__REQUEST__ is valid) or RESET (__REQUEST__ is invalid) + */ +#define IS_DMA_ALL_REQUEST(__REQUEST__) (((__REQUEST__) == DMA_REQUEST_SPIM_TX) || \ + ((__REQUEST__) == DMA_REQUEST_SPIM_RX) || \ + ((__REQUEST__) == DMA_REQUEST_SPIS_TX) || \ + ((__REQUEST__) == DMA_REQUEST_SPIS_RX) || \ + ((__REQUEST__) == DMA_REQUEST_QSPI0_TX) || \ + ((__REQUEST__) == DMA_REQUEST_QSPI0_RX) || \ + ((__REQUEST__) == DMA_REQUEST_I2C0_TX) || \ + ((__REQUEST__) == DMA_REQUEST_I2C0_RX) || \ + ((__REQUEST__) == DMA_REQUEST_I2C1_TX) || \ + ((__REQUEST__) == DMA_REQUEST_I2C1_RX) || \ + ((__REQUEST__) == DMA_REQUEST_I2S_S_TX) || \ + ((__REQUEST__) == DMA_REQUEST_I2S_S_RX) || \ + ((__REQUEST__) == DMA_REQUEST_UART0_TX) || \ + ((__REQUEST__) == DMA_REQUEST_UART0_RX) || \ + ((__REQUEST__) == DMA_REQUEST_QSPI1_TX) || \ + ((__REQUEST__) == DMA_REQUEST_QSPI1_RX) || \ + ((__REQUEST__) == DMA_REQUEST_I2S_M_TX) || \ + ((__REQUEST__) == DMA_REQUEST_I2S_M_RX) || \ + ((__REQUEST__) == DMA_REQUEST_SNSADC) || \ + ((__REQUEST__) == DMA_REQUEST_MEM)) + +/** @brief Check if DMA direction is valid. + * @param __DIRECTION__ DMA direction. + * @retval SET (__DIRECTION__ is valid) or RESET (__DIRECTION__ is invalid) + */ +#define IS_DMA_DIRECTION(__DIRECTION__) (((__DIRECTION__) == DMA_MEMORY_TO_MEMORY) || \ + ((__DIRECTION__) == DMA_MEMORY_TO_PERIPH) || \ + ((__DIRECTION__) == DMA_PERIPH_TO_MEMORY) || \ + ((__DIRECTION__) == DMA_PERIPH_TO_PERIPH)) + +/** @brief Check if DMA buffer size is valid. + * @param __SIZE__ DMA buffer size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_DMA_BUFFER_SIZE(__SIZE__) (((__SIZE__) >= 0x1) && ((__SIZE__) < 0xFFF)) + +/** @brief Check if DMA source address increment state is valid. + * @param __STATE__ DMA source address increment state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_DMA_SOURCE_INC_STATE(__STATE__) (((__STATE__) == DMA_SRC_INCREMENT) || \ + ((__STATE__) == DMA_SRC_DECREMENT) || \ + ((__STATE__) == DMA_SRC_NO_CHANGE)) + +/** @brief Check if DMA destination address increment state is valid. + * @param __STATE__ DMA destination address increment state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_DMA_DESTINATION_INC_STATE(__STATE__) (((__STATE__) == DMA_DST_INCREMENT) || \ + ((__STATE__) == DMA_DST_DECREMENT) || \ + ((__STATE__) == DMA_DST_NO_CHANGE)) + +/** @brief Check if DMA source data size is valid. + * @param __SIZE__ DMA source data size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_DMA_SOURCE_DATA_SIZE(__SIZE__) (((__SIZE__) == DMA_SDATAALIGN_BYTE) || \ + ((__SIZE__) == DMA_SDATAALIGN_HALFWORD) || \ + ((__SIZE__) == DMA_SDATAALIGN_WORD)) + +/** @brief Check if DMA destination data size is valid. + * @param __SIZE__ DMA destination data size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_DMA_DESTINATION_DATA_SIZE(__SIZE__) (((__SIZE__) == DMA_DDATAALIGN_BYTE) || \ + ((__SIZE__) == DMA_DDATAALIGN_HALFWORD) || \ + ((__SIZE__) == DMA_DDATAALIGN_WORD )) + +/** @brief Check if DMA mode is valid. + * @param __MODE__ DMA mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_DMA_MODE(__MODE__) (((__MODE__) == DMA_NORMAL ) || \ + ((__MODE__) == DMA_CIRCULAR)) + +/** @brief Check if DMA priority is valid. + * @param __PRIORITY__ DMA priority. + * @retval SET (__PRIORITY__ is valid) or RESET (__PRIORITY__ is invalid) + */ +#define IS_DMA_PRIORITY(__PRIORITY__) (((__PRIORITY__) == DMA_PRIORITY_LOW ) || \ + ((__PRIORITY__) == DMA_PRIORITY_MEDIUM) || \ + ((__PRIORITY__) == DMA_PRIORITY_HIGH) || \ + ((__PRIORITY__) == DMA_PRIORITY_VERY_HIGH)) +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_DMA_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize the DMA Channel source + and destination addresses, incrementation and data sizes, transfer direction, + circular/normal mode selection, memory-to-memory mode selection and Channel priority value. + [..] + The hal_dma_init() function follows the DMA configuration procedures as described in + reference manual. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the DMA according to the specified + * parameters in the dma_init_t and initialize the associated handle. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_init(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief De-initialize the DMA peripheral. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_deinit (dma_handle_t *p_dma); + +/** @} */ + + +/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions + * @brief Input and Output operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the source, destination address and data length and Start DMA transfer + (+) Configure the source, destination address and data length and + Start DMA transfer with interrupt + (+) Abort DMA transfer + (+) Poll for transfer complete + (+) Handle DMA interrupt request + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Start the DMA Transfer. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * @param[in] src_address: The source memory Buffer address + * @param[in] dst_address: The destination memory Buffer address + * @param[in] data_length: The length of data to be transferred from source to destination, ranging between 0 and 4095. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_start (dma_handle_t *p_dma, uint32_t src_address, uint32_t dst_address, uint32_t data_length); + +/** + **************************************************************************************** + * @brief Start the DMA Transfer with interrupt enabled. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * @param[in] src_address: The source memory Buffer address + * @param[in] dst_address: The destination memory Buffer address + * @param[in] data_length: The length of data to be transferred from source to destination, ranging between 0 and 4095. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_start_it(dma_handle_t *p_dma, uint32_t src_address, uint32_t dst_address, uint32_t data_length); + +/** + **************************************************************************************** + * @brief Abort the DMA Transfer. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_abort(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Aborts the DMA Transfer in Interrupt mode. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_abort_it(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Polling for transfer complete. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * @param[in] timeout: Timeout duration. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_poll_for_transfer(dma_handle_t *p_dma, uint32_t timeout); + +/** @} */ + +/** @addtogroup DMA_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle DMA interrupt request. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + **************************************************************************************** + */ +void hal_dma_irq_handler(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Register callbacks + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * @param[in] id: User Callback identifer. This parameter can be one of the following values: + * @arg @ref HAL_DMA_XFER_TFR_CB_ID + * @arg @ref HAL_DMA_XFER_BLK_CB_ID + * @arg @ref HAL_DMA_XFER_ERROR_CB_ID + * @arg @ref HAL_DMA_XFER_ABORT_CB_ID + * @param[in] callback: Pointer to private callbacsk function which has pointer to a dma_handle_t structure as parameter. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_register_callback(dma_handle_t *p_dma, hal_dma_callback_id_t id, void (* callback)( dma_handle_t * p_dma)); + +/** + **************************************************************************************** + * @brief UnRegister callbacks + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * @param[in] id: User Callback identifer. This parameter can be a combiantion of the following values: + * @arg @ref HAL_DMA_XFER_TFR_CB_ID + * @arg @ref HAL_DMA_XFER_BLK_CB_ID + * @arg @ref HAL_DMA_XFER_ERROR_CB_ID + * @arg @ref HAL_DMA_XFER_ABORT_CB_ID + * @arg @ref HAL_DMA_XFER_ALL_CB_ID + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_unregister_callback(dma_handle_t *p_dma, hal_dma_callback_id_t id); + +/** @} */ + +/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DMA state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the DMA hande state. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @retval ::HAL_DMA_STATE_RESET: DMA not yet initialized or disabled. + * @retval ::HAL_DMA_STATE_READY: DMA process succeeded and ready for use. + * @retval ::HAL_DMA_STATE_BUSY: DMA process is ongoing. + * @retval ::HAL_DMA_STATE_TIMEOUT: DMA timeout state. + * @retval ::HAL_DMA_STATE_ERROR: DMA error state. + **************************************************************************************** + */ +hal_dma_state_t hal_dma_get_state(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Return the DMA error code. + * + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration information for the specified DMA Channel. + * + * @return DMA Error Code + **************************************************************************************** + */ +uint32_t hal_dma_get_error(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Suspend some registers related to DMA configuration before sleep. + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration + * information for the specified DMA module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_suspend_reg(dma_handle_t *p_dma); + +/** + **************************************************************************************** + * @brief Restore some registers related to DMA configuration after sleep. + * This function must be used in conjunction with the hal_dma_resume_reg(). + * @param[in] p_dma: Pointer to a DMA handle which contains the configuration + * information for the specified DMA module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dma_resume_reg(dma_handle_t *p_dma); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_DMA_H__*/ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dual_tim.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dual_tim.h new file mode 100644 index 0000000..b794960 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_dual_tim.h @@ -0,0 +1,493 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_dual_tim.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of DUAL TIMER HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_DUAL_TIMER DUAL TIMER + * @brief DUAL TIM HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_DUAL_TIMER_H__ +#define __GR55xx_HAL_DUAL_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_dual_tim.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_DUAL_TIMER_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_DUAL_TIMER_state HAL DUAL TIM state + * @{ + */ + +/** + * @brief HAL DUAL TIMER State Enumerations definition + */ +typedef enum +{ + HAL_DUAL_TIMER_STATE_RESET = 0x00, /**< Peripheral not yet initialized or disabled */ + HAL_DUAL_TIMER_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + HAL_DUAL_TIMER_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_DUAL_TIMER_STATE_ERROR = 0x04 /**< Reception process is ongoing */ +} hal_dual_timer_state_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_DUAL_TIMER_STRUCTURES Structures + * @{ + */ + +/** @defgroup DUAL_TIMER_Configuration DUAL TIMER Configuration + * @{ + */ + +/** + * @brief DUAL TIMER init Structure definition + */ +typedef struct _dual_timer_init +{ + uint32_t prescaler; /**< Specifies the prescaler value used to divide the DUAL_TIMER clock. + This parameter can be a value of @ref DUAL_TIMER_Prescaler_Div */ + + uint32_t counter_mode; /**< Specifies the counter mode. + This parameter can be a value of @ref DUAL_TIMER_Counter_Mode */ + + uint32_t auto_reload; /**< Specifies the auto-reload value. */ + +} dual_timer_init_t; + +/** @} */ + +/** @defgroup DUAL_TIMER_handle DUAL TIMER handle + * @{ + */ + +/** + * @brief DUAL_TIMER handle Structure definition + */ +typedef struct _dual_timer_handle +{ + dual_timer_regs_t *p_instance; /**< Register base address */ + + dual_timer_init_t init; /**< DUAL_TIMER Base required parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_dual_timer_state_t state; /**< DUAL_TIMER operation state */ + +} dual_timer_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_DUAL_TIMER_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_DUAL_TIMER_Callback Callback + * @{ + */ + +/** + * @brief HAL_DUAL_TIMER Callback function definition + */ + +typedef struct _hal_dual_timer_callback +{ + void (*dual_timer_msp_init)(dual_timer_handle_t *p_dual_timer); /**< DUAL_TIMER init MSP callback */ + void (*dual_timer_msp_deinit)(dual_timer_handle_t *p_dual_timer); /**< DUAL_TIMER de-init MSP callback */ + void (*dual_timer_period_elapsed_callback)(dual_timer_handle_t *p_dual_timer); /**< DUAL_TIMER period elapsed callback */ +} hal_dual_timer_callback_t; +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_DUAL_TIMER_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_Exported_Constants DUAL TIMER Exported Constants + * @{ + */ + +/** @defgroup DUAL_TIMER_Prescaler_Div DUAL TIMER Prescaler Division + * @{ + */ +#define DUAL_TIMER_PRESCALER_DIV0 LL_DUAL_TIMER_PRESCALER_DIV0 /**< 0 stage of prescale, clock is divided by 1. */ +#define DUAL_TIMER_PRESCALER_DIV16 LL_DUAL_TIMER_PRESCALER_DIV16 /**< 4 stages of prescale, clock is divided by 16. */ +#define DUAL_TIMER_PRESCALER_DIV256 LL_DUAL_TIMER_PRESCALER_DIV256 /**< 8 stages of prescale, clock is divided by 256. */ +/** @} */ + +/** @defgroup DUAL_TIMER_Counter_Mode DUAL TIMER Counter Mode + * @{ + */ +#define DUAL_TIMER_COUNTERMODE_LOOP 0x00000000U /**< DUAL TIMER Loop mode.*/ +#define DUAL_TIMER_COUNTERMODE_ONESHOT DUAL_TIMER_CTRL_ONESHOT /**< DUAL TIMER One-shot mode. */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_Exported_Macros DUAL TIMER Exported Macros + * @{ + */ + +/** @brief Reset DUAL TIMER handle states. + * @param __HANDLE__ DUAL TIMER handle. + * @retval None + */ +#define __HAL_DUAL_TIMER_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_DUAL_TIMER_STATE_RESET) + +/** @brief Enable the specified DUAL TIMER peripheral. + * @param __HANDLE__ Specifies the DUAL TIMER Handle. + * @retval None + */ +#define __HAL_DUAL_TIMER_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, DUAL_TIMER_CTRL_EN) + +/** @brief Disable the specified DUAL TIMER peripheral. + * @param __HANDLE__ Specifies the DUAL TIMER Handle. + * @retval None + */ +#define __HAL_DUAL_TIMER_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, DUAL_TIMER_CTRL_EN) + +/** @brief Enable the DUAL TIMER interrupt. + * @param __HANDLE__ Specifies the DUAL TIM Handle. + * @retval None + */ +#define __HAL_DUAL_TIMER_ENABLE_IT(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, DUAL_TIMER_CTRL_INTEN) + +/** @brief Disable the DUAL TIMER interrupt. + * @param __HANDLE__ Specifies the DUAL TIM Handle. + * @retval None + */ +#define __HAL_DUAL_TIMER_DISABLE_IT(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, DUAL_TIMER_CTRL_INTEN) + +/** @brief Check whether the DUAL TIMER interrupt has occurred or not. + * @param __HANDLE__ Specifies the DUAL TIMER Handle. + * @retval The new state of DUAL TIMER interrupt (SET or RESET). + */ +#define __HAL_DUAL_TIMER_GET_FLAG_IT(__HANDLE__) ll_dual_timer_is_active_flag_it(__HANDLE__->p_instance) + +/** @brief Clear the DUAL TIMER interrupt flag. + * @param __HANDLE__ Specifies the DUAL TIMER Handle. + * @retval None. + */ +#define __HAL_DUAL_TIMER_CLEAR_FLAG_IT(__HANDLE__) ll_dual_timer_clear_flag_it(__HANDLE__->p_instance) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_Private_Macros DUAL TIMER Private Macros + * @{ + */ + +/** @brief Check if DUAL TIMER prescaler is valid. + * @param __PRESCALER__ DUAL TIMER prescaler. + * @retval SET (__PRESCALER__ is valid) or RESET (__PRESCALER__ is invalid) + */ +#define IS_DUAL_TIMER_PRESCALER(__PRESCALER__) (((__PRESCALER__) == DUAL_TIMER_PRESCALER_DIV0) || \ + ((__PRESCALER__) == DUAL_TIMER_PRESCALER_DIV16) || \ + ((__PRESCALER__) == DUAL_TIMER_PRESCALER_DIV256)) + +/** @brief Check if DUAL TIMER counter mode is valid. + * @param __MODE__ DUAL TIMER counter mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_DUAL_TIMER_COUNTERMODE(__MODE__) (((__MODE__) == DUAL_TIMER_COUNTERMODE_LOOP) || \ + ((__MODE__) == DUAL_TIMER_COUNTERMODE_ONESHOT)) +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_DUAL_TIMER_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup DUAL_TIMER_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * + * @verbatim +=============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the DUAL TIMER. + (+) De-initialize the DUAL TIMER. + (+) Start the Timer. + (+) Stop the Timer. + (+) Start the Timer and enable interrupt. + (+) Stop the Timer and disable interrupt. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the DUAL TIMER according to the specified parameters + * in the dual_timer_init_t and initialize the associated handle. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_init(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief De-initialize the DUAL TIMER peripheral. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIM handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_deinit(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Initialize the DUAL TIMER MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_dual_timer_base_msp_init could be implemented in the user file + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + **************************************************************************************** + */ +void hal_dual_timer_base_msp_init(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief De-initialize the DUAL TIMER MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_dual_timer_base_msp_deinit could be implemented in the user file + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIM handle which contains the configuration information for the specified DUAL TIMER. + **************************************************************************************** + */ +void hal_dual_timer_base_msp_deinit(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Starts the DUAL TIMER counter. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_start(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Stops the DUAL TIMER counter. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIM handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_stop(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Starts the DUAL TIMER counter in interrupt mode. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIM handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_start_it(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Stops the DUAL TIMER counter in interrupt mode. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_base_stop_it(dual_timer_handle_t *p_dual_timer); + +/** @} */ + +/** @addtogroup DUAL_TIMER_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle DUAL TIMER interrupt request. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + **************************************************************************************** + */ +void hal_dual_timer_irq_handler(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief Period elapsed callback in non-blocking mode. + * + * @note This function should not be modified. When the callback is needed, + * the hal_dual_timer_period_elapsed_callback can be implemented in the user file. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + **************************************************************************************** + */ +void hal_dual_timer_period_elapsed_callback(dual_timer_handle_t *p_dual_timer); + +/** @} */ + +/** @addtogroup DUAL_TIMER_Exported_Functions_Group2 Peripheral Control and State functions + * @brief DUAL TIMER Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral Control and State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the DUAL TIMER handle state. + (+) Configure the DUAL TIMER. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the DUAL TIMER handle state. + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * + * @retval ::HAL_DUAL_TIMER_STATE_RESET: Peripheral not yet initialized or disabled. + * @retval ::HAL_DUAL_TIMER_STATE_READY: Peripheral Initialized and ready for use. + * @retval ::HAL_DUAL_TIMER_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_DUAL_TIMER_STATE_ERROR: Reception process is ongoing. + **************************************************************************************** + */ +hal_dual_timer_state_t hal_dual_timer_get_state(dual_timer_handle_t *p_dual_timer); + +/** + **************************************************************************************** + * @brief DUAL TIMER configuration + * + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * @param[in] p_structure: The DUAL TIMER configuration structure + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_set_config(dual_timer_handle_t *p_dual_timer, dual_timer_init_t *p_structure); + +/** + **************************************************************************************** + * @brief DUAL TIMER set background reload value + * The background reload value contains the value from which the counter is to decrement. + * This is the value used to reload the counter when Periodic mode is enabled, and the current count reaches 0. + * The difference is that writes to background reload value do not cause the counter to immediately restart from the new value. + * @param[in] p_dual_timer: Pointer to a DUAL_TIMER handle which contains the configuration information for the specified DUAL TIMER. + * @param[in] reload_value: Background reload value + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + **************************************************************************************** + */ +hal_status_t hal_dual_timer_set_background_reload(dual_timer_handle_t *p_dual_timer, uint32_t reload_value); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_DUAL_TIMER_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_efuse.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_efuse.h new file mode 100644 index 0000000..2f3359d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_efuse.h @@ -0,0 +1,514 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_efuse.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of eFuse HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_EFUSE EFUSE + * @brief eFuse HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_EFUSE_H__ +#define __GR55xx_HAL_EFUSE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_efuse.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_EFUSE_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_EFUSE_state HAL EFUSE state + * @{ + */ + +/** + * @brief HAL eFuse State Enumerations definition + */ +typedef enum +{ + HAL_EFUSE_STATE_RESET = 0x00, /**< Peripheral not yet initialized or disabled */ + HAL_EFUSE_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + HAL_EFUSE_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_EFUSE_STATE_ERROR = 0x04 /**< Reception process is error */ +} hal_efuse_state_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_EFUSE_STRUCTURES Structures + * @{ + */ + +/** @defgroup EFUSE_Configuration EFUSE Configuration + * @{ + */ + +/** + * @brief eFuse init Structure definition + */ +typedef struct _efuse_init +{ + uint32_t info_mode; /**< Specifies the info mode, enable or disable main or backup info. */ + +} efuse_init_t; + +/** @} */ + +/** @defgroup EFUSE_handle EFUSE handle + * @{ + */ + +/** + * @brief eFuse handle Structure definition + */ +typedef struct _efuse_handle +{ + efuse_regs_t *p_instance; /**< Register base address */ + + efuse_init_t init; /**< eFuse base required parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_efuse_state_t state; /**< eFuse operation state */ + + __IO uint32_t error_code; /**< eFuse Error code */ + +} efuse_handle_t; +/** @} */ + +/** @defgroup EFUSE_Keyram Keyram configuration + * @{ + */ + +/** + * @brief eFuse Keyram Structure definition + */ +typedef struct _keyram_mask +{ + uint32_t aes_mask; /**< AES port mask. */ + + uint32_t hmac_mask; /**< HMAC port mask. */ + + uint32_t present_mcu_mask; /**< Present of MCU port mask. */ + + uint32_t present_xip_mask; /**< Present of XIP port mask. */ + + uint32_t efuse_mask; /**< eFuse port mask. */ + + uint32_t enc_key_low; /**< encrypt key low 32bit mask. */ + + uint32_t enc_key_high; /**< encrypt key high 32bit mask. */ +} keyram_mask_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_EFUSE_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_EFUSE_Callback Callback + * @{ + */ + +/** + * @brief HAL_EFUSE Callback function definition + */ + +typedef struct _hal_efuse_callback +{ + void (*efuse_msp_init)(efuse_handle_t *p_efuse); /**< EFUSE init MSP callback */ + void (*efuse_msp_deinit)(efuse_handle_t *p_efuse); /**< EFUSE de-init MSP callback */ +} hal_efuse_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_EFUSE_MACRO Defines + * @{ + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EFUSE_Exported_Macros EFUSE Exported Macros + * @{ + */ + +/** @defgroup EFUSE_Error_Code EFUSE Error Code + * @{ + */ +#define HAL_EFUSE_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_EFUSE_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_EFUSE_ERROR_INVALID_PARAM ((uint32_t)0x00000002) /**< Invalid parameters error */ +/** @} */ + +/** @defgroup EFUSE_Flags EFUSE Flags + * @{ + */ +#define EFUSE_FLAG_WRITE_KEYRAM_BUSY LL_EFUSE_WRITE_KEYRAM_BUSY /**< Write keyram operation is in process */ +#define EFUSE_FLAG_READ_TRIM_DONE LL_EFUSE_READ_TRIM_DONE /**< Read trim from eFuse has done */ +#define EFUSE_FLAG_CRC_CHECK_DONE LL_EFUSE_CRC_CHECK_DONE /**< eFuse CRC check done */ +#define EFUSE_FLAG_CRC_CHECK_SUCCESS LL_EFUSE_CRC_CHECK_SUCCESS /**< CRC check succeeded */ +#define EFUSE_FLAG_INIT_CHECK_DONE LL_EFUSE_INIT_CHECK_DONE /**< eFuse initial value check done */ +#define EFUSE_FLAG_INIT_CHECK_SUCCESS LL_EFUSE_INIT_CHECK_SUCCESS /**< eFuse initial value check succeeded */ +#define EFUSE_FLAG_WRITE_DONE LL_EFUSE_WRITE_DONE /**< eFuse one word write done */ +#define EFUSE_FLAG_TEST_DONE LL_EFUSE_TEST_DONE /**< Read from eFuse has done in test mode */ +/** @} */ + +/** @defgroup EFUSE_Loyout_Map EFUSE Loyout Map + * @{ + */ +#define EFUSE_OFFSET_USER_DSVD (0x0000UL) /**< Reserved offset in backup info block */ +#define EFUSE_OFFSET_BBLK_TRIM (0x0020UL) /**< Triming offset in backup info block */ +#define EFUSE_OFFSET_BBLK_CONFIG (0x005CUL) /**< Configuration offset in backup info block */ +#define EFUSE_OFFSET_BBLK_SWD (0x0060UL) /**< SWD Enable offset in backup info block */ +#define EFUSE_OFFSET_BBLK_EncMode (0x0062UL) /**< Encryption Mode offset in backup info block */ +#define EFUSE_OFFSET_BBLK_CRC32 (0x0064UL) /**< CRC32 offset in backup info block */ +#define EFUSE_OFFSET_BBLK_CHIP_ID (0x0068UL) /**< Chip ID offset in backup info block */ +#define EFUSE_OFFSET_BBLK_PRODUCT_ID (0x006EUL) /**< Product ID offset in backup info block */ +#define EFUSE_OFFSET_BBLK_FW_PUBLICKEY (0x0070UL) /**< Firmware public key offset in backup info block */ +#define EFUSE_OFFSET_BBLK_ROOT_PUBLICKEY (0x0080UL) /**< Root public key offset in backup info block */ +#define EFUSE_OFFSET_BBLK_ECC_KEY (0x0090UL) /**< ECC key offset in backup info block */ +#define EFUSE_OFFSET_BBLK_FW_KEY (0x00B0UL) /**< Firmware key offset in backup info block */ +#define EFUSE_OFFSET_BBLK_HMAC_KEY (0x00D0UL) /**< HMAC key offset in backup info block */ +#define EFUSE_OFFSET_BBLK_DATA_KEY (0x00F0UL) /**< Data key offset in backup info block */ +#define EFUSE_OFFSET_MBLK_TRIM (0x0110UL) /**< Triming offset in main info block */ +#define EFUSE_OFFSET_MBLK_CONFIG (0x014CUL) /**< Configuration offset in main info block */ +#define EFUSE_OFFSET_MBLK_SWD (0x0150UL) /**< SWD Enable offset in main info block */ +#define EFUSE_OFFSET_MBLK_EncMode (0x0152UL) /**< Encryption Mode offset in main info block */ +#define EFUSE_OFFSET_MBLK_CRC32 (0x0154UL) /**< CRC32 offset in main info block */ +#define EFUSE_OFFSET_MBLK_CHIP_ID (0x0158UL) /**< Chip ID offset in main info block */ +#define EFUSE_OFFSET_MBLK_PRODUCT_ID (0x015EUL) /**< Product ID offset in main info block */ +#define EFUSE_OFFSET_MBLK_FW_PUBLICKEY (0x0160UL) /**< Firmware public key offset in main info block */ +#define EFUSE_OFFSET_MBLK_ROOT_PUBLICKEY (0x0170UL) /**< Root public key offset in main info block */ +#define EFUSE_OFFSET_MBLK_ECC_KEY (0x0180UL) /**< ECC key offset in main info block */ +#define EFUSE_OFFSET_MBLK_FW_KEY (0x01A0UL) /**< Firmware key offset in main info block */ +#define EFUSE_OFFSET_MBLK_HMAC_KEY (0x01C0UL) /**< HMAC key offset in main info block */ +#define EFUSE_OFFSET_MBLK_DATA_KEY (0x01E0UL) /**< Data key offset in main info block */ +#define EFUSE_OFFSET_END (0x0200UL) /**< eFuse Offset end */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EFUSE_Exported_Macros EFUSE Exported Macros + * @{ + */ + +/** @brief Enable the eFuse main or backup. + * @param __HANDLE__ Specifies the eFuse Handle. + * @retval None. + */ +#define __HAL_EFUSE_ENABLE_MAIN_BACKUP(__HANDLE__) ll_efuse_enable_main_backup((__HANDLE__)->p_instance) + +/** @brief Disable the eFuse main or backup. + * @param __HANDLE__ Specifies the eFuse Handle. + * @retval None. + */ +#define __HAL_EFUSE_DISABLE_MAIN_BACKUP(__HANDLE__) ll_efuse_disable_main_backup((__HANDLE__)->p_instance) + +/** @brief Enable the eFuse PGENB. + * @param __HANDLE__ Specifies the eFuse Handle. + * @retval None. + */ +#define __HAL_EFUSE_ENABLE_PGENB(__HANDLE__) ll_efuse_enable_pgenb((__HANDLE__)->p_instance) + +/** @brief Disable the eFuse PGENB. + * @param __HANDLE__ Specifies the eFuse Handle. + * @retval None. + */ +#define __HAL_EFUSE_DISABLE_PGENB(__HANDLE__) ll_efuse_disable_pgenb((__HANDLE__)->p_instance) + +/** @brief Check whether the specified eFuse flag is set or not. + * @param __HANDLE__ specifies the eFuse Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref EFUSE_FLAG_WRITE_KEYRAM_BUSY Write keyram operation is in process + * @arg @ref EFUSE_FLAG_READ_TRIM_DONE Read trim from eFuse has done + * @arg @ref EFUSE_FLAG_CRC_CHECK_DONE eFuse CRC check done + * @arg @ref EFUSE_FLAG_CRC_CHECK_SUCCESS CRC check succeeded + * @arg @ref EFUSE_FLAG_INIT_CHECK_DONE eFuse initial value check done + * @arg @ref EFUSE_FLAG_INIT_CHECK_SUCCESS eFuse initial value check succeeded + * @arg @ref EFUSE_FLAG_WRITE_DONE eFuse one word write done + * @arg @ref EFUSE_FLAG_TEST_DONE Read from eFuse has done in test mode + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_EFUSE_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->STAT, (__FLAG__)) != 0) ? SET : RESET) +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_EFUSE_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup EFUSE_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the EFUSEx peripheral: + + (+) User must implement hal_efuse_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_efuse_init() to configure the selected device with + the selected configuration: + (++) info_mode + + (+) Call the function hal_efuse_deinit() to restore the default configuration + of the selected EFUSEx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the eFuse according to the specified parameters + * in the efuse_init_t and initialize the associated handle. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_init(efuse_handle_t *p_efuse); + +/** + **************************************************************************************** + * @brief De-initialize the eFuse peripheral. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_deinit(efuse_handle_t *p_efuse); + +/** + **************************************************************************************** + * @brief Initialize the eFuse MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_efuse_msp_deinit can be implemented in the user file. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + **************************************************************************************** + */ +void hal_efuse_msp_init(efuse_handle_t *p_efuse); + +/** + **************************************************************************************** + * @brief De-initialize the eFuse MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_efuse_msp_deinit can be implemented in the user file. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + **************************************************************************************** + */ +void hal_efuse_msp_deinit(efuse_handle_t *p_efuse); + +/** @} */ + +/** @defgroup EFUSE_Exported_Functions_Group2 IO operation functions + * @brief eFuse Data manage functions + * + * @{ + */ + +/** + **************************************************************************************** + * @brief Write the eFuse memory data. + * + * @note Address should be eFuse memory address. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * @param[in] word_offset: eFuse memory offset, unit word, this parament can be a value between: 0x00 ~ 0x80. + * @param[in] p_data: Pointer to data buffer for storage eFuse data. + * @param[in] nword: Size of data to be write, unit word. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_write(efuse_handle_t *p_efuse, uint32_t word_offset, uint32_t *p_data, uint32_t nword); + +/** + **************************************************************************************** + * @brief Read the eFuse memory data. + * + * @note Address should be eFuse memory address. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * @param[in] word_offset: eFuse memory offset, unit word, this parament can be a value between: 0x000 ~ 0x80. + * @param[in] p_data: Pointer to data buffer for storage eFuse data. + * @param[in] nword: Size of data to be read, unit word. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_read(efuse_handle_t *p_efuse, uint32_t word_offset, uint32_t *p_data, uint32_t nword); + +/** + **************************************************************************************** + * @brief Read the key from eFuse memory and write to keyram. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * @param[in] p_mask: Pointer to a KEYRAM handle which contains the configuration information for the specified KEYRAM MASK. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_write_keyram(efuse_handle_t *p_efuse, keyram_mask_t *p_mask); + +/** + **************************************************************************************** + * @brief Check the eFuse memory with 0, if memory are all 0, return HAL_OK, then return HAL_ERROR. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_initial_value_check(efuse_handle_t *p_efuse); + +/** + **************************************************************************************** + * @brief Calculate CRC of the eFuse memory data. + * + * @note Address must be main info eFuse memory address. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * @param[in] word_offset: eFuse memory offset, unit word, this parament can be a value between: 0x00 ~ 0x80. + * @param[in] nword: Size of data to be read, unit word, this parament can be a value between: 1 ~ 60. + * @param[in] p_result: Pointer to result. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_crc_calculate(efuse_handle_t *p_efuse, uint32_t word_offset, uint32_t nword, uint32_t *p_result); + +/** + **************************************************************************************** + * @brief Read trim from eFuse memory data. + * + * @note Address must be main info eFuse memory address. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * @param[in] word_offset: eFuse memory offset, unit word, this parament can be a value between: 0x00 ~ 0x80. + * @param[in] p_data: Pointer to data buffer for storage eFuse data. + * @param[in] nword: Size of data to be read, unit word, this parament can be a value between: 1 ~ 20. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_read_trim(efuse_handle_t *p_efuse, uint32_t word_offset, uint32_t *p_data, uint32_t nword); + +/** + **************************************************************************************** + * @brief Set the main or backup info of the eFuse memory. + * + * @param[in] p_efuse: Pointer to a eFuse handle which contains the configuration information for the specified eFuse module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_efuse_set_main_backup(efuse_handle_t *p_efuse); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_EFUSE_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_exflash.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_exflash.h new file mode 100644 index 0000000..7ce0992 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_exflash.h @@ -0,0 +1,778 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_exflash.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of EXFLASH HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_EXFLASH EXFLASH + * @brief exFlash HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_EXFLASH_H__ +#define __GR55xx_HAL_EXFLASH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_xqspi.h" +#include "gr55xx_hal_xqspi.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_EXFLASH_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_EXFLASH_STATE HAL EXFLASH State + * @{ + */ + +/** + * @brief HAL exFlash State Enumerations definition + */ +typedef enum +{ + HAL_EXFLASH_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_EXFLASH_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_EXFLASH_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_EXFLASH_STATE_BUSY_READ = 0x12, /**< Peripheral in indirect mode with reception ongoing */ + HAL_EXFLASH_STATE_BUSY_WRITE = 0x22, /**< Peripheral in indirect mode with transmission ongoing */ + HAL_EXFLASH_STATE_BUSY_ERASE = 0x42, /**< Peripheral in indirect mode with erase ongoing */ + HAL_EXFLASH_STATE_SUSPEND_WRITE = 0x21, /**< Peripheral in suspend mode from transmission */ + HAL_EXFLASH_STATE_SUSPEND_ERASE = 0x41, /**< Peripheral in suspend mode from erase */ + HAL_EXFLASH_STATE_ERROR = 0x04 /**< Peripheral in error */ +} hal_exflash_state_t; + +/** + * @brief HAL exFlash Security Enumerations definition + */ +typedef enum +{ + HAL_EXFLASH_UNENCRYPTED = 0x00, /**< Data will not be encrypted and decrypted in write-read operations */ + HAL_EXFLASH_ENCRYPTED = 0x01, /**< Data will be encrypted and decrypted in write-read operations */ +} hal_eflash_security; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_EXFLASH_STRUCTURES Structures + * @{ + */ + +/** @defgroup EXFLASH_HANDLE EXFLASH handle + * @{ + */ + +/** + * @brief exFlash handle Structure definition + */ +typedef struct _exflash_handle +{ + xqspi_handle_t *p_xqspi; /**< exFlash XQSPI Handle parameters */ + + __IO uint32_t fw_mode; /**< exFlash firmware mode */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_exflash_state_t state; /**< exFlash communication state */ + + __IO hal_eflash_security security; /**< exFlash data security */ + + __IO uint32_t flash_id; /**< exFlash ID */ + + __IO uint32_t flash_size; /**< exFlash Size */ + + __IO uint32_t count; /**< exFlash count for suspend and resume */ + + __IO uint32_t error_code; /**< exFlash Error code */ + + uint32_t retry; /**< Repeat times for the exFlash memory access */ + +} exflash_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_EXFLASH_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_EXFLASH_Callback Callback + * @{ + */ + +/** + * @brief HAL_EXFLASH Callback function definition + */ + +typedef struct _hal_exflash_callback +{ + void (*exflash_msp_init)(exflash_handle_t *p_exflash); /**< EXFLASH init MSP callback */ + void (*exflash_msp_deinit)(exflash_handle_t *p_exflash); /**< EXFLASH de-init MSP callback */ +} hal_exflash_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_EXFLASH_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXFLASH_EXPORTED_CONSTANTS EXFLASH Exported Constants + * @{ + */ + +/** @defgroup EXFLASH_ERROR_CODE EXFLASH Error Code + * @{ + */ +#define HAL_EXFLASH_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_EXFLASH_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_EXFLASH_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_EXFLASH_ERROR_ID ((uint32_t)0x00000003) /**< Flash ID error */ +#define HAL_EXFLASH_ERROR_QUAD ((uint32_t)0x00000004) /**< Quad mode error */ +#define HAL_EXFLASH_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +/** @} */ + +/** @defgroup EXFLASH_ERASE_TYPE EXFLASH Erase Type + * @{ + */ +#define EXFLASH_ERASE_SECTOR 0 /**< Sector erase */ +#define EXFLASH_ERASE_CHIP 1 /**< Chip erase */ +/** @} */ + +/** @defgroup EXFLASH_SIZE_INFO EXFLASH Size Information + * @{ + */ +#define EXFLASH_SIZE_PAGE_BYTES ((uint32_t)256) /**< Page size in Bytes */ +#define EXFLASH_SIZE_SECTOR_BYTES ((uint32_t)4096) /**< Sector size in Bytes */ +#define EXFLASH_SIZE_CHIP_BYTES ((uint32_t)0x800000) /**< Chip size in Bytes */ +#define EXFLASH_START_ADDR FLASH_BASE /**< Flash start address */ +#define EXFLASH_SIZE (0x00800000UL) /**< Flash size */ +#define EXFLASH_END_ADDR (EXFLASH_START_ADDR + EXFLASH_SIZE) /**< Flash end address */ +#define EXFLASH_ALIAS_OFFSET (0x02000000UL) /**< Alias address offset */ +#define EXFLASH_ALIAS_ADDR (EXFLASH_START_ADDR + EXFLASH_ALIAS_OFFSET) /**< Alias start address */ +/** @} */ + +/** @defgroup EXFLASH_LOCK_AREA_TYPE EXFLASH Lock Area Type + * @{ + */ +#define EXFLASH_LOCK_AREA_NONE 0 /**< Offset NONE */ +#define EXFLASH_LOCK_AREA_UPPER_1_8 1 /**< Offset 0x070000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_1_4 2 /**< Offset 0x060000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_1_2 3 /**< Offset 0x040000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_LOWER_1_8 9 /**< Offset 0x000000 - 0x00FFFF */ +#define EXFLASH_LOCK_AREA_LOWER_1_4 10 /**< Offset 0x000000 - 0x01FFFF */ +#define EXFLASH_LOCK_AREA_LOWER_1_2 11 /**< Offset 0x000000 - 0x03FFFF */ +#define EXFLASH_LOCK_AREA_ALL 12 /**< Offset 0x000000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_TOP_4K 17 /**< Offset 0x07F000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_TOP_8K 18 /**< Offset 0x07E000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_TOP_16K 19 /**< Offset 0x07C000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_TOP_32K 20 /**< Offset 0x078000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_BOTTOM_4K 25 /**< Offset 0x000000 - 0x000FFF */ +#define EXFLASH_LOCK_AREA_BOTTOM_8K 26 /**< Offset 0x000000 - 0x001FFF */ +#define EXFLASH_LOCK_AREA_BOTTOM_16K 27 /**< Offset 0x000000 - 0x003FFF */ +#define EXFLASH_LOCK_AREA_BOTTOM_32K 28 /**< Offset 0x000000 - 0x007FFF */ +#define EXFLASH_LOCK_AREA_LOWER_7_8 33 /**< Offset 0x070000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_LOWER_3_4 34 /**< Offset 0x060000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_7_8 41 /**< Offset 0x000000 - 0x00FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_3_4 42 /**< Offset 0x000000 - 0x01FFFF */ +#define EXFLASH_LOCK_AREA_LOWER_127_128 49 /**< Offset 0x000000 - 0x07EFFF */ +#define EXFLASH_LOCK_AREA_LOWER_63_64 50 /**< Offset 0x000000 - 0x07DFFF */ +#define EXFLASH_LOCK_AREA_LOWER_31_32 51 /**< Offset 0x000000 - 0x07BFFF */ +#define EXFLASH_LOCK_AREA_LOWER_15_16 52 /**< Offset 0x000000 - 0x077FFF */ +#define EXFLASH_LOCK_AREA_UPPER_127_128 57 /**< Offset 0x001000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_63_64 58 /**< Offset 0x002000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_31_32 59 /**< Offset 0x004000 - 0x07FFFF */ +#define EXFLASH_LOCK_AREA_UPPER_15_16 60 /**< Offset 0x008000 - 0x07FFFF */ +/** @} */ + +/** @defgroup EXFLASH_RETRY_DEFINITION EXFLASH Repeat Times definition + * @{ + */ +#define HAL_EXFLASH_RETRY_DEFAULT_VALUE ((uint32_t)400000) /**< 400000 times */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXFLASH_EXPORTED_MACROS EXFLASH Exported Macros + * @{ + */ + +/** @brief Reset exFlash handle states. + * @param __HANDLE__ exFlash handle. + * @retval None + */ +#define __HAL_EXFLASH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_EXFLASH_STATE_RESET) + +/** @brief Enable the specified exFlash power. + * @retval None + */ +#define __HAL_EXFLASH_POWER_ON() ll_xqspi_enable_exflash_power() + +/** @brief Disable the specified exFlash power. + * @retval None + */ +#define __HAL_EXFLASH_POWER_OFF() ll_xqspi_disable_exflash_power() + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup EXFLASH_PRIVATE_MACRO EXFLASH Private Macros + * @{ + */ + +/** + * @brief Check if exFlash erase type is valid. + * @param __TYPE__ exFlash erase type. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_EXFLASH_ERASE_TYPE(__TYPE__) (((__TYPE__) == EXFLASH_ERASE_SECTOR) || \ + ((__TYPE__) == EXFLASH_ERASE_CHIP)) + +/** + * @brief Check if exFlash lock area type is valid. + * @param __AREA__ exFlash lock area type. + * @retval SET (__AREA__ is valid) or RESET (__AREA__ is invalid) + */ +#define IS_EXFLASH_LOCK_AREA(__AREA__) (((__AREA__) == EXFLASH_LOCK_AREA_NONE) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_1_8) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_1_4) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_1_2) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_1_8) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_1_4) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_1_2) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_ALL) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_TOP_4K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_TOP_8K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_TOP_16K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_TOP_32K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_BOTTOM_4K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_BOTTOM_8K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_BOTTOM_16K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_BOTTOM_32K) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_7_8) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_3_4) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_7_8) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_3_4) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_127_128) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_63_64) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_31_32) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_LOWER_15_16) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_127_128) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_63_64) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_31_32) || \ + ((__AREA__) == EXFLASH_LOCK_AREA_UPPER_15_16)) +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_EXFLASH_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup EXFLASH_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the exFlash peripheral: + + (+) User must implement hal_exflash_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_exflash_deinit() to restore the default configuration + of the selected exFlash peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the exFlash according to the specified parameters + * in the exflash_init_t and initialize the associated handle. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_init(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief De-initialize the exFlash peripheral. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_deinit(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Initialize the exFlash MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_exflash_msp_deinit can be implemented in the user file. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + **************************************************************************************** + */ +void hal_exflash_msp_init(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief De-initialize the exFlash MSP. + * + * @note This function should not be modified. When the callback is needed, + * the hal_exflash_msp_deinit can be implemented in the user file. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + **************************************************************************************** + */ +void hal_exflash_msp_deinit(exflash_handle_t *p_exflash); + +/** @} */ + +/** @defgroup EXFLASH_EXPORTED_FUNCTIONS_GROUP2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the exFlash + data transfers. + + [..] The exFlash supports XIP and QSPI mode: + + (#) There are only one modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + +@endverbatim + * @{ + */ +/** + **************************************************************************************** + * @brief During Flash erase/write operation, Disable external interrupts with a priority less than or equal to base_priority in the system. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] base_priority: Base Priority value to set. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_operation_protection(exflash_handle_t *p_exflash, uint32_t base_priority); + +/** + **************************************************************************************** + * @brief Write an amount of data with specified instruction and address to flash. + * + * @note This function is used only in Indirect Write Mode. In secure mode, address alignment requires 4 bytes. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] addr: Address to write data in flash, start at @ref EXFLASH_START_ADDR. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Size of buffer bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_write(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data with specified instruction and address from flash. + * + * @note This function is used only in non-encrypted Indirect Read Mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] addr: Address to read data in flash, start at @ref EXFLASH_START_ADDR. + * @param[out] p_data: Pointer to data buffer + * @param[in] size: Size of buffer bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_read(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); + +/** + **************************************************************************************** + * @brief [High speed]Read an amount of data with specified instruction and address from flash. + * + * @note This function is used only in non-encrypted Indirect Read Mode. + * Data content needs to be processed in 4-byte reverse order. + * And all parameters need to be aligned with 4 bytes. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] addr: Address to read data in flash, start at @ref EXFLASH_START_ADDR.(Aligned with 4 bytes) + * @param[out] p_data: Pointer to data buffer.(Pointer aligned with 4 bytes) + * @param[in] size: Size of buffer bytes.number of bytes to read.(A multiple of 4) + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_read_align_word(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); + +/** + **************************************************************************************** + * @brief Erase flash region. + * + * @note All sectors that have address in range of [addr, addr+len] will be erased. If addr is not sector aligned, + * preceding data on the sector that addr belongs to will also be erased. If (addr + size) is not sector + * aligned, the whole sector will also be erased. If erase_type is @ref EXFLASH_ERASE_CHIP , all data in flash + * will be erased ignored addr and size. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] erase_type: Erase flash with page/sector/chip. + * @arg @ref EXFLASH_ERASE_SECTOR + * @arg @ref EXFLASH_ERASE_CHIP + * @param[in] addr: Address to erased data in flash, start at @ref EXFLASH_START_ADDR. + * @param[in] size: Size of erased bytes. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_erase(exflash_handle_t *p_exflash, uint32_t erase_type, uint32_t addr, uint32_t size); + +/** + **************************************************************************************** + * @brief Suspend flash pragram/erase. + * + * @note The Suspend instruction interrupts a Page Program, Sector Erase, or Block Erase operation to allow access + * to the memory array. After the program or erase operation has entered the suspended state, the memory + * array can be read except for the page being programmed or the sector or block being erased. This function + * is only used in XIP mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_suspend(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Resume flash pragram/erase. + * + * @note The Resume instruction resumes a suspended Page Program, Sector Erase, or Block Erase operation. + * Before issuing the Resume instruction to restart a suspended erase operation, make sure that there is no + * Page Program operation in progress. This function is only used in XIP mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_resume(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Lock area of flash to be software protected against Write and Erase operation. + * + * @note Locked area only to be read. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] lock_type Area need to lock + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_lock(exflash_handle_t *p_exflash, uint32_t lock_type); + +/** + **************************************************************************************** + * @brief Unlock write/erase protected in flash. + * + * @note This function will unlock all chip. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_unlock(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief the exFlash will go to the Deep Power-Down Mode. + * + * @note This function is used only in Indirect Write Mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_deepsleep(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief exFlash will be released from Deep Power-Down Mode. + * + * @note This function is used only in Indirect Write Mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_wakeup(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Reset exFlash. exFlash will return to its default power-on state and lose all + * the current volatile settings. + * + * @note This function is used only in Indirect Write Mode. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_reset(exflash_handle_t *p_exflash); + +#if defined(ENCRYPT_ENABLE) + +/** + **************************************************************************************** + * @brief Specify the offset address and encrypted KEY address read by XIP. + * + * @param[in] p_exflash Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] read_offset The value must be 0x0 and EXFLASH_ALIAS_OFFSET. + * @param[in] key_addr The value must be FWCODEKEY_BASE_ADDR(0xA00170E0) and AESKEY_BASE_ADDR(0xA0017060). + **************************************************************************************** + */ +hal_status_t hal_exflash_encrypt_mode(exflash_handle_t *p_exflash, uint32_t read_offset, uint32_t key_addr); + +/** + **************************************************************************************** + * @brief Expand write an amount of data with specified instruction and address to flash. + * + * @note This function is used only in Indirect Write Mode. In secure mode, address alignment requires 4 bytes. + * Can specify write data to data area or code area. Need to call first hal_exflash_encrypt_mode + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] addr: Address to write data in flash, start at @ref EXFLASH_START_ADDR. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Size of buffer bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_write_expand(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); + +/** + **************************************************************************************** + * @brief Expand read an amount of data with specified instruction and address from flash. + * + * @note This function is used only in non-encrypted Indirect Read Mode. + * Can specify read data from data area or code area. Need to call first hal_exflash_encrypt_mode + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] addr: Address to read data in flash, start at @ref EXFLASH_START_ADDR. + * @param[out] p_data: Pointer to data buffer + * @param[in] size: Size of buffer bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_exflash_read_expand(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); + + + +#endif + +/** @} */ + +/** @defgroup EXFLASH_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief exFlash control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the exFlash. + (+) hal_exflash_get_state()API can be helpful to check in run-time the state of the exFlash peripheral. + (+) hal_exflash_get_error() check in run-time Errors occurring during communication. + (+) hal_exflash_set_timeout() set the timeout during internal process. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the exFlash handle state. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @retval ::HAL_EXFLASH_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_EXFLASH_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_EXFLASH_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_EXFLASH_STATE_BUSY_WRITE: Peripheral in indirect mode with transmission ongoing. + * @retval ::HAL_EXFLASH_STATE_BUSY_READ: Peripheral in indirect mode with reception ongoing. + * @retval ::HAL_EXFLASH_STATE_BUSY_ERASE: Peripheral in indirect mode with erase ongoing. + * @retval ::HAL_EXFLASH_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_exflash_state_t hal_exflash_get_state(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Return the exFlash error code. + * + * @param[in] p_exflash: Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * + * @return exFlash error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_exflash_get_error(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Set the exFlash internal process timeout value. + * + * @param[in] p_exflash Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] retry Internal process repeat times value. + **************************************************************************************** + */ +void hal_exflash_set_retry(exflash_handle_t *p_exflash, uint32_t retry); + + +/** + * @brief HAL exFlash operation function + */ +typedef hal_status_t (*exflash_operation_func)(exflash_handle_t *p_exflash); + +/** + **************************************************************************************** + * @brief Call user XIP Flash operation functon. + * + * @param[in] p_exflash Pointer to an exFlash handle which contains the configuration information for the specified exFlash module. + * @param[in] p_func_exflash_operation HAL exFlash operation function. + **************************************************************************************** + */ +hal_status_t hal_exflash_operation(exflash_handle_t *p_exflash, exflash_operation_func p_func_exflash_operation); +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_EXFLASH_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio.h new file mode 100644 index 0000000..a4d3f9a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio.h @@ -0,0 +1,477 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_gpio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of GPIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_GPIO GPIO + * @brief GPIO HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_GPIO_H__ +#define __GR55xx_HAL_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_gpio.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_GPIO_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_GPIO_Callback Callback + * @{ + */ + +/** + * @brief HAL_GPIO Callback function definition + */ + +typedef struct _hal_gpio_callback +{ + void (*gpio_callback)(gpio_regs_t *GPIOx, uint16_t gpio_pin); /**< GPIO pin detection callback */ +} hal_gpio_callback_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_GPIO_ENUMERATIONS Enumerations + * @{ + */ + +/** + * @brief GPIO Bit SET and Bit RESET Enumerations + */ +typedef enum +{ + GPIO_PIN_RESET = 0U, /**< GPIO pin low level.*/ + GPIO_PIN_SET /**< GPIO pin high level.*/ +} gpio_pin_state_t; + +/** @} */ + + +/** @addtogroup HAL_GPIO_STRUCTURES Structures + * @{ + */ + +/** + * @brief GPIO init structure definition + */ +typedef struct _gpio_init +{ + uint32_t pin; /**< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins */ + + uint32_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode */ + + uint32_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref GPIO_pull */ + + uint32_t mux; /**< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIOEx_Mux_Function_Selection. */ +} gpio_init_t; + +/** @} */ + +/** + * @defgroup HAL_GPIO_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_pins GPIO pins + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001U) /**< Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002U) /**< Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004U) /**< Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008U) /**< Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010U) /**< Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020U) /**< Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040U) /**< Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080U) /**< Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100U) /**< Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200U) /**< Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400U) /**< Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800U) /**< Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000U) /**< Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000U) /**< Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000U) /**< Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000U) /**< Pin 15 selected */ +#define GPIO_PIN_ALL ((uint16_t)0xFFFFU) /**< All pins selected */ + +#define GPIO_PIN_MASK (0x0000FFFFU) /**< PIN mask for assert test */ +/** @} */ + +/** @defgroup GPIO_mode GPIO mode + * @brief GPIO Configuration Mode + * Elements values convention: 0x000000YX + * - X : IO Direction mode (Input, Output, Mux) + * - Y : IT trigger detection + * @{ + */ +#define GPIO_MODE_INPUT (LL_GPIO_MODE_INPUT << 0) /**< Input Mode */ +#define GPIO_MODE_OUTPUT (LL_GPIO_MODE_OUTPUT << 0) /**< Output Mode */ +#define GPIO_MODE_MUX (LL_GPIO_MODE_MUX << 0) /**< Mux Mode */ +#define GPIO_MODE_IT_RISING (LL_GPIO_TRIGGER_RISING << 4) /**< Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING (LL_GPIO_TRIGGER_FALLING << 4) /**< Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_HIGH (LL_GPIO_TRIGGER_HIGH << 4) /**< Interrupt Mode with High-level trigger detection */ +#define GPIO_MODE_IT_LOW (LL_GPIO_TRIGGER_LOW << 4) /**< Interrupt Mode with Low-level trigger detection */ +/** @} */ + +/** @defgroup GPIO_pull GPIO pull + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL LL_GPIO_PULL_NO /**< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP LL_GPIO_PULL_UP /**< Pull-up activation */ +#define GPIO_PULLDOWN LL_GPIO_PULL_DOWN /**< Pull-down activation */ +/** @} */ + +/** + * @brief GPIO_default_config InitStruct default configuartion + */ +#define GPIO_DEFAULT_CONFIG \ +{ \ + .pin = GPIO_PIN_ALL, \ + .mode = GPIO_MODE_INPUT, \ + .pull = GPIO_PULLDOWN, \ + .mux = GPIO_PIN_MUX_GPIO, \ +} + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Check whether the specified GPIO pin is asserted or not. + * @param __GPIOX__ Where X can be (0, 1) to select the GPIO peripheral port + * @param __GPIO_PIN__ Specifies the GPIO pin to check. + * This parameter can be GPIO_PIN_x where x can be (0..15) + * @retval The new state of __GPIO_PIN__ (SET or RESET). + */ +#define __HAL_GPIO_IT_GET_IT(__GPIOX__, __GPIO_PIN__) ll_gpio_read_flag_it(__GPIOX__, __GPIO_PIN__) + +/** + * @brief Clear the GPIO pin pending bits. + * @param __GPIOX__ Where X can be (0, 1) to select the GPIO peripheral port + * @param __GPIO_PIN__ Specifies the GPIO pins to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_IT_CLEAR_IT(__GPIOX__, __GPIO_PIN__) ll_gpio_clear_flag_it(__GPIOX__, __GPIO_PIN__) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ + +/** + * @brief Check if GPIO pin action is valid. + * @param __ACTION__ GPIO pin action. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_GPIO_PIN_ACTION(__ACTION__) (((__ACTION__) == GPIO_PIN_RESET) || ((__ACTION__) == GPIO_PIN_SET)) + +/** + * @brief Check if GPIO pins are valid. + * @param __PIN__ GPIO pins. + * @retval SET (__PIN__ is valid) or RESET (__PIN__ is invalid) + */ +#define IS_GPIO_PIN(__PIN__) ((((__PIN__) & GPIO_PIN_MASK) != 0x00U) &&\ + (((__PIN__) & ~GPIO_PIN_MASK) == 0x00U)) + +/** + * @brief Check if GPIO mode is valid. + * @param __MODE__ GPIO mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_GPIO_MODE(__MODE__) (((__MODE__) == GPIO_MODE_INPUT) ||\ + ((__MODE__) == GPIO_MODE_OUTPUT) ||\ + ((__MODE__) == GPIO_MODE_MUX) ||\ + ((__MODE__) == GPIO_MODE_IT_RISING) ||\ + ((__MODE__) == GPIO_MODE_IT_FALLING) ||\ + ((__MODE__) == GPIO_MODE_IT_HIGH) ||\ + ((__MODE__) == GPIO_MODE_IT_LOW)) + +/** + * @brief Check if GPIO pull type is valid. + * @param __PULL__ GPIO pull type. + * @retval SET (__PULL__ is valid) or RESET (__PULL__ is invalid) + */ +#define IS_GPIO_PULL(__PULL__) (((__PULL__) == GPIO_NOPULL) ||\ + ((__PULL__) == GPIO_PULLUP) || \ + ((__PULL__) == GPIO_PULLDOWN)) + +/** @} */ + +/** @} */ + +/* Include GPIO HAL Extended module */ +#include "gr55xx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_GPIO_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and de-initialization functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the GPIOx peripheral according to the specified parameters in the p_gpio_init. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + * @param[in] p_gpio_init: Pointer to a gpio_init_t structure that contains the configuration information + * for the specified GPIO peripheral port. + **************************************************************************************** + */ +void hal_gpio_init(gpio_regs_t *GPIOx, gpio_init_t *p_gpio_init); + +/** + **************************************************************************************** + * @brief De-initialize the GPIOx peripheral registers to their default reset values. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port for GR55xx device + * @param[in] gpio_pin: Specifies the port bit to be written. + * This parameter can be a combiantion of the following values: + * @arg @ref GPIO_PIN_0 + * @arg @ref GPIO_PIN_1 + * @arg @ref GPIO_PIN_2 + * @arg @ref GPIO_PIN_3 + * @arg @ref GPIO_PIN_4 + * @arg @ref GPIO_PIN_5 + * @arg @ref GPIO_PIN_6 + * @arg @ref GPIO_PIN_7 + * @arg @ref GPIO_PIN_8 + * @arg @ref GPIO_PIN_9 + * @arg @ref GPIO_PIN_10 + * @arg @ref GPIO_PIN_11 + * @arg @ref GPIO_PIN_12 + * @arg @ref GPIO_PIN_13 + * @arg @ref GPIO_PIN_14 + * @arg @ref GPIO_PIN_15 + * @arg @ref GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_gpio_deinit(gpio_regs_t *GPIOx, uint32_t gpio_pin); + +/** @} */ + +/** @addtogroup GPIO_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Read the specified input port pin. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + * @param[in] gpio_pin: Specifies the port bit to be read. + * This parameter can be a one of the following values: + * @arg @ref GPIO_PIN_0 + * @arg @ref GPIO_PIN_1 + * @arg @ref GPIO_PIN_2 + * @arg @ref GPIO_PIN_3 + * @arg @ref GPIO_PIN_4 + * @arg @ref GPIO_PIN_5 + * @arg @ref GPIO_PIN_6 + * @arg @ref GPIO_PIN_7 + * @arg @ref GPIO_PIN_8 + * @arg @ref GPIO_PIN_9 + * @arg @ref GPIO_PIN_10 + * @arg @ref GPIO_PIN_11 + * @arg @ref GPIO_PIN_12 + * @arg @ref GPIO_PIN_13 + * @arg @ref GPIO_PIN_14 + * @arg @ref GPIO_PIN_15 + * + * @retval ::GPIO_PIN_RESET: GPIO pin low level. + * @retval ::GPIO_PIN_SET: GPIO pin high level. + **************************************************************************************** + */ +gpio_pin_state_t hal_gpio_read_pin(gpio_regs_t *GPIOx, uint16_t gpio_pin); + +/** + **************************************************************************************** + * @brief Set or clear the selected data port bit. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + * @param[in] gpio_pin: Specifies the port bit to be written. + * This parameter can be a combiantion of the following values: + * @arg @ref GPIO_PIN_0 + * @arg @ref GPIO_PIN_1 + * @arg @ref GPIO_PIN_2 + * @arg @ref GPIO_PIN_3 + * @arg @ref GPIO_PIN_4 + * @arg @ref GPIO_PIN_5 + * @arg @ref GPIO_PIN_6 + * @arg @ref GPIO_PIN_7 + * @arg @ref GPIO_PIN_8 + * @arg @ref GPIO_PIN_9 + * @arg @ref GPIO_PIN_10 + * @arg @ref GPIO_PIN_11 + * @arg @ref GPIO_PIN_12 + * @arg @ref GPIO_PIN_13 + * @arg @ref GPIO_PIN_14 + * @arg @ref GPIO_PIN_15 + * @arg @ref GPIO_PIN_ALL + * @param[in] pin_state: Specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg @ref GPIO_PIN_RESET clear the port pin + * @arg @ref GPIO_PIN_SET set the port pin + **************************************************************************************** + */ +void hal_gpio_write_pin(gpio_regs_t *GPIOx, uint16_t gpio_pin, gpio_pin_state_t pin_state); + +/** + **************************************************************************************** + * @brief Toggle the specified GPIO pin. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + * @param[in] gpio_pin: Specifies the pin to be toggled. + * This parameter can be a combiantion of the following values: + * @arg @ref GPIO_PIN_0 + * @arg @ref GPIO_PIN_1 + * @arg @ref GPIO_PIN_2 + * @arg @ref GPIO_PIN_3 + * @arg @ref GPIO_PIN_4 + * @arg @ref GPIO_PIN_5 + * @arg @ref GPIO_PIN_6 + * @arg @ref GPIO_PIN_7 + * @arg @ref GPIO_PIN_8 + * @arg @ref GPIO_PIN_9 + * @arg @ref GPIO_PIN_10 + * @arg @ref GPIO_PIN_11 + * @arg @ref GPIO_PIN_12 + * @arg @ref GPIO_PIN_13 + * @arg @ref GPIO_PIN_14 + * @arg @ref GPIO_PIN_15 + * @arg @ref GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_gpio_toggle_pin(gpio_regs_t *GPIOx, uint16_t gpio_pin); + +/** @} */ + +/** @addtogroup GPIO_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle GPIO interrupt request. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + **************************************************************************************** + */ +void hal_gpio_exti_irq_handler(gpio_regs_t *GPIOx); + +/** + **************************************************************************************** + * @brief GPIO pin detection callback. + * + * @note This function should not be modified. When the callback is needed, + * the hal_gpio_exti_callback can be implemented in the user file. + * + * @param[in] GPIOx: Where x can be (0, 1) to select the GPIO peripheral port + * @param[in] gpio_pin: Indicate the port pin whose interrupt was triggered. + * This parameter can be a combiantion of the following values: + * @arg @ref GPIO_PIN_0 + * @arg @ref GPIO_PIN_1 + * @arg @ref GPIO_PIN_2 + * @arg @ref GPIO_PIN_3 + * @arg @ref GPIO_PIN_4 + * @arg @ref GPIO_PIN_5 + * @arg @ref GPIO_PIN_6 + * @arg @ref GPIO_PIN_7 + * @arg @ref GPIO_PIN_8 + * @arg @ref GPIO_PIN_9 + * @arg @ref GPIO_PIN_10 + * @arg @ref GPIO_PIN_11 + * @arg @ref GPIO_PIN_12 + * @arg @ref GPIO_PIN_13 + * @arg @ref GPIO_PIN_14 + * @arg @ref GPIO_PIN_15 + * @arg @ref GPIO_PIN_ALL + **************************************************************************************** + */ +void hal_gpio_exti_callback(gpio_regs_t *GPIOx, uint16_t gpio_pin); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_GPIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio_ex.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio_ex.h new file mode 100644 index 0000000..3a99c44 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_gpio_ex.h @@ -0,0 +1,497 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_gpio_ex.h + * @author BLE Driver Team + * @brief Header file containing extended macro of GPIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_GPIOEx GPIOEx + * @brief GPIOEx HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_GPIO_EX_H__ +#define __GR55xx_HAL_GPIO_EX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_gpio.h" + +/* Exported types ------------------------------------------------------------*/ + +/** + * @defgroup HAL_GPIOEX_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants + * @{ + */ + +/** @defgroup GPIOEx_Mux_Mode GPIOEx Mux Mode definition + * @{ + */ +#define GPIO_MUX_0 LL_GPIO_MUX_0 /**< GPIO Mux mode 0 */ +#define GPIO_MUX_1 LL_GPIO_MUX_1 /**< GPIO Mux mode 1 */ +#define GPIO_MUX_2 LL_GPIO_MUX_2 /**< GPIO Mux mode 2 */ +#define GPIO_MUX_3 LL_GPIO_MUX_3 /**< GPIO Mux mode 3 */ +#define GPIO_MUX_4 LL_GPIO_MUX_4 /**< GPIO Mux mode 4 */ +#define GPIO_MUX_5 LL_GPIO_MUX_5 /**< GPIO Mux mode 5 */ +#define GPIO_MUX_6 LL_GPIO_MUX_6 /**< GPIO Mux mode 6 */ +#define GPIO_MUX_7 LL_GPIO_MUX_7 /**< GPIO Mux mode 7 */ +#define GPIO_MUX_8 LL_GPIO_MUX_8 /**< GPIO Mux mode 8 */ +/** @} */ + +/** @defgroup GPIOEx_Mux_Function_Selection GPIOEx Mux function selection + * @{ + */ + +#if defined (GR551xx) +/*---------------------------------- GR551xx ------------------------------*/ + +/** @defgroup GPIOEx_Common_Selection GPIO PIN common MUX selection(Available for all GPIO pins) + * @{ + */ +#define GPIO_PIN_MUX_TESTBUS GPIO_MUX_8 /**< GPIO PIN x Mux Select TESTBUS */ + +#define GPIO_PIN_MUX_GPIO GPIO_MUX_7 /**< GPIO PIN x Mux Select GPIO */ + +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN0_Mux_Selection GPIO0_PIN0 MUX selection + * @{ + */ +#define GPIO0_PIN0_MUX_SWD_CLK GPIO_MUX_0 /**< GPIO0_PIN0 Mux Select SWD_CLK */ +#define GPIO0_PIN0_MUX_I2C0_SCL GPIO_MUX_1 /**< GPIO0_PIN0 Mux Select I2C0_SCL */ +#define GPIO0_PIN0_MUX_I2C1_SCL GPIO_MUX_2 /**< GPIO0_PIN0 Mux Select I2C1_SCL */ +#define GPIO0_PIN0_MUX_UART1_RTS GPIO_MUX_3 /**< GPIO0_PIN0 Mux Select UART1_RTS */ +#define GPIO0_PIN0_MUX_UART0_TX GPIO_MUX_4 /**< GPIO0_PIN0 Mux Select UART0_TX */ +#define GPIO0_PIN0_MUX_UART1_TX GPIO_MUX_5 /**< GPIO0_PIN0 Mux Select UART1_TX */ +#define GPIO0_PIN0_MUX_UART0_RTS GPIO_MUX_6 /**< GPIO0_PIN0 Mux Select UART0_RTS */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN1_Mux_Selection GPIO0_PIN1 MUX selection + * @{ + */ +#define GPIO0_PIN1_MUX_SWD_IO GPIO_MUX_0 /**< GPIO0_PIN1 Mux Select SWD_IO */ +#define GPIO0_PIN1_MUX_I2C0_SDA GPIO_MUX_1 /**< GPIO0_PIN1 Mux Select I2C0_SDA */ +#define GPIO0_PIN1_MUX_I2C1_SDA GPIO_MUX_2 /**< GPIO0_PIN1 Mux Select I2C1_SDA */ +#define GPIO0_PIN1_MUX_UART1_CTS GPIO_MUX_3 /**< GPIO0_PIN1 Mux Select UART1_CTS */ +#define GPIO0_PIN1_MUX_UART0_RX GPIO_MUX_4 /**< GPIO0_PIN1 Mux Select UART0_RX */ +#define GPIO0_PIN1_MUX_UART1_RX GPIO_MUX_5 /**< GPIO0_PIN1 Mux Select UART1_RX */ +#define GPIO0_PIN1_MUX_UART0_CTS GPIO_MUX_6 /**< GPIO0_PIN1 Mux Select UART0_CTS */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN2_Mux_Selection GPIO0_PIN2 MUX selection + * @{ + */ +#define GPIO0_PIN2_MUX_UART0_CTS GPIO_MUX_0 /**< GPIO0_PIN2 Mux Select UART0_CTS */ +#define GPIO0_PIN2_MUX_SIM_PRESENCE GPIO_MUX_1 /**< GPIO0_PIN2 Mux Select SIM_PRESENCE */ +#define GPIO0_PIN2_MUX_SWV GPIO_MUX_2 /**< GPIO0_PIN2 Mux Select SWV */ +#define GPIO0_PIN2_MUX_SPIS_CS_N GPIO_MUX_3 /**< GPIO0_PIN2 Mux Select SPIS_CS_N */ +#define GPIO0_PIN2_MUX_I2C0_SDA GPIO_MUX_4 /**< GPIO0_PIN2 Mux Select I2C0_SDA */ +#define GPIO0_PIN2_MUX_PWM0_A GPIO_MUX_5 /**< GPIO0_PIN2 Mux Select PWM0_A */ +#define GPIO0_PIN2_MUX_FERP_TRIG GPIO_MUX_6 /**< GPIO0_PIN2 Mux Select FERP_TRIG */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN3_Mux_Selection GPIO0_PIN3 MUX selection + * @{ + */ +#define GPIO0_PIN3_MUX_UART0_TX GPIO_MUX_0 /**< GPIO0_PIN3 Mux Select UART0_TX */ +#define GPIO0_PIN3_MUX_SIM_RST_N GPIO_MUX_1 /**< GPIO0_PIN3 Mux Select SIM_RST_N */ +#define GPIO0_PIN3_MUX_SPIM_CLK GPIO_MUX_2 /**< GPIO0_PIN3 Mux Select SPIM_CLK */ +#define GPIO0_PIN3_MUX_SPIS_CLK GPIO_MUX_3 /**< GPIO0_PIN3 Mux Select SPIS_CLK */ +#define GPIO0_PIN3_MUX_SPIM_CS1 GPIO_MUX_4 /**< GPIO0_PIN3 Mux Select SPIM_CS1 */ +#define GPIO0_PIN3_MUX_PWM0_B GPIO_MUX_5 /**< GPIO0_PIN3 Mux Select PWM0_B */ +#define GPIO0_PIN3_MUX_COEX_BLE_TX GPIO_MUX_6 /**< GPIO0_PIN3 Mux Select COEX_BLE_TX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN4_Mux_Selection GPIO0_PIN4 MUX selection + * @{ + */ +#define GPIO0_PIN4_MUX_UART0_RX GPIO_MUX_0 /**< GPIO0_PIN4 Mux Select UART0_RX */ +#define GPIO0_PIN4_MUX_SIM_IO GPIO_MUX_1 /**< GPIO0_PIN4 Mux Select SIM_IO */ +#define GPIO0_PIN4_MUX_SPIM_MOSI GPIO_MUX_2 /**< GPIO0_PIN4 Mux Select SPIM_MOSI */ +#define GPIO0_PIN4_MUX_SPIS_MISO GPIO_MUX_3 /**< GPIO0_PIN4 Mux Select SPIS_MISO */ +#define GPIO0_PIN4_MUX_SPIM_CS0 GPIO_MUX_4 /**< GPIO0_PIN4 Mux Select SPIM_CS0 */ +#define GPIO0_PIN4_MUX_PWM0_C GPIO_MUX_5 /**< GPIO0_PIN3 Mux Select PWM0_C */ +#define GPIO0_PIN4_MUX_COEX_BLE_RX GPIO_MUX_6 /**< GPIO0_PIN4 Mux Select COEX_BLE_RX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN5_Mux_Selection GPIO0_PIN5 MUX selection + * @{ + */ +#define GPIO0_PIN5_MUX_UART0_RTS GPIO_MUX_0 /**< GPIO0_PIN5 Mux Select UART0_RTS */ +#define GPIO0_PIN5_MUX_SIM_CLK GPIO_MUX_1 /**< GPIO0_PIN5 Mux Select SIM_CLK */ +#define GPIO0_PIN5_MUX_SPIM_MISO GPIO_MUX_2 /**< GPIO0_PIN5 Mux Select SPIM_MISO */ +#define GPIO0_PIN5_MUX_SPIS_MOSI GPIO_MUX_3 /**< GPIO0_PIN5 Mux Select SPIS_MOSI */ +//#define GPIO0_PIN5_MUX_SPIM_MISO GPIO_MUX_4 /**< GPIO0_PIN5 Mux Select SPIM_MISO */ +#define GPIO0_PIN5_MUX_I2C0_SCL GPIO_MUX_5 /**< GPIO0_PIN5 Mux Select I2C0_SCL */ +#define GPIO0_PIN5_MUX_COEX_WLAN_TX GPIO_MUX_6 /**< GPIO0_PIN5 Mux Select COEX_WLAN_TX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN6_Mux_Selection GPIO0_PIN6 MUX selection + * @{ + */ +#define GPIO0_PIN6_MUX_I2SM_WS GPIO_MUX_0 /**< GPIO0_PIN6 Mux Select I2S_WS */ +#define GPIO0_PIN6_MUX_I2SS_WS GPIO_MUX_1 /**< GPIO0_PIN6 Mux Select I2S_S_WS */ +#define GPIO0_PIN6_MUX_SPIM_CS0 GPIO_MUX_2 /**< GPIO0_PIN6 Mux Select SPIM_CS0 */ +#define GPIO0_PIN6_MUX_UART1_RX GPIO_MUX_3 /**< GPIO0_PIN6 Mux Select UART1_RX */ +#define GPIO0_PIN6_MUX_SPIM_MOSI GPIO_MUX_4 /**< GPIO0_PIN6 Mux Select SPIM_MOSI */ +#define GPIO0_PIN6_MUX_I2C0_SDA GPIO_MUX_5 /**< GPIO0_PIN6 Mux Select I2C0_SDA */ +#define GPIO0_PIN6_MUX_COEX_WLAN_RX GPIO_MUX_6 /**< GPIO0_PIN6 Mux Select COEX_WLAN_RX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN7_Mux_Selection GPIO0_PIN7 MUX selection + * @{ + */ +#define GPIO0_PIN7_MUX_I2SM_TX_SDO GPIO_MUX_0 /**< GPIO0_PIN7 Mux Select I2SM_TX_SDO */ +#define GPIO0_PIN7_MUX_I2SS_TX_SDO GPIO_MUX_1 /**< GPIO0_PIN7 Mux Select I2SS_TX_SDO */ +#define GPIO0_PIN7_MUX_SPIM_CS1 GPIO_MUX_2 /**< GPIO0_PIN7 Mux Select SPIM_CS1 */ +#define GPIO0_PIN7_MUX_UART1_TX GPIO_MUX_3 /**< GPIO0_PIN7 Mux Select UART1_TX */ +#define GPIO0_PIN7_MUX_SPIM_CLK GPIO_MUX_4 /**< GPIO0_PIN7 Mux Select SPIM_CLK */ +#define GPIO0_PIN7_MUX_PWM1_A GPIO_MUX_5 /**< GPIO0_PIN7 Mux Select PWM1_A */ +#define GPIO0_PIN7_MUX_COEX_BLE_PROC GPIO_MUX_6 /**< GPIO0_PIN7 Mux Select COEX_BLE_PROC */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN8_Mux_Selection GPIO0_PIN8 MUX selection + * @{ + */ +#define GPIO0_PIN8_MUX_XQSPIM_IO_0 GPIO_MUX_0 /**< GPIO0_PIN8 Mux Select XQSPIM_IO_0 */ +#define GPIO0_PIN8_MUX_I2C1_SDA GPIO_MUX_1 /**< GPIO0_PIN8 Mux Select I2C1_SDA */ +#define GPIO0_PIN8_MUX_QSPIM1_IO_0 GPIO_MUX_2 /**< GPIO0_PIN8 Mux Select QSPIM1_IO_0 */ +#define GPIO0_PIN8_MUX_UART1_RX GPIO_MUX_3 /**< GPIO0_PIN8 Mux Select UART1_RX */ +#define GPIO0_PIN8_MUX_PWM1_B GPIO_MUX_5 /**< GPIO0_PIN8 Mux Select PWM1_B */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN9_Mux_Selection GPIO0_PIN9 MUX selection + * @{ + */ +#define GPIO0_PIN9_MUX_XQSPIM_CLK GPIO_MUX_0 /**< GPIO0_PIN9 Mux Select XQSPIM_CLK */ +#define GPIO0_PIN9_MUX_I2C1_SCL GPIO_MUX_1 /**< GPIO0_PIN9 Mux Select I2C1_SCL */ +#define GPIO0_PIN9_MUX_QSPIM1_CLK GPIO_MUX_2 /**< GPIO0_PIN9 Mux Select QSPIM1_CLK */ +#define GPIO0_PIN9_MUX_UART1_TX GPIO_MUX_3 /**< GPIO0_PIN9 Mux Select UART1_TX */ +#define GPIO0_PIN9_MUX_PWM1_C GPIO_MUX_5 /**< GPIO0_PIN9 Mux Select PWM1_C */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN10_Mux_Selection GPIO0_PIN10 MUX selection + * @{ + */ +#define GPIO0_PIN10_MUX_I2SM_RX_SDI GPIO_MUX_0 /**< GPIO0_PIN10 Mux Select I2SM_RX_SDI */ +#define GPIO0_PIN10_MUX_I2SS_RX_SDI GPIO_MUX_1 /**< GPIO0_PIN10 Mux Select I2SS_RX_SDI */ +#define GPIO0_PIN10_MUX_UART0_TX GPIO_MUX_2 /**< GPIO0_PIN10 Mux Select UART0_TX */ +#define GPIO0_PIN10_MUX_I2C0_SCL GPIO_MUX_4 /**< GPIO0_PIN10 Mux Select I2C0_SCL */ +#define GPIO0_PIN10_MUX_PWM1_B GPIO_MUX_5 /**< GPIO0_PIN10 Mux Select PWM1_B */ +#define GPIO0_PIN10_MUX_COEX_BLE_TX GPIO_MUX_6 /**< GPIO0_PIN10 Mux Select COEX_BLE_TX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN11_Mux_Selection GPIO0_PIN11 MUX selection + * @{ + */ +#define GPIO0_PIN11_MUX_I2SM_SCLK GPIO_MUX_0 /**< GPIO0_PIN10 Mux Select I2SM_SCLK */ +#define GPIO0_PIN11_MUX_I2SS_SCLK GPIO_MUX_1 /**< GPIO0_PIN10 Mux Select I2SS_SCLK */ +#define GPIO0_PIN11_MUX_UART0_RX GPIO_MUX_2 /**< GPIO0_PIN10 Mux Select UART0_RX */ +#define GPIO0_PIN11_MUX_I2C0_SDA GPIO_MUX_4 /**< GPIO0_PIN10 Mux Select I2C0_SDA */ +#define GPIO0_PIN11_MUX_PWM1_C GPIO_MUX_5 /**< GPIO0_PIN10 Mux Select PWM1_C */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN12_Mux_Selection GPIO0_PIN12 MUX selection + * @{ + */ +#define GPIO0_PIN12_MUX_XQSPIM_IO_3 GPIO_MUX_0 /**< GPIO0_PIN12 Mux Select XQSPIM_IO_3 */ +#define GPIO0_PIN12_MUX_SPIM_CLK GPIO_MUX_1 /**< GPIO0_PIN12 Mux Select SPIM_CLK */ +#define GPIO0_PIN12_MUX_QSPIM1_IO3 GPIO_MUX_2 /**< GPIO0_PIN12 Mux Select QSPIM1_IO3 */ +#define GPIO0_PIN12_MUX_SIM_PRESENCE GPIO_MUX_3 /**< GPIO0_PIN12 Mux Select SIM_PRESENCE */ +#define GPIO0_PIN12_MUX_I2SM_WS GPIO_MUX_4 /**< GPIO0_PIN12 Mux Select I2SM_WS */ +#define GPIO0_PIN12_MUX_I2SS_WS GPIO_MUX_5 /**< GPIO0_PIN12 Mux Select I2SS_WS */ +#define GPIO0_PIN12_MUX_SPIS_CS GPIO_MUX_6 /**< GPIO0_PIN12 Mux Select I2SS_WS */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN13_Mux_Selection GPIO0_PIN13 MUX selection + * @{ + */ +#define GPIO0_PIN13_MUX_XQSPIM_IO_2 GPIO_MUX_0 /**< GPIO0_PIN13 Mux Select XQSPIM_IO_2 */ +#define GPIO0_PIN13_MUX_SPIM_MOSI GPIO_MUX_1 /**< GPIO0_PIN13 Mux Select SPIM_MOSI */ +#define GPIO0_PIN13_MUX_QSPIM1_IO_2 GPIO_MUX_2 /**< GPIO0_PIN13 Mux Select QSPIM1_IO_2 */ +#define GPIO0_PIN13_MUX_SIM_RST_N GPIO_MUX_3 /**< GPIO0_PIN13 Mux Select SIM_RST_N */ +#define GPIO0_PIN13_MUX_I2SM_TX_SDO GPIO_MUX_4 /**< GPIO0_PIN13 Mux Select I2SM_TX_SDO */ +#define GPIO0_PIN13_MUX_I2SS_TX_SDO GPIO_MUX_5 /**< GPIO0_PIN13 Mux Select I2SS_TX_SDO */ +#define GPIO0_PIN13_MUX_SPIS_CLK GPIO_MUX_6 /**< GPIO0_PIN13 Mux Select SPIS_CLK */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN14_Mux_Selection GPIO0_PIN14 MUX selection + * @{ + */ +#define GPIO0_PIN14_MUX_XQSPIM_IO_1 GPIO_MUX_0 /**< GPIO0_PIN14 Mux Select XQSPIM_IO_1 */ +#define GPIO0_PIN14_MUX_SPIM_MISO GPIO_MUX_1 /**< GPIO0_PIN14 Mux Select SPIM_MISO */ +#define GPIO0_PIN14_MUX_QSPIM1_IO1 GPIO_MUX_2 /**< GPIO0_PIN14 Mux Select QSPIM1_IO1 */ +#define GPIO0_PIN14_MUX_SIM_IO GPIO_MUX_3 /**< GPIO0_PIN14 Mux Select SIM_IO */ +#define GPIO0_PIN14_MUX_I2SM_RX_SDI GPIO_MUX_4 /**< GPIO0_PIN14 Mux Select I2SM_RX_SDI */ +#define GPIO0_PIN14_MUX_I2SS_RX_SDI GPIO_MUX_5 /**< GPIO0_PIN14 Mux Select I2SS_RX_SDI */ +#define GPIO0_PIN14_MUX_SPIS_MISO GPIO_MUX_6 /**< GPIO0_PIN14 Mux Select SPIS_MISO */ +/** @} */ + +/** @defgroup GPIOEx_GPIO0_PIN15_Mux_Selection GPIO0_PIN15 MUX selection + * @{ + */ +#define GPIO0_PIN15_MUX_XQSPIM_CS_N GPIO_MUX_0 /**< GPIO0_PIN15 Mux Select QSPIM_CS_N */ +#define GPIO0_PIN15_MUX_SPIM_CS0 GPIO_MUX_1 /**< GPIO0_PIN15 Mux Select SPIM_CS0 */ +#define GPIO0_PIN15_MUX_QSPIM1_CS_N GPIO_MUX_2 /**< GPIO0_PIN15 Mux Select QSPIM1_CS_N */ +#define GPIO0_PIN15_MUX_SIM_CLK GPIO_MUX_3 /**< GPIO0_PIN15 Mux Select SIM_CLK */ +#define GPIO0_PIN15_MUX_I2SM_SCLK GPIO_MUX_4 /**< GPIO0_PIN15 Mux Select I2SM_SCLK */ +#define GPIO0_PIN15_MUX_I2SS_SCLK GPIO_MUX_5 /**< GPIO0_PIN15 Mux Select I2SS_SCLK */ +#define GPIO0_PIN15_MUX_SPIS_MOSI GPIO_MUX_6 /**< GPIO0_PIN15 Mux Select SPIS_MOSI */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN0_Mux_Selection GPIO1_PIN0 MUX selection + * @{ + */ +#define GPIO1_PIN0_MUX_SPIM_MISO GPIO_MUX_0 /**< GPIO1_PIN0 Mux Select SPIM_MISO */ +#define GPIO1_PIN0_MUX_SPIS_MOSI GPIO_MUX_1 /**< GPIO1_PIN0 Mux Select SPIS_MOSI */ +#define GPIO1_PIN0_MUX_SIM_IO GPIO_MUX_2 /**< GPIO1_PIN0 Mux Select SIM_IO */ +#define GPIO1_PIN0_MUX_I2SM_RX_SDI GPIO_MUX_3 /**< GPIO1_PIN0 Mux Select I2SM_RX_SDI */ +#define GPIO1_PIN0_MUX_I2SS_RX_SDI GPIO_MUX_4 /**< GPIO1_PIN0 Mux Select I2SS_RX_SDI */ +#define GPIO1_PIN0_MUX_QSPIM0_IO_1 GPIO_MUX_5 /**< GPIO1_PIN0 Mux Select QSPIM0_IO_1 */ +#define GPIO1_PIN0_MUX_ISO_SYNC GPIO_MUX_6 /**< GPIO1_PIN0 Mux Select ISO_SYNC */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN1_Mux_Selection GPIO1_PIN1 MUX selection + * @{ + */ +#define GPIO1_PIN1_MUX_SPIM_CS0 GPIO_MUX_0 /**< GPIO1_PIN1 Mux Select SPIM_CS0 */ +#define GPIO1_PIN1_MUX_SPIS_CS GPIO_MUX_1 /**< GPIO1_PIN1 Mux Select SPIS_CS */ +#define GPIO1_PIN1_MUX_SIM_CLK GPIO_MUX_2 /**< GPIO1_PIN1 Mux Select SIM_CLK */ +#define GPIO1_PIN1_MUX_I2SM_SCLK GPIO_MUX_3 /**< GPIO1_PIN1 Mux Select I2SM_SCLK */ +#define GPIO1_PIN1_MUX_I2SS_SCLK GPIO_MUX_4 /**< GPIO1_PIN1 Mux Select I2SS_SCLK */ +#define GPIO1_PIN1_MUX_QSPIM0_IO_2 GPIO_MUX_5 /**< GPIO1_PIN1 Mux Select QSPIM0_IO_2 */ +#define GPIO1_PIN1_MUX_COEX_BLE_RX GPIO_MUX_6 /**< GPIO1_PIN1 Mux Select COEX_BLE_RX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN2_Mux_Selection GPIO1_PIN2 MUX selection + * @{ + */ +#define GPIO1_PIN2_MUX_QSPIM0_CS_N GPIO_MUX_0 /**< GPIO1_PIN2 Mux Select QSPIM0_CS_N */ +#define GPIO1_PIN2_MUX_XQSPIM_CS_N GPIO_MUX_1 /**< GPIO1_PIN2 Mux Select XQSPIM_CS_N */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN3_Mux_Selection GPIO1_PIN3 MUX selection + * @{ + */ +#define GPIO1_PIN3_MUX_QSPIM0_IO_3 GPIO_MUX_0 /**< GPIO1_PIN3 Mux Select QSPIM0_IO_3 */ +#define GPIO1_PIN3_MUX_XQSPIM_IO_3 GPIO_MUX_1 /**< GPIO1_PIN3 Mux Select XQSPIM_IO_3 */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN4_Mux_Selection GPIO1_PIN4 MUX selection + * @{ + */ +#define GPIO1_PIN4_MUX_QSPIM0_CLK GPIO_MUX_0 /**< GPIO1_PIN4 Mux Select QSPIM0_CLK */ +#define GPIO1_PIN4_MUX_XQSPIM_CLK GPIO_MUX_1 /**< GPIO1_PIN4 Mux Select XQSPIM_CLK */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN5_Mux_Selection GPIO1_PIN5 MUX selection + * @{ + */ +#define GPIO1_PIN5_MUX_QSPIM0_IO_2 GPIO_MUX_0 /**< GPIO1_PIN5 Mux Select QSPIM0_IO_2 */ +#define GPIO1_PIN5_MUX_XQSPIM_IO_2 GPIO_MUX_1 /**< GPIO1_PIN5 Mux Select XQSPIM_IO_2 */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN6_Mux_Selection GPIO1_PIN6 MUX selection + * @{ + */ +#define GPIO1_PIN6_MUX_QSPIM0_IO_1 GPIO_MUX_0 /**< GPIO1_PIN6 Mux Select QSPIM0_IO_1 */ +#define GPIO1_PIN6_MUX_XQSPIM_IO_1 GPIO_MUX_1 /**< GPIO1_PIN6 Mux Select XQSPIM_IO_1 */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN7_Mux_Selection GPIO1_PIN7 MUX selection + * @{ + */ +#define GPIO1_PIN7_MUX_QSPIM0_IO_0 GPIO_MUX_0 /**< GPIO1_PIN7 Mux Select QSPIM0_IO_0 */ +#define GPIO1_PIN7_MUX_XQSPIM_IO_0 GPIO_MUX_1 /**< GPIO1_PIN7 Mux Select XQSPIM_IO_0 */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN8_Mux_Selection GPIO1_PIN8 MUX selection + * @{ + */ +#define GPIO1_PIN8_MUX_SPIM_CLK GPIO_MUX_0 /**< GPIO1_PIN8 Mux Select SPIM_CLK */ +#define GPIO1_PIN8_MUX_SPIS_CLK GPIO_MUX_1 /**< GPIO1_PIN8 Mux Select SPIS_CLK */ +#define GPIO1_PIN8_MUX_SIM_PRESENCE GPIO_MUX_2 /**< GPIO1_PIN8 Mux Select SIM_PRESENCE */ +#define GPIO1_PIN8_MUX_I2SM_WS GPIO_MUX_3 /**< GPIO1_PIN8 Mux Select I2SM_WS */ +#define GPIO1_PIN8_MUX_I2SS_WS GPIO_MUX_4 /**< GPIO1_PIN8 Mux Select I2SS_WS */ +#define GPIO1_PIN8_MUX_QSPIM0_CLK GPIO_MUX_5 /**< GPIO1_PIN8 Mux Select QSPIM0_CLK */ +#define GPIO1_PIN8_MUX_COEX_WLAN_TX GPIO_MUX_6 /**< GPIO1_PIN8 Mux Select COEX_WLAN_TX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN9_Mux_Selection GPIO1_PIN9 MUX selection + * @{ + */ +#define GPIO1_PIN9_MUX_SPIM_MOSI GPIO_MUX_0 /**< GPIO1_PIN9 Mux Select SPIM_MOSI */ +#define GPIO1_PIN9_MUX_SPIS_MISO GPIO_MUX_1 /**< GPIO1_PIN9 Mux Select SPIS_MISO */ +#define GPIO1_PIN9_MUX_SIM_RST_N GPIO_MUX_2 /**< GPIO1_PIN9 Mux Select SIM_RST_N */ +#define GPIO1_PIN9_MUX_I2SM_TX_SD0 GPIO_MUX_3 /**< GPIO1_PIN9 Mux Select I2SM_TX_SD0 */ +#define GPIO1_PIN9_MUX_I2SS_TX_SD0 GPIO_MUX_4 /**< GPIO1_PIN9 Mux Select I2SS_TX_SD0 */ +#define GPIO1_PIN9_MUX_QSPIM0_IO_0 GPIO_MUX_5 /**< GPIO1_PIN9 Mux Select QSPIM0_IO_0 */ +#define GPIO1_PIN9_MUX_COEX_BLE_PROC GPIO_MUX_6 /**< GPIO1_PIN9 Mux Select COEX_BLE_PROC */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN10_Mux_Selection GPIO1_PIN10 MUX selection + * @{ + */ +#define GPIO1_PIN10_MUX_I2C1_SDA GPIO_MUX_0 /**< GPIO1_PIN10 Mux Select I2C1_SDA */ +#define GPIO1_PIN10_MUX_UART1_RX GPIO_MUX_1 /**< GPIO1_PIN10 Mux Select UART1_RX */ +#define GPIO1_PIN10_MUX_I2C0_SDA GPIO_MUX_2 /**< GPIO1_PIN10 Mux Select I2C0_SDA */ +#define GPIO1_PIN10_MUX_PWM0_C GPIO_MUX_3 /**< GPIO1_PIN10 Mux Select PWM0_C */ +#define GPIO1_PIN10_MUX_PWM1_C GPIO_MUX_4 /**< GPIO1_PIN10 Mux Select PWM5 */ +#define GPIO1_PIN10_MUX_UART0_RX GPIO_MUX_5 /**< GPIO1_PIN10 Mux Select UART0_RX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN11_Mux_Selection GPIO1_PIN11 MUX selection + * @{ + */ +#define GPIO1_PIN11_MUX_UART1_RTS GPIO_MUX_1 /**< GPIO1_PIN11 Mux Select UART1_RTS */ +#define GPIO1_PIN11_MUX_UART0_RTS GPIO_MUX_5 /**< GPIO1_PIN11 Mux Select UART0_RTS */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN12_Mux_Selection GPIO1_PIN12 MUX selection + * @{ + */ +#define GPIO1_PIN12_MUX_UART1_CTS GPIO_MUX_1 /**< GPIO1_PIN12 Mux Select UART1_CTS */ +#define GPIO1_PIN12_MUX_UART0_CTS GPIO_MUX_5 /**< GPIO1_PIN12 Mux Select UART0_CTS */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN13_Mux_Selection GPIO1_PIN13 MUX selection + * @{ + */ + +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN14_Mux_Selection GPIO1_PIN14 MUX selection + * @{ + */ +#define GPIO1_PIN14_MUX_I2C1_SCL GPIO_MUX_0 /**< GPIO1_PIN14 Mux Select I2C1_SCL */ +#define GPIO1_PIN14_MUX_UART1_TX GPIO_MUX_1 /**< GPIO1_PIN14 Mux Select UART1_TX */ +#define GPIO1_PIN14_MUX_I2C0_SCL GPIO_MUX_2 /**< GPIO1_PIN14 Mux Select I2C0_SCL */ +#define GPIO1_PIN14_MUX_PWM0_B GPIO_MUX_3 /**< GPIO1_PIN14 Mux Select PWM0_B */ +#define GPIO1_PIN14_MUX_PWM1_B GPIO_MUX_4 /**< GPIO1_PIN14 Mux Select PWM1_B */ +#define GPIO1_PIN14_MUX_UART0_TX GPIO_MUX_5 /**< GPIO1_PIN14 Mux Select UART0_TX */ +#define GPIO1_PIN14_MUX_COEX_BLE_TX GPIO_MUX_6 /**< GPIO1_PIN14 Mux Select COEX_BLE_TX */ +/** @} */ + +/** @defgroup GPIOEx_GPIO1_PIN15_Mux_Selection GPIO1_PIN15 MUX selection + * @{ + */ +#define GPIO1_PIN15_MUX_SPIM_CS1 GPIO_MUX_0 /**< GPIO1_PIN15 Mux Select SPIM_CS1 */ +#define GPIO1_PIN15_MUX_PWM0_A GPIO_MUX_3 /**< GPIO1_PIN15 Mux Select PWM0_A */ +#define GPIO1_PIN15_MUX_PWM1_A GPIO_MUX_4 /**< GPIO1_PIN15 Mux Select PWM1_A */ +#define GPIO1_PIN15_MUX_QSPIM0_IO_3 GPIO_MUX_5 /**< GPIO1_PIN15 Mux Select QSPIM0_IO_3 */ +#define GPIO1_PIN15_MUX_COEX_WLAN_TX GPIO_MUX_6 /**< GPIO1_PIN15 Mux Select COEX_WLAN_TX */ +/** @} */ + +/** + * @brief Check if GPIO Mux mode is valid. + * @param __MUX__ GPIO mux mode. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_GPIO_MUX(__MUX__) (((__MUX__) <= GPIO_MUX_8)) + +/*------------------------------------------------------------------------------------------*/ +#endif /* GR551xx */ + +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIOEx Exported Macros + * @{ + */ + +/** @defgroup GPIOEx_Get_Port_Index GPIOEx_Get Port Index +* @{ + */ +#if defined(GR551xx) + +/** + * @brief Get GPIO Port Index. + * @param __GPIOx__ GPIO instance. + * @retval Port Index. + */ +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIO0))? 0U : 1U) + +#endif /* GR551xx */ +/** @} */ + +/** @defgroup GPIOEx_Get_Port_IRQNum GPIOEx_Get Port IRQ number +* @{ + */ +#if defined(GR551xx) + +/** + * @brief Get GPIO Port IRQ number. + * @param __GPIOx__ GPIO instance. + * @retval Port IRQ number. + */ +#define GPIO_GET_IRQNUM(__GPIOx__) (((__GPIOx__) == (GPIO0))? EXT0_IRQn : EXT1_IRQn) + +#endif /* GR551xx */ + +/** @} */ + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_GPIO_EX_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_hmac.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_hmac.h new file mode 100644 index 0000000..cdd36f9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_hmac.h @@ -0,0 +1,615 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_hmac.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of HMAC HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_HMAC HMAC + * @brief HMAC HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_HMAC_H__ +#define __GR55xx_HAL_HMAC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_hmac.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_HMAC_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_HMAC_state HAL HMAC state + * @{ + */ + +/** + * @brief HAL HMAC State enumerations definition + * @note HAL HMAC State value is a combination of 2 different substates: gState and RxState. + */ +typedef enum +{ + HAL_HMAC_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_HMAC_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_HMAC_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_HMAC_STATE_ERROR = 0x03, /**< Peripheral in error */ + HAL_HMAC_STATE_TIMEOUT = 0x04, /**< Peripheral in timeout */ + HAL_HMAC_STATE_SUSPENDED = 0x05, /**< Peripheral in suspended */ + +} hal_hmac_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_HMAC_STRUCTURES Structures + * @{ + */ + +/** @defgroup HMAC_Configuration HMAC Configuration + * @{ + */ + +/** + * @brief HMAC init Structure definition + */ +typedef struct _hmac_init +{ + uint32_t mode; /**< Operating mode */ + + uint32_t *p_key; /**< Encryption/Decryption Key */ + + uint32_t *p_user_hash; /**< Initialization HASH value */ + + uint32_t key_fetch_type; /**< @ref HAL_HMAC_KEYTYPE_MCU Fetch key from ram; + { Start_private + @ref HAL_HMAC_KEYTYPE_AHB Fetch key from AHB; + } End_private + @ref HAL_HMAC_KEYTYPE_KRAM Fetch key from keyport */ + uint32_t dpa_mode; /**< DPA Mode */ + +} hmac_init_t; +/** @} */ + +/** @defgroup HMAC_handle HMAC handle + * @{ + */ + +/** + * @brief HMAC handle Structure definition + */ +typedef struct _hmac_handle +{ + hmac_regs_t *p_instance; /**< HMAC registers base address */ + + hmac_init_t init; /**< HMAC operation parameters */ + + uint32_t *p_message; /**< Pointer to message input buffer */ + + uint32_t *p_digest; /**< Pointer to digest output buffer */ + + uint32_t block_size; /**< Data size in blocks (64 bytes per block) */ + + uint32_t block_count; /**< Blocks count */ + + uint32_t is_last_trans; /**< Flag for last transfer */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_hmac_state_t state; /**< HMAC operation state */ + + __IO uint32_t error_code; /**< HMAC Error code */ + + uint32_t timeout; /**< Timeout for the HMAC operation */ + + uint32_t retention[17]; /**< HMAC important register information. */ + +} hmac_handle_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_HMAC_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_HMAC_Callback Callback + * @{ + */ + +/** + * @brief HAL_HMAC Callback function definition + */ + +typedef struct _hal_hmac_callback +{ + void (*hmac_msp_init)(hmac_handle_t *p_hmac); /**< HMAC init MSP callback */ + void (*hmac_msp_deinit)(hmac_handle_t *p_hmac); /**< HMAC de-init MSP callback */ + void (*hmac_done_callback)(hmac_handle_t *p_hmac); /**< HMAC digest done callback */ + void (*hmac_error_callback)(hmac_handle_t *p_hmac); /**< HMAC error callback */ +} hal_hmac_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_HMAC_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HMAC_Exported_Constants HMAC Exported Constants + * @{ + */ + +/** @defgroup HMAC_Error_Code HMAC Error Code + * @{ + */ +#define HAL_HMAC_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_HMAC_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_HMAC_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_HMAC_ERROR_INVALID_PARAM ((uint32_t)0x00000004) /**< Invalid parameters error */ +/** @} */ + +/** @defgroup HMAC_Mode HMAC Mode + * @{ + */ +#define HMAC_MODE_SHA LL_HMAC_CALCULATETYPE_SHA /**< SHA mode */ +#define HMAC_MODE_HMAC LL_HMAC_CALCULATETYPE_HMAC /**< HMAC mode */ +/** @} */ + +/** @defgroup HMAC_Block_Size HAMC Block Size + * @{ + */ +#define HMAC_BLOCK_MAX (512) /**< Block max size */ +#define HMAC_BLOCKSIZE_BITS (512) /**< Block size in bits */ +#define HMAC_BLOCKSIZE_BYTES (HMAC_BLOCKSIZE_BITS >> 3) /**< Block size in bytes */ +#define HMAC_BLOCKSIZE_WORDS (HMAC_BLOCKSIZE_BYTES >> 2) /**< Block size in words */ +#define HMAC_DIGESTSIZE_BITS (256) /**< Digest size in bits */ +#define HMAC_DIGESTSIZE_BYTES (HMAC_DIGESTSIZE_BITS >> 3) /**< Digest size in bytes */ +#define HMAC_DIGESTSIZE_WORDS (HMAC_DIGESTSIZE_BYTES >> 2) /**< Digest size in words */ +#define HMAC_DMA_BLOCK_MAX (512) /**< DMA Block max size */ +/** @} */ + +/** @defgroup HMAC_Flags_definition HAMC Flags Definition + * @{ + */ +#define HMAC_FLAG_DATAREADY_SHA LL_HMAC_FLAG_DATAREADY_SHA /**< HMAC data ready (SHA mode) */ +#define HMAC_FLAG_DATAREADY_HMAC LL_HMAC_FLAG_DATAREADY_HMAC /**< HMAC data ready (HAMC mode) */ +#define HMAC_FLAG_DMA_MESSAGEDONE LL_HMAC_FLAG_DMA_MESSAGEDONE /**< HMAC DMA message done */ +#define HMAC_FLAG_DMA_DONE LL_HMAC_FLAG_DMA_DONE /**< HMAC DMA transfer done */ +#define HMAC_FLAG_DMA_ERR LL_HMAC_FLAG_DMA_ERR /**< HMAC DMA transfer error */ +#define HMAC_FLAG_KEY_VALID LL_HMAC_FLAG_KEY_VALID /**< HMAC has fetched key */ +/** @} */ + +/** @defgroup HMAC_HAL_KEY_TYPE Key Type + * @{ + */ +#define HAL_HMAC_KEYTYPE_MCU LL_HMAC_KEYTYPE_MCU /**< Key from MCU */ +/* { Start_private */ +#define HAL_HMAC_KEYTYPE_AHB LL_HMAC_KEYTYPE_AHB /**< Key from AHB master */ +/* } End_private */ +#define HAL_HMAC_KEYTYPE_KRAM LL_HMAC_KEYTYPE_KRAM /**< Key from Key Port */ +/** @} */ + +/** @defgroup HMAC_Interrupt_definition HMAC Interrupt_definition + * @{ + */ +#define HMAC_IT_DONE ((uint32_t)0x00000001) /**< Operation Done Interrupt source */ +/** @} */ + +/** @defgroup HMAC_Timeout_definition HMAC Timeout_definition + * @{ + */ +#define HAL_HMAC_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HMAC_Exported_Macros HMAC Exported Macros + * @{ + */ + +/** @brief Reset HMAC handle states. + * @param __HANDLE__ HMAC handle. + * @retval None + */ +#define __HAL_HMAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_HMAC_STATE_RESET) + +/** @brief Enable the specified HMAC peripheral. + * @param __HANDLE__ Specifies the HMAC Handle. + * @retval None + */ +#define __HAL_HMAC_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, HMAC_CTRL_ENABLE) + +/** @brief Disable the specified HMAC peripheral. + * @param __HANDLE__ Specifies the HMAC Handle. + * @retval None + */ +#define __HAL_HMAC_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, HMAC_CTRL_ENABLE) + +/** @brief Enable the HMAC interrupt. + * @param __HANDLE__ Specifies the HMAC Handle. + * @retval None + */ +#define __HAL_HMAC_ENABLE_IT(__HANDLE__) ll_hmac_enable_it_done((__HANDLE__)->p_instance) + +/** @brief Disable the HMAC interrupt. + * @param __HANDLE__ Specifies the HMAC Handle. + * @retval None + */ +#define __HAL_HMAC_DISABLE_IT(__HANDLE__) ll_hmac_disable_it_done((__HANDLE__)->p_instance) + +/** @brief Check whether the specified HMAC interrupt flag is set or not. + * @param __HANDLE__ Specifies the HMAC Handle. + * @param __FLAG__ Specifies the interrupt flag to check. + * This parameter can be one of the following values: + * @arg @ref HMAC_IT_DONE Encrypted or Decrypted Data Done Interrupt + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_HMAC_GET_FLAG_IT(__HANDLE__, __FLAG__) (READ_BITS((__HANDLE__)->p_instance->INTERRUPT, (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified HMAC interrupt flag. + * @param __HANDLE__ Specifies the HMAC interrupt Handle. + * @param __FLAG__ Specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref HMAC_IT_DONE Encrypted or Decrypted Data Done Interrupt + * @retval None + */ +#define __HAL_HMAC_CLEAR_FLAG_IT(__HANDLE__, __FLAG__) SET_BITS((__HANDLE__)->p_instance->INTERRUPT, (__FLAG__)) + +/** @brief Check whether the specified HMAC flag is set or not. + * @param __HANDLE__ Specifies the HMAC Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref HMAC_FLAG_DATAREADY_SHA Data ready (SHA mode) flag + * @arg @ref HMAC_FLAG_DATAREADY_HMAC Data ready (HMAC mode) flag + * @arg @ref HMAC_FLAG_DMA_DONE DMA transfer done flag + * @arg @ref HMAC_FLAG_DMA_ERR DMA transfer error flag + * @arg @ref HMAC_FLAG_KEY_VALID Key valid flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_HMAC_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->STATUS, (__FLAG__)) != 0) ? SET : RESET) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_HMAC_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup HMAC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the HMACx peripheral: + + (+) User must implement hal_hmac_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_hmac_init() to configure the selected device with + the selected configuration: + (++) mode + (++) key + (++) user_hash + (++) dpa_mode + + (+) Call the function hal_hmac_deinit() to restore the default configuration + of the selected HMACx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the HMAC according to the specified parameters + * in the hmac_init_t and initialize the associated handle. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_init(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief De-initialize the HMAC peripheral. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_deinit(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief Initialize the HMAC MSP. + * @note This function should not be modified. When the callback is needed, + the hal_hmac_msp_deinit can be implemented in the user file. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + **************************************************************************************** + */ +void hal_hmac_msp_init(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief De-initialize the HMAC MSP. + * @note This function should not be modified. When the callback is needed, + the HAL_HMAC_MspDeInit can be implemented in the user file. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + **************************************************************************************** + */ +void hal_hmac_msp_deinit(hmac_handle_t *p_hmac); + +/** @} */ + +/** @addtogroup HMAC_Exported_Functions_Group2 IO operation functions + * @brief HMAC Encrypt/Decrypt functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the HMAC encrypt or decrypt. + + (#) There are two mode of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated HMAC IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_hmac_done_callback() user callbacks will be executed respectively + at the end of the encrypt or decrypt process + The hal_hmac_error_callback() user callback will be executed when a error is detected + + (#) Blocking mode API's are : + (++) hal_hmac_sha256_digest() + + (#) Non-Blocking mode API's with Interrupt are : + (++) hal_hmac_sha256_digest_it() + + (#) Non-Blocking mode API's with DMA are : + (++) hal_hmac_sha256_digest_dma() + + (#) A set of encrypt or decrypt Callbacks are provided in Non_Blocking mode: + (++) hal_hmac_done_callback() + (++) hal_hmac_error_callback() + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief xxx in blocking mode in SHA/HMAC mode. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @param[in] p_message: Pointer to message buffer + * @param[in] number: Amount of data + * @param[out] p_digest: Pointer to digest buffer + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_sha256_digest(hmac_handle_t *p_hmac, uint32_t *p_message, uint32_t number, uint32_t *p_digest, uint32_t timeout); + +/** + **************************************************************************************** + * @brief xxx in non-blocking mode with interrupt in SHA/HMAC mode. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @param[in] p_message: Pointer to message buffer + * @param[in] number: Amount of data + * @param[out] p_digest: Pointer to digest buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_sha256_digest_it(hmac_handle_t *p_hmac, uint32_t *p_message, uint32_t number, uint32_t *p_digest); + +/** + **************************************************************************************** + * @brief xxx in non-blocking mode with DMA in SHA/HMAC mode. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @param[in] p_message: Pointer to massage buffer + * @param[in] number: Amount of data + * @param[out] p_digest: Pointer to digest buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_sha256_digest_dma(hmac_handle_t *p_hmac, uint32_t *p_message, uint32_t number, uint32_t *p_digest); + +/** @} */ + +/** @addtogroup HMAC_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle HMAC interrupt request. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + **************************************************************************************** + */ +void hal_hmac_irq_handler(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief Digest Done callback. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + **************************************************************************************** + */ +void hal_hmac_done_callback(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief HMAC error callback. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + **************************************************************************************** + */ +void hal_hmac_error_callback(hmac_handle_t *p_hmac); + +/** @} */ + +/** @defgroup HMAC_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief HMAC control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the HMAC. + (+) hal_hmac_get_state() API can be helpful to check in run-time the state of the HMAC peripheral. + (+) hal_hmac_get_error() check in run-time Errors occurring during communication. + (+) hal_hmac_set_timeout() set the timeout during internal process. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the HMAC handle state. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @retval ::HAL_HMAC_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_HMAC_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_HMAC_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_HMAC_STATE_ERROR: Peripheral in error. + * @retval ::HAL_HMAC_STATE_TIMEOUT: Peripheral in timeout. + * @retval ::HAL_HMAC_STATE_SUSPENDED: Peripheral in suspended. + **************************************************************************************** + */ +hal_hmac_state_t hal_hmac_get_state(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief Return the HMAC error code. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @return HMAC error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_hmac_get_error(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief Set the HMAC internal process timeout value. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration information for the specified HMAC module. + * @param[in] timeout: Internal process timeout value. + **************************************************************************************** + */ +void hal_hmac_set_timeout(hmac_handle_t *p_hmac, uint32_t timeout); + + +/** + **************************************************************************************** + * @brief Suspend some registers related to HMAC configuration before sleep. + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration + * information for the specified HMAC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_suspend_reg(hmac_handle_t *p_hmac); + +/** + **************************************************************************************** + * @brief Restore some registers related to HMAC configuration after sleep. + * This function must be used in conjunction with the hal_hmac_suspend_reg(). + * @param[in] p_hmac: Pointer to a HMAC handle which contains the configuration + * information for the specified HMAC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_hmac_resume_reg(hmac_handle_t *p_hmac); + + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_HMAC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2c.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2c.h new file mode 100644 index 0000000..a921016 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2c.h @@ -0,0 +1,1245 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_i2c.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2C HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_I2C I2C + * @brief I2C HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_I2C_H__ +#define __GR55xx_HAL_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_i2c.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_I2C_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_I2C_state HAL I2C state + * @{ + */ + +/** + * @brief HAL I2C State Enumerations definition + * @note HAL I2C State value coding follow below described bitmap :\n + * @verbatim + b7-b6 Error information + 00 : No Error + 01 : Abort (Abort user request on going) + 10 : Timeout + 11 : Error + b5 IP initilisation status + 0 : Reset (IP not initialized) + 1 : init done (IP initialized and ready to use. HAL I2C init function called) + b4 (not used) + x : Should be set to 0 + b3 + 0 : Ready or Busy (No Listen mode ongoing) + 1 : Listen (IP in Address Listen Mode) + b2 Intrinsic process state + 0 : Ready + 1 : Busy (IP busy with some configuration or internal operations) + b1 Rx state + 0 : Ready (no Rx operation ongoing) + 1 : Busy (Rx operation ongoing) + b0 Tx state + 0 : Ready (no Tx operation ongoing) + 1 : Busy (Tx operation ongoing) + * @endverbatim + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00U, /**< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /**< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /**< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /**< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /**< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /**< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /**< Address Listen Mode and Data Transmission + process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /**< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /**< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /**< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /**< Error */ + +} hal_i2c_state_t; +/** @} */ + +/** @defgroup HAL_I2C_mode HAL I2C mode + * @{ + */ + +/** + * @brief HAL I2C Mode Enumerations definition + * @note HAL I2C Mode value coding follow below described bitmap :\n + * @verbatim + b7 (not used) + x : Should be set to 0 + b6 + 0 : None + 1 : Memory (HAL I2C communication is in Memory Mode) + b5 + 0 : None + 1 : Slave (HAL I2C communication is in Slave Mode) + b4 + 0 : None + 1 : Master (HAL I2C communication is in Master Mode) + b3-b2-b1-b0 (not used) + xxxx : Should be set to 0000 + * @endverbatim + */ +typedef enum +{ + HAL_I2C_MODE_NONE = 0x00U, /**< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /**< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /**< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /**< I2C communication is in Memory Mode */ + +} hal_i2c_mode_t; +/** @} */ + +/** @} */ + + +/** @addtogroup HAL_I2C_STRUCTURES Structures + * @{ + */ + +/** @defgroup I2C_Configuration I2C Configuration + * @{ + */ + +/** + * @brief I2C Configuration Structure definition + */ +typedef struct _i2c_init +{ + uint32_t speed; /**< Specifies the I2C transfer speed. + This parameter can be a value of @ref I2C_Speed */ + + uint32_t own_address; /**< Specifies the device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t addressing_mode; /**< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_Addressing_Mode */ + + uint32_t general_call_mode; /**< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_General_Call_Addressing_Mode */ + +} i2c_init_t; +/** @} */ + +/** @defgroup I2C_handle I2C handle + * @{ + */ + +/** + * @brief I2C handle Structure definition + */ +typedef struct _i2c_handle +{ + i2c_regs_t *p_instance; /**< I2C registers base address */ + + i2c_init_t init; /**< I2C communication parameters */ + + uint8_t *p_buffer; /**< Pointer to I2C transfer buffer */ + + uint16_t xfer_size; /**< I2C transfer size */ + + __IO uint16_t xfer_count; /**< I2C transfer counter */ + + __IO uint16_t master_ack_count; /**< I2C master acknowledge counter in master receive progress */ + + __IO uint32_t xfer_options; /**< I2C sequantial transfer options, this parameter can + be a value of @ref I2C_XferOptions */ + + __IO uint32_t previous_state; /**< I2C communication Previous state */ + + hal_status_t(*xfer_isr)(struct _i2c_handle *p_i2c, uint32_t it_source, uint32_t abort_sources); + /**< I2C transfer IRQ handler function pointer */ + + dma_handle_t *p_dmatx; /**< I2C Tx DMA handle parameters */ + + dma_handle_t *p_dmarx; /**< I2C Rx DMA handle parameters */ + + hal_lock_t lock; /**< I2C locking object */ + + __IO hal_i2c_state_t state; /**< I2C communication state */ + + __IO hal_i2c_mode_t mode; /**< I2C communication mode */ + + __IO uint32_t error_code; /**< I2C Error code */ + + uint32_t retention[19]; /**< I2C important register information. */ +} i2c_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_I2C_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_I2C_Callback Callback + * @{ + */ + +/** + * @brief HAL_I2C Callback function definition + */ + +typedef struct _hal_i2c_callback +{ + void (*i2c_msp_init)(i2c_handle_t *p_i2c); /**< I2C init MSP callback */ + void (*i2c_msp_deinit)(i2c_handle_t *p_i2c); /**< I2C de-init MSP callback */ + void (*i2c_master_tx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C master tx transfer completed callbac */ + void (*i2c_master_rx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C master rx transfer completed callback */ + void (*i2c_slave_tx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C slave tx transfer completed callback */ + void (*i2c_slave_rx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C slave rx transfer completed callback */ + void (*i2c_listen_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C listen Complete callback */ + void (*i2c_mem_tx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C mem tx transfer completed callback */ + void (*i2c_mem_rx_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C mem rx transfer completed callback */ + void (*i2c_error_callback)(i2c_handle_t *p_i2c); /**< I2C error callback */ + void (*i2c_abort_cplt_callback)(i2c_handle_t *p_i2c); /**< I2C abort completed callback */ +} hal_i2c_callback_t; + +/** @} */ + +/** @} */ + +/** @defgroup HAL_I2C_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_Error_Code_definition I2C Error Code definition + * @{ + */ +#define HAL_I2C_ERROR_NONE (0x00000000U) /**< No error */ +#define HAL_I2C_ERROR_ARB_LOST (0x00000002U) /**< Arbitration lost error */ +#define HAL_I2C_ERROR_NOACK (0x00000004U) /**< No acknowledge error */ +#define HAL_I2C_ERROR_OVER (0x00000008U) /**< RX_OVER error */ +#define HAL_I2C_ERROR_DMA (0x00000010U) /**< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT (0x00000020U) /**< Timeout error */ +/** @} */ + +/** @defgroup I2C_Speed I2C Transfer Speed + * @{ + */ +#define I2C_SPEED_100K LL_I2C_SPEED_100K /**< Standard speed. */ +#define I2C_SPEED_400K LL_I2C_SPEED_400K /**< Fast speed. */ +#define I2C_SPEED_1000K LL_I2C_SPEED_1000K /**< Fast Plus speed. */ +#define I2C_SPEED_2000K LL_I2C_SPEED_2000K /**< High speed. */ +/** @} */ + +/** @defgroup I2C_Addressing_Mode I2C Addressing Mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT (0x00000001U) /**< 7-bit addressing mode. */ +#define I2C_ADDRESSINGMODE_10BIT (0x00000002U) /**< 10-bit addressing mode. */ +/** @} */ + +/** @defgroup I2C_General_Call_Addressing_Mode I2C General Call Addressing Mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE (0x00000000U) /**< General call mode disable. */ +#define I2C_GENERALCALL_ENABLE (0x00000001U) /**< General call mode enable. */ +/** @} */ + +/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT (0x00000001U) /**< 8-bit memory address. */ +#define I2C_MEMADD_SIZE_16BIT (0x00000002U) /**< 16-bit memory address. */ +/** @} */ + +/** @defgroup I2C_XferOptions I2C Sequential Transfer Options + * @{ + */ +#define I2C_FIRST_FRAME (0x00000000U) /**< First transfer frame. */ +#define I2C_FIRST_AND_NEXT_FRAME (0x00000001U) /**< First and next transfer frames. */ +#define I2C_NEXT_FRAME (0x00000002U) /**< Next transfer frame. */ +#define I2C_FIRST_AND_LAST_FRAME (0x00000003U) /**< First and last transfer frames. */ +#define I2C_LAST_FRAME (0x00000004U) /**< Last transfer frame. */ +/** @} */ + +/** @defgroup I2C_Timing_type I2C Timing type + * @{ + */ +#define I2C_TIMING_SS_SCL_LOW (0x00000000U) /**< Standard speed(0, 100K] SCL low time. */ +#define I2C_TIMING_SS_SCL_HIGH (0x00000001U) /**< Standard speed(0, 100K] SCL high time. */ +#define I2C_TIMING_FS_SCL_LOW (0x00000002U) /**< Fast and fast puls speed(100K, 1000K] SCL low time. */ +#define I2C_TIMING_FS_SCL_HIGH (0x00000003U) /**< Fast and fast puls speed(100K, 1000K] SCL high time. */ +#define I2C_TIMING_HS_SCL_LOW (0x00000004U) /**< High speed(1000K, 3400K] SCL low time. */ +#define I2C_TIMING_HS_SCL_HIGH (0x00000005U) /**< High speed(1000K, 3400K] SCL high time. */ +#define I2C_TIMING_FS_SPK (0x00000006U) /**< Fast and fast puls speed(100K, 1000K] spike suppression time. */ +#define I2C_TIMING_HS_SPK (0x00000007U) /**< High speed(1000K, 3400K] spike suppression time. */ +#define I2C_TIMING_SDA_TX_HOLD (0x00000008U) /**< SDA hold time when TX. (Hold time: Time of master and slave exchange SDA control) */ +#define I2C_TIMING_SDA_RX_HOLD (0x00000009U) /**< SDA hold time when RX. (Hold time: Time of master and slave exchange SDA control) */ +/** @} */ + +/** + * @brief I2C InitStruct default configuartion + */ +#define I2C_DEFAULT_CONFIG \ +{ \ + .speed = I2C_SPEED_400K, \ + .own_address = 0x55U, \ + .addressing_mode = I2C_ADDRESSINGMODE_7BIT, \ + .general_call_mode = I2C_GENERALCALL_DISABLE, \ +} + +/** @} */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state. + * @param __HANDLE__ Specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_I2C_STATE_RESET) +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macro I2C Private Macros + * @{ + */ + +/** + * @brief Check if the I2C speed is valid. + * @param __SPEED__ I2C transfer speed. + * @retval SET (__SPEED__ is valid) or RESET (__SPEED__ is invalid) + */ +#define IS_I2C_SPEED(__SPEED__) (((__SPEED__) == I2C_SPEED_100K) || \ + ((__SPEED__) == I2C_SPEED_400K) || \ + ((__SPEED__) == I2C_SPEED_1000K) || \ + ((__SPEED__) == I2C_SPEED_2000K)) + +/** + * @brief Check if the I2C addressing mode is valid. + * @param __MODE__ I2C addressing mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_I2C_ADDRESSING_MODE(__MODE__) (((__MODE__) == I2C_ADDRESSINGMODE_7BIT) || \ + ((__MODE__) == I2C_ADDRESSINGMODE_10BIT)) + +/** + * @brief Check if the I2C general call mode is valid. + * @param __CALL__ I2C general call mode. + * @retval SET (__CALL__ is valid) or RESET (__CALL__ is invalid) + */ +#define IS_I2C_GENERAL_CALL(__CALL__) (((__CALL__) == I2C_GENERALCALL_DISABLE) || \ + ((__CALL__) == I2C_GENERALCALL_ENABLE)) + +/** + * @brief Check if the I2C memory address size is valid. + * @param __SIZE__ I2C memory address size. + * @retval SET (__SIZE__ is valid) or RESET (__SIZE__ is invalid) + */ +#define IS_I2C_MEMADD_SIZE(__SIZE__) (((__SIZE__) == I2C_MEMADD_SIZE_8BIT) || \ + ((__SIZE__) == I2C_MEMADD_SIZE_16BIT)) + +/** + * @brief Check if the I2C transfer request command is valid. + * @param __REQUEST__ I2C transfer request command. + * @retval SET (__REQUEST__ is valid) or RESET (__REQUEST__ is invalid) + */ +#define IS_TRANSFER_REQUEST(__REQUEST__) (((__REQUEST__) == I2C_CMD_SLV_NONE) || \ + ((__REQUEST__) == I2C_CMD_MST_WRITE) || \ + ((__REQUEST__) == I2C_CMD_MST_READ) || \ + ((__REQUEST__) == I2C_CMD_MST_GEN_STOP) || \ + ((__REQUEST__) == I2C_CMD_MST_GEN_RESTART)) + +/** + * @brief Check if the I2C transfer options request is valid. + * @param __REQUEST__ I2C transfer options request. + * @retval SET (__REQUEST__ is valid) or RESET (__REQUEST__ is invalid) + */ +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(__REQUEST__) (((__REQUEST__) == I2C_FIRST_FRAME) || \ + ((__REQUEST__) == I2C_FIRST_AND_NEXT_FRAME) || \ + ((__REQUEST__) == I2C_NEXT_FRAME) || \ + ((__REQUEST__) == I2C_FIRST_AND_LAST_FRAME) || \ + ((__REQUEST__) == I2C_LAST_FRAME)) + +/** + * @brief Check if the I2C slave address is valid. + * @param __ADDRESS__ I2C slave address. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define IS_I2C_SLV_ADDRESS(__ADDRESS__) ((__ADDRESS__) < 0x03FFU) + +/** + * @brief Check if the I2C own address is valid. + * @param __ADDRESS__ I2C own address. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define IS_I2C_OWN_ADDRESS(__ADDRESS__) ((((__ADDRESS__) > 0x0007U) && ((__ADDRESS__) < 0x0078U)) || \ + (((__ADDRESS__) > 0x007FU) && ((__ADDRESS__) < 0x03FFU))) + +/** + * @brief Get the Most Significant 8 Bits of memory address. + * @param __ADDRESS__ Memory address. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U))) + +/** + * @brief Get the Least Significant 8 Bits of memory address. + * @param __ADDRESS__ Memory address. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_I2C_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * @verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Cx peripheral: + + (+) User must Implement hal_i2c_msp_init() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_i2c_init() to configure the selected device with + the selected configuration: + (++) Speed + (++) Own Address + (++) Addressing mode (Master, Slave) + (++) General call mode + + (+) Call the function hal_i2c_deinit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initializes the I2C according to the specified parameters + * in the i2c_init_t and initialize the associated handle. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration + * information for the specified I2C. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_init(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief De-initialize the I2C peripheral. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_deinit(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Initialize the I2C MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_msp_init could be implemented in the user file. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_msp_init(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief De-initialize the I2C MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_msp_deinit could be implemented in the user file. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_msp_deinit(i2c_handle_t *p_i2c); + +/** @} */ + +/** @addtogroup I2C_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) hal_i2c_master_transmit() + (++) hal_i2c_master_receive() + (++) hal_i2c_slave_transmit() + (++) hal_i2c_slave_receive() + (++) hal_i2c_mem_write() + (++) hal_i2c_mem_read() + (++) hal_i2c_is_device_ready() + + (#) No-Blocking mode functions with Interrupt are : + (++) hal_i2c_master_transmit_it() + (++) hal_i2c_master_receive_it() + (++) hal_i2c_slave_transmit_it() + (++) hal_i2c_slave_receive_it() + (++) hal_i2c_mem_write_it() + (++) hal_i2c_mem_read_it() + + (#) No-Blocking mode functions with DMA are : + (++) hal_i2c_master_transmit_dma() + (++) hal_i2c_master_recevice_dma() + (++) hal_i2c_slave_transmit_dma() + (++) hal_i2c_slave_receive_dma() + (++) hal_i2c_mem_write_dma() + (++) hal_i2c_mem_read_dma() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) hal_i2c_mem_tx_cplt_callback() + (++) hal_i2c_mem_rx_cplt_callback() + (++) hal_i2c_master_tx_cplt_callback() + (++) hal_i2c_master_rx_cplt_callback() + (++) hal_i2c_slave_tx_cplt_callback() + (++) hal_i2c_slave_rx_cplt_callback()() + (++) hal_i2c_error_callback() + +@endverbatim + * @{ + */ + +/******* Blocking mode: Polling */ + +/** + **************************************************************************************** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_transmit(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receives in master mode an amount of data in blocking mode. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + * @note This function will return HAL_OK even if the length of data sent by slave is + * less than the expected Size. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_receive(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_transmit(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive in slave mode an amount of data in blocking mode + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_receive(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_write(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_read(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/******* Non-Blocking mode: Interrupt */ + +/** + **************************************************************************************** + * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_transmit_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_receive_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_transmit_it(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_receive_it(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_write_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_read_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Sequentially transmit in master I2C mode an amount of data in non-blocking mode with Interrupt. + * @note This interface allows to manage repeated start condition when a direction changes during transfer + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] xfer_options: Options of Transfer, value of @ref I2C_XferOptions + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_sequential_transmit_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size, uint32_t xfer_options); + +/** + **************************************************************************************** + * @brief Sequentially receive in master I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allows to manage repeated start condition when a direction changes during transfer + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] xfer_options: Options of Transfer, value of @ref I2C_XferOptions + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_sequential_receive_it(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size, uint32_t xfer_options); + +/** + **************************************************************************************** + * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] xfer_options: Options of Transfer, value of @ref I2C_XferOptions + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_sequential_transmit_it(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size, uint32_t xfer_options); + +/** + **************************************************************************************** + * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent + * @param[in] xfer_options: Options of Transfer, value of @ref I2C_XferOptions + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_sequential_receive_it(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size, uint32_t xfer_options); + +/** + **************************************************************************************** + * @brief Enable the Master Read Request listen mode with Interrupt. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_enable_listen_it(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Disable the Master Read Request listen mode with Interrupt. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_disable_listen_it(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Abort a master I2C IT or DMA process communication with Interrupt. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_abort_it(i2c_handle_t *p_i2c); + +/******* Non-Blocking mode: DMA */ + +/** + **************************************************************************************** + * @brief Transmit in master mode an amount of data in non-blocking mode with DMA + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_transmit_dma(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive in master mode an amount of data in non-blocking mode with DMA + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_receive_dma(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_transmit_dma(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive in slave mode an amount of data in non-blocking mode with DMA + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_receive_dma(i2c_handle_t *p_i2c, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_write_dma(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] mem_address: Internal memory address + * @param[in] mem_addr_size: Size of internal memory address + * @param[in] p_data: Pointer to data buffer + * @param[in] size: Amount of data to be sent, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_mem_read_dma(i2c_handle_t *p_i2c, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size); + +/** @} */ + +/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief This function handles I2C event interrupt request. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_irq_handler(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Master Tx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_master_tx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_master_tx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Master Rx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_master_rx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_master_rx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Slave Tx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_slave_tx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_slave_tx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Slave Rx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_slave_rx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_slave_rx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Memory Tx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_mem_tx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_mem_tx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Memory Rx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_mem_rx_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_mem_rx_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Listen Complete callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_listen_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_listen_cplt_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief I2C error callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_error_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_error_callback(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief I2C abort callback. + * @note This function should not be modified. When the callback is needed, + * the hal_i2c_abort_cplt_callback can be implemented in the user file + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + **************************************************************************************** + */ +void hal_i2c_abort_cplt_callback(i2c_handle_t *p_i2c); + +/** @} */ + +/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @brief Peripheral State, Mode and Error functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the I2C handle state. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_I2C_STATE_RESET: Peripheral is not yet Initialized. + * @retval ::HAL_I2C_STATE_READY: Peripheral Initialized and ready for use. + * @retval ::HAL_I2C_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_I2C_STATE_BUSY_TX: Data Transmission process is ongoing. + * @retval ::HAL_I2C_STATE_BUSY_RX: Data Reception process is ongoing. + * @retval ::HAL_I2C_STATE_LISTEN: Address Listen Mode is ongoing. + * @retval ::HAL_I2C_STATE_BUSY_TX_LISTEN: Address Listen Mode and Data Transmission process is ongoing. + * @retval ::HAL_I2C_STATE_BUSY_RX_LISTEN: Address Listen Mode and Data Reception process is ongoing. + * @retval ::HAL_I2C_STATE_ABORT: Abort user request ongoing. + * @retval ::HAL_I2C_STATE_TIMEOUT: Timeout state. + * @retval ::HAL_I2C_STATE_ERROR: Error. + **************************************************************************************** + */ +hal_i2c_state_t hal_i2c_get_state(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Returns the I2C Master, Slave, Memory or no mode. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @retval ::HAL_I2C_MODE_NONE: No I2C communication on going. + * @retval ::HAL_I2C_MODE_MASTER: I2C communication is in Master Mode. + * @retval ::HAL_I2C_MODE_SLAVE: I2C communication is in Slave Mode. + * @retval ::HAL_I2C_MODE_MEM: I2C communication is in Memory Mode. + **************************************************************************************** + */ +hal_i2c_mode_t hal_i2c_get_mode(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Return the I2C error code. + * @param[in] p_i2c: Pointer to an I2C handle which contains the configuration information for the specified I2C. + * @return I2C Error Code + **************************************************************************************** + */ +uint32_t hal_i2c_get_error(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Suspend some registers related to I2C configuration before sleep. + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * information for the specified I2C module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_suspend_reg(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Restore some registers related to I2C configuration after sleep. + * This function must be used in conjunction with the hal_i2c_suspend_reg(). + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * information for the specified I2C module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2c_resume_reg(i2c_handle_t *p_i2c); + +/** + **************************************************************************************** + * @brief Adjust I2C timing value to adapt to real load. + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * information for the specified I2C module. + * @param[in] timing_type: Timing type. See I2C_Timing_tpye. + * @param[in] delta: timing change value(uinit: I2C work clock cycles). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + **************************************************************************************** + */ +hal_status_t hal_i2c_timing_adjust(i2c_handle_t *p_i2c, uint32_t timing_type, int32_t delta); + +/** + **************************************************************************************** + * @brief Get the I2C timing value. + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * information for the specified I2C module. + * @param[in] timing_type: Timing type. See I2C_Timing_tpye. + * @param[in] p_timing_value: Pointer of I2C timing value(uinit: I2C work clock cycles). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error. + **************************************************************************************** + */ +hal_status_t hal_i2c_timing_get(i2c_handle_t *p_i2c, uint32_t timing_type, uint32_t *p_timing_value); + +/** + **************************************************************************************** + * @brief I2C MASTER transmit and receive data with only one bit. For Microsoft HID Over I2C protocol. + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * @param[in] dev_address: Target device address: The device 7 bits address value in datasheet must be shifted at right before call interface + * @param[in] p_tdata: Pointer to transmit data buffer + * @param[in] tsize: Amount of data to be sent + * @param[in] p_rdata: Pointer to receive data buffer + * @param[in] rsize: Amount of data to be received + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error. + **************************************************************************************** + */ +hal_status_t hal_i2c_master_transmit_receive(i2c_handle_t *p_i2c, uint16_t dev_address, uint8_t *p_tdata, uint16_t tsize, uint8_t *p_rdata, uint16_t rsize, uint32_t timeout); + +/** + **************************************************************************************** + * @brief I2C SLAVE receive and transmit data with only one bit. Add for hal_i2c_master_transmit_receive. + * @param[in] p_i2c: Pointer to a I2C handle which contains the configuration + * @param[in] p_tdata: Pointer to transmit data buffer + * @param[in] tsize: Amount of data to be sent + * @param[in] p_rdata: Pointer to receive data buffer + * @param[in] rsize: Amount of data to be received + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error. + **************************************************************************************** + */ +hal_status_t hal_i2c_slave_receive_transmit(i2c_handle_t *p_i2c, uint8_t *p_tdata, uint16_t tsize, uint8_t *p_rdata, uint16_t rsize, uint32_t timeout); +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_I2C_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2s.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2s.h new file mode 100644 index 0000000..f05c30b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_i2s.h @@ -0,0 +1,975 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_i2s.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2S HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_I2S I2S + * @brief I2S HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_I2S_H__ +#define __GR55xx_HAL_I2S_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_i2s.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_I2S_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_I2S_state HAL I2S state + * @{ + */ + +/** + * @brief HAL I2S State Enumerations definition + */ +typedef enum +{ + HAL_I2S_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_I2S_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_I2S_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_I2S_STATE_BUSY_TX = 0x12, /**< Data Transmission process is ongoing */ + HAL_I2S_STATE_BUSY_RX = 0x22, /**< Data Reception process is ongoing */ + HAL_I2S_STATE_BUSY_TX_RX = 0x32, /**< Data Transmission and Reception process is ongoing */ + HAL_I2S_STATE_ABORT = 0x08, /**< Peripheral with abort request ongoing */ + HAL_I2S_STATE_ERROR = 0x04 /**< Peripheral in error */ + +} hal_i2s_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_I2S_STRUCTURES Structures + * @{ + */ + +/** @defgroup I2S_Configuration I2S Configuration + * @{ + */ + +/** + * @brief I2S init Structure definition + */ +typedef struct _i2s_init +{ + uint32_t data_size; /**< Specifies the data size for I2S communication. + This parameter can be a value of @ref I2S_Data_Size */ + + uint32_t clock_source; /**< Specifies the source of the I2S clock. + This parameter can be a value of @ref I2S_Clock_Source */ + + uint32_t audio_freq; /**< Specifies the frequency selected for the I2S communication. + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ +#if I2S_CHANNEL_NUM > 1 + uint32_t channel_active; /**< Specifies the active channels for I2S communication. + This parameter can be one or more value of @ref I2S_Channel */ +#endif + +} i2s_init_t; +/** @} */ + +/** @defgroup I2S_handle I2S handle + * @{ + */ + +/** + * @brief I2S handle Structure definition + */ +typedef struct _i2s_handle +{ + i2s_regs_t *p_instance; /**< I2S registers base address */ + + i2s_init_t init; /**< I2S communication parameters */ + + uint16_t *p_tx_buffer; /**< Pointer to I2S TX transfer Buffer */ + + __IO uint32_t tx_xfer_size; /**< I2S TX Transfer size */ + + __IO uint32_t tx_xfer_count; /**< I2S TX Transfer Counter */ + + uint16_t *p_rx_buffer; /**< Pointer to I2S RX transfer Buffer */ + + __IO uint32_t rx_xfer_size; /**< I2S RX Transfer size */ + + __IO uint32_t rx_xfer_count; /**< I2S RX Transfer Counter */ + + void (*write_fifo)(struct _i2s_handle *p_i2s); /**< Pointer to I2S Tx transfer FIFO write function */ + + void (*read_fifo)(struct _i2s_handle *p_i2s); /**< Pointer to I2S Rx transfer FIFO read function */ + + dma_handle_t *p_dmatx; /**< I2S TX DMA Handle parameters */ + + dma_handle_t *p_dmarx; /**< I2S RX DMA Handle parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_i2s_state_t state; /**< I2S communication state */ + + __IO uint32_t error_code; /**< I2S Error code */ + + uint32_t timeout; /**< Timeout for the I2S memory access */ + + uint32_t retention[7]; /**< I2S important register information. */ +} i2s_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_I2S_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_I2S_Callback Callback + * @{ + */ + +/** + * @brief HAL_I2S Callback function definition + */ + +typedef struct _hal_i2s_callback +{ + void (*i2s_msp_init)(i2s_handle_t *p_i2s); /**< I2S init MSP callback */ + void (*i2s_msp_deinit)(i2s_handle_t *p_i2s); /**< I2S de-init MSP callback */ + void (*i2s_error_callback)(i2s_handle_t *p_i2s); /**< I2S error callback */ + void (*i2s_rx_cplt_callback)(i2s_handle_t *p_i2s); /**< I2S rx transfer completed callback */ + void (*i2s_tx_cplt_callback)(i2s_handle_t *p_i2s); /**< I2S tx transfer completed callbac */ + void (*i2s_tx_rx_cplt_callback)(i2s_handle_t *p_i2s); /**< I2S tx/rx transfer completed callback */ +} hal_i2s_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_I2S_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup I2S_Direction I2S Direction + * @{ + */ +#define I2S_DIRECTION_FULL_DUPLEX LL_I2S_FULL_DUPLEX /**< Full Duplex: Transmit & Receive */ +#define I2S_DIRECTION_SIMPLEX_TX LL_I2S_SIMPLEX_TX /**< Simplex TX: Transmit only */ +#define I2S_DIRECTION_SIMPLEX_RX LL_I2S_SIMPLEX_RX /**< Simplex RX: Receive only */ +/** @} */ + +/** @defgroup I2S_Error_Code I2S Error Code + * @{ + */ +#define HAL_I2S_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_I2S_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_I2S_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_I2S_ERROR_DMA ((uint32_t)0x00000004) /**< DMA transfer error */ +#define HAL_I2S_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +#define HAL_I2S_ERROR_TX_OVERFLOW ((uint32_t)0x00000010) /**< Transmit overflow error */ +#define HAL_I2S_ERROR_RX_OVERFLOW ((uint32_t)0x00000020) /**< Receive overflow error */ +/** @} */ + +/** @defgroup I2S_Data_Size I2S Data Size + * @{ + */ +#define I2S_DATASIZE_12BIT LL_I2S_DATASIZE_12BIT /**< 12-bit serial data transfer */ +#define I2S_DATASIZE_16BIT LL_I2S_DATASIZE_16BIT /**< 16-bit serial data transfer */ +#define I2S_DATASIZE_20BIT LL_I2S_DATASIZE_20BIT /**< 20-bit serial data transfer */ +#define I2S_DATASIZE_24BIT LL_I2S_DATASIZE_24BIT /**< 24-bit serial data transfer */ +#define I2S_DATASIZE_32BIT LL_I2S_DATASIZE_32BIT /**< 32-bit serial data transfer */ +/** @} */ + +/** @defgroup I2S_Clock_Source I2S Clock Source + * @{ + */ +#define I2S_CLOCK_SRC_96M LL_I2S_CLOCK_SRC_96M /**< Inactive state of SCLK is low */ +#define I2S_CLOCK_SRC_32M LL_I2S_CLOCK_SRC_32M /**< Inactive state of SCLK is high */ +/** @} */ + +/** @defgroup I2S_FIFO_LEVEL_MAX I2S FIFO Level Max + * @{ + */ +#define I2S_TX_FIFO_LEVEL_MAX 16 /**< I2S TX FIFO Level Max Value */ +#define I2S_RX_FIFO_LEVEL_MAX 16 /**< I2S RX FIFO Level Max Value */ +/** @} */ + +/** @defgroup I2S_Flags_definition I2S Flags Definition + * @{ + */ +#define I2S_FLAG_TXFO LL_I2S_STATUS_TXFO /**< TX FIFO write overflow flag */ +#define I2S_FLAG_TXFE LL_I2S_STATUS_TXFE /**< TX FIFO empty trigger flag */ +#define I2S_FLAG_RXFO LL_I2S_STATUS_RXFO /**< RX FIFO receive overflow flag */ +#define I2S_FLAG_RXDA LL_I2S_STATUS_RXDA /**< RX FIFO data available flag */ +/** @} */ + +/** @defgroup I2S_Interrupt_definition I2S Interrupt Definition + * @{ + */ +#define I2S_IT_TXFO LL_I2S_INT_TXFO /**< TX FIFO write overflow interrupt */ +#define I2S_IT_TXFE LL_I2S_INT_TXFE /**< TX FIFO empty trigger interrupt */ +#define I2S_IT_RXFO LL_I2S_INT_RXFO /**< RX FIFO receive overflow interrupt */ +#define I2S_IT_RXDA LL_I2S_INT_RXDA /**< RX FIFO data available interrupt */ +/** @} */ + +/** @defgroup I2S_Timeout_definition I2S Timeout_definition + * @{ + */ +#define HAL_I2S_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2S_Exported_Macros I2S Exported Macros + * @{ + */ + +/** @brief Reset I2S handle states. + * @param __HANDLE__ I2S handle. + * @retval None + */ +#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_I2S_STATE_RESET) + +/** @brief Enable the specified I2S peripheral. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->ENABLE, I2S_ENABLE_EN) + +/** @brief Disable the specified I2S peripheral. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->ENABLE, I2S_ENABLE_EN) + +/** @brief Enable the specified I2S clock. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE_CLOCK(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CLKEN, I2S_CLKEN_EN) + +/** @brief Disable the specified I2S clock. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE_CLOCK(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CLKEN, I2S_CLKEN_EN) + +/** @brief Enable the specified I2S transmitter block. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE_TX_BLOCK(__HANDLE__) ll_i2s_enable_txblock((__HANDLE__)->p_instance) + +/** @brief Disable the specified I2S transmitter block. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE_TX_BLOCK(__HANDLE__) ll_i2s_disable_txblock((__HANDLE__)->p_instance) + +/** @brief Enable the specified I2S receiver block. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE_RX_BLOCK(__HANDLE__) ll_i2s_enable_rxblock((__HANDLE__)->p_instance) + +/** @brief Disable the specified I2S receiver block. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE_RX_BLOCK(__HANDLE__) ll_i2s_disable_rxblock((__HANDLE__)->p_instance) + +/** @brief Enable the specified I2S transmitter channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __CH__ Specifies the I2S channel. + * @retval None + */ +#define __HAL_I2S_ENABLE_TX_CHANNEL(__HANDLE__, __CH__) ll_i2s_enable_tx((__HANDLE__)->p_instance, (__CH__)) + +/** @brief Disable the specified I2S transmitter channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __CH__ Specifies the I2S channel. + * @retval None + */ +#define __HAL_I2S_DISABLE_TX_CHANNEL(__HANDLE__, __CH__) ll_i2s_disable_tx((__HANDLE__)->p_instance, (__CH__)) + +/** @brief Enable the specified I2S receiver channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __CH__ Specifies the I2S channel. + * @retval None + */ +#define __HAL_I2S_ENABLE_RX_CHANNEL(__HANDLE__, __CH__) ll_i2s_enable_rx((__HANDLE__)->p_instance, (__CH__)) + +/** @brief Disable the specified I2S receiver channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __CH__ Specifies the I2S channel. + * @retval None + */ +#define __HAL_I2S_DISABLE_RX_CHANNEL(__HANDLE__, __CH__) ll_i2s_disable_rx((__HANDLE__)->p_instance, (__CH__)) + +/** @brief Flush the I2S transmitter FIFO. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_FLUSH_TX_FIFO(__HANDLE__) ll_i2s_clr_txfifo_all((__HANDLE__)->p_instance) + +/** @brief Flush the I2S receiver FIFO. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_FLUSH_RX_FIFO(__HANDLE__) ll_i2s_clr_rxfifo_all((__HANDLE__)->p_instance) + +/** @brief Enable the I2S DMA Request. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE_DMA(__HANDLE__) ll_i2s_enable_dma(__HANDLE__->p_instance) + +/** @brief Disable the I2S DMA Request. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE_DMA(__HANDLE__) ll_i2s_disable_dma(__HANDLE__->p_instance) + +/** @brief Reset the I2S TX DMA request to the lowest enabled channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_RESET_TXDMA(__HANDLE__) WRITE_REG((__HANDLE__)->p_instance->TXDMA_RST, I2S_TXDMA_RST) + +/** @brief Reset the I2S RX DMA request to the lowest enabled channel. + * @param __HANDLE__ Specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_RESET_RXDMA(__HANDLE__) WRITE_REG((__HANDLE__)->p_instance->RXDMA_RST, I2S_RXDMA_RST) + +/** @brief Enable the specified I2S interrupts. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref I2S_IT_TXFO TX FIFO write overflow interrupt + * @arg @ref I2S_IT_TXFE TX FIFO empty trigger interrupt + * @arg @ref I2S_IT_RXFO RX FIFO receive overflow interrupt + * @arg @ref I2S_IT_RXDA RX FIFO data available interrupt + * @retval None + */ +#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BITS((__HANDLE__)->p_instance->I2S_CHANNEL[0].INTMASK, (__INTERRUPT__)) + +/** @brief Disable the specified I2S interrupts. + * @param __HANDLE__ Specifies the I2S handle. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref I2S_IT_TXFO TX FIFO write overflow interrupt + * @arg @ref I2S_IT_TXFE TX FIFO empty trigger interrupt + * @arg @ref I2S_IT_RXFO RX FIFO receive overflow interrupt + * @arg @ref I2S_IT_RXDA RX FIFO data available interrupt + * @retval None + */ +#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) SET_BITS((__HANDLE__)->p_instance->I2S_CHANNEL[0].INTMASK, (__INTERRUPT__)) + +/** @brief Check whether the specified I2S flag is set or not. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref I2S_FLAG_TXFO TX FIFO write overflow flag + * @arg @ref I2S_FLAG_TXFE TX FIFO empty trigger flag + * @arg @ref I2S_FLAG_RXFO RX FIFO receive overflow flag + * @arg @ref I2S_FLAG_RXDA RX FIFO data available flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->I2S_CHANNEL[0].INTSTAT, (__FLAG__)) != 0) ? SET : RESET) + +/** @brief Clear the specified I2S flag. + * @param __HANDLE__ Specifies the I2S Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref I2S_FLAG_TXFO TX FIFO write overflow flag + * @arg @ref I2S_FLAG_RXFO RX FIFO receive overflow flag + * @retval None + */ +#define __HAL_I2S_CLEAR_FLAG(__HANDLE__, __FLAG__) do { \ + if ((__FLAG__) & I2S_FLAG_RXFO) \ + { \ + READ_BITS((__HANDLE__)->p_instance->I2S_CHANNEL[0].RXOVR, I2S_RXOVR_RXCHO);\ + } \ + if ((__FLAG__) & I2S_FLAG_TXFO) \ + { \ + READ_BITS((__HANDLE__)->p_instance->I2S_CHANNEL[0].TXOVR, I2S_TXOVR_TXCHO);\ + } \ + } while(0); + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2S_Private_Macro I2S Private Macros + * @{ + */ + +/** @brief Check if I2S Direction Mode is valid. + * @param __MODE__ I2S Direction Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_I2S_DIRECTION(__MODE__) (((__MODE__) == I2S_DIRECTION_FULL_DUPLEX) || \ + ((__MODE__) == I2S_DIRECTION_SIMPLEX_TX) || \ + ((__MODE__) == I2S_DIRECTION_SIMPLEX_RX)) + +/** @brief Check if I2S Data Size is valid. + * @param __DATASIZE__ I2S Data Size. + * @retval SET (__DATASIZE__ is valid) or RESET (__DATASIZE__ is invalid) + */ +#define IS_I2S_DATASIZE(__DATASIZE__) (((__DATASIZE__) == I2S_DATASIZE_12BIT) || \ + ((__DATASIZE__) == I2S_DATASIZE_16BIT) || \ + ((__DATASIZE__) == I2S_DATASIZE_20BIT) || \ + ((__DATASIZE__) == I2S_DATASIZE_24BIT) || \ + ((__DATASIZE__) == I2S_DATASIZE_32BIT)) + +/** @brief Check if I2S Clock Polarity is valid. + * @param __CPOL__ I2S Clock Polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_I2S_CPOL(__CPOL__) (((__CPOL__) == I2S_POLARITY_LOW) || \ + ((__CPOL__) == I2S_POLARITY_HIGH)) + +/** @brief Check if I2S Audio Frequency is valid. + * @param __FREQUENCY__ I2S Audio Frequency. + * @retval SET (__FREQUENCY__ is valid) or RESET (__FREQUENCY__ is invalid) + */ +#define IS_I2S_AUDIO_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) > 0) && ((__FREQUENCY__) <= 1500000)) + +/** @brief Check if I2S FIFO Threshold is valid. + * @param __THR__ I2S FIFO Threshold. + * @retval SET (__THR__ is valid) or RESET (__THR__ is invalid) + */ +#define IS_I2S_FIFO_THRESHOLD(__THR__) (((__THR__) >= 0) && ((__THR__) <= I2S_TX_FIFO_LEVEL_MAX)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_I2S_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initializations functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Sx peripheral: + + (+) User must implement hal_i2s_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_i2s_init() to configure the selected device with + the selected configuration: + (++) Data Size + (++) Clock Polarity + (++) Audio Frequency + + (+) Call the function hal_i2s_deinit() to restore the default configuration + of the selected I2Sx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the I2S according to the specified parameters + * in the i2s_init_t and initialize the associated handle. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_init(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief De-initialize the I2S peripheral. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_deinit(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Initialize the I2S MSP. + * @note This function should not be modified. When the callback is needed, + the hal_i2s_msp_deinit can be implemented in the user file. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_msp_init(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief De-initialize the I2S MSP. + * @note This function should not be modified. When the callback is needed, + the hal_i2s_msp_deinit can be implemented in the user file. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_msp_deinit(i2s_handle_t *p_i2s); + +/** @} */ + +/** @defgroup I2S_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2S + data transfers. + + [..] The I2S supports master and slave mode: + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_i2s_tx_cplt_callback(), hal_i2s_rx_cplt_callback() and hal_i2s_tx_rx_cplt_callback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The hal_i2s_error_callback() user callback will be executed when a communication error is detected. + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1-Line (simplex) and 2-Line (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in halfword, data of a channel. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in halfword, data of a channel. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_receive(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in blocking mode. + * @param[in] p_i2s: Pointer to a I2S handle which contains the configuration information for the specified I2S module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit_receive(i2s_handle_t *p_i2s, uint16_t *p_tx_data, uint16_t *p_rx_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with Interrupt. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in halfword, data of a channel. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit_it(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in halfword, data of a channel. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_receive_it(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] p_i2s: Pointer to a I2S handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit_receive_it(i2s_handle_t *p_i2s, uint16_t *p_tx_data, uint16_t *p_rx_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with DMA. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in halfword, data of a channel, ranging between 1 and 4095. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit_dma(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in halfword, data of a channel, ranging between 1 and 4095. + * For example, when 32 bytes of data need to be sent in each of the left and right channels, length = 16. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_receive_dma(i2s_handle_t *p_i2s, uint16_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. + * @param[in] p_i2s: Pointer to a I2S handle which contains the configuration information for the specified I2S module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_transmit_receive_dma(i2s_handle_t *p_i2s, uint16_t *p_tx_data, uint16_t *p_rx_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Start the I2S master clock. + * @note In case of SLAVE mode, this function will not take effect. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_start_clock(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Stop the I2S master clock. + * @note In case of SLAVE mode, this function will not take effect. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_stop_clock(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (blocking mode). + * @param[in] p_i2s: I2S handle. + * @note This procedure could be used for aborting any ongoing transfer (TX and RX), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable I2S Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: When exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_abort(i2s_handle_t *p_i2s); + +/** @} */ + +/** @addtogroup I2S_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle I2S interrupt request. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_irq_handler(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief TX Transfer completed callback. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_tx_cplt_callback(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief RX Transfer completed callback. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_rx_cplt_callback(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief TX/RX Transfer completed callback. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_tx_rx_cplt_callback(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief I2S error callback. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + **************************************************************************************** + */ +void hal_i2s_error_callback(i2s_handle_t *p_i2s); + +/** @} */ + +/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief I2S control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the I2S. + (+) hal_i2s_get_state() API can be helpful to check in run-time the state of the I2S peripheral + (+) hal_i2s_get_error() check in run-time Errors occurring during communication + (+) hal_i2s_set_timeout() set the timeout during internal process + (+) hal_i2s_set_tx_fifo_threshold() set the TX FIFO Threshold + (+) hal_i2s_set_rx_fifo_threshold() set the RX FIFO Threshold + (+) hal_i2s_get_tx_fifo_threshold() get the TX FIFO Threshold + (+) hal_i2s_get_rx_fifo_threshold() get the RX FIFO Threshold +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the I2S handle state. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @retval ::HAL_I2S_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_I2S_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_I2S_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_I2S_STATE_BUSY_TX: Data Transmii2son process is ongoing. + * @retval ::HAL_I2S_STATE_BUSY_RX: Data Reception process is ongoing. + * @retval ::HAL_I2S_STATE_ABORT: Peripheral with abort request ongoing. + * @retval ::HAL_I2S_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_i2s_state_t hal_i2s_get_state(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Return the I2S error code. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @return I2S error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_i2s_get_error(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Set the TX FIFO threshold. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[in] threshold: TX FIFO threshold value ranging bwtween 0x0U ~ 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_set_tx_fifo_threshold(i2s_handle_t *p_i2s, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Set the RX FIFO threshold. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @param[in] threshold: RX FIFO threshold value ranging bwtween 0x0U ~ 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_set_rx_fifo_threshold(i2s_handle_t *p_i2s, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Get the TX FIFO threshold. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @return TX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_i2s_get_tx_fifo_threshold(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Get the RX FIFO threshold. + * @param[in] p_i2s: Pointer to an I2S handle which contains the configuration information for the specified I2S module. + * @return RX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_i2s_get_rx_fifo_threshold(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Suspend some registers related to I2S configuration before sleep. + * @param[in] p_i2s: Pointer to a I2S handle which contains the configuration + * information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_suspend_reg(i2s_handle_t *p_i2s); + +/** + **************************************************************************************** + * @brief Restore some registers related to I2S configuration after sleep. + * This function must be used in conjunction with the hal_i2s_suspend_reg(). + * @param[in] p_i2s: Pointer to a I2S handle which contains the configuration + * information for the specified I2S module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_i2s_resume_reg(i2s_handle_t *p_i2s); + + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_I2S_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_iso7816.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_iso7816.h new file mode 100644 index 0000000..a34aef8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_iso7816.h @@ -0,0 +1,634 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_iso7816.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ISO7816 HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_ISO7816 ISO7816 + * @brief ISO7816 HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_ISO7816_H__ +#define __GR55xx_HAL_ISO7816_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_iso7816.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_ISO7816_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_ISO7816_state HAL ISO7816 State + * @{ + */ +/** + * @brief HAL ISO7816 State Enumerations definition + */ +typedef enum +{ + HAL_ISO7816_STATE_RESET = 0x00U, /**< Peripheral not initialized */ + HAL_ISO7816_STATE_READY = 0x20U, /**< Peripheral initialized and ready for use */ + HAL_ISO7816_STATE_BUSY = 0x24U, /**< An internal process is ongoing */ + HAL_ISO7816_STATE_BUSY_TX = 0x21U, /**< Data Transmission process is ongoing */ + HAL_ISO7816_STATE_BUSY_RX = 0x22U, /**< Data Reception process is ongoing */ + HAL_ISO7816_STATE_BUSY_TX_RX = 0x23U, /**< Data Transmission and Reception process is ongoing */ + HAL_ISO7816_STATE_ABORT = 0x08U, /**< Peripheral with abort request ongoing */ + HAL_ISO7816_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_ISO7816_STATE_ERROR = 0xE0U /**< Peripheral in error */ +} hal_iso7816_state_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_ISO7816_STRUCTURES Structures + * @{ + */ + +/** @defgroup ISO7816_Configuration ISO7816 Configuration + * @{ + */ +/** + * @brief ISO7816_init_structure ISO7816 init structure definition + */ +typedef struct +{ + uint32_t clk_div; /*!< clk_div is used for dividing the system clock, + and ISO7816 output clock is equal to (system clock)/(clk_div+1).*/ + uint32_t wait_time; /*!< Specifies the guard time value in terms of number of baud clocks */ + uint16_t guard_time; /*!< Specifies the maximum card response time (leading edge to leading edge) */ + uint8_t detect_coding; /*!< Specifies whether automatically detect coding convention during ATR receiption. */ +} iso7816_init_t; +/** @} */ +/** @} */ + +/** @defgroup HAL_ISO7816_MACRO Defines + * @{ + */ +/** + * @brief ISO7816_default_config InitStruct default configuration + */ +#define ISO7816_DEFAULT_CONFIG \ +{ \ + .clk_div = 0x2F, \ + .wait_time = 0x6B, \ + .guard_time = 0x00, \ + .detect_coding = ENABLE, \ +} +/** @} */ + +/** @addtogroup HAL_ISO7816_STRUCTURES Structures + * @{ + */ +/** @defgroup ISO7816_handle Handle + * @{ + */ + +/** + * @brief ISO7816 handle Structure definition + */ +typedef struct _iso7816_handle_t +{ + iso7816_regs_t *p_instance; /**< ISO7816 registers base address */ + iso7816_init_t init; /**< ISO7816 configuration parameters */ + uint8_t *p_tx_rx_buffer; /**< Pointer to ISO7816 Tx&Rx transfer Buffer */ + uint16_t buffer_size; /**< ISO7816 Tx Transfer size */ + uint16_t tx_xfer_size; /**< ISO7816 Tx Transfer size */ + __IO uint16_t tx_xfer_count; /**< ISO7816 Tx Transfer Counter */ + uint16_t rx_xfer_size; /**< ISO7816 Rx Transfer size */ + __IO uint16_t rx_xfer_count; /**< ISO7816 Rx Transfer Counter */ + __IO hal_lock_t lock; /**< Locking object */ + __IO hal_iso7816_state_t state; /**< ISO7816 communication state */ + __IO hal_iso7816_state_t tx_state; /**< ISO7816 state information related to Tx operations. */ + __IO hal_iso7816_state_t rx_state; /**< ISO7816 state information related to Rx operations. */ + __IO uint32_t previous_action; /**< ISO7816 previous_action */ + __IO uint32_t error_code; /**< ISO7816 error code */ + uint32_t retention[6]; /**< ISO7816 important register information. */ +} iso7816_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_ISO7816_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup ISO7816_Callback ISO7816 Callback + * @{ + */ + + /** + * @brief HAL_ISO7816 Callback function definition + */ + +typedef struct _iso7816_callback +{ + void (*iso7816_msp_init)(iso7816_handle_t *p_iso7816); /**< ISO7816 init MSP callback */ + void (*iso7816_msp_deinit)(iso7816_handle_t *p_iso7816); /**< ISO7816 de-init MSP callback */ + void (*iso7816_error_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 error callback */ + void (*iso7816_abort_cplt_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 abort completed callback */ + void (*iso7816_presence_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 card presence state changed callback */ + void (*iso7816_atr_cplt_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 reseive atr completed callback */ + void (*iso7816_tx_cplt_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 rx transfer completed callback */ + void (*iso7816_rx_cplt_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 tx transfer completed callback */ + void (*iso7816_tx_rx_cplt_callback)(iso7816_handle_t *p_iso7816); /**< ISO7816 tx/rx transfer completed callback */ +} iso7816_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_ISO7816_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ISO7816_Exported_Constants ISO7816 Exported Constants + * @{ + */ + +/** @defgroup ISO7816_ACTION Action state + * @{ + */ +#define HAL_ISO7816_ACTION_NONE LL_ISO7816_ACTION_NONE /**< Do Nothing. */ +#define HAL_ISO7816_ACTION_OFF LL_ISO7816_ACTION_OFF /**< Switch Off. */ +#define HAL_ISO7816_ACTION_STOPCLK LL_ISO7816_ACTION_STOPCLK /**< Stop the clock. */ +#define HAL_ISO7816_ACTION_ON LL_ISO7816_ACTION_ON /**< Switch on and receive ATR. */ +#define HAL_ISO7816_ACTION_WARMRST LL_ISO7816_ACTION_WARMRST /**< Trigger warm reset and receive ATR.*/ +#define HAL_ISO7816_ACTION_RX LL_ISO7816_ACTION_RX /**< Receive. */ +#define HAL_ISO7816_ACTION_TX LL_ISO7816_ACTION_TX /**< Transmit. */ +#define HAL_ISO7816_ACTION_TXRX LL_ISO7816_ACTION_TXRX /**< Transmit, followed by RX. */ +/** @} */ + +/** @defgroup ISO7816_Interrupt_definition ISO7816 Interrupt Definition + * @{ + */ +#define HAL_ISO7816_INTR_TEST LL_ISO7816_INTR_TEST /**< Test interrupt */ +#define HAL_ISO7816_INTR_PRESENCE LL_ISO7816_INTR_PRESENCE /**< Source presence interrupt */ +#define HAL_ISO7816_INTR_STATE_ERR LL_ISO7816_INTR_STATE_ERR /**< Source state error interrupt */ +#define HAL_ISO7816_INTR_DMA_ERR LL_ISO7816_INTR_DMA_ERR /**< Source dma error interrupt */ +#define HAL_ISO7816_INTR_RETRY_ERR LL_ISO7816_INTR_RETRY_ERR /**< Source retry error interrupt */ +#define HAL_ISO7816_INTR_RX_ERR LL_ISO7816_INTR_RX_ERR /**< Source rx error interrupt */ +#define HAL_ISO7816_INTR_DONE LL_ISO7816_INTR_DONE /**< Source done error interrupt */ +/** @} */ + + +/** @defgroup ISO7816_HAL_CARD_PRESENCE Card Presence Defines + * @{ + */ +#define HAL_ISO7816_CARD_ABSENT LL_ISO7816_CARD_ABSENT /**< SIM Card is absent. */ +#define HAL_ISO7816_CARD_PRESENT LL_ISO7816_CARD_PRESENT /**< SIM Card is present. */ +/** @} */ + +/** @defgroup ISO7816_HAL_IO_STATES IO States Defines + * @{ + */ +#define HAL_ISO7816_IO_STATE_OFF LL_ISO7816_IO_STATE_OFF /**< Off */ +#define HAL_ISO7816_IO_STATE_IDLE LL_ISO7816_IO_STATE_IDLE /**< Idle */ +#define HAL_ISO7816_IO_STATE_RX_WAIT LL_ISO7816_IO_STATE_RX_WAIT /**< Receive Wait */ +#define HAL_ISO7816_IO_STATE_RX LL_ISO7816_IO_STATE_RX /**< Receive */ +#define HAL_ISO7816_IO_STATE_TX LL_ISO7816_IO_STATE_TX /**< Transmit */ +#define HAL_ISO7816_IO_STATE_TX_GUARD LL_ISO7816_IO_STATE_TX_GUARD /**< Transmit Guard */ +/** @} */ + +/** @defgroup ISO7816_HAL_PWR_STATES Power States Defines + * @{ + */ +#define HAL_ISO7816_PWR_STATE_OFF LL_ISO7816_PWR_STATE_OFF /**< Off */ +#define HAL_ISO7816_PWR_STATE_PWRUP_VCC LL_ISO7816_PWR_STATE_PWRUP_VCC /**< Power up VCC */ +#define HAL_ISO7816_PWR_STATE_PWRUP_RST LL_ISO7816_PWR_STATE_PWRUP_RST /**< Power up reset */ +#define HAL_ISO7816_PWR_STATE_PWRDN_RST LL_ISO7816_PWR_STATE_PWRDN_RST /**< Power Down reset */ +#define HAL_ISO7816_PWR_STATE_PWRDN_VCC LL_ISO7816_PWR_STATE_PWRDN_VCC /**< Power Down VCC */ +#define HAL_ISO7816_PWR_STATE_STOP_PRE LL_ISO7816_PWR_STATE_STOP_PRE /**< Preparing Clock Stop */ +#define HAL_ISO7816_PWR_STATE_STOP LL_ISO7816_PWR_STATE_STOP /**< Clock Stopped */ +#define HAL_ISO7816_PWR_STATE_STOP_POST LL_ISO7816_PWR_STATE_STOP_POST /**< Exiting Clock Stop */ +#define HAL_ISO7816_PWR_STATE_IDLE LL_ISO7816_PWR_STATE_IDLE /**< Idle */ +#define HAL_ISO7816_PWR_STATE_RX_TS0 LL_ISO7816_PWR_STATE_RX_TS0 /**< RX TS Character */ +#define HAL_ISO7816_PWR_STATE_RX_TS1 LL_ISO7816_PWR_STATE_RX_TS1 /**< RX TS Character */ +#define HAL_ISO7816_PWR_STATE_RX LL_ISO7816_PWR_STATE_RX /**< Receive */ +#define HAL_ISO7816_PWR_STATE_TX LL_ISO7816_PWR_STATE_TX /**< Transmit */ +#define HAL_ISO7816_PWR_STATE_TX_RX LL_ISO7816_PWR_STATE_TX_RX /**< Transmit and Receive */ +/** @} */ + +/** @defgroup ISO7816_Error_Code ISO7816 Error Code + * @{ + */ +#define HAL_ISO7816_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_ISO7816_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_ISO7816_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_ISO7816_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ISO7816_Exported_Macros ISO7816 Exported Macros + * @{ + */ + +/** @brief Enable the specified ISO7816 interrupts. + * @param __HANDLE__ Specifies the ISO7816 Handle. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref HAL_ISO7816_INTR_TEST Test interrupt + * @arg @ref HAL_ISO7816_INTR_PRESENCE Presence interrupt + * @arg @ref HAL_ISO7816_INTR_STATE_ERR State error interrupt + * @arg @ref HAL_ISO7816_INTR_DMA_ERR DMA error interrupt + * @arg @ref HAL_ISO7816_INTR_RETRY_ERR Retry error interrupt + * @arg @ref HAL_ISO7816_INTR_RX_ERR Rx error interrupt + * @arg @ref HAL_ISO7816_INTR_DONE Done error interrupt + * @retval None + */ +#define __HAL_ISO7816_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BITS((__HANDLE__)->p_instance->INT_MASK, (__INTERRUPT__)) + +/** @brief Disable the specified ISO7816 interrupts. + * @param __HANDLE__ Specifies the ISO7816 handle. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref HAL_ISO7816_INTR_TEST Test interrupt + * @arg @ref HAL_ISO7816_INTR_PRESENCE Presence interrupt + * @arg @ref HAL_ISO7816_INTR_STATE_ERR State error interrupt + * @arg @ref HAL_ISO7816_INTR_DMA_ERR DMA error interrupt + * @arg @ref HAL_ISO7816_INTR_RETRY_ERR Retry error interrupt + * @arg @ref HAL_ISO7816_INTR_RX_ERR Rx error interrupt + * @arg @ref HAL_ISO7816_INTR_DONE Done error interrupt + * @retval None + */ +#define __HAL_ISO7816_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BITS((__HANDLE__)->p_instance->INT_MASK, (__INTERRUPT__)) + +/** @brief Get the ISO7816 interrupt flags. + * @param __ISO7816_REGS ISO7816 Register. + * @retval ISO78116 Interrupt definitions. + */ +#define __HAL_ISO7816_IT_GET_IT_FLAG(__ISO7816_REGS) ll_iso7816_get_it_flag(__ISO7816_REGS) +/** @} */ +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_ISO7816_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + * @brief Transimit data in blocking mode + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param tx_size Bytes of data to transmit + * @param timeout Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_transmit(iso7816_handle_t *p_iso7816, uint16_t tx_size, uint32_t timeout); + +/** + * @brief Receive data in blocking mode + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param rx_size Bytes of data to receive + * @param timeout Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_receive(iso7816_handle_t *p_iso7816, uint16_t rx_size, uint32_t timeout); + +/** + * @brief Transimit and receive data in blocking mode + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param tx_size Bytes of data to transmit + * @param rx_size Bytes of data to receive + * @param timeout Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_transmit_receive(iso7816_handle_t *p_iso7816, uint16_t tx_size,uint16_t rx_size, uint32_t timeout); + +/** + * @brief Transimit data in non-blocking mode with Interrupt + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param tx_size Bytes of data to transmit + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_transmit_it(iso7816_handle_t *p_iso7816, uint16_t tx_size); + +/** + * @brief Receive data in non-blocking mode with Interrupt + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param rx_size Bytes of data to receive + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_receive_it(iso7816_handle_t *p_iso7816, uint16_t rx_size); + +/** + * @brief Transimit and receive data in non-blocking mode with Interrupt + * + * @param p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @param tx_size: Bytes of data to transfer. + * @param rx_size: Bytes of data to receive. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ + +hal_status_t hal_iso7816_transmit_receive_it(iso7816_handle_t *p_iso7816, uint16_t tx_size, uint16_t rx_size); + +/** + * @brief Transfer Abort functions + * + * @param p_iso7816 Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +hal_status_t hal_iso7816_abort(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Initializes the ISO7816 according to the specified parameters + * in the iso7816_init_t and initialize the associated handle. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration + * information for the specified ISO7816. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_iso7816_init(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief De-initializes the ISO7816 according to the specified parameters + * in the iso7816_init_t and initialize the associated handle. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration + * information for the specified ISO7816. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_iso7816_deinit(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Initialize the ISO7816 MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_iso7816_msp_init could be implemented in the user file. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + **************************************************************************************** + */ +void hal_iso7816_msp_init(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief De-initialize the ISO7816 MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_iso7816_msp_deinit could be implemented in the user file. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + **************************************************************************************** + */ +void hal_iso7816_msp_deinit(iso7816_handle_t *p_iso7816); +/** + **************************************************************************************** + * @brief Handle ISO7816 interrupt request. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816. + **************************************************************************************** + */ +void hal_iso7816_irq_handler(iso7816_handle_t *p_iso7816); + + +/** + **************************************************************************************** + * @brief Card presence state changed callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_presence_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Receive ART completed callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_atr_cplt_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Rx Transfer completed callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_rx_cplt_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Tx Transfer completed callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_tx_cplt_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Tx and Rx Transfer completed callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_tx_rx_cplt_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief ISO7816 error callback. + * @param[in] p_iso7816: Pointer to an ISO7816 handle which contains the configuration information for the specified ISO7816 module. + **************************************************************************************** + */ +void hal_iso7816_error_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief ISO7816 Abort Completed callback. + * @param[in] p_iso7816: ISO7816 handle. + **************************************************************************************** + */ +void hal_iso7816_abort_cplt_callback(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Return the ISO7816 handle state. + * @param[in] p_iso7816: ISO7816 handle. + * @retval ::HAL_ISO7816_STATE_RESET + * @retval ::HAL_ISO7816_STATE_READY + * @retval ::HAL_ISO7816_STATE_BUSY + * @retval ::HAL_ISO7816_STATE_BUSY_TX + * @retval ::HAL_ISO7816_STATE_BUSY_RX + * @retval ::HAL_ISO7816_STATE_BUSY_TX_RX + * @retval ::HAL_ISO7816_STATE_ABORT + * @retval ::HAL_ISO7816_STATE_TIMEOUT + * @retval ::HAL_ISO7816_STATE_ERROR + **************************************************************************************** + */ +hal_iso7816_state_t hal_iso7816_get_state(iso7816_handle_t *p_iso7816); + +/** + * @brief Request ISO7816 to go to the next action. + * @param p_iso7816: ISO7816 handle. + * @param action: This parameter can be one of the following values: + * @arg @ref HAL_ISO7816_ACTION_NONE + * @arg @ref HAL_ISO7816_ACTION_OFF + * @arg @ref HAL_ISO7816_ACTION_STOPCLK + * @arg @ref HAL_ISO7816_ACTION_ON + * @arg @ref HAL_ISO7816_ACTION_WARMRST + * @arg @ref HAL_ISO7816_ACTION_RX + * @arg @ref HAL_ISO7816_ACTION_TX + * @arg @ref HAL_ISO7816_ACTION_TXRX + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + */ +hal_status_t hal_iso7816_set_action(iso7816_handle_t *p_iso7816, uint32_t action); + +/** + * @brief Get ISO7816 Power States. + * @param p_iso7816: ISO7816 handle. + * @retval Returned value can be one of the following values: + * @arg @ref HAL_ISO7816_PWR_STATE_OFF + * @arg @ref HAL_ISO7816_PWR_STATE_PWRUP_VCC + * @arg @ref HAL_ISO7816_PWR_STATE_PWRUP_RST + * @arg @ref HAL_ISO7816_PWR_STATE_PWRDN_RST + * @arg @ref HAL_ISO7816_PWR_STATE_PWRDN_VCC + * @arg @ref HAL_ISO7816_PWR_STATE_STOP_PRE + * @arg @ref HAL_ISO7816_PWR_STATE_STOP + * @arg @ref HAL_ISO7816_PWR_STATE_STOP_POST + * @arg @ref HAL_ISO7816_PWR_STATE_IDLE + * @arg @ref HAL_ISO7816_PWR_STATE_RX_TS0 + * @arg @ref HAL_ISO7816_PWR_STATE_RX_TS1 + * @arg @ref HAL_ISO7816_PWR_STATE_RX + * @arg @ref HAL_ISO7816_PWR_STATE_TX + * @arg @ref HAL_ISO7816_PWR_STATE_TX_RX + */ +uint32_t hal_iso7816_get_power_states(iso7816_handle_t *p_iso7816); + +/** + * @brief Set divide ISO7816 clock. + * @note Divide SIM clock by this value+1 to define ETU length. The reset value + * is the one, needed for theATR. + * @param p_iso7816: ISO7816 handle. + * @param divide This parameter should range between 0x0 and 0x3FF. + * @retval None. + */ +hal_status_t hal_iso7816_set_etudiv(iso7816_handle_t *p_iso7816, uint32_t divide); + +/** + **************************************************************************************** + * @brief Return the ISO7816 error code. + * @param[in] p_iso7816: ISO7816 handle. + * @return ISO7816 Error Code + **************************************************************************************** + */ +uint32_t hal_iso7816_get_error(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Suspend some registers related to ISO7816 configuration before sleep. + * @param[in] p_iso7816: ISO7816 handle. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_iso7816_suspend_reg(iso7816_handle_t *p_iso7816); + +/** + **************************************************************************************** + * @brief Restore some registers related to ISO7816 configuration after sleep. + * This function must be used in conjunction with the hal_iso7816_suspend_reg(). + * @param[in] p_iso7816: ISO7816 handle. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_iso7816_resume_reg(iso7816_handle_t *p_iso7816); + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_ISO7816_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio.h new file mode 100644 index 0000000..8d615f3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio.h @@ -0,0 +1,341 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_msio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of MSIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_MSIO MSIO + * @brief MSIO HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_MSIO_H__ +#define __GR55xx_HAL_MSIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_msio.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_MSIO_ENUMERATIONS Enumerations + * @{ + */ + +/** + * @brief MSIO Bit SET and Bit RESET enumerations + */ +typedef enum +{ + MSIO_PIN_RESET = 0U, /**< MSIO pin low level. */ + MSIO_PIN_SET /**< MSIO pin high level.*/ +} msio_pin_state_t; + +/** @} */ + +/** @addtogroup HAL_MSIO_STRUCTURES Structures + * @{ + */ + +/** + * @brief MSIO init structure definition + */ +typedef struct _msio_init +{ + uint32_t pin; /**< Specifies the MSIO pins to be configured. + This parameter can be any value of @ref MSIO_pins */ + + uint32_t direction; /**< Specifies the direction for the selected pins. + This parameter can be a value of @ref MSIO_direction */ + + uint32_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref MSIO_mode */ + + uint32_t pull; /**< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref MSIO_pull */ + + uint32_t mux; /**< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIOEx_Mux_Function_Selection. */ +} msio_init_t; + +/** @} */ + +/** + * @defgroup HAL_MSIO_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup MSIO_Exported_Constants MSIO Exported Constants + * @{ + */ + +/** @defgroup MSIO_pins MSIO pins + * @{ + */ +#define MSIO_PIN_0 ((uint16_t)0x0001U) /**< Pin 0 selected */ +#define MSIO_PIN_1 ((uint16_t)0x0002U) /**< Pin 1 selected */ +#define MSIO_PIN_2 ((uint16_t)0x0004U) /**< Pin 2 selected */ +#define MSIO_PIN_3 ((uint16_t)0x0008U) /**< Pin 3 selected */ +#define MSIO_PIN_4 ((uint16_t)0x0010U) /**< Pin 4 selected */ + +#define MSIO_PIN_ALL ((uint16_t)0x001FU) /**< All pins selected */ + +#define MSIO_PIN_MASK (0x0000001FU) /**< PIN mask for assert test */ +/** @} */ + +/** @defgroup MSIO_direction MSIO direction + * @{ + */ +#define MSIO_DIRECTION_NONE LL_MSIO_DIRECTION_NONE /**< Disable input & output */ +#define MSIO_DIRECTION_INPUT LL_MSIO_DIRECTION_INPUT /**< Only Input */ +#define MSIO_DIRECTION_OUTPUT LL_MSIO_DIRECTION_OUTPUT /**< Only Output */ +#define MSIO_DIRECTION_INOUT LL_MSIO_DIRECTION_INOUT /**< Input & Output */ +/** @} */ + +/** @defgroup MSIO_mode MSIO mode + * @brief MSIO Analog or Digital mode + * @{ + */ +#define MSIO_MODE_ANALOG LL_MSIO_MODE_ANALOG /**< Analog IO */ +#define MSIO_MODE_DIGITAL LL_MSIO_MODE_DIGITAL /**< Digital IO */ +/** @} */ + +/** @defgroup MSIO_pull MSIO pull + * @brief MSIO Pull-Up or Pull-Down Activation + * @{ + */ +#define MSIO_NOPULL LL_MSIO_PULL_NO /**< No Pull-up or Pull-down activation */ +#define MSIO_PULLUP LL_MSIO_PULL_UP /**< Pull-up activation */ +#define MSIO_PULLDOWN LL_MSIO_PULL_DOWN /**< Pull-down activation */ +/** @} */ + +/** + * @brief MSIO_default_config initStruct default configuartion + */ +#define MSIO_DEFAULT_CONFIG \ +{ \ + .pin = MSIO_PIN_ALL, \ + .direction = MSIO_DIRECTION_INPUT, \ + .mode = MSIO_MODE_DIGITAL, \ + .pull = MSIO_PULLDOWN, \ + .mux = GPIO_MUX_7, \ +} +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup MSIO_Exported_Macros MSIO Exported Macros + * @{ + */ + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup MSIO_Private_Macros MSIO Private Macros + * @{ + */ + +/** + * @brief Check if MSIO pin action is valid. + * @param __ACTION__ MSIO pin action. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_MSIO_PIN_ACTION(__ACTION__) (((__ACTION__) == MSIO_PIN_RESET) || ((__ACTION__) == MSIO_PIN_SET)) + +/** + * @brief Check if MSIO pins are valid. + * @param __PIN__ MSIO pins. + * @retval SET (__PIN__ is valid) or RESET (__PIN__ is invalid) + */ +#define IS_MSIO_PIN(__PIN__) ((((__PIN__) & MSIO_PIN_MASK) != 0x00U) && \ + (((__PIN__) & ~MSIO_PIN_MASK) == 0x00U)) + +/** + * @brief Check if MSIO direction is valid. + * @param __DIR__ MSIO direction. + * @retval SET (__DIR__ is valid) or RESET (__DIR__ is invalid) + */ +#define IS_MSIO_DIRECTION(__DIR__) (((__DIR__) == MSIO_DIRECTION_NONE) || \ + ((__DIR__) == MSIO_DIRECTION_INPUT) || \ + ((__DIR__) == MSIO_DIRECTION_OUTPUT) || \ + ((__DIR__) == MSIO_DIRECTION_INOUT)) + +/** + * @brief Check if MSIO mode is valid. + * @param __MODE__ MSIO mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_MSIO_MODE(__MODE__) (((__MODE__) == MSIO_MODE_ANALOG) || \ + ((__MODE__) == MSIO_MODE_DIGITAL)) + +/** + * @brief Check if MSIO pull type is valid. + * @param __PULL__ MSIO pull type. + * @retval SET (__PULL__ is valid) or RESET (__PULL__ is invalid) + */ +#define IS_MSIO_PULL(__PULL__) (((__PULL__) == MSIO_NOPULL) || \ + ((__PULL__) == MSIO_PULLUP) || \ + ((__PULL__) == MSIO_PULLDOWN)) + +/** @} */ + +/** @} */ + +/* Include MSIO HAL Extended module */ +#include "gr55xx_hal_msio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_MSIO_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup MSIO_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the MSIOx peripheral according to the specified parameters in the @ref msio_init_t. + * @param[in] MSIOx: MSIO peripheral port. + * @param[in] p_msio_init: Pointer to an @ref msio_init_t structure that contains + * the configuration information for the specified MSIO peripheral port. + **************************************************************************************** + */ +void hal_msio_init(msio_pad_t MSIOx, msio_init_t *p_msio_init); + +/** + **************************************************************************************** + * @brief De-initialize the MSIOx peripheral registers to their default reset values. + * @param[in] MSIOx: MSIO peripheral port. + * @param[in] msio_pin: Specifies the port bit to be written. + * This parameter can be a combination of the following values: + * @arg @ref MSIO_PIN_0 + * @arg @ref MSIO_PIN_1 + * @arg @ref MSIO_PIN_2 + * @arg @ref MSIO_PIN_3 + * @arg @ref MSIO_PIN_4 + * @arg @ref MSIO_PIN_ALL + **************************************************************************************** + */ +void hal_msio_deinit(msio_pad_t MSIOx, uint32_t msio_pin); + +/** @} */ + +/** @addtogroup MSIO_Exported_Functions_Group2 IO operation functions + * @brief MSIO Read, Write, and Toggle management functions. + * @{ + */ + +/** + **************************************************************************************** + * @brief Read the specified input port pin. + * @param[in] MSIOx: MSIO peripheral port. + * @param[in] msio_pin: Specifies the port bit to be read. + * This parameter can be one of the following values: + * @arg @ref MSIO_PIN_0 + * @arg @ref MSIO_PIN_1 + * @arg @ref MSIO_PIN_2 + * @arg @ref MSIO_PIN_3 + * @arg @ref MSIO_PIN_4 + * @retval ::MSIO_PIN_RESET: MSIO pin low level. + * @retval ::MSIO_PIN_SET: MSIO pin high level. + **************************************************************************************** + */ +msio_pin_state_t hal_msio_read_pin(msio_pad_t MSIOx, uint16_t msio_pin); + +/** + **************************************************************************************** + * @brief Set or clear the selected data port bit. + * @param[in] MSIOx: MSIO peripheral port. + * @param[in] msio_pin: Specifies the port bit to be written. + * This parameter can be a combination of the following values: + * @arg @ref MSIO_PIN_0 + * @arg @ref MSIO_PIN_1 + * @arg @ref MSIO_PIN_2 + * @arg @ref MSIO_PIN_3 + * @arg @ref MSIO_PIN_4 + * @arg @ref MSIO_PIN_ALL + * @param[in] pin_state: Specifies the value to be written to the selected bit. + * This parameter can be one of the MSIO_PinState enum values: + * @arg MSIO_PIN_RESET: to clear the port pin + * @arg MSIO_PIN_SET: to set the port pin + **************************************************************************************** + */ +void hal_msio_write_pin(msio_pad_t MSIOx, uint16_t msio_pin, msio_pin_state_t pin_state); + +/** + **************************************************************************************** + * @brief Toggle the specified MSIO pin. + * @param[in] MSIOx: MSIO peripheral port. + * @param[in] msio_pin: Specifies the pin to be toggled. + * This parameter can be a combination of the following values: + * @arg @ref MSIO_PIN_0 + * @arg @ref MSIO_PIN_1 + * @arg @ref MSIO_PIN_2 + * @arg @ref MSIO_PIN_3 + * @arg @ref MSIO_PIN_4 + * @arg @ref MSIO_PIN_ALL + **************************************************************************************** + */ +void hal_msio_toggle_pin(msio_pad_t MSIOx, uint16_t msio_pin); + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_MSIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio_ex.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio_ex.h new file mode 100644 index 0000000..4f89011 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_msio_ex.h @@ -0,0 +1,176 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_msio_ex.h + * @author BLE Driver Team + * @brief Header file containing extended macro of MSIO HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_MSIOEx MSIOEx + * @brief MSIOEx HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_MSIO_EX_H__ +#define __GR55xx_HAL_MSIO_EX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_msio.h" + +/* Exported types ------------------------------------------------------------*/ + +/** + * @defgroup HAL_MSIOEX_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup MSIOEx_Exported_Constants MSIOEx Exported Constants + * @{ + */ + +/** @defgroup MSIOEx_Mux_Mode MSIOEx Mux Mode definition + * @{ + */ +#define MSIO_MUX_0 LL_MSIO_MUX_0 /**< MSIO mux mode 0 */ +#define MSIO_MUX_1 LL_MSIO_MUX_1 /**< MSIO mux mode 1 */ +#define MSIO_MUX_2 LL_MSIO_MUX_2 /**< MSIO mux mode 2 */ +#define MSIO_MUX_3 LL_MSIO_MUX_3 /**< MSIO mux mode 3 */ +#define MSIO_MUX_4 LL_MSIO_MUX_4 /**< MSIO mux mode 4 */ +#define MSIO_MUX_5 LL_MSIO_MUX_5 /**< MSIO mux mode 5 */ +#define MSIO_MUX_6 LL_MSIO_MUX_6 /**< MSIO mux mode 6 */ +#define MSIO_MUX_7 LL_MSIO_MUX_7 /**< MSIO mux mode 7 */ +/** @} */ + +/** @defgroup MSIOEx_Mux_Function_Selection MSIOEx Mux function selection + * @{ + */ + +#if defined (GR551xx) +/*---------------------------------- GR551xx ------------------------------*/ + +/** @defgroup MSIOEx_Common_Selection MSIO PIN common MUX selection(Available for all MSIO pins) + * @{ + */ + +#define MSIO_PIN_MUX_GPIO MSIO_MUX_7 /**< MSIO PIN x Mux Select GPIO */ + +/** @} */ + +/** @defgroup MSIOEx_PIN0_Mux_Selection MSIO_PIN0 MUX selection + * @{ + */ +#define MSIO_PIN0_MUX_PWM0_A MSIO_MUX_0 /**< MSIO_PIN0 Mux Select PWM0_A */ +#define MSIO_PIN0_MUX_UART0_TX MSIO_MUX_1 /**< MSIO_PIN0 Mux Select UART0_TX */ +#define MSIO_PIN0_MUX_UART1_TX MSIO_MUX_2 /**< MSIO_PIN0 Mux Select UART1_TX */ +#define MSIO_PIN0_MUX_I2C0_SCL MSIO_MUX_3 /**< MSIO_PIN0 Mux Select I2C0_SCL */ +#define MSIO_PIN0_MUX_I2C1_SCL MSIO_MUX_4 /**< MSIO_PIN0 Mux Select I2C1_SCL */ +/** @} */ + +/** @defgroup MSIOEx_PIN1_Mux_Selection MSIO_PIN1 MUX selection + * @{ + */ +#define MSIO_PIN1_MUX_PWM0_B MSIO_MUX_0 /**< MSIO_PIN1 Mux Select PWM0_B */ +#define MSIO_PIN1_MUX_UART0_RX MSIO_MUX_1 /**< MSIO_PIN1 Mux Select UART0_RX */ +#define MSIO_PIN1_MUX_UART1_RX MSIO_MUX_2 /**< MSIO_PIN1 Mux Select UART1_RX */ +#define MSIO_PIN1_MUX_I2C0_SDA MSIO_MUX_3 /**< MSIO_PIN1 Mux Select I2C0_SDA */ +#define MSIO_PIN1_MUX_I2C1_SDA MSIO_MUX_4 /**< MSIO_PIN1 Mux Select I2C1_SDA */ +/** @} */ + +/** @defgroup MSIOEx_PIN2_Mux_Selection MSIO_PIN2 MUX selection + * @{ + */ +#define MSIO_PIN2_MUX_PWM0_C MSIO_MUX_0 /**< MSIO_PIN2 Mux Select PWM0_C */ +/** @} */ + +/** @defgroup MSIOEx_PIN3_Mux_Selection MSIO_PIN3 MUX selection + * @{ + */ +#define MSIO_PIN3_MUX_PWM1_A MSIO_MUX_0 /**< MSIO_PIN3 Mux Select PWM1_A */ +#define MSIO_PIN3_MUX_UART0_RTS MSIO_MUX_1 /**< MSIO_PIN3 Mux Select UART0_RTS */ +#define MSIO_PIN3_MUX_UART1_RTS MSIO_MUX_2 /**< MSIO_PIN3 Mux Select UART1_RTS */ +#define MSIO_PIN3_MUX_I2C0_SCL MSIO_MUX_3 /**< MSIO_PIN3 Mux Select I2C0_SCL */ +#define MSIO_PIN3_MUX_I2C1_SCL MSIO_MUX_4 /**< MSIO_PIN3 Mux Select I2C1_SCL */ +/** @} */ + +/** @defgroup MSIOEx_PIN4_Mux_Selection MSIO_PIN4 MUX selection + * @{ + */ +#define MSIO_PIN4_MUX_PWM1_B MSIO_MUX_0 /**< MSIO_PIN4 Mux Select PWM1_B */ +#define MSIO_PIN4_MUX_UART0_CTS MSIO_MUX_1 /**< MSIO_PIN4 Mux Select UART0_CTS */ +#define MSIO_PIN4_MUX_UART1_CTS MSIO_MUX_2 /**< MSIO_PIN4 Mux Select UART1_CTS */ +#define MSIO_PIN4_MUX_I2C0_SDA MSIO_MUX_3 /**< MSIO_PIN4 Mux Select I2C0_SDA */ +#define MSIO_PIN4_MUX_I2C1_SDA MSIO_MUX_4 /**< MSIO_PIN4 Mux Select I2C1_SDA */ +/** @} */ + +/** + * @brief Check if MSIO mux mode is valid. + * @param __MUX__ MSIO mux mode. + * @retval SET (__ACTION__ is valid) or RESET (__ACTION__ is invalid) + */ +#define IS_MSIO_MUX(__MUX__) (((__MUX__) <= MSIO_MUX_7)) + +/*------------------------------------------------------------------------------------------*/ +#endif /* GR551xx */ + +/** @} */ + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_MSIO_EX_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pkc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pkc.h new file mode 100644 index 0000000..484355e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pkc.h @@ -0,0 +1,1044 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_pkc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PKC HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_PKC PKC + * @brief PKC HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_PKC_H__ +#define __GR55xx_HAL_PKC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_pkc.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_PKC_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_PKC_state HAL PKC state + * @{ + */ + +/** + * @brief HAL PKC State Enumerations definition + */ +typedef enum +{ + HAL_PKC_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_PKC_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_PKC_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_PKC_STATE_ERROR = 0x04, /**< Peripheral in error */ + HAL_PKC_STATE_TIMEOUT = 0x08, /**< Peripheral in timeout */ + +} hal_pkc_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_PKC_STRUCTURES Structures + * @{ + */ + +/** @defgroup PKC_Configuration PKC Configuration + * @{ + */ + +/** + * @brief PKC ECC Point Structure definition + */ +typedef struct _ll_ecc_point ecc_point_t; + +/** + * @brief PKC ECC P-256 Elliptic Curve Init Structure definition + */ +typedef struct _ll_ecc_curve_init ecc_curve_init_t; + +/** + * @brief PKC Init Structure definition + */ +typedef struct +{ + ecc_curve_init_t *p_ecc_curve; /**< Specifies the pointer to elliptic curve description */ + + uint32_t data_bits; /**< Specifies the Data size: 256 ~ 2048 bits */ + + uint32_t secure_mode; /**< Specifies the Secure Mode. It indicates that DPA-resistance software algorithm + and hardware measures are applied at a cost of about 35%- 50% performance loss. + This parameter can be a value of @ref PKC_Secure_Mode. */ + + uint32_t (*random_func)(void); /**< Specifies the function to generate random number. */ + +} pkc_init_t; + +/** @} */ + +/** @defgroup PKC_handle PKC handle + * @{ + */ + +/** + * @brief PKC handle Structure definition + */ +typedef struct _pkc_handle +{ + pkc_regs_t *p_instance; /**< PKC registers base address */ + + pkc_init_t init; /**< PKC operation parameters */ + + void *p_result; /**< Pointer to PKC result buffer */ + + uint32_t shift_count; /**< Count to left shift */ + + uint32_t *p_P; /**< Prime number */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_pkc_state_t state; /**< PKC operation state */ + + __IO uint32_t error_code; /**< PKC Error code */ + + uint32_t timeout; /**< Timeout for the PKC operation */ + + uint32_t retention[1]; /**< pkc important register information. */ +} pkc_handle_t; +/** @} */ + +/** @defgroup PKC_Expression_Input PKC expression input + * @{ + */ + +/** + * @brief PKC ECC Point Multiplication expression input + * @note Result = K * Point + */ +typedef struct _pkc_ecc_point_multi +{ + uint32_t *p_K; /**< Pointer to operand K */ + ecc_point_t *p_ecc_point; /**< Pointer to ECC Point. If set to NULL, it will be + modified to the G point of the current curve. */ +} pkc_ecc_point_multi_t; + +/** + * @brief PKC RSA Modular Exponentiation expression input + * @note Result = A^B mod P + */ +typedef struct _pkc_rsa_modular_exponent +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ + uint32_t *p_P; /**< Pointer to prime number P */ + uint32_t *p_P_R2; /**< P_R2 = R^2 mod P, where R = 2^DataBits */ + uint32_t ConstP; /**< Montgomery multiplication constant of P */ +} pkc_rsa_modular_exponent_t; + +/** + * @brief PKC Modular Addition expression input + * @note Result = (A + B) mod P + */ +typedef struct _pkc_modular_add +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ + uint32_t *p_P; /**< Pointer to prime number P */ +} pkc_modular_add_t; + +/** + * @brief PKC Modular Subtraction expression input + * @note Result = (A - B) mod P + */ +typedef struct _pkc_modular_sub +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ + uint32_t *p_P; /**< Pointer to prime number P */ +} pkc_modular_sub_t; + +/** + * @brief PKC Modular Left Shift expression input + * @note Result = (A << ShiftBits) mod P + */ +typedef struct _pkc_modular_shift +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t shift_bits; /**< Pointer to operand A */ + uint32_t *p_P; /**< Pointer to prime number P */ +} pkc_modular_shift_t; + +/** + * @brief PKC Modular Comparison expression input + * @note Result = A mod P + */ +typedef struct _pkc_modular_compare +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_P; /**< Pointer to prime number P */ +} pkc_modular_compare_t; + +/** + * @brief PKC Montgomery Modular Multiplication expression input + * @note Result = A * B * R^(-1) mod P, where R = 2^DataBits + */ +typedef struct _pkc_montgomery_multi +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ + uint32_t *p_P; /**< Pointer to prime number P */ + uint32_t ConstP; /**< Montgomery multiplication constant for P, + where constp = (-P[0])^(-1) mod 2^32 */ +} pkc_montgomery_multi_t; + +/** + * @brief PKC Montgomery Inversion expression input + * @note Result = A^(-1) * 2^(K) mod P + */ +typedef struct _pkc_montgomery_inversion +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_P; /**< Pointer to prime number P */ + uint32_t ConstP; /**< Montgomery multiplication constant for P, + where ConstP = (-P[0])^(-1) mod 2^32 */ +} pkc_montgomery_inversion_t; + +/** + * @brief PKC Big Number Multiplication expression input + * @note Result = A * B, up to 1024 bits + */ +typedef struct _pkc_big_number_multi +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ +} pkc_big_number_multi_t; + +/** + * @brief PKC Big Number Addition expression input + * @note Result = A + B, up to 2048 bits + */ +typedef struct _pkc_big_number_add +{ + uint32_t *p_A; /**< Pointer to operand A */ + uint32_t *p_B; /**< Pointer to operand B */ +} pkc_big_number_add_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_PKC_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_PKC_Callback Callback + * @{ + */ + +/** + * @brief HAL_PKC Callback function definition + */ + +typedef struct _hal_pkc_callback +{ + void (*pkc_msp_init)(pkc_handle_t *p_pkc); /**< PKC init MSP callback */ + void (*pkc_msp_deinit)(pkc_handle_t *p_pkc); /**< PKC de-init MSP callback */ + void (*pkc_done_callback)(pkc_handle_t *p_pkc); /**< PKC calculate done callback */ + void (*pkc_error_callback)(pkc_handle_t *p_pkc); /**< PKC error callback */ + void (*pkc_overflow_callback)(pkc_handle_t *p_pkc); /**< PKC over flow callback */ +} hal_pkc_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_PKC_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PKC_Exported_Constants PKC Exported Constants + * @{ + */ + +/** @defgroup PKC_Error_Code PKC Error Code + * @{ + */ +#define HAL_PKC_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_PKC_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_PKC_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_PKC_ERROR_OVERFLOW ((uint32_t)0x00000004) /**< Result overflow error */ +#define HAL_PKC_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +#define HAL_PKC_ERROR_INVERSE_K ((uint32_t)0x00000010) /**< Inverse K error */ +#define HAL_PKC_ERROR_IRREVERSIBLE ((uint32_t)0x00000020) /**< Irreversible error */ +/** @} */ + +/** @defgroup PKC_Secure_Mode PKC Secure Mode + * @{ + */ +#define PKC_SECURE_MODE_DISABLE ((uint32_t)0x00000000) /**< Secure mode disable */ +#define PKC_SECURE_MODE_ENABLE ((uint32_t)0x00000001) /**< Secure mode enable */ +/** @} */ + +/** @defgroup PKC_Operation_Mode PKC Operation Mode + * @{ + */ +#define PKC_OPERATION_MODE_MULTI LL_PKC_operation_mode_MULTIPLY /**< Multiplication operation mode */ +#define PKC_OPERATION_MODE_INVER LL_PKC_operation_mode_INVERTION /**< Inversion operation mode */ +#define PKC_OPERATION_MODE_ADD LL_PKC_operation_mode_ADD /**< Addition operation mode */ +#define PKC_OPERATION_MODE_SUB LL_PKC_operation_mode_SUB /**< Subtraction operation mode */ +#define PKC_OPERATION_MODE_CMP LL_PKC_operation_mode_COMPARE /**< Comparison operation mode */ +#define PKC_OPERATION_MODE_LSHIFT LL_PKC_operation_mode_LEFTSHIFT /**< Left Shift operation mode */ +#define PKC_OPERATION_MODE_BIGMULTI LL_PKC_operation_mode_BIGINTEGERMULTIPLY /**< Big Number Multiplication operation mode */ +#define PKC_OPERATION_MODE_BIGADD LL_PKC_operation_mode_BIGINTEGERADD /**< Big Number Addition operation mode */ +/** @} */ + +/** @defgroup PKC_Bits_Length PKC Bits Length + * @{ + */ +#define PKC_BITS_LENGTH_MIN LL_PKC_BITS_LENGTH_MIN /**< Min value of bits length */ +#define PKC_BITS_LENGTH_MAX LL_PKC_BITS_LENGTH_MAX /**< Max value of bits length */ +#define PKC_BIGMULTI_BITS_LENGTH_MAX LL_PKC_BIGMULTI_BITS_LENGTH_MAX /**< Max value of big number multiplication bits length */ +/** @} */ + +/** @defgroup PKC_Flags PKC Flags + * @{ + */ +#define PKC_FLAG_BUSY LL_PKC_WORKSTAT_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup PKC_Interrupt_definition PKC Interrupt_definition + * @{ + */ +#define PKC_IT_DONE LL_PKC_INTEN_DONE /**< Operation Done Interrupt source */ +#define PKC_IT_ERR LL_PKC_INTEN_ERR /**< Operation Error Interrupt source */ +#define PKC_IT_OVF LL_PKC_INTEN_BAOVF /**< Big Integer Result Overflow Interrupt source */ +/** @} */ + +/** @defgroup PKC_Timeout_definition PKC Timeout_definition + * @{ + */ +#define HAL_PKC_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< The default value of PKC timeout is 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PKC_Exported_Macros PKC Exported Macros + * @{ + */ + +/** @brief Reset PKC handle states. + * @param __HANDLE__ PKC handle. + * @retval None + */ +#define __HAL_PKC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_PKC_STATE_RESET) + +/** @brief Reset the specified PKC peripheral. + * @param __HANDLE__ PKC handle. + * @retval None + */ +#define __HAL_PKC_RESET(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, PKC_CTRL_SWRST); \ + SET_BITS((__HANDLE__)->p_instance->CTRL, PKC_CTRL_SWRST) + +/** @brief Enable the specified PKC peripheral. + * @param __HANDLE__ Specifies the PKC Handle. + * @retval None + */ +#define __HAL_PKC_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, PKC_CTRL_EN) + +/** @brief Disable the specified PKC peripheral. + * @param __HANDLE__ Specifies the PKC Handle. + * @retval None + */ +#define __HAL_PKC_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, PKC_CTRL_EN) + +/** @brief Enable the specified PKC interrupts. + * @param __HANDLE__ Specifies the PKC Handle. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref PKC_IT_DONE Operation Done Interrupt source + * @arg @ref PKC_IT_ERR Operation Error Interrupt source + * @arg @ref PKC_IT_OVF Big Integer Result Overflow Interrupt source + * @retval None + */ +#define __HAL_PKC_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BITS((__HANDLE__)->p_instance->INTEN, (__INTERRUPT__)) + +/** @brief Disable the specified PKC interrupts. + * @param __HANDLE__ Specifies the PKC Handle. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref PKC_IT_DONE Operation Done Interrupt source + * @arg @ref PKC_IT_ERR Operation Error Interrupt source + * @arg @ref PKC_IT_OVF Big Integer Result Overflow Interrupt source + * @retval None + */ +#define __HAL_PKC_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BITS((__HANDLE__)->p_instance->INTEN, (__INTERRUPT__)) + +/** @brief Check whether the specified PKC interrupt flag is set or not. + * @param __HANDLE__ Specifies the PKC Handle. + * @param __FLAG__ Specifies the interrupt flag to check. + * This parameter can be one of the following values: + * @arg @ref PKC_IT_DONE Operation Done Interrupt source + * @arg @ref PKC_IT_ERR Operation Error Interrupt source + * @arg @ref PKC_IT_OVF Big Integer Result Overflow Interrupt source + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PKC_GET_FLAG_IT(__HANDLE__, __FLAG__) (READ_BITS((__HANDLE__)->p_instance->INTSTAT, (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified PKC interrupt flag. + * @param __HANDLE__ Specifies the PKC Handle. + * @param __FLAG__ Specifies the interrupt flag to clear. + * This parameter can be one of the following values: + * @arg @ref PKC_IT_DONE Operation Done Interrupt source + * @arg @ref PKC_IT_ERR Operation Error Interrupt source + * @arg @ref PKC_IT_OVF Big Integer Result Overflow Interrupt source + * @retval None + */ +#define __HAL_PKC_CLEAR_FLAG_IT(__HANDLE__, __FLAG__) SET_BITS((__HANDLE__)->p_instance->INTSTAT, (__FLAG__)) + +/** @brief Check whether the specified PKC flag is set or not. + * @param __HANDLE__ Specifies the PKC Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref PKC_FLAG_BUSY Busy flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PKC_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->WORKSTAT, (__FLAG__)) != 0) ? SET : RESET) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PKC_Private_Macro PKC Private Macros + * @{ + */ + +/** @brief Check if PKC Bits Length is valid. + * @param __BITS__ PKC Bits Length. + * @retval SET (__BITS__ is valid) or RESET (__BITS__ is invalid) + */ +#define IS_PKC_BITS_LENGTH(__BITS__) (((__BITS__) >= PKC_BITS_LENGTH_MIN) && ((__BITS__) <= PKC_BITS_LENGTH_MAX)) + +/** @brief Check if PKC Big Number Multiplication Bits Length is valid. + * @param __BITS__ PKC Big Number Multiplication Bits Length. + * @retval SET (__BITS__ is valid) or RESET (__BITS__ is invalid) + */ +#define IS_PKC_BIGMULTI_BITS_LENGTH(__BITS__) (((__BITS__) >= PKC_BITS_LENGTH_MIN) && ((__BITS__) <= PKC_BIGMULTI_BITS_LENGTH_MAX)) + +/** @brief Check if PKC Secure Mode is valid. + * @param __MODE__ PKC Secure Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PKC_SECURE_MODE(__MODE__) (((__MODE__) == PKC_SECURE_MODE_DISABLE) || \ + ((__MODE__) == PKC_SECURE_MODE_ENABLE)) + +/** @brief Check if PKC Operation Mode is valid. + * @param __MODE__ PKC Operation Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PKC_OPERATION_MODE(__MODE__) (((__MODE__) == PKC_OPERATION_MODE_MULTI) || \ + ((__MODE__) == PKC_OPERATION_MODE_INVER) || \ + ((__MODE__) == PKC_OPERATION_MODE_ADD) || \ + ((__MODE__) == PKC_OPERATION_MODE_SUB) || \ + ((__MODE__) == PKC_OPERATION_MODE_CMP) || \ + ((__MODE__) == PKC_OPERATION_MODE_LSHIFT) || \ + ((__MODE__) == PKC_OPERATION_MODE_BIGMULTI) || \ + ((__MODE__) == PKC_OPERATION_MODE_BIGADD)) + +/** @} */ + +/** @} */ + + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_PKC_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup PKC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the PKC peripheral: + + (+) User must implement hal_pkc_msp_init() function in which it configures + all related peripherals resources (IT and NVIC ). + + (+) Call the function hal_pkc_init() to configure the selected device with + the selected configuration: + (++) pECC_Curve + (++) DataBits + (++) SecureMode + (++) pRandomFunc + + (+) Call the function hal_pkc_deinit() to restore the default configuration + of the selected PKC peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the PKC according to the specified parameters + * in the pkc_init_t and initialize the associated handle. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_init(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief De-initialize the PKC peripheral. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_deinit(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief Initialize the PKC MSP. + * @note This function should not be modified. When the callback is needed, + the hal_pkc_msp_deinit can be implemented in the user file. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_msp_init(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief De-initialize the PKC MSP. + * @note This function should not be modified. When the callback is needed, + the hal_pkc_msp_deinit can be implemented in the user file. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_msp_deinit(pkc_handle_t *p_pkc); + +/** @} */ + +/** @defgroup PKC_Exported_Functions_Group2 IO Operation Functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PKC + data transfers. + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + , These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated PKC IRQ when using Interrupt mode. + The hal_pkc_done_callback() user callbacks will be executed respectively at the end of the calculate process + The hal_pkc_error_callback() user callback will be executed when a communication error is detected + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Execute RSA Modular Exponentiation in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_rsa_modular_exponent(pkc_handle_t *p_pkc, pkc_rsa_modular_exponent_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute ECC Point Multiplication in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_ecc_point_multi(pkc_handle_t *p_pkc, pkc_ecc_point_multi_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute ECC Point Multiplication in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_ecc_point_multi_it(pkc_handle_t *p_pkc, pkc_ecc_point_multi_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Modular Addition in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_add(pkc_handle_t *p_pkc, pkc_modular_add_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Modular Addition in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_add_it(pkc_handle_t *p_pkc, pkc_modular_add_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Modular Subtraction in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_sub(pkc_handle_t *p_pkc, pkc_modular_sub_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Modular Subtraction in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_sub_it(pkc_handle_t *p_pkc, pkc_modular_sub_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Modular Left Shift in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_left_shift(pkc_handle_t *p_pkc, pkc_modular_shift_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Modular Left Shift in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_left_shift_it(pkc_handle_t *p_pkc, pkc_modular_shift_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Modular Comparison in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_compare(pkc_handle_t *p_pkc, pkc_modular_compare_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Modular Comparison in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_modular_compare_it(pkc_handle_t *p_pkc, pkc_modular_compare_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Montgomery Modular Multiplication in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_montgomery_multi(pkc_handle_t *p_pkc, pkc_montgomery_multi_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Montgomery Modular Multiplication in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_montgomery_multi_it(pkc_handle_t *p_pkc, pkc_montgomery_multi_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Montgomery Inversion in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_montgomery_inversion(pkc_handle_t *p_pkc, pkc_montgomery_inversion_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Montgomery Inversion in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_montgomery_inversion_it(pkc_handle_t *p_pkc, pkc_montgomery_inversion_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Big Number Multiplication in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_big_number_multi(pkc_handle_t *p_pkc, pkc_big_number_multi_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Big Number Multiplication in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_big_number_multi_it(pkc_handle_t *p_pkc, pkc_big_number_multi_t *p_input); + +/** + **************************************************************************************** + * @brief Execute Big Number Addition in blocking mode. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_big_number_add(pkc_handle_t *p_pkc, pkc_big_number_add_t *p_input, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Execute Big Number Addition in non-blocking mode with Interrupt. + * @note The computed result will be stored in the buffter pointed by p_pkc->pResult. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] p_input: Pointer to an expression structure which contains the input computing parameters. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pkc_big_number_add_it(pkc_handle_t *p_pkc, pkc_big_number_add_t *p_input); + +/** @} */ + +/** @addtogroup PKC_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle PKC interrupt request. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_irq_handler(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief PKC calculate done callback. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_done_callback(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief PKC error callback. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_error_callback(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief PKC over flow callback. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + **************************************************************************************** + */ +void hal_pkc_overflow_callback(pkc_handle_t *p_pkc); + +/** @} */ + +/** @addtogroup PKC_Exported_Functions_Group3 Peripheral Control and State functions + * @brief PKC Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral Control and State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the PKC handle state. + (+) Return the PKC handle error code. + (+) Set the timeout during internal process. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the PKC handle state. + * @param[in] p_pkc: Pointer to a pkc_handle_t structure that contains + * the configuration information for the specified PKC. + * @retval ::HAL_PKC_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_PKC_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_PKC_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_PKC_STATE_ERROR: Peripheral in error. + * @retval ::HAL_PKC_STATE_TIMEOUT: Peripheral in timeout. + **************************************************************************************** + */ +hal_pkc_state_t hal_pkc_get_state(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief Return the PKC error code. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @return PKC error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_pkc_get_error(pkc_handle_t *p_pkc); + +/** + **************************************************************************************** + * @brief Set the PKC internal process timeout value. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @param[in] timeout: Internal process timeout value. + **************************************************************************************** + */ +void hal_pkc_set_timeout(pkc_handle_t *p_pkc, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Suspend some registers related to PKC configuration before sleep. + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ + +hal_status_t hal_pkc_suspend_reg(pkc_handle_t *p_pkc); +/** + **************************************************************************************** + * @brief Restore some registers related to PKC configuration after sleep. + * This function must be used in conjunction with the hal_hmac_suspend_reg(). + * @param[in] p_pkc: Pointer to a PKC handle which contains the configuration + * information for the specified PKC module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ + +hal_status_t hal_pkc_resume_reg(pkc_handle_t *p_pkc); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_PKC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwm.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwm.h new file mode 100644 index 0000000..768ffe3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwm.h @@ -0,0 +1,519 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_pwm.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWM HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_PWM PWM + * @brief PWM HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_PWM_H__ +#define __GR55xx_HAL_PWM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_pwm.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_PWM_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_PWM_state HAL PWM state + * @{ + */ + +/** + * @brief HAL PWM State Enumerations definition + */ +typedef enum +{ + HAL_PWM_STATE_RESET = 0x00, /**< Peripheral is not initialized or disabled */ + HAL_PWM_STATE_READY = 0x01, /**< Peripheral is initialized and ready for use */ + HAL_PWM_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_PWM_STATE_ERROR = 0x04 /**< Reception process is ongoing */ +} hal_pwm_state_t; +/** @} */ + +/** @defgroup HAL_PWM_active_channel HAL PWM active channel + * @{ + */ + +/** + * @brief HAL PWM active channel Enumerations definition + */ +typedef enum +{ + HAL_PWM_ACTIVE_CHANNEL_A = 0x01, /**< The active channel is A */ + HAL_PWM_ACTIVE_CHANNEL_B = 0x02, /**< The active channel is B */ + HAL_PWM_ACTIVE_CHANNEL_C = 0x04, /**< The active channel is C */ + HAL_PWM_ACTIVE_CHANNEL_ALL = 0x07, /**< The active channels are ALL */ + HAL_PWM_ACTIVE_CHANNEL_CLEARED = 0x00 /**< All active channels are cleared */ +} hal_pwm_active_channel_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_PWM_STRUCTURES Structures + * @{ + */ + +/** @defgroup PWM_Configuration PWM Configuration + * @{ + */ + +/** + * @brief PWM Channel init Structure definition + */ +typedef struct +{ + uint8_t duty; /**< Specifies the duty in PWM output mode. + This parameter must be a number between 0 ~ 100.*/ + + uint8_t drive_polarity; /**< Specifies the drive polarity in PWM output mode. + This parameter can be a value of @ref PWM_Drive_Polarity.*/ + +} pwm_channel_init_t; + +/** + * @brief PWM init Structure definition + */ +typedef struct +{ + uint32_t mode; /**< Specifies the PWM output mode state. + This parameter can be a value of @ref PWM_Mode */ + + uint32_t align; /**< Specifies the PWM alignment mode with three channels + This parameter can be a value of @ref PWM_Alignment_Mode */ + + uint32_t freq; /**< Specifies the PWM frequency. + This parameter must be a number between 0 ~ SystemFreq/2 (max = 32Mhz).*/ + + uint32_t bperiod; /**< Specifies the PWM breath period in breath mode. Unit: ms. + This parameter must be a number between 0 ~ 0xFFFFFFFF/SystemFreq*1000. */ + + uint32_t hperiod; /**< Specifies the PWM hold period in breath mode. Unit: ms. + This parameter must be a number between 0 ~ 0xFFFFFF/SystemFreq*1000. */ + + pwm_channel_init_t channel_a; /**< Specifies the configuration parameters of channel A. */ + + pwm_channel_init_t channel_b; /**< Specifies the configuration parameters of channel B. */ + + pwm_channel_init_t channel_c; /**< Specifies the configuration parameters of channel C. */ + +} pwm_init_t; +/** @} */ + +/** @defgroup PWM_handle PWM handle + * @{ + */ + +/** + * @brief PWM handle Structure definition + */ +typedef struct +{ + pwm_regs_t *p_instance; /**< Register base address */ + + pwm_init_t init; /**< Required parameters for PWM Base */ + + hal_pwm_active_channel_t active_channel; /**< Active channel */ + + __IO hal_lock_t lock; /**< Lock object */ + + __IO hal_pwm_state_t state; /**< PWM operation state */ + + uint32_t retention[11]; /**< PWM important register information. */ + +} pwm_handle_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_PWM_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_PWM_Callback Callback + * @{ + */ + +/** + * @brief HAL_PWM Callback function definition + */ + +typedef struct _hal_pwm_callback +{ + void (*pwm_msp_init)(pwm_handle_t *p_pwm); /**< PWM init MSP callback */ + void (*pwm_msp_deinit)(pwm_handle_t *p_pwm); /**< PWM de-init MSP callback */ +} hal_pwm_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_PWM_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWM_Exported_Constants PWM Exported Constants + * @{ + */ + +/** @defgroup PWM_Mode PWM Mode + * @{ + */ +#define PWM_MODE_FLICKER LL_PWM_FLICKER_MODE /**< PWM flicker mode */ +#define PWM_MODE_BREATH LL_PWM_BREATH_MODE /**< PWM breath mode */ +/** @} */ + +/** @defgroup PWM_Alignment_Mode PWM Pulses Aligned. + * @{ + */ +#define PWM_ALIGNED_EDGE LL_PWM_EDGE_ALIGNED /**< PWM edge-aligned */ +#define PWM_ALIGNED_CENTER LL_PWM_CENTER_ALIGNED /**< PWM center-aligned */ +/** @} */ + +/** @defgroup PWM_Drive_Polarity PWM Drive Polarity + * @{ + */ +#define PWM_DRIVEPOLARITY_NEGATIVE LL_PWM_DRIVEPOLARITY_NEGATIVE /**< PWM led-negative-drive mode */ +#define PWM_DRIVEPOLARITY_POSITIVE LL_PWM_DRIVEPOLARITY_POSITIVE /**< PWM led-positive-drive mode */ +/** @} */ +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWM_Exported_Macros PWM Exported Macros + * @{ + */ + +/** @brief Reset PWM handle states. + * @param __HANDLE__ PWM handle. + * @retval None + */ +#define __HAL_PWM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_PWM_STATE_RESET) + +/** @brief Enable the specified PWM peripheral. + * @param __HANDLE__ specifies the PWM Handle. + * @retval None + */ +#define __HAL_PWM_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->MODE, PWM_MODE_EN) + +/** @brief Disable the specified PWM peripheral. + * @param __HANDLE__ specifies the PWM Handle. + * @retval None + */ +#define __HAL_PWM_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->MODE, PWM_MODE_EN) + +/** @brief Enable PWM breath mode. + * @param __HANDLE__ specifies the PWM Handle. + * @retval None + */ +#define __HAL_PWM_ENABLE_BREATH(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->MODE, PWM_MODE_BREATHEN) + +/** @brief Disable PWM breath mode. + * @param __HANDLE__ specifies the PWM Handle. + * @retval None + */ +#define __HAL_PWM_DISABLE_BREATH(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->MODE, PWM_MODE_BREATHEN) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWM_Private_Macro PWM Private Macros + * @{ + */ + +/** + * @brief Check if PWM mode is valid. + * @param __MODE__ PWM mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PWM_MODE(__MODE__) (((__MODE__) == PWM_MODE_FLICKER) || \ + ((__MODE__) == PWM_MODE_BREATH)) + +/** + * @brief Check if PWM Alignment mode is valid. + * @param __MODE__ PWM Alignment mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PWM_ALIGNMENT_MODE(__MODE__) (((__MODE__) == PWM_EDGE) || \ + ((__MODE__) == PWM_CENTER)) + +/** + * @brief Check if PWM drive polarity is valid. + * @param __POLARITY__ PWM drive polarity. + * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid) + */ +#define IS_PWM_DRIVEPOLARITY(__POLARITY__) (((__POLARITY__) == PWM_DRIVEPOLARITY_NEGATIVE) || \ + ((__POLARITY__) == PWM_DRIVEPOLARITY_POSITIVE)) + +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_PWM_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup PWM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * + * @verbatim +=============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the PWMx. + (+) The parameters below can only be configured in breath mode: + (++) BreathPeriod + (++) HoldPeriod + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the PWM mode according to the specified + * parameters in the pwm_init_t and initialize the associated handle. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_init(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief De-initialize the PWM peripheral. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_deinit(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief Initialize the PWM MSP. + * @note This function should not be modified. When the callback is needed, + the hal_pwm_msp_init can be implemented in the user file. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + **************************************************************************************** + */ +void hal_pwm_msp_init(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief De-initialize the PWM MSP. + * @note This function should not be modified. When the callback is needed, + the hal_pwm_msp_deinit can be implemented in the user file. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + **************************************************************************************** + */ +void hal_pwm_msp_deinit(pwm_handle_t *p_pwm); + +/** @} */ + +/** @addtogroup PWM_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the PWM. + (+) Stop the PWM. + (+) Configure the specified PWM channel. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Starts the PWM signal generation on the output. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_start(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief Stops the PWM signal generation on the output. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_stop(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief Update the PWM frequency on the output. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @param[in] freq: This parameter ranges between min = 0 and max = SystemFreq / 2. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_update_freq(pwm_handle_t *p_pwm, uint32_t freq); + +/** + **************************************************************************************** + * @brief Suspend some registers related to PWM configuration before sleep. + * @param[in] p_pwm: Pointer to a PWM handle which contains the configuration + * information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_suspend_reg(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief Restore some registers related to PWM configuration after sleep. + * This function must be used in conjunction with the hal_pwm_suspend_reg(). + * @param[in] p_pwm: Pointer to a PWM handle which contains the configuration + * information for the specified PWM module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_resume_reg(pwm_handle_t *p_pwm); + +/** + **************************************************************************************** + * @brief Initialize the PWM channels according to the specified + * parameters in the pwm_init_t. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration information for the specified PWM module. + * @param[in] p_config: PWM Channels configuration structure. + * @param[in] channel: PWM Channels to be configured. + * This parameter can be one of the following values: + * @arg @ref HAL_PWM_ACTIVE_CHANNEL_A :PWM Channel A is active + * @arg @ref HAL_PWM_ACTIVE_CHANNEL_B :PWM Channel B is active + * @arg @ref HAL_PWM_ACTIVE_CHANNEL_C :PWM Channel C is active + * @arg @ref HAL_PWM_ACTIVE_CHANNEL_ALL :All Channels are active + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwm_config_channel(pwm_handle_t *p_pwm, pwm_channel_init_t *p_config, hal_pwm_active_channel_t channel); + +/** @} */ + +/** @addtogroup PWM_Exported_Functions_Group3 Peripheral Control and State functions + * @brief PWM Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral Control and State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the PWM handle state. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the PWM handle state. + * @param[in] p_pwm: Pointer to a PWM handle that contains the configuration + * information for the specified PWM module. + * @retval ::HAL_PWM_STATE_RESET: Peripheral is not initialized or disabled. + * @retval ::HAL_PWM_STATE_READY: Peripheral is initialized and ready for use. + * @retval ::HAL_PWM_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_PWM_STATE_ERROR: Reception process is ongoing. + **************************************************************************************** + */ +hal_pwm_state_t hal_pwm_get_state(pwm_handle_t *p_pwm); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_PWM_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwr.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwr.h new file mode 100644 index 0000000..3d52391 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_pwr.h @@ -0,0 +1,484 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_pwr.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWR HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_PWR PWR + * @brief PWR HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_PWR_H__ +#define __GR55xx_HAL_PWR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_pwr.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ + +/** @addtogroup HAL_PWR_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_PWR_SLEEP_ELAPSED_HANDLER HAL PWR sleep elapsed handler define + * @{ + */ + +/** + * @brief PWR Sleep Timer Elapsed callback + */ + +typedef void (*pwr_slp_elapsed_handler_t)(void); + +/** @} */ + + +/** @defgroup HAL_PWR_CALLBACK_HANDLER PWR callback handle + * @{ + */ + +/** + * @brief PWR callback handle Structure definition + */ +typedef struct _hal_pwr_handler +{ + pwr_slp_elapsed_handler_t pwr_slp_elapsed_hander; /**< PWR sleep timer elapsed callback */ +} hal_pwr_handler_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_PWR_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWR_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_WakeUp_Pins PWR WakeUp Pins + * @{ + */ +#define PWR_EXTWKUP_PIN0 LL_PWR_EXTWKUP_PIN0 /**< External wakeup pin 0 */ +#define PWR_EXTWKUP_PIN1 LL_PWR_EXTWKUP_PIN1 /**< External wakeup pin 1 */ +#define PWR_EXTWKUP_PIN2 LL_PWR_EXTWKUP_PIN2 /**< External wakeup pin 2 */ +#define PWR_EXTWKUP_PIN3 LL_PWR_EXTWKUP_PIN3 /**< External wakeup pin 3 */ +#define PWR_EXTWKUP_PIN4 LL_PWR_EXTWKUP_PIN4 /**< External wakeup pin 4 */ +#define PWR_EXTWKUP_PIN5 LL_PWR_EXTWKUP_PIN5 /**< External wakeup pin 5 */ +#define PWR_EXTWKUP_PIN6 LL_PWR_EXTWKUP_PIN6 /**< External wakeup pin 6 */ +#define PWR_EXTWKUP_PIN7 LL_PWR_EXTWKUP_PIN7 /**< External wakeup pin 7 */ +#define PWR_EXTWKUP_PIN_ALL LL_PWR_EXTWKUP_PIN_ALL /**< External wakeup pin 0 ~ 7 */ +/** @} */ + +/** @defgroup PWR_WakeUp_Conditions PWR Wakeup Condition + * @{ + */ +#define PWR_WKUP_COND_EXT LL_PWR_WKUP_COND_EXT /**< External wakeup: AON_GPIO */ +#define PWR_WKUP_COND_TIMER LL_PWR_WKUP_COND_TIMER /**< AON Timer wakeup */ +#define PWR_WKUP_COND_BLE LL_PWR_WKUP_COND_BLE /**< BLE wakeup */ +#define PWR_WKUP_COND_CALENDAR LL_PWR_WKUP_COND_CALENDAR /**< Calendar wakeup */ +#define PWR_WKUP_COND_BOD_FEDGE LL_PWR_WKUP_COND_BOD_FEDGE /**< PMU Bod falling edge wakeup */ +#define PWR_WKUP_COND_MSIO_COMP LL_PWR_WKUP_COND_MSIO_COMP /**< Msio comparator wakeup */ +#define PWR_WKUP_COND_ALL LL_PWR_WKUP_COND_ALL /**< All wakeup sources mask */ + +/** @} */ + +/** @defgroup PWR_External_WakeUp_Type PWR External Wakeup Type + * @{ + */ +#define PWR_EXTWKUP_TYPE_LOW LL_PWR_EXTWKUP_TYPE_LOW /**< Low level wakeup */ +#define PWR_EXTWKUP_TYPE_HIGH LL_PWR_EXTWKUP_TYPE_HIGH /**< High level wakeup */ +#define PWR_EXTWKUP_TYPE_RISING LL_PWR_EXTWKUP_TYPE_RISING /**< Rising edge wakeup */ +#define PWR_EXTWKUP_TYPE_FALLING LL_PWR_EXTWKUP_TYPE_FALLING /**< Falling edge wakeup */ +/** @} */ + +/** @defgroup PWR_Sleep_Timer_Mode PWR Sleep Timer Mode + * @{ + */ +#define PWR_SLP_TIMER_MODE_NORMAL 0x0U /**< Start counting after sleeping and disabled when waked up */ +#define PWR_SLP_TIMER_MODE_SINGLE 0x1U /**< Single mode(keep counting until finished) */ +#define PWR_SLP_TIMER_MODE_RELOAD 0x2U /**< Auto reload */ +#define PWR_SLP_TIMER_MODE_DISABLE 0x3U /**< Disabled (used for reset mode) */ +/** @} */ + +/** @defgroup PWR_Timer_Type PWR Timer Type + * @note Only available on GR5515_C and later versions. + * @{ + */ +#define PWR_TIMER_TYPE_CAL_TIMER LL_PWR_TIMER_READ_SEL_CAL_TIMER /**< Calendar timer */ +#define PWR_TIMER_TYPE_AON_WDT LL_PWR_TIMER_READ_SEL_AON_WDT /**< AON watchdog timer */ +#define PWR_TIMER_TYPE_SLP_TIMER LL_PWR_TIMER_READ_SEL_SLP_TIMER /**< Sleep timer */ +#define PWR_TIMER_TYPE_CAL_ALARM LL_PWR_TIMER_READ_SEL_CAL_ALARM /**< Calendar timer */ +/** @} */ + + +/** @defgroup PWR_Memory_Power_State Memory Power State + * @{ + */ +#define PWR_MEM_POWER_OFF LL_PWR_MEM_POWER_OFF /**< Power off */ +#define PWR_MEM_POWER_FULL LL_PWR_MEM_POWER_FULL /**< Full power */ +#define PWR_MEM_POWER_RETENTION LL_PWR_MEM_POWER_RETENTION /**< Power retention, low valtage mode */ +/** @} */ + +/** @defgroup PWR_Communication_Power_State Communication Power State + * @{ + */ +#define PWR_COMM_TIMER_POWER_DOWN 0x0U /**< Power down communication timer */ +#define PWR_COMM_TIMER_POWER_UP 0x1U /**< Power on communication timer */ +#define PWR_COMM_CORE_POWER_DOWN 0x0U /**< Power down communication core */ +#define PWR_COMM_CORE_POWER_UP 0x1U /**< Power on communication core */ +/** @} */ + +/** @defgroup PWR_Communication_Mode Communication Mode + * @{ + */ +#define PWR_COMM_TIMER_MODE_RESET 0x0U /**< Communication timer in reset mode */ +#define PWR_COMM_TIMER_MODE_RUNNING 0x1U /**< Communication timer in running mode */ +#define PWR_COMM_CORE_MODE_RESET 0x0U /**< Communication core in reset mode */ +#define PWR_COMM_CORE_MODE_RUNNING 0x1U /**< Communication core in running mode */ +/** @} */ + +/** @defgroup PWR_Timeout_definition PWR Timeout definition + * @{ + */ +#define HAL_PWR_TIMEOUT_DEFAULT_VALUE ((uint32_t)0x000FFFFF) /**< 0xFFFFF counts */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup PWR_Private_Macros PWR Private Macros + * @{ + */ + +/** + * @brief Check if PWR wakeup condition is valid. + * @param __COND__ PWR wakeup condition. + * @retval SET (__COND__ is valid) or RESET (__COND__ is invalid) + */ +#define IS_PWR_WAKEUP_CONDITION(__COND__) ((((__COND__) & PWR_WKUP_COND_ALL) != 0x00U) &&\ + (((__COND__) & ~PWR_WKUP_COND_ALL) == 0x00U)) + +/** + * @brief Check if PWR external wakeup pin is valid. + * @param __PIN__ PWR external wakeup pin. + * @retval SET (__PIN__ is valid) or RESET (__PIN__ is invalid) + */ +#define IS_PWR_EXT_WAKEUP_PIN(__PIN__) ((((__PIN__) & PWR_EXTWKUP_PIN_ALL) != 0x00U) &&\ + (((__PIN__) & ~PWR_EXTWKUP_PIN_ALL) == 0x00U)) + +/** + * @brief Check if PWR sleep timer mode is valid. + * @param __MODE__ PWR sleep timer mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PWR_SLP_TIMER_MODE(__MODE__) (((__MODE__) == PWR_SLP_TIMER_MODE_NORMAL) || \ + ((__MODE__) == PWR_SLP_TIMER_MODE_SINGLE) || \ + ((__MODE__) == PWR_SLP_TIMER_MODE_RELOAD) || \ + ((__MODE__) == PWR_SLP_TIMER_MODE_DISABLE)) + +/** + * @brief Check if PWR external wakeup type is valid. + * @param __TYPE__ PWR external wakeup type. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_PWR_EXTWKUP_TYPE(__TYPE__) (((__TYPE__) == PWR_EXTWKUP_TYPE_LOW) || \ + ((__TYPE__) == PWR_EXTWKUP_TYPE_HIGH) || \ + ((__TYPE__) == PWR_EXTWKUP_TYPE_RISING) || \ + ((__TYPE__) == PWR_EXTWKUP_TYPE_FALLING)) + +/** + * @brief Check if PWR memory block is valid. + * @param __BLOCK__ PWR memory block. + * @retval SET (__BLOCK__ is valid) or RESET (__BLOCK__ is invalid) + */ +#define IS_PWR_MEM_BLOCK(__BLOCK__) ((((__BLOCK__) & PWR_MEM_ALL) != 0x00U) &&\ + (((__BLOCK__) & ~PWR_MEM_ALL) == 0x00U)) + +/** + * @brief Check if PWR memory power state is valid. + * @param __STATE__ PWR memory power state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_PWR_MEM_POWER_STAT(__STATE__) (((__STATE__) == PWR_MEM_POWER_OFF) || \ + ((__STATE__) == PWR_MEM_POWER_FULL) || \ + ((__STATE__) == PWR_MEM_POWER_RETENTION)) + +/** + * @brief Check if PWR BLE communication timer power state is valid. + * @param __STATE__ PWR BLE communication timer power state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_PWR_COMM_TIMER_POWER_STAT(__STATE__) (((__STATE__) == PWR_COMM_TIMER_POWER_DOWN) || \ + ((__STATE__) == PWR_COMM_TIMER_POWER_UP)) + +/** + * @brief Check if PWR BLE communication core power state is valid. + * @param __STATE__ PWR BLE communication core power state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_PWR_COMM_CORE_POWER_STAT(__STATE__) (((__STATE__) == PWR_COMM_CORE_POWER_DOWN) || \ + ((__STATE__) == PWR_COMM_CORE_POWER_UP)) + +/** + * @brief Check if PWR BLE communication timer mode is valid. + * @param __MODE__ PWR BLE communication timer mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PWR_COMM_TIMER_MODE(__MODE__) (((__MODE__) == PWR_COMM_TIMER_MODE_RESET) || \ + ((__MODE__) == PWR_COMM_TIMER_MODE_RUNNING)) + +/** + * @brief Check if PWR BLE communication core mode is valid. + * @param __MODE__ PWR BLE communication core mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_PWR_COMM_CORE_MODE(__MODE__) (((__MODE__) == PWR_COMM_CORE_MODE_RESET) || \ + ((__MODE__) == PWR_COMM_CORE_MODE_RUNNING)) + +/** + * @brief Check if PWR sleep timer type is valid. + * @param __TYPE__ PWR sleep timer type. + * @retval SET (__TYPE__ is valid) or RESET (__TYPE__ is invalid) + */ +#define IS_PWR_PWR_TIMER_TYPE(__TYPE__) (((__TYPE__) == PWR_TIMER_TYPE_CAL_TIMER) || \ + ((__TYPE__) == PWR_TIMER_TYPE_AON_WDT) || \ + ((__TYPE__) == PWR_TIMER_TYPE_SLP_TIMER) || \ + ((__TYPE__) == PWR_TIMER_TYPE_CAL_ALARM)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_PWR_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup PWR_Exported_Functions_Group1 Low Power mode configuration functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Set the DeepSleep WakeUp Condition + * @param[in] condition: This parameter can be a combination of the following values: + * @arg @ref PWR_WKUP_COND_EXT + * @arg @ref PWR_WKUP_COND_TIMER + * @arg @ref PWR_WKUP_COND_BLE + * @arg @ref PWR_WKUP_COND_CALENDAR + * @arg @ref PWR_WKUP_COND_BOD_FEDGE + * @arg @ref PWR_WKUP_COND_MSIO_COMP + * @arg @ref PWR_WKUP_COND_ALL + * @note When @ref PWR_WKUP_COND_EXT is set, use @ref hal_pwr_config_ext_wakeup() to configure wakeup pins and pin trigger type. + * When @ref PWR_WKUP_COND_TIMER is set, use @ref hal_pwr_config_timer_wakeup() to configure the time count to wakeup. + * When @ref PWR_WKUP_COND_ALL is set, use @ref hal_pwr_config_ext_wakeup() and @ref hal_pwr_config_timer_wakeup() to configure + * AON timer and External AON GPIO. + **************************************************************************************** + */ +void hal_pwr_set_wakeup_condition(uint32_t condition); + +/** + **************************************************************************************** + * @brief Configure the AON Sleep Timer mode and count used to wakeup MCU. + * @param[in] timer_mode: Specifies the sleep timer mode. + * This parameter can be a combination of the following values: + * @arg @ref PWR_SLP_TIMER_MODE_NORMAL + * @arg @ref PWR_SLP_TIMER_MODE_SINGLE + * @arg @ref PWR_SLP_TIMER_MODE_RELOAD + * @arg @ref PWR_SLP_TIMER_MODE_DISABLE + * @param[in] load_count: Count value of the AON Sleep Timer. + * @note The sleep clock of AON Timer is 32 KHz. + **************************************************************************************** + */ +void hal_pwr_config_timer_wakeup(uint8_t timer_mode, uint32_t load_count); + +/** + **************************************************************************************** + * @brief Configure the External AON GPIO pins and pin trigger type that is used to wakeup MCU. + * @param[in] ext_wakeup_pinx: This parameter can be a combination of the following values: + * @arg @ref PWR_EXTWKUP_PIN0 + * @arg @ref PWR_EXTWKUP_PIN1 + * @arg @ref PWR_EXTWKUP_PIN2 + * @arg @ref PWR_EXTWKUP_PIN3 + * @arg @ref PWR_EXTWKUP_PIN4 + * @arg @ref PWR_EXTWKUP_PIN5 + * @arg @ref PWR_EXTWKUP_PIN_ALL + * @param[in] ext_wakeup_type: This parameter can be a combination of the following values: + * @arg @ref PWR_EXTWKUP_TYPE_LOW + * @arg @ref PWR_EXTWKUP_TYPE_HIGH + * @arg @ref PWR_EXTWKUP_TYPE_RISING + * @arg @ref PWR_EXTWKUP_TYPE_FALLING + * @note When the level of any selected GPIO pin changes in accordance with the set + * trigger type, MCU will be waked up from DeepSleep mode. + **************************************************************************************** + */ +void hal_pwr_config_ext_wakeup(uint32_t ext_wakeup_pinx, uint32_t ext_wakeup_type); + +/** + **************************************************************************************** + * @brief Disable the interrupt wake-up function of the specified AON GPIO pin. + * @param[in] disable_wakeup_pinx: This parameter can be a combination of the following values: + * @arg @ref PWR_EXTWKUP_PIN0 + * @arg @ref PWR_EXTWKUP_PIN1 + * @arg @ref PWR_EXTWKUP_PIN2 + * @arg @ref PWR_EXTWKUP_PIN3 + * @arg @ref PWR_EXTWKUP_PIN4 + * @arg @ref PWR_EXTWKUP_PIN5 + * @arg @ref PWR_EXTWKUP_PIN_ALL + **************************************************************************************** + */ +void hal_pwr_disable_ext_wakeup(uint32_t disable_wakeup_pinx); + +/** + **************************************************************************************** + * @brief Enters DeepSleep mode. + * @note In DeepSleep mode, all I/O pins keep the same state as in Run mode. + **************************************************************************************** +*/ +void hal_pwr_enter_chip_deepsleep(void); + +/** @} */ + +/** @addtogroup PWR_Exported_Functions_Group2 BLE Communication timer and core configuration function + * @{ + */ + +/** + **************************************************************************************** + * @brief Set the power state of communication timer and communication core in running mode. + * @param[in] timer_power_state: This parameter can be one of the following values: + * @arg @ref PWR_COMM_TIMER_POWER_UP + * @arg @ref PWR_COMM_TIMER_POWER_DOWN + * @param[in] core_power_state: This parameter can be one of the following values: + * @arg @ref PWR_COMM_CORE_POWER_UP + * @arg @ref PWR_COMM_CORE_POWER_DOWN + **************************************************************************************** + */ +void hal_pwr_set_comm_power(uint32_t timer_power_state, uint32_t core_power_state); + +/** + **************************************************************************************** + * @brief Set the work mode of communication timer and communication core. + * @param[in] timer_mode: This parameter can be one of the following values: + * @arg @ref PWR_COMM_TIMER_MODE_RESET + * @arg @ref PWR_COMM_TIMER_MODE_RUNNING + * @param[in] core_mode: This parameter can be one of the following values: + * @arg @ref PWR_COMM_CORE_MODE_RESET + * @arg @ref PWR_COMM_CORE_MODE_RUNNING + **************************************************************************************** + */ +void hal_pwr_set_comm_mode(uint32_t timer_mode, uint32_t core_mode); + +/** + **************************************************************************************** + * @brief Get the current value of specified timer. + * @note Only available on GR5515_C and later versions. + * @param[in] timer_type: This parameter can be one of the following values: + * @arg @ref PWR_TIMER_TYPE_CAL_TIMER + * @arg @ref PWR_TIMER_TYPE_AON_WDT + * @arg @ref PWR_TIMER_TYPE_SLP_TIMER + * @arg @ref PWR_TIMER_TYPE_CAL_ALARM + * @param[out] p_value: Pointer to an integer storing current value + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_pwr_get_timer_current_value(uint32_t timer_type, uint32_t *p_value); + +/** @} */ + +/** @addtogroup PWR_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle PWR Sleep Timer interrupt request. + * @note Only available on GR5515_C and later versions. + **************************************************************************************** + */ +void hal_pwr_sleep_timer_irq_handler(void); + + +/** + **************************************************************************************** + * @brief PWR Sleep Timer Elapsed callback. + * @note Only available on GR5515_C and later versions. + * This function should not be modified. When the callback is needed, + * the hal_pwr_sleep_timer_elapsed_callback can be implemented in the user file. + **************************************************************************************** + */ +void hal_pwr_sleep_timer_elapsed_callback(void); + + + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __GR55xx_HAL_PWR_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_qspi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_qspi.h new file mode 100644 index 0000000..603cd13 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_qspi.h @@ -0,0 +1,1123 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_qspi.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of QSPI HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_QSPI QSPI + * @brief QSPI HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_QSPI_H__ +#define __GR55xx_HAL_QSPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_spi.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_QSPI_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_QSPI_state HAL QSPI state + * @{ + */ + +/** + * @brief HAL QSPI State Enumerations definition + */ +typedef enum +{ + HAL_QSPI_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_QSPI_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_QSPI_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_QSPI_STATE_BUSY_INDIRECT_TX = 0x12, /**< Peripheral in indirect mode with transmission ongoing */ + HAL_QSPI_STATE_BUSY_INDIRECT_RX = 0x22, /**< Peripheral in indirect mode with reception ongoing */ + HAL_QSPI_STATE_ABORT = 0x08, /**< Peripheral with abort request ongoing */ + HAL_QSPI_STATE_ERROR = 0x04 /**< Peripheral in error */ + +} hal_qspi_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_QSPI_STRUCTURES Structures + * @{ + */ + +/** @defgroup QSPI_Configuration QSPI Configuration + * @{ + */ + +/** + * @brief QSPI init Structure definition + */ +typedef struct _qspi_init_t +{ + uint32_t clock_prescaler; /**< Specifies the prescaler factor for generating clock based on the AHB clock. + This parameter can be a number between 0 and 0xFFFF */ + + uint32_t clock_mode; /**< Specifies the Clock Mode. It indicates the level that clock takes between commands. + This parameter can be a value of @ref QSPI_Clock_Mode */ + + uint32_t rx_sample_delay; /**< Specifies the RX sample delay. It is used to delay the sample of the RX input port. + This parameter can be a number between 0 and 0x7 */ +} qspi_init_t; +/** @} */ + +/** @defgroup QSPI_handle QSPI handle + * @{ + */ + +/** + * @brief QSPI handle Structure definition + */ +typedef struct _qspi_handle +{ + ssi_regs_t *p_instance; /**< QSPI registers base address */ + + qspi_init_t init; /**< QSPI communication parameters */ + + uint8_t *p_tx_buffer; /**< Pointer to QSPI Tx transfer Buffer */ + + __IO uint32_t tx_xfer_size; /**< QSPI Tx Transfer size */ + + __IO uint32_t tx_xfer_count; /**< QSPI Tx Transfer Counter */ + + uint8_t *p_rx_buffer; /**< Pointer to QSPI Rx transfer Buffer */ + + __IO uint32_t rx_xfer_size; /**< QSPI Rx Transfer size */ + + __IO uint32_t rx_xfer_count; /**< QSPI Rx Transfer Counter */ + + void (*write_fifo)(struct _qspi_handle *p_qspi); /**< Pointer to QSPI Tx transfer FIFO write function */ + + void (*read_fifo)(struct _qspi_handle *p_qspi); /**< Pointer to QSPI Rx transfer FIFO read function */ + + dma_handle_t *p_dma; /**< QSPI Rx/Tx DMA Handle parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_qspi_state_t state; /**< QSPI communication state */ + + __IO uint32_t error_code; /**< QSPI Error code */ + + uint32_t timeout; /**< Timeout for the QSPI memory access */ + + uint32_t retention[9]; /**< DMA important register information. */ +} qspi_handle_t; +/** @} */ + +/** @defgroup QSPI_Command QSPI command + * @{ + */ + +/** + * @brief QSPI command Structure definition + */ +typedef struct _qspi_command_t +{ + uint32_t instruction; /**< Specifies the Instruction to be sent. + This parameter can be a value (8-bit) between 0x00 and 0xFF. */ + + uint32_t address; /**< Specifies the Address to be sent (Size from 1 to 4 bytes according AddressSize). + This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF. */ + + uint32_t instruction_size; /**< Specifies the Instruction Size. + This parameter can be a value of @ref QSPI_Instruction_Size. */ + + uint32_t address_size; /**< Specifies the Address Size. + This parameter can be a value of @ref QSPI_Address_Size. */ + + uint32_t dummy_cycles; /**< Specifies the Number of Dummy Cycles. + This parameter can be a number between 0 and 31. */ + + uint32_t data_size; /**< Specifies the QSPI address width. + This parameter can be a value of @ref QSPI_Data_Size. */ + + uint32_t instruction_address_mode; /**< Specifies the Instruction and Address Mode. + This parameter can be a value of @ref QSPI_Inst_Addr_Mode. */ + + uint32_t data_mode; /**< Specifies the Data Mode (used for dummy cycles and data phases). + This parameter can be a value of @ref QSPI_Data_Mode. */ + + uint32_t length; /**< Specifies the number of data to transfer. (This is the number of bytes). + This parameter can be any value between 0 and 0xFFFFFFFF (0 means undefined length + until end of memory). */ + +} qspi_command_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_QSPI_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_QSPI_Callback Callback + * @{ + */ + +/** + * @brief HAL_QSPI Callback function definition + */ + +typedef struct _hal_qspi_callback +{ + void (*qspi_msp_init)(qspi_handle_t *p_qspi); /**< QSPI init MSP callback */ + void (*qspi_msp_deinit)(qspi_handle_t *p_qspi); /**< QSPI de-init MSP callback */ + void (*qspi_error_callback)(qspi_handle_t *p_qspi); /**< QSPI error callback */ + void (*qspi_abort_cplt_callback)(qspi_handle_t *p_qspi); /**< QSPI abort complete callback */ + void (*qspi_fifo_threshold_callback)(qspi_handle_t *p_qspi); /**< QSPI FIFO threshold callback */ + void (*qspi_rx_cplt_callback)(qspi_handle_t *p_qspi); /**< QSPI rx transfer completed callback */ + void (*qspi_tx_cplt_callback)(qspi_handle_t *p_qspi); /**< QSPI tx transfer completed callback */ +} hal_qspi_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_QSPI_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup QSPI_Exported_Constants QSPI Exported Constants + * @{ + */ + +/** @defgroup QSPI_Error_Code QSPI Error Code + * @{ + */ +#define HAL_QSPI_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_QSPI_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_QSPI_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_QSPI_ERROR_DMA ((uint32_t)0x00000004) /**< DMA transfer error */ +#define HAL_QSPI_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameter error */ +/** @} */ + +/** @defgroup QSPI_Clock_Mode QSPI Clock Mode + * @{ + */ +#define QSPI_CLOCK_MODE_0 (LL_SSI_SCPOL_LOW | LL_SSI_SCPHA_1EDGE) /**< Inactive state of CLK is low; + CLK toggles at the start of the first data bit */ +#define QSPI_CLOCK_MODE_1 (LL_SSI_SCPOL_LOW | LL_SSI_SCPHA_2EDGE) /**< Inactive state of CLK is low; + CLK toggles in the middle of the first data bit */ +#define QSPI_CLOCK_MODE_2 (LL_SSI_SCPOL_HIGH | LL_SSI_SCPHA_1EDGE) /**< Inactive state of CLK is high; + CLK toggles at the start of the first data bit */ +#define QSPI_CLOCK_MODE_3 (LL_SSI_SCPOL_HIGH | LL_SSI_SCPHA_2EDGE) /**< Inactive state of CLK is high; + CLK toggles in the middle of the first data bit */ +/** @} */ + +/** @defgroup QSPI_Data_Mode QSPI Data Mode + * @{ + */ +#define QSPI_DATA_MODE_SPI LL_SSI_FRF_SPI /**< Standard SPI Frame Format */ +#define QSPI_DATA_MODE_DUALSPI LL_SSI_FRF_DUALSPI /**< Dual SPI Frame Format */ +#define QSPI_DATA_MODE_QUADSPI LL_SSI_FRF_QUADSPI /**< Quad SPI Frame Format */ +/** @} */ + +/** @defgroup QSPI_Instruction_Size QSPI Instruction Size + * @{ + */ +#define QSPI_INSTSIZE_00_BITS LL_SSI_INSTSIZE_0BIT /**< 0-bit (No Instruction) */ +#define QSPI_INSTSIZE_04_BITS LL_SSI_INSTSIZE_4BIT /**< 4-bit Instruction */ +#define QSPI_INSTSIZE_08_BITS LL_SSI_INSTSIZE_8BIT /**< 8-bit Instruction */ +#define QSPI_INSTSIZE_16_BITS LL_SSI_INSTSIZE_16BIT /**< 16-bit Instruction */ +/** @} */ + +/** @defgroup QSPI_Address_Size QSPI Address Size + * @{ + */ +#define QSPI_ADDRSIZE_00_BITS LL_SSI_ADDRSIZE_0BIT /**< 0-bit address */ +#define QSPI_ADDRSIZE_04_BITS LL_SSI_ADDRSIZE_4BIT /**< 4-bit address */ +#define QSPI_ADDRSIZE_08_BITS LL_SSI_ADDRSIZE_8BIT /**< 8-bit address */ +#define QSPI_ADDRSIZE_12_BITS LL_SSI_ADDRSIZE_12BIT /**< 12-bit address */ +#define QSPI_ADDRSIZE_16_BITS LL_SSI_ADDRSIZE_16BIT /**< 16-bit address */ +#define QSPI_ADDRSIZE_20_BITS LL_SSI_ADDRSIZE_20BIT /**< 20-bit address */ +#define QSPI_ADDRSIZE_24_BITS LL_SSI_ADDRSIZE_24BIT /**< 24-bit address */ +#define QSPI_ADDRSIZE_28_BITS LL_SSI_ADDRSIZE_28BIT /**< 28-bit address */ +#define QSPI_ADDRSIZE_32_BITS LL_SSI_ADDRSIZE_32BIT /**< 32-bit address */ +/** @} */ + +/** @defgroup QSPI_Data_Size Data Width + * @{ + */ +#define QSPI_DATASIZE_04_BITS LL_SSI_DATASIZE_4BIT /**< Data length for SPI transfer: 4 bits */ +#define QSPI_DATASIZE_05_BITS LL_SSI_DATASIZE_5BIT /**< Data length for SPI transfer: 5 bits */ +#define QSPI_DATASIZE_06_BITS LL_SSI_DATASIZE_6BIT /**< Data length for SPI transfer: 6 bits */ +#define QSPI_DATASIZE_07_BITS LL_SSI_DATASIZE_7BIT /**< Data length for SPI transfer: 7 bits */ +#define QSPI_DATASIZE_08_BITS LL_SSI_DATASIZE_8BIT /**< Data length for SPI transfer: 8 bits */ +#define QSPI_DATASIZE_09_BITS LL_SSI_DATASIZE_9BIT /**< Data length for SPI transfer: 9 bits */ +#define QSPI_DATASIZE_10_BITS LL_SSI_DATASIZE_10BIT /**< Data length for SPI transfer: 10 bits */ +#define QSPI_DATASIZE_11_BITS LL_SSI_DATASIZE_11BIT /**< Data length for SPI transfer: 11 bits */ +#define QSPI_DATASIZE_12_BITS LL_SSI_DATASIZE_12BIT /**< Data length for SPI transfer: 12 bits */ +#define QSPI_DATASIZE_13_BITS LL_SSI_DATASIZE_13BIT /**< Data length for SPI transfer: 13 bits */ +#define QSPI_DATASIZE_14_BITS LL_SSI_DATASIZE_14BIT /**< Data length for SPI transfer: 14 bits */ +#define QSPI_DATASIZE_15_BITS LL_SSI_DATASIZE_15BIT /**< Data length for SPI transfer: 15 bits */ +#define QSPI_DATASIZE_16_BITS LL_SSI_DATASIZE_16BIT /**< Data length for SPI transfer: 16 bits */ +#define QSPI_DATASIZE_17_BITS LL_SSI_DATASIZE_17BIT /**< Data length for SPI transfer: 17 bits */ +#define QSPI_DATASIZE_18_BITS LL_SSI_DATASIZE_18BIT /**< Data length for SPI transfer: 18 bits */ +#define QSPI_DATASIZE_19_BITS LL_SSI_DATASIZE_19BIT /**< Data length for SPI transfer: 19 bits */ +#define QSPI_DATASIZE_20_BITS LL_SSI_DATASIZE_20BIT /**< Data length for SPI transfer: 20 bits */ +#define QSPI_DATASIZE_21_BITS LL_SSI_DATASIZE_21BIT /**< Data length for SPI transfer: 21 bits */ +#define QSPI_DATASIZE_22_BITS LL_SSI_DATASIZE_22BIT /**< Data length for SPI transfer: 22 bits */ +#define QSPI_DATASIZE_23_BITS LL_SSI_DATASIZE_23BIT /**< Data length for SPI transfer: 23 bits */ +#define QSPI_DATASIZE_24_BITS LL_SSI_DATASIZE_24BIT /**< Data length for SPI transfer: 24 bits */ +#define QSPI_DATASIZE_25_BITS LL_SSI_DATASIZE_25BIT /**< Data length for SPI transfer: 25 bits */ +#define QSPI_DATASIZE_26_BITS LL_SSI_DATASIZE_26BIT /**< Data length for SPI transfer: 26 bits */ +#define QSPI_DATASIZE_27_BITS LL_SSI_DATASIZE_27BIT /**< Data length for SPI transfer: 27 bits */ +#define QSPI_DATASIZE_28_BITS LL_SSI_DATASIZE_28BIT /**< Data length for SPI transfer: 28 bits */ +#define QSPI_DATASIZE_29_BITS LL_SSI_DATASIZE_29BIT /**< Data length for SPI transfer: 29 bits */ +#define QSPI_DATASIZE_30_BITS LL_SSI_DATASIZE_30BIT /**< Data length for SPI transfer: 30 bits */ +#define QSPI_DATASIZE_31_BITS LL_SSI_DATASIZE_31BIT /**< Data length for SPI transfer: 31 bits */ +#define QSPI_DATASIZE_32_BITS LL_SSI_DATASIZE_32BIT /**< Data length for SPI transfer: 32 bits */ + +/** @} */ + + +/** @defgroup QSPI_Inst_Addr_Mode QSPI Instruction and Address Mode + * @{ + */ +#define QSPI_INST_ADDR_ALL_IN_SPI LL_SSI_INST_ADDR_ALL_IN_SPI /**< Instruction and address are sent in SPI mode */ +#define QSPI_INST_IN_SPI_ADDR_IN_SPIFRF LL_SSI_INST_IN_SPI_ADDR_IN_SPIFRF /**< Instruction is sent in SPI mode, and address is sent in Daul/Quad SPI mode */ +#define QSPI_INST_ADDR_ALL_IN_SPIFRF LL_SSI_INST_ADDR_ALL_IN_SPIFRF /**< Instruction and address are sent in Daul/Quad SPI mode */ +/** @} */ + +/** @defgroup QSPI_Flags QSPI Flags + * @{ + */ +#define QSPI_FLAG_DCOL LL_SSI_SR_DCOL /**< Data collision error flag */ +#define QSPI_FLAG_TXE LL_SSI_SR_TXE /**< Transmission error flag */ +#define QSPI_FLAG_RFF LL_SSI_SR_RFF /**< Rx FIFO full flag */ +#define QSPI_FLAG_RFNE LL_SSI_SR_RFNE /**< Rx FIFO not empty flag */ +#define QSPI_FLAG_TFE LL_SSI_SR_TFE /**< Tx FIFO empty flag */ +#define QSPI_FLAG_TFNF LL_SSI_SR_TFNF /**< Tx FIFO not full flag */ +#define QSPI_FLAG_BUSY LL_SSI_SR_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup QSPI_Interrupts QSPI Interrupts + * @{ + */ +#define QSPI_IT_MST LL_SSI_IS_MST /**< Multi-Master Contention Interrupt flag */ +#define QSPI_IT_RXF LL_SSI_IS_RXF /**< Receive FIFO Full Interrupt flag */ +#define QSPI_IT_RXO LL_SSI_IS_RXO /**< Receive FIFO Overflow Interrupt flag */ +#define QSPI_IT_RXU LL_SSI_IS_RXU /**< Receive FIFO Underflow Interrupt flag */ +#define QSPI_IT_TXO LL_SSI_IS_TXO /**< Transmit FIFO Overflow Interrupt flag */ +#define QSPI_IT_TXE LL_SSI_IS_TXE /**< Transmit FIFO Empty Interrupt flag */ +/** @} */ + +/** @defgroup QSPI_Timeout_definition QSPI Timeout_definition + * @{ + */ +#define HAL_QSPI_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup QSPI_Exported_Macros QSPI Exported Macros + * @{ + */ + +/** @brief Reset QSPI handle states. + * @param __HANDLE__ QSPI handle. + * @retval None + */ +#define __HAL_QSPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_QSPI_STATE_RESET) + +/** @brief Enable the specified QSPI peripheral. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->SSI_EN, SSI_SSIEN_EN) + +/** @brief Disable the specified QSPI peripheral. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->SSI_EN, SSI_SSIEN_EN) + +/** @brief Enable the QSPI DMA TX Request. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_ENABLE_DMATX(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_TDMAE) + +/** @brief Enable the QSPI DMA RX Request. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_ENABLE_DMARX(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_RDMAE) + +/** @brief Disable the QSPI DMA TX Request. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_DISABLE_DMATX(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_TDMAE) + +/** @brief Disable the QSPI DMA RX Request. + * @param __HANDLE__ Specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_DISABLE_DMARX(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_RDMAE) + +/** @brief Enable the specified QSPI interrupts. + * @param __HANDLE__ Specifies the QSPI Handle. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref QSPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref QSPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref QSPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref QSPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval None + */ +#define __HAL_QSPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BITS((__HANDLE__)->p_instance->INTMASK, (__INTERRUPT__)) + +/** @brief Disable the specified QSPI interrupts. + * @param __HANDLE__ Specifies the QSPI handle. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref QSPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref QSPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref QSPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref QSPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval None + */ +#define __HAL_QSPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BITS((__HANDLE__)->p_instance->INTMASK, (__INTERRUPT__)) + +/** @brief Check whether the specified QSPI interrupt source is enabled or not. + * @param __HANDLE__ Specifies the QSPI Handle. + * @param __INTERRUPT__ Specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref QSPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref QSPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref QSPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref QSPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref QSPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_QSPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (READ_BITS((__HANDLE__)->p_instance->INTSTAT, (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Check whether the specified QSPI flag is set or not. + * @param __HANDLE__ Specifies the QSPI Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref QSPI_FLAG_DCOL Data collision error flag + * @arg @ref QSPI_FLAG_TXE Transmission error flag + * @arg @ref QSPI_FLAG_RFF Rx FIFO full flag + * @arg @ref QSPI_FLAG_RFNE Rx FIFO not empty flag + * @arg @ref QSPI_FLAG_TFE Tx FIFO empty flag + * @arg @ref QSPI_FLAG_TFNF Tx FIFO not full flag + * @arg @ref QSPI_FLAG_BUSY Busy flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_QSPI_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->STAT, (__FLAG__)) != 0) ? SET : RESET) + +/** @brief Clear the specified QSPI flag. + * @param __HANDLE__ Specifies the QSPI Handle. + * @param __FLAG__ Specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref QSPI_FLAG_DCOL Data collision error flag + * @arg @ref QSPI_FLAG_TXE Transmission error flag + * @arg @ref QSPI_FLAG_RFF Rx FIFO full flag + * @arg @ref QSPI_FLAG_RFNE Rx FIFO not empty flag + * @arg @ref QSPI_FLAG_TFE Tx FIFO empty flag + * @arg @ref QSPI_FLAG_TFNF Tx FIFO not full flag + * @arg @ref QSPI_FLAG_BUSY Busy flag + * @retval None + */ +#define __HAL_QSPI_CLEAR_FLAG(__HANDLE__, __FLAG__) READ_BITS((__HANDLE__)->p_instance->STAT, (__FLAG__)) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup QSPI_Private_Macro QSPI Private Macros + * @{ + */ + +/** @brief Check if QSPI Clock Prescaler is valid. + * @param __PRESCALER__ QSPI Clock Prescaler. + * @retval SET (__PRESCALER__ is valid) or RESET (__PRESCALER__ is invalid) + */ +#define IS_QSPI_CLOCK_PRESCALER(__PRESCALER__) ((__PRESCALER__) <= 0xFFFF) + +/** @brief Check if QSPI FIFO Threshold is valid. + * @param __THR__ QSPI FIFO Threshold. + * @retval SET (__THR__ is valid) or RESET (__THR__ is invalid) + */ +#define IS_QSPI_FIFO_THRESHOLD(__THR__) (((__THR__) >= 0) && ((__THR__) <= 7)) + +/** @brief Check if QSPI Clock Mode is valid. + * @param __CLKMODE__ QSPI Clock Mode. + * @retval SET (__CLKMODE__ is valid) or RESET (__CLKMODE__ is invalid) + */ +#define IS_QSPI_CLOCK_MODE(__CLKMODE__) (((__CLKMODE__) == QSPI_CLOCK_MODE_0) || \ + ((__CLKMODE__) == QSPI_CLOCK_MODE_1) || \ + ((__CLKMODE__) == QSPI_CLOCK_MODE_2) || \ + ((__CLKMODE__) == QSPI_CLOCK_MODE_3)) + +/** @brief Check if QSPI Instruction Size is valid. + * @param __INST_SIZE__ QSPI Instruction Size. + * @retval SET (__INST_SIZE__ is valid) or RESET (__INST_SIZE__ is invalid) + */ +#define IS_QSPI_INSTRUCTION_SIZE(__INST_SIZE__) (((__INST_SIZE__) == QSPI_INSTSIZE_00_BITS) || \ + ((__INST_SIZE__) == QSPI_INSTSIZE_04_BITS) || \ + ((__INST_SIZE__) == QSPI_INSTSIZE_08_BITS) || \ + ((__INST_SIZE__) == QSPI_INSTSIZE_16_BITS)) + +/** @brief Check if QSPI Address Size is valid. + * @param __ADDR_SIZE__ QSPI Address Size . + * @retval SET (__ADDR_SIZE__ is valid) or RESET (__ADDR_SIZE__ is invalid) + */ +#define IS_QSPI_ADDRESS_SIZE(__ADDR_SIZE__) (((__ADDR_SIZE__) == QSPI_ADDRSIZE_00_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_04_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_08_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_12_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_16_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_20_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_24_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_28_BITS) || \ + ((__ADDR_SIZE__) == QSPI_ADDRSIZE_32_BITS)) + +/** @brief Check if QSPI Dummy Cycle is valid. + * @param __DCY__ QSPI Dummy Cycle. + * @retval SET (__DCY__ is valid) or RESET (__DCY__ is invalid) + */ +#define IS_QSPI_DUMMY_CYCLES(__DCY__) ((__DCY__) <= 31) + +/** @brief Check if QSPI Instruction and Address Mode is valid. + * @param __MODE__ QSPI Instruction and Address Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_QSPI_INSTADDR_MODE(__MODE__) (((__MODE__) == QSPI_INST_ADDR_ALL_IN_SPI) || \ + ((__MODE__) == QSPI_INST_IN_SPI_ADDR_IN_SPIFRF) || \ + ((__MODE__) == QSPI_INST_ADDR_ALL_IN_SPIFRF)) + +/** @brief Check if QSPI Data Mode is valid. + * @param __MODE__ QSPI Data Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_QSPI_DATA_MODE(__MODE__) (((__MODE__) == QSPI_DATA_MODE_SPI) || \ + ((__MODE__) == QSPI_DATA_MODE_DUALSPI) || \ + ((__MODE__) == QSPI_DATA_MODE_QUADSPI)) + +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_QSPI_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup QSPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the QSPIx peripheral: + + (+) User must implement hal_qspi_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_qspi_init() to configure the selected device with + the selected configuration: + (++) Clock Prescaler + (++) Clock Mode + + (+) Call the function hal_qspi_deinit() to restore the default configuration + of the selected QSPIx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the QSPI according to the specified parameters + * in the qspi_init_t and initialize the associated handle. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_init(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief De-initialize the QSPI peripheral. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_deinit(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Initialize the QSPI MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_qspi_msp_deinit can be implemented in the user file. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_msp_init(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief De-initialize the QSPI MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_qspi_msp_deinit can be implemented in the user file. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_msp_deinit(qspi_handle_t *p_qspi); + +/** @} */ + +/** @defgroup QSPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the QSPI + data transfers. + + [..] The QSPI supports master and slave mode: + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts. + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated QSPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_qspi_tx_cplt_callback(), hal_qspi_rx_cplt_callback() and hal_qspi_txrx_cplt_callback() user callbacks + will be executed respectively at the end of the transmit or Receive process. + The hal_qspi_error_callback() user callback will be executed when a communication error is detected + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1 Line (simplex) and 2 Lines (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Transmit an amount of data with the specified instruction and address in blocking mode. + * @note This function is used only in Indirect Write Mode. Dummy cycles in command will be ignored. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[in] p_data: Pointer to data buffer + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_transmit(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data with the specified instruction, address and dummy cycles in blocking mode. + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_receive(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit only instruction in blocking mode. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode with standard SPI. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_transmit(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode with standard SPI. + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_receive(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data with the specified instruction and address in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Write Mode. Dummy cycles in command will be ignored. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[in] p_data: Pointer to data buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_transmit_it(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Receive an amount of data with the specified instruction, address and dummy cycles in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_receive_it(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Transmit instruction in non-blocking mode with Interrupt. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_it(qspi_handle_t *p_qspi, qspi_command_t *p_cmd); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode at standard SPI with Interrupt. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_transmit_it(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode at standard SPI with Interrupt. + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_receive_it(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit an amount of data with the specified instruction and address in non-blocking mode with DMA . + * @note This function is used only in Indirect Write Mode. Dummy cycles in command will be ignored. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[in] p_data: Pointer to data buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_transmit_dma(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Receive an amount of data with the specified instruction, address and dummy cycles in non-blocking mode with DMA . + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_receive_dma(qspi_handle_t *p_qspi, qspi_command_t *p_cmd, uint8_t *p_data); + +/** + **************************************************************************************** + * @brief Transmit instruction in non-blocking mode with DMA. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_cmd: Pointer to a qspi_command_t structure that contains the instruction and address for data transfer. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_command_dma(qspi_handle_t *p_qspi, qspi_command_t *p_cmd); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode at standard SPI with DMA. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_transmit_dma(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode at standard SPI with DMA. + * @note This function is used only in Indirect Read Mode. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_receive_dma(qspi_handle_t *p_qspi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Abort the current transmission. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_abort(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Abort the current transmission (non-blocking function) + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_abort_it(qspi_handle_t *p_qspi); + +/** @} */ + +/** @addtogroup QSPI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle QSPI interrupt request. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_irq_handler(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Tx Transfer completed callback. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_tx_cplt_callback(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Rx Transfer completed callback. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_rx_cplt_callback(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief QSPI error callback. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_error_callback(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief QSPI Abort Complete callback. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_abort_cplt_callback(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief FIFO Threshold callback. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + **************************************************************************************** + */ +void hal_qspi_fifo_threshold_callback(qspi_handle_t *p_qspi); + +/** @} */ + +/** @defgroup QSPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief QSPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the QSPI. + (+) hal_qspi_get_state() API can be helpful to check in run-time the state of the QSPI peripheral. + (+) hal_qspi_get_error() check in run-time Errors occurring during communication. + (+) hal_qspi_set_timeout() set the timeout during internal process. + (+) hal_qspi_set_tx_fifo_threshold() set the TX FIFO Threshold. + (+) hal_qspi_set_rx_fifo_threshold() set the RX FIFO Threshold. + (+) hal_qspi_get_tx_fifo_threshold() get the TX FIFO Threshold. + (+) hal_qspi_get_rx_fifo_threshold() get the RX FIFO Threshold. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the QSPI handle state. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @retval ::HAL_QSPI_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_QSPI_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_QSPI_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_QSPI_STATE_BUSY_INDIRECT_TX: Peripheral in indirect mode with transmission ongoing. + * @retval ::HAL_QSPI_STATE_BUSY_INDIRECT_RX: Peripheral in indirect mode with reception ongoing. + * @retval ::HAL_QSPI_STATE_ABORT: Peripheral with abort request ongoing. + * @retval ::HAL_QSPI_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_qspi_state_t hal_qspi_get_state(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Return the QSPI error code. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @return QSPI error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_qspi_get_error(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Set the QSPI internal process timeout value. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] timeout: Internal process timeout value. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +void hal_qspi_set_timeout(qspi_handle_t *p_qspi, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Set the TX FIFO threshold. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] threshold: TX FIFO threshold value ranging between 0x0U and 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_set_tx_fifo_threshold(qspi_handle_t *p_qspi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Set the RX FIFO threshold. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @param[in] threshold: RX FIFO threshold value ranging between 0x0U and 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_set_rx_fifo_threshold(qspi_handle_t *p_qspi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Get the TX FIFO threshold. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @return TX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_qspi_get_tx_fifo_threshold(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Get the RX FIFO threshold. + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration information for the specified QSPI module. + * @return RX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_qspi_get_rx_fifo_threshold(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Suspend some registers related to QSPI configuration before sleep. + * @param[in] p_qspi: Pointer to a QSPIhandle which contains the configuration + * information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_suspend_reg(qspi_handle_t *p_qspi); + +/** + **************************************************************************************** + * @brief Restore some registers related to QSPI configuration after sleep. + * This function must be used in conjunction with the hal_qspi_suspend_reg(). + * @param[in] p_qspi: Pointer to a QSPI handle which contains the configuration + * information for the specified QSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_qspi_resume_reg(qspi_handle_t *p_qspi); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_QSPI_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_rng.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_rng.h new file mode 100644 index 0000000..b9b5cb5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_rng.h @@ -0,0 +1,449 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_rng.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of RNG HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_RNG RNG + * @brief RNG HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_RNG_H__ +#define __GR55xx_HAL_RNG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_rng.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_RNG_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_RNG_state HAL RNG state + * @{ + */ + +/** + * @brief HAL RNG State Enumerations definition + */ +typedef enum +{ + HAL_RNG_STATE_RESET = 0x00, /**< RNG not initialized or disabled yet */ + HAL_RNG_STATE_READY = 0x01, /**< RNG initialized and ready for use */ + HAL_RNG_STATE_BUSY = 0x02, /**< RNG internal process is ongoing */ + HAL_RNG_STATE_TIMEOUT = 0x03, /**< RNG timeout state */ + HAL_RNG_STATE_ERROR = 0x04 /**< RNG error state */ +} hal_rng_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_RNG_STRUCTURES Structures + * @{ + */ + +/** @defgroup RNG_Configuration RNG Configuration + * @{ + */ + +/** + * @brief RNG init structure definition + */ +typedef struct _rng_init +{ + uint32_t seed_mode; /**< Specifies the seed source for the LFSR. + This parameter can be a value of @ref RNG_SEED_SOURCE */ + + uint32_t lfsr_mode; /**< Specifies the configuration mode for the LFSR. + This parameter can be a value of @ref RNG_LFSR_MODE */ + + uint32_t out_mode; /**< Specifies the Output mode for the RNG. + This parameter can be a value of @ref RNG_OUTPUT_MODE */ + + uint32_t post_mode; /**< Specifies post-process configuration for the RNG. + This parameter can be a value of @ref RNG_POST_PRO */ + +} rng_init_t; + +/** @} */ + +/** @defgroup RNG_handle RNG handle + * @{ + */ + +/** + * @brief RNG handle Structure definition + */ +typedef struct _rng_handle +{ + rng_regs_t *p_instance; /**< Register base address */ + + rng_init_t init; /**< RNG required parameters */ + + hal_lock_t lock; /**< RNG locking object */ + + __IO hal_rng_state_t state; /*!< RNG communication state */ + + uint32_t random_number; /*!< Last-generated RNG Data */ + + uint32_t retention[1]; /**< RNG important register information. */ +} rng_handle_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_RNG_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_RNG_Callback Callback + * @{ + */ + +/** + * @brief HAL_RNG Callback function definition + */ + +typedef struct _hal_rng_callback +{ + void (*rng_msp_init)(rng_handle_t *p_rng); /**< RNG init MSP callback */ + void (*rng_msp_deinit)(rng_handle_t *p_rng); /**< RNG de-init MSP callback */ + void (*rng_ready_data_callback)(rng_handle_t *p_rng, uint32_t random32bit); /**< RNG data ready callback */ +} hal_rng_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_RNG_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RNG_Exported_Constants RNG Exported Constants + * @{ + */ + +/** @defgroup RNG_SEED_SOURCE LFSR seed source + * @{ + */ +#define RNG_SEED_FR0_S0 LL_RNG_SEED_FR0_S0 /**< LFSR seed is from the switching oscillator S0. */ +#define RNG_SEED_USER LL_RNG_SEED_USER /**< LFSR seed is configured by users. */ +/** @} */ + + +/** @defgroup RNG_LFSR_MODE LFSR configuration mode + * @{ + */ +#define RNG_LFSR_MODE_59BIT LL_RNG_LFSR_MODE_59BIT /**< 59-bit LFSR. */ +#define RNG_LFSR_MODE_128BIT LL_RNG_LFSR_MODE_128BIT /**< 128-bit LFSR. */ +/** @} */ + +/** @defgroup RNG_POST_PRO Post-process mode + * @{ + */ +#define RNG_POST_PRO_NOT LL_RNG_POST_PRO_NOT /**< No post process. */ +#define RNG_POST_PRO_SKIPPING LL_RNG_POST_PRO_SKIPPING /**< bit skipping. */ +#define RNG_POST_PRO_COUNTING LL_RNG_POST_PRO_COUNTING /**< bit counting. */ +#define RNG_POST_PRO_NEUMANN LL_RNG_POST_PRO_NEUMANN /**< Von-Neumann. */ +/** @} */ + +/** @defgroup RNG_OUTPUT_MODE RNG Output mode + * @{ + */ +#define RNG_OUTPUT_FR0_S0 LL_RNG_OUTPUT_FR0_S0 /**< Digital RNG direct output, for ring oscillator S0 LFSR seed. */ +#define RNG_OUTPUT_CYCLIC_PARITY LL_RNG_OUTPUT_CYCLIC_PARITY /**< LFSR and RNG cyclic sampling and parity generation. */ +#define RNG_OUTPUT_CYCLIC LL_RNG_OUTPUT_CYCLIC /**< LFSR and RNG cyclic sampling. */ +#define RNG_OUTPUT_LFSR_RNG LL_RNG_OUTPUT_LFSR_RNG /**< LFSR ⊕ RNG. */ +#define RNG_OUTPUT_LFSR LL_RNG_OUTPUT_LFSR /**< LFSR direct output. */ +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_RNG_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup RNG_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and start the RNG according to the specified parameters + in the rng_init_t of associated handle. + (+) Initialize the RNG MSP. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the RNG according to the specified + * parameters in the rng_init_t of associated handle. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_init(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief De-initialize the RNG peripheral. + * @param[in] p_rng: RNG handle. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_deinit(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief Initialize the RNG MSP. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @note When rewriting this function in user file, mechanism may be added + * to avoid multiple initialize when hal_rng_init function is called + * again to change parameters. + **************************************************************************************** + */ +void hal_rng_msp_init(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief De-initialize the RNG MSP. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @note When rewriting this function in user file, mechanism may be added + * to avoid multiple initialize when hal_rng_init function is called + * again to change parameters. + **************************************************************************************** + */ +void hal_rng_msp_deinit(rng_handle_t *p_rng); + +/** @} */ + + +/** @addtogroup RNG_Exported_Functions_Group2 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Generate Random Number. + (+) Handle RNG interrupt request and associated function callback. + +@endverbatim + * @{ + */ + + +/** + **************************************************************************************** + * @brief Generate a 32-bit random number. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @param[in] p_seed: user configured seeds. the seed is valid when seed_mode member of + * rng_init_t is configured as RNG_SEED_USER. If 59-bit random number is + * selected, the seed need to provide [0~58] bit spaces. If 128-bit random + * number is selected, the seed need to provide [0~127] bit spaces. + * @param[out] p_random32bit: Pointer to generated random number variable if successful. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_generate_random_number(rng_handle_t *p_rng, uint16_t *p_seed, uint32_t *p_random32bit); + +/** + **************************************************************************************** + * @brief Generate a 32-bit random number in interrupt mode. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @param[in] p_seed: user configured seeds. the seed is valid when seed_mode member of + * rng_init_t is configured as RNG_SEED_USER. If 59-bit random number is + * selected, the seed need to provide [0~58] bit spaces. If 128-bit random + * number is selected, the seed need to provide [0~127] bit spaces. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_generate_random_number_it(rng_handle_t *p_rng, uint16_t *p_seed); + +/** + **************************************************************************************** + * @brief Read the latest generated random number. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @retval random value. + **************************************************************************************** + */ +uint32_t hal_rng_read_last_random_number(rng_handle_t *p_rng); + +/** @} */ + +/** @addtogroup RNG_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callback functions + * @{ + */ +/** + **************************************************************************************** + * @brief Handle RNG interrupt request. + * @param[in] p_rng: RNG handle. + **************************************************************************************** + */ +void hal_rng_irq_handler(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief Data Ready callback in non-blocking mode. + * @note This function should not be modified. When the callback is needed, + the hal_rng_ready_data_callback can be implemented in the user file. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @param random32bit: generated random value + * @retval None + **************************************************************************************** + */ +void hal_rng_ready_data_callback(rng_handle_t *p_rng, uint32_t random32bit); + +/** @} */ + +/** @defgroup RNG_Exported_Functions_Group3 Peripheral State functions + * @brief RNG State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RNG. + (+) hal_rng_get_state() API can be helpful to check in run-time the state of the RNG peripheral. +@endverbatim + * @{ + */ +/** + **************************************************************************************** + * @brief Return the RNG handle state. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration information for the specified HMAC module. + * @retval ::HAL_RNG_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_RNG_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_RNG_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_RNG_STATE_ERROR: Peripheral in error. + * @retval ::HAL_RNG_STATE_TIMEOUT: Peripheral in timeout. + **************************************************************************************** + */ +hal_rng_state_t hal_rng_get_state(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief Suspend some registers related to RNG configuration before sleep. + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_suspend_reg(rng_handle_t *p_rng); + +/** + **************************************************************************************** + * @brief Restore some registers related to RNG configuration after sleep. + * This function must be used in conjunction with the hal_rng_resume_reg(). + * @param[in] p_rng: Pointer to a RNG handle which contains the configuration + * information for the specified RNG module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_rng_resume_reg(rng_handle_t *p_rng); + + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_RNG_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_sleep_timer.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_sleep_timer.h new file mode 100644 index 0000000..b3efc9c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_sleep_timer.h @@ -0,0 +1,126 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_sleep_timer.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of sleep timer HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_SLEEP_TIMER SLEEP_TIMER + * @brief SLEEP TIMER HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_SLEEP_TIMER_H__ +#define __GR55xx_HAL_SLEEP_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_SLEEP_TIMER_FUNCTIONS Functions + * @{ + */ + +/** +**************************************************************************************** +* @brief Configure the AON Sleep Timer mode, count and start used to wakeup MCU. +* @param[in] mode: Specifies the sleep timer mode. +* This parameter can be a combination of the following values: +* @arg @ref PWR_SLP_TIMER_MODE_NORMAL +* @arg @ref PWR_SLP_TIMER_MODE_SINGLE +* @arg @ref PWR_SLP_TIMER_MODE_RELOAD +* @param[in] value: Count value of the AON Sleep Timer. +* @retval ::HAL_OK: Operation is OK. +* @retval ::HAL_ERROR: Operation is ERROR. +**************************************************************************************** +*/ +hal_status_t hal_sleep_timer_config_and_start(uint8_t mode, uint32_t value); + +/** +**************************************************************************************** +* @brief stop Sleep Timer +**************************************************************************************** +*/ +void hal_sleep_timer_stop(void); + +/** +**************************************************************************************** +* @brief Get the current value of sleep timer +* @retval the current value of sleep timer +**************************************************************************************** +*/ +uint32_t hal_sleep_timer_get_current_value(void); + +/** +**************************************************************************************** +* @brief Get clock frequency of sleep timer +* @retval clock frequency of sleep timer +**************************************************************************************** +*/ +uint32_t hal_sleep_timer_get_clock_freq(void); + +/** +**************************************************************************************** +* @brief get sleep timer is running or not +* @retval runing state of sleep timer (1 or 0). +**************************************************************************************** +*/ +uint8_t hal_sleep_timer_status_get(void); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_SLEEP_TIMER_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi.h new file mode 100644 index 0000000..22ed25a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi.h @@ -0,0 +1,1098 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_spi.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of SPI HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_SPI SPI + * @brief SPI HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_SPI_H__ +#define __GR55xx_HAL_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_spi.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_SPI_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_SPI_state HAL SPI state + * @{ + */ + +/** + * @brief HAL SPI State Enumerations definition + */ +typedef enum +{ + HAL_SPI_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_SPI_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_SPI_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_SPI_STATE_BUSY_TX = 0x12, /**< Data Transmission process is ongoing */ + HAL_SPI_STATE_BUSY_RX = 0x22, /**< Data Reception process is ongoing */ + HAL_SPI_STATE_BUSY_TX_RX = 0x32, /**< Data Transmission and Reception process is ongoing */ + HAL_SPI_STATE_ABORT = 0x08, /**< Peripheral with abort request ongoing */ + HAL_SPI_STATE_ERROR = 0x04 /**< Peripheral in error */ + +} hal_spi_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_SPI_STRUCTURES Structures + * @{ + */ + +/** @defgroup SPI_Configuration SPI Configuration + * @{ + */ + +/** + * @brief SPI init Structure definition + */ +typedef struct _spi_init +{ + uint32_t data_size; /**< Specifies the SPI data size. + This parameter can be a value of @ref SPI_Data_Size */ + + uint32_t clock_polarity; /**< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint32_t clock_phase; /**< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint32_t baudrate_prescaler; /**< Specifies the BaudRate prescaler value which will be + used to configure the transmit and receive SCK clock. + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint32_t ti_mode; /**< Specifies if the TI mode is enabled or not. + This parameter can be a value of @ref SPI_TI_Mode */ + + uint32_t slave_select; /**< Specifies the slaves to be selected. + This parameter can be a value of @ref SPI_Slave_Select */ +} spi_init_t; +/** @} */ + +/** @defgroup SPI_handle SPI handle + * @{ + */ + +/** + * @brief SPI handle Structure definition + */ +typedef struct _spi_handle +{ + ssi_regs_t *p_instance; /**< SPI registers base address */ + + spi_init_t init; /**< SPI communication parameters */ + + uint8_t *p_tx_buffer; /**< Pointer to SPI Tx transfer Buffer */ + + __IO uint32_t tx_xfer_size; /**< SPI Tx Transfer size */ + + __IO uint32_t tx_xfer_count; /**< SPI Tx Transfer Counter */ + + uint8_t *p_rx_buffer; /**< Pointer to SPI Rx transfer Buffer */ + + __IO uint32_t rx_xfer_size; /**< SPI Rx Transfer size */ + + __IO uint32_t rx_xfer_count; /**< SPI Rx Transfer Counter */ + + void (*write_fifo)(struct _spi_handle *p_spi); /**< Pointer to SPI Tx transfer FIFO write function */ + + void (*read_fifo)(struct _spi_handle *p_spi); /**< Pointer to SPI Rx transfer FIFO read function */ + + void (*read_write_fifo)(struct _spi_handle *p_spi); /**< Pointer to SPI transfer FIFO read and write function */ + + dma_handle_t *p_dmatx; /**< SPI Tx DMA Handle parameters */ + + dma_handle_t *p_dmarx; /**< SPI Rx DMA Handle parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_spi_state_t state; /**< SPI communication state */ + + __IO uint32_t error_code; /**< SPI Error code */ + + uint32_t timeout; /**< Timeout for the SPI memory access */ + +#if defined(HAL_SPI_V2_MODULE_ENABLED) + uint32_t retention[9]; /**< SPI important register information. */ +#else + uint32_t retention[8]; /**< SPI important register information. */ +#endif +} spi_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_SPI_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_SPI_Callback Callback + * @{ + */ + +/** + * @brief HAL_SPI Callback function definition + */ + +typedef struct _hal_spi_callback +{ + void (*spi_msp_init)(spi_handle_t *p_spi); /**< SPI init MSP callback */ + void (*spi_msp_deinit)(spi_handle_t *p_spi); /**< SPI de-init MSP callback */ + void (*spi_error_callback)(spi_handle_t *p_spi); /**< SPI error callback */ + void (*spi_abort_cplt_callback)(spi_handle_t *p_spi); /**< SPI abort completed callback */ + void (*spi_rx_cplt_callback)(spi_handle_t *p_spi); /**< SPI rx transfer completed callback */ + void (*spi_tx_cplt_callback)(spi_handle_t *p_spi); /**< SPI tx transfer completed callback */ + void (*spi_tx_rx_cplt_callback)(spi_handle_t *p_spi); /**< SPI tx/rx transfer completed callback */ +} hal_spi_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_SPI_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_Direction SPI Direction + * @{ + */ +#define SPI_DIRECTION_FULL_DUPLEX LL_SSI_FULL_DUPLEX /**< Full Duplex: Transmit & Receive */ +#define SPI_DIRECTION_SIMPLEX_TX LL_SSI_SIMPLEX_TX /**< Simplex Tx: Transmit only */ +#define SPI_DIRECTION_SIMPLEX_RX LL_SSI_SIMPLEX_RX /**< Simplex Rx: Receive only */ +#define SPI_DIRECTION_READ_EEPROM LL_SSI_READ_EEPROM /**< Read EEPROM */ +/** @} */ + +/** @defgroup SPI_Error_Code SPI Error Code + * @{ + */ +#define HAL_SPI_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_SPI_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_SPI_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_SPI_ERROR_DMA ((uint32_t)0x00000004) /**< DMA transfer error */ +#define HAL_SPI_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameters error */ +/** @} */ + +/** @defgroup SPI_Data_Size SPI Data Size + * @{ + */ +#define SPI_DATASIZE_4BIT LL_SSI_DATASIZE_4BIT /**< 4-bit serial data transfer */ +#define SPI_DATASIZE_5BIT LL_SSI_DATASIZE_5BIT /**< 5-bit serial data transfer */ +#define SPI_DATASIZE_6BIT LL_SSI_DATASIZE_6BIT /**< 6-bit serial data transfer */ +#define SPI_DATASIZE_7BIT LL_SSI_DATASIZE_7BIT /**< 7-bit serial data transfer */ +#define SPI_DATASIZE_8BIT LL_SSI_DATASIZE_8BIT /**< 8-bit serial data transfer */ +#define SPI_DATASIZE_9BIT LL_SSI_DATASIZE_9BIT /**< 9-bit serial data transfer */ +#define SPI_DATASIZE_10BIT LL_SSI_DATASIZE_10BIT /**< 10-bit serial data transfer */ +#define SPI_DATASIZE_11BIT LL_SSI_DATASIZE_11BIT /**< 11-bit serial data transfer */ +#define SPI_DATASIZE_12BIT LL_SSI_DATASIZE_12BIT /**< 12-bit serial data transfer */ +#define SPI_DATASIZE_13BIT LL_SSI_DATASIZE_13BIT /**< 13-bit serial data transfer */ +#define SPI_DATASIZE_14BIT LL_SSI_DATASIZE_14BIT /**< 14-bit serial data transfer */ +#define SPI_DATASIZE_15BIT LL_SSI_DATASIZE_15BIT /**< 15-bit serial data transfer */ +#define SPI_DATASIZE_16BIT LL_SSI_DATASIZE_16BIT /**< 16-bit serial data transfer */ +#define SPI_DATASIZE_17BIT LL_SSI_DATASIZE_17BIT /**< 17-bit serial data transfer */ +#define SPI_DATASIZE_18BIT LL_SSI_DATASIZE_18BIT /**< 18-bit serial data transfer */ +#define SPI_DATASIZE_19BIT LL_SSI_DATASIZE_19BIT /**< 19-bit serial data transfer */ +#define SPI_DATASIZE_20BIT LL_SSI_DATASIZE_20BIT /**< 20-bit serial data transfer */ +#define SPI_DATASIZE_21BIT LL_SSI_DATASIZE_21BIT /**< 21-bit serial data transfer */ +#define SPI_DATASIZE_22BIT LL_SSI_DATASIZE_22BIT /**< 22-bit serial data transfer */ +#define SPI_DATASIZE_23BIT LL_SSI_DATASIZE_23BIT /**< 23-bit serial data transfer */ +#define SPI_DATASIZE_24BIT LL_SSI_DATASIZE_24BIT /**< 24-bit serial data transfer */ +#define SPI_DATASIZE_25BIT LL_SSI_DATASIZE_25BIT /**< 25-bit serial data transfer */ +#define SPI_DATASIZE_26BIT LL_SSI_DATASIZE_26BIT /**< 26-bit serial data transfer */ +#define SPI_DATASIZE_27BIT LL_SSI_DATASIZE_27BIT /**< 27-bit serial data transfer */ +#define SPI_DATASIZE_28BIT LL_SSI_DATASIZE_28BIT /**< 28-bit serial data transfer */ +#define SPI_DATASIZE_29BIT LL_SSI_DATASIZE_29BIT /**< 29-bit serial data transfer */ +#define SPI_DATASIZE_30BIT LL_SSI_DATASIZE_30BIT /**< 30-bit serial data transfer */ +#define SPI_DATASIZE_31BIT LL_SSI_DATASIZE_31BIT /**< 31-bit serial data transfer */ +#define SPI_DATASIZE_32BIT LL_SSI_DATASIZE_32BIT /**< 32-bit serial data transfer */ +/** @} */ + +/** @defgroup SPI_Clock_Polarity SPI Clock Polarity + * @{ + */ +#define SPI_POLARITY_LOW LL_SSI_SCPOL_LOW /**< Inactive state of CLK is low */ +#define SPI_POLARITY_HIGH LL_SSI_SCPOL_HIGH /**< Inactive state of CLK is high */ +/** @} */ + +/** @defgroup SPI_Clock_Phase SPI Clock Phase + * @{ + */ +#define SPI_PHASE_1EDGE LL_SSI_SCPHA_1EDGE /**< CLK toggles at start of first data bit */ +#define SPI_PHASE_2EDGE LL_SSI_SCPHA_2EDGE /**< CLK toggles in middle of first data bit */ +/** @} */ + +/** @defgroup SPI_TI_Mode SPI TI Mode + * @{ + */ +#define SPI_TIMODE_DISABLE ((uint32_t)0x00000000) /**< SPI TI mode disable */ +#define SPI_TIMODE_ENABLE LL_SSI_PROTOCOL_TI /**< SPI TI mode enable */ +/** @} */ + +/** @defgroup SPI_Slave_Select SPI Slave Select + * @{ + */ +#define SPI_SLAVE_SELECT_0 LL_SSI_SLAVE0 /**< SPIM Select Slave 0 */ +#define SPI_SLAVE_SELECT_1 LL_SSI_SLAVE1 /**< SPIM Select Slave 1 */ +#define SPI_SLAVE_SELECT_ALL (LL_SSI_SLAVE0 | LL_SSI_SLAVE1) /**< SPIM Select All Slave */ +/** @} */ + +/** @defgroup SPI_FIFO_LEVEL_MAX SPI FIFO Level Max + * @{ + */ +#define SPI_TX_FIFO_LEVEL_MAX 8 /**< SPI TX FIFO Level Max Value */ +#define SPI_RX_FIFO_LEVEL_MAX 8 /**< SPI RX FIFO Level Max Value */ +/** @} */ + +/** @defgroup SPI_Flags_definition SPI Flags Definition + * @{ + */ +#define SPI_FLAG_DCOL LL_SSI_SR_DCOL /**< Data collision error flag */ +#define SPI_FLAG_TXE LL_SSI_SR_TXE /**< Transmission error flag */ +#define SPI_FLAG_RFF LL_SSI_SR_RFF /**< Rx FIFO full flag */ +#define SPI_FLAG_RFNE LL_SSI_SR_RFNE /**< Rx FIFO not empty flag */ +#define SPI_FLAG_TFE LL_SSI_SR_TFE /**< Tx FIFO empty flag */ +#define SPI_FLAG_TFNF LL_SSI_SR_TFNF /**< Tx FIFO not full flag */ +#define SPI_FLAG_BUSY LL_SSI_SR_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition + * @{ + */ +#define SPI_IT_MST LL_SSI_IS_MST /**< Multi-Master Contention Interrupt flag */ +#define SPI_IT_RXF LL_SSI_IS_RXF /**< Receive FIFO Full Interrupt flag */ +#define SPI_IT_RXO LL_SSI_IS_RXO /**< Receive FIFO Overflow Interrupt flag */ +#define SPI_IT_RXU LL_SSI_IS_RXU /**< Receive FIFO Underflow Interrupt flag */ +#define SPI_IT_TXO LL_SSI_IS_TXO /**< Transmit FIFO Overflow Interrupt flag */ +#define SPI_IT_TXE LL_SSI_IS_TXE /**< Transmit FIFO Empty Interrupt flag */ +/** @} */ + +/** @defgroup SPI_Timeout_definition SPI Timeout_definition + * @{ + */ +#define HAL_SPI_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @brief Reset SPI handle states. + * @param __HANDLE__ SPI handle. + * @retval None + */ +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_SPI_STATE_RESET) + +/** @brief Enable the specified SPI peripheral. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->SSI_EN, SSI_SSIEN_EN) + +/** @brief Disable the specified SPI peripheral. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->SSI_EN, SSI_SSIEN_EN) + +/** @brief Enable the SPI DMA TX Request. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_ENABLE_DMATX(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_TDMAE) + +/** @brief Enable the SPI DMA RX Request. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_ENABLE_DMARX(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_RDMAE) + +/** @brief Disable the SPI DMA TX Request. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_DISABLE_DMATX(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_TDMAE) + +/** @brief Disable the SPI DMA RX Request. + * @param __HANDLE__ Specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_DISABLE_DMARX(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->DMAC, SSI_DMAC_RDMAE) + +/** @brief Enable the specified SPI interrupts. + * @param __HANDLE__ Specifies the SPI Handle. + * @param __INTERRUPT__ Specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref SPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref SPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref SPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref SPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval None + */ +#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BITS((__HANDLE__)->p_instance->INTMASK, (__INTERRUPT__)) + +/** @brief Disable the specified SPI interrupts. + * @param __HANDLE__ Specifies the SPI handle. + * @param __INTERRUPT__ Specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref SPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref SPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref SPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref SPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval None + */ +#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BITS((__HANDLE__)->p_instance->INTMASK, (__INTERRUPT__)) + +/** @brief Check whether the specified SPI interrupt source is enabled or not. + * @param __HANDLE__ Specifies the SPI Handle. + * @param __INTERRUPT__ Specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref SPI_IT_MST Multi-Master Contention Interrupt enable + * @arg @ref SPI_IT_RXF Receive FIFO Full Interrupt enable + * @arg @ref SPI_IT_RXO Receive FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_RXU Receive FIFO Underflow Interrupt enable + * @arg @ref SPI_IT_TXO Transmit FIFO Overflow Interrupt enable + * @arg @ref SPI_IT_TXE Transmit FIFO Empty Interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (READ_BITS((__HANDLE__)->p_instance->INTSTAT, (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Check whether the specified SPI flag is set or not. + * @param __HANDLE__ Specifies the SPI Handle. + * @param __FLAG__ Specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref SPI_FLAG_DCOL Data collision error flag + * @arg @ref SPI_FLAG_TXE Transmission error flag + * @arg @ref SPI_FLAG_RFF Rx FIFO full flag + * @arg @ref SPI_FLAG_RFNE Rx FIFO not empty flag + * @arg @ref SPI_FLAG_TFE Tx FIFO empty flag + * @arg @ref SPI_FLAG_TFNF Tx FIFO not full flag + * @arg @ref SPI_FLAG_BUSY Busy flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->STAT, (__FLAG__)) != 0) ? SET : RESET) + +/** @brief Clear the specified SPI flag. + * @param __HANDLE__ Specifies the SPI Handle. + * @param __FLAG__ Specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref SPI_FLAG_DCOL Data collision error flag + * @arg @ref SPI_FLAG_TXE Transmission error flag + * @arg @ref SPI_FLAG_RFF Rx FIFO full flag + * @arg @ref SPI_FLAG_RFNE Rx FIFO not empty flag + * @arg @ref SPI_FLAG_TFE Tx FIFO empty flag + * @arg @ref SPI_FLAG_TFNF Tx FIFO not full flag + * @arg @ref SPI_FLAG_BUSY Busy flag + * @retval None + */ +#define __HAL_SPI_CLEAR_FLAG(__HANDLE__, __FLAG__) READ_BITS((__HANDLE__)->p_instance->STAT, (__FLAG__)) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPI_Private_Macro SPI Private Macros + * @{ + */ + +/** @brief Check if SPI Direction Mode is valid. + * @param __MODE__ SPI Direction Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_SPI_DIRECTION(__MODE__) (((__MODE__) == SPI_DIRECTION_FULL_DUPLEX) || \ + ((__MODE__) == SPI_DIRECTION_SIMPLEX_TX) || \ + ((__MODE__) == SPI_DIRECTION_SIMPLEX_RX) || \ + ((__MODE__) == SPI_DIRECTION_READ_EEPROM)) + +/** @brief Check if SPI Data Size is valid. + * @param __DATASIZE__ SPI Data Size. + * @retval SET (__DATASIZE__ is valid) or RESET (__DATASIZE__ is invalid) + */ +#define IS_SPI_DATASIZE(__DATASIZE__) (((__DATASIZE__) >= SPI_DATASIZE_4BIT) && \ + ((__DATASIZE__) <= SPI_DATASIZE_32BIT)) + +/** @brief Check if SPI Clock Polarity is valid. + * @param __CPOL__ SPI Clock Polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_SPI_CPOL(__CPOL__) (((__CPOL__) == SPI_POLARITY_LOW) || \ + ((__CPOL__) == SPI_POLARITY_HIGH)) + +/** @brief Check if SPI Clock Phase is valid. + * @param __CPHA__ SPI Clock Phase. + * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid) + */ +#define IS_SPI_CPHA(__CPHA__) (((__CPHA__) == SPI_PHASE_1EDGE) || \ + ((__CPHA__) == SPI_PHASE_2EDGE)) + +/** @brief Check if SPI BaudRate Prescaler is valid. + * @param __PRESCALER__ SPI BaudRate Prescaler. + * @retval SET (__PRESCALER__ is valid) or RESET (__PRESCALER__ is invalid) + */ +#define IS_SPI_BAUDRATE_PRESCALER(__PRESCALER__) ((__PRESCALER__) <= 0xFFFF) + +/** @brief Check if SPI TI Mode is valid. + * @param __MODE__ SPI TI Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_SPI_TIMODE(__MODE__) (((__MODE__) == SPI_TIMODE_DISABLE) || \ + ((__MODE__) == SPI_TIMODE_ENABLE)) + +/** @brief Check if SPI Slave Select is valid. + * @param __SLAVE__ SPI Slave Select. + * @retval SET (__SLAVE__ is valid) or RESET (__SLAVE__ is invalid) + */ +#define IS_SPI_SLAVE(__SLAVE__) (((__SLAVE__) == SPI_SLAVE_SELECT_0) || \ + ((__SLAVE__) == SPI_SLAVE_SELECT_1) || \ + ((__SLAVE__) == SPI_SLAVE_SELECT_ALL)) + +/** @brief Check if SPI Receive Sample Delay Value is valid. + * @param __DLY__ SPI Receive Sample Delay Value + * @retval SET (__DLY__ is valid) or RESET (__DLY__ is invalid) + */ +#define IS_SPI_RX_SAMPLE_DLY(__DLY__) (((__DLY__) >= 0) && ((__DLY__) <= 7)) + + +/** @brief Check if SPI FIFO Threshold is valid. + * @param __THR__ SPI FIFO Threshold. + * @retval SET (__THR__ is valid) or RESET (__THR__ is invalid) + */ +#define IS_SPI_FIFO_THRESHOLD(__THR__) (((__THR__) >= 0) && ((__THR__) <= 7)) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_SPI_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPIx peripheral: + + (+) User must implement hal_spi_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_spi_init() to configure the selected device with + the selected configuration: + (++) Direction + (++) Data Size + (++) Clock Polarity and Phase + (++) BaudRate Prescaler + (++) TIMode + (++) Slave Select + + (+) Call the function hal_spi_deinit() to restore the default configuration + of the selected SPIx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the SPI according to the specified parameters + * in the spi_init_t and initialize the associated handle. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_init(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief De-initialize the SPI peripheral. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_deinit(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Initialize the SPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_spi_msp_deinit can be implemented in the user file. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_msp_init(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief De-initialize the SPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_spi_msp_deinit can be implemented in the user file. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_msp_deinit(spi_handle_t *p_spi); + +/** @} */ + +/** @defgroup SPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfer functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SPI + data transfer. + + [..] The SPI supports master and slave mode: + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_spi_tx_cplt_callback(), hal_spi_rx_cplt_callback() and hal_spi_txrx_cplt_callback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The hal_spi_error_callback() user callback will be executed when a communication error is detected. + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1-Line (simplex) and 2-Line (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_receive(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in blocking mode. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_receive(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in blocking mode. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_number_data: Amount of data to be sent in bytes + * @param[in] rx_number_data: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_read_eeprom(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_number_data, uint32_t rx_number_data, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with Interrupt. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_it(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_receive_it(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent and received in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_receive_it(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with Interrupt. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_number_data: Amount of data to be sent in bytes + * @param[in] rx_number_data: Amount of data to be received in bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_read_eeprom_it(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_number_data, uint32_t rx_number_data); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with DMA. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_dma(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @note In case of MASTER mode and SPI_DIRECTION_2LINES direction, p_dmatx shall be defined. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_receive_dma(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_receive_dma(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Read an amount of data from EEPROM in non-blocking mode with DMA. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_tx_data: Pointer to transmission data buffer + * @param[out] p_rx_data: Pointer to reception data buffer + * @param[in] tx_number_data: Amount of data to be sent in bytes + * @param[in] rx_number_data: Amount of data to be received in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_read_eeprom_dma(spi_handle_t *p_spi, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_number_data, uint32_t rx_number_data); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (blocking mode). + * @param[in] p_spi: SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_abort(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (Interrupt mode). + * @param[in] p_spi: SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort_it (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_abort_it(spi_handle_t *p_spi); + +/** @} */ + +/** @addtogroup SPI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle SPI interrupt request. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_irq_handler(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Tx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_tx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Rx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_rx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Tx and Rx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_tx_rx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief SPI error callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_error_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief SPI Abort Completed callback. + * @param[in] p_spi: SPI handle. + **************************************************************************************** + */ +void hal_spi_abort_cplt_callback(spi_handle_t *p_spi); + +/** @} */ + +/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SPI. + (+) hal_spi_get_state() API can be helpful to check in run-time the state of the SPI peripheral + (+) hal_spi_get_error() check in run-time Errors occurring during communication + (+) hal_spi_set_timeout() set the timeout during internal process + (+) hal_spi_set_tx_fifo_threshold() set the TX FIFO Threshold + (+) hal_spi_set_rx_fifo_threshold() set the RX FIFO Threshold + (+) hal_spi_get_tx_fifo_threshold() get the TX FIFO Threshold + (+) hal_spi_get_rx_fifo_threshold() get the RX FIFO Threshold +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the SPI handle state. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @retval ::HAL_SPI_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_SPI_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_SPI_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_TX: Data Transmission process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_RX: Data Reception process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_TX_RX: Data Transmission and Reception process is ongoing. + * @retval ::HAL_SPI_STATE_ABORT: Peripheral with abort request ongoing. + * @retval ::HAL_SPI_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_spi_state_t hal_spi_get_state(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Return the SPI error code. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return SPI error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_spi_get_error(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Set the SPI internal process timeout value. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] timeout: Internal process timeout value. + **************************************************************************************** + */ +void hal_spi_set_timeout(spi_handle_t *p_spi, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Set the TX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] threshold: TX FIFO threshold value ranging bwtween 0x0U ~ 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_set_tx_fifo_threshold(spi_handle_t *p_spi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Set the RX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] threshold: RX FIFO threshold value ranging bwtween 0x0U ~ 0x7U. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_set_rx_fifo_threshold(spi_handle_t *p_spi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Get the TX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return TX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_spi_get_tx_fifo_threshold(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Get the RX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return RX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_spi_get_rx_fifo_threshold(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Suspend some registers related to SPI configuration before sleep. + * @param[in] p_spi: Pointer to a SPI handle which contains the configuration + * information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_suspend_reg(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Restore some registers related to SPI configuration after sleep. + * This function must be used in conjunction with the hal_spi_suspend_reg(). + * @param[in] p_spi: Pointer to a SPI handle which contains the configuration + * information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_resume_reg(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with polling. Support Setting C&A + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: 1 byte instruction + * @param[in] addr: 3 bytes address + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @param[in] timeout: Timeout duration + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_with_ia(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in non-blocking mode with DMA. Support Setting C&A + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: 1 byte instruction + * @param[in] addr: 3 bytes address + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes, ranging between 0 and 4095. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_transmit_dma_with_ia(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_SPI_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi_v2.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi_v2.h new file mode 100644 index 0000000..0e3b0fb --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_spi_v2.h @@ -0,0 +1,613 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_spi_v2.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of SPI HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2020 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_SPI SPI + * @brief SPI HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_SPI_V2_H__ +#define __GR55xx_HAL_SPI_V2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_spi.h" +#include "gr55xx_hal_def.h" +#include "gr55xx_hal_dma.h" +#include "gr55xx_hal_spi.h" + +/** + * @defgroup HAL_SPI_MACRO Defines + * @{ + */ +#define SPI_XFER_INST_NONE 0xFF /**< SPI XFER Instruction None. */ +#define SPI_XFER_ADDR_NONE 0xFFFFFF /**< SPI XFER Address None. */ +#define SPI_XFER_INST_ADDR_NONE 0xFFFFFFFF /**< SPI XFER Instruction Address None. */ +/** @} */ + + +/** @addtogroup HAL_SPI_DRIVER_FUNCTIONS Functions + * @{ + */ + /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPIx peripheral: + + (+) User must implement hal_spi_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_spi_init() to configure the selected device with + the selected configuration: + (++) Direction + (++) Data Size + (++) Clock Polarity and Phase + (++) BaudRate Prescaler + (++) TIMode + (++) Slave Select + + (+) Call the function hal_spi_deinit() to restore the default configuration + of the selected SPIx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the SPI according to the specified parameters + * in the spi_init_t and initialize the associated handle. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] rx_sample_delay: Receive sample delay [0, 7] + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_init(spi_handle_t *p_spi, uint32_t rx_sample_delay); + +/** + **************************************************************************************** + * @brief De-initialize the SPI peripheral. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_deinit(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Initialize the SPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_spi_msp_deinit can be implemented in the user file. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_msp_init(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief De-initialize the SPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_spi_msp_deinit can be implemented in the user file. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_msp_deinit(spi_handle_t *p_spi); +/** @} */ + +/** + **************************************************************************************** + * @brief set receive sample delay + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] rx_delay: 0 ~ 7. + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +void hal_spi_v2_set_rx_delay(spi_handle_t *p_spi, uint32_t rx_delay); + + +/** @defgroup SPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfer functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SPI + data transfer. + + [..] The SPI supports master and slave mode: + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_spi_tx_cplt_callback(), hal_spi_rx_cplt_callback() and hal_spi_txrx_cplt_callback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The hal_spi_error_callback() user callback will be executed when a communication error is detected. + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1-Line (simplex) and 2-Line (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode with 8bit data width, and CS Signal will be assert/de-assert in every byte. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_8bit_toggle(spi_handle_t *p_spi, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode with 8bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_8bit(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode with 8bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_receive_8bit(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit Then Receive an amount of data in blocking mode with 8bit data width. + * This Function works at EEPROM Read Mode, not Full duplex Mode + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] tx_data: Pointer to transmit data buffer + * @param[in] tx_length: Amount of data to be transmited in bytes + * @param[in] rx_data: Pointer to received data buffer + * @param[in] rx_length: Amount of data to be received in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_receive_8bit(spi_handle_t *p_spi, uint8_t *tx_data, uint32_t tx_length, uint8_t *rx_data, uint32_t rx_length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode with 32bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_32bit(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length, uint32_t timeout); + + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode with 32bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] timeout: Timeout duration + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_receive_32bit(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in DMA mode with 8bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_8bit_dma(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in DMA mode with 8bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_receive_8bit_dma(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Transmit an amount of data in DMA mode with 32bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_tx_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_32bit_dma(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_tx_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Receive an amount of data in DMA mode with 32bit data width. + * if set inst to SPI_XFER_INST_NONE or set addr to SPI_XFER_ADDR_NONE, inst & addr won't be used in transfer + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] inst: Instruction used in transfer + * @param[in] addr: Address used in transfer + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_receive_32bit_dma(spi_handle_t *p_spi, uint8_t inst, uint32_t addr, uint8_t *p_data, uint32_t length); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (blocking mode). + * @param[in] p_spi: SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_abort(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Abort ongoing transfer (Interrupt mode). + * @param[in] p_spi: SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort_it (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_abort_it(spi_handle_t *p_spi); +/** @} */ + + +/** @addtogroup SPI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle SPI interrupt request. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_irq_handler(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Tx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_tx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Rx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_rx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Tx and Rx Transfer completed callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_tx_rx_cplt_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief SPI error callback. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + **************************************************************************************** + */ +void hal_spi_v2_error_callback(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief SPI Abort Completed callback. + * @param[in] p_spi: SPI handle. + **************************************************************************************** + */ +void hal_spi_v2_abort_cplt_callback(spi_handle_t *p_spi); + +/** @} */ + +/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SPI. + (+) hal_spi_get_state() API can be helpful to check in run-time the state of the SPI peripheral + (+) hal_spi_get_error() check in run-time Errors occurring during communication + (+) hal_spi_set_timeout() set the timeout during internal process + (+) hal_spi_get_tx_fifo_threshold() get the TX FIFO Threshold + (+) hal_spi_get_rx_fifo_threshold() get the RX FIFO Threshold +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the SPI handle state. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @retval ::HAL_SPI_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_SPI_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_SPI_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_TX: Data Transmission process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_RX: Data Reception process is ongoing. + * @retval ::HAL_SPI_STATE_BUSY_TX_RX: Data Transmission and Reception process is ongoing. + * @retval ::HAL_SPI_STATE_ABORT: Peripheral with abort request ongoing. + * @retval ::HAL_SPI_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_spi_state_t hal_spi_v2_get_state(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Return the SPI error code. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return SPI error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_spi_v2_get_error(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Set the SPI internal process timeout value. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @param[in] timeout: Internal process timeout value. + **************************************************************************************** + */ +void hal_spi_v2_set_timeout(spi_handle_t *p_spi, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Get the TX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return TX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_spi_v2_get_tx_fifo_threshold(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Get the RX FIFO threshold. + * @param[in] p_spi: Pointer to an SPI handle which contains the configuration information for the specified SPI module. + * @return RX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_spi_v2_get_rx_fifo_threshold(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Suspend some registers related to SPI configuration before sleep. + * @param[in] p_spi: Pointer to a SPI handle which contains the configuration + * information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_suspend_reg(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Restore some registers related to SPI configuration after sleep. + * This function must be used in conjunction with the hal_spi_suspend_reg(). + * @param[in] p_spi: Pointer to a SPI handle which contains the configuration + * information for the specified SPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_resume_reg(spi_handle_t *p_spi); + +/** + **************************************************************************************** + * @brief Using DMA to Transmit data by toggling CS in every data beat. + * + * @param[in] p_spi: Pointer to a SPI handle which contains the configuration + * information for the specified SPI module. + * @param[in] data_size: Optional value - @ref SPI_DATASIZE_8BIT @ref SPI_DATASIZE_16BIT @ref SPI_DATASIZE_32BIT + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Length of data to be sent + * + * @return Result of operation. + **************************************************************************************** + */ +hal_status_t hal_spi_v2_transmit_dma_with_toggle(spi_handle_t *p_spi, uint32_t data_size, uint8_t *p_data, uint32_t length); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_SPI_V2_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_tim.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_tim.h new file mode 100644 index 0000000..0b269a3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_tim.h @@ -0,0 +1,417 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_tim.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of TIMER HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_TIMER TIMER + * @brief TIM HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_TIMER_H__ +#define __GR55xx_HAL_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal_def.h" +#include "gr55xx_ll_tim.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_TIMER_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_TIMER_state HAL TIMER state + * @{ + */ + +/** + * @brief HAL TIMER State Enumerations definition + */ +typedef enum +{ + HAL_TIMER_STATE_RESET = 0x00, /**< Peripheral not yet initialized or disabled */ + HAL_TIMER_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + HAL_TIMER_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + HAL_TIMER_STATE_ERROR = 0x04 /**< Reception process is ongoing */ +} hal_timer_state_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_TIMER_STRUCTURES Structures + * @{ + */ + +/** @defgroup TIMER_Configuration TIMER Configuration + * @{ + */ + +/** + * @brief TIMER init Structure definition + */ +typedef struct _timer_init +{ + uint32_t auto_reload; /**< Specifies the auto-reload value. */ + +} timer_init_t; + +/** @} */ + +/** @defgroup TIMER_handle TIMER handle + * @{ + */ + +/** + * @brief TIMER handle Structure definition + */ +typedef struct _timer_handle +{ + timer_regs_t *p_instance; /**< Register base address */ + + timer_init_t init; /**< TIMER Base required parameters */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_timer_state_t state; /**< TIMER operation state */ + +} timer_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_TIMER_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_TIMER_Callback Callback + * @{ + */ + +/** + * @brief HAL_TIMER Callback function definition + */ + +typedef struct _hal_timer_callback +{ + void (*timer_msp_init)(timer_handle_t *p_timer); /**< TIMER init MSP callback */ + void (*timer_msp_deinit)(timer_handle_t *p_timer); /**< TIMER de-init MSP callback */ + void (*timer_period_elapsed_callback)(timer_handle_t *p_timer); /**< TIMER period elapsed callback */ +} hal_timer_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_TIMER_MACRO Defines + * @{ + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMER_Exported_Macros TIMER Exported Macros + * @{ + */ + +/** @brief Reset TIMER handle states. + * @param __HANDLE__ TIMER handle. + * @retval None + */ +#define __HAL_TIMER_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_TIMER_STATE_RESET) + +/** @brief Enable the specified TIMER peripheral. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval None + */ +#define __HAL_TIMER_ENABLE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, TIMER_CTRL_EN) + +/** @brief Disable the specified TIMER peripheral. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval None + */ +#define __HAL_TIMER_DISABLE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, TIMER_CTRL_EN) + +/** @brief Enable the TIMER interrupt. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval None + */ +#define __HAL_TIMER_ENABLE_IT(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CTRL, TIMER_CTRL_INTEN) + +/** @brief Disable the TIMER interrupt. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval None + */ +#define __HAL_TIMER_DISABLE_IT(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CTRL, TIMER_CTRL_INTEN) + +/** @brief Check whether the TIMER interrupt has occurred or not. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval The new state of TIMER interrupt (SET or RESET). + */ +#define __HAL_TIMER_GET_FLAG_IT(__HANDLE__) ll_timer_is_active_flag_it(__HANDLE__->p_instance) + +/** @brief Clear the TIMER interrupt flag. + * @param __HANDLE__ Specifies the TIMER Handle. + * @retval None + */ +#define __HAL_TIMER_CLEAR_FLAG_IT(__HANDLE__) ll_timer_clear_flag_it(__HANDLE__->p_instance) + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_TIMER_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup TIMER_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * + * @verbatim +=============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIMER. + (+) De-initialize the TIMER. + (+) Start the Timer. + (+) Stop the Timer. + (+) Start the Timer and enable interrupt. + (+) Stop the Timer and disable interrupt. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the TIMER according to the specified parameters + * in the timer_init_t and initialize the associated handle. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_init(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief De-initialize the TIMER peripheral. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_deinit(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Initialize the TIMER MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_timer_base_msp_init could be implemented in the user file. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + **************************************************************************************** + */ +void hal_timer_base_msp_init(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief De-initialize the TIMER MSP. + * @note This function should not be modified. When the callback is needed, + * the hal_timer_base_msp_deinit could be implemented in the user file. + * @param[in] p_timer: Pointer to a TIM handle which contains the configuration + * information for the specified TIMER module. + **************************************************************************************** + */ +void hal_timer_base_msp_deinit(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Starts the TIMER counter. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_start(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Stops the TIMER counter. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_stop(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Starts the TIMER counter in interrupt mode. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_start_it(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Stops the TIMER counter in interrupt mode. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_base_stop_it(timer_handle_t *p_timer); + +/** @} */ + +/** @addtogroup TIMER_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle TIMER interrupt request. + * @param[in] p_timer: TIMER handle. + **************************************************************************************** + */ +void hal_timer_irq_handler(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief Period elapsed callback in non-blocking mode. + * @note This function should not be modified. When the callback is needed, + the hal_timer_period_elapsed_callback can be implemented in the user file. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + **************************************************************************************** + */ +void hal_timer_period_elapsed_callback(timer_handle_t *p_timer); + +/** @} */ + +/** @addtogroup TIMER_Exported_Functions_Group2 Peripheral Control and State functions + * @brief TIMER Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral Control and State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the TIMER handle state. + (+) Configure the TIMER. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the TIMER handle state. + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @retval ::HAL_TIMER_STATE_RESET: Peripheral not yet initialized or disabled. + * @retval ::HAL_TIMER_STATE_READY: Peripheral Initialized and ready for use. + * @retval ::HAL_TIMER_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_TIMER_STATE_ERROR: Reception process is ongoing. + **************************************************************************************** + */ +hal_timer_state_t hal_timer_get_state(timer_handle_t *p_timer); + +/** + **************************************************************************************** + * @brief TIMER configuration + * @param[in] p_timer: Pointer to a TIMER handle which contains the configuration + * information for the specified TIMER module. + * @param[in] p_structure: The TIMER configuration structure + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_timer_set_config(timer_handle_t *p_timer, timer_init_t *p_structure); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_TIMER_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_uart.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_uart.h new file mode 100644 index 0000000..ce3188f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_uart.h @@ -0,0 +1,1045 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_uart.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of UART HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_UART UART + * @brief UART HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_UART_H__ +#define __GR55xx_HAL_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_uart.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_UART_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_UART_state HAL UART state + * @{ + */ + +/** + * @brief HAL UART State enumerations definition + * @note HAL UART State value is a combination of 2 different substates: gState and RxState. + */ +typedef enum +{ + HAL_UART_STATE_RESET = 0x00U, /**< Peripheral is not initialized. + Value is allowed for gState and RxState */ + + HAL_UART_STATE_READY = 0x10U, /**< Peripheral initialized and ready for use. + Value is allowed for gState and RxState */ + + HAL_UART_STATE_BUSY = 0x14U, /**< An internal process is ongoing. + Value is allowed for gState only */ + + HAL_UART_STATE_BUSY_TX = 0x11U, /**< Data Transmission process is ongoing. + Value is allowed for gState only */ + + HAL_UART_STATE_BUSY_RX = 0x12U, /**< Data Reception process is ongoing. + Value is allowed for RxState only */ + + HAL_UART_STATE_BUSY_TXRX = 0x13U, /**< Data Transmission and Reception process is ongoing. + Value is allowed for gState only */ + + HAL_UART_STATE_TIMEOUT = 0x30U, /**< Timeout state. + Value is allowed for gState only */ + + HAL_UART_STATE_ERROR = 0x70U /**< Error. + Value is allowed for gState only */ + +} hal_uart_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_UART_STRUCTURES Structures + * @{ + */ + +/** @defgroup UART_Configuration UART Configuration + * @{ + */ + +/** + * @brief UART init structure definition + */ +typedef struct _uart_init +{ + uint32_t baud_rate; /**< This member configures the UART communication baud rate. */ + + uint32_t data_bits; /**< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref UART_Data_Bits. */ + + uint32_t stop_bits; /**< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_Stop_Bits. */ + + uint32_t parity; /**< Specifies the parity mode. + This parameter can be a value of @ref UART_Parity. */ + + uint32_t hw_flow_ctrl; /**< Specifies whether the hardware flow control mode is enabled or disabled. + This parameter can be a value of @ref UART_Hardware_Flow_Control. */ + + uint32_t rx_timeout_mode; /**< Specifies whether the receive timeout mode is enabled or disabled. + When rx_timeout_mode is enabled, character timeout interrupt will disable + current receive process after the data in RxFIFO is received, and call + hal_uart_rx_cplt_callback(). Note that the rx_timeout_mode only works + in interrupt mode. + This parameter can be a value of @ref UART_Receiver_TimeOut. */ + +} uart_init_t; +/** @} */ + +/** @defgroup UART_handle UART handle + * @{ + */ + +/** + * @brief UART handle Structure definition + */ +typedef struct _uart_handle +{ + uart_regs_t *p_instance; /**< UART registers base address */ + + uart_init_t init; /**< UART communication parameters */ + + uint8_t *p_tx_buffer; /**< Pointer to UART Tx transfer Buffer */ + + uint16_t tx_xfer_size; /**< UART Tx Transfer size */ + + __IO uint16_t tx_xfer_count; /**< UART Tx Transfer Counter */ + + uint8_t *p_rx_buffer; /**< Pointer to UART Rx transfer Buffer */ + + uint16_t rx_xfer_size; /**< UART Rx Transfer size */ + + __IO uint16_t rx_xfer_count; /**< UART Rx Transfer Counter */ + + dma_handle_t *p_dmatx; /**< UART Tx DMA Handle parameters */ + + dma_handle_t *p_dmarx; /**< UART Rx DMA Handle parameters */ + + functional_state_t dma_tx_mode; /**< UART Tx DMA mode state */ + + functional_state_t dma_rx_mode; /**< UART Rx DMA mode state */ + + hal_lock_t lock; /**< Locking object */ + + __IO hal_uart_state_t tx_state; /**< UART state information related to Tx operations. + This parameter can be a value of @ref hal_uart_state_t */ + + __IO hal_uart_state_t rx_state; /**< UART state information related to Rx operations. + This parameter can be a value of @ref hal_uart_state_t */ + + __IO uint32_t error_code; /**< UART Error code */ + + uint32_t retention[8]; /**< UART important register information. */ +} uart_handle_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_UART_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_UART_Callback Callback + * @{ + */ + +/** + * @brief HAL_UART Callback function definition + */ + +typedef struct _hal_uart_callback +{ + void (*uart_msp_init)(uart_handle_t *p_uart); /**< UART init MSP callback */ + void (*uart_msp_deinit)(uart_handle_t *p_uart); /**< UART de-init MSP callback */ + void (*uart_tx_cplt_callback)(uart_handle_t *p_uart); /**< UART tx transfer completed callback */ + void (*uart_rx_cplt_callback)(uart_handle_t *p_uart); /**< UART rx transfer completed callback */ + void (*uart_error_callback)(uart_handle_t *p_uart); /**< UART error callback */ + void (*uart_abort_cplt_callback)(uart_handle_t *p_uart); /**< UART abort completed callback */ + void (*uart_abort_tx_cplt_callback)(uart_handle_t *p_uart); /**< UART abort tansmit complete callback */ + void (*uart_abort_rx_cplt_callback)(uart_handle_t *p_uart); /**< UART abort receive complete callback */ +} hal_uart_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_UART_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UART_Exported_Constants UART Exported Constants + * @{ + */ + +/** @defgroup UART_Error_Code UART Error Code + * @{ + */ +#define HAL_UART_ERROR_NONE (0x00000000U) /**< No error */ +#define HAL_UART_ERROR_PE LL_UART_LSR_PE /**< Parity error */ +#define HAL_UART_ERROR_FE LL_UART_LSR_FE /**< frame error */ +#define HAL_UART_ERROR_OE LL_UART_LSR_OE /**< Overrun error */ +#define HAL_UART_ERROR_BI LL_UART_LSR_BI /**< Break dection error */ +#define HAL_UART_ERROR_DMA (0x00000100U) /**< DMA transfer error */ +#define HAL_UART_ERROR_BUSY (0x00000200U) /**< Busy Error */ +/** @} */ + +/** @defgroup UART_Data_Bits UART Number of Data Bits + * @{ + */ +#define UART_DATABITS_5 LL_UART_DATABITS_5B /**< UART frame with 5 data bits */ +#define UART_DATABITS_6 LL_UART_DATABITS_6B /**< UART frame with 6 data bits */ +#define UART_DATABITS_7 LL_UART_DATABITS_7B /**< UART frame with 7 data bits */ +#define UART_DATABITS_8 LL_UART_DATABITS_8B /**< UART frame with 8 data bits */ +/** @} */ + +/** @defgroup UART_Stop_Bits UART Number of Stop Bits + * @{ + */ +#define UART_STOPBITS_1 LL_UART_STOPBITS_1 /**< UART frame with 1 stop bit */ +#define UART_STOPBITS_1_5 LL_UART_STOPBITS_1_5 /**< UART frame with 1.5 stop bits */ +#define UART_STOPBITS_2 LL_UART_STOPBITS_2 /**< UART frame with 2 stop bits */ +/** @} */ + +/** @defgroup UART_Parity UART Parity + * @{ + */ +#define UART_PARITY_NONE LL_UART_PARITY_NONE /**< No parity */ +#define UART_PARITY_ODD LL_UART_PARITY_ODD /**< Odd parity */ +#define UART_PARITY_EVEN LL_UART_PARITY_EVEN /**< Even parity */ +#define UART_PARITY_SP0 LL_UART_PARITY_SP0 /**< Stick Parity 0 */ +#define UART_PARITY_SP1 LL_UART_PARITY_SP1 /**< Stick Parity 1 */ +/** @} */ + +/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control + * @{ + */ +#define UART_HWCONTROL_NONE LL_UART_HWCONTROL_NONE /**< No hardware control */ +#define UART_HWCONTROL_RTS_CTS LL_UART_HWCONTROL_RTS_CTS /**< Auto RTS and CTS hardware flow control */ +/** @} */ + +/** @defgroup UART_Receiver_TimeOut UART Receiver TimeOut + * @{ + */ +#define UART_RECEIVER_TIMEOUT_DISABLE (0x00000000U) /**< UART receiver timeout disable */ +#define UART_RECEIVER_TIMEOUT_ENABLE (0x00000001U) /**< UART receiver timeout enable */ +/** @} */ + +/** @defgroup UART_Interrupt_definition UART Interrupt_definition + * @{ + */ +#define UART_IT_MS LL_UART_IER_MS /**< Enable Modem Status Interrupt */ +#define UART_IT_RLS LL_UART_IER_RLS /**< Enable Receiver Line Status Interrupt */ +#define UART_IT_THRE LL_UART_IER_THRE /**< Enable Transmit Holding Register Empty Interrupt */ +#define UART_IT_RDA LL_UART_IER_RDA /**< Enable Received Data Available Interrupt and Character Timeout Interrupt */ +/** @} */ + +/** @defgroup UART_Request_Parameters UART Request Parameters + * @{ + */ +#define UART_RXDATA_FLUSH_REQUEST UART_SRR_RFR /**< RX FIFO flush Request */ +#define UART_TXDATA_FLUSH_REQUEST UART_SRR_XFR /**< TX FIFO flush Request */ +#define UART_TXRXDATA_FLUSH_REQUEST (UART_SRR_XFR | UART_SRR_RFR) /**< TX FIFO and RX FIFO flush Request */ +/** @} */ + +/** @defgroup UART_Interrupt_Mask UART Interrupt Flag Mask + * @{ + */ +#define UART_IT_MASK (0x008FU) /**< UART interruptions flags mask */ +/** @} */ + +/** @defgroup UART_Line_Error_Mask UART Line Error Flag Mask + * @{ + */ +#define UART_LINE_ERROR_MASK (LL_UART_LSR_PE | LL_UART_LSR_OE | LL_UART_LSR_FE | LL_UART_LSR_BI) /**< UART interruptions flags mask */ +/** @} */ + +/** @defgroup UART_Retention_Length UART Retention Register Length + * @{ + */ +#define UART_RETENTION_LENGTH ((uint32_t)8) /**< the number of retention registers */ +/** @} */ + +/** @defgroup UART_Timeout_definition UART Timeout_definition + * @{ + */ +#define HAL_UART_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000) /**< 5s */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup UART_Exported_Macros UART Exported Macros + * @{ + */ + +/** @brief Reset UART handle states. + * @param __HANDLE__ UART handle. + * @retval None + */ +#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) \ + do{ \ + (__HANDLE__)->g_state = HAL_UART_STATE_RESET; \ + (__HANDLE__)->rx_state = HAL_UART_STATE_RESET; \ + } while(0U) + +/** @brief Enable the specified UART interrupt. + * @param __HANDLE__ Specifies the UART Handle. + * @param __INTERRUPT__ Specifies the UART interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RDA + * @arg @ref UART_IT_THRE + * @arg @ref UART_IT_RLS + * @arg @ref UART_IT_MS + * @retval None + */ +#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + do { \ + GLOBAL_EXCEPTION_DISABLE(); \ + ll_uart_enable_it((__HANDLE__)->p_instance, (__INTERRUPT__)); \ + GLOBAL_EXCEPTION_ENABLE(); \ + } while(0U) + +/** @brief Disable the specified UART interrupt. + * @param __HANDLE__ Specifies the UART Handle. + * @param __INTERRUPT__ Specifies the UART interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RDA + * @arg @ref UART_IT_THRE + * @arg @ref UART_IT_RLS + * @arg @ref UART_IT_MS + * @retval None + */ +#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + do { \ + GLOBAL_EXCEPTION_DISABLE(); \ + ll_uart_disable_it((__HANDLE__)->p_instance, (__INTERRUPT__)); \ + GLOBAL_EXCEPTION_ENABLE(); \ + } while(0) + +/** @brief Flush the UART FIFO and treat FIFO as empty. + * @param __HANDLE__ Specifies the UART Handle. + * @param __REQ__ Specifies the request flag to set + * This parameter can be one of the following values: + * @arg @ref UART_RXDATA_FLUSH_REQUEST RX FIFO flush Request + * @arg @ref UART_TXDATA_FLUSH_REQUEST TX FIFO flush Request + * @arg @ref UART_TXRXDATA_FLUSH_REQUEST TX FIFO and RX FIFO flush + * @retval None + */ +#define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->p_instance->SRR = (__REQ__)) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UART_Private_Macro UART Private Macros + * @{ + */ + +/** @brief Check if UART Baudrate is valid. + * @param __BAUDRATE__ UART Baudrate. + * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) + */ +#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 921600U) + +/** + * @brief Check if UART frame number of stop bits is valid. + * @param __STOPBITS__ UART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_UART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ + ((__STOPBITS__) == UART_STOPBITS_1_5) || \ + ((__STOPBITS__) == UART_STOPBITS_2)) + +/** + * @brief Check if UART frame number of data bits is valid. + * @param __DATABITS__ UART frame number of data bits. + * @retval SET (__DATABITS__ is valid) or RESET (__DATABITS__ is invalid) + */ +#define IS_UART_DATABITS(__DATABITS__) (((__DATABITS__) == UART_DATABITS_5) || \ + ((__DATABITS__) == UART_DATABITS_6) || \ + ((__DATABITS__) == UART_DATABITS_7) || \ + ((__DATABITS__) == UART_DATABITS_8)) + +/** + * @brief Check if UART frame parity is valid. + * @param __PARITY__ UART frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_UART_PARITY(__PARITY__) (((__PARITY__) == UART_PARITY_NONE) || \ + ((__PARITY__) == UART_PARITY_EVEN) || \ + ((__PARITY__) == UART_PARITY_ODD) || \ + ((__PARITY__) == UART_PARITY_SP0) || \ + ((__PARITY__) == UART_PARITY_SP1)) + +/** + * @brief Check if UART hardware flow control is valid. + * @param __CONTROL__ UART hardware flow control. + * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid) + */ +#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)\ + (((__CONTROL__) == UART_HWCONTROL_NONE) || \ + ((__CONTROL__) == UART_HWCONTROL_RTS_CTS) +/** @} */ + +/** + * @brief Default configuartion for initializing structure + */ +#define UART_DEFAULT_CONFIG \ +{ \ + .baud_rate = 9600, \ + .data_bits = UART_DATABITS_8, \ + .stop_bits = UART_STOPBITS_1, \ + .parity = UART_PARITY_NONE, \ + .hw_flow_ctrl = UART_HWCONTROL_NONE, \ + .rx_timeout_mode = UART_RECEIVER_TIMEOUT_DISABLE, \ +} + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_UART_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * + * @verbatim +=============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the UARTx. + (+) For the asynchronous mode the parameters below can be configured: + (++) Baud Rate + (++) Data Bit + (++) Stop Bit + (++) Parity + (++) Hardware flow control + [..] + The hal_uart_init() API follow the UART asynchronous configuration procedures. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the UART according to the specified + * parameters in the uart_init_t and initialize the associated handle. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_init(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief De-initialize the UART peripheral. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_deinit (uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Initialize the UART MSP. + * @note This function should not be modified. When the callback is needed, + the hal_uart_msp_init can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_msp_init(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief De-initialize the UART MSP. + * @note This function should not be modified. When the callback is needed, + the hal_uart_msp_deinit can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_msp_deinit(uart_handle_t *p_uart); + +/** @} */ + +/** @addtogroup UART_Exported_Functions_Group2 IO operation functions + * @brief UART Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the UART asynchronous + and Half duplex data transfers. + + (#) There are two mode of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The hal_uart_tx_cplt_callback(), hal_uart_rx_cplt_callback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The hal_uart_error_callback() user callback will be executed when a + communication error is detected + + (#) Blocking mode API's are : + (++) hal_uart_transmit() + (++) hal_uart_receive() + + (#) Non-Blocking mode API's with Interrupt are : + (++) hal_uart_transmit_it() + (++) hal_uart_receive_it() + (++) hal_uart_irq_handler() + + (#) Non-Blocking mode API's with DMA are : + (++) hal_uart_transmit_dma() + (++) hal_uart_receive_dma() + (++) hal_uart_dma_pause() + (++) hal_uart_dma_resume() + (++) hal_uart_dma_stop() + + (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: + (++) hal_uart_tx_cplt_callback() + (++) hal_uart_rx_cplt_callback() + (++) hal_uart_error_callback() + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (++) hal_uart_abort() + (++) hal_uart_abort_transmit() + (++) hal_uart_abort_receive() + (++) hal_uart_abort_it() + (++) hal_uart_abort_transmit_it() + (++) hal_uart_abort_receive_it() + + (#) For Abort services based on interrupts (hal_uart_abort_xxx_it), a set + of Abort Complete Callbacks are provided: + (++) hal_uart_abort_cplt_callback() + (++) hal_uart_abort_tx_cplt_callback() + (++) hal_uart_abort_rx_cplt_callback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (++) Error is considered as Recoverable and non blocking. Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, + and hal_uart_error_callback() user callback is executed. Transfer is kept ongoing on UART side. + If user wants to abort it, Abort services should be called by user. + (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and hal_uart_error_callback() user callback is executed. + + -@- In the Half duplex communication, it is forbidden to run the transmit + and receive process in parallel, the UART state hal_uart_state_busy_tx_rx can't be useful. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Send an amount of data in blocking mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[in] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be sent. + * @param[in] timeout: Timeout duration. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_transmit(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[out] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be received. + * @param[in] timeout: Timeout duration. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_receive(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size, uint32_t timeout); + +/** + **************************************************************************************** + * @brief Send an amount of data in interrupt mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[in] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be sent. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_transmit_it(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive an amount of data in interrupt mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[out] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be received. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_receive_it(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Send an amount of data in DMA mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[in] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be sent, ranging between 0 ~ 4095. + * @note This function starts a DMA transfer in interrupt mode meaning that + * DMA half transfer complete, DMA transfer complete and DMA transfer + * error interrupts are enabled + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_transmit_dma(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Receive an amount of data in DMA mode. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @param[out] p_data: Pointer to data buffer. + * @param[in] size: Amount of data to be received, ranging between 0 and 4095. + * @note When the UART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). + * @note This function starts a DMA transfer in interrupt mode meaning that + * DMA half transfer complete, DMA transfer complete and DMA transfer + * error interrupts are enabled + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_receive_dma(uart_handle_t *p_uart, uint8_t *p_data, uint16_t size); + +/** + **************************************************************************************** + * @brief Pause the DMA Transfer. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_dma_pause(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Resume the DMA Transfer. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_dma_resume(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Stop the DMA Transfer. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_dma_stop(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing transfers (blocking mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort_transmit(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode: when exiting function, Abort is considered as completed. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort_receive(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing transfers (Interrupt mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort_it (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort_it(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort_it (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort_transmit_it(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling hal_dma_abort_it (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_abort_receive_it(uart_handle_t *p_uart); + +/** @} */ + +/** @addtogroup UART_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle UART interrupt request. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration information + * for the specified UART module. + **************************************************************************************** + */ +void hal_uart_irq_handler(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Tx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_tx_cplt_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_tx_cplt_callback(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Rx Transfer completed callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_rx_cplt_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_rx_cplt_callback(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief UART error callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_error_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_error_callback(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief UART Abort Complete callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_abort_cplt_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_abort_cplt_callback (uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief UART Abort Tansmit Complete callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_abort_tx_cplt_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_abort_tx_cplt_callback (uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief UART Abort Receive Complete callback. + * @note This function should not be modified. When the callback is needed, + * the hal_uart_abort_rx_cplt_callback can be implemented in the user file. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + **************************************************************************************** + */ +void hal_uart_abort_rx_cplt_callback (uart_handle_t *p_uart); + +/** @} */ + + +/** @addtogroup UART_Exported_Functions_Group3 Peripheral Control and State functions + * @brief UART Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral Control and State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the UART handle state. + (+) Return the UART handle error code + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the UART handle state. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_UART_STATE_RESET: Peripheral is not initialized. + * @retval ::HAL_UART_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_UART_STATE_BUSY: An internal process is ongoing. + * @retval ::HAL_UART_STATE_BUSY_TX: Data Transmission process is ongoing. + * @retval ::HAL_UART_STATE_BUSY_RX: Data Reception process is ongoing. + * @retval ::HAL_UART_STATE_TIMEOUT: Timeout state. + * @retval ::HAL_UART_STATE_ERROR: Error. + **************************************************************************************** + */ +hal_uart_state_t hal_uart_get_state(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Return the UART handle error code. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @return UART Error Code + **************************************************************************************** + */ +uint32_t hal_uart_get_error(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Suspend some registers related to UART configuration before sleep. + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_suspend_reg(uart_handle_t *p_uart); + +/** + **************************************************************************************** + * @brief Restore some registers related to UART configuration after sleep. + * This function must be used in conjunction with the hal_uart_suspend_reg(). + * @param[in] p_uart: Pointer to a UART handle which contains the configuration + * information for the specified UART module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_uart_resume_reg(uart_handle_t *p_uart); + + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_UART_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_wdt.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_wdt.h new file mode 100644 index 0000000..c327642 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_wdt.h @@ -0,0 +1,323 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_wdt.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of WDT HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_WDT WDT + * @brief WDT HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_WDT_H__ +#define __GR55xx_HAL_WDT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_wdt.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_WDT_STRUCTURES Structures + * @{ + */ + +/** @defgroup WDT_Configuration WDT Configuration + * @{ + */ + +/** + * @brief WDT init structure definition + */ +typedef struct _wdt_init +{ + uint32_t counter; /**< Specifies the WDT free-running downcounter value. + This parameter can be a number ranging between 0x0U and 0xFFFFFFFFU. */ + + uint32_t reset_mode ; /**< Specifies if WDT Reset output is enable or not. + When RESET Mode is enabled, WDT will generate an interrupt + on first timeout. If interrupt has not been cleared before the second + timeout, WDT will then request a SoC Reset. + + This parameter can be a value of @ref WDT_RESET_Mode. */ + +} wdt_init_t; + +/** @} */ + +/** @defgroup WDT_handle WDT handle + * @{ + */ + +/** + * @brief WDT handle Structure definition + */ +typedef struct _wdt_handle +{ + wdt_regs_t *p_instance; /**< Register base address */ + + wdt_init_t init; /**< WDT required parameters */ + + hal_lock_t lock; /**< WDT locking object */ + +} wdt_handle_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_WDT_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_WDT_Callback Callback + * @{ + */ + +/** + * @brief HAL_WDT Callback function definition + */ + +typedef struct _hal_wdt_callback +{ + void (*wdt_msp_init)(wdt_handle_t *p_wdt); /**< WDT init MSP callback */ + void (*wdt_msp_deinit)(wdt_handle_t *p_wdt); /**< WDT de-init MSP callback */ + void (*wdt_period_elapsed_callback)(wdt_handle_t *p_wdt); /**< WDT count complete callback */ +} hal_wdt_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_WDT_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup WDT_Exported_Constants WDT Exported Constants + * @{ + */ + +/** @defgroup WDT_RESET_Mode WDT Reset Mode + * @{ + */ +#define WDT_RESET_DISABLE (0x00000000U) /**< Reset ouput disable */ +#define WDT_RESET_ENABLE (0x00000001U) /**< Reset output enable */ +/** @} */ + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup WDT_Private_Macros WDT Private Macros + * @{ + */ + +/** + * @brief Check if the WDT reset mode is valid. + * @param __MODE__ WDT reset mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_WDT_RESET_MODE(__MODE__) (((__MODE__) == WDT_RESET_ENABLE) || \ + ((__MODE__) == WDT_RESET_DISABLE)) +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_WDT_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @addtogroup WDT_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and start the WDT according to the specified parameters + in the wdt_init_t of associated handle. + (+) Initialize the WDT MSP. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the WDT according to the specified + * parameters in the wdt_init_t of associated handle. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_wdt_init(wdt_handle_t *p_wdt); + +/** + **************************************************************************************** + * @brief De-initialize the WDT peripheral. + * @param[in] p_wdt: WDT handle. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_wdt_deinit(wdt_handle_t *p_wdt); + +/** + **************************************************************************************** + * @brief Initialize the WDT MSP. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + * @note When rewriting this function in a user file, this mechanism may be added + * to avoid multiple initialization when hal_wdt_init function is called + * again to change parameters. + **************************************************************************************** + */ +void hal_wdt_msp_init(wdt_handle_t *p_wdt); + +/** + **************************************************************************************** + * @brief De-initialize the WDT MSP. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + * @note When rewriting this function in a user file, this mechanism may be added + * to avoid multiple initialization when hal_wdt_init function is called + * again to change parameters. + **************************************************************************************** + */ +void hal_wdt_msp_deinit(wdt_handle_t *p_wdt); + +/** @} */ + +/** @addtogroup WDT_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Refresh the WDT. + (+) Handle WDT interrupt request and associated function callback. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Refresh the WDT. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_wdt_refresh(wdt_handle_t *p_wdt); + +/** @} */ + + +/** @addtogroup WDT_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @brief IRQ Handler and Callbacks functions + * @{ + */ + +/** + **************************************************************************************** + * @brief Handle WDT interrupt request. + * @note The Count Complete can be used if specific safety operations + * or data logging must be performed before the actual reset is generated. + * When RESET Mode is enabled, WDT will generate an interrupt on first timeout. + * If interrupt has not been cleared before the second timeout, WDT will then + * request a SoC Reset. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + **************************************************************************************** + */ +void hal_wdt_irq_handler(wdt_handle_t *p_wdt); + +/** + **************************************************************************************** + * @brief WDT count complete(counter reaches to 0) callback. + * @note In RESET mode, NVIC interrupt of WDT can be disabled in + * hal_wdt_period_elapsed_callback() to make sure this callback + * be called once only. + * This function should not be modified. When the callback is needed, + * the hal_wdt_count_cplt_callback can be implemented in the user file. + * @param[in] p_wdt: Pointer to a WDT handle which contains the configuration + * information for the specified WDT module. + **************************************************************************************** + */ +void hal_wdt_period_elapsed_callback(wdt_handle_t *p_wdt); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_WDT_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_xqspi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_xqspi.h new file mode 100644 index 0000000..3cd20cc --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_hal_xqspi.h @@ -0,0 +1,826 @@ +/** + **************************************************************************************** + * + * @file gr55xx_hal_xqspi.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of XQSPI HAL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_XQSPI XQSPI + * @brief XQSPI HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_HAL_XQSPI_H__ +#define __GR55xx_HAL_XQSPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_ll_xqspi.h" +#include "gr55xx_hal_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup HAL_XQSPI_ENUMERATIONS Enumerations + * @{ + */ + +/** @defgroup HAL_XQSPI_state HAL XQSPI state + * @{ + */ + +/** + * @brief HAL XQSPI State Enumerations definition + */ +typedef enum +{ + HAL_XQSPI_STATE_RESET = 0x00, /**< Peripheral not initialized */ + HAL_XQSPI_STATE_READY = 0x01, /**< Peripheral initialized and ready for use */ + HAL_XQSPI_STATE_BUSY = 0x02, /**< Peripheral in indirect mode and busy */ + HAL_XQSPI_STATE_BUSY_INDIRECT_TX = 0x12, /**< Peripheral in indirect mode with transmission ongoing */ + HAL_XQSPI_STATE_BUSY_INDIRECT_RX = 0x22, /**< Peripheral in indirect mode with reception ongoing */ + HAL_XQSPI_STATE_ABORT = 0x08, /**< Peripheral with abort request ongoing */ + HAL_XQSPI_STATE_ERROR = 0x04 /**< Peripheral in error */ + +} hal_xqspi_state_t; + +/** @} */ + +/** @} */ + +/** @addtogroup HAL_XQSPI_STRUCTURES Structures + * @{ + */ + +/** @defgroup XQSPI_Configuration XQSPI Configuration + * @{ + */ + +/** + * @brief XQSPI init Structure definition + */ +typedef struct _xqspi_init_t +{ + uint32_t work_mode; /**< Specifies the work mode for XQSPI. + This parameter can be a value of @ref XQSPI_Work_Mode */ + + uint32_t cache_mode; /**< Specifies the cache mode for XIP mode. + This parameter can be a value of @ref XQSPI_Cache_Mode */ + + uint32_t read_cmd; /**< Specifies the read command for transmit in XIP mode. + This parameter can be a value of @ref XQSPI_Read_CMD */ + + uint32_t baud_rate; /**< Specifies the serial clock speed for transmit in both XIP and QSPI mode. + This parameter can be a value of @ref XQSPI_Baud_Rate */ + + uint32_t clock_mode; /**< Specifies the Clock Mode. It indicates the level that clock takes between commands. + This parameter can be a value of @ref XQSPI_Clock_Mode */ + +} xqspi_init_t; +/** @} */ + +/** @defgroup XQSPI_handle XQSPI handle + * @{ + */ + +/** + * @brief XQSPI handle Structure definition + */ +typedef struct _xqspi_handle_t +{ + xqspi_regs_t *p_instance; /**< XQSPI registers base address */ + + xqspi_init_t init; /**< XQSPI communication parameters */ + + uint8_t *p_tx_buffer; /**< Pointer to XQSPI Tx transfer Buffer */ + + __IO uint32_t tx_xfer_size; /**< XQSPI Tx Transfer size */ + + __IO uint32_t tx_xfer_count; /**< XQSPI Tx Transfer Counter */ + + uint8_t *p_rx_buffer; /**< Pointer to XQSPI Rx transfer Buffer */ + + __IO uint32_t rx_xfer_size; /**< XQSPI Rx Transfer size */ + + __IO uint32_t rx_xfer_count; /**< XQSPI Rx Transfer Counter */ + + __IO hal_lock_t lock; /**< Locking object */ + + __IO hal_xqspi_state_t state; /**< XQSPI communication state */ + + __IO uint32_t error_code; /**< XQSPI Error code */ + + uint32_t retry; /**< Retry for the XQSPI flag access */ + +} xqspi_handle_t; +/** @} */ + +/** @defgroup XQSPI_Command XQSPI command + * @{ + */ + +/** + * @brief XQSPI command Structure definition + */ +typedef struct _xqspi_command_t +{ + uint32_t inst; /**< Specifies the Instruction to be sent. + This parameter can be a value (8-bit) between 0x00 and 0xFF */ + + uint32_t addr; /**< Specifies the Address to be sent (Size from 1 to 4 bytes according to AddressSize). + This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF */ + + uint32_t inst_size; /**< Specifies the Instruction Size. + This parameter can be a value of @ref XQSPI_Instruction_Size */ + + uint32_t addr_size; /**< Specifies the Address Size. + This parameter can be a value of @ref XQSPI_Address_Size */ + + uint32_t dummy_cycles; /**< Specifies the Number of Dummy Cycles. + This parameter can be a number between 0 and 31 */ + + uint32_t inst_addr_mode; /**< Specifies the Instruction and Address Mode. + This parameter can be a value of @ref XQSPI_Inst_Addr_Mode */ + + uint32_t data_mode; /**< Specifies the Data Mode (used for dummy cycles and data phases). + This parameter can be a value of @ref XQSPI_Data_Mode */ + + uint32_t length; /**< Specifies the number of data to transfer. (This is the number of bytes). + This parameter can be any value between 0 and 0xFFFFFFFF (0 means undefined length + until end of memory) */ + +} xqspi_command_t; +/** @} */ + +/** @} */ + +/** @addtogroup HAL_XQSPI_CALLBACK_STRUCTURES Callback Structures + * @{ + */ + +/** @defgroup HAL_XQSPI_Callback Callback + * @{ + */ + +/** + * @brief HAL_XQSPI Callback function definition + */ + +typedef struct _hal_xqspi_callback +{ + void (*xqspi_msp_init)(xqspi_handle_t *p_xqspi); /**< XQSPI init MSP callback */ + void (*xqspi_msp_deinit)(xqspi_handle_t *p_xqspi); /**< XQSPI de-init MSP callback */ +} hal_xqspi_callback_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HAL_XQSPI_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup XQSPI_Exported_Constants XQSPI Exported Constants + * @{ + */ + +/** @defgroup XQSPI_Error_Code XQSPI Error Code + * @{ + */ +#define HAL_XQSPI_ERROR_NONE ((uint32_t)0x00000000) /**< No error */ +#define HAL_XQSPI_ERROR_TIMEOUT ((uint32_t)0x00000001) /**< Timeout error */ +#define HAL_XQSPI_ERROR_TRANSFER ((uint32_t)0x00000002) /**< Transfer error */ +#define HAL_XQSPI_ERROR_INVALID_PARAM ((uint32_t)0x00000008) /**< Invalid parameter error */ +/** @} */ + +/** @defgroup XQSPI_Work_Mode XQSPI Work Mode + * @{ + */ +#define XQSPI_WORK_MODE_QSPI LL_XQSPI_MODE_QSPI /**< Work in QSPI mode */ +#define XQSPI_WORK_MODE_XIP LL_XQSPI_MODE_XIP /**< Work in XIP mode */ +/** @} */ + +/** @defgroup XQSPI_Cache_Mode XQSPI Cache Mode in XIP mode + * @{ + */ +#define XQSPI_CACHE_MODE_DIS LL_XQSPI_CACHE_DIS /**< Cache off in XIP mode */ +#define XQSPI_CACHE_MODE_EN LL_XQSPI_CACHE_EN /**< Cache on in XIP mode */ +/** @} */ + +/** @defgroup XQSPI_Read_CMD XQSPI Read Command in XIP mode + * @{ + */ +#define XQSPI_READ_CMD_READ LL_XQSPI_XIP_CMD_READ /**< Read mode */ +#define XQSPI_READ_CMD_FAST_READ LL_XQSPI_XIP_CMD_FAST_READ /**< Fast Read mode */ +#define XQSPI_READ_CMD_DUAL_OUT_READ LL_XQSPI_XIP_CMD_DUAL_OUT_READ /**< Dual-Out Fast Read mode */ +#define XQSPI_READ_CMD_DUAL_IO_READ LL_XQSPI_XIP_CMD_DUAL_IO_READ /**< Dual-IO Fast Read mode */ +#define XQSPI_READ_CMD_QUAD_OUT_READ LL_XQSPI_XIP_CMD_QUAD_OUT_READ /**< Quad-Out Fast Read mode */ +#define XQSPI_READ_CMD_QUAD_IO_READ LL_XQSPI_XIP_CMD_QUAD_IO_READ /**< Quad-IO Fast Read mode */ +/** @} */ + +/** @defgroup XQSPI_Clock_Mode XQSPI Clock Mode + * @{ + */ +#define XQSPI_CLOCK_MODE_0 ((LL_XQSPI_SCPOL_LOW << 1) | LL_XQSPI_SCPHA_1EDGE) /**< Inactive state of CLK is low, + CLK toggles at the start of first data bit */ +#define XQSPI_CLOCK_MODE_1 ((LL_XQSPI_SCPOL_LOW << 1) | LL_XQSPI_SCPHA_2EDGE) /**< Inactive state of CLK is low, + CLK toggles in the middle of first data bit */ +#define XQSPI_CLOCK_MODE_2 ((LL_XQSPI_SCPOL_HIGH << 1) | LL_XQSPI_SCPHA_1EDGE) /**< Inactive state of CLK is high, + CLK toggles at the start of first data bit */ +#define XQSPI_CLOCK_MODE_3 ((LL_XQSPI_SCPOL_HIGH << 1) | LL_XQSPI_SCPHA_2EDGE) /**< Inactive state of CLK is high, + CLK toggles in the middle of first data bit */ +/** @} */ + +/** @defgroup XQSPI_Baud_Rate XQSPI Clock Speed + * @{ + */ +#define XQSPI_BAUD_RATE_64M LL_XQSPI_BAUD_RATE_64M /**< Serial clock speed is 64 MHz */ +#define XQSPI_BAUD_RATE_48M LL_XQSPI_BAUD_RATE_48M /**< Serial clock speed is 48 MHz */ +#define XQSPI_BAUD_RATE_32M LL_XQSPI_BAUD_RATE_32M /**< Serial clock speed is 32 MHz */ +#define XQSPI_BAUD_RATE_24M LL_XQSPI_BAUD_RATE_24M /**< Serial clock speed is 24 MHz */ +#define XQSPI_BAUD_RATE_16M LL_XQSPI_BAUD_RATE_16M /**< Serial clock speed is 16 MHz */ +/** @} */ + +/** @defgroup XQSPI_Data_Mode XQSPI Data Mode, only in QSPI mode + * @{ + */ +#define XQSPI_DATA_MODE_SPI LL_XQSPI_QSPI_FRF_SPI /**< Standard SPI Frame Format */ +#define XQSPI_DATA_MODE_DUALSPI LL_XQSPI_QSPI_FRF_DUALSPI /**< Dual-SPI Frame Format */ +#define XQSPI_DATA_MODE_QUADSPI LL_XQSPI_QSPI_FRF_QUADSPI /**< Quad-SPI Frame Format */ +/** @} */ + +/** @defgroup XQSPI_FIFO_Threshold XQSPI FIFO Threshold, FIFO depth is 64*4bytes, only in QSPI mode + * @{ + */ +#define XQSPI_FIFO_THRESHOLD_1_8 LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 /**< FIFO depth/8 */ +#define XQSPI_FIFO_THRESHOLD_1_4 LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 /**< FIFO depth/4 */ +#define XQSPI_FIFO_THRESHOLD_1_2 LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 /**< FIFO depth/2 */ +#define XQSPI_FIFO_THRESHOLD_3_4 LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 /**< FIFO depth*3/4 */ +#define XQSPI_FIFO_DEPTH LL_XQSPI_QSPI_FIFO_DEPTH /**< FIFO full depth */ +/** @} */ + +/** @defgroup XQSPI_Instruction_Size XQSPI Instruction Size, only in QSPI mode + * @{ + */ +#define XQSPI_INSTSIZE_00_BITS (0) /**< 0-bit (No Instruction) */ +#define XQSPI_INSTSIZE_08_BITS (1) /**< 8-bit Instruction */ +#define XQSPI_INSTSIZE_16_BITS (2) /**< 16-bit Instruction */ +/** @} */ + +/** @defgroup XQSPI_Address_Size XQSPI Address Size, only in QSPI mode + * @{ + */ +#define XQSPI_ADDRSIZE_00_BITS (0) /**< 0-bit (No Address) */ +#define XQSPI_ADDRSIZE_08_BITS (1) /**< 8-bit Address */ +#define XQSPI_ADDRSIZE_16_BITS (2) /**< 16-bit Address */ +#define XQSPI_ADDRSIZE_24_BITS (3) /**< 24-bit Address */ +#define XQSPI_ADDRSIZE_32_BITS (4) /**< 32-bit Address */ +/** @} */ + +/** @defgroup XQSPI_Inst_Addr_Mode XQSPI Instruction and Address Mode, only in QSPI mode + * @{ + */ +#define XQSPI_INST_ADDR_ALL_IN_SPI (0) /**< Instruction and address are sent in SPI mode */ +#define XQSPI_INST_IN_SPI_ADDR_IN_SPIFRF (1) /**< Instruction is sent in SPI mode, and address is sent in Daul/Quad SPI mode */ +#define XQSPI_INST_ADDR_ALL_IN_SPIFRF (2) /**< Instruction and address are sent in Daul/Quad SPI mode */ +/** @} */ + +/** @defgroup XQSPI_Flags XQSPI Flags, only in QSPI mode + * @{ + */ +#define XQSPI_FLAG_RFF LL_XQSPI_QSPI_STAT_RFF /**< Rx FIFO full flag */ +#define XQSPI_FLAG_RFTF LL_XQSPI_QSPI_STAT_RFTF /**< Rx FIFO threshold flag */ +#define XQSPI_FLAG_RFE LL_XQSPI_QSPI_STAT_RFE /**< Rx FIFO empty flag */ +#define XQSPI_FLAG_TFF LL_XQSPI_QSPI_STAT_TFF /**< Tx FIFO full flag */ +#define XQSPI_FLAG_TFTF LL_XQSPI_QSPI_STAT_TFTF /**< Tx FIFO threshold flag */ +#define XQSPI_FLAG_TFE LL_XQSPI_QSPI_STAT_TFE /**< Tx FIFO empty flag */ +#define XQSPI_FLAG_BUSY LL_XQSPI_QSPI_STAT_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup XQSPI_Ctrl_Present Control Present Status, only in XIP mode + * @{ + */ +#define XQSPI_DISABLE_PRESENT LL_XQSPI_DISABLE_PRESENT /**< Disable Present */ +#define XQSPI_ENABLE_PRESENT LL_XQSPI_ENABLE_PRESENT /**< Enable Present */ +/** @} */ + +/** + * @brief XQSPI_Retry_definition XQSPI Retry definition + */ +#define HAL_XQSPI_RETRY_DEFAULT_VALUE ((uint32_t)1000) /**< 1000 times */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup XQSPI_Exported_Macros XQSPI Exported Macros + * @{ + */ + +/** @brief Reset XQSPI handle states. + * @param __HANDLE__ XQSPI handle. + * @retval None + */ +#define __HAL_XQSPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->state = HAL_XQSPI_STATE_RESET) + +/** @brief Enable the specified QSPI peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_ENABLE_QSPI(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->QSPI.SPIEN, SSI_SSIEN_EN) + +/** @brief Disable the specified QSPI peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_DISABLE_QSPI(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->QSPI.SPIEN, SSI_SSIEN_EN) + +/** @brief Enable the specified XIP peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_ENABLE_XIP(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->XIP.CTRL3, SSI_SSIEN_EN);\ + while(!ll_xqspi_get_xip_flag(__HANDLE__->p_instance)) + +/** @brief Disable the specified XIP peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_DISABLE_XIP(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->XIP.CTRL3, SSI_SSIEN_EN);\ + while(ll_xqspi_get_xip_flag(__HANDLE__->p_instance)) + +/** @brief Enable the specified CACHE peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_ENABLE_CACHE(__HANDLE__) CLEAR_BITS((__HANDLE__)->p_instance->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS) + +/** @brief Disable the specified CACHE peripheral in XQSPI. + * @param __HANDLE__ specifies the XQSPI Handle. + * @retval None + */ +#define __HAL_XQSPI_DISABLE_CACHE(__HANDLE__) SET_BITS((__HANDLE__)->p_instance->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS) + +/** @brief Check whether the specified XQSPI flag is set or not. + * @param __HANDLE__ specifies the XQSPI Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref XQSPI_FLAG_RFF Rx FIFO full flag + * @arg @ref XQSPI_FLAG_RFTF Rx FIFO threshold flag + * @arg @ref XQSPI_FLAG_RFE Rx FIFO empty flag + * @arg @ref XQSPI_FLAG_TFF Tx FIFO full flag + * @arg @ref XQSPI_FLAG_TFTF Tx FIFO threshold flag + * @arg @ref XQSPI_FLAG_TFE Tx FIFO empty flag + * @arg @ref XQSPI_FLAG_BUSY Busy flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_XQSPI_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BITS((__HANDLE__)->p_instance->QSPI.STAT, (__FLAG__)) != 0) ? SET : RESET) + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup XQSPI_Private_Macro XQSPI Private Macros + * @{ + */ + +/** @brief Check if XQSPI Work Mode is valid. + * @param __MODE__ XQSPI Work Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_XQSPI_WORK_MODE(__MODE__) (((__MODE__) == XQSPI_WORK_MODE_QSPI) || \ + ((__MODE__) == XQSPI_WORK_MODE_XIP)) + +/** @brief Check if XQSPI Cache Mode is valid. + * @param __MODE__ XQSPI Cache Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_XQSPI_CACHE_MODE(__MODE__) (((__MODE__) == XQSPI_CACHE_MODE_DIS) || \ + ((__MODE__) == XQSPI_CACHE_MODE_EN)) + +/** @brief Check if XQSPI Read CMD is valid. + * @param __CMD__ XQSPI Cache Mode. + * @retval SET (__CMD__ is valid) or RESET (__CMD__ is invalid) + */ +#define IS_XQSPI_READ_CMD(__CMD__) (((__CMD__) == XQSPI_READ_CMD_READ ) || \ + ((__CMD__) == XQSPI_READ_CMD_FAST_READ ) || \ + ((__CMD__) == XQSPI_READ_CMD_DUAL_OUT_READ) || \ + ((__CMD__) == XQSPI_READ_CMD_DUAL_IO_READ ) || \ + ((__CMD__) == XQSPI_READ_CMD_QUAD_OUT_READ) || \ + ((__CMD__) == XQSPI_READ_CMD_QUAD_IO_READ )) + +/** @brief Check if XQSPI Clock Baud Rate is valid. + * @param __BAUD__ XQSPI Clock Baud Rate. + * @retval SET (__BAUD__ is valid) or RESET (__BAUD__ is invalid) + */ +#define IS_XQSPI_BAUD_RATE(__BAUD__) (((__BAUD__) == XQSPI_BAUD_RATE_64M) || \ + ((__BAUD__) == XQSPI_BAUD_RATE_48M) || \ + ((__BAUD__) == XQSPI_BAUD_RATE_32M) || \ + ((__BAUD__) == XQSPI_BAUD_RATE_24M) || \ + ((__BAUD__) == XQSPI_BAUD_RATE_16M)) + +/** @brief Check if XQSPI Clock Mode is valid. + * @param __CLKMODE__ XQSPI Clock Mode. + * @retval SET (__CLKMODE__ is valid) or RESET (__CLKMODE__ is invalid) + */ +#define IS_XQSPI_CLOCK_MODE(__CLKMODE__) (((__CLKMODE__) == XQSPI_CLOCK_MODE_0) || \ + ((__CLKMODE__) == XQSPI_CLOCK_MODE_1) || \ + ((__CLKMODE__) == XQSPI_CLOCK_MODE_2) || \ + ((__CLKMODE__) == XQSPI_CLOCK_MODE_3)) + +/** @brief Check if XQSPI FIFO Threshold is valid. + * @param __THR__ XQSPI FIFO Threshold. + * @retval SET (__THR__ is valid) or RESET (__THR__ is invalid) + */ +#define IS_XQSPI_FIFO_THRESHOLD(__THR__) (((__THR__) == XQSPI_FIFO_THRESHOLD_1_8) || \ + ((__THR__) == XQSPI_FIFO_THRESHOLD_1_4) || \ + ((__THR__) == XQSPI_FIFO_THRESHOLD_1_2) || \ + ((__THR__) == XQSPI_FIFO_THRESHOLD_3_4)) + +/** @brief Check if XQSPI Instruction Size is valid. + * @param __INST_SIZE__ XQSPI Instruction Size. + * @retval SET (__INST_SIZE__ is valid) or RESET (__INST_SIZE__ is invalid) + */ +#define IS_XQSPI_INSTRUCTION_SIZE(__INST_SIZE__) (((__INST_SIZE__) == XQSPI_INSTSIZE_00_BITS) || \ + ((__INST_SIZE__) == XQSPI_INSTSIZE_08_BITS) || \ + ((__INST_SIZE__) == XQSPI_INSTSIZE_16_BITS)) + +/** @brief Check if XQSPI Address Size is valid. + * @param __ADDR_SIZE__ XQSPI Address Size . + * @retval SET (__ADDR_SIZE__ is valid) or RESET (__ADDR_SIZE__ is invalid) + */ +#define IS_XQSPI_ADDRESS_SIZE(__ADDR_SIZE__) (((__ADDR_SIZE__) == XQSPI_ADDRSIZE_00_BITS) || \ + ((__ADDR_SIZE__) == XQSPI_ADDRSIZE_08_BITS) || \ + ((__ADDR_SIZE__) == XQSPI_ADDRSIZE_16_BITS) || \ + ((__ADDR_SIZE__) == XQSPI_ADDRSIZE_24_BITS) || \ + ((__ADDR_SIZE__) == XQSPI_ADDRSIZE_32_BITS)) + +/** @brief Check if XQSPI Instruction and Address Mode is valid. + * @param __MODE__ XQSPI Instruction and Address Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_XQSPI_INSTADDR_MODE(__MODE__) (((__MODE__) == XQSPI_INST_ADDR_ALL_IN_SPI) || \ + ((__MODE__) == XQSPI_INST_IN_SPI_ADDR_IN_SPIFRF) || \ + ((__MODE__) == XQSPI_INST_ADDR_ALL_IN_SPIFRF)) + +/** @brief Check if XQSPI Data Mode is valid. + * @param __MODE__ XQSPI Data Mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_XQSPI_DATA_MODE(__MODE__) (((__MODE__) == XQSPI_DATA_MODE_SPI) || \ + ((__MODE__) == XQSPI_DATA_MODE_DUALSPI) || \ + ((__MODE__) == XQSPI_DATA_MODE_QUADSPI)) + +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_XQSPI_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup XQSPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the XQSPIx peripheral: + + (+) User must implement hal_xqspi_msp_init() function in which he configures + all related peripherals resources (GPIO, DMA, IT and NVIC ). + + (+) Call the function hal_xqspi_init() to configure the selected device with + the selected configuration: + (++) work_mode + (++) cache_mode + (++) read_cmd + (++) baud_rate + (++) clock_mode + + (+) Call the function hal_xqspi_deinit() to restore the default configuration + of the selected XQSPIx peripheral. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Initialize the XQSPI according to the specified parameters + * in the xqspi_init_t and initialize the associated handle. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_init(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief De-initialize the XQSPI peripheral. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_deinit(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief Initialize the XQSPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_xqspi_msp_deinit can be implemented in the user file. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + **************************************************************************************** + */ +void hal_xqspi_msp_init(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief De-initialize the XQSPI MSP. + * @note This function should not be modified. When the callback is needed, + the hal_xqspi_msp_deinit can be implemented in the user file. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + **************************************************************************************** + */ +void hal_xqspi_msp_deinit(xqspi_handle_t *p_xqspi); + +/** @} */ + +/** @defgroup XQSPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the XQSPI + data transfers. + + [..] The XQSPI supports master and slave mode: + + (#) There are one modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + + (#) APIs provided for only one transfer mode (Blocking mode) + exist for 1Line/2Line/4Line (simplex) modes. + +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Transmit an amount of data with specified instruction and address in blocking mode. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] p_cmd: Pointer to a xqspi_command_t structure that contains the instruction and address for data transfer. + * @param[in] p_data: Pointer to data buffer + * @param[in] retry: Repeat times + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_command_transmit(xqspi_handle_t *p_xqspi, xqspi_command_t *p_cmd, uint8_t *p_data, uint32_t retry); + +/** + **************************************************************************************** + * @brief Receive an amount of data with specified instruction and address in blocking mode. + * @note This function is used only in Indirect Write Mode. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] p_cmd: Pointer to a xqspi_command_t structure that contains the instruction and address for data transfer. + * @param[out] p_data: Pointer to data buffer + * @param[in] retry: Repeat times + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_command_receive(xqspi_handle_t *p_xqspi, xqspi_command_t *p_cmd, uint8_t *p_data, uint32_t retry); + +#if defined RTL_SIM +hal_status_t hal_xqspi_command_receive_rtl(xqspi_handle_t *p_xqspi, xqspi_command_t *p_cmd, uint8_t *p_data, uint32_t retry); +#endif + + +/** + **************************************************************************************** + * @brief Transmit an amount of data in blocking mode. + * @note This function is used only in Indirect Write Mode, only in standard SPI mode. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be sent in bytes + * @param[in] retry: Repeat times + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_transmit(xqspi_handle_t *p_xqspi, uint8_t *p_data, uint32_t length, uint32_t retry); + +/** + **************************************************************************************** + * @brief Receive an amount of data in blocking mode. + * @note This function is used only in Indirect Read Mode, only in standard SPI mode. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[out] p_data: Pointer to data buffer + * @param[in] length: Amount of data to be received in bytes + * @param[in] retry: Repeat times + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_receive(xqspi_handle_t *p_xqspi, uint8_t *p_data, uint32_t length, uint32_t retry); + +/** @} */ + +/** @defgroup XQSPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief XQSPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the XQSPI. + (+) hal_xqspi_get_state()API can be helpful to check in run-time the state of the XQSPI peripheral. + (+) hal_xqspi_get_error() check in run-time Errors occurring during communication. + (+) hal_xqspi_set_retry() set the repeat times during internal process. + (+) hal_xqspi_set_tx_fifo_threshold() set the TX FIFO Threshold. + (+) hal_xqspi_set_rx_fifo_threshold() set the RX FIFO Threshold. + (+) hal_xqspi_get_tx_fifo_threshold() get the TX FIFO Threshold. + (+) hal_xqspi_get_rx_fifo_threshold() get the RX FIFO Threshold. +@endverbatim + * @{ + */ + +/** + **************************************************************************************** + * @brief Return the XQSPI handle state. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @retval ::HAL_XQSPI_STATE_RESET: Peripheral not initialized. + * @retval ::HAL_XQSPI_STATE_READY: Peripheral initialized and ready for use. + * @retval ::HAL_XQSPI_STATE_BUSY: Peripheral in indirect mode and busy. + * @retval ::HAL_XQSPI_STATE_BUSY_INDIRECT_TX: Peripheral in indirect mode with transmission ongoing. + * @retval ::HAL_XQSPI_STATE_BUSY_INDIRECT_RX: Peripheral in indirect mode with reception ongoing. + * @retval ::HAL_XQSPI_STATE_ABORT: Peripheral with abort request ongoing. + * @retval ::HAL_XQSPI_STATE_ERROR: Peripheral in error. + **************************************************************************************** + */ +hal_xqspi_state_t hal_xqspi_get_state(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief Return the XQSPI error code. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @return XQSPI error code in bitmap format + **************************************************************************************** + */ +uint32_t hal_xqspi_get_error(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief Set the XQSPI internal process repeat times value. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] retry: Internal process repeat times value. + **************************************************************************************** + */ +void hal_xqspi_set_retry(xqspi_handle_t *p_xqspi, uint32_t retry); + +/** + **************************************************************************************** + * @brief Set the TXFIFO threshold. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] threshold: TX FIFO threshold can be one of the following values: + * @arg @ref XQSPI_FIFO_THRESHOLD_1_8 threshold is 8 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_1_4 threshold is 16 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_1_2 threshold is 32 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_3_4 threshold is 48 bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_set_tx_fifo_threshold(xqspi_handle_t *p_xqspi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Set the RXFIFO threshold. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] threshold: RX FIFO threshold can be one of the following values: + * @arg @ref XQSPI_FIFO_THRESHOLD_1_8 threshold is 8 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_1_4 threshold is 16 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_1_2 threshold is 32 bytes + * @arg @ref XQSPI_FIFO_THRESHOLD_3_4 threshold is 48 bytes + * @retval ::HAL_OK: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + **************************************************************************************** + */ +hal_status_t hal_xqspi_set_rx_fifo_threshold(xqspi_handle_t *p_xqspi, uint32_t threshold); + +/** + **************************************************************************************** + * @brief Get the TXFIFO threshold. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @return TX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_xqspi_get_tx_fifo_threshold(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief Get the RXFIFO threshold. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @return RX FIFO threshold + **************************************************************************************** + */ +uint32_t hal_xqspi_get_rx_fifo_threshold(xqspi_handle_t *p_xqspi); + +/** + **************************************************************************************** + * @brief Turn on/off present module, only in XIP mode. + * @param[in] p_xqspi: Pointer to an XQSPI handle which contains the configuration information for the specified XQSPI module. + * @param[in] status: Presen status can be one of the following values: + * @arg @ref XQSPI_DISABLE_PRESENT Disable Present + * @arg @ref XQSPI_ENABLE_PRESENT Enable Present + + **************************************************************************************** + */ +void hal_xqspi_set_xip_present_status(xqspi_handle_t *p_xqspi, uint32_t status); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_HAL_XQSPI_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_adc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_adc.h new file mode 100644 index 0000000..30e300b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_adc.h @@ -0,0 +1,1084 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_adc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ADC LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_ADC ADC + * @brief ADC LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_ADC_H__ +#define __GR55XX_LL_ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** @defgroup LL_ADC_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup LL_ADC_ES_INIT ADC Exported init structures + * @{ + */ + +/** + * @brief LL ADC init Structure definition + */ +typedef struct _ll_adc_init +{ + uint32_t channel_p; /**< Specifies the input source to ADC channel P. + This parameter can be any value of @ref LL_ADC_EC_INPUT_SRC. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_channelp(). */ + + uint32_t channel_n; /**< Specifies the input source to ADC channel N. + This parameter can be any value of @ref LL_ADC_EC_INPUT_SRC. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_channeln(). */ + + uint32_t input_mode; /**< Specifies the operation mode for the ADC sample. + This parameter can be a value of @ref LL_ADC_EC_INPUT_MODE. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_input_mode(). */ + + uint32_t ref_source; /**< Specifies the source of the ADC reference. + This parameter can be a value of @ref LL_ADC_EC_REFERENCE_SRC. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_ref().*/ + + uint32_t ref_value; /*!< Specifies the value of the ADC buffered reference. + This parameter can be a value of @ref LL_ADC_EC_REFERENCE. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_ref_value().*/ + + uint32_t clock; /**< Specifies the clock of ADC. + This parameter can be a value of @ref LL_ADC_EC_CLK. + + This parament can be modified afterwards using unitary function @ref ll_adc_set_clock().*/ + +} ll_adc_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup LL_ADC_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LL_ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup LL_ADC_EC_CLK ADC CLOCK + * @{ + */ +#define LL_ADC_CLK_16 (0x00000000UL) /**< 16 MHz */ +#define LL_ADC_CLK_8 (1UL << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) /**< 8 MHz */ +#define LL_ADC_CLK_4 (2UL << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) /**< 4 MHz */ +#define LL_ADC_CLK_2 (3UL << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) /**< 2 MHz */ +#define LL_ADC_CLK_1P6 (4UL << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) /**< 1.6 MHz */ +#define LL_ADC_CLK_1 (5UL << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) /**< 1 MHz */ +/** @} */ + +/** @defgroup LL_ADC_EC_REFERENCE ADC Buffered Internal Reference Value + * @{ + */ +#define LL_ADC_REF_VALUE_0P8 (0x3UL << AON_SNSADC_CFG_REF_VALUE_Pos) /**< Reference = 0.85 V */ +#define LL_ADC_REF_VALUE_1P2 (0x7UL << AON_SNSADC_CFG_REF_VALUE_Pos) /**< Reference = 1.28 V */ +#define LL_ADC_REF_VALUE_1P6 (0xAUL << AON_SNSADC_CFG_REF_VALUE_Pos) /**< Reference = 1.60 V */ +//#define LL_ADC_REF_VALUE_2P0 (0xFUL << AON_SNSADC_CFG_REF_VALUE_Pos) /**< Reference = 2.00 V */ +/** @} */ + +/** @defgroup LL_ADC_EC_INPUT_MODE ADC Input Mode + * @{ + */ +#define LL_ADC_INPUT_SINGLE (1UL << AON_SNSADC_CFG_SINGLE_EN_Pos) /**< Single ended mode */ +#define LL_ADC_INPUT_DIFFERENTIAL (0x00000000UL) /**< Differential mode */ +/** @} */ + +/** @defgroup LL_ADC_EC_INPUT_SRC ADC Input Source + * @{ + */ +#define LL_ADC_INPUT_SRC_IO0 (0UL) /**< Select MSIO0 as input */ +#define LL_ADC_INPUT_SRC_IO1 (1UL) /**< Select MSIO1 as input */ +#define LL_ADC_INPUT_SRC_IO2 (2UL) /**< Select MSIO2 as input */ +#define LL_ADC_INPUT_SRC_IO3 (3UL) /**< Select MSIO3 as input */ +#define LL_ADC_INPUT_SRC_IO4 (4UL) /**< Select MSIO4 as input */ +#define LL_ADC_INPUT_SRC_TMP (5UL) /**< Select temperature as input */ +#define LL_ADC_INPUT_SRC_BAT (6UL) /**< Select Vbattery as input */ +#define LL_ADC_INPUT_SRC_REF (7UL) /**< Select reference as input */ + +/** @} */ + +/** @defgroup LL_ADC_EC_REFERENCE_SRC ADC Reference Source + * @{ + */ +#define LL_ADC_REF_SRC_BUF_INT (0x00000000UL) /**< Select buffered internal reference as reference */ +#define LL_ADC_REF_SRC_IO0 (3UL << AON_SNSADC_CFG_REF_SEL_Pos) /**< Select MSIO0 as reference */ +#define LL_ADC_REF_SRC_IO1 (4UL << AON_SNSADC_CFG_REF_SEL_Pos) /**< Select MSIO1 as reference */ +#define LL_ADC_REF_SRC_IO2 (5UL << AON_SNSADC_CFG_REF_SEL_Pos) /**< Select MSIO2 as reference */ +#define LL_ADC_REF_SRC_IO3 (6UL << AON_SNSADC_CFG_REF_SEL_Pos) /**< Select MSIO3 as reference */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup LL_ADC_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @defgroup LL_ADC_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ADC register + * @param __instance__ ADC instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_ADC_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG((__instance__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ADC register + * @param __instance__ ADC instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ADC_ReadReg(__instance__, __REG__) READ_REG((__instance__)->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup LL_ADC_Private_Macros ADC Private Macros + * @{ + */ + +/** @defgroup LL_ADC_EC_DEFAULT_CONFIG InitStruct default configuartion + * @{ + */ + +/** + * @brief LL ADC InitStrcut default configuartion + */ +#define LL_ADC_DEFAULT_CONFIG \ +{ \ + .channel_p = LL_ADC_INPUT_SRC_IO0, \ + .channel_n = LL_ADC_INPUT_SRC_IO1, \ + .input_mode = LL_ADC_INPUT_DIFFERENTIAL, \ + .ref_source = LL_ADC_REF_SRC_BUF_INT, \ + .ref_value = LL_ADC_REF_VALUE_1P5, \ + .clock = LL_ADC_CLK_16 \ +} +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup LL_ADC_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup LL_ADC_EF_Configuration Basic Configuration + * @{ + */ + +/** + * @brief Enable ADC module. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable(void) +{ + SET_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_EN_Msk); +} + +/** + * @brief Disable ADC module. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable(void) +{ + CLEAR_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_EN_Msk); +} + +/** + * @brief Check if ADC module is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled(void) +{ + return (READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_EN_Msk) == (AON_SNSADC_CFG_EN_Msk)); +} + +/** + * @brief Enable ADC clock. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | MSIO_PAD_CFG_1 | ADC_CLK_EN | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable_clock(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_MSIO_PAD_CFG_1_ADC_CLK_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable ADC clock. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | MSIO_PAD_CFG_1 | ADC_CLK_EN | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable_clock(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, AON_MSIO_PAD_CFG_1_ADC_CLK_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if ADC clock is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | MSIO_PAD_CFG_1 | ADC_CLK_EN | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled_clock(void) +{ + return (READ_BITS(AON->MSIO_PAD_CFG_1, AON_MSIO_PAD_CFG_1_ADC_CLK_EN) == (AON_MSIO_PAD_CFG_1_ADC_CLK_EN)); +} + +/** + * @brief Set ADC clock source. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | MSIO_PAD_CFG_1 | ADC_CLK_SEL | + * +----------------------+-----------------------------+ + * \endrst + * + * @param clk This parameter can be one of the following values: + * @arg @ref LL_ADC_CLK_16 + * @arg @ref LL_ADC_CLK_8 + * @arg @ref LL_ADC_CLK_4 + * @arg @ref LL_ADC_CLK_2 + * @arg @ref LL_ADC_CLK_1P6 + * @arg @ref LL_ADC_CLK_1 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_clock(uint32_t clk) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->MSIO_PAD_CFG_1, AON_MSIO_PAD_CFG_1_ADC_CLK_SEL, clk); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return source for ADC clock. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | MSIO_PAD_CFG_1 | ADC_CLK_SEL | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CLK_16 + * @arg @ref LL_ADC_CLK_8 + * @arg @ref LL_ADC_CLK_4 + * @arg @ref LL_ADC_CLK_2 + * @arg @ref LL_ADC_CLK_1P6 + * @arg @ref LL_ADC_CLK_1 + */ +__STATIC_INLINE uint32_t ll_adc_get_clock(void) +{ + return (uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_MSIO_PAD_CFG_1_ADC_CLK_SEL) >> AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos); +} + +/** + * @brief Set ADC bias reference. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG1 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param value This parameter can be one of the following values: + * @arg @ref LL_ADC_REF_VALUE_0P8 + * @arg @ref LL_ADC_REF_VALUE_1P2 + * @arg @ref LL_ADC_REF_VALUE_1P6 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_ref_value(uint32_t value) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_VALUE_Msk, value); +} + +/** + * @brief Return ADC bias reference. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG1 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REF_VALUE_0P8 + * @arg @ref LL_ADC_REF_VALUE_1P2 + * @arg @ref LL_ADC_REF_VALUE_1P6 + */ +__STATIC_INLINE uint32_t ll_adc_get_ref_value(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_VALUE_Msk) >> AON_SNSADC_CFG_REF_VALUE_Pos); +} + +/** + * @brief Enable temperature sensor. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable_temp(void) +{ + SET_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_TEMP_EN_Msk); +} + +/** + * @brief Disable temperature sensor. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable_temp(void) +{ + CLEAR_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_TEMP_EN_Msk); +} + +/** + * @brief Check if temperature sensor is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled_temp(void) +{ + return (READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_TEMP_EN_Msk) == (AON_SNSADC_CFG_TEMP_EN_Msk)); +} + +/** + * @brief Enable Vbattery sensor. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable_vbat(void) +{ + SET_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_VBAT_EN_Msk); +} + +/** + * @brief Disable Vbattery sensor. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable_vbat(void) +{ + CLEAR_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_VBAT_EN_Msk); +} + +/** + * @brief Check if Vbattery sensor is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled_vbat(void) +{ + return (READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_VBAT_EN_Msk) == (AON_SNSADC_CFG_VBAT_EN_Msk)); +} + +/** + * @brief Set ADC input mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param mode This parameter can be one of the following values: + * @arg @ref LL_ADC_INPUT_SINGLE + * @arg @ref LL_ADC_INPUT_DIFFERENTIAL + * @retval None + */ +__STATIC_INLINE void ll_adc_set_input_mode(uint32_t mode) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_SINGLE_EN_Msk, mode); +} + +/** + * @brief Return ADC input mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INPUT_SINGLE + * @arg @ref LL_ADC_INPUT_DIFFERENTIAL + */ +__STATIC_INLINE uint32_t ll_adc_get_input_mode(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_SINGLE_EN_Msk) >> AON_SNSADC_CFG_SINGLE_EN_Pos); +} + +/** + * @brief Enable offset calibration. + * @note Enable offset calibration, used to swap inputs of comparator for offset + * calibration. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable_ofs_cal(void) +{ + SET_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_OFS_CAL_EN_Msk); +} + +/** + * @brief Disable offset calibration. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable_ofs_cal(void) +{ + CLEAR_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_OFS_CAL_EN_Msk); +} + +/** + * @brief Check if offset calibration is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled_ofs_cal(void) +{ + return (READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_OFS_CAL_EN_Msk) == (AON_SNSADC_CFG_OFS_CAL_EN_Msk)); +} + +/** + * @brief Set dynamic rang of ADC. + * @note When higher input signal frequencies close to Nyquist rate, you should set 1. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param rang This parameter can be a value between: 1 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_dynamic_rang(uint32_t rang) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_DYMAMIC_Msk, (rang & 0x7) << AON_SNSADC_CFG_DYMAMIC_Pos); +} + +/** + * @brief Return ADC dynamic rang. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG2 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be a value between: 1 ~ 7 + */ +__STATIC_INLINE uint32_t ll_adc_get_dynamic_rang(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_DYMAMIC_Msk) >> AON_SNSADC_CFG_DYMAMIC_Pos); +} + +/** + * @brief Set source of ADC input channelP. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG3 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param source This parameter can be one of the following values: + * @arg @ref LL_ADC_INPUT_SRC_IO0 + * @arg @ref LL_ADC_INPUT_SRC_IO1 + * @arg @ref LL_ADC_INPUT_SRC_IO2 + * @arg @ref LL_ADC_INPUT_SRC_IO3 + * @arg @ref LL_ADC_INPUT_SRC_IO4 + * @arg @ref LL_ADC_INPUT_SRC_TMP + * @arg @ref LL_ADC_INPUT_SRC_BAT + * @retval None + */ +__STATIC_INLINE void ll_adc_set_channelp(uint32_t source) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_CHN_P_Msk, source << AON_SNSADC_CFG_CHN_P_Pos); +} + +/** + * @brief Return source of ADC input channelP. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG3 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INPUT_SRC_IO0 + * @arg @ref LL_ADC_INPUT_SRC_IO1 + * @arg @ref LL_ADC_INPUT_SRC_IO2 + * @arg @ref LL_ADC_INPUT_SRC_IO3 + * @arg @ref LL_ADC_INPUT_SRC_IO4 + * @arg @ref LL_ADC_INPUT_SRC_TMP + * @arg @ref LL_ADC_INPUT_SRC_BAT + */ +__STATIC_INLINE uint32_t ll_adc_get_channelp(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_CHN_P_Msk) >> AON_SNSADC_CFG_CHN_P_Pos); +} + +/** + * @brief Set source of ADC input channelN. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG3 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param source This parameter can be one of the following values: + * @arg @ref LL_ADC_INPUT_SRC_IO0 + * @arg @ref LL_ADC_INPUT_SRC_IO1 + * @arg @ref LL_ADC_INPUT_SRC_IO2 + * @arg @ref LL_ADC_INPUT_SRC_IO3 + * @arg @ref LL_ADC_INPUT_SRC_IO4 + * @arg @ref LL_ADC_INPUT_SRC_TMP + * @arg @ref LL_ADC_INPUT_SRC_BAT + * @retval None + */ +__STATIC_INLINE void ll_adc_set_channeln(uint32_t source) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_CHN_N_Msk, source << AON_SNSADC_CFG_CHN_N_Pos); +} + +/** + * @brief Return source of ADC input channelN. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG3 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INPUT_SRC_IO0 + * @arg @ref LL_ADC_INPUT_SRC_IO1 + * @arg @ref LL_ADC_INPUT_SRC_IO2 + * @arg @ref LL_ADC_INPUT_SRC_IO3 + * @arg @ref LL_ADC_INPUT_SRC_IO4 + * @arg @ref LL_ADC_INPUT_SRC_TMP + * @arg @ref LL_ADC_INPUT_SRC_BAT + */ +__STATIC_INLINE uint32_t ll_adc_get_channeln(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_CHN_N_Msk) >> AON_SNSADC_CFG_CHN_N_Pos); +} + +/** + * @brief Enable ADC MAS_RST. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_enable_mas_rst(void) +{ + SET_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_MAS_RST_Msk); +} + +/** + * @brief Disable ADC MAS_RST. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_adc_disable_mas_rst(void) +{ + CLEAR_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_MAS_RST_Msk); +} + +/** + * @brief Check if ADC MAS_RST is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_enabled_mas_rst(void) +{ + return (READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_MAS_RST_Msk) == (AON_SNSADC_CFG_MAS_RST_Msk)); +} + +/** + * @brief Set source of ADC reference. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param source This parameter can be one of the following values: + * @arg @ref LL_ADC_REF_SRC_BUF_INT + * @arg @ref LL_ADC_REF_SRC_IO0 + * @arg @ref LL_ADC_REF_SRC_IO1 + * @arg @ref LL_ADC_REF_SRC_IO2 + * @arg @ref LL_ADC_REF_SRC_IO3 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_ref(uint32_t source) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_SEL_Msk, source); +} + +/** + * @brief Return source of ADC reference. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REF_SRC_BUF_INT + * @arg @ref LL_ADC_REF_SRC_IO0 + * @arg @ref LL_ADC_REF_SRC_IO1 + * @arg @ref LL_ADC_REF_SRC_IO2 + * @arg @ref LL_ADC_REF_SRC_IO3 + */ +__STATIC_INLINE uint32_t ll_adc_get_ref(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_SEL_Msk) >> AON_SNSADC_CFG_REF_SEL_Pos); +} + +/** + * @brief Set current of ADC reference circuit. + * @note When samples at 100kbps, you should set 0. + * When samples at 1mbps, you should set 7. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @param source This parameter can be a value between: 0 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_ref_current(uint32_t source) +{ + MODIFY_REG(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_HP_Msk, (source & 0x7) << AON_SNSADC_CFG_REF_HP_Pos); +} + +/** + * @brief Return current of ADC reference circuit. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SNSADC_CFG | REG4 | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be a value between: 0 ~ 7 + */ +__STATIC_INLINE uint32_t ll_adc_get_ref_current(void) +{ + return (uint32_t)(READ_BITS(AON->SNSADC_CFG, AON_SNSADC_CFG_REF_HP_Msk) >> AON_SNSADC_CFG_REF_HP_Pos); +} + +/** @} */ + +/** @defgroup LL_ADC_EF_FIFO_Access FIFO Access + * @{ + */ + +/** + * @brief Return samples value of ADC by reading FIFO. + * @note There are two value in the register, both of them is 16bits. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SENSE_ADC_FIFO | SENSE_ADC_FIFO | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Smaples value of input + */ +__STATIC_INLINE uint32_t ll_adc_read_fifo(void) +{ + return (uint32_t)(READ_REG(MCU_SUB->SENSE_ADC_FIFO)); +} + +/** + * @brief Set threshold of ADC FIFO. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SENSE_FF_THRESH | SENSE_FF_THRESH | + * +----------------------+-----------------------------+ + * \endrst + * + * @param thresh This parameter can be a value between: 0 ~ 64 + * @retval None + */ +__STATIC_INLINE void ll_adc_set_thresh(uint32_t thresh) +{ + MODIFY_REG(MCU_SUB->SENSE_FF_THRESH, MCU_SUB_SNSADC_FF_THRESH, (thresh & 0x3F) << MCU_SUB_SNSADC_FF_THRESH_Pos); +} + +/** + * @brief Return threshold of ADC FIFO. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SENSE_FF_THRESH | SENSE_FF_THRESH | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be a value between: 0 ~ 64 + */ +__STATIC_INLINE uint32_t ll_adc_get_thresh(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->SENSE_FF_THRESH, MCU_SUB_SNSADC_FF_THRESH) >> MCU_SUB_SNSADC_FF_THRESH_Pos); +} + +/** + * @brief Check if ADC FIFO is not empty. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SENSE_ADC_STAT | VAL | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_adc_is_fifo_notempty(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->SENSE_ADC_STAT, MCU_SUB_SNSADC_STAT_VAL) == MCU_SUB_SNSADC_STAT_VAL); +} + +/** + * @brief Return count of ADC FIFO. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SENSE_ADC_STAT | FF_COUNT | + * +----------------------+-----------------------------+ + * \endrst + * + * @retval Returned value can be a value between: 0 ~ 64 + */ +__STATIC_INLINE uint32_t ll_adc_get_fifo_count(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->SENSE_ADC_STAT, MCU_SUB_SNSADC_STAT_FF_COUNT) >> MCU_SUB_SNSADC_STAT_FF_COUNT_Pos); +} + +/** @} */ + +/** @defgroup LL_ADC_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize ADC registers (Registers restored to their default values). + * @retval An error_status_t enumeration value: + * - SUCCESS: ADC registers are de-initialized + * - ERROR: ADC registers are not de-initialized + */ +error_status_t ll_adc_deinit(void); + +/** + * @brief Initialize ADC registers according to the specified. + * parameters in p_adc_init. + * @param p_adc_init Pointer to a ll_adc_init_t structure that contains the configuration + * information for the specified ADC peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: ADC registers are initialized according to p_adc_init content + * - ERROR: Problem occurred during ADC Registers initialization + */ +error_status_t ll_adc_init(ll_adc_init_t *p_adc_init); + +/** + * @brief Set each field of a @ref ll_adc_init_t type structure to default value. + * @param p_adc_init Pointer to a @ref ll_adc_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_adc_struct_init(ll_adc_init_t *p_adc_init); + +/** @} */ + +/** @} */ + +#endif /* AON */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_ADC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aes.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aes.h new file mode 100644 index 0000000..afde7df --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aes.h @@ -0,0 +1,1693 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_aes.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AES LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_AES AES + * @brief AES LL module driver. + * @{ + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_AES_H__ +#define __GR55XX_LL_AES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (AES) + +/** @defgroup AES_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup AES_LL_ES_INIT AES Exported Init structures + * @{ + */ + +/** + * @brief LL AES Init Structure definition + */ +typedef struct _ll_aes_init +{ + uint32_t key_size; /**< 128, 192 or 256-bit key length. + This parameter can be a value of @ref AES_LL_EC_KEY_SIZE */ + + uint32_t *p_key; /**< Encryption/Decryption Key */ + + uint32_t *p_init_vector; /**< Initialization Vector used for CBC modes */ + + uint32_t *p_seed; /**< Random seeds */ + +} ll_aes_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup AES_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup AES_LL_Exported_Constants AES Exported Constants + * @{ + */ + +/** @defgroup AES_LL_EC_GET_FLAG Get Flag Defines + * @brief Flag definitions which can be used with LL_AES_ReadReg function + * @{ + */ +#define LL_AES_FLAG_DATAREADY AES_STATUS_READY /**< AES result data out ready */ +#define LL_AES_FLAG_DMA_DONE AES_STATUS_TRANSDONE /**< AES dma transfer done */ +#define LL_AES_FLAG_DMA_ERR AES_STATUS_TRANSERR /**< AES dma transfer error */ +#define LL_AES_FLAG_KEY_VALID AES_STATUS_KEYVALID /**< AES has fetched key */ +/** @} */ + +/** @defgroup AES_LL_EC_KEY_SIZE Key Size + * @{ + */ +#define LL_AES_KEY_SIZE_128 0x00000000U /**< 128 bits */ +#define LL_AES_KEY_SIZE_192 (1UL << AES_CONFIG_KEYMODE_Pos) /**< 192 bits */ +#define LL_AES_KEY_SIZE_256 (2UL << AES_CONFIG_KEYMODE_Pos) /**< 256 bits */ +/** @} */ + +/** @defgroup AES_LL_EC_OPERATION_MODE Operation Mode + * @{ + */ +#define LL_AES_OPERATION_MODE_ECB 0x00000000U /**< Electronic codebook (ECB) mode */ +#define LL_AES_OPERATION_MODE_CBC (1UL << AES_CONFIG_OPMODE_Pos) /**< Cipher block chaining (CBC) mode */ +/** @} */ + +/** @defgroup AES_LL_EC_KEY_TYPE Key Type + * @{ + */ +#define LL_AES_KEYTYPE_MCU 0x00000000U /**< MCU */ +#define LL_AES_KEYTYPE_AHB (1UL << AES_CONFIG_KEYTYPE_Pos) /**< AHB master */ +#define LL_AES_KEYTYPE_KRAM (2UL << AES_CONFIG_KEYTYPE_Pos) /**< Key Port */ +/** @} */ + +/** @defgroup AES_LL_EC_TRANSFER_SIZE Transfer Size + * @{ + */ +#define LL_AES_DMA_TRANSIZE_MIN (1) /**< Min size = 1 block */ +#define LL_AES_DMA_TRANSIZE_MAX (2048) /**< Max size = 2048 blocks */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup AES_LL_Exported_Macros AES Exported Macros + * @{ + */ + +/** @defgroup AES_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in AES register + * @param __INSTANCE__ AES Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_AES_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in AES register + * @param __INSTANCE__ AES Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_AES_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup AES_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup AES_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable AES. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable(aes_regs_t *AESx) +{ + SET_BITS(AESx->CTRL, AES_CTRL_ENABLE); +} + +/** + * @brief Disable AES. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CTRL, AES_CTRL_ENABLE); +} + +/** + * @brief Indicate whether the AES is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CTRL, AES_CTRL_ENABLE) == (AES_CTRL_ENABLE)); +} + +/** + * @brief Enable AES start in MCU mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_NORMAL | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_start(aes_regs_t *AESx) +{ + SET_BITS(AESx->CTRL, AES_CTRL_START_NORMAL); +} + +/** + * @brief Disable AES start in MCU mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_NORMAL | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_start(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CTRL, AES_CTRL_START_NORMAL); +} + +/** + * @brief Indicate whether the AES start in MCU mode is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_NORMAL | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_start(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CTRL, AES_CTRL_START_NORMAL) == (AES_CTRL_START_NORMAL)); +} + +/** + * @brief Enable AES DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_dma_start(aes_regs_t *AESx) +{ + SET_BITS(AESx->CTRL, AES_CTRL_START_DMA); +} + +/** + * @brief Disable AES DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_dma_start(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CTRL, AES_CTRL_START_DMA); +} + +/** + * @brief Indicate whether the AES DMA mode is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_dma_start(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CTRL, AES_CTRL_START_DMA) == (AES_CTRL_START_DMA)); +} + +/** + * @brief Enable fetch key through AHB/key port. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CTRL | ENABLE_RKEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_read_key(aes_regs_t *AESx) +{ + SET_BITS(AESx->CTRL, AES_CTRL_ENABLE_RKEY); +} + +/** + * @brief Set AES key size. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | KEYMODE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param size This parameter can be one of the following values: + * @arg @ref LL_AES_KEY_SIZE_128 + * @arg @ref LL_AES_KEY_SIZE_192 + * @arg @ref LL_AES_KEY_SIZE_256 + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_size(aes_regs_t *AESx, uint32_t size) +{ + MODIFY_REG(AESx->CONFIG, AES_CONFIG_KEYMODE, size); +} + +/** + * @brief Get AES key size. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | KEYMODE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_AES_KEY_SIZE_128 + * @arg @ref LL_AES_KEY_SIZE_192 + * @arg @ref LL_AES_KEY_SIZE_256 + */ +__STATIC_INLINE uint32_t ll_aes_get_key_size(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_KEYMODE)); +} + +/** + * @brief Enable AES full mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_FULLMASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_full_mask(aes_regs_t *AESx) +{ + SET_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_FULLMASK); +} + +/** + * @brief Disable AES full mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_FULLMASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_full_mask(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_FULLMASK); +} + +/** + * @brief Indicate whether the AES full mask is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_FULLMASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_full_mask(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_FULLMASK) == (AES_CONFIG_ENABLE_FULLMASK)); +} + +/** + * @brief Enable AES encryption mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_ENCRYPTION | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_encryption(aes_regs_t *AESx) +{ + SET_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_ENCRYPTION); +} + +/** + * @brief Disable AES encryption mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_ENCRYPTION | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_encryption(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_ENCRYPTION); +} + +/** + * @brief Indicate whether the AES encryption mode is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENABLE_ENCRYPTION | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_encryption(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_ENABLE_ENCRYPTION) == (AES_CONFIG_ENABLE_ENCRYPTION)); +} + +/** + * @brief Set AES to load seed for LFSR. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | LOADSEED | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_set_load_seed(aes_regs_t *AESx) +{ + SET_BITS(AESx->CONFIG, AES_CONFIG_LOADSEED); +} + +/** + * @brief Set AES in first block before starting the first block in normal CBC and DMA CBC mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | FIRSTBLOCK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_set_first_block(aes_regs_t *AESx) +{ + SET_BITS(AESx->CONFIG, AES_CONFIG_FIRSTBLOCK); +} + +/** + * @brief Enable AES in little endian. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_little_endian(aes_regs_t *AESx) +{ + SET_BITS(AESx->CONFIG, AES_CONFIG_ENDIAN); +} + +/** + * @brief Disable AES in little endian. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_little_endian(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->CONFIG, AES_CONFIG_ENDIAN); +} + +/** + * @brief Indicate whether the AES is in little endian. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_little_endian(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_ENDIAN) == (AES_CONFIG_ENDIAN)); +} + +/** + * @brief Set AES operation mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | OPMODE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param mode This parameter can be one of the following values: + * @arg @ref LL_AES_OPERATION_MODE_ECB + * @arg @ref LL_AES_OPERATION_MODE_CBC + * @retval None + */ +__STATIC_INLINE void ll_aes_set_operation_mode(aes_regs_t *AESx, uint32_t mode) +{ + MODIFY_REG(AESx->CONFIG, AES_CONFIG_OPMODE, mode); +} + +/** + * @brief Get AES operation mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | OPMODE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_AES_OPERATION_MODE_ECB + * @arg @ref LL_AES_OPERATION_MODE_CBC + */ +__STATIC_INLINE uint32_t ll_aes_get_operation_mode(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_OPMODE)); +} + +/** + * @brief Set ways to obtain AES key. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | KEYTYPE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param Type This parameter can be one of the following values: + * @arg @ref LL_AES_KEYTYPE_MCU + * @arg @ref LL_AES_KEYTYPE_AHB + * @arg @ref LL_AES_KEYTYPE_KRAM + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_type(aes_regs_t *AESx, uint32_t Type) +{ + MODIFY_REG(AESx->CONFIG, AES_CONFIG_KEYTYPE, Type); +} + +/** + * @brief Get ways to obtain AES key. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | CONFIG | KEYTYPE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_AES_KEYTYPE_MCU + * @arg @ref LL_AES_KEYTYPE_AHB + * @arg @ref LL_AES_KEYTYPE_KRAM + */ +__STATIC_INLINE uint32_t ll_aes_get_key_type(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->CONFIG, AES_CONFIG_KEYTYPE)); +} + +/** @} */ + +/** @defgroup AES_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable AES the done interrupt. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_enable_it_done(aes_regs_t *AESx) +{ + SET_BITS(AESx->INTERRUPT, AES_INTERRUPT_ENABLE); +} + +/** + * @brief Disable AES the done interrupt. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_disable_it_done(aes_regs_t *AESx) +{ + CLEAR_BITS(AESx->INTERRUPT, AES_INTERRUPT_ENABLE); +} + +/** + * @brief Indicate whether the done interrupt is enabled. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_enabled_it_done(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->INTERRUPT, AES_INTERRUPT_ENABLE) == (AES_INTERRUPT_ENABLE)); +} + +/** @} */ + +/** @defgroup AES_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate whether the ready flag is set. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | STATUS | READY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_action_flag_ready(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->STATUS, AES_STATUS_READY) == AES_STATUS_READY); +} + +/** + * @brief Indicate whether the DMA transfer done flag is set. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | STATUS | TRANSDONE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_action_flag_dma_done(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->STATUS, AES_STATUS_TRANSDONE) == AES_STATUS_TRANSDONE); +} + +/** + * @brief Indicate whether the DMA transfer error flag is set. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | STATUS | TRANSERR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_action_flag_dma_error(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->STATUS, AES_STATUS_TRANSERR) == AES_STATUS_TRANSERR); +} + +/** + * @brief Indicate whether the key valid flag is set. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | STATUS | KEYVALID | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_action_flag_key_valid(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->STATUS, AES_STATUS_KEYVALID) == AES_STATUS_KEYVALID); +} + +/** + * @brief Indicate whether the done interrupt flag is set. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | INTERRUPT | DONE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aes_is_action_flag_it_done(aes_regs_t *AESx) +{ + return (READ_BITS(AESx->INTERRUPT, AES_INTERRUPT_DONE) == AES_INTERRUPT_DONE); +} + +/** + * @brief Clear the done interrupt flag. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | INTERRUPT | DONE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval None + */ +__STATIC_INLINE void ll_aes_clear_flag_it_done(aes_regs_t *AESx) +{ + SET_BITS(AESx->INTERRUPT, AES_INTERRUPT_DONE); +} + +/** @} */ + +/** @defgroup AES_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Set AES transfer blocks in DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | TRAN_SIZE | TRAN_SIZE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param block This parameter can be one of the following values: 1 ~ 2048. + * @retval None + */ +__STATIC_INLINE void ll_aes_set_dma_transfer_block(aes_regs_t *AESx, uint32_t block) +{ + MODIFY_REG(AESx->TRAN_SIZE, AES_TRAN_SIZE, (block << 4) - 1); +} + +/** + * @brief Get AES transfer blocks in DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | TRAN_SIZE | TRAN_SIZE | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Return value between 1 and 2048. + */ +__STATIC_INLINE uint32_t ll_aes_get_dma_transfer_block(aes_regs_t *AESx) +{ + return ((READ_BITS(AESx->TRAN_SIZE, AES_TRAN_SIZE) + 1) >> 4); +} + +/** + * @brief Set AES read address of RAM in DMA mode. + * @note This read address of RAM requires 4 byte alignment. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | RSTART_ADDR | RSTART_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param address This parameter can be a address in RAM area (0x30000000 ~ 0x3003FFFF). + * @retval None + */ +__STATIC_INLINE void ll_aes_set_dma_read_address(aes_regs_t *AESx, uint32_t address) +{ + WRITE_REG(AESx->RSTART_ADDR, address); +} + +/** + * @brief Get AES read address of RAM in DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | RSTART_ADDR | RSTART_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the read address in RAM. + */ +__STATIC_INLINE uint32_t ll_aes_get_dma_read_address(aes_regs_t *AESx) +{ + return (READ_REG(AESx->RSTART_ADDR)); +} + +/** + * @brief Set AES write address of RAM in DMA mode. + * @note This write address of RAM requires 4 byte alignment. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | WSTART_ADDR | WSTART_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param address This parameter can be a address in RAM area (0x30000000 ~ 0x3003FFFF). + * @retval None + */ +__STATIC_INLINE void ll_aes_set_dma_write_address(aes_regs_t *AESx, uint32_t address) +{ + WRITE_REG(AESx->WSTART_ADDR, address); +} + +/** + * @brief Get AES write address of RAM in DMA mode. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | WSTART_ADDR | WSTART_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the wrute address in RAM + */ +__STATIC_INLINE uint32_t ll_aes_get_dma_write_address(aes_regs_t *AESx) +{ + return (READ_REG(AESx->WSTART_ADDR)); +} + +/** @} */ + +/** @defgroup AES_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Set AES key address in memory. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY_ADDR | KEY_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param address This parameter can be one of the address in RAM + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_address(aes_regs_t *AESx, uint32_t address) +{ + WRITE_REG(AESx->KEY_ADDR, address); +} + +/** + * @brief Get AES key address in memory. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY_ADDR | KEY_ADDR | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the key address in RAM. + */ +__STATIC_INLINE uint32_t ll_aes_get_key_address(aes_regs_t *AESx) +{ + return (READ_REG(AESx->KEY_ADDR)); +} + +/** + * @brief Get AES output data[127:96]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_OUT[0] | DATA_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Output Data[127:96] + */ +__STATIC_INLINE uint32_t ll_aes_get_data_127_96(aes_regs_t *AESx) +{ + return (READ_REG(AESx->DATA_OUT[0])); +} + +/** + * @brief Get AES output data[95:64]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_OUT[1] | DATA_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Output Data[95:64] + */ +__STATIC_INLINE uint32_t ll_aes_get_data_95_64(aes_regs_t *AESx) +{ + return (READ_REG(AESx->DATA_OUT[1])); +} + +/** + * @brief Get AES output data[63:32]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_OUT[2] | DATA_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Output Data[63:32] + */ +__STATIC_INLINE uint32_t ll_aes_get_data_63_32(aes_regs_t *AESx) +{ + return (READ_REG(AESx->DATA_OUT[2])); +} + +/** + * @brief Get AES output data[31:0]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_OUT[3] | DATA_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Output Data[31:0] + */ +__STATIC_INLINE uint32_t ll_aes_get_data_31_0(aes_regs_t *AESx) +{ + return (READ_REG(AESx->DATA_OUT[3])); +} + +/** + * @brief Set AES key[255:224]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[0] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_255_224(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[0], key); +} + +/** + * @brief Set AES key[223:192]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[1] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_223_192(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[1], key); +} + +/** + * @brief Set AES key[191:160]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[2] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_191_160(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[2], key); +} + +/** + * @brief Set AES key[159:128]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[3] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_159_128(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[3], key); +} + +/** + * @brief Set AES key[127:96]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[4] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_127_96(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[4], key); +} + +/** + * @brief Set AES key[95:64]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[5] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_95_64(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[5], key); +} + +/** + * @brief Set AES key[63:32]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[6] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_63_32(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[6], key); +} + +/** + * @brief Set AES key[31:0]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KEY[7] | KEY | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_31_0(aes_regs_t *AESx, uint32_t key) +{ + WRITE_REG(AESx->KEY[7], key); +} + +/** + * @brief Set AES input seed. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_IN | SEED_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param seed This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_seed_in(aes_regs_t *AESx, uint32_t seed) +{ + WRITE_REG(AESx->SEED_IN, seed); +} + +/** + * @brief Get AES input seed. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_IN | SEED_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the input seed. + */ +__STATIC_INLINE uint32_t ll_aes_get_seed_in(aes_regs_t *AESx) +{ + return (READ_REG(AESx->SEED_IN)); +} + +/** + * @brief Set AES output seed. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_OUT | SEED_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param seed This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_seed_out(aes_regs_t *AESx, uint32_t seed) +{ + WRITE_REG(AESx->SEED_OUT, seed); +} + +/** + * @brief Get AES output seed. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_OUT | SEED_OUT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the output seed. + */ +__STATIC_INLINE uint32_t ll_aes_get_seed_out(aes_regs_t *AESx) +{ + return (READ_REG(AESx->SEED_OUT)); +} + +/** + * @brief Set sbox input data's mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_IMASK | SEED_IMASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param mask This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_seed_Imask(aes_regs_t *AESx, uint32_t mask) +{ + WRITE_REG(AESx->SEED_IMASK, mask); +} + +/** + * @brief Get sbox input data's mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_IMASK | SEED_IMASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the input data's mask. + */ +__STATIC_INLINE uint32_t ll_aes_get_seed_Imask(aes_regs_t *AESx) +{ + return (READ_REG(AESx->SEED_IMASK)); +} + +/** + * @brief Set sbox output data's mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_OSBOX | SEED_OSBOX | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param mask This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_seed_Osbox(aes_regs_t *AESx, uint32_t mask) +{ + WRITE_REG(AESx->SEED_OSBOX, mask); +} + +/** + * @brief Get sbox output data's mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | SEED_OSBOX | SEED_OSBOX | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @retval Returned value is the output data's mask. + */ +__STATIC_INLINE uint32_t ll_aes_get_seed_Osbox(aes_regs_t *AESx) +{ + return (READ_REG(AESx->SEED_OSBOX)); +} + +/** + * @brief Set AES initialization vector[127:96]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | VECTOR_INIT[0] | VECTOR_INIT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param vector This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_vector_127_96(aes_regs_t *AESx, uint32_t vector) +{ + WRITE_REG(AESx->VECTOR_INIT[0], vector); +} + +/** + * @brief Set AES initialization vector[95:64]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | VECTOR_INIT[1] | VECTOR_INIT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param vector This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_vector_95_64(aes_regs_t *AESx, uint32_t vector) +{ + WRITE_REG(AESx->VECTOR_INIT[1], vector); +} + +/** + * @brief Set AES initialization vector[63:32]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | VECTOR_INIT[2] | VECTOR_INIT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param vector This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_vector_63_32(aes_regs_t *AESx, uint32_t vector) +{ + WRITE_REG(AESx->VECTOR_INIT[2], vector); +} + +/** + * @brief Set AES initialization vector[31:0]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | VECTOR_INIT[3] | VECTOR_INIT | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param vector This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_vector_31_0(aes_regs_t *AESx, uint32_t vector) +{ + WRITE_REG(AESx->VECTOR_INIT[3], vector); +} + +/** + * @brief Set AES input data[127:96]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_IN[0] | DATA_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param data This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_data_127_96(aes_regs_t *AESx, uint32_t data) +{ + WRITE_REG(AESx->DATA_IN[0], data); +} + +/** + * @brief Set AES input data[95:64]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_IN[1] | DATA_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param data This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_data_95_64(aes_regs_t *AESx, uint32_t data) +{ + WRITE_REG(AESx->DATA_IN[1], data); +} + +/** + * @brief Set AES input data[63:32]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_IN[2] | DATA_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param data This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_data_63_32(aes_regs_t *AESx, uint32_t data) +{ + WRITE_REG(AESx->DATA_IN[2], data); +} + +/** + * @brief Set AES input data[31:0]. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | DATA_IN[3] | DATA_IN | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param data This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_data_31_0(aes_regs_t *AESx, uint32_t data) +{ + WRITE_REG(AESx->DATA_IN[3], data); +} + +/** + * @brief Set AES fetch key port mask. + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | KPORT_MASK | KPORT_MASK | + * +----------------------+-----------------------------+ + * \endrst + * + * @param AESx AES instance + * @param mask This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_aes_set_key_port_mask(aes_regs_t *AESx, uint32_t mask) +{ + WRITE_REG(AESx->KPORT_MASK, mask); +} + +/** @} */ + +/** @defgroup AES_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize AES registers (Registers restored to their default values). + * @param AESx AES Instance + * @retval An error_status_t enumeration value: + * - SUCCESS: AES registers are de-initialized + * - ERROR: AES registers are not de-initialized + */ +error_status_t ll_aes_deinit(aes_regs_t *AESx); + +/** + * @brief Initialize AES registers according to the specified + * parameters in p_aes_init. + * @param AESx AES Instance + * @param p_aes_init Pointer to a ll_aes_init_t structure that contains the configuration + * information for the specified AES peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: AES registers are initialized according to p_aes_init content + * - ERROR: Problem occurred during AES Registers initialization + */ +error_status_t ll_aes_init(aes_regs_t *AESx, ll_aes_init_t *p_aes_init); + +/** + * @brief Set each field of a @ref ll_aes_init_t type structure to default value. + * @param p_aes_init Pointer to a @ref ll_aes_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_aes_struct_init(ll_aes_init_t *p_aes_init); + +/** @} */ + +/** @} */ + +#endif /* AES */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_AES_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_gpio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_gpio.h new file mode 100644 index 0000000..fd632a1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_gpio.h @@ -0,0 +1,1236 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_aon_gpio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AON GPIO LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_AON_GPIO AON_GPIO + * @brief AON_GPIO LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_AON_GPIO_H__ +#define __GR55XX_LL_AON_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** @defgroup AON_GPIO_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup AON_GPIO_LL_ES_INIT AON_GPIO Exported init structures + * @{ + */ + +/** + * @brief LL AON_GPIO init Structure definition + */ +typedef struct _ll_aon_gpio_init +{ + uint32_t pin; /**< Specifies the AON_GPIO pins to be AON_GPIO_InitStructured. + This parameter can be any value of @ref AON_GPIO_LL_EC_PIN */ + + uint32_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref AON_GPIO_LL_EC_MODE. + + AON_GPIO HW AON_GPIO_InitStructuration can be modified afterwards using unitary function @ref ll_aon_gpio_set_pin_mode(). */ + + uint32_t pull; /**< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref AON_GPIO_LL_EC_PULL. + + AON_GPIO HW configuration can be modified afterwards using unitary function @ref ll_aon_gpio_set_pin_pull().*/ + + uint32_t mux; /*!< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref AON_GPIO_LL_EC_MUX. + + GPIO HW AON_GPIO_InitStructuration can be modified afterwards using unitary function + @ref ll_aon_gpio_set_mux_pin_0_7(). */ + + uint32_t trigger; /**< Specifies the trigger signal active edge. + This parameter can be a value of @ref AON_GPIO_LL_EC_TRIGGER. */ +} ll_aon_gpio_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup AON_GPIO_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup AON_GPIO_LL_Exported_Constants AON_GPIO Exported Constants + * @{ + */ + +/** @defgroup AON_GPIO_LL_EC_PIN PIN + * @{ + */ +#define LL_AON_GPIO_PIN_0 ((uint32_t)0x01U) /**< Select pin 0 */ +#define LL_AON_GPIO_PIN_1 ((uint32_t)0x02U) /**< Select pin 1 */ +#define LL_AON_GPIO_PIN_2 ((uint32_t)0x04U) /**< Select pin 2 */ +#define LL_AON_GPIO_PIN_3 ((uint32_t)0x08U) /**< Select pin 3 */ +#define LL_AON_GPIO_PIN_4 ((uint32_t)0x10U) /**< Select pin 4 */ +#define LL_AON_GPIO_PIN_5 ((uint32_t)0x20U) /**< Select pin 5 */ +#define LL_AON_GPIO_PIN_6 ((uint32_t)0x40U) /**< Select pin 6 */ +#define LL_AON_GPIO_PIN_7 ((uint32_t)0x80U) /**< Select pin 7 */ +#define LL_AON_GPIO_PIN_ALL ((uint32_t)0xFFU) /**< Select all pins */ +/** @} */ + +/** @defgroup AON_GPIO_LL_EC_MODE Mode + * @{ + */ +#define LL_AON_GPIO_MODE_INPUT ((uint32_t)0x0U) /**< Select input mode */ +#define LL_AON_GPIO_MODE_OUTPUT ((uint32_t)0x1U) /**< Select output mode */ +#define LL_AON_GPIO_MODE_MUX ((uint32_t)0x2U) /**< Select mux peripheral mode */ +/** @} */ + +/** @defgroup AON_GPIO_LL_EC_PULL Pull Up Pull Down + * @{ + */ +#define LL_AON_GPIO_PULL_NO LL_AON_GPIO_RE_N /**< Select I/O no pull */ +#define LL_AON_GPIO_PULL_UP LL_AON_GPIO_RTYP /**< Select I/O pull up */ +#define LL_AON_GPIO_PULL_DOWN ((uint32_t)0x0U) /**< Select I/O pull down */ +/** @} */ + +/** @defgroup AON_GPIO_LL_EC_MUX Alternate Function + * @{ + */ +#define LL_AON_GPIO_MUX_0 ((uint32_t)0x0U) /*!< Select alternate function 0 */ +#define LL_AON_GPIO_MUX_1 ((uint32_t)0x1U) /*!< Select alternate function 1 */ +#define LL_AON_GPIO_MUX_2 ((uint32_t)0x2U) /*!< Select alternate function 2 */ +#define LL_AON_GPIO_MUX_3 ((uint32_t)0x3U) /*!< Select alternate function 3 */ +#define LL_AON_GPIO_MUX_4 ((uint32_t)0x4U) /*!< Select alternate function 4 */ +#define LL_AON_GPIO_MUX_5 ((uint32_t)0x5U) /*!< Select alternate function 5 */ +#define LL_AON_GPIO_MUX_6 ((uint32_t)0x6U) /*!< Select alternate function 6 */ +#define LL_AON_GPIO_MUX_7 ((uint32_t)0x7U) /*!< Select alternate function 7 */ +#define LL_AON_GPIO_MUX_8 ((uint32_t)0x8U) /*!< Select alternate function 8 */ +/** @} */ + + +/** @defgroup AON_GPIO_LL_EC_TRIGGER Interrupt Trigger + * @{ + */ +#define LL_AON_GPIO_TRIGGER_NONE ((uint32_t)0x00U) /**< No Trigger Mode */ +#define LL_AON_GPIO_TRIGGER_RISING ((uint32_t)0x01U) /**< Trigger Rising Mode */ +#define LL_AON_GPIO_TRIGGER_FALLING ((uint32_t)0x02U) /**< Trigger Falling Mode */ +#define LL_AON_GPIO_TRIGGER_HIGH ((uint32_t)0x03U) /**< Trigger High Mode */ +#define LL_AON_GPIO_TRIGGER_LOW ((uint32_t)0x04U) /**< Trigger Low Mode */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup AON_GPIO_LL_Exported_Macros AON_GPIO Exported Macros + * @{ + */ + +/** @defgroup AON_GPIO_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in AON_GPIO register + * @param __instance__ AON_GPIO instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_AON_GPIO_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in AON_GPIO register + * @param __instance__ AON_GPIO instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_AON_GPIO_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup AON_GPIO_LL_Private_Macros AON_GPIO Private Macros + * @{ + */ + +/** @defgroup AON_GPIO_LL_PM_RESISTOR Resistor Enable + * @{ + */ +#define LL_AON_GPIO_RE_N_Pos AON_PAD_CTL0_GPO_RE_N_Pos /**< Resistor Enable bits position */ +#define LL_AON_GPIO_RE_N_Msk (0x1U << LL_AON_GPIO_RE_N_Pos) /**< Resistor Enable bits mask */ +#define LL_AON_GPIO_RE_N LL_AON_GPIO_RE_N_Msk /**< Resistor Enable bits */ +/** @} */ + +/** @defgroup AON_GPIO_LL_PM_RESISTOR_TYPE Resistor Type + * @{ + */ +#define LL_AON_GPIO_RTYP_Pos AON_PAD_CTL0_GPO_RTYPE_Pos /**< Resistor Type bits position */ +#define LL_AON_GPIO_RTYP_Msk (0x1U << LL_AON_GPIO_RTYP_Pos) /**< Resistor Type bits mask */ +#define LL_AON_GPIO_RTYP LL_AON_GPIO_RTYP_Msk /**< Resistor Type bits */ +/** @} */ + +/** @defgroup AON_GPIO_LL_EC_DEFAULT_CONFIG InitStruct default configuartion + * @{ + */ + +/** + * @brief LL AON_GPIO InitStrcut default configuartion + */ +#define LL_AON_GPIO_DEFAULT_CONFIG \ +{ \ + .pin = LL_AON_GPIO_PIN_ALL, \ + .mode = LL_AON_GPIO_MODE_INPUT, \ + .pull = LL_AON_GPIO_PULL_DOWN, \ + .mux = LL_AON_GPIO_MUX_7, \ + .trigger = LL_AON_GPIO_TRIGGER_NONE, \ +} +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup AON_GPIO_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup AON_GPIO_LL_EF_Port_Configuration Port Configuration + * @{ + */ + +/** + * @brief Set several AON_GPIO pins to input/output mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO_OE_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @param mode This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_MODE_INPUT + * @arg @ref LL_AON_GPIO_MODE_OUTPUT + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_set_pin_mode(uint32_t pin_mask, uint32_t mode) +{ + pin_mask = (pin_mask << AON_PAD_CTL1_AON_GPO_OE_N_Pos) & AON_PAD_CTL1_AON_GPO_OE_N; + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->AON_PAD_CTL1, pin_mask, (mode == LL_AON_GPIO_MODE_INPUT) ? pin_mask : 0); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return gpio mode for a AON_GPIO pin. + * @note I/O mode can be Input mode. General purpose output. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO_OE_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_AON_GPIO_MODE_INPUT + * @arg @ref LL_AON_GPIO_MODE_OUTPUT + */ +__STATIC_INLINE uint32_t ll_aon_gpio_get_pin_mode(uint32_t pin) +{ + pin = (pin << AON_PAD_CTL1_AON_GPO_OE_N_Pos) & AON_PAD_CTL1_AON_GPO_OE_N; + return ((uint32_t)(READ_BITS(AON->AON_PAD_CTL1, pin) != LL_AON_GPIO_MODE_INPUT) ? + LL_AON_GPIO_MODE_OUTPUT : LL_AON_GPIO_MODE_INPUT); +} + +/** + * @brief Configure gpio pull-up or pull-down for a dedicated AON_GPIO pin. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL0 | GPO_RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * AON_PAD_CTL0 | GPO_RTYPE + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @param pull This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_PULL_NO + * @arg @ref LL_AON_GPIO_PULL_UP + * @arg @ref LL_AON_GPIO_PULL_DOWN + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_set_pin_pull(uint32_t pin_mask, uint32_t pull) +{ + uint32_t RTypeMask = (pin_mask << AON_PAD_CTL0_GPO_RTYPE_Pos) & AON_PAD_CTL0_GPO_RTYPE; + uint32_t REnMask = (pin_mask << AON_PAD_CTL0_GPO_RE_N_Pos) & AON_PAD_CTL0_GPO_RE_N; + uint32_t RType = (pull == LL_AON_GPIO_PULL_UP) ? RTypeMask : 0x0000U; + uint32_t REn = (pull == LL_AON_GPIO_PULL_NO) ? REnMask : 0x0000U; + MODIFY_REG(AON->AON_PAD_CTL0, REnMask | RTypeMask, REn | RType); +} + +/** + * @brief Return gpio pull-up or pull-down for a dedicated AON_GPIO pin. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL0 | GPO_RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * AON_PAD_CTL0 | GPO_RTYPE + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_AON_GPIO_PULL_NO + * @arg @ref LL_AON_GPIO_PULL_UP + * @arg @ref LL_AON_GPIO_PULL_DOWN + */ +__STATIC_INLINE uint32_t ll_aon_gpio_get_pin_pull(uint32_t pin) +{ + uint32_t RTypeMask = (pin << AON_PAD_CTL0_GPO_RTYPE_Pos) & AON_PAD_CTL0_GPO_RTYPE; + uint32_t REnMask = (pin << AON_PAD_CTL0_GPO_RE_N_Pos) & AON_PAD_CTL0_GPO_RE_N; + //return (READ_BITS(AON->AON_PAD_CTL0, REnMask | RTypeMask) >> POSITION_VAL(Pin)); + return ((READ_BITS(AON->AON_PAD_CTL0, REnMask) != RESET) ? LL_AON_GPIO_PULL_NO : + ((READ_BITS(AON->AON_PAD_CTL0, RTypeMask) != RESET) ? LL_AON_GPIO_PULL_UP : LL_AON_GPIO_PULL_DOWN)); +} + +/** + * @brief Configure gpio pinmux number of a dedicated pin from 0 to 7 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_MUX_CTRL | CTRL0_7 | + * +----------------------+-----------------------------------+ + * \endrst + * AON_PAD_CTL_0 | MCU_OVR + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @param mux This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_MUX_0 + * @arg @ref LL_AON_GPIO_MUX_1 + * @arg @ref LL_AON_GPIO_MUX_2 + * @arg @ref LL_AON_GPIO_MUX_3 + * @arg @ref LL_AON_GPIO_MUX_4 + * @arg @ref LL_AON_GPIO_MUX_5 + * @arg @ref LL_AON_GPIO_MUX_6 + * @arg @ref LL_AON_GPIO_MUX_7 + * @arg @ref LL_AON_GPIO_MUX_8 + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_set_mux_pin_0_7(uint32_t pin, uint32_t mux) +{ + uint32_t pos = POSITION_VAL(pin) << 2; + MODIFY_REG(MCU_SUB->AON_PAD_MUX_CTL, 0xF << pos, mux << pos); + if(LL_AON_GPIO_MUX_7 == mux) + { + CLEAR_BITS(AON->AON_PAD_CTL0, pin << AON_PAD_CTL0_MCU_OVR_Pos); + } + else + { + SET_BITS(AON->AON_PAD_CTL0, pin << AON_PAD_CTL0_MCU_OVR_Pos); + } +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_MUX_CTRL | CTRL0_7 | + * +----------------------+-----------------------------------+ + * \endrst + * AON_PAD_CTL_0 | MCU_OVR + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_AON_GPIO_MUX_0 + * @arg @ref LL_AON_GPIO_MUX_1 + * @arg @ref LL_AON_GPIO_MUX_2 + * @arg @ref LL_AON_GPIO_MUX_3 + * @arg @ref LL_AON_GPIO_MUX_4 + * @arg @ref LL_AON_GPIO_MUX_5 + * @arg @ref LL_AON_GPIO_MUX_6 + * @arg @ref LL_AON_GPIO_MUX_7 + * @arg @ref LL_AON_GPIO_MUX_8 + */ +__STATIC_INLINE uint32_t ll_aon_gpio_get_mux_pin_0_7(uint32_t pin) +{ + if(READ_BITS(AON->AON_PAD_CTL0, pin << AON_PAD_CTL0_MCU_OVR_Pos)) + { + uint32_t pos = POSITION_VAL(pin) << 2; + return (READ_BITS(MCU_SUB->AON_PAD_MUX_CTL, 0xF << pos) >> pos); + } + else + { + return LL_AON_GPIO_MUX_7; + } +} + +/** + * @brief Enable Xo_2MHz output on AON_GPIO_PIN5. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XO_2MHZ_ENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_xo_2mhz_output(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_XO_2MHZ_ENA); +} + +/** + * @brief Disable Xo_2MHz output on AON_GPIO_PIN5. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XO_2MHZ_ENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_disable_xo_2mhz_output(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_XO_2MHZ_ENA); +} + +/** + * @brief Check if Xo_2MHz output on AON_GPIO_PIN5 is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XO_2MHZ_ENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_xo_2mhz_output(void) +{ + return (uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_XO_2MHZ_ENA) == AON_PWR_REG01_XO_2MHZ_ENA); +} + +/** @} */ + +/** @defgroup AON_GPIO_LL_EF_Data_Access Data Access + * @{ + */ + +/** + * @brief Return full input data register value of AON_GPIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | O_AON_GPI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Input data register value of port + */ +__STATIC_INLINE uint32_t ll_aon_gpio_read_input_port(void) +{ + return (uint32_t)(READ_BITS(GPIO2->DATA, GPIO_DATA)); +} + +/** + * @brief Return if input data level of several AON_GPIO pins is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | O_AON_GPI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_input_pin_set(uint32_t pin_mask) +{ + return (uint32_t)(READ_BITS(GPIO2->DATA, pin_mask) == pin_mask); +} + +/** + * @brief Write output data register of AON_GPIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param port_value Level value for each pin of the port + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_write_output_port(uint32_t port_value) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->AON_PAD_CTL1, AON_PAD_CTL1_AON_GPO, (port_value << AON_PAD_CTL1_AON_GPO_Pos) & AON_PAD_CTL1_AON_GPO); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return full output data register value of AON_GPIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Output data register value of port + */ +__STATIC_INLINE uint32_t ll_aon_gpio_read_output_port(void) +{ + return (uint32_t)(READ_BITS(AON->AON_PAD_CTL1, AON_PAD_CTL1_AON_GPO) >> AON_PAD_CTL1_AON_GPO_Pos); +} + +/** + * @brief Return if input data level of several AON_GPIO pins is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_output_pin_set(uint32_t pin_mask) +{ + pin_mask = (pin_mask << AON_PAD_CTL1_AON_GPO_Pos) & AON_PAD_CTL1_AON_GPO; + return (uint32_t)(READ_BITS(AON->AON_PAD_CTL1, pin_mask) == pin_mask); +} + +/** + * @brief Set specified AON_GPIO pins to high level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_set_output_pin(uint32_t pin_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->AON_PAD_CTL1, (pin_mask << AON_PAD_CTL1_AON_GPO_Pos) & AON_PAD_CTL1_AON_GPO); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Set specified AON_GPIO pins to low level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_reset_output_pin(uint32_t pin_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->AON_PAD_CTL1, (pin_mask << AON_PAD_CTL1_AON_GPO_Pos) & AON_PAD_CTL1_AON_GPO); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Toggle data value of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_GPO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_toggle_pin(uint32_t pin_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + WRITE_REG(AON->AON_PAD_CTL1, (READ_REG(AON->AON_PAD_CTL1) ^ ((pin_mask << AON_PAD_CTL1_AON_GPO_Pos) & AON_PAD_CTL1_AON_GPO))); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** @} */ + +/** @defgroup AON_GPIO_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable AON_GPIO Falling Edge Trigger of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_falling_trigger(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTPOLCLR, pin_mask); + WRITE_REG(GPIO2->INTTYPESET, pin_mask); +} + +/** + * @brief Check if falling edge trigger is enabled of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_falling_trigger(uint32_t pin_mask) +{ + return ((READ_BITS(GPIO2->INTPOLCLR, pin_mask) == (pin_mask)) & + (READ_BITS(GPIO2->INTTYPESET, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable AON_GPIO Rising Edge Trigger of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_rising_trigger(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTPOLSET, pin_mask); + WRITE_REG(GPIO2->INTTYPESET, pin_mask); +} + +/** + * @brief Check if rising edge trigger is enabled of specified AON_GPIO pins. + * @note Please check each device line mapping for AON_GPIO Line availability + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_rising_trigger(uint32_t pin_mask) +{ + return ((READ_BITS(GPIO2->INTPOLSET, pin_mask) == (pin_mask)) & + (READ_BITS(GPIO2->INTTYPESET, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable AON_GPIO High Level Trigger of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_high_trigger(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTPOLSET, pin_mask); + WRITE_REG(GPIO2->INTTYPECLR, pin_mask); +} + +/** + * @brief Check if high level trigger is enabled of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_high_trigger(uint32_t pin_mask) +{ + return ((READ_BITS(GPIO2->INTPOLSET, pin_mask) == (pin_mask)) & + (READ_BITS(GPIO2->INTTYPECLR, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable AON_GPIO Low Level Trigger of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_low_trigger(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTPOLCLR, pin_mask); + WRITE_REG(GPIO2->INTTYPECLR, pin_mask); +} + +/** + * @brief Check if low level trigger is enabled of specified AON_GPIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_low_trigger(uint32_t pin_mask) +{ + return ((READ_BITS(GPIO2->INTPOLCLR, pin_mask) == (pin_mask)) & + (READ_BITS(GPIO2->INTTYPECLR, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable AON_GPIO interrupts of specified AON_GPIO pins. + * @note @ref AON_GPIO_LL_EC_TRIGGER can be used to specify the interrupt trigger type + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENSET | INTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_enable_it(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTENSET, pin_mask); +} + +/** + * @brief Disable AON_GPIO interrupts of specified AON_GPIO pins. + * @note @ref AON_GPIO_LL_EC_TRIGGER can be used to specify the interrupt trigger type + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENCLR | INTENCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_disable_it(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTENCLR, pin_mask); +} + +/** + * @brief Check if the Interrupt of specified GPIO pins is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENSET | INTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_enabled_it(uint32_t pin_mask) +{ + return (READ_BITS(GPIO2->INTENSET, pin_mask) == (pin_mask)); +} + +/** @} */ + +/** @defgroup AON_GPIO_LL_EF_Flag_Management Flag_Management + * @{ + */ + +/** + * @brief Read AON_GPIO Interrupt Combination Flag of specified AON_GPIO pins. + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval Interrupt flag whose bits were set when the selected trigger event arrives on the interrupt + */ +__STATIC_INLINE uint32_t ll_aon_gpio_read_flag_it(uint32_t pin_mask) +{ + uint32_t ext2 = READ_BITS(GPIO2->INTSTAT, pin_mask); + uint32_t wkup = (READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_EXT_WKUP_STATUS) >> AON_SLP_EVENT_EXT_WKUP_STATUS_Pos) & \ + pin_mask & READ_BITS(AON->EXT_WKUP_CTL, LL_AON_GPIO_PIN_ALL); + return (uint32_t)(ext2 | wkup); +} + +/** + * @brief Indicate if the AON_GPIO Interrupt Flag is set or not of specified AON_GPIO pins. + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_gpio_is_active_flag_it(uint32_t pin_mask) +{ + return (READ_BITS(GPIO2->INTSTAT, pin_mask) == pin_mask); +} + +/** + * @brief Clear Interrupt Status flag of specified AON_GPIO pins. + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can be cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_AON_GPIO_PIN_0 + * @arg @ref LL_AON_GPIO_PIN_1 + * @arg @ref LL_AON_GPIO_PIN_2 + * @arg @ref LL_AON_GPIO_PIN_3 + * @arg @ref LL_AON_GPIO_PIN_4 + * @arg @ref LL_AON_GPIO_PIN_5 + * @arg @ref LL_AON_GPIO_PIN_6 + * @arg @ref LL_AON_GPIO_PIN_7 + * @arg @ref LL_AON_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_aon_gpio_clear_flag_it(uint32_t pin_mask) +{ + WRITE_REG(GPIO2->INTSTAT, pin_mask); +} + +/** @} */ + +/** @defgroup AON_GPIO_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize AON_GPIO registers (Registers restored to their default values). + * @retval An error_status_t enumeration value: + * - SUCCESS: AON_GPIO registers are de-initialized + * - ERROR: AON_GPIO registers are not de-initialized + */ +error_status_t ll_aon_gpio_deinit(void); + +/** + * @brief Initialize AON_GPIO registers according to the specified. + * parameters in p_aon_gpio_init. + * @param p_aon_gpio_init Pointer to a ll_aon_gpio_init_t structure that contains the configuration + * information for the specified AON_GPIO peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: AON_GPIO registers are initialized according to p_aon_gpio_init content + * - ERROR: Problem occurred during AON_GPIO Registers initialization + */ +error_status_t ll_aon_gpio_init(ll_aon_gpio_init_t *p_aon_gpio_init); + +/** + * @brief Set each field of a @ref ll_aon_gpio_init_t type structure to default value. + * @param p_aon_gpio_init Pointer to a @ref ll_aon_gpio_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_aon_gpio_struct_init(ll_aon_gpio_init_t *p_aon_gpio_init); + +/** @} */ + +/** @} */ + +#endif /* AON */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_AON_GPIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_wdt.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_wdt.h new file mode 100644 index 0000000..6f09128 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_aon_wdt.h @@ -0,0 +1,305 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_aon_wdt.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of AON WDT LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_AON_WDT AON_WDT + * @brief AON_WDT LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_AON_WDT_H__ +#define __GR55XX_LL_AON_WDT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (AON) + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup AON_WDT_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup AON_WDT_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable AON watchdog counter and interrupt event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_enable(void) +{ + SET_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_EN); +} + +/** + * @brief Disable AON watchdog counter and interrupt event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_disable(void) +{ + CLEAR_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_EN); +} + +/** + * @brief Check if the AON_WDT peripheral is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_wdt_is_enabled(void) +{ + return (READ_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_EN) == (AON_EXT_WKUP_CTL_WDT_EN)); +} + +/** + * @brief Specify the AON WDT down-counter reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMER_VALUE | TIMER_VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param counter Value for reload down-counter which should ranging between 0 ~ 0xFFFF_FFFF + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_set_reload_counter(uint32_t counter) +{ + WRITE_REG(AON->TIMER_VALUE, counter); +} + +/** + * @brief Reloads AON WDT counter. + * @note The value in TIMER_VALUE register will be reloaded into AON WDT down-counter + * after enable this bit, so ll_aon_wdt_set_reload_counter() should be called before + * every reload. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_RELOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_reload_counter(void) +{ + SET_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_RELOAD); +} + +/** + * @brief Read the AON WDT counter current value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | AON_WDT_TIMER | + * +----------------------+-----------------------------------+ + * \endrst + * TIMER_VAL | TIMER_VAL_READ + * + * @retval Value for current counter which should ranging between 0 ~ 0xFFFF_FFFF + */ +__STATIC_INLINE uint32_t ll_aon_wdt_get_counter(void) +{ + MODIFY_REG(AON->AON_PAD_CTL1, AON_PAD_CTL1_TIMER_READ_SEL, AON_PAD_CTL1_TIMER_READ_SEL_AON_WDT); + return (uint32_t)READ_REG(AON->TIMER_VAL); +} + +/** + * @brief Specify the AON_WDT down-counter alarm value + * @note AON watchdog will generate an interrupt when it counts down to the + * alarm value to alram that it is almost expired. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_ALARM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param counter Value between Min_Data=0 and Max_Data=0x1F + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_set_alarm_counter(uint32_t counter) +{ + MODIFY_REG(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_ALARM, (counter << AON_EXT_WKUP_CTL_WDT_ALARM_Pos) & AON_EXT_WKUP_CTL_WDT_ALARM); +} + +/** + * @brief Get the AON_WDT down-counter alarm value + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_ALARM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Value between Min_Data=0 and Max_Data=0x1F + */ +__STATIC_INLINE uint32_t ll_aon_wdt_get_alarm_counter(void) +{ + return (uint32_t)(READ_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_ALARM) >> AON_EXT_WKUP_CTL_WDT_ALARM_Pos); +} + +/** @} */ + +/** @defgroup AON_WDT_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate if the AON Watchdog Running Flag is set or not. + * @note This bit can be used to check if AON Watchdog is in running state. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WDT_RUNNING | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_wdt_is_active_flag_running(void) +{ + return (uint32_t)(READ_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_WDT_RUNNING) == (AON_EXT_WKUP_CTL_WDT_RUNNING)); +} + +/** + * @brief Indicate if the AON WDT Reboot Event Flag is set or not. + * @note This bit is set by hardware when the counter has reached alarm value. + * It can be cleared by writing 0 to this bit. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | SLP_EVENT_WDT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_aon_wdt_is_active_flag_reboot(void) +{ + return (uint32_t)(READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_WDT_REBOOT) == AON_SLP_EVENT_WDT_REBOOT); +} + +/** + * @brief Clear Interrupt Status flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | SLP_EVENT_WDT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_aon_wdt_clear_flag_reboot(void) +{ + WRITE_REG(AON->SLP_EVENT, ~AON_SLP_EVENT_WDT_REBOOT); +} + +/** @} */ + +/** @} */ + +#endif /* AON_WDT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_AON_WDT_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_bod.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_bod.h new file mode 100644 index 0000000..91f2363 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_bod.h @@ -0,0 +1,331 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_bod.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of CALENDAR LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_BOD BOD + * @brief BOD LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_BOD_H_ +#define __GR55XX_LL_BOD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +/** @defgroup BOD_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup BOD_LL_ES_INIT BOD Exported init structures + * @{ + */ + +/** + * @brief LL BOD init Structure definition + */ +typedef struct _ll_bod_init +{ + uint8_t bod_en; /**< Specifies the bod enable. + + This parament can be modified afterwards using unitary function @ref ll_bod_enable() and ll_bod_disable(). */ + + uint8_t bod2_en; /**< Specifies the bod2 enable. + + This parament can be modified afterwards using unitary function @ref ll_bod2_enable() and ll_bod2_disable().. */ + + uint8_t bod2_lvl; /**< Specifies the bod2 level. + + This parament can be modified afterwards using unitary function @ref ll_bod2_lvl_ctrl_lv_set(). */ + + uint8_t bod_static_en; /**< Specifies the bod static enbale. + This parameter can be a value of @ref LL_BOD_STATIC_ENABLE. + This parament can be modified afterwards using unitary function @ref ll_bod_static_lv_enable() and ll_bod_static_lv_disable(). */ +} ll_bod_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup BOD_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup BOD_LL_Exported_Constants BOD Exported Constants + * @{ + */ + +/** @defgroup BOD_LL_ENABLE BOD ENABLE + * @{ + */ +#define LL_BOD_ENABLE 0x1 /**< BOD enable */ +#define LL_BOD_DISABLE 0x0 /**< BOD disable */ +/** @} */ + +/** @defgroup BOD2_LL_ENABLE BOD2 ENABLE + * @{ + */ +#define LL_BOD2_ENABLE 0x1 /**< BOD2 enable */ +#define LL_BOD2_DISABLE 0x0 /**< BOD2 disable */ +/** @} */ + +/** @defgroup BOD_LL_STATIC_ENABLE BOD STATIC ENABLE + * @{ + */ +#define LL_BOD_STATIC_ENABLE (0x1) /**< BOD STATIC enable */ +#define LL_BOD_STATIC_DISABLE (0x0) /**< BOD STATIC disable */ +/** @} */ + +/** @defgroup BOD2_LL_LEVEL BOD2 LVEVL + * @{ + */ +#define LL_BOD2_LEVEL_0 0x0 /**< BOD2 Level 0 */ +#define LL_BOD2_LEVEL_1 0x1 /**< BOD2 Level 1 */ +#define LL_BOD2_LEVEL_2 0x2 /**< BOD2 Level 2 */ +#define LL_BOD2_LEVEL_3 0x3 /**< BOD2 Level 3 */ +#define LL_BOD2_LEVEL_4 0x4 /**< BOD2 Level 4 */ +#define LL_BOD2_LEVEL_5 0x5 /**< BOD2 Level 5 */ +#define LL_BOD2_LEVEL_6 0x6 /**< BOD2 Level 6 */ +#define LL_BOD2_LEVEL_7 0x7 /**< BOD2 Level 7 */ +/** @} */ + +/** @} */ + +/** @} */ + +/** @defgroup BOD_LL_DRIVER_FUNCTIONS Functions + * @{ + */ +/** + * @brief Enable the bod + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod_en_lv + * + */ +__STATIC_INLINE void ll_bod_enable(void) +{ + SET_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD_EN); +} + +/** + * @brief Disable the bod + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod_en_lv + * + */ +__STATIC_INLINE void ll_bod_disable(void) +{ + CLEAR_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD_EN); +} + +/** + * @brief Enable the bod2 + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod2_en_lv + * + */ +__STATIC_INLINE void ll_bod2_enable(void) +{ + SET_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD2_EN); +} + +/** + * @brief Disable the bod2 + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod2_en_lv + * + */ +__STATIC_INLINE void ll_bod2_disable(void) +{ + CLEAR_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD2_EN); +} + +/** + * @brief Set bod control level + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod_lvl_ctrl_lv_3_0 + * @param lvl_ctrl_lv: 0x0 ~ 0x7 + */ +__STATIC_INLINE void ll_bod2_lvl_ctrl_lv_set(uint8_t lvl_ctrl_lv) +{ + MODIFY_REG(AON->RF_REG_3, AON_RF_REG_3_BOD_LVL_CTRL_LV, (lvl_ctrl_lv << AON_RF_REG_3_BOD_LVL_CTRL_LV_Pos)); +} + +/** + * @brief enable bod static lv + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod_static_lv + */ +__STATIC_INLINE void ll_bod_static_lv_enable(void) +{ + SET_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD_STATIC_LV_EN); +} + +/** + * @brief disable bod static lv + * + * Register|BitsName + * --------|-------- + * RF_REG_3 | bod_static_lv + */ +__STATIC_INLINE void ll_bod_static_lv_disable(void) +{ + CLEAR_BITS(AON->RF_REG_3, AON_RF_REG_3_BOD_STATIC_LV_EN); +} + +/** + * @brief enable BOD FEDGE Event. + * + * Register|BitsName + * --------|-------- + * AON_IRQ | PMU_BOD_FEDGE + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void ll_bod_enable_fedge(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL_PMU_BOD_FEDGE); +} + +/** + * @brief disable BOD FEDGE Event. + * + * Register|BitsName + * --------|-------- + * AON_IRQ | PMU_BOD_FEDGE + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void ll_bod_disable_fedge(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL_PMU_BOD_FEDGE); +} + +/** + * @brief Indicate if the BOD REDGE Event Flag is set or not. + * + * Register|BitsName + * --------|-------- + * AON_IRQ | PMU_BOD_REDGE + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_bod_is_active_flag_fedge(void) +{ + return (uint32_t)(READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_PMU_BOD_FEDGE) == AON_SLP_EVENT_PMU_BOD_FEDGE); +} + +/** + * @brief Clear Interrupt Status flag. + * + * Register|BitsName + * --------|-------- + * AON_IRQ| PMU_BOD_REDGE + * + * @retval None + */ +__STATIC_INLINE void ll_bod_clear_flag_fedge(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + WRITE_REG(AON->SLP_EVENT, ~AON_SLP_EVENT_PMU_BOD_FEDGE); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief De-initialize the BOD registers to their default reset values. + * @retval An error_status_t enumeration value: + * - SUCCESS: PDM registers are de-initialized + * - ERROR: PDM registers are not de-initialized + */ +error_status_t ll_bod_deinit(void); + +/** + * @brief Initialize the BOD registers according to the specified parameters. + * @param p_bod_init pointer to a @ref ll_bod_init_t structure. + * @retval An error_status_t enumeration value: + * - SUCCESS: BOD registers are initialized + * - ERROR: Not applicable + */ +error_status_t ll_bod_init(ll_bod_init_t *p_bod_init); + +/** + * @brief Set BOD initial structure to default value. + * @param p_bod_init Pointer to a @ref ll_bod_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_bod_struct_init(ll_bod_init_t *p_bod_init); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_calendar.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_calendar.h new file mode 100644 index 0000000..215cb22 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_calendar.h @@ -0,0 +1,488 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_calendar.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of CALENDAR LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_CALENDAR CALENDAR + * @brief CALENDAR LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_CALENDAR_H__ +#define __GR55XX_LL_CALENDAR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** + * @defgroup CALENDAR_LL_MACRO Defines + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CALENDAR_LL_Exported_Constants CALENDAR Exported Constants + * @{ + */ + +/** @defgroup CALENDAR_LL_EC_CLOCK_DIV Clock divider + * @{ + */ +#define LL_CALENDAR_DIV_NONE ((uint32_t)0x00U) /**< Select RTC clock */ +#define LL_CALENDAR_DIV_32 ((uint32_t)0x01U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) /**< Select 1/32 divider */ +#define LL_CALENDAR_DIV_64 ((uint32_t)0x02U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) /**< Select 1/64 divider */ +#define LL_CALENDAR_DIV_128 ((uint32_t)0x03U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) /**< Select 1/128 divider */ +#define LL_CALENDAR_DIV_256 ((uint32_t)0x04U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) /**< Select 1/256 divider */ +#define LL_CALENDAR_NO_CLOCK ((uint32_t)0x05U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) /**< Select no clock */ +/** @} */ + +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CALENDAR_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup CALENDAR_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable calendar counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_enable(void) +{ + SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_EN); +} + +/** + * @brief Disable calendar counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_disable(void) +{ + CLEAR_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_EN); +} + +/** + * @brief Check if the CALENDAR peripheral is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_calendar_is_enabled(void) +{ + return (READ_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_EN) == (AON_CALENDAR_TIMER_CTL_EN)); +} + +/** + * @brief Reloads CALENDAR counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | VAL_LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * TIMER_VALUE | TIMER_VALUE + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_reload_counter(uint32_t counter) +{ + WRITE_REG(AON->TIMER_VALUE, counter); + SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_VAL_LOAD); +} + +/** + * @brief Reloads CALENDAR alarm. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ALARM_VAL_LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * TIMER_VALUE | TIMER_VALUE + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_reload_alarm(uint32_t alarm) +{ + WRITE_REG(AON->TIMER_VALUE, alarm); + SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD); +} + +/** + * @brief Read the CALENDAR counter current value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | CAL_TIMER | + * +----------------------+-----------------------------------+ + * \endrst + * TIMER_VAL | TIMER_VAL_READ + * + * @retval Value for current counter which should ranging between 0 ~ 0xFFFF_FFFF + */ +__STATIC_INLINE uint32_t ll_calendar_get_counter(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->AON_PAD_CTL1, AON_PAD_CTL1_TIMER_READ_SEL, AON_PAD_CTL1_TIMER_READ_SEL_CAL_TIMER); + GLOBAL_EXCEPTION_ENABLE(); + return (uint32_t)READ_REG(AON->TIMER_VAL); +} + +/** + * @brief Read the CALENDAR counter alarm value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AON_PAD_CTL1 | CAL_ALARM | + * +----------------------+-----------------------------------+ + * \endrst + * TIMER_VAL | TIMER_VAL_READ + * + * @retval Value for current alarm which should ranging between 0 ~ 0xFFFF_FFFF + */ +__STATIC_INLINE uint32_t ll_calendar_get_alarm(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->AON_PAD_CTL1, AON_PAD_CTL1_TIMER_READ_SEL, AON_PAD_CTL1_TIMER_READ_SEL_CAL_ALARM); + GLOBAL_EXCEPTION_ENABLE(); + return (uint32_t)READ_REG(AON->TIMER_VAL); +} + +/** + * @brief Get the CALENDAR wrap-around value. + * @note The value should be read multiple times until get the same value in at least two reads. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | WRAP_CNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Value between Min_Data=0 and Max_Data=0xF + */ +__STATIC_INLINE uint32_t ll_calendar_get_wrapcnt(void) +{ + return (uint32_t)(READ_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_WRAP_CNT) >> AON_CALENDAR_TIMER_CTL_WRAP_CNT_Pos); +} + +/** + * @brief Select the CALENDAR clock divider. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | CLK_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param div This parameter can be one of the following values: + * @arg @ref LL_CALENDAR_DIV_NONE + * @arg @ref LL_CALENDAR_DIV_32 + * @arg @ref LL_CALENDAR_DIV_64 + * @arg @ref LL_CALENDAR_DIV_128 + * @arg @ref LL_CALENDAR_DIV_256 + * @arg @ref LL_CALENDAR_NO_CLOCK + * @retval None + */ +__STATIC_INLINE void ll_calendar_set_clock_div(uint32_t div) +{ + MODIFY_REG(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_CLK_SEL, div); +} + +/** + * @brief Enable calendar alarm interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ALARM_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_it_enable_alarm(void) +{ + SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_ALARM_INT_EN); +} + +/** + * @brief Disable calendar alarm interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ALARM_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_it_disable_alarm(void) +{ + CLEAR_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_ALARM_INT_EN); +} + +/** + * @brief Check if the CALENDAR alarm interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ALARM_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_calendar_it_is_enabled_alarm(void) +{ + return (READ_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_ALARM_INT_EN) == (AON_CALENDAR_TIMER_CTL_ALARM_INT_EN)); +} + +/** + * @brief Enable calendar wrap interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | WRAP_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_it_enable_wrap(void) +{ + SET_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_WRAP_INT_EN); +} + +/** + * @brief Disable calendar warp interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | WRAP_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_it_disable_wrap(void) +{ + CLEAR_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_WRAP_INT_EN); +} + +/** + * @brief Check if the CALENDAR wrap interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | WRAP_INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_calendar_it_is_enabled_wrap(void) +{ + return (READ_BITS(AON->CALENDAR_TIMER_CTL, AON_CALENDAR_TIMER_CTL_WRAP_INT_EN) == (AON_CALENDAR_TIMER_CTL_WRAP_INT_EN)); +} + +/** @} */ + +/** @defgroup CALENDAR_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate if the CALENDAR alarm event flag is set or not. + * @note This bit is set by hardware when the counter has reached alarm value. + * It can be cleared by writing 0 to this bit. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | CALENDAR_TIMER_ALARM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_calendar_is_active_flag_alarm(void) +{ + return (uint32_t)(READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_CALENDAR_TIMER_ALARM) == AON_SLP_EVENT_CALENDAR_TIMER_ALARM); +} + +/** + * @brief Indicate if the CALENDAR wrap event flag is set or not. + * @note This bit is set by hardware when the counter has overflow. + * It can be cleared by writing 0 to this bit. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | CALENDAR_TIMER_WRAP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_calendar_is_active_flag_wrap(void) +{ + return (uint32_t)(READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_CALENDAR_TIMER_WRAP) == AON_SLP_EVENT_CALENDAR_TIMER_WRAP); +} + +/** + * @brief Clear calendar alarm interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | CALENDAR_TIMER_ALARM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_clear_flag_alarm(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + WRITE_REG(AON->SLP_EVENT, ~AON_SLP_EVENT_CALENDAR_TIMER_ALARM); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Clear calendar wrap interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | CALENDAR_TIMER_WRAP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_calendar_clear_flag_wrap(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + WRITE_REG(AON->SLP_EVENT, ~AON_SLP_EVENT_CALENDAR_TIMER_WRAP); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** @} */ + +/** @} */ + +#endif /* CALENDAR */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_CALENDAR_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_cgc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_cgc.h new file mode 100644 index 0000000..6878ed6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_cgc.h @@ -0,0 +1,2711 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_cgc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of CGC LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_CGC CGC + * @brief CGC LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_CGC_H__ +#define __GR55XX_LL_CGC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(MCU_SUB) + +/** @defgroup CGC_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CGC_LL_ES_INIT CGC Exported init structures + * @{ + */ + +/** + * @brief LL CGC init Structure definition + */ +typedef struct _ll_cgc_init_t +{ + uint32_t wfi_clk0; /**< Specifies the block that automatically closes the clock. + This parameter can be a combination of @ref CGC_LL_EC_WFI_CLK0. */ + + uint32_t wfi_clk1; /**< Specifies the block that automatically closes the clock. + This parameter can be a combination of @ref CGC_LL_EC_WFI_CLK1. */ + + uint32_t wfi_clk2; /**< Specifies the block that automatically closes the clock. + This parameter can be a combination of @ref CGC_LL_EC_WFI_CLK2. */ + + uint32_t force_clk0; /**< Specifies the blocks for forced turn off clock. + This parameter can be a combination of @ref CGC_LL_EC_FRC_CLK0. */ + + uint32_t force_clk1; /**< Specifies the blocks for forced turn off clock. + This parameter can be a combination of @ref CGC_LL_EC_FRC_CLK1. */ + + uint32_t force_clk2; /**< Specifies the blocks for forced turn off clock. + This parameter can be a combination of @ref CGC_LL_EC_FRC_CLK2. */ +} ll_cgc_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup CGC_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CGC_LL_Exported_Constants CGC Exported Constants + * @{ + */ + +/** @defgroup CGC_LL_EC_WFI_CLK0 Block0 Clock During WFI + * @{ + */ +#define LL_CGC_WFI_SECU_HCLK MCU_SUB_WFI_SECU_HCLK /**< Hclk for all security blocks */ +#define LL_CGC_WFI_SIM_HCLK MCU_SUB_WFI_SIM_HCLK /**< Hclk for sim card interface */ +#define LL_CGC_WFI_HTB_HCLK MCU_SUB_WFI_HTB_HCLK /**< Hclk for hopping table */ +#define LL_CGC_WFI_PWM_HCLK MCU_SUB_WFI_PWM_HCLK /**< Hclk for PWM */ +#define LL_CGC_WFI_ROM_HCLK MCU_SUB_WFI_ROM_HCLK /**< Hclk for ROM */ +#define LL_CGC_WFI_SNSADC_HCLK MCU_SUB_WFI_SNSADC_HCLK /**< Hclk for sense ADC */ +#define LL_CGC_WFI_GPIO_HCLK MCU_SUB_WFI_GPIO_HCLK /**< Hclk for GPIOs */ +#define LL_CGC_WFI_DMA_HCLK MCU_SUB_WFI_DMA_HCLK /**< Hclk for DMA engine */ +#define LL_CGC_WFI_BLE_BRG_HCLK MCU_SUB_WFI_BLE_BRG_HCLK /**< Hclk for BLE MCU bridge */ +#define LL_CGC_WFI_APB_SUB_HCLK MCU_SUB_WFI_APB_SUB_HCLK /**< Hclk for APB subsystem */ +#define LL_CGC_WFI_SERIAL_HCLK MCU_SUB_WFI_SERIAL_HCLK /**< Hclk for serial blocks */ +#define LL_CGC_WFI_I2S_S_HCLK MCU_SUB_WFI_I2S_S_HCLK /**< Hclk for I2S slave */ + +#define LL_CGC_WFI_ALL_HCLK0 ((uint32_t)0x00000FFFU) /**< All clock group 0 */ +/** @} */ + +/** @defgroup CGC_LL_EC_WFI_CLK1 Block1 Clock During WFI + * @{ + */ +#define LL_CGC_WFI_AON_MCUSUB_HCLK MCU_SUB_WFI_AON_MCUSUB_HCLK /**< Hclk for Always-on register */ +#define LL_CGC_WFI_XF_XQSPI_HCLK MCU_SUB_WFI_XF_XQSPI_HCLK /**< Hclk for cache top */ +#define LL_CGC_WFI_SRAM_HCLK MCU_SUB_WFI_SRAM_HCLK /**< Hclk for SRAMs */ + +#define LL_CGC_WFI_ALL_HCLK1 ((uint32_t)0x00000007U) /**< All clock group 1 */ +/** @} */ + +/** @defgroup CGC_LL_EC_WFI_CLK2 Block2 Clock During WFI + * @{ + */ +#define LL_CGC_WFI_SECU_DIV4_PCLK MCU_SUB_WFI_SECU_DIV4_PCLK /**< Div4 clk for security blocks */ +#define LL_CGC_WFI_XQSPI_DIV4_PCLK MCU_SUB_WFI_XQSPI_DIV4_PCLK /**< Div4 clk for xf qspi */ + +#define LL_CGC_WFI_ALL_HCLK2 ((uint32_t)0x05000000U) /**< All clock group 2 */ +/** @} */ + + +/** @defgroup CGC_LL_EC_FRC_CLK0 Force Clock OFF + * @{ + */ +#define LL_CGC_FRC_SECU_HCLK MCU_SUB_FORCE_SECU_HCLK /**< Hclk for all security blocks */ +#define LL_CGC_FRC_SIM_HCLK MCU_SUB_FORCE_SIM_HCLK /**< Hclk for sim card interface */ +#define LL_CGC_FRC_HTB_HCLK MCU_SUB_FORCE_HTB_HCLK /**< Hclk for hopping table */ +#define LL_CGC_FRC_PWM_HCLK MCU_SUB_FORCE_PWM_HCLK /**< Hclk for PWM */ +#define LL_CGC_FRC_ROM_HCLK MCU_SUB_FORCE_ROM_HCLK /**< Hclk for ROM */ +#define LL_CGC_FRC_SNSADC_HCLK MCU_SUB_FORCE_SNSADC_HCLK /**< Hclk for sense ADC */ +#define LL_CGC_FRC_GPIO_HCLK MCU_SUB_FORCE_GPIO_HCLK /**< Hclk for GPIOs */ +#define LL_CGC_FRC_DMA_HCLK MCU_SUB_FORCE_DMA_HCLK /**< Hclk for DMA engine */ +#define LL_CGC_FRC_BLE_BRG_HCLK MCU_SUB_FORCE_BLE_BRG_HCLK /**< Hclk for BLE MCU bridge */ +#define LL_CGC_FRC_APB_SUB_HCLK MCU_SUB_FORCE_APB_SUB_HCLK /**< Hclk for APB subsystem */ +#define LL_CGC_FRC_SERIAL_HCLK MCU_SUB_FORCE_SERIAL_HCLK /**< Hclk for serial blocks */ +#define LL_CGC_FRC_I2S_S_HCLK MCU_SUB_FORCE_I2S_S_HCLK /**< Hclk for I2S slave */ + +#define LL_CGC_FRC_ALL_HCLK0 ((uint32_t)0x00000FFFU) /**< All clock group 0 */ +/** @} */ + +/** @defgroup CGC_LL_EC_FRC_CLK1 Force Clock OFF + * @{ + */ +#define LL_CGC_FRC_AON_MCUSUB_HCLK MCU_SUB_FORCE_AON_MCUSUB_HCLK /**< Hclk for Always-on register */ +#define LL_CGC_FRC_XF_XQSPI_HCLK MCU_SUB_FORCE_XF_XQSPI_HCLK /**< Hclk for cache top */ +#define LL_CGC_FRC_SRAM_HCLK MCU_SUB_FORCE_SRAM_HCLK /**< Hclk for SRAMs */ + +#define LL_CGC_FRC_ALL_HCLK1 ((uint32_t)0x00070000U) /**< All clock group 1 */ +/** @} */ + +/** @defgroup CGC_LL_EC_FRC_CLK2 Force Clock OFF + * @{ + */ +#define LL_CGC_FRC_UART0_HCLK MCU_SUB_FORCE_UART0_HCLK /**< Hclk for uart0 */ +#define LL_CGC_FRC_UART1_HCLK MCU_SUB_FORCE_UART1_HCLK /**< Hclk for uart1 */ +#define LL_CGC_FRC_I2C0_HCLK MCU_SUB_FORCE_I2C0_HCLK /**< Hclk for i2c0 */ +#define LL_CGC_FRC_I2C1_HCLK MCU_SUB_FORCE_I2C1_HCLK /**< Hclk for i2c1 */ +#define LL_CGC_FRC_SPIM_HCLK MCU_SUB_FORCE_SPIM_HCLK /**< Hclk for spim */ +#define LL_CGC_FRC_SPIS_HCLK MCU_SUB_FORCE_SPIS_HCLK /**< Hclk for spis */ +#define LL_CGC_FRC_QSPI0_HCLK MCU_SUB_FORCE_QSPI0_HCLK /**< Hclk for qspi0 */ +#define LL_CGC_FRC_QSPI1_HCLK MCU_SUB_FORCE_QSPI1_HCLK /**< Hclk for qspi1 */ +#define LL_CGC_FRC_I2S_HCLK MCU_SUB_FORCE_I2S_HCLK /**< Hclk for i2s */ +#define LL_CGC_FRC_SECU_DIV4_PCLK MCU_SUB_FORCE_SECU_DIV4_PCLK /**< Div4 clk for security blocks */ +#define LL_CGC_FRC_XQSPI_DIV4_PCLK MCU_SUB_FORCE_XQSPI_DIV4_PCLK /**< Div4 clk for xf qspi */ + +#define LL_CGC_FRC_SERIALS_HCLK2 ((uint32_t)0x0001FF00U) /**< Hclk for serial blocks */ +#define LL_CGC_FRC_ALL_HCLK2 ((uint32_t)0x0A01FF00U) /**< All clock group 2 */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CGC_LL_Exported_Macros CGC Exported Macros + * @{ + */ + +/** @defgroup CGC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in CGC register + * @param __instance__ CGC instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_CGC_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in CGC register + * @param __instance__ CGC instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_CGC_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CGC_LL_Private_Macros CGC Private Macros + * @{ + */ + +/** @defgroup CGC_LL_EC_DEFAULT_CONFIG InitStruct default configuartion + * @{ + */ + +/** + * @brief LL CGC InitStrcut default configuartion + */ +#define LL_CGC_DEFAULT_CONFIG \ +{ \ + .wfi_clk0 = ~LL_CGC_WFI_ALL_HCLK0, \ + .wfi_clk1 = ~LL_CGC_WFI_ALL_HCLK1, \ + .wfi_clk2 = ~LL_CGC_WFI_ALL_HCLK2, \ + .force_clk0 = ~LL_CGC_FRC_ALL_HCLK0, \ + .force_clk1 = ~LL_CGC_FRC_ALL_HCLK1, \ + .force_clk2 = ~LL_CGC_FRC_ALL_HCLK2, \ +} +/** @} */ + +/** @} */ + +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CGC_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup CGC_LL_EF_CLK_Configuration Clock Configuration + * @{ + */ + +/** + * @brief Some peripherals automatic turn off clock during WFI. (Include: Security/SIM/HTB/PWM/ + * ROM/SNSADC/GPIO/DMA/BLE_BRG/APB_SUB/SERIAL/I2S) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SECU_HCLK + * CG_CTRL_0 | SIM_HCLK + * CG_CTRL_0 | HTB_HCLK + * CG_CTRL_0 | PWM_HCLK + * CG_CTRL_0 | ROM_HCLK + * CG_CTRL_0 | SNSADC_HCLK + * CG_CTRL_0 | GPIO_HCLK + * CG_CTRL_0 | DMA_HCLK + * CG_CTRL_0 | BLE_BRG_HCLK + * CG_CTRL_0 | APB_SUB_HCLK + * CG_CTRL_0 | SERIAL_HCLK + * CG_CTRL_0 | I2S_S_HCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_WFI_SECU_HCLK + * @arg @ref LL_CGC_WFI_SIM_HCLK + * @arg @ref LL_CGC_WFI_HTB_HCLK + * @arg @ref LL_CGC_WFI_PWM_HCLK + * @arg @ref LL_CGC_WFI_ROM_HCLK + * @arg @ref LL_CGC_WFI_SNSADC_HCLK + * @arg @ref LL_CGC_WFI_GPIO_HCLK + * @arg @ref LL_CGC_WFI_DMA_HCLK + * @arg @ref LL_CGC_WFI_BLE_BRG_HCLK + * @arg @ref LL_CGC_WFI_APB_SUB_HCLK + * @arg @ref LL_CGC_WFI_SERIAL_HCLK + * @arg @ref LL_CGC_WFI_I2S_S_HCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_wfi_off_hclk_0(uint32_t clk_mask) +{ + WRITE_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], clk_mask); +} + +/** + * @brief Return to clock blocks that is turned off during WFI.(Include: Security/SIM/HTB/PWM/ + * ROM/SNSADC/GPIO/DMA/BLE_BRG/APB_SUB/SERIAL/I2S) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SECU_HCLK + * CG_CTRL_0 | SIM_HCLK + * CG_CTRL_0 | HTB_HCLK + * CG_CTRL_0 | PWM_HCLK + * CG_CTRL_0 | ROM_HCLK + * CG_CTRL_0 | SNSADC_HCLK + * CG_CTRL_0 | GPIO_HCLK + * CG_CTRL_0 | DMA_HCLK + * CG_CTRL_0 | BLE_BRG_HCLK + * CG_CTRL_0 | APB_SUB_HCLK + * CG_CTRL_0 | SERIAL_HCLK + * CG_CTRL_0 | I2S_S_HCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_WFI_SECU_HCLK + * @arg @ref LL_CGC_WFI_SIM_HCLK + * @arg @ref LL_CGC_WFI_HTB_HCLK + * @arg @ref LL_CGC_WFI_PWM_HCLK + * @arg @ref LL_CGC_WFI_ROM_HCLK + * @arg @ref LL_CGC_WFI_SNSADC_HCLK + * @arg @ref LL_CGC_WFI_GPIO_HCLK + * @arg @ref LL_CGC_WFI_DMA_HCLK + * @arg @ref LL_CGC_WFI_BLE_BRG_HCLK + * @arg @ref LL_CGC_WFI_APB_SUB_HCLK + * @arg @ref LL_CGC_WFI_SERIAL_HCLK + * @arg @ref LL_CGC_WFI_I2S_S_HCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_wfi_off_hclk_0(void) +{ + return READ_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[0]); +} + + +/** + * @brief Some peripherals automatic turn off clock during WFI. (Include: AON_MCUSUB/XF_XQSPI/SRAM) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * CG_CTRL_2 | XF_XQSPI_HCLK + * CG_CTRL_2 | SRAM_HCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_WFI_AON_MCUSUB_HCLK + * @arg @ref LL_CGC_WFI_XF_XQSPI_HCLK + * @arg @ref LL_CGC_WFI_SRAM_HCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_wfi_off_hclk_1(uint32_t clk_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_MSK_HCLK_1, clk_mask); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return to clock blocks that is turned off during WFI.(Include: AON_MCUSUB/XF_XQSPI/SRAM) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * CG_CTRL_2 | XF_XQSPI_HCLK + * CG_CTRL_2 | SRAM_HCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_WFI_AON_MCUSUB_HCLK + * @arg @ref LL_CGC_WFI_XF_XQSPI_HCLK + * @arg @ref LL_CGC_WFI_SRAM_HCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_wfi_off_hclk_1(void) +{ + return READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_MSK_HCLK_1); +} + +/** + * @brief Some peripherals automatic turn off clock during WFI. (Include: SECU_DIV4/XQSPI_DIV4) + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SECU_DIV4_PCLK + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_WFI_SECU_DIV4_PCLK + * @arg @ref LL_CGC_WFI_XQSPI_DIV4_PCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_wfi_off_hclk_2(uint32_t clk_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_MSK_HCLK_2, clk_mask); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return to clock blocks that is turned off during WFI.(Include: AON_MCUSUB/XF_XQSPI/SRAM) + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SECU_DIV4_PCLK + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_WFI_SECU_DIV4_PCLK + * @arg @ref LL_CGC_WFI_XQSPI_DIV4_PCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_wfi_off_hclk_2(void) +{ + return READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_MSK_HCLK_2); +} + +/** + * @brief Some peripherals force turn off clock. (Include: Security/SIM/HTB/PWM/ROM/SNSADC/GPIO/ + * DMA/BLE_BRG/APB_SUB/SERIAL/I2S) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SECU_HCLK + * CG_CTRL_1 | SIM_HCLK + * CG_CTRL_1 | HTB_HCLK + * CG_CTRL_1 | PWM_HCLK + * CG_CTRL_1 | ROM_HCLK + * CG_CTRL_1 | SNSADC_HCLK + * CG_CTRL_1 | GPIO_HCLK + * CG_CTRL_1 | DMA_HCLK + * CG_CTRL_1 | BLE_BRG_HCLK + * CG_CTRL_1 | APB_SUB_HCLK + * CG_CTRL_1 | SERIAL_HCLK + * CG_CTRL_1 | I2S_S_HCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_FRC_SECU_HCLK + * @arg @ref LL_CGC_FRC_SIM_HCLK + * @arg @ref LL_CGC_FRC_HTB_HCLK + * @arg @ref LL_CGC_FRC_PWM_HCLK + * @arg @ref LL_CGC_FRC_ROM_HCLK + * @arg @ref LL_CGC_FRC_SNSADC_HCLK + * @arg @ref LL_CGC_FRC_GPIO_HCLK + * @arg @ref LL_CGC_FRC_DMA_HCLK + * @arg @ref LL_CGC_FRC_BLE_BRG_HCLK + * @arg @ref LL_CGC_FRC_APB_SUB_HCLK + * @arg @ref LL_CGC_FRC_SERIAL_HCLK + * @arg @ref LL_CGC_FRC_I2S_S_HCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_force_off_hclk_0(uint32_t clk_mask) +{ + WRITE_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], clk_mask); +} + +/** + * @brief Return to clock blocks that was forcibly closed.(Include: Security/SIM/HTB/PWM/ + * ROM/SNSADC/GPIO/DMA/BLE_BRG/APB_SUB/SERIAL/I2S) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SECU_HCLK + * CG_CTRL_1 | SIM_HCLK + * CG_CTRL_1 | HTB_HCLK + * CG_CTRL_1 | PWM_HCLK + * CG_CTRL_1 | ROM_HCLK + * CG_CTRL_1 | SNSADC_HCLK + * CG_CTRL_1 | GPIO_HCLK + * CG_CTRL_1 | DMA_HCLK + * CG_CTRL_1 | BLE_BRG_HCLK + * CG_CTRL_1 | APB_SUB_HCLK + * CG_CTRL_1 | SERIAL_HCLK + * CG_CTRL_1 | I2S_S_HCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_FRC_SECU_HCLK + * @arg @ref LL_CGC_FRC_SIM_HCLK + * @arg @ref LL_CGC_FRC_HTB_HCLK + * @arg @ref LL_CGC_FRC_PWM_HCLK + * @arg @ref LL_CGC_FRC_ROM_HCLK + * @arg @ref LL_CGC_FRC_SNSADC_HCLK + * @arg @ref LL_CGC_FRC_GPIO_HCLK + * @arg @ref LL_CGC_FRC_DMA_HCLK + * @arg @ref LL_CGC_FRC_BLE_BRG_HCLK + * @arg @ref LL_CGC_FRC_APB_SUB_HCLK + * @arg @ref LL_CGC_FRC_SERIAL_HCLK + * @arg @ref LL_CGC_FRC_I2S_S_HCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_force_off_hclk_0(void) +{ + return READ_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[1]); +} + + +/** + * @brief Some peripherals force turn off clock. (Include: AON_MCUSUB/XF_XQSPI/SRAM) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * CG_CTRL_2 | XF_XQSPI_HCLK + * CG_CTRL_2 | SRAM_HCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_FRC_AON_MCUSUB_HCLK + * @arg @ref LL_CGC_FRC_XF_XQSPI_HCLK + * @arg @ref LL_CGC_FRC_SRAM_HCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_force_off_hclk_1(uint32_t clk_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_MSK_HCLK_1, clk_mask); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return to clock blocks that was forcibly closed.(Include: AON_MCUSUB/XF_XQSPI/SRAM) + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * CG_CTRL_2 | XF_XQSPI_HCLK + * CG_CTRL_2 | SRAM_HCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_FRC_AON_MCUSUB_HCLK + * @arg @ref LL_CGC_FRC_XF_XQSPI_HCLK + * @arg @ref LL_CGC_FRC_SRAM_HCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_force_off_hclk_1(void) +{ + return READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_MSK_HCLK_1); +} + +/** + * @brief Some peripherals force turn off clock. (Include: UART0_HCLK/UART1_HCLK/I2C0_HCLK/ + * I2C1_HCLK/SPIM_HCLK/SPIS_HCLK/QSPI0_HCLK/QSPI1_HCLK/I2S_HCLK/SECU_DIV4_PCLK/XQSPI_DIV4_PCLK) + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART0_HCLK + * PERIPH_GC | UART1_HCLK + * PERIPH_GC | I2C0_HCLK + * PERIPH_GC | I2C1_HCLK + * PERIPH_GC | SPIM_HCLK + * PERIPH_GC | SPIS_HCLK + * PERIPH_GC | QSPI0_HCLK + * PERIPH_GC | QSPI1_HCLK + * PERIPH_GC | I2S_HCLK + * PERIPH_GC | SECU_DIV4_PCLK + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @param clk_mask This parameter can be a combination of the following values: + * @arg @ref LL_CGC_FRC_UART0_HCLK + * @arg @ref LL_CGC_FRC_UART1_HCLK + * @arg @ref LL_CGC_FRC_I2C0_HCLK + * @arg @ref LL_CGC_FRC_I2C1_HCLK + * @arg @ref LL_CGC_FRC_SPIM_HCLK + * @arg @ref LL_CGC_FRC_SPIS_HCLK + * @arg @ref LL_CGC_FRC_QSPI0_HCLK + * @arg @ref LL_CGC_FRC_QSPI1_HCLK + * @arg @ref LL_CGC_FRC_I2S_HCLK + * @arg @ref LL_CGC_FRC_SECU_DIV4_PCLK + * @arg @ref LL_CGC_FRC_XQSPI_DIV4_PCLK + * @retval None + */ +__STATIC_INLINE void ll_cgc_set_force_off_hclk_2(uint32_t clk_mask) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_MSK_HCLK_2, clk_mask); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return to clock blocks that was forcibly closed.(Include: UART0_HCLK/UART1_HCLK/I2C0_HCLK/ + * I2C1_HCLK/SPIM_HCLK/SPIS_HCLK/QSPI0_HCLK/QSPI1_HCLK/I2S_HCLK/SECU_DIV4_PCLK/XQSPI_DIV4_PCLK) + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART0_HCLK + * PERIPH_GC | UART1_HCLK + * PERIPH_GC | I2C0_HCLK + * PERIPH_GC | I2C1_HCLK + * PERIPH_GC | SPIM_HCLK + * PERIPH_GC | SPIS_HCLK + * PERIPH_GC | QSPI0_HCLK + * PERIPH_GC | QSPI1_HCLK + * PERIPH_GC | I2S_HCLK + * PERIPH_GC | SECU_DIV4_PCLK + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_CGC_FRC_UART0_HCLK + * @arg @ref LL_CGC_FRC_UART1_HCLK + * @arg @ref LL_CGC_FRC_I2C0_HCLK + * @arg @ref LL_CGC_FRC_I2C1_HCLK + * @arg @ref LL_CGC_FRC_SPIM_HCLK + * @arg @ref LL_CGC_FRC_SPIS_HCLK + * @arg @ref LL_CGC_FRC_QSPI0_HCLK + * @arg @ref LL_CGC_FRC_QSPI1_HCLK + * @arg @ref LL_CGC_FRC_I2S_HCLK + * @arg @ref LL_CGC_FRC_SECU_DIV4_PCLK + * @arg @ref LL_CGC_FRC_XQSPI_DIV4_PCLK + */ +__STATIC_INLINE uint32_t ll_cgc_get_force_off_hclk_2(void) +{ + return READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_MSK_HCLK_2); +} + +/** + * @brief Enable security blocks(including AES, PKC, Present, HMAC) automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SECU_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_secu_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SECU_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable security blocks(including AES, PKC, Present, HMAC) automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SECU_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_secu_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SECU_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the security blocks(including AES, PKC, Present, HMAC) automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SECU_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_secu_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SECU_HCLK) == (MCU_SUB_WFI_SECU_HCLK)); +} + +/** + * @brief Enable SIM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_sim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SIM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable SIM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_sim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SIM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the SIM automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SIM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_sim_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SIM_HCLK) == (MCU_SUB_WFI_SIM_HCLK)); +} + +/** + * @brief Enable Hopping Table automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | HTB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_htb_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_HTB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable Hopping Table automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | HTB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_htb_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_HTB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the Hopping Table automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | HTB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_htb_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_HTB_HCLK) == (MCU_SUB_WFI_HTB_HCLK)); +} + +/** + * @brief Enable PWM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | PWM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_pwm_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_PWM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable PWM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | PWM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_pwm_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_PWM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the PWM automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | PWM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_pwm_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_PWM_HCLK) == (MCU_SUB_WFI_PWM_HCLK)); +} + +/** + * @brief Enable ROM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | ROM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_rom_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_ROM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable ROM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | ROM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_rom_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_ROM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the ROM automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | ROM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_rom_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_ROM_HCLK) == (MCU_SUB_WFI_ROM_HCLK)); +} + +/** + * @brief Enable SNSADC automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SNSADC_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_snsadc_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SNSADC_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable SNSADC automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SNSADC_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_snsadc_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SNSADC_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the SNSADC automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SNSADC_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_snsadc_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SNSADC_HCLK) == (MCU_SUB_WFI_SNSADC_HCLK)); +} + +/** + * @brief Enable GPIO automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | GPIO_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_gpio_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_GPIO_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable GPIO automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | GPIO_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_gpio_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_GPIO_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the GPIO automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | GPIO_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_gpio_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_GPIO_HCLK) == (MCU_SUB_WFI_GPIO_HCLK)); +} + +/** + * @brief Enable DMA automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | DMA_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_dma_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_DMA_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable DMA automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | DMA_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_dma_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_DMA_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the DMA automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | DMA_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_dma_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_DMA_HCLK) == (MCU_SUB_WFI_DMA_HCLK)); +} + +/** + * @brief Enable BLE Bridge automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | BLE_BRG_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_ble_brg_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_BLE_BRG_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable BLE Bridge automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | BLE_BRG_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_ble_brg_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_BLE_BRG_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the BLE Bridge automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | BLE_BRG_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_ble_brg_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_BLE_BRG_HCLK) == (MCU_SUB_WFI_BLE_BRG_HCLK)); +} + +/** + * @brief Enable APB Subsystem automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | APB_SUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_apb_sub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_APB_SUB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable APB Subsystem automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | APB_SUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_apb_sub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_APB_SUB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the APB Subsystem automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | APB_SUB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_apb_sub_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_APB_SUB_HCLK) == (MCU_SUB_WFI_APB_SUB_HCLK)); +} + +/** + * @brief Enable serial blocks(including I2C, UART, QSPI, I2S, SPI) automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SERIAL_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_serial_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SERIAL_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable serial blocks(including I2C, UART, QSPI, I2S, SPI) automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SERIAL_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_serial_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SERIAL_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the serial blocks(including I2C, UART, QSPI, I2S, SPI) automatic turn off + * clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | SERIAL_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_serial_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_SERIAL_HCLK) == (MCU_SUB_WFI_SERIAL_HCLK)); +} + +/** + * @brief Enable I2S slave automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | I2S_S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_i2s_s_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_I2S_S_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable I2S slave automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | I2S_S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_i2s_s_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_I2S_S_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the I2S slave automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_0 | I2S_S_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_i2s_s_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[0], MCU_SUB_WFI_I2S_S_HCLK) == (MCU_SUB_WFI_I2S_S_HCLK)); +} + +/** + * @brief Enable AON_MUCSUB automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_aon_mcusub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_AON_MCUSUB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable AON_MUCSUB automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_aon_mcusub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_AON_MCUSUB_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the AON_MUCSUB automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_aon_mcusub_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_AON_MCUSUB_HCLK) == (MCU_SUB_WFI_AON_MCUSUB_HCLK)); +} + +/** + * @brief Enable XQSPI automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_xqspi_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_XF_XQSPI_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable XQSPI automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_xqspi_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_XF_XQSPI_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the XQSPI automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_xqspi_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_XF_XQSPI_HCLK) == (MCU_SUB_WFI_XF_XQSPI_HCLK)); +} + +/** + * @brief Enable SRAM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_sram_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_SRAM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable SRAM automatic turn off clock during WFI + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_sram_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_SRAM_HCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the SRAM automatic turn off clock is enabled. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_sram_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_WFI_SRAM_HCLK) == (MCU_SUB_WFI_SRAM_HCLK)); +} + +/** + * @brief Enable security blocks automatic turn off div4 clock during WFI + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SECU_DIV4_PCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_secu_div4_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_SECU_DIV4_PCLK); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable security blocks automatic turn off div4 clock during WFI + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SECU_DIV4_PCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_secu_div4_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_SECU_DIV4_PCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the security blocks automatic turn off div4 + * clock is enabled. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SECU_DIV4_PCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_secu_div4_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_SECU_DIV4_PCLK) == (MCU_SUB_WFI_SECU_DIV4_PCLK)); +} + +/** + * @brief Enable XQSPI automatic turn off div4 clock during WFI + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_wfi_off_xqspi_div4_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_XQSPI_DIV4_PCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable XQSPI automatic turn off div4 clock during WFI + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_wfi_off_xqspi_div4_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_XQSPI_DIV4_PCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the XQSPI automatic turn off div4 clock is enabled. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | XQSPI_DIV4_PCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_wfi_off_xqspi_div4_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_WFI_XQSPI_DIV4_PCLK) == (MCU_SUB_WFI_XQSPI_DIV4_PCLK)); +} + +/** + * @brief Enabling force to turn off the clock for security blocks(including AES, PKC, Present, HMAC). + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SECU_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_secu_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SECU_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for security blocks(including AES, PKC, Present, HMAC). + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SECU_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_secu_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SECU_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for security blocks(including AES, PKC, Present, HMAC) is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SECU_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_secu_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SECU_HCLK) == (MCU_SUB_FORCE_SECU_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for SIM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_sim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SIM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for SIM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_sim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SIM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for SIM is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SIM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_sim_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SIM_HCLK) == (MCU_SUB_FORCE_SIM_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for Hopping Table. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | HTB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_htb_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_HTB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for Hopping Table. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | HTB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_htb_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_HTB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for Hopping Table is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | HTB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_htb_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_HTB_HCLK) == (MCU_SUB_FORCE_HTB_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for PWM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | PWM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_pwm_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_PWM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for PWM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | PWM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_pwm_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_PWM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for PWM is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | PWM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_pwm_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_PWM_HCLK) == (MCU_SUB_FORCE_PWM_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for ROM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | ROM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_rom_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_ROM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for ROM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | ROM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_rom_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_ROM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for ROM is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | ROM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_rom_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_ROM_HCLK) == (MCU_SUB_FORCE_ROM_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for SNSADC. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SNSADC_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_snsadc_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SNSADC_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for SNSADC. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SNSADC_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_snsadc_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SNSADC_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for SNSADC is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SNSADC_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_snsadc_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SNSADC_HCLK) == (MCU_SUB_FORCE_SNSADC_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for GPIO. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | GPIO_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_gpio_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_GPIO_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for GPIO. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | GPIO_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_gpio_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_GPIO_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for GPIO is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | GPIO_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_gpio_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_GPIO_HCLK) == (MCU_SUB_FORCE_GPIO_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for DMA. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | DMA_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_dma_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_DMA_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for DMA. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | DMA_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_dma_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_DMA_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for DMA is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | DMA_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_dma_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_DMA_HCLK) == (MCU_SUB_FORCE_DMA_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for BLE Bridge. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | BLE_BRG_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_ble_brg_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_BLE_BRG_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for BLE Bridge. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | BLE_BRG_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_ble_brg_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_BLE_BRG_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for BLE Bridge is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | BLE_BRG_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_ble_brg_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_BLE_BRG_HCLK) == (MCU_SUB_FORCE_BLE_BRG_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for APB Subsystem. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | APB_SUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_apb_sub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_APB_SUB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for APB Subsystem. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | APB_SUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_apb_sub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_APB_SUB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for APB Subsystem is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | APB_SUB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_apb_sub_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_APB_SUB_HCLK) == (MCU_SUB_FORCE_APB_SUB_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for serial blocks(including I2C, UART, QSPI, I2S, SPI). + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SERIAL_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_serial_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SERIAL_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for serial blocks(including I2C, UART, QSPI, I2S, SPI). + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SERIAL_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_serial_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SERIAL_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for serial blocks(including I2C, UART, QSPI, I2S, SPI) is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | SERIAL_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_serial_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_SERIAL_HCLK) == (MCU_SUB_FORCE_SERIAL_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for I2S slave. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | I2S_S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_i2s_s_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_I2S_S_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for I2S slave. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | I2S_S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_i2s_s_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_I2S_S_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for I2S slave is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_1 | I2S_S_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_i2s_s_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[1], MCU_SUB_FORCE_I2S_S_HCLK) == (MCU_SUB_FORCE_I2S_S_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for AON_MUCSUB. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_aon_mcusub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_AON_MCUSUB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for AON_MUCSUB. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_aon_mcusub_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_AON_MCUSUB_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for AON_MUCSUB is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | AON_MCUSUB_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_aon_mcusub_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_AON_MCUSUB_HCLK) == (MCU_SUB_FORCE_AON_MCUSUB_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for XQSPI. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_xqspi_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_XF_XQSPI_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for XQSPI. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_xqspi_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_XF_XQSPI_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for XQSPI is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | XF_XQSPI_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_xqspi_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_XF_XQSPI_HCLK) == (MCU_SUB_FORCE_XF_XQSPI_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for SRAM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_sram_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_SRAM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for SRAM. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_sram_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_SRAM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for SRAM is forced to close. + * + * Register | BitsName + * ----------|-------- + * CG_CTRL_2 | SRAM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_sram_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_SUBSYS_CG_CTRL[2], MCU_SUB_FORCE_SRAM_HCLK) == (MCU_SUB_FORCE_SRAM_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for UART0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_uart0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for UART0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_uart0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for UART0 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART0_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_uart0_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART0_HCLK) == (MCU_SUB_FORCE_UART0_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for UART1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_uart1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for UART1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_uart1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for UART1 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | UART1_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_uart1_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_UART1_HCLK) == (MCU_SUB_FORCE_UART1_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for I2C0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_i2c0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for I2C0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_i2c0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for I2C0 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C0_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_i2c0_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C0_HCLK) == (MCU_SUB_FORCE_I2C0_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for I2C1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_i2c1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for I2C1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_i2c1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for I2C1 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2C1_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_i2c1_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2C1_HCLK) == (MCU_SUB_FORCE_I2C1_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for SPIM. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_spim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for SPIM. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIM_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_spim_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIM_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for SPIM is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIM_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_spim_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIM_HCLK) == (MCU_SUB_FORCE_SPIM_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for SPIS. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIS_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_spis_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIS_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for SPIS. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIS_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_spis_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIS_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for SPIS is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | SPIS_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_spis_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SPIS_HCLK) == (MCU_SUB_FORCE_SPIS_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for QSPI0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_qspi0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for QSPI0. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI0_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_qspi0_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI0_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for QSPI0 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI0_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_qspi0_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI0_HCLK) == (MCU_SUB_FORCE_QSPI0_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for QSPI1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_qspi1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for QSPI1. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI1_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_qspi1_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI1_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for QSPI1 is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | QSPI1_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_qspi1_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_QSPI1_HCLK) == (MCU_SUB_FORCE_QSPI1_HCLK)); +} + +/** + * @brief Enabling force to turn off the clock for I2S master. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_i2s_m_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2S_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the clock for I2S master. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_i2s_m_hclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2S_HCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the clock for I2S master is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_i2s_m_hclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_I2S_HCLK) == (MCU_SUB_FORCE_I2S_HCLK)); +} + +/** + * @brief Enabling force to turn off the div4 clock for security blocks. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_enable_force_off_secu_div4_pclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + SET_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SECU_DIV4_PCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disabling force to turn off the div4 clock for security blocks. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval None + */ +__STATIC_INLINE void ll_cgc_disable_force_off_secu_div4_pclk(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + + CLEAR_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SECU_DIV4_PCLK); + + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Indicate whether the div4 clock for security blocks is forced to close. + * + * Register | BitsName + * ----------|-------- + * PERIPH_GC | I2S_HCLK + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_cgc_is_enabled_force_off_secu_div4_pclk(void) +{ + return (READ_BITS(MCU_SUB->MCU_PERIPH_CG, MCU_SUB_FORCE_SECU_DIV4_PCLK) == (MCU_SUB_FORCE_SECU_DIV4_PCLK)); +} + + +/** @} */ + +/** @defgroup CGC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize CGC registers (Registers restored to their default values). + * @retval An error_status_t enumeration value: + * - SUCCESS: CGC registers are de-initialized + * - ERROR: CGC registers are not de-initialized + */ +error_status_t ll_cgc_deinit(void); + +/** + * @brief Initialize CGC registers according to the specified. + * parameters in p_cgc_init. + * @param p_cgc_init Pointer to a ll_cgc_init_t structure that contains the configuration + * information for the specified CGC register. + * @retval An error_status_t enumeration value: + * - SUCCESS: CGC registers are initialized according to p_cgc_init content + * - ERROR: Problem occurred during CGC Registers initialization + */ +error_status_t ll_cgc_init(ll_cgc_init_t *p_cgc_init); + +/** + * @brief Set each field of a @ref ll_cgc_init_t type structure to default value. + * @param p_cgc_init Pointer to a @ref ll_cgc_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_cgc_struct_init(ll_cgc_init_t *p_cgc_init); + +/** @} */ + +/** @} */ + + +#endif /* CGC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_CGC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_comp.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_comp.h new file mode 100644 index 0000000..5d1dd21 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_comp.h @@ -0,0 +1,413 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_comp.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of COMP LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_COMP COMP + * @brief COMP LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_COMP_H__ +#define __GR55XX_LL_COMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** @defgroup COMP_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup COMP_LL_ES_INIT COMP Exported init structures + * @{ + */ + +/** + * @brief LL COMP init Structure definition + */ +typedef struct _ll_comp_init +{ + uint32_t input_source; /**< Specifies the input source for the comparator. + This parameter can be any value of @ref COMP_LL_EC_INPUT_SRC. + + This parameter can be modified afterwards using unitary function @ref ll_comp_set_input_src(). */ + + uint32_t ref_source; /**< Specifies the reference source for the comparator. + This parameter can be any value of @ref COMP_LL_EC_INPUT_SRC. + + This parameter can be modified afterwards using unitary function @ref ll_comp_set_ref_src(). */ + uint32_t ref_value; /*!< Specifies the value of the COMP buffered reference. + If ref_source select to LL_COMP_REF_SRC_VBAT, this parameter can be a value between: 0 ~ 7. + This parameter can be modified afterwards using unitary function @ref ll_comp_set_vbatt_lvl(). + + If ref_source select to LL_COMP_REF_SRC_VREF, this parameter can be a value between: 0 ~ 63. + This parameter can be modified afterwards using unitary function @ref ll_comp_set_vref_lvl(). */ +} ll_comp_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup COMP_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Constants COMP Exported Constants + * @{ + */ + +/** @defgroup COMP_LL_EC_INPUT_SRC COMP INPUT SOURCE + * @{ + */ +#define LL_COMP_INPUT_SRC_IO0 (0UL << AON_RF_REG_10_CHANNEL_SEL_P_Pos) /**< Set MSIO_0 as inputs for the comparator */ +#define LL_COMP_INPUT_SRC_IO1 (1UL << AON_RF_REG_10_CHANNEL_SEL_P_Pos) /**< Set MSIO_1 as inputs for the comparator */ +#define LL_COMP_INPUT_SRC_IO2 (2UL << AON_RF_REG_10_CHANNEL_SEL_P_Pos) /**< Set MSIO_2 as inputs for the comparator */ +#define LL_COMP_INPUT_SRC_IO3 (3UL << AON_RF_REG_10_CHANNEL_SEL_P_Pos) /**< Set MSIO_3 as inputs for the comparator */ +#define LL_COMP_INPUT_SRC_IO4 (4UL << AON_RF_REG_10_CHANNEL_SEL_P_Pos) /**< Set MSIO_4 as inputs for the comparator */ +/** @} */ + +/** @defgroup COMP_LL_EC_REF_SRC COMP REF SOURCE + * @{ + */ +#define LL_COMP_REF_SRC_IO0 (0UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set MSIO_0 as references for the comparator */ +#define LL_COMP_REF_SRC_IO1 (1UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set MSIO_1 as references for the comparator */ +#define LL_COMP_REF_SRC_IO2 (2UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set MSIO_2 as references for the comparator */ +#define LL_COMP_REF_SRC_IO3 (3UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set MSIO_3 as references for the comparator */ +#define LL_COMP_REF_SRC_IO4 (4UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set MSIO_4 as references for the comparator */ +#define LL_COMP_REF_SRC_VBAT (6UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set VBATT as references for the comparator */ +#define LL_COMP_REF_SRC_VREF (7UL << AON_RF_REG_10_CHANNEL_SEL_N_Pos) /**< Set VREF as references for the comparator */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Macros COMP Exported Macros + * @{ + */ + +/** @defgroup COMP_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in COMP register + * @param __instance__ COMP instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_COMP_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG((__instance__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in COMP register + * @param __instance__ COMP instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_COMP_ReadReg(__instance__, __REG__) READ_REG((__instance__)->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup COMP_LL_Private_Macros COMP Private Macros + * @{ + */ + +/** @defgroup COMP_LL_EC_DEFAULT_CONFIG InitStruct default configuartion + * @{ + */ + +/** + * @brief Default configuartion for initializing structure + */ +#define LL_COMP_DEFAULT_CONFIG \ +{ \ + .channel_p = LL_COMP_CHANNEL_IO0, \ + .channel_n = LL_COMP_CHANNEL_IO1, \ +} +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup COMP_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup COMP_LL_EF_Configuration Basic Configuration + * @{ + */ + +/** + * @brief Enable COMP module. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | COMP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_comp_enable(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL_MSIO_COMP); + SET_BITS(AON->RF_REG_10, AON_RF_REG_10_WAKE_COMP_EN_Msk); +} + +/** + * @brief Disable COMP module. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | COMP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_comp_disable(void) +{ + CLEAR_BITS(AON->RF_REG_10, AON_RF_REG_10_WAKE_COMP_EN_Msk); + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL_MSIO_COMP); +} + +/** + * @brief Set channel of COMP input source. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | AON_RF_REG_10_CHANNEL_SEL_P | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param source This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_SRC_IO0 + * @arg @ref LL_COMP_INPUT_SRC_IO1 + * @arg @ref LL_COMP_INPUT_SRC_IO2 + * @arg @ref LL_COMP_INPUT_SRC_IO3 + * @arg @ref LL_COMP_INPUT_SRC_IO4 + * @retval None + */ +__STATIC_INLINE void ll_comp_set_input_src(uint32_t source) +{ + MODIFY_REG(AON->RF_REG_10, AON_RF_REG_10_CHANNEL_SEL_P_Msk, source); +} + +/** + * @brief Set channel of COMP reference source. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | AON_RF_REG_10_CHANNEL_SEL_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param source This parameter can be one of the following values: + * @arg @ref LL_COMP_REF_SRC_IO0 + * @arg @ref LL_COMP_REF_SRC_IO1 + * @arg @ref LL_COMP_REF_SRC_IO2 + * @arg @ref LL_COMP_REF_SRC_IO3 + * @arg @ref LL_COMP_REF_SRC_IO4 + * @arg @ref LL_COMP_REF_SRC_VBAT + * @arg @ref LL_COMP_REF_SRC_VREF + * @retval None + */ +__STATIC_INLINE void ll_comp_set_ref_src(uint32_t source) +{ + MODIFY_REG(AON->RF_REG_10, AON_RF_REG_10_CHANNEL_SEL_N_Msk, source); +} + +/** + * @brief Set VBATT control level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | BATT_LVL_CTRL_LV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param level This parameter can be a value between: 0 ~ 7 + * Vbatt_ref = ((level+1)/10) * VBATT + * @retval None + */ +__STATIC_INLINE void ll_comp_set_vbatt_lvl(uint32_t level) +{ + MODIFY_REG(AON->RF_REG_10, AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Msk, level << AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Pos); +} + +/** + * @brief Set VREF control level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RF_REG_10 | COMP_REF_CTRL_LV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param level This parameter can be a value between: 0 ~ 63 + * Vref = 30mv * level + * @retval None + */ +__STATIC_INLINE void ll_comp_set_vref_lvl(uint32_t level) +{ + MODIFY_REG(AON->RF_REG_10, AON_RF_REG_10_COMP_REF_CTRL_LV_Msk, level << AON_RF_REG_10_COMP_REF_CTRL_LV_Pos); +} + +/** + * @brief Indicate if the COMP Interrupt Flag is set or not. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | MSIO_COMP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or o). + */ +__STATIC_INLINE uint32_t ll_comp_is_active_flag_it(void) +{ + return (READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_PMU_MSIO_COMP) == AON_SLP_EVENT_PMU_MSIO_COMP); +} + +/** + * @brief Clear Interrupt Status flag for COMP. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | MSIO_COMP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None. + */ +__STATIC_INLINE void ll_comp_clear_flag_it(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->SLP_EVENT, AON_SLP_EVENT_PMU_MSIO_COMP); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** @} */ + +/** @defgroup COMP_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize COMP registers (Registers restored to their default values). + * @retval An error_status_t enumeration value: + * - SUCCESS: COMP registers are de-initialized + * - ERROR: COMP registers are not de-initialized + */ +error_status_t ll_comp_deinit(void); + +/** + * @brief Initialize COMP registers according to the specified. + * parameters in p_comp_init. + * @param p_comp_init Pointer to a ll_comp_init_t structure that contains the configuration + * information for the specified COMP peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: COMP registers are initialized according to p_comp_init content + * - ERROR: Problem occurred during COMP Registers initialization + */ +error_status_t ll_comp_init(ll_comp_init_t *p_comp_init); + +/** + * @brief Set each field of a @ref ll_comp_init_t type structure to default value. + * @param p_comp_init Pointer to a @ref ll_comp_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_comp_struct_init(ll_comp_init_t *p_comp_init); + +/** @} */ + +/** @} */ + +#endif /* AON */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_COMP_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dma.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dma.h new file mode 100644 index 0000000..5ea6cfc --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dma.h @@ -0,0 +1,4627 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_dma.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of DMA LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_DMA DMA + * @brief DMA LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_DMA_H__ +#define __GR55xx_LL_DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (DMA) + +/** @defgroup DMA_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DMA_LL_ES_INIT DMA Exported init structures + * @{ + */ + +/** + * @brief LL DMA init Structure definition + */ +typedef struct _ll_dma_init +{ + uint32_t src_address; /**< Specifies the Source base address for DMA transfer. + + This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */ + + uint32_t dst_address; /**< Specifies the Destination base address for DMA transfer. + + This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */ + + uint32_t direction; /**< Specifies if the data will be transferred from memory to peripheral, + from memory to memory or from peripheral to memory or form peripheral to peripheral. + This parameter can be a value of @ref DMA_LL_EC_DIRECTION + + This feature can be modified afterwards using unitary function @ref ll_dma_set_data_transfer_direction(). */ + + uint32_t mode; /**< Specifies the Single block or Multi-block operation mode. + This parameter can be a value of @ref DMA_LL_EC_MODE + @note: The circular buffer mode cannot be used if the memory to memory + data transfer direction is configured on the selected Channel + + This feature can be modified afterwards using unitary function @ref ll_dma_set_mode(). */ + + uint32_t src_increment_mode; /**< Specifies whether the Source address is incremented or decrement or not. + This parameter can be a value of @ref DMA_LL_EC_SOURCE + + This feature can be modified afterwards using unitary function @ref ll_dma_set_source_increment_mode(). */ + + uint32_t dst_increment_mode; /**< Specifies whether the Destination address is incremented or decrement or not. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION + + This feature can be modified afterwards using unitary function @ref ll_dma_set_destination_increment_mode(). */ + + uint32_t src_data_width; /**< Specifies the Souce transfer width alignment(byte, half word, word). + This parameter can be a value of @ref DMA_LL_EC_SDATAALIGN + + This feature can be modified afterwards using unitary function @ref ll_dma_set_source_width(). */ + + uint32_t dst_data_width; /**< Specifies the Destination transfer width alignment(byte, half word, word). + This parameter can be a value of @ref DMA_LL_EC_DDATAALIGN + + This feature can be modified afterwards using unitary function @ref ll_dma_set_destination_width(). */ + + uint32_t block_size; /**< Specifies the number of data to transfer, in data unit. + The data unit is equal to the source buffer configuration set in src_data_width parameters. + This parameter must be a value between Min_Data = 0 and Max_Data = 0x1FF + + This feature can be modified afterwards using unitary function @ref ll_dma_set_block_size(). */ + + uint32_t src_peripheral; /**< Specifies the Source peripheral type. + This parameter can be a value of @ref DMA_LL_EC_PERIPH + + This feature can be modified afterwards using unitary function @ref ll_dma_set_source_peripheral(). */ + + uint32_t dst_peripheral; /**< Specifies the Destination peripheral type. + This parameter can be a value of @ref DMA_LL_EC_PERIPH + + This feature can be modified afterwards using unitary function @ref ll_dma_set_destination_peripheral(). */ + + uint32_t priority; /**< Specifies the channel priority level. + This parameter can be a value of @ref DMA_LL_EC_PRIORITY + + This feature can be modified afterwards using unitary function @ref ll_dma_set_channel_priority_level(). */ + +} ll_dma_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup DMA_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA_LL_Exported_Constants DMA Exported Constants + * @{ + */ + +/** @defgroup DMA_LL_EC_CHANNEL CHANNEL + * @{ + */ +#define LL_DMA_CHANNEL_0 ((uint32_t)0x00000000U) /**< DMA Channel 0 */ +#define LL_DMA_CHANNEL_1 ((uint32_t)0x00000001U) /**< DMA Channel 1 */ +#define LL_DMA_CHANNEL_2 ((uint32_t)0x00000002U) /**< DMA Channel 2 */ +#define LL_DMA_CHANNEL_3 ((uint32_t)0x00000003U) /**< DMA Channel 3 */ +#define LL_DMA_CHANNEL_4 ((uint32_t)0x00000004U) /**< DMA Channel 4 */ +#define LL_DMA_CHANNEL_5 ((uint32_t)0x00000005U) /**< DMA Channel 5 */ +#define LL_DMA_CHANNEL_6 ((uint32_t)0x00000006U) /**< DMA Channel 6 */ +#define LL_DMA_CHANNEL_7 ((uint32_t)0x00000007U) /**< DMA Channel 7 */ +#define LL_DMA_CHANNEL_ALL ((uint32_t)0xFFFF0000U) /**< DMA Channel all (used only for function @ref ll_dma_deinit(). */ +/** @} */ + +/** @defgroup DMA_LL_EC_DIRECTION Transfer Direction + * @{ + */ +#define LL_DMA_DIRECTION_MEMORY_TO_MEMORY DMA_CTLL_TT_FC_M2M /**< Memory to memory direction */ +#define LL_DMA_DIRECTION_MEMORY_TO_PERIPH DMA_CTLL_TT_FC_M2P /**< Memory to peripheral direction */ +#define LL_DMA_DIRECTION_PERIPH_TO_MEMORY DMA_CTLL_TT_FC_P2M /**< Peripheral to memory direction */ +#define LL_DMA_DIRECTION_PERIPH_TO_PERIPH DMA_CTLL_TT_FC_P2P /**< Peripheral to Peripheral direction */ +/** @} */ + + +/** @defgroup DMA_LL_EC_MODE Transfer mode + * @{ + */ +#define LL_DMA_MODE_SINGLE_BLOCK ((uint32_t)0x00000000U) /**< Single block */ +#define LL_DMA_MODE_MULTI_BLOCK_SRC_RELOAD DMA_CFGL_RELOAD_SRC /**< Multi-block: src address reload, dst address contiguous */ +#define LL_DMA_MODE_MULTI_BLOCK_DST_RELOAD DMA_CFGL_RELOAD_DST /**< Multi-block: src address contiguous, dst address reload */ +#define LL_DMA_MODE_MULTI_BLOCK_ALL_RELOAD (DMA_CFGL_RELOAD_SRC | DMA_CFGL_RELOAD_DST) /**< Multi-block: src address reload, dst address reload */ +/** @} */ + +/** @defgroup DMA_LL_EC_SOURCE Source increment mode + * @{ + */ +#define LL_DMA_SRC_INCREMENT DMA_CTLL_SINC_INC /**< Source Address increment */ +#define LL_DMA_SRC_DECREMENT DMA_CTLL_SINC_DEC /**< Source Address decrement */ +#define LL_DMA_SRC_NO_CHANGE DMA_CTLL_SINC_NO /**< Source Address no change */ +/** @} */ + +/** @defgroup DMA_LL_EC_DESTINATION Destination increment mode + * @{ + */ +#define LL_DMA_DST_INCREMENT DMA_CTLL_DINC_INC /**< Destination Address increment */ +#define LL_DMA_DST_DECREMENT DMA_CTLL_DINC_DEC /**< Destination Address decrement */ +#define LL_DMA_DST_NO_CHANGE DMA_CTLL_DINC_NO /**< Destination Address no change */ +/** @} */ + +/** @defgroup DMA_LL_EC_SRC_BURST Source burst transaction length + * @{ + */ +#define LL_DMA_SRC_BURST_LENGTH_1 DMA_CTLL_SRC_MSIZE_1 /**< Source Burst length: 1 word */ +#define LL_DMA_SRC_BURST_LENGTH_4 DMA_CTLL_SRC_MSIZE_4 /**< Source Burst length: 4 words */ +#define LL_DMA_SRC_BURST_LENGTH_8 DMA_CTLL_SRC_MSIZE_8 /**< Source Burst length: 8 words */ +#define LL_DMA_SRC_BURST_LENGTH_16 DMA_CTLL_SRC_MSIZE_16 /**< Source Burst length: 16 words */ +#define LL_DMA_SRC_BURST_LENGTH_32 DMA_CTLL_SRC_MSIZE_32 /**< Source Burst length: 32 words */ +#define LL_DMA_SRC_BURST_LENGTH_64 DMA_CTLL_SRC_MSIZE_64 /**< Source Burst length: 64 words */ +/** @} */ + +/** @defgroup DMA_LL_EC_DST_BURST Destination burst transaction length + * @{ + */ +#define LL_DMA_DST_BURST_LENGTH_1 DMA_CTLL_DST_MSIZE_1 /**< Destination Burst length: 1 word */ +#define LL_DMA_DST_BURST_LENGTH_4 DMA_CTLL_DST_MSIZE_4 /**< Destination Burst length: 4 words */ +#define LL_DMA_DST_BURST_LENGTH_8 DMA_CTLL_DST_MSIZE_8 /**< Destination Burst length: 8 words */ +#define LL_DMA_DST_BURST_LENGTH_16 DMA_CTLL_DST_MSIZE_16 /**< Destination Burst length: 16 words */ +#define LL_DMA_DST_BURST_LENGTH_32 DMA_CTLL_DST_MSIZE_32 /**< Destination Burst length: 32 words */ +#define LL_DMA_DST_BURST_LENGTH_64 DMA_CTLL_DST_MSIZE_64 /**< Destination Burst length: 64 words */ +/** @} */ + +/** @defgroup DMA_LL_EC_SDATAALIGN Source data alignment + * @{ + */ +#define LL_DMA_SDATAALIGN_BYTE DMA_CTLL_SRC_TR_WIDTH_8 /**< Source data alignment : Byte */ +#define LL_DMA_SDATAALIGN_HALFWORD DMA_CTLL_SRC_TR_WIDTH_16 /**< Source data alignment : HalfWord */ +#define LL_DMA_SDATAALIGN_WORD DMA_CTLL_SRC_TR_WIDTH_32 /**< Source data alignment : Word */ +/** @} */ + +/** @defgroup DMA_LL_EC_DDATAALIGN Destination data alignment + * @{ + */ +#define LL_DMA_DDATAALIGN_BYTE DMA_CTLL_DST_TR_WIDTH_8 /**< Destination data alignment : Byte */ +#define LL_DMA_DDATAALIGN_HALFWORD DMA_CTLL_DST_TR_WIDTH_16 /**< Destination data alignment : HalfWord */ +#define LL_DMA_DDATAALIGN_WORD DMA_CTLL_DST_TR_WIDTH_32 /**< Destination data alignment : Word */ +/** @} */ + +/** @defgroup DMA_LL_EC_PRIORITY Transfer Priority level + * @{ + */ +#define LL_DMA_PRIORITY_0 DMA_CFGL_CH_PRIOR_0 /**< Priority level : 0 */ +#define LL_DMA_PRIORITY_1 DMA_CFGL_CH_PRIOR_1 /**< Priority level : 1 */ +#define LL_DMA_PRIORITY_2 DMA_CFGL_CH_PRIOR_2 /**< Priority level : 2 */ +#define LL_DMA_PRIORITY_3 DMA_CFGL_CH_PRIOR_3 /**< Priority level : 3 */ +#define LL_DMA_PRIORITY_4 DMA_CFGL_CH_PRIOR_4 /**< Priority level : 4 */ +#define LL_DMA_PRIORITY_5 DMA_CFGL_CH_PRIOR_5 /**< Priority level : 5 */ +#define LL_DMA_PRIORITY_6 DMA_CFGL_CH_PRIOR_6 /**< Priority level : 6 */ +#define LL_DMA_PRIORITY_7 DMA_CFGL_CH_PRIOR_7 /**< Priority level : 7 */ +/** @} */ + +/** @defgroup DMA_LL_EC_SHANDSHAKING Source handshake interface + * @{ + */ +#define LL_DMA_SHANDSHAKING_HW ((uint32_t)0x00000000U) /**< Source: hardware handshake */ +#define LL_DMA_SHANDSHAKING_SW DMA_CFGL_HS_SEL_SRC /**< Source: software handshake */ +/** @} */ + +/** @defgroup DMA_LL_EC_DHANDSHAKING Destination handshake interface + * @{ + */ +#define LL_DMA_DHANDSHAKING_HW ((uint32_t)0x00000000U) /**< Destination: hardware handshake */ +#define LL_DMA_DHANDSHAKING_SW DMA_CFGL_HS_SEL_DST /**< Destination: software handshake */ +/** @} */ + +/** @defgroup DMA_LL_EC_PERIPH DMA Peripheral type + * @{ + */ +#define LL_DMA_PERIPH_SPIM_TX ((uint32_t)0x00000000U) /**< DMA Peripheral type is SPIM TX */ +#define LL_DMA_PERIPH_SPIM_RX ((uint32_t)0x00000001U) /**< DMA Peripheral type is SPIM RX */ +#define LL_DMA_PERIPH_SPIS_TX ((uint32_t)0x00000002U) /**< DMA Peripheral type is SPIS TX */ +#define LL_DMA_PERIPH_SPIS_RX ((uint32_t)0x00000003U) /**< DMA Peripheral type is SPIS RX */ +#define LL_DMA_PERIPH_QSPI0_TX ((uint32_t)0x00000004U) /**< DMA Peripheral type is QSPI0 TX */ +#define LL_DMA_PERIPH_QSPI0_RX ((uint32_t)0x00000005U) /**< DMA Peripheral type is QSPI0 RX */ +#define LL_DMA_PERIPH_I2C0_TX ((uint32_t)0x00000006U) /**< DMA Peripheral type is I2C0 TX */ +#define LL_DMA_PERIPH_I2C0_RX ((uint32_t)0x00000007U) /**< DMA Peripheral type is I2C0 RX */ +#define LL_DMA_PERIPH_I2C1_TX ((uint32_t)0x00000008U) /**< DMA Peripheral type is I2C1 TX */ +#define LL_DMA_PERIPH_I2C1_RX ((uint32_t)0x00000009U) /**< DMA Peripheral type is I2C1 RX */ +#define LL_DMA_PERIPH_I2S_S_TX ((uint32_t)0x00000008U) /**< DMA Peripheral type is I2S_S TX */ +#define LL_DMA_PERIPH_I2S_S_RX ((uint32_t)0x00000009U) /**< DMA Peripheral type is I2S_S RX */ +#define LL_DMA_PERIPH_UART0_TX ((uint32_t)0x0000000AU) /**< DMA Peripheral type is UART0 TX */ +#define LL_DMA_PERIPH_UART0_RX ((uint32_t)0x0000000BU) /**< DMA Peripheral type is UART0 RX */ +#define LL_DMA_PERIPH_QSPI1_TX ((uint32_t)0x0000000CU) /**< DMA peripheral type is QSPI1 TX */ +#define LL_DMA_PERIPH_QSPI1_RX ((uint32_t)0x0000000DU) /**< DMA peripheral type is QSPI1 RX */ +#define LL_DMA_PERIPH_I2S_M_TX ((uint32_t)0x0000000CU) /**< DMA Peripheral type is I2S_M TX */ +#define LL_DMA_PERIPH_I2S_M_RX ((uint32_t)0x0000000DU) /**< DMA Peripheral type is I2S_M RX */ +#define LL_DMA_PERIPH_SNSADC ((uint32_t)0x0000000EU) /**< DMA peripheral type is SNSADC */ +#define LL_DMA_PERIPH_MEM ((uint32_t)0x0000000FU) /**< DMA peripheral type is Memory */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA_LL_Exported_Macros DMA Exported Macros + * @{ + */ + +/** @defgroup DMA_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in DMA register + * @param __instance__ DMA instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DMA_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__.__REG__, (__VALUE__)) + +/** + * @brief Read a value in DMA register + * @param __instance__ DMA instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DMA_ReadReg(__instance__, __REG__) READ_REG(__instance__.__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DMA_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup DMA_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable DMA Module. + * @note This function is used to enable the DMA Module, which must be done before any + * channel activity can begin. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_REG | CFG_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @retval None + */ +__STATIC_INLINE void ll_dma_enable(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->MISCELLANEOU.CFG, DMA_MODULE_CFG_EN); +} + +/** + * @brief Disable DMA Module. + * @note If the ll_dma_disable() function is called while any dma channel is still active, + * the ll_dma_is_enable() function still return 1 to indicate that there are channels + * still active until hardware has terminated all cativity on all channels, at which + * point the ll_dma_is_enable() function returns 0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_REG | CFG_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @retval None + */ +__STATIC_INLINE void ll_dma_disable(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->MISCELLANEOU.CFG, 0); +} + +/** + * @brief Check if DMA Module is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_REG | CFG_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->MISCELLANEOU.CFG, DMA_MODULE_CFG_EN) == DMA_MODULE_CFG_EN); +} + +/** + * @brief Enable DMA channel. + * @note When the DMA Module is disabled, then call this function to DMA_CFG_REG register + * is ignored and call ll_dma_disable_channel() function will always returns 0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CH_EN_REG | CH_EN_WE&CH_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_channel(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->MISCELLANEOU.CH_EN, (1 << (channel + DMA_CH_WE_EN_Pos)) + (1 << channel)); +} + +/** + * @brief Disable DMA channel. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CH_EN_REG | CH_EN_WE&CH_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_channel(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->MISCELLANEOU.CH_EN, (1 << (channel + DMA_CH_WE_EN_Pos))); +} + +/** + * @brief Check if DMA channel is enabled or disabled. + * @note Software can therefore poll this function to determine when channel is free + * for a new DMA transfer. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CH_EN_REG | CH_EN_WE&CH_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enabled_channel(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->MISCELLANEOU.CH_EN, (1 << channel)) ? 1 : 0; +} + +/** + * @brief Suspend a DMA channel transfer. + * @note Suspends all DMA data transfers from the source until the ll_dma_resume_channel() + * function is called. The function may be called after enabling the DMA channel. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFGL | CH_SUSP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_suspend_channel(dma_regs_t *DMAx, uint32_t channel) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_CH_SUSP, DMA_CFGL_CH_SUSP); +} + +/** + * @brief Resume a DMA channel. + * @note The function may be called after enabling the DMA channel. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFGL | CH_SUSP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_resume_channel(dma_regs_t *DMAx, uint32_t channel) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_CH_SUSP, 0); +} + +/** + * @brief Check if DMA channel is suspended or resumed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFGL | CH_SUSP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_suspended(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_CH_SUSP) == DMA_CFGL_CH_SUSP); +} + +/** + * @brief Check if DMA channel FIFO is empty. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFGL | FIFO_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_empty_fifo(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_FIFO_EMPTY) == DMA_CFGL_FIFO_EMPTY); +} + +/** + * @brief Configure all parameters link to DMA transfer. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CCR | DIR | + * +----------------------+-----------------------------------+ + * \endrst + * CCR | MEM2MEM + * CCR | CIRC + * CCR | PINC + * CCR | MINC + * CCR | PSIZE + * CCR | MSIZE + * CCR | PL + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_MODE_SINGLE_BLOCK or @ref LL_DMA_MODE_MULTI_BLOCK_SRC_RELOAD or @ref LL_DMA_MODE_MULTI_BLOCK_DST_RELOAD or @ref LL_DMA_MODE_MULTI_BLOCK_ALL_RELOAD + * @arg @ref LL_DMA_SRC_INCREMENT or @ref LL_DMA_SRC_DECREMENT or @ref LL_DMA_SRC_NO_CHANGE + * @arg @ref LL_DMA_DST_INCREMENT or @ref LL_DMA_DST_DECREMENT or @ref LL_DMA_DST_NO_CHANGE + * @arg @ref LL_DMA_SDATAALIGN_BYTE or @ref LL_DMA_SDATAALIGN_HALFWORD or @ref LL_DMA_SDATAALIGN_WORD + * @arg @ref LL_DMA_DDATAALIGN_BYTE or @ref LL_DMA_DDATAALIGN_HALFWORD or @ref LL_DMA_DDATAALIGN_WORD + * @arg @ref LL_DMA_SRC_BURST_LENGTH_1 or @ref LL_DMA_SRC_BURST_LENGTH_4 or @ref LL_DMA_SRC_BURST_LENGTH_8 + * @arg @ref LL_DMA_DST_BURST_LENGTH_1 or @ref LL_DMA_DST_BURST_LENGTH_4 or @ref LL_DMA_DST_BURST_LENGTH_8 + * @retval None + */ +__STATIC_INLINE void ll_dma_config_transfer(dma_regs_t *DMAx, uint32_t channel, uint32_t configuration) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DST_TR_WIDTH | DMA_CTLL_SRC_TR_WIDTH |\ + DMA_CTLL_DINC | DMA_CTLL_SINC | DMA_CTLL_DST_MSIZE | DMA_CTLL_SRC_MSIZE | DMA_CTLL_TT_FC, + configuration); +} + +/** + * @brief Set Data transfer direction (read from peripheral or from memory). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | TT_FC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param direction This parameter can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_PERIPH + * @retval None + */ +__STATIC_INLINE void ll_dma_set_data_transfer_direction(dma_regs_t *DMAx, uint32_t channel, uint32_t direction) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_TT_FC, direction); +} + +/** + * @brief Get Data transfer direction (read from peripheral or from memory). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | TT_FC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_PERIPH + */ +__STATIC_INLINE uint32_t ll_dma_get_data_transfer_direction(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_TT_FC); +} + +/** + * @brief Set DMA mode Single block or Multi block. + * @note The circular buffer mode cannot be used if the memory-to-memory + * data transfer is configured on the selected Channel. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_LO | RELOAD_DST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param mode This parameter can be one of the following values: + * @arg @ref LL_DMA_MODE_SINGLE_BLOCK + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_SRC_RELOAD + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_DST_RELOAD + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_ALL_RELOAD + * @retval None + */ +__STATIC_INLINE void ll_dma_set_mode(dma_regs_t *DMAx, uint32_t channel, uint32_t mode) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_RELOAD_DST | DMA_CFGL_RELOAD_SRC, mode); +} + + +/** + * @brief Get DMA mode circular or normal. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_LO | RELOAD_DST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_MODE_SINGLE_BLOCK + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_SRC_RELOAD + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_DST_RELOAD + * @arg @ref LL_DMA_MODE_MULTI_BLOCK_ALL_RELOAD + */ +__STATIC_INLINE uint32_t ll_dma_get_mode(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_RELOAD_DST | DMA_CFGL_RELOAD_SRC); +} + +/** + * @brief Set Source increment mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SINC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param src_increment_mode This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_INCREMENT + * @arg @ref LL_DMA_SRC_DECREMENT + * @arg @ref LL_DMA_SRC_NO_CHANGE + * @retval None + */ +__STATIC_INLINE void ll_dma_set_source_increment_mode(dma_regs_t *DMAx, uint32_t channel, uint32_t src_increment_mode) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SINC, src_increment_mode); +} + +/** + * @brief Get Source increment mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SINC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_INCREMENT + * @arg @ref LL_DMA_SRC_DECREMENT + * @arg @ref LL_DMA_SRC_NO_CHANGE + */ +__STATIC_INLINE uint32_t ll_dma_get_source_increment_mode(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SINC); +} + +/** + * @brief Set Destination increment mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DINC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param dst_increment_mode This parameter can be one of the following values: + * @arg @ref LL_DMA_DST_INCREMENT + * @arg @ref LL_DMA_DST_DECREMENT + * @arg @ref LL_DMA_DST_NO_CHANGE + * @retval None + */ +__STATIC_INLINE void ll_dma_set_destination_increment_mode(dma_regs_t *DMAx, uint32_t channel, uint32_t dst_increment_mode) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DINC, dst_increment_mode); +} + +/** + * @brief Get Destination increment mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DINC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DST_INCREMENT + * @arg @ref LL_DMA_DST_DECREMENT + * @arg @ref LL_DMA_DST_NO_CHANGE + */ +__STATIC_INLINE uint32_t ll_dma_get_destination_increment_mode(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DINC); +} + +/** + * @brief Set Source transfer width. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SRC_TR_WIDTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param src_width This parameter can be one of the following values: + * @arg @ref LL_DMA_SDATAALIGN_BYTE + * @arg @ref LL_DMA_SDATAALIGN_HALFWORD + * @arg @ref LL_DMA_SDATAALIGN_WORD + * @retval None + */ +__STATIC_INLINE void ll_dma_set_source_width(dma_regs_t *DMAx, uint32_t channel, uint32_t src_width) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SRC_TR_WIDTH, src_width); +} + +/** + * @brief Get Source transfer width. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SRC_TR_WIDTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SDATAALIGN_BYTE + * @arg @ref LL_DMA_SDATAALIGN_HALFWORD + * @arg @ref LL_DMA_SDATAALIGN_WORD + */ +__STATIC_INLINE uint32_t ll_dma_get_source_width(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SRC_TR_WIDTH); +} + +/** + * @brief Set Destination transfer width. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DST_TR_WIDTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param dst_width This parameter can be one of the following values: + * @arg @ref LL_DMA_DDATAALIGN_BYTE + * @arg @ref LL_DMA_DDATAALIGN_HALFWORD + * @arg @ref LL_DMA_DDATAALIGN_WORD + * @retval None + */ +__STATIC_INLINE void ll_dma_set_destination_width(dma_regs_t *DMAx, uint32_t channel, uint32_t dst_width) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DST_TR_WIDTH, dst_width); +} + +/** + * @brief Get Destination transfer width. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DST_TR_WIDTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DDATAALIGN_BYTE + * @arg @ref LL_DMA_DDATAALIGN_HALFWORD + * @arg @ref LL_DMA_DDATAALIGN_WORD + */ +__STATIC_INLINE uint32_t ll_dma_get_destination_width(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DST_TR_WIDTH); +} + +/** + * @brief Set Source Burst Transaction Length. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SRC_MSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param burst_length This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_BURST_LENGTH_1 + * @arg @ref LL_DMA_SRC_BURST_LENGTH_4 + * @arg @ref LL_DMA_SRC_BURST_LENGTH_8 + * @retval None + */ +__STATIC_INLINE void ll_dma_set_source_burst_length(dma_regs_t *DMAx, uint32_t channel, uint32_t burst_length) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SRC_MSIZE, burst_length); +} + +/** + * @brief Get Burst Transaction Length. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | SRC_MSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_BURST_LENGTH_1 + * @arg @ref LL_DMA_SRC_BURST_LENGTH_4 + * @arg @ref LL_DMA_SRC_BURST_LENGTH_8 + */ +__STATIC_INLINE uint32_t ll_dma_get_source_burst_length(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_SRC_MSIZE); +} + +/** + * @brief Set Destination Burst Transaction Length. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DST_MSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param burst_length This parameter can be one of the following values: + * @arg @ref LL_DMA_DST_BURST_LENGTH_1 + * @arg @ref LL_DMA_DST_BURST_LENGTH_4 + * @arg @ref LL_DMA_DST_BURST_LENGTH_8 + * @retval None + */ +__STATIC_INLINE void ll_dma_set_destination_burst_length(dma_regs_t *DMAx, uint32_t channel, uint32_t burst_length) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DST_MSIZE, burst_length); +} + +/** + * @brief Get Destination Burst Transaction Length. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_LO | DST_MSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DST_BURST_LENGTH_1 + * @arg @ref LL_DMA_DST_BURST_LENGTH_4 + * @arg @ref LL_DMA_DST_BURST_LENGTH_8 + */ +__STATIC_INLINE uint32_t ll_dma_get_destination_burst_length(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_DST_MSIZE); +} + +/** + * @brief Set Channel priority level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_LO | CH_PRIOR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param priority This parameter can be one of the following values: + * @arg @ref LL_DMA_PRIORITY_0 + * @arg @ref LL_DMA_PRIORITY_1 + * @arg @ref LL_DMA_PRIORITY_2 + * @arg @ref LL_DMA_PRIORITY_3 + * @arg @ref LL_DMA_PRIORITY_4 + * @arg @ref LL_DMA_PRIORITY_5 + * @arg @ref LL_DMA_PRIORITY_6 + * @arg @ref LL_DMA_PRIORITY_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_set_channel_priority_level(dma_regs_t *DMAx, uint32_t channel, uint32_t priority) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_CH_PRIOR, priority); +} + +/** + * @brief Get Channel priority level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_LO | CH_PRIOR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PRIORITY_0 + * @arg @ref LL_DMA_PRIORITY_1 + * @arg @ref LL_DMA_PRIORITY_2 + * @arg @ref LL_DMA_PRIORITY_3 + * @arg @ref LL_DMA_PRIORITY_4 + * @arg @ref LL_DMA_PRIORITY_5 + * @arg @ref LL_DMA_PRIORITY_6 + * @arg @ref LL_DMA_PRIORITY_7 + */ +__STATIC_INLINE uint32_t ll_dma_get_channel_priority_level(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_CH_PRIOR); +} + +/** + * @brief Set the block size of a transfer. + * @note This action has no effect if channel is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_HI | BLOCK_TS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param block_size Between Min_Data = 0 and Max_Data = 0xFFF + * @retval None + */ +__STATIC_INLINE void ll_dma_set_block_size(dma_regs_t *DMAx, uint32_t channel, uint32_t block_size) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_HI, DMA_CTLH_BLOCK_TS, block_size); +} + +/** + * @brief Get the block size of a transfer. + * @note Once the channel is enabled, the return value indicate the + * remaining bytes to be transmitted. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTL_HI | BLOCK_TS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFF + */ +__STATIC_INLINE uint32_t ll_dma_get_block_size(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_HI, DMA_CTLH_BLOCK_TS); +} + +/** + * @brief Configure the Source and Destination addresses. + * @note Each IP using DMA provides an API to get directly the register adress (LL_PPP_DMA_GetRegAddr) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SAR | SAR | + * +----------------------+-----------------------------------+ + * \endrst + * DAR | DAR + * CTL_LO | TT_FC + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param src_address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @param dst_address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @param direction This parameter can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_PERIPH + * @retval None + */ +__STATIC_INLINE void ll_dma_config_address(dma_regs_t *DMAx, + uint32_t channel, + uint32_t src_address, + uint32_t dst_address, + uint32_t direction) +{ + WRITE_REG(DMAx->CHANNEL[channel].SAR, src_address); + WRITE_REG(DMAx->CHANNEL[channel].DAR, dst_address); + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_TT_FC, direction); +} + +/** + * @brief Set the Source address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SAR | SAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dma_set_source_address(dma_regs_t *DMAx, uint32_t channel, uint32_t address) +{ + WRITE_REG(DMAx->CHANNEL[channel].SAR, address); +} + +/** + * @brief Set the Destination address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DAR | DAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dma_set_destination_address(dma_regs_t *DMAx, uint32_t channel, uint32_t address) +{ + WRITE_REG(DMAx->CHANNEL[channel].DAR, address); +} + +/** + * @brief Get Source address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SAR | SAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_dma_get_source_address(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_REG(DMAx->CHANNEL[channel].SAR); +} + +/** + * @brief Get Destination address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DAR | DAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_dma_get_destination_address(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_REG(DMAx->CHANNEL[channel].DAR); +} + +/** + * @brief Set the Memory to Memory Source address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SAR | SAR | + * +----------------------+-----------------------------------+ + * \endrst + * CTL_LO | TT_FC + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dma_set_m2m_src_address(dma_regs_t *DMAx, uint32_t channel, uint32_t address) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_TT_FC, 0); + WRITE_REG(DMAx->CHANNEL[channel].SAR, address); +} + +/** + * @brief Set the Memory to Memory Destination address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DAR | DAR | + * +----------------------+-----------------------------------+ + * \endrst + * CTL_LO | TT_FC + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param address Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dma_set_m2m_dst_address(dma_regs_t *DMAx, uint32_t channel, uint32_t address) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_TT_FC, 0); + WRITE_REG(DMAx->CHANNEL[channel].DAR, address); +} + +/** + * @brief Get the Memory to Memory Source address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SAR | SAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_dma_get_m2m_src_address(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_REG(DMAx->CHANNEL[channel].SAR); +} + +/** + * @brief Get the Memory to Memory Destination address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DAR | DAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_dma_get_m2m_dst_address(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_REG(DMAx->CHANNEL[channel].DAR); +} + +/** + * @brief Set source peripheral for DMA instance on Channel x. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_HI | SRC_PER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param peripheral This parameter can be one of the following values: + * @arg @ref LL_DMA_PERIPH_SPIM_TX + * @arg @ref LL_DMA_PERIPH_SPIM_RX + * @arg @ref LL_DMA_PERIPH_SPIS_TX + * @arg @ref LL_DMA_PERIPH_SPIS_RX + * @arg @ref LL_DMA_PERIPH_QSPI0_TX + * @arg @ref LL_DMA_PERIPH_QSPI0_RX + * @arg @ref LL_DMA_PERIPH_I2C0_TX + * @arg @ref LL_DMA_PERIPH_I2C0_RX + * @arg @ref LL_DMA_PERIPH_I2C1_TX + * @arg @ref LL_DMA_PERIPH_I2C1_RX + * @arg @ref LL_DMA_PERIPH_I2S_S_TX + * @arg @ref LL_DMA_PERIPH_I2S_S_RX + * @arg @ref LL_DMA_PERIPH_UART0_TX + * @arg @ref LL_DMA_PERIPH_UART0_RX + * @arg @ref LL_DMA_PERIPH_QSPI1_TX + * @arg @ref LL_DMA_PERIPH_QSPI1_RX + * @arg @ref LL_DMA_PERIPH_I2S_M_TX + * @arg @ref LL_DMA_PERIPH_I2S_M_RX + * @arg @ref LL_DMA_PERIPH_SNSADC + * @retval None + */ +__STATIC_INLINE void ll_dma_set_source_peripheral(dma_regs_t *DMAx, uint32_t channel, uint32_t peripheral) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_HI, DMA_CFGH_SRC_PER, (peripheral << DMA_CFGH_SRC_PER_Pos)); +} + +/** + * @brief Get source peripheral for DMA instance on Channel x. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_HI | SRC_PER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PERIPH_SPIM_TX + * @arg @ref LL_DMA_PERIPH_SPIM_RX + * @arg @ref LL_DMA_PERIPH_SPIS_TX + * @arg @ref LL_DMA_PERIPH_SPIS_RX + * @arg @ref LL_DMA_PERIPH_QSPI0_TX + * @arg @ref LL_DMA_PERIPH_QSPI0_RX + * @arg @ref LL_DMA_PERIPH_I2C0_TX + * @arg @ref LL_DMA_PERIPH_I2C0_RX + * @arg @ref LL_DMA_PERIPH_I2C1_TX + * @arg @ref LL_DMA_PERIPH_I2C1_RX + * @arg @ref LL_DMA_PERIPH_I2S_S_TX + * @arg @ref LL_DMA_PERIPH_I2S_S_RX + * @arg @ref LL_DMA_PERIPH_UART0_TX + * @arg @ref LL_DMA_PERIPH_UART0_RX + * @arg @ref LL_DMA_PERIPH_QSPI1_TX + * @arg @ref LL_DMA_PERIPH_QSPI1_RX + * @arg @ref LL_DMA_PERIPH_I2S_M_TX + * @arg @ref LL_DMA_PERIPH_I2S_M_RX + * @arg @ref LL_DMA_PERIPH_SNSADC + */ +__STATIC_INLINE uint32_t ll_dma_get_source_peripheral(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_HI, DMA_CFGH_SRC_PER) >> DMA_CFGH_SRC_PER_Pos; +} + +/** + * @brief Set destination peripheral for DMA instance on Channel x. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_HI | DST_PER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param peripheral This parameter can be one of the following values: + * @arg @ref LL_DMA_PERIPH_SPIM_TX + * @arg @ref LL_DMA_PERIPH_SPIM_RX + * @arg @ref LL_DMA_PERIPH_SPIS_TX + * @arg @ref LL_DMA_PERIPH_SPIS_RX + * @arg @ref LL_DMA_PERIPH_QSPI0_TX + * @arg @ref LL_DMA_PERIPH_QSPI0_RX + * @arg @ref LL_DMA_PERIPH_I2C0_TX + * @arg @ref LL_DMA_PERIPH_I2C0_RX + * @arg @ref LL_DMA_PERIPH_I2C1_TX + * @arg @ref LL_DMA_PERIPH_I2C1_RX + * @arg @ref LL_DMA_PERIPH_I2S_S_TX + * @arg @ref LL_DMA_PERIPH_I2S_S_RX + * @arg @ref LL_DMA_PERIPH_UART0_TX + * @arg @ref LL_DMA_PERIPH_UART0_RX + * @arg @ref LL_DMA_PERIPH_QSPI1_TX + * @arg @ref LL_DMA_PERIPH_QSPI1_RX + * @arg @ref LL_DMA_PERIPH_I2S_M_TX + * @arg @ref LL_DMA_PERIPH_I2S_M_RX + * @arg @ref LL_DMA_PERIPH_SNSADC + * @retval None + */ +__STATIC_INLINE void ll_dma_set_destination_peripheral(dma_regs_t *DMAx, uint32_t channel, uint32_t peripheral) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_HI, DMA_CFGH_DST_PER, (peripheral << DMA_CFGH_DST_PER_Pos)); +} + +/** + * @brief Get destination peripheral for DMA instance on Channel x. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_HI | DST_PER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PERIPH_SPIM_TX + * @arg @ref LL_DMA_PERIPH_SPIM_RX + * @arg @ref LL_DMA_PERIPH_SPIS_TX + * @arg @ref LL_DMA_PERIPH_SPIS_RX + * @arg @ref LL_DMA_PERIPH_QSPI0_TX + * @arg @ref LL_DMA_PERIPH_QSPI0_RX + * @arg @ref LL_DMA_PERIPH_I2C0_TX + * @arg @ref LL_DMA_PERIPH_I2C0_RX + * @arg @ref LL_DMA_PERIPH_I2C1_TX + * @arg @ref LL_DMA_PERIPH_I2C1_RX + * @arg @ref LL_DMA_PERIPH_I2S_S_TX + * @arg @ref LL_DMA_PERIPH_I2S_S_RX + * @arg @ref LL_DMA_PERIPH_UART0_TX + * @arg @ref LL_DMA_PERIPH_UART0_RX + * @arg @ref LL_DMA_PERIPH_QSPI1_TX + * @arg @ref LL_DMA_PERIPH_QSPI1_RX + * @arg @ref LL_DMA_PERIPH_I2S_M_TX + * @arg @ref LL_DMA_PERIPH_I2S_M_RX + * @arg @ref LL_DMA_PERIPH_SNSADC + */ +__STATIC_INLINE uint32_t ll_dma_get_destination_peripheral(dma_regs_t *DMAx, uint32_t channel) +{ + return READ_BITS(DMAx->CHANNEL[channel].CTL_HI, DMA_CFGH_DST_PER) >> DMA_CFGH_DST_PER_Pos; +} + +/** + * @brief Set source and destination source handshaking interface. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CFG_HI | DST_PER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param src_handshaking This parameter can be one of the following values: + * @arg @ref LL_DMA_SHANDSHAKING_HW + * @arg @ref LL_DMA_SHANDSHAKING_HW + * @param dst_handshaking This parameter can be one of the following values: + * @arg @ref LL_DMA_DHANDSHAKING_HW + * @arg @ref LL_DMA_DHANDSHAKING_HW + * @retval None + */ +__STATIC_INLINE void ll_dma_select_handshaking(dma_regs_t *DMAx, uint32_t channel, uint32_t src_handshaking, uint32_t dst_handshaking) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CFG_LO, DMA_CFGL_HS_SEL_SRC | DMA_CFGL_HS_SEL_DST, + src_handshaking | dst_handshaking); +} + +/** + * @brief Source Single Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SGL_REQ_SRC | REQ_SRC_WE&REQ_SRC | + * +----------------------+-----------------------------------+ + * \endrst + * REQ_SRC | SRC_WE&SRC + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_src_single_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.SGL_RQ_SRC, (1 << (channel + DMA_SGL_REQ_SRC_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_SRC, (1 << (channel + DMA_REQ_SRC_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Source Burst Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | REQ_SRC | SRC_WE&SRC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_src_burst_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.REQ_SRC, (1 << (channel + DMA_REQ_SRC_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Source Last Single Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SGL_REQ_SRC | REQ_SRC_WE&REQ_SRC | + * +----------------------+-----------------------------------+ + * \endrst + * LST_SRC | LST_SRC_WE&LST_SRC + * REQ_SRC | SRC_WE&SRC + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_src_last_single_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.SGL_RQ_SRC, (1 << (channel + DMA_SGL_REQ_SRC_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.LST_SRC, (1 << (channel + DMA_LST_SRC_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_SRC, (1 << (channel + DMA_REQ_SRC_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Source Last Burst Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LST_SRC | LST_SRC_WE&LST_SRC | + * +----------------------+-----------------------------------+ + * \endrst + * REQ_SRC | SRC_WE&SRC + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_src_last_burst_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.LST_SRC, (1 << (channel + DMA_LST_SRC_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_SRC, (1 << (channel + DMA_REQ_SRC_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Destination Single Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SGL_REQ_DST | REQ_DST_WE&REQ_DST | + * +----------------------+-----------------------------------+ + * \endrst + * REQ_DST | DST_WE&DST + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_dst_single_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.SGL_RQ_DST, (1 << (channel + DMA_SGL_REQ_DST_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_DST, (1 << (channel + DMA_REQ_DST_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Destination Burst Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | REQ_DST | DST_WE&DST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_dst_burst_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.REQ_DST, (1 << (channel + DMA_REQ_DST_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Destination Last Single Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SGL_REQ_DST | REQ_DST_WE&REQ_DST | + * +----------------------+-----------------------------------+ + * \endrst + * LST_DST | LST_DST_WE&LST_DST + * REQ_DST | DST_WE&DST + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_dst_last_single_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.SGL_RQ_DST, (1 << (channel + DMA_SGL_REQ_DST_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.LST_DST, (1 << (channel + DMA_LST_DST_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_DST, (1 << (channel + DMA_REQ_DST_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Destination Last Burst Transaction Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LST_DST | LST_DST_WE&LST_DST | + * +----------------------+-----------------------------------+ + * \endrst + * REQ_DST | DST_WE&DST + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_req_dst_last_burst_transaction(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->HANDSHAKE.LST_DST, (1 << (channel + DMA_LST_DST_WE_Pos)) + (1 << channel)); + WRITE_REG(DMAx->HANDSHAKE.REQ_DST, (1 << (channel + DMA_REQ_DST_WE_Pos)) + (1 << channel)); +} + +/** @} */ + +/** @defgroup DMA_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Get DMA Module global transfer complete interrupt status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS_INT | TFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_gtfr(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_EVT, DMA_STAT_INT_TFR) == DMA_STAT_INT_TFR); +} + +/** + * @brief Get DMA Module global block complete interrupt status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS_INT | BLOCK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_gblk(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_EVT, DMA_STAT_INT_BLK) == DMA_STAT_INT_BLK); +} + +/** + * @brief Get DMA Module global source transaction complete interrupt status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS_INT | SRCT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_gsrct(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_EVT, DMA_STAT_INT_SRC) == DMA_STAT_INT_SRC); +} + +/** + * @brief Get DMA Module global destination transaction complete interrupt status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS_INT | DSTT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_gdstt(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_EVT, DMA_STAT_INT_DST) == DMA_STAT_INT_DST); +} + +/** + * @brief Get DMA Module global error interrupt status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS_INT | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_gerr(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_EVT, DMA_STAT_INT_ERR) == DMA_STAT_INT_ERR); +} + +/** + * @brief Indicate the Raw Status of IntTfr Interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_TFR | RAW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_rtfr(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.RAW_CH_EVT[0], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the Raw Status of IntBlock Interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_BLK | RAW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_rblk(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.RAW_CH_EVT[2], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the Raw Status of IntSrcTran Interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_SRC_TRN | RAW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_rsrct(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.RAW_CH_EVT[4], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the Raw Status of IntDstTran Interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_DST_TRN | RAW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_rdstt(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.RAW_CH_EVT[6], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the Raw Status of IntErr Interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_ERR | RAW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_rerr(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.RAW_CH_EVT[8], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of DMA Channel transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of Channel 0 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr0(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 0)) == (1 << 0)); +} + +/** + * @brief Indicate the status of Channel 1 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr1(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 1)) == (1 << 1)); +} + +/** + * @brief Indicate the status of Channel 2 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr2(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 2)) == (1 << 2)); +} + +/** + * @brief Indicate the status of Channel 3 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr3(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 3)) == (1 << 3)); +} + +/** + * @brief Indicate the status of Channel 4 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr4(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 4)) == (1 << 4)); +} + +/** + * @brief Indicate the status of Channel 5 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr5(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 5)) == (1 << 5)); +} + +/** + * @brief Indicate the status of Channel 6 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr6(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 6)) == (1 << 6)); +} + +/** + * @brief Indicate the status of Channel 7 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_TFR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_tfr7(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[0], (1 << 7)) == (1 << 7)); +} + +/** + * @brief Indicate the status of DMA Channel block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of Channel 0 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk0(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 0)) == (1 << 0)); +} + +/** + * @brief Indicate the status of Channel 1 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk1(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 1)) == (1 << 1)); +} + +/** + * @brief Indicate the status of Channel 2 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk2(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 2)) == (1 << 2)); +} + +/** + * @brief Indicate the status of Channel 3 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk3(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 3)) == (1 << 3)); +} + +/** + * @brief Indicate the status of Channel 4 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk4(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 4)) == (1 << 4)); +} + +/** + * @brief Indicate the status of Channel 5 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk5(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 5)) == (1 << 5)); +} + +/** + * @brief Indicate the status of Channel 6 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk6(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 6)) == (1 << 6)); +} + +/** + * @brief Indicate the status of Channel 7 block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_BLK | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_blk7(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[2], (1 << 7)) == (1 << 7)); +} + +/** + * @brief Indicate the status of DMA Channel source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of Channel 0 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct0(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 0)) == (1 << 0)); +} + +/** + * @brief Indicate the status of Channel 1 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct1(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 1)) == (1 << 1)); +} + +/** + * @brief Indicate the status of Channel 2 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct2(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 2)) == (1 << 2)); +} + +/** + * @brief Indicate the status of Channel 3 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct3(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 3)) == (1 << 3)); +} + +/** + * @brief Indicate the status of Channel 4 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct4(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 4)) == (1 << 4)); +} + +/** + * @brief Indicate the status of Channel 5 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct5(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 5)) == (1 << 5)); +} + +/** + * @brief Indicate the status of Channel 6 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct6(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 6)) == (1 << 6)); +} + +/** + * @brief Indicate the status of Channel 7 source transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_SRC_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_srct7(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[4], (1 << 7)) == (1 << 7)); +} + +/** + * @brief Indicate the status of DMA Channel destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of Channel 0 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt0(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 0)) == (1 << 0)); +} + +/** + * @brief Indicate the status of Channel 1 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt1(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 1)) == (1 << 1)); +} + +/** + * @brief Indicate the status of Channel 2 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt2(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 2)) == (1 << 2)); +} + +/** + * @brief Indicate the status of Channel 3 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt3(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 3)) == (1 << 3)); +} + +/** + * @brief Indicate the status of Channel 4 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt4(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 4)) == (1 << 4)); +} + +/** + * @brief Indicate the status of Channel 5 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt5(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 5)) == (1 << 5)); +} + +/** + * @brief Indicate the status of Channel 6 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt6(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 6)) == (1 << 6)); +} + +/** + * @brief Indicate the status of Channel 7 destination transaction complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_DST_TRN | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_dstt7(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[6], (1 << 7)) == (1 << 7)); +} + +/** + * @brief Indicate the status of DMA Channel error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Indicate the status of Channel 0 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err0(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 0)) == (1 << 0)); +} + +/** + * @brief Indicate the status of Channel 1 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err1(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 1)) == (1 << 1)); +} + +/** + * @brief Indicate the status of Channel 2 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err2(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 2)) == (1 << 2)); +} + +/** + * @brief Indicate the status of Channel 3 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err3(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 3)) == (1 << 3)); +} + +/** + * @brief Indicate the status of Channel 4 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err4(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 4)) == (1 << 4)); +} + +/** + * @brief Indicate the status of Channel 5 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err5(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 5)) == (1 << 5)); +} + +/** + * @brief Indicate the status of Channel 6 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err6(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 6)) == (1 << 6)); +} + +/** + * @brief Indicate the status of Channel 7 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT_ERR | STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_active_flag_err7(dma_regs_t *DMAx) +{ + return (READ_BITS(DMAx->EVENT.STATUS_CH_EVT[8], (1 << 7)) == (1 << 7)); +} + +/** + * @brief Clear DMA Channel transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << channel)); +} + +/** + * @brief Clear Channel 0 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr0(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 0)); +} + +/** + * @brief Clear Channel 1 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr1(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 1)); +} + +/** + * @brief Clear Channel 2 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr2(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 2)); +} + +/** + * @brief Clear Channel 3 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr3(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 3)); +} + +/** + * @brief Clear Channel 4 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr4(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 4)); +} + +/** + * @brief Clear Channel 5 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr5(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 5)); +} + +/** + * @brief Clear Channel 6 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr6(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 6)); +} + +/** + * @brief Clear Channel 7 transfer complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_TFR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_tfr7(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[0], (1 << 7)); +} + +/** + * @brief Clear DMA Channel block complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << channel)); +} + +/** + * @brief Clear Channel 0 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk0(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 0)); +} + +/** + * @brief Clear Channel 1 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk1(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 1)); +} + +/** + * @brief Clear Channel 2 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk2(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 2)); +} + +/** + * @brief Clear Channel 3 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk3(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 3)); +} + +/** + * @brief Clear Channel 4 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk4(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 4)); +} + +/** + * @brief Clear Channel 5 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk5(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 5)); +} + +/** + * @brief Clear Channel 6 Block Cmplete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk6(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 6)); +} + +/** + * @brief Clear Channel 7 Block Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_BLK | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_blk7(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[2], (1 << 7)); +} + +/** + * @brief Clear DMA Channel source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << channel)); +} + +/** + * @brief Clear Channel 0 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct0(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 0)); +} + +/** + * @brief Clear Channel 1 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct1(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 1)); +} + +/** + * @brief Clear Channel 2 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct2(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 2)); +} + +/** + * @brief Clear Channel 3 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct3(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 3)); +} + +/** + * @brief Clear Channel 4 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct4(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 4)); +} + +/** + * @brief Clear Channel 5 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct5(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 5)); +} + +/** + * @brief Clear Channel 6 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct6(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 6)); +} + +/** + * @brief Clear Channel 7 source transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_SRC_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_srct7(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[4], (1 << 7)); +} + +/** + * @brief Clear DMA Channel destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << channel)); +} + +/** + * @brief Clear Channel 0 destination transaction Complete status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt0(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 0)); +} + +/** + * @brief Clear Channel 1 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt1(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 1)); +} + +/** + * @brief Clear Channel 2 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt2(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 2)); +} + +/** + * @brief Clear Channel 3 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt3(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 3)); +} + +/** + * @brief Clear Channel 4 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt4(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 4)); +} + +/** + * @brief Clear Channel 5 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt5(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 5)); +} + +/** + * @brief Clear Channel 6 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt6(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 6)); +} + +/** + * @brief Clear Channel 7 destination transaction Complete flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_DST_TRN | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_dstt7(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[6], (1 << 7)); +} + +/** + * @brief Clear DMA Channel error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << channel)); +} + +/** + * @brief Clear Channel 0 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err0(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 0)); +} + +/** + * @brief Clear Channel 1 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err1(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 1)); +} + +/** + * @brief Clear Channel 2 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err2(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 2)); +} + +/** + * @brief Clear Channel 3 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err3(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 3)); +} + +/** + * @brief Clear Channel 4 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err4(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 4)); +} + +/** + * @brief Clear Channel 5 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err5(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 5)); +} + +/** + * @brief Clear Channel 6 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err6(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 6)); +} + +/** + * @brief Clear Channel 7 error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLR_ERR | CLEAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @retval None. + */ +__STATIC_INLINE void ll_dma_clear_flag_err7(dma_regs_t *DMAx) +{ + WRITE_REG(DMAx->EVENT.CLEAR_CH_EVT[8], (1 << 7)); +} + +/** @} */ + +/** @defgroup DMA_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Transfer Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_TFR | TFR_WE&TFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it_tfr(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[0], (1 << (channel + DMA_MASK_TFR_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Enable Block Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_BLK | BLK_WE&BLK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it_blk(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[2], (1 << (channel + DMA_MASK_BLK_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Enable source transaction Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_SRC_TRN | SRC_TRN_WE&SRC_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it_srct(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[4], (1 << (channel + DMA_MASK_SRC_TRN_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Enable destination transaction Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_DST_TRN | DST_TRN_WE&DST_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it_dstt(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[6], (1 << (channel + DMA_MASK_DST_TRN_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Enable error interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_ERR | ERR_WE&ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it_err(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[8], (1 << (channel + DMA_MASK_ERR_WE_Pos)) + (1 << channel)); +} + +/** + * @brief Disable Transfer Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_TFR | TFR_WE&TFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it_tfr(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[0], (1 << (channel + DMA_MASK_TFR_WE_Pos))); +} + +/** + * @brief Disable Block Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_BLK | BLK_WE&BLK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it_blk(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[2], (1 << (channel + DMA_MASK_BLK_WE_Pos))); +} + +/** + * @brief Disable source transaction Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_SRC_TRN | SRC_TRN_WE&SRC_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it_srct(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[4], (1 << (channel + DMA_MASK_SRC_TRN_WE_Pos))); +} + +/** + * @brief Disable destination transaction Complete interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_DST_TRN | DST_TRN_WE&DST_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it_dstt(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[6], (1 << (channel + DMA_MASK_DST_TRN_WE_Pos))); +} + +/** + * @brief Disable error interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_ERR | ERR_WE&ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it_err(dma_regs_t *DMAx, uint32_t channel) +{ + WRITE_REG(DMAx->EVENT.MASK_CH_EVT[8], (1 << (channel + DMA_MASK_ERR_WE_Pos))); +} + +/** + * @brief Check if DMA Transfer interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_TFR | TFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable_it_tfr(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.MASK_CH_EVT[0], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Check if DMA block interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_BLK | BLK_WE&BLK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable_it_blk(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.MASK_CH_EVT[2], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Check if DMA source transaction interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_SRC_TRN | SRC_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable_it_srct(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.MASK_CH_EVT[4], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Check if DMA destination transaction interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_DST_TRN | DST_TRN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable_it_dstt(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.MASK_CH_EVT[6], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Check if DMA error interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MASK_ERR | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dma_is_enable_it_err(dma_regs_t *DMAx, uint32_t channel) +{ + return (READ_BITS(DMAx->EVENT.MASK_CH_EVT[8], (1 << channel)) == (1 << channel)); +} + +/** + * @brief Enable DMA channel interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTLL | INI_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_enable_it(dma_regs_t *DMAx, uint32_t channel) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_INI_EN, DMA_CTLL_INI_EN); +} + +/** + * @brief Disable DMA channel interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTLL | INI_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DMAx DMA instance. + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ +__STATIC_INLINE void ll_dma_disable_it(dma_regs_t *DMAx, uint32_t channel) +{ + MODIFY_REG(DMAx->CHANNEL[channel].CTL_LO, DMA_CTLL_INI_EN, 0); +} + +/** @} */ + +/** @defgroup DMA_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize the DMA registers to their default reset values. + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval An error_status_t enumeration value: + * - SUCCESS: DMA registers are de-initialized + * - ERROR: DMA registers are not de-initialized + */ +error_status_t ll_dma_deinit(dma_regs_t *DMAx, uint32_t channel); + +/** + * @brief Initialize the DMA registers according to the specified parameters in p_dma_init. + * @param DMAx DMAx instance + * @param channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param p_dma_init pointer to a @ref ll_dma_init_t structure. + * @retval An error_status_t enumeration value: + * - SUCCESS: DMA registers are initialized + * - ERROR: Not applicable + */ +error_status_t ll_dma_init(dma_regs_t *DMAx, uint32_t channel, ll_dma_init_t *p_dma_init); + +/** + * @brief Set each field of a @ref ll_dma_init_t type structure to default value. + * @param p_dma_init Pointer to a @ref ll_dma_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_dma_struct_init(ll_dma_init_t *p_dma_init); + +/** @} */ + +/** @} */ + +#endif /* DMA */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_DMA_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dual_tim.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dual_tim.h new file mode 100644 index 0000000..5208113 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_dual_tim.h @@ -0,0 +1,719 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_dual_tim.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of DUAL TIMER LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_DUAL_TIMER DUAL_TIMER + * @brief DUAL TIM LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_DUAL_TIMER_H__ +#define __GR55XX_LL_DUAL_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (DUAL_TIMER0) || defined (DUAL_TIMER1) + +/** @defgroup DUAL_TIMER_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_LL_ES_INIT DUAL_TIM Exported init structures + * @{ + */ + +/** + * @brief LL DUAL TIMER init Structure definition + */ +typedef struct _ll_dual_timer_init +{ + uint32_t prescaler; /**< Specifies the prescaler value used to divide the TIMER clock. + This parameter can be a value of @ref DUAL_TIMER_EC_LL_PRESCALER. + + This feature can be modified afterwards using unitary function @ref ll_dual_timer_set_prescaler().*/ + + uint32_t counter_size; /**< Specifies the prescaler value used to divide the DUAL_TIMER clock. + This parameter can be a value of @ref DUAL_TIMER_EC_LL_COUNTERSIZE. + + This feature can be modified afterwards using unitary function @ref ll_dual_timer_set_counter_size().*/ + + uint32_t counter_mode; /**< Specifies the counter mode. + This parameter can be a value of @ref DUAL_TIMER_LL_EC_COUNTERMODE. + + This feature can be modified afterwards using unitary function @ref ll_dual_timer_set_counter_mode().*/ + + uint32_t auto_reload; /**< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF. + Some timer instances may support 16 bits counters. In that case this parameter must be a number between 0x0000 and 0xFFFF. + + This feature can be modified afterwards using unitary function @ref ll_dual_timer_set_auto_reload().*/ +} ll_dual_timer_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup DUAL_TIMER_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_LL_Exported_Constants DUAL_TIM Exported Constants + * @{ + */ + +/** @defgroup DUAL_TIMER_LL_EC_COUNTERMODE DUAL_TIM counter mode + * @{ + */ +#define LL_DUAL_TIMER_FREERUNNING_MODE 0x00000000U /**< Free running mode */ +#define LL_DUAL_TIMER_PERIODIC_MODE DUAL_TIMER_CTRL_MODE /**< Periodic mode */ +/** @} */ + +/** @defgroup DUAL_TIMER_EC_LL_PRESCALER DUAL_TIM prescaler + * @{ + */ +#define LL_DUAL_TIMER_PRESCALER_DIV0 0x00000000U /**< 0 stage of prescale, clock is divided by 1. */ +#define LL_DUAL_TIMER_PRESCALER_DIV16 (1UL << DUAL_TIMER_CTRL_PRE_Pos) /**< 4 stages of prescale, clock is divided by 16. */ +#define LL_DUAL_TIMER_PRESCALER_DIV256 (2UL << DUAL_TIMER_CTRL_PRE_Pos) /**< 8 stages of prescale, clock is divided by 256. */ +/** @} */ + +/** @defgroup DUAL_TIMER_EC_LL_COUNTERSIZE DUAL_TIM counter size + * @{ + */ +#define LL_DUAL_TIMER_COUNTERSIZE_16 0x00000000U /**< Counter size 16 bits */ +#define LL_DUAL_TIMER_COUNTERSIZE_32 DUAL_TIMER_CTRL_SIZE /**< Counter size 32 bits */ +/** @} */ + +/** @defgroup DUAL_TIMER_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL DUAL_TIMER InitStrcut default configuartion + */ +#define DUAL_TIMER_DEFAULT_CONFIG \ +{ \ + .prescaler = LL_DUAL_TIMER_PRESCALER_DIV0, \ + .counter_size = LL_DUAL_TIMER_COUNTERSIZE_32, \ + .counter_mode = LL_DUAL_TIMER_PERIODIC_MODE, \ + .auto_reload = SystemCoreClock - 1, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_LL_Exported_Macros DUAL_TIM Exported Macros + * @{ + */ + +/** @defgroup DUAL_TIMER_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in DUAL_TIMER register + * @param __instance__ DUAL_TIMER instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DUAL_TIMER_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DUAL_TIMER register + * @param __instance__ DUAL_TIMER instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DUAL_TIMER_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DUAL_TIMER_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup DUAL_TIMER_LL_EF_Configuration Configuration functions + * @{ + */ + + +/** + * @brief Enable dual_timer counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_enable_counter(dual_timer_regs_t *DUAL_TIMERx) +{ + SET_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_EN); +} + +/** + * @brief Disable dual_timer counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_disable_counter(dual_timer_regs_t *DUAL_TIMERx) +{ + CLEAR_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_EN); +} + +/** + * @brief Indicate whether the dual_timer counter is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dual_timer_is_enabled_counter(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_EN) == (DUAL_TIMER_CTRL_EN)); +} + +/** + * @brief Set the counter mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @param counter_mode This parameter can be one of the following values: + * @arg @ref LL_DUAL_TIMER_FREERUNNING_MODE + * @arg @ref LL_DUAL_TIMER_PERIODIC_MODE + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_set_counter_mode(dual_timer_regs_t *DUAL_TIMERx, uint32_t counter_mode) +{ + MODIFY_REG(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_MODE, counter_mode); +} + +/** + * @brief Get the counter mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Return value can be one of the following values: + * @arg @ref LL_DUAL_TIMER_FREERUNNING_MODE + * @arg @ref LL_DUAL_TIMER_PERIODIC_MODE + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_counter_mode(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_MODE)); +} + +/** + * @brief Set the prescaler. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | PRE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @param prescaler This parameter can be one of the following values: + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV0 + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV16 + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV256 + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_set_prescaler(dual_timer_regs_t *DUAL_TIMERx, uint32_t prescaler) +{ + MODIFY_REG(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_PRE, prescaler); +} + +/** + * @brief Get the prescaler. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | PRE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Return value can be one of the following values: + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV0 + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV16 + * @arg @ref LL_DUAL_TIMER_PRESCALER_DIV256 + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_prescaler(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_PRE)); +} + +/** + * @brief Set the counter size. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @param counter_size This parameter can be one of the following values: + * @arg @ref LL_DUAL_TIMER_COUNTERSIZE_16 + * @arg @ref LL_DUAL_TIMER_COUNTERSIZE_32 + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_set_counter_size(dual_timer_regs_t *DUAL_TIMERx, uint32_t counter_size) +{ + MODIFY_REG(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_SIZE, counter_size); +} + +/** + * @brief Get the counter size. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Return value can be one of the following values: + * @arg @ref LL_DUAL_TIMER_COUNTERSIZE_16 + * @arg @ref LL_DUAL_TIMER_COUNTERSIZE_32 + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_counter_size(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_SIZE)); +} + +/** + * @brief Enable one-shot mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ONESHOT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_enable_oneshot(dual_timer_regs_t *DUAL_TIMERx) +{ + SET_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_ONESHOT); +} + +/** + * @brief Disable one-shot mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ONESHOT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_disable_oneshot(dual_timer_regs_t *DUAL_TIMERx) +{ + CLEAR_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_ONESHOT); +} + +/** + * @brief Indicate whether the one-shot mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ONESHOT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dual_timer_is_enabled_oneshot(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_ONESHOT) == (DUAL_TIMER_CTRL_ONESHOT)); +} + +/** + * @brief Get the counter value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | VALUE | VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFFFFFF) + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_counter(dual_timer_regs_t *DUAL_TIMERx) +{ + return (uint32_t)(READ_REG(DUAL_TIMERx->VALUE)); +} + +/** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RELOAD | RELOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @param auto_reload between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_set_auto_reload(dual_timer_regs_t *DUAL_TIMERx, uint32_t auto_reload) +{ + WRITE_REG(DUAL_TIMERx->RELOAD, auto_reload); +} + +/** + * @brief Get the auto-reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RELOAD | RELOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_auto_reload(dual_timer_regs_t *DUAL_TIMERx) +{ + return (uint32_t)(READ_REG(DUAL_TIMERx->RELOAD)); +} + +/** + * @brief Set the backgroud-reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BG_LOAD | BG_LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @param background_reload between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_set_background_reload(dual_timer_regs_t *DUAL_TIMERx, uint32_t background_reload) +{ + WRITE_REG(DUAL_TIMERx->BG_LOAD, background_reload); +} + +/** + * @brief Get the backgroud-reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BG_LOAD | BG_LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval Return value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_background_reload(dual_timer_regs_t *DUAL_TIMERx) +{ + return (uint32_t)(READ_REG(DUAL_TIMERx->BG_LOAD)); +} + +/** @} */ + +/** @defgroup DUAL_TIM_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable dual_timer interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_enable_it(dual_timer_regs_t *DUAL_TIMERx) +{ + SET_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_INTEN); +} + +/** + * @brief Disable dual_timer interrput. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_disable_it(dual_timer_regs_t *DUAL_TIMERx) +{ + CLEAR_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_INTEN); +} + +/** + * @brief Indicate whether the dual_timer interrput is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dual_timer_is_enabled_it(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->CTRL, DUAL_TIMER_CTRL_INTEN) == (DUAL_TIMER_CTRL_INTEN)); +} + +/** @} */ + +/** @defgroup DUAL_TIMER_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Clear the interrupt flag (INTSTAT). + * + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INTCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_dual_timer_clear_flag_it(dual_timer_regs_t *DUAL_TIMERx) +{ + WRITE_REG(DUAL_TIMERx->INTCLR, DUAL_TIMER_INT_CLR); +} + +/** + * @brief Indicate whether interrupt flag (INTSTAT) is set (interrupt is pending). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dual_timer_is_active_flag_it(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_BITS(DUAL_TIMERx->INTSTAT, DUAL_TIMER_ISR_TI) == (DUAL_TIMER_ISR_TI)); +} + +/** + * @brief Get Dual_timer raw interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_INTSTAT | RAW_INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param DUAL_TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_dual_timer_get_raw_it_flag(dual_timer_regs_t *DUAL_TIMERx) +{ + return (READ_REG(DUAL_TIMERx->RAW_INTSTAT)); +} + +/** @} */ + +/** @defgroup DUAL_TIMER_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize DUAL_TIMER registers (Registers restored to their default values). + * @param DUAL_TIMERx DUAL_TIM instance + * @retval An error_status_t enumeration value: + * - SUCCESS: DUAL_TIMER registers are de-initialized + * - ERROR: DUAL_TIMER registers are not de-initialized + */ +error_status_t ll_dual_timer_deinit(dual_timer_regs_t *DUAL_TIMERx); + +/** + * @brief Initialize DUAL_TIMER registers according to the specified + * parameters in p_dual_timer_init. + * @param DUAL_TIMERx DUAL_TIMER instance + * @param p_dual_timer_init Pointer to a ll_dual_timer_init_t structure that contains the configuration + * information for the specified DUAL_TIMER peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: DUAL_TIMER registers are initialized according to p_dual_timer_init content + * - ERROR: Problem occurred during DUAL_TIM Registers initialization + */ +error_status_t ll_dual_timer_init(dual_timer_regs_t *DUAL_TIMERx, ll_dual_timer_init_t *p_dual_timer_init); + +/** + * @brief Set each field of a @ref ll_dual_timer_init_t type structure to default value. + * @param p_dual_timer_init Pointer to a @ref ll_dual_timer_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_dual_timer_struct_init(ll_dual_timer_init_t *p_dual_timer_init); + +/** @} */ + +/** @} */ + + +#endif /* DUAL_TIMER0 || DUAL_TIMER1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_DUAL_TIMER_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_efuse.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_efuse.h new file mode 100644 index 0000000..d998b90 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_efuse.h @@ -0,0 +1,802 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_efuse.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of eFuse LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_EFUSE EFUSE + * @brief eFuse LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_EFUSE_H__ +#define __GR55xx_LL_EFUSE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (EFUSE) + +/** + * @defgroup EFUSE_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EFUSE_LL_Exported_Constants EFUSE Exported Constants + * @{ + */ + +/** @defgroup EFUSE_LL_EC_OPERATION EFUSE Operation Defines + * @brief Operation defines which can be used with LL_EFUSE_WriteReg function + * @{ + */ +#define LL_EFUSE_WRITE_KEYRAM EFUSE_OPER_WRITE_KEYRAM /**< Read fwkay and rootkey from eFuse, and write to keyram */ +#define LL_EFUSE_READ_TRIM EFUSE_OPER_READ_TRIM /**< Read analog trim from eFuse */ +#define LL_EFUSE_CRC_CHECK EFUSE_OPER_CRC_CHECK /**< Read the special eFuse addr, and calculate CRC value */ +#define LL_EFUSE_INIT_CHECK EFUSE_OPER_INIT_CHECK /**< Read the whole eFuse value, and check this value with 0 */ +#define LL_EFUSE_TEST_READ EFUSE_OPER_RD_TEST_MODE /**< Read eFuse test mode from eFuse */ +/** @} */ + +/** @defgroup EFUSE_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_EFUSE_ReadReg function + * @{ + */ +#define LL_EFUSE_WRITE_KEYRAM_BUSY EFUSE_STATUS_WRITE_KEYRAM_BUSY /**< Write keyram operation is in processing */ +#define LL_EFUSE_READ_TRIM_DONE EFUSE_STATUS_READ_TRIM_DONE /**< Read trim from eFuse has done */ +#define LL_EFUSE_CRC_CHECK_DONE EFUSE_STATUS_CRC_CHECK_DONE /**< eFuse CRC check done */ +#define LL_EFUSE_CRC_CHECK_SUCCESS EFUSE_STATUS_TRIM_CRC_SUCCESS /**< CRC check success */ +#define LL_EFUSE_INIT_CHECK_DONE EFUSE_STATUS_INIT_DONE /**< eFuse initial value check done */ +#define LL_EFUSE_INIT_CHECK_SUCCESS EFUSE_STATUS_INIT_SUCCESS /**< eFuse initial value check success */ +#define LL_EFUSE_WRITE_DONE EFUSE_STATUS_WRITE_DONE /**< eFuse one word write done */ +#define LL_EFUSE_TEST_DONE EFUSE_STATUS_TEST_MODE_DONE /**< Read from eFuse has done in test mode */ +/** @} */ + +/** @defgroup EFUSE_LL_EC_GET_CTL_FLAG Get Power Controller Flags Defines + * @brief Flags defines which can be used with LL_EFUSE_ReadReg function + * @{ + */ +#define LL_EFUSE_PWR_CTL_EN_DONE MCU_SUB_EFUSE_PWR_CTL0_EN_DONE /**< eFuse power enable done */ +#define LL_EFUSE_PWR_CTL_DIS_DONE MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE /**< eFuse power disable done */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EFUSE_LL_Exported_Macros EFUSE Exported Macros + * @{ + */ + +/** @defgroup EFUSE_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in eFuse register + * @param __instance__ eFuse instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_EFUSE_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in eFuse register + * @param __instance__ eFuse instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_EFUSE_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup EFUSE_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup EFUSE_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Set eFuse program time + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param time This parameter can be one of the following values: 0 ~ 0xFFF + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_tpro(efuse_regs_t *EFUSEx, uint32_t time) +{ + MODIFY_REG(EFUSEx->TPGM, EFUSE_TPGM_TIME, time << EFUSE_TPGM_TIME_Pos); +} + +/** + * @brief Get eFuse program time + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0 ~ 0xFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_tpro(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_BITS(EFUSEx->TPGM, EFUSE_TPGM_TIME) >> EFUSE_TPGM_TIME_Pos); +} + +/** + * @brief Enable read address through APB bus be a main address or backup address + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | MAIN_OR_BACKUP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval None + */ +__STATIC_INLINE void ll_efuse_enable_main_backup(efuse_regs_t *EFUSEx) +{ + SET_BITS(EFUSEx->TPGM, EFUSE_TPGM_MAIN_OR_BACKUP); +} + +/** + * @brief Disable read address through APB bus be a main address or backup address + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | MAIN_OR_BACKUP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval None + */ +__STATIC_INLINE void ll_efuse_disable_main_backup(efuse_regs_t *EFUSEx) +{ + CLEAR_BITS(EFUSEx->TPGM, EFUSE_TPGM_MAIN_OR_BACKUP); +} + +/** + * @brief Check if read address through APB bus be a main address or backup address is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | MAIN_OR_BACKUP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_efuse_is_enabled_main_backup(efuse_regs_t *EFUSEx) +{ + return (READ_BITS(EFUSEx->TPGM, EFUSE_TPGM_MAIN_OR_BACKUP) == (EFUSE_TPGM_MAIN_OR_BACKUP)); +} + +/** + * @brief Set CRC check length + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | CRC_CHECK_LEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param length This parameter can be one of the following values: 1 ~ 60 + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_crc_check_len(efuse_regs_t *EFUSEx, uint32_t length) +{ + MODIFY_REG(EFUSEx->TPGM, EFUSE_TPGM_CRC_CHECK_LEN, length << EFUSE_TPGM_CRC_CHECK_LEN_Pos); +} + +/** + * @brief Get CRC check length + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | CRC_CHECK_LEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 1 ~ 60 + */ +__STATIC_INLINE uint32_t ll_efuse_get_crc_check_len(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_BITS(EFUSEx->TPGM, EFUSE_TPGM_CRC_CHECK_LEN) >> EFUSE_TPGM_CRC_CHECK_LEN_Pos); +} + +/** + * @brief Set the interval number of clk cycles between two bit fuse + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | WRITE_INTERVAL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param interval This parameter can be one of the following values: 0 ~ 0xFF + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_interval(efuse_regs_t *EFUSEx, uint32_t interval) +{ + MODIFY_REG(EFUSEx->TPGM, EFUSE_TPGM_WRITE_INTERVAL, interval << EFUSE_TPGM_WRITE_INTERVAL_Pos); +} + +/** + * @brief Get the interval number of clk cycles between two bit fuse + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | WRITE_INTERVAL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0 ~ 0xFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_interval(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_BITS(EFUSEx->TPGM, EFUSE_TPGM_WRITE_INTERVAL) >> EFUSE_TPGM_WRITE_INTERVAL_Pos); +} + +/** + * @brief Enable eFuse PGENB sigal + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PGENB | PGENB_SIG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval None + */ +__STATIC_INLINE void ll_efuse_enable_pgenb(efuse_regs_t *EFUSEx) +{ + SET_BITS(EFUSEx->PGENB, EFUSE_PGENB_SIG); +} + +/** + * @brief Disable eFuse PGENB sigal + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PGENB | PGENB_SIG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval None + */ +__STATIC_INLINE void ll_efuse_disable_pgenb(efuse_regs_t *EFUSEx) +{ + CLEAR_BITS(EFUSEx->PGENB, EFUSE_PGENB_SIG); +} + +/** + * @brief Check if eFuse PGENB sigal is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PGENB | PGENB_SIG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_efuse_is_enabled_pgenb(efuse_regs_t *EFUSEx) +{ + return (READ_BITS(EFUSEx->PGENB, EFUSE_PGENB_SIG) == (EFUSE_PGENB_SIG)); +} + +/** + * @brief Get test mode + * @note This bit should be read only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TEST_MODE | TEST_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0xFFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_test_mode(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_BITS(EFUSEx->TEST_MODE, EFUSE_TEST_MODE)); +} + +/** + * @brief Set eFuse operation mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | OPERATION | WRITE_KEYRAM | + * +----------------------+-----------------------------------+ + * \endrst + * OPERATION | INIT_CHECK + * OPERATION | CRC_CHECK + * OPERATION | READ_TRIM + * OPERATION | RD_TEST_MODE + * + * @param EFUSEx eFuse instance + * @param mode This parameter can be one of the following values: + * @arg @ref LL_EFUSE_WRITE_KEYRAM + * @arg @ref LL_EFUSE_READ_TRIM + * @arg @ref LL_EFUSE_CRC_CHECK + * @arg @ref LL_EFUSE_INIT_CHECK + * @arg @ref LL_EFUSE_TEST_READ + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_operation(efuse_regs_t *EFUSEx, uint32_t mode) +{ + WRITE_REG(EFUSEx->OPERATION, mode); +} + +/** + * @brief Check active flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | WRITE_KEYRAM_BUSY | + * +----------------------+-----------------------------------+ + * \endrst + * STAT | READ_TRIM_DONE + * STAT | TRIM_CRC_SUCCESS + * STAT | INIT_DONE + * STAT | INIT_SUCCESS + * STAT | CRC_CHECK_DONE + * STAT | WRITE_DONE + * STAT | TEST_MODE_DONE + * + * @param EFUSEx eFuse instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_EFUSE_WRITE_KEYRAM_BUSY + * @arg @ref LL_EFUSE_READ_TRIM_DONE + * @arg @ref LL_EFUSE_CRC_CHECK_DONE + * @arg @ref LL_EFUSE_CRC_CHECK_SUCCESS + * @arg @ref LL_EFUSE_INIT_CHECK_DONE + * @arg @ref LL_EFUSE_INIT_CHECK_SUCCESS + * @arg @ref LL_EFUSE_WRITE_DONE + * @arg @ref LL_EFUSE_TEST_DONE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_efuse_is_active_flag(efuse_regs_t *EFUSEx, uint32_t flag) +{ + return (READ_BITS(EFUSEx->STAT, flag) == (flag)); +} + +/** + * @brief Set key mask + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY_MASK | KEY_MASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param mask Key mask + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_key_mask(efuse_regs_t *EFUSEx, uint32_t mask) +{ + WRITE_REG(EFUSEx->KEY_MASK, mask); +} + +/** + * @brief Get key mask + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY_MASK | KEY_MASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval None + */ +__STATIC_INLINE uint32_t ll_efuse_get_key_mask(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_REG(EFUSEx->KEY_MASK)); +} + +/** + * @brief Set CRC check start address + * @note The address must be a main info address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CRC_ADDR | START_CHECK_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param address This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_crc_check_addr(efuse_regs_t *EFUSEx, uint32_t address) +{ + WRITE_REG(EFUSEx->CRC_ADDR, address); +} + +/** + * @brief Get CRC check start address + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CRC_ADDR | START_CHECK_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_crc_check_addr(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_REG(EFUSEx->CRC_ADDR)); +} + +/** + * @brief Get CRC check results + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CRC_OUTPUT | OUTPUT_VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_crc_check_result(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_REG(EFUSEx->CRC_OUTPUT)); +} + +/** + * @brief Set read trim start address + * @note The address must be a main info address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRIM_ADDR | START_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param address This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_trim_addr(efuse_regs_t *EFUSEx, uint32_t address) +{ + WRITE_REG(EFUSEx->TRIM_ADDR, address); +} + +/** + * @brief Get read trim start address + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRIM_ADDR | START_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_trim_addr(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_REG(EFUSEx->TRIM_ADDR)); +} + +/** + * @brief Set read trim length + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRIM_LEN | LENGTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param length This parameter can be one of the following values: 1 ~ 14 + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_trim_length(efuse_regs_t *EFUSEx, uint32_t length) +{ + WRITE_REG(EFUSEx->TRIM_LEN, length & EFUSE_TRIM_LENGTH); +} + +/** + * @brief Get read trim length + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRIM_LEN | LENGTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @retval Returned value can be one of the following values: 1 ~ 14 + */ +__STATIC_INLINE uint32_t ll_efuse_get_trim_length(efuse_regs_t *EFUSEx) +{ + return (uint32_t)(READ_REG(EFUSEx->TRIM_LEN) & EFUSE_TRIM_LENGTH); +} + +/** + * @brief Get trim value + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRIM[n] | TRIM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param EFUSEx eFuse instance + * @param indx index of trim value registers: 0 ~ 13 + * @retval Returned value can be one of the following values: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_efuse_get_trim_value(efuse_regs_t *EFUSEx, uint32_t indx) +{ + return (uint32_t)(READ_REG(EFUSEx->TRIM[indx])); +} + +/** + * @brief eFuse v1.1 power on. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | CRC_CHECK_LEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_enable_power(efuse_regs_t *EFUSEx) +{ + SET_BITS(AON->RF_REG_2, AON_RF_REG_2_EFUSE_VDD_EN); +} + +/** + * @brief eFuse v1.1 power off. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TPGM | CRC_CHECK_LEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_disable_power(efuse_regs_t *EFUSEx) +{ + CLEAR_BITS(AON->RF_REG_2, AON_RF_REG_2_EFUSE_VDD_EN); +} + +/** + * @brief Set Efulse power controller timing pararmeter. + * + * Register |BitsName + * ----------|-------- + * PWR_DELTA| PWR_DELTA_0 + * PWR_DELTA| PWR_DELTA_1 + * PWR_DELTA| PWR_DELTA_2 + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_set_controller_power_timing(efuse_regs_t *EFUSEx, uint16_t vddq_0, uint16_t vddq_1, uint16_t vddq_2) +{ + WRITE_REG(MCU_SUB->EFUSE_PWR_DELTA[0], vddq_0 + (vddq_1 << 16)); + WRITE_REG(MCU_SUB->EFUSE_PWR_DELTA[1], vddq_2); +} + +/** + * @brief Power sequencer begin. + * + * Register |BitsName + * -----------|-------- + * PWR_CTRL0 | CTRL_ENABLE + * PWR_CTRL0 | SEQR_BEGIN + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_enable_controller_power_begin(efuse_regs_t *EFUSEx) +{ + WRITE_REG(MCU_SUB->EFUSE_PWR_CTRL[0], MCU_SUB_EFUSE_PWR_CTL0_BGN | MCU_SUB_EFUSE_PWR_CTL0_EN); +} + +/** + * @brief Power sequencer begin. + * + * Register |BitsName + * -----------|-------- + * PWR_CTRL0 | CTRL_ENABLE + * PWR_CTRL0 | SEQR_STOP + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_enable_controller_power_stop(efuse_regs_t *EFUSEx) +{ + WRITE_REG(MCU_SUB->EFUSE_PWR_CTRL[0], MCU_SUB_EFUSE_PWR_CTL0_STP | MCU_SUB_EFUSE_PWR_CTL0_EN); +} + +/** + * @brief Power sequencer begin. + * + * Register |BitsName + * --------- -|-------- + * PWR_CTRL0 | CTRL_ENABLE + * PWR_CTRL0 | SEQR_BEGIN + * PWR_CTRL0 | SEQR_STOP + * + * @retval None + */ +__STATIC_INLINE void ll_efuse_disable_controller_power(efuse_regs_t *EFUSEx) +{ + WRITE_REG(MCU_SUB->EFUSE_PWR_CTRL[0], 0); +} + +/** + * @brief Check power controller active flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_CTRL1 | EN_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * PWR_CTRL1 | DIS_DONE + * + * @param EFUSEx eFuse instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_EFUSE_PWR_CTL_EN_DONE + * @arg @ref LL_EFUSE_PWR_CTL_DIS_DONE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_efuse_is_controller_power_flag(efuse_regs_t *EFUSEx, uint32_t flag) +{ + return (READ_BITS(MCU_SUB->EFUSE_PWR_CTRL[1], flag) == (flag)); +} + + + +/** @} */ + +/** @} */ + +#endif /* EFUSE */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_EFUSE_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_gpio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_gpio.h new file mode 100644 index 0000000..204161d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_gpio.h @@ -0,0 +1,1507 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_gpio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of GPIO LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_GPIO GPIO + * @brief GPIO LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_GPIO_H__ +#define __GR55XX_LL_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (GPIO0) || defined (GPIO1) + +/** @defgroup GPIO_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup GPIO_LL_ES_INIT GPIO Exported init structures + * @{ + */ + +/** + * @brief LL GPIO init configuration definition + */ +typedef struct _ll_gpio_init +{ + uint32_t pin; /*!< Specifies the GPIO pins to be GPIO_InitStructured. + This parameter can be any value of @ref GPIO_LL_EC_PIN */ + + uint32_t mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_MODE. + + GPIO HW GPIO_InitStructuration can be modified afterwards using unitary function @ref ll_gpio_set_pin_mode(). */ + + uint32_t pull; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_PULL. + + GPIO HW configuration can be modified afterwards using unitary function @ref ll_gpio_set_pin_pull().*/ + + uint32_t mux; /*!< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_MUX. + + GPIO HW GPIO_InitStructuration can be modified afterwards using unitary function + @ref ll_gpio_set_mux_pin_0_7() and ll_gpio_set_mux_pin_8_15(). */ + + uint32_t trigger; /*!< Specifies the trigger signal active edge. + This parameter can be a value of @ref GPIO_LL_EC_TRIGGER. */ + +} ll_gpio_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup GPIO_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_LL_EC_PIN PIN + * @{ + */ +#define LL_GPIO_PIN_0 ((uint32_t)0x0001U) /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 ((uint32_t)0x0002U) /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 ((uint32_t)0x0004U) /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 ((uint32_t)0x0008U) /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 ((uint32_t)0x0010U) /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 ((uint32_t)0x0020U) /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 ((uint32_t)0x0040U) /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 ((uint32_t)0x0080U) /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 ((uint32_t)0x0100U) /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 ((uint32_t)0x0200U) /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 ((uint32_t)0x0400U) /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 ((uint32_t)0x0800U) /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 ((uint32_t)0x1000U) /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 ((uint32_t)0x2000U) /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 ((uint32_t)0x4000U) /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 ((uint32_t)0x8000U) /*!< Select pin 15 */ +#define LL_GPIO_PIN_ALL ((uint32_t)0xFFFFU) /*!< Select all pins */ +/** @} */ + +/** @defgroup GPIO_LL_EC_MODE Mode + * @{ + */ +#define LL_GPIO_MODE_INPUT ((uint32_t)0x0U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT ((uint32_t)0x1U) /*!< Select output mode */ +#define LL_GPIO_MODE_MUX ((uint32_t)0x2U) /*!< Select mux peripheral mode */ +/** @} */ + +/** @defgroup GPIO_LL_EC_PULL Pull Up Pull Down + * @{ + */ +#define LL_GPIO_PULL_NO LL_GPIO_RE_N /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP LL_GPIO_RTYP /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN ((uint32_t)0x0U) /*!< Select I/O pull down */ +/** @} */ + +/** @defgroup GPIO_LL_EC_MUX Alternate Function + * @{ + */ +#define LL_GPIO_MUX_0 ((uint32_t)0x0U) /*!< Select alternate function 0 */ +#define LL_GPIO_MUX_1 ((uint32_t)0x1U) /*!< Select alternate function 1 */ +#define LL_GPIO_MUX_2 ((uint32_t)0x2U) /*!< Select alternate function 2 */ +#define LL_GPIO_MUX_3 ((uint32_t)0x3U) /*!< Select alternate function 3 */ +#define LL_GPIO_MUX_4 ((uint32_t)0x4U) /*!< Select alternate function 4 */ +#define LL_GPIO_MUX_5 ((uint32_t)0x5U) /*!< Select alternate function 5 */ +#define LL_GPIO_MUX_6 ((uint32_t)0x6U) /*!< Select alternate function 6 */ +#define LL_GPIO_MUX_7 ((uint32_t)0x7U) /*!< Select alternate function 7 */ +#define LL_GPIO_MUX_8 ((uint32_t)0x8U) /*!< Select alternate function 8 */ +/** @} */ + +/** @defgroup GPIO_LL_EC_TRIGGER Interrupt Trigger + * @{ + */ +#define LL_GPIO_TRIGGER_NONE ((uint32_t)0x00U) /*!< No Trigger Mode */ +#define LL_GPIO_TRIGGER_RISING ((uint32_t)0x01U) /*!< Trigger Rising Mode */ +#define LL_GPIO_TRIGGER_FALLING ((uint32_t)0x02U) /*!< Trigger Falling Mode */ +#define LL_GPIO_TRIGGER_HIGH ((uint32_t)0x03U) /*!< Trigger High Mode */ +#define LL_GPIO_TRIGGER_LOW ((uint32_t)0x04U) /*!< Trigger Low Mode */ +/** @} */ + +/** @defgroup GPIO_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL GPIO InitStrcut default configuartion + */ +#define LL_GPIO_DEFAULT_CONFIG \ +{ \ + .pin = LL_GPIO_PIN_ALL, \ + .mode = LL_GPIO_MODE_INPUT, \ + .pull = LL_GPIO_PULL_DOWN, \ + .mux = LL_GPIO_MUX_7, \ + .trigger = LL_GPIO_TRIGGER_NONE, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** @defgroup GPIO_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in GPIO register + * @param __instance__ GPIO instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_GPIO_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in GPIO register + * @param __instance__ GPIO instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_GPIO_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_LL_Private_Macros GPIO Private Macros + * @{ + */ + +/** @brief Get the starting position of the specified GPIO instance in related pull-up/pull-down register. + * @param __GPIOx__ This parameter can be one of the following values: + * @arg GPIO0 + * @arg GPIO1 + * @retval none + */ +#define LL_GPIO_GET_RESISTOR_POS(__GPIOx__) (((__GPIOx__) == GPIO0) ? 0 : 16) + +/** @brief Get mux control register address of specified GPIO instance. + * @param __GPIOx__ This parameter can be one of the following values: + * @arg GPIO0 + * @arg GPIO1 + * @retval none + */ +#define LL_GPIO_GET_REG_MUX_CTRL_0_7( __GPIOx__) \ + (((__GPIOx__) == GPIO0) ? &(MCU_SUB->DPAD_MUX_CTL0_7) : &(MCU_SUB->DPAD_MUX_CTL16_23)) + +/** @brief Get mux control register address of specified GPIO instance. + * @param __GPIOx__ This parameter can be one of the following values: + * @arg GPIO0 + * @arg GPIO1 + * @retval none + */ +#define LL_GPIO_GET_REG_MUX_CTRL_8_15( __GPIOx__) \ + (((__GPIOx__) == GPIO0) ? &(MCU_SUB->DPAD_MUX_CTL8_15) : &(MCU_SUB->DPAD_MUX_CTL24_31)) + +/** @defgroup GPIO_LL_PM_RESISTOR Resistor Enable + * @{ + */ +#define LL_GPIO_RE_N_Pos 0 /**< Resistor Enable bits position */ +#define LL_GPIO_RE_N_Msk (0x1U << LL_GPIO_RE_N_Pos) /**< Resistor Enable bits mask */ +#define LL_GPIO_RE_N LL_GPIO_RE_N_Msk /**< Resistor Enable bits */ +/** @} */ + +/** @defgroup GPIO_LL_PM_RESISTOR_TYPE Resistor Type + * @{ + */ +#define LL_GPIO_RTYP_Pos 1 /**< Resistor Type bits position */ +#define LL_GPIO_RTYP_Msk (0x1U << LL_GPIO_RTYP_Pos) /**< Resistor Type bits mask */ +#define LL_GPIO_RTYP LL_GPIO_RTYP_Msk /**< Resistor Type bits */ +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIO_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup GPIO_LL_EF_Port_Configuration Port Configuration + * @{ + */ + +/** + * @brief Set several pins to input/output mode on dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | OUTENSET | OUTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * OUTENCLR | OUTENCLR + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @param mode This parameter can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + * @retval None + */ +__STATIC_INLINE void ll_gpio_set_pin_mode(gpio_regs_t *GPIOx, uint32_t pin_mask, uint32_t mode) +{ + if (mode == LL_GPIO_MODE_OUTPUT) + { + WRITE_REG(GPIOx->OUTENSET, pin_mask); + } + else if(mode == LL_GPIO_MODE_INPUT) + { + WRITE_REG(GPIOx->OUTENCLR, pin_mask); + } +} + +/** + * @brief Return gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, General purpose output. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | OUTENSET | OUTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + */ +__STATIC_INLINE uint32_t ll_gpio_get_pin_mode(gpio_regs_t *GPIOx, uint32_t pin) +{ + return (uint32_t)(READ_BITS(GPIOx->OUTENSET, pin) != RESET); +} + +/** + * @brief Configure gpio pull-up or pull-down for a dedicated pin on a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_RE_N_BUS | RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_RTYP_BUS | RTYP + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param pull This parameter can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + * @retval None + */ +__STATIC_INLINE void ll_gpio_set_pin_pull(gpio_regs_t *GPIOx, uint32_t pin_mask, uint32_t pull) +{ + /* Get pin mask in resitor related registers, GPIO0:0~15, GPIO1:16~31 */ + pin_mask <<= LL_GPIO_GET_RESISTOR_POS(GPIOx); + MODIFY_REG(MCU_SUB->DPAD_RTYP_BUS, pin_mask, (pull == LL_GPIO_PULL_UP) ? pin_mask : 0x0000U); + MODIFY_REG(MCU_SUB->DPAD_RE_N_BUS, pin_mask, (pull == LL_GPIO_PULL_NO) ? pin_mask : 0x0000U); +} + +/** + * @brief Return gpio pull-up or pull-down for a dedicated pin on a dedicated port + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_RE_N_BUS | RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_RTYP_BUS | RTYP + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + */ +__STATIC_INLINE uint32_t ll_gpio_get_pin_pull(gpio_regs_t *GPIOx, uint32_t pin) +{ + /* Get pin position in resitor related registers, GPIO0:0~15, GPIO1:16~31 */ + pin <<= LL_GPIO_GET_RESISTOR_POS(GPIOx); + return ((READ_BITS(MCU_SUB->DPAD_RE_N_BUS, pin) != RESET) ? LL_GPIO_PULL_NO : + ((READ_BITS(MCU_SUB->DPAD_RTYP_BUS, pin) != RESET) ? LL_GPIO_PULL_UP : LL_GPIO_PULL_DOWN)); +} + +/** + * @brief Configure gpio pinmux number of a dedicated pin from 0 to 7 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_MUX_CTRL0_7 | CTRL0_7 | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_MUX_CTRL16_23 | CTRL16_23 + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @param mux This parameter can be one of the following values: + * @arg @ref LL_GPIO_MUX_0 + * @arg @ref LL_GPIO_MUX_1 + * @arg @ref LL_GPIO_MUX_2 + * @arg @ref LL_GPIO_MUX_3 + * @arg @ref LL_GPIO_MUX_4 + * @arg @ref LL_GPIO_MUX_5 + * @arg @ref LL_GPIO_MUX_6 + * @arg @ref LL_GPIO_MUX_7 + * @arg @ref LL_GPIO_MUX_8 + * @retval None + */ +__STATIC_INLINE void ll_gpio_set_mux_pin_0_7(gpio_regs_t *GPIOx, uint32_t pin, uint32_t mux) +{ + volatile uint32_t *pReg = LL_GPIO_GET_REG_MUX_CTRL_0_7(GPIOx); + uint32_t pos = POSITION_VAL(pin) << 2; + MODIFY_REG(*pReg, 0xF << pos, mux << pos); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_MUX_CTRL0_7 | CTRL0_7 | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_MUX_CTRL16_23 | CTRL16_23 + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_MUX_0 + * @arg @ref LL_GPIO_MUX_1 + * @arg @ref LL_GPIO_MUX_2 + * @arg @ref LL_GPIO_MUX_3 + * @arg @ref LL_GPIO_MUX_4 + * @arg @ref LL_GPIO_MUX_5 + * @arg @ref LL_GPIO_MUX_6 + * @arg @ref LL_GPIO_MUX_7 + * @arg @ref LL_GPIO_MUX_8 + */ +__STATIC_INLINE uint32_t ll_gpio_get_mux_pin_0_7(gpio_regs_t *GPIOx, uint32_t pin) +{ + volatile uint32_t *pReg = LL_GPIO_GET_REG_MUX_CTRL_0_7(GPIOx); + uint32_t pos = POSITION_VAL(pin) << 2; + return (READ_BITS(*pReg, 0xF << pos) >> pos); +} + +/** + * @brief Configure gpio alternate function of a dedicated pin from 8 to 15 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_MUX_CTRL8_15 | CTRL8_15 | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_MUX_CTRL24_31 | CTRL24_31 + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param mux This parameter can be one of the following values: + * @arg @ref LL_GPIO_MUX_0 + * @arg @ref LL_GPIO_MUX_1 + * @arg @ref LL_GPIO_MUX_2 + * @arg @ref LL_GPIO_MUX_3 + * @arg @ref LL_GPIO_MUX_4 + * @arg @ref LL_GPIO_MUX_5 + * @arg @ref LL_GPIO_MUX_6 + * @arg @ref LL_GPIO_MUX_7 + * @arg @ref LL_GPIO_MUX_8 + * @retval None + */ +__STATIC_INLINE void ll_gpio_set_mux_pin_8_15(gpio_regs_t *GPIOx, uint32_t pin, uint32_t mux) +{ + volatile uint32_t *pReg = LL_GPIO_GET_REG_MUX_CTRL_8_15(GPIOx); + uint32_t pos = POSITION_VAL(pin >> 8) << 2; + MODIFY_REG(*pReg, 0xF << pos, mux << pos); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 8 to 15 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DPAD_MUX_CTRL8_15 | CTRL8_15 | + * +----------------------+-----------------------------------+ + * \endrst + * DPAD_MUX_CTRL24_31 | CTRL24_31 + * + * @param GPIOx GPIO Port + * @param pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_MUX_0 + * @arg @ref LL_GPIO_MUX_1 + * @arg @ref LL_GPIO_MUX_2 + * @arg @ref LL_GPIO_MUX_3 + * @arg @ref LL_GPIO_MUX_4 + * @arg @ref LL_GPIO_MUX_5 + * @arg @ref LL_GPIO_MUX_6 + * @arg @ref LL_GPIO_MUX_7 + * @arg @ref LL_GPIO_MUX_8 + */ +__STATIC_INLINE uint32_t ll_gpio_get_mux_pin_8_15(gpio_regs_t *GPIOx, uint32_t pin) +{ + volatile uint32_t *pReg = LL_GPIO_GET_REG_MUX_CTRL_8_15(GPIOx); + uint32_t pos = POSITION_VAL(pin >> 8) << 2; + return (READ_BITS(*pReg, 0xF << pos) >> pos); +} + +/** @} */ + +/** @defgroup GPIO_LL_EF_Data_Access Data Access + * @{ + */ + +/** + * @brief Return full input data register value for a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @retval Input data register value of port + */ +__STATIC_INLINE uint32_t ll_gpio_read_input_port(gpio_regs_t *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->DATA)); +} + +/** + * @brief Return if input data level for several pins of dedicated port is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_input_pin_set(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return (READ_BITS(GPIOx->DATA, pin_mask) == (pin_mask)); +} + +/** + * @brief Write output data register for the port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param port_value Level value for each pin of the port + * @retval None + */ +__STATIC_INLINE void ll_gpio_write_output_port(gpio_regs_t *GPIOx, uint32_t port_value) +{ + WRITE_REG(GPIOx->DATAOUT, port_value); +} + +/** + * @brief Return full output data register value for a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @retval Output data register value of port + */ +__STATIC_INLINE uint32_t ll_gpio_read_output_port(gpio_regs_t *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->DATAOUT)); +} + +/** + * @brief Return if input data level for several pins of dedicated port is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_output_pin_set(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return (READ_BITS(GPIOx->DATAOUT, pin_mask) == (pin_mask)); +} + +/** + * @brief Set several pins to high level on dedicated gpio port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_set_output_pin(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ +#ifdef USE_GPIO_MASK_REGISTER + WRITE_REG(GPIOx->MASKLOWBYTE[(uint8_t)pin_mask], pin_mask & GPIO_MASKLOWBYTE_DATA); + WRITE_REG(GPIOx->MASKHIGHBYTE[(uint8_t)(pin_mask >> GPIO_MASKHIGHBYTE_DATA_Pos)], + pin_mask & GPIO_MASKHIGHBYTE_DATA); +#else + SET_BITS(GPIOx->DATAOUT, pin_mask); +#endif +} + +/** + * @brief Set several pins to low level on dedicated gpio port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_reset_output_pin(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ +#ifdef USE_GPIO_MASK_REGISTER + WRITE_REG(GPIOx->MASKLOWBYTE[(uint8_t)pin_mask], 0x0000U); + WRITE_REG(GPIOx->MASKHIGHBYTE[(uint8_t)(pin_mask >> 8)], 0x0000U); +#else + CLEAR_BITS(GPIOx->DATAOUT, pin_mask); +#endif +} + +/** + * @brief Toggle data value for several pin of dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATAOUT | DATAOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO Port + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_toggle_pin(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->DATAOUT, READ_REG(GPIOx->DATAOUT) ^ pin_mask); +} + +/** @} */ + +/** @defgroup GPIO_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable GPIO Falling Edge Trigger for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_enable_falling_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTPOLCLR, pin_mask); + WRITE_REG(GPIOx->INTTYPESET, pin_mask); +} + +/** + * @brief Check if falling edge trigger is enabled for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_enabled_falling_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return ((READ_BITS(GPIOx->INTPOLCLR, pin_mask) == (pin_mask)) && + (READ_BITS(GPIOx->INTTYPESET, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable GPIO Rising Edge Trigger for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_enable_rising_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTPOLSET, pin_mask); + WRITE_REG(GPIOx->INTTYPESET, pin_mask); +} + +/** + * @brief Check if rising edge trigger is enabled for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPESET | INTTYPESET + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @note Please check each device line mapping for GPIO Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_enabled_rising_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return ((READ_BITS(GPIOx->INTPOLSET, pin_mask) == (pin_mask)) && + (READ_BITS(GPIOx->INTTYPESET, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable GPIO High Level Trigger for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_enable_high_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTPOLSET, pin_mask); + WRITE_REG(GPIOx->INTTYPECLR, pin_mask); +} + +/** + * @brief Check if high level trigger is enabled for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLSET | INTPOLSET | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_enabled_high_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return ((READ_BITS(GPIOx->INTPOLSET, pin_mask) == (pin_mask)) && + (READ_BITS(GPIOx->INTTYPECLR, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable GPIO Low Level Trigger for pins in the range of 0 to 15. + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_enable_low_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTPOLCLR, pin_mask); + WRITE_REG(GPIOx->INTTYPECLR, pin_mask); +} + +/** + * @brief Check if low level trigger is enabled for pins in the range of 0 to 15 + * @note + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTPOLCLR | INTPOLCLR | + * +----------------------+-----------------------------------+ + * \endrst + * INTTYPECLR | INTTYPECLR + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_enabled_low_trigger(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return ((READ_BITS(GPIOx->INTPOLCLR, pin_mask) == (pin_mask)) && + (READ_BITS(GPIOx->INTTYPECLR, pin_mask) == (pin_mask))); +} + +/** + * @brief Enable GPIO interrupts for pins in the range of 0 to 15. + * @note @ref GPIO_LL_EC_TRIGGER can be used to specify the interrupt trigger type + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENSET | INTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_enable_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTENSET, pin_mask); +} + +/** + * @brief Disable GPIO interrupts for pins in the range of 0 to 15. + * @note @ref GPIO_LL_EC_TRIGGER can be used to specify the interrupt trigger type + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENCLR | INTENCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_disable_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTENCLR, pin_mask); +} + +/** + * @brief Check if the Interrupt of specified GPIO pins is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTENSET | INTENSET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_enabled_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return (READ_BITS(GPIOx->INTENSET, pin_mask) == (pin_mask)); +} + +/** @} */ + +/** @defgroup GPIO_LL_EF_Flag_Management Flag_Management + * @{ + */ + +/** + * @brief Read GPIO Interrupt Combination Flag for pins in the range of 0 to 15 + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can be cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval Interrupt flag whose bits were set when the selected trigger event arrives on the interrupt + */ +__STATIC_INLINE uint32_t ll_gpio_read_flag_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return (uint32_t)(READ_BITS(GPIOx->INTSTAT, pin_mask)); +} + +/** + * @brief Indicates if the GPIO Interrupt Flag is set or not for pins in the range of 0 to 15. + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can be cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_gpio_is_active_flag_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + return (READ_BITS(GPIOx->INTSTAT, pin_mask) == pin_mask); +} + +/** + * @brief Clear Interrupt Status flag for pins in the range of 0 to 15. + * @note After an interrupt is triggered, the corresponding bit in the INTSTATUS Register is set. + * The interrupt status can be cleared by writing 1 to corresponding bit in INTCLEAR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTATUS | INTSTATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param GPIOx GPIO instance. + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_gpio_clear_flag_it(gpio_regs_t *GPIOx, uint32_t pin_mask) +{ + WRITE_REG(GPIOx->INTSTAT, pin_mask); +} + +/** @} */ + +/** @defgroup GPIO_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize GPIO registers (Registers restored to their default values). + * @param GPIOx GPIO instance. + * @retval An error_status_t enumeration value: + * - SUCCESS: GPIO registers are de-initialized + * - ERROR: GPIO registers are not de-initialized + */ +error_status_t ll_gpio_deinit(gpio_regs_t *GPIOx); + +/** + * @brief Initialize GPIO registers according to the specified + * parameters in p_gpio_init. + * @param GPIOx GPIO instance. + * @param p_gpio_init Pointer to a ll_gpio_init_t structure that contains the configuration + * information for the specified GPIO peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: GPIO registers are initialized according to p_gpio_init content + * - ERROR: Problem occurred during GPIO Registers initialization + */ +error_status_t ll_gpio_init(gpio_regs_t *GPIOx, ll_gpio_init_t *p_gpio_init); + +/** + * @brief Set each field of a @ref ll_gpio_init_t type structure to default value. + * @param p_gpio_init Pointer to a @ref ll_gpio_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_gpio_struct_init(ll_gpio_init_t *p_gpio_init); + +/** @} */ + +/** @} */ + +#endif /* defined (GPIO0) || defined (GPIO1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_GPIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_hmac.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_hmac.h new file mode 100644 index 0000000..22e74c1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_hmac.h @@ -0,0 +1,1425 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_hmac.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of HMAC LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_HMAC HMAC + * @brief HMAC LL module driver. + * @{ + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_HMAC_H__ +#define __GR55XX_LL_HMAC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (HMAC) + +/** @defgroup HMAC_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HMAC_LL_ES_INIT HMAC Exported Init structures + * @{ + */ + +/** + * @brief LL HMAC Init Structure definition + */ +typedef struct _ll_hmac_init_t +{ + uint32_t *p_key; /**< Key */ + + uint32_t *p_hash; /**< HASH value */ + +} ll_hmac_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup HMAC_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HMAC_LL_Exported_Constants HMAC Exported Constants + * @{ + */ + +/** @defgroup HMAC_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags definitions which can be used with LL_HMAC_ReadReg function + * @{ + */ +#define LL_HMAC_FLAG_DATAREADY_SHA HMAC_STATUS_DATAREADY_SHA /**< HMAC data ready(SHA mode) */ +#define LL_HMAC_FLAG_DATAREADY_HMAC HMAC_STATUS_DATAREADY_HMAC /**< HMAC data ready(HAMC mode) */ +#define LL_HMAC_FLAG_DMA_MESSAGEDONE HMAC_STATUS_MESSAGEDONE_DMA /**< HMAC dma message done */ +#define LL_HMAC_FLAG_DMA_DONE HMAC_STATUS_TRANSDONE_DMA /**< HMAC dma transfer done */ +#define LL_HMAC_FLAG_DMA_ERR HMAC_STATUS_TRANSERR_DMA /**< HMAC dma transfer error */ +#define LL_HMAC_FLAG_KEY_VALID HMAC_STATUS_KEYVALID /**< HMAC has fetched key */ +/** @} */ + +/** @defgroup HMAC_LL_EC_HASH_MODE Hash Mode + * @{ + */ +#define LL_HMAC_HASH_STANDARD 0x00000000U /**< Standard Mode */ +#define LL_HMAC_HASH_USER (1UL << HMAC_CONFIG_ENABLE_USERHASH) /**< User Mode */ +/** @} */ + +/** @defgroup HMAC_LL_EC_CALCULATE_TYPE Calculate Type + * @{ + */ +#define LL_HMAC_CALCULATETYPE_HMAC 0x00000000U /**< HMAC mode */ +#define LL_HMAC_CALCULATETYPE_SHA (1UL << HMAC_CONFIG_CALCTYPE_Pos) /**< SHA moe */ +/** @} */ + +/** @defgroup HMAC_LL_EC_KEY_TYPE Key Type + * @{ + */ +#define LL_HMAC_KEYTYPE_MCU 0x00000000U /**< MCU */ +#define LL_HMAC_KEYTYPE_AHB (1UL << HMAC_CONFIG_KEYTYPE_Pos) /**< AHB master */ +#define LL_HMAC_KEYTYPE_KRAM (2UL << HMAC_CONFIG_KEYTYPE_Pos) /**< Key Port */ +/** @} */ + +/** @defgroup HMAC_LL_EC_TRANSFER_SIZE Transfer Size + * @{ + */ +#define LL_HMAC_DMA_TRANSIZE_MIN (1) /**< Min size = 1 block */ +#define LL_HMAC_DMA_TRANSIZE_MAX (512) /**< Min size = 512 blocks */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HMAC_LL_Exported_Macros HMAC Exported Macros + * @{ + */ + +/** @defgroup HMAC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in HMAC register + * @param __INSTANCE__ HMAC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_HMAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in HMAC register + * @param __INSTANCE__ HMAC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_HMAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup HMAC_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup HMAC_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable HMAC. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CTRL, HMAC_CTRL_ENABLE); +} + +/** + * @brief Disable HMAC. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CTRL, HMAC_CTRL_ENABLE); +} + +/** + * @brief Indicate whether the HMAC is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CTRL, HMAC_CTRL_ENABLE) == (HMAC_CTRL_ENABLE)); +} + +/** + * @brief Enable HMAC DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_dma_start(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CTRL, HMAC_CTRL_START_DMA); +} + +/** + * @brief Disable HMAC DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_dma_start(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CTRL, HMAC_CTRL_START_DMA); +} + +/** + * @brief Indicate whether the HMAC DMA mode is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_dma_start(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CTRL, HMAC_CTRL_START_DMA) == (HMAC_CTRL_START_DMA)); +} + +/** + * @brief Enable fetch key through AHB/key port. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ENABLE_RKEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_read_key(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CTRL, HMAC_CTRL_ENABLE_RKEY); +} + +/** + * @brief Enable last block transfer in MCU/DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | LASTTRANSFER | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_last_transfer(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CTRL, HMAC_CTRL_LASTTRANSFER); +} + +/** + * @brief Enable user HASH. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENABLE_USERHASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_user_hash(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CONFIG, HMAC_CONFIG_ENABLE_USERHASH); +} + +/** + * @brief Disable user HASH. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENABLE_USERHASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_user_hash(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CONFIG, HMAC_CONFIG_ENABLE_USERHASH); +} + +/** + * @brief Indicate whether the user HASH is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENABLE_USERHASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_user_hash(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CONFIG, HMAC_CONFIG_ENABLE_USERHASH) == (HMAC_CONFIG_ENABLE_USERHASH)); +} + +/** + * @brief Enable HMAC in little endian. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_little_endian(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CONFIG, HMAC_CONFIG_ENDIAN); +} + +/** + * @brief Disable HMAC in little endian. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_little_endian(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CONFIG, HMAC_CONFIG_ENDIAN); +} + +/** + * @brief Indicate whether the HMAC is in little endian. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | ENDIAN | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_little_endian(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CONFIG, HMAC_CONFIG_ENDIAN) == (HMAC_CONFIG_ENDIAN)); +} + +/** + * @brief Set ways to obtain HMAC key. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | KEYTYPE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param type This parameter can be one of the following values: + * @arg @ref LL_HMAC_KEYTYPE_MCU + * @arg @ref LL_HMAC_KEYTYPE_AHB + * @arg @ref LL_HMAC_KEYTYPE_KRAM + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key_type(hmac_regs_t *HMACx, uint32_t type) +{ + MODIFY_REG(HMACx->CONFIG, HMAC_CONFIG_KEYTYPE, type); +} + +/** + * @brief Get ways to obtain HMAC key. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | KEYTYPE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_HMAC_KEYTYPE_MCU + * @arg @ref LL_HMAC_KEYTYPE_AHB + * @arg @ref LL_HMAC_KEYTYPE_KRAM + */ +__STATIC_INLINE uint32_t ll_hmac_get_key_type(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CONFIG, HMAC_CONFIG_KEYTYPE)); +} + +/** + * @brief Enable SHA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | CALCTYPE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_sha(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CONFIG, HMAC_CONFIG_CALCTYPE); +} + +/** + * @brief Disable SHA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | CALCTYPE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_sha(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CONFIG, HMAC_CONFIG_CALCTYPE); +} + +/** + * @brief Indicate whether the SHA mode is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | CALCTYPE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_sha(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CONFIG, HMAC_CONFIG_CALCTYPE) == (HMAC_CONFIG_CALCTYPE)); +} + +/** + * @brief Enable private mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | PRIVATE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_private(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->CONFIG, HMAC_CONFIG_PRIVATE); +} + +/** + * @brief Disable private mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | PRIVATE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_private(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->CONFIG, HMAC_CONFIG_PRIVATE); +} + +/** + * @brief Indicate whether the private mode is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | PRIVATE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_private(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->CONFIG, HMAC_CONFIG_PRIVATE) == (HMAC_CONFIG_PRIVATE)); +} + +/** @} */ + +/** @defgroup HMAC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable the done interrupt for HMAC. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_enable_it_done(hmac_regs_t *HMACx) +{ + SET_BITS(HMACx->INTERRUPT, HMAC_INTERRUPT_ENABLE); +} + +/** + * @brief Disable the done interrupt for HMAC. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_disable_it_done(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->INTERRUPT, HMAC_INTERRUPT_ENABLE); +} + +/** + * @brief Indicate whether Done Interrupt is enabled. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTERRUPT | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_enabled_it_done(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->INTERRUPT, HMAC_INTERRUPT_ENABLE) == (HMAC_INTERRUPT_ENABLE)); +} + +/** @} */ + +/** @defgroup HMAC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Indicate whether SHA Ready flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | DATAREADY_SHA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_sha_ready(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_DATAREADY_SHA) == HMAC_STATUS_DATAREADY_SHA); +} + +/** + * @brief Indicate whether HMAC Ready flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | DATAREADY_HMAC | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_hmac_ready(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_DATAREADY_HMAC) == HMAC_STATUS_DATAREADY_HMAC); +} + +/** + * @brief Indicate whether DMA Transmit Message Done flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | MESSAGEDONE_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_dma_message_done(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_MESSAGEDONE_DMA) == HMAC_STATUS_MESSAGEDONE_DMA); +} + +/** + * @brief Indicate whether DMA Transfer Done flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | TRANSDONE_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_dma_done(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_TRANSDONE_DMA) == HMAC_STATUS_TRANSDONE_DMA); +} + +/** + * @brief Indicate whether DMA Transfer Error flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | TRANSERR_DMA | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_dma_error(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_TRANSERR_DMA) == HMAC_STATUS_TRANSERR_DMA); +} + +/** + * @brief Indicate whether Key Valid flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | KEYVALID | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_key_valid(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->STATUS, HMAC_STATUS_KEYVALID) == HMAC_STATUS_KEYVALID); +} + +/** + * @brief Indicate whether Done interrupt flag is set. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTERRUPT | DONE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_hmac_is_action_flag_it_done(hmac_regs_t *HMACx) +{ + return (READ_BITS(HMACx->INTERRUPT, HMAC_INTERRUPT_DONE) == HMAC_INTERRUPT_DONE); +} + +/** + * @brief Clear Done interrupt flag. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTERRUPT | DONE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval None + */ +__STATIC_INLINE void ll_hmac_clear_flag_it_done(hmac_regs_t *HMACx) +{ + CLEAR_BITS(HMACx->INTERRUPT, HMAC_INTERRUPT_DONE); +} + +/** @} */ + +/** @defgroup HMAC_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Set HMAC transfer blocks in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRANSIZE | TRANSIZE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param block This parameter can be one of the following values: 1 ~ 512 + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_dma_transfer_block(hmac_regs_t *HMACx, uint32_t block) +{ + MODIFY_REG(HMACx->TRAN_SIZE, HMAC_TRANSIZE, (block << 6) - 1); +} + +/** + * @brief Get HMAC transfer blocks in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TRANSIZE | TRANSIZE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Return value is between: 1 ~ 512 + */ +__STATIC_INLINE uint32_t ll_hmac_get_dma_transfer_block(hmac_regs_t *HMACx) +{ + return ((READ_BITS(HMACx->TRAN_SIZE, HMAC_TRANSIZE) + 1) >> 6); +} + +/** + * @brief Set HMAC read address of RAM in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RSTART_ADDR | RSTART_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param address This parameter can be one of the address in RAM + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_dma_read_address(hmac_regs_t *HMACx, uint32_t address) +{ + WRITE_REG(HMACx->RSTART_ADDR, address); +} + +/** + * @brief Get HMAC read address of RAM in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RSTART_ADDR | RSTART_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Return value is the address in RAM + */ +__STATIC_INLINE uint32_t ll_hmac_get_dma_read_address(hmac_regs_t *HMACx) +{ + return (READ_REG(HMACx->RSTART_ADDR)); +} + +/** + * @brief Set HMAC write address of RAM in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | WSTART_ADDR | WSTART_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param address This parameter can be one of the address in RAM + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_dma_write_address(hmac_regs_t *HMACx, uint32_t address) +{ + WRITE_REG(HMACx->WSTART_ADDR, address); +} + +/** + * @brief Get HMAC write address of RAM in DMA mode. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | WSTART_ADDR | WSTART_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Return value is the address in RAM + */ +__STATIC_INLINE uint32_t ll_hmac_get_dma_write_address(hmac_regs_t *HMACx) +{ + return (READ_REG(HMACx->WSTART_ADDR)); +} + +/** @} */ + +/** @defgroup HMAC_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Set user HASH[255:224]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[0] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_255_224(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[0], hash); +} + +/** + * @brief Set user HASH[223:192]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[1] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_223_192(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[1], hash); +} + +/** + * @brief Set user HASH[191:160]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[2] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_191_160(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[2], hash); +} + +/** + * @brief Set user HASH[159:128]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[3] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_159_128(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[3], hash); +} + +/** + * @brief Set user HASH[127:96]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[4] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_127_96(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[4], hash); +} + +/** + * @brief Set user HASH[95:64]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[5] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_95_64(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[5], hash); +} + +/** + * @brief Set user HASH[63:32]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[6] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_63_32(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[6], hash); +} + +/** + * @brief Set user HASH[31:0]. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER_HASH[7] | USER_HASH | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param hash This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_user_hash_31_0(hmac_regs_t *HMACx, uint32_t hash) +{ + WRITE_REG(HMACx->USER_HASH[7], hash); +} + +/** + * @brief Get abstract from HMAC. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | FIFO_OUT | FIFO_OUT | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Abstract + */ +__STATIC_INLINE uint32_t ll_hmac_get_data(hmac_regs_t *HMACx) +{ + return (READ_REG(HMACx->FIFO_OUT)); +} + +/** + * @brief Send data to calculate. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | FIFO_MESSAGE | FIFO_MESSAGE | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param data This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_data(hmac_regs_t *HMACx, uint32_t data) +{ + WRITE_REG(HMACx->MESSAGE_FIFO, data); +} + +/** + * @brief Set HMAC key0. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[0] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key0(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[0], key); +} + +/** + * @brief Set HMAC key1. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[1] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key1(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[1], key); +} + +/** + * @brief Set HMAC key2. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[2] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key2(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[2], key); +} + +/** + * @brief Set HMAC key3. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[3] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key3(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[3], key); +} + +/** + * @brief Set HMAC key4. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[4] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key4(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[4], key); +} + +/** + * @brief Set HMAC key5. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[5] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key5(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[5], key); +} + +/** + * @brief Set HMAC key6. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[6] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key6(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[6], key); +} + +/** + * @brief Set HMAC key7. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY[7] | KEY | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param key This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key7(hmac_regs_t *HMACx, uint32_t key) +{ + WRITE_REG(HMACx->KEY[7], key); +} + +/** + * @brief Set HMAC key address in memory. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY_ADDR | KEY_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param address This parameter can be one of the address in RAM + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key_address(hmac_regs_t *HMACx, uint32_t address) +{ + WRITE_REG(HMACx->KEY_ADDR, address); +} + +/** + * @brief Get HMAC key address in memory. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KEY_ADDR | KEY_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @retval Return value is the address in RAM + */ +__STATIC_INLINE uint32_t ll_hmac_get_key_address(hmac_regs_t *HMACx) +{ + return (READ_REG(HMACx->KEY_ADDR)); +} + +/** + * @brief Set HMAC fetch key port mask. + + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | KPORT_MASK | KPORT_MASK | + * +----------------------+-----------------------------------+ + * \endrst + + * @param HMACx HMAC instance + * @param mask This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_hmac_set_key_port_mask(hmac_regs_t *HMACx, uint32_t mask) +{ + WRITE_REG(HMACx->KPORT_MASK, mask); +} + +/** @} */ + +/** @defgroup HMAC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize HMAC registers (Registers restored to their default values). + * @param HMACx HMAC Instance + * @retval An error_status_t enumeration value: + * - SUCCESS: HMAC registers are de-initialized + * - ERROR: HMAC registers are not de-initialized + */ +error_status_t ll_hmac_deinit(hmac_regs_t *HMACx); + +/** + * @brief Initialize HMAC registers according to the specified + * parameters in p_hmac_init. + * @param HMACx HMAC Instance + * @param p_hmac_init Pointer to a ll_hmac_init_t structure that contains the configuration + * information for the specified HMAC peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: HMAC registers are initialized according to p_hmac_init content + * - ERROR: Problem occurred during HMAC Registers initialization + */ +error_status_t ll_hmac_init(hmac_regs_t *HMACx, ll_hmac_init_t *p_hmac_init); + +/** + * @brief Set each field of a @ref ll_hmac_init_t type structure to default value. + * @param p_hmac_init Pointer to a @ref ll_hmac_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_hmac_struct_init(ll_hmac_init_t *p_hmac_init); + +/** @} */ + +/** @} */ + +#endif /* HMAC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_HMAC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2c.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2c.h new file mode 100644 index 0000000..06cb55d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2c.h @@ -0,0 +1,3961 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_i2c.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2C LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_I2C I2C + * @brief I2C LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_I2C_H__ +#define __GR55xx_LL_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (I2C0) || defined (I2C1) + +/** @defgroup I2C_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_LL_ES_INIT I2C Exported init structure + * @{ + */ + +/** + * @brief LL I2C init Structure definition + */ +typedef struct _ll_i2c_init +{ + uint32_t speed; /**< Specifies the transfer speed. See @ref I2C_LL_EC_SPEED. */ + + uint32_t own_address; /**< Specifies the device own address. + This parameter must be a value between Min_Data = 0x00 and Max_Data = 0x3FF + + This feature can be modified afterwards using unitary function @ref ll_i2c_set_own_address(). */ + + uint32_t own_addr_size; /**< Specifies the device own address 1 size (7-bit or 10-bit). + This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS + + This feature can be modified afterwards using unitary function @ref ll_i2c_set_own_address(). */ +} ll_i2c_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup I2C_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_LL_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags definitions which can be used with LL_I2C_ReadReg function + * @{ + */ +#define LL_I2C_INTR_STAT_MST_ON_HOLD I2C_INTR_GEN_CALL /**< MST_ON_HOLD interrupt flag */ +#define LL_I2C_INTR_STAT_RESTART_DET I2C_INTR_RESTART_DET /**< RESTART_DET interrupt flag */ +#define LL_I2C_INTR_STAT_GEN_CALL I2C_INTR_GEN_CALL /**< GEN_CALL interrupt flag */ +#define LL_I2C_INTR_STAT_START_DET I2C_INTR_START_DET /**< START_DET interrupt flag */ +#define LL_I2C_INTR_STAT_STOP_DET I2C_INTR_STOP_DET /**< STOP_DET interrupt flag */ +#define LL_I2C_INTR_STAT_ACTIVITY I2C_INTR_ACTIVITY /**< ACTIVITY interrupt flag */ +#define LL_I2C_INTR_STAT_RX_DONE I2C_INTR_RX_DONE /**< RX_DONE interrupt flag */ +#define LL_I2C_INTR_STAT_TX_ABRT I2C_INTR_TX_ABRT /**< TX_ABRT interrupt flag */ +#define LL_I2C_INTR_STAT_RD_REQ I2C_INTR_RD_REQ /**< RD_REQ interrupt flag */ +#define LL_I2C_INTR_STAT_TX_EMPTY I2C_INTR_TX_EMPTY /**< TX_EMPTY interrupt flag */ +#define LL_I2C_INTR_STAT_TX_OVER I2C_INTR_TX_OVER /**< TX_OVER interrupt flag */ +#define LL_I2C_INTR_STAT_RX_FULL I2C_INTR_RX_FULL /**< RX_FULL interrupt flag */ +#define LL_I2C_INTR_STAT_RX_OVER I2C_INTR_RX_OVER /**< RX_OVER interrupt flag */ +#define LL_I2C_INTR_STAT_RX_UNDER I2C_INTR_RX_UNDER /**< RX_UNDER interrupt flag */ + +#define LL_I2C_ABRT_TX_FLUSH_CNT I2C_TX_ABRT_SRC_TX_FLUSH_CNT /**< Transfer abort detected by master */ +#define LL_I2C_ABRT_USER_ABRT I2C_TX_ABRT_SRC_USER_ABRT /**< Transfer abort detected by master */ +#define LL_I2C_ABRT_SLVRD_INTX I2C_TX_ABRT_SRC_SLVRD_INTX /**< Slave trying to transmit to remote master in read mode */ +#define LL_I2C_ABRT_SLV_ARBLOST I2C_TX_ABRT_SRC_SLV_ARBLOST /**< Slave lost arbitration to remote master */ +#define LL_I2C_ABRT_SLVFLUSH_TXFIFO I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO /**< Slave flushes existing data in TX-FIFO upon getting read command */ +#define LL_I2C_ABRT_ARB_LOST I2C_TX_ABRT_SRC_ARB_LOST /**< Master or Slave Transmitter lost arbitration */ +#define LL_I2C_ABRT_MST_DIS I2C_TX_ABRT_SRC_MST_DIS /**< User intitating master operation when MASTER disabled */ +#define LL_I2C_ABRT_10B_RD_NORSTRT I2C_TX_ABRT_SRC_10B_RD_NORSTRT /**< Master trying to read in 10-Bit addressing mode when RESTART disabled */ +#define LL_I2C_ABRT_SBYTE_NORSTRT I2C_TX_ABRT_SRC_SBYTE_NORSTRT /**< User trying to send START byte when RESTART disabled */ +#define LL_I2C_ABRT_HS_NORSTRT I2C_TX_ABRT_SRC_HS_NORSTRT /**< User trying to swidth Master to HS mode when RESTART disabled */ +#define LL_I2C_ABRT_SBYTE_ACKDET I2C_TX_ABRT_SRC_SBYTE_ACKDET /**< ACK detected for START byte */ +#define LL_I2C_ABRT_HS_ACKDET I2C_TX_ABRT_SRC_HS_ACKDET /**< HS Master code is ACKed in HS Mode */ +#define LL_I2C_ABRT_GCALL_READ I2C_TX_ABRT_SRC_GCALL_READ /**< GCALL is followed by read from bus */ +#define LL_I2C_ABRT_GCALL_NOACK I2C_TX_ABRT_SRC_GCALL_NOACK /**< GCALL is not ACKed by any slave */ +#define LL_I2C_ABRT_TXDATA_NOACK I2C_TX_ABRT_SRC_TXDATA_NOACK /**< Transmitted data is not ACKed by addressed slave */ +#define LL_I2C_ABRT_10ADDR2_NOACK I2C_TX_ABRT_SRC_10ADDR2_NOACK /**< Byte 2 of 10-Bit Address is not ACKed by any slave */ +#define LL_I2C_ABRT_10ADDR1_NOACK I2C_TX_ABRT_SRC_10ADDR1_NOACK /**< Byte 1 of 10-Bit Address is not ACKed by any slave */ +#define LL_I2C_ABRT_7B_ADDR_NOACK I2C_TX_ABRT_SRC_7B_ADDR_NOACK /**< 7Bit Address is not ACKed by any slave */ +/** @} */ + +/** @defgroup I2C_LL_EC_IT IT Defines + * @brief Interrupt definitions which can be used with LL_I2C_ReadReg and LL_I2C_WriteReg functions + * @{ + */ +#define LL_I2C_INTR_MASK_MST_ON_HOLD I2C_INTR_GEN_CALL /**< MST_ON_HOLD interrupt */ +#define LL_I2C_INTR_MASK_RESTART_DET I2C_INTR_RESTART_DET /**< RESTART_DET interrupt */ +#define LL_I2C_INTR_MASK_GEN_CALL I2C_INTR_GEN_CALL /**< GEN_CALL interrupt */ +#define LL_I2C_INTR_MASK_START_DET I2C_INTR_START_DET /**< START_DET interrupt */ +#define LL_I2C_INTR_MASK_STOP_DET I2C_INTR_STOP_DET /**< STOP_DET interrupt */ +#define LL_I2C_INTR_MASK_ACTIVITY I2C_INTR_ACTIVITY /**< ACTIVITY interrupt */ +#define LL_I2C_INTR_MASK_RX_DONE I2C_INTR_RX_DONE /**< RX_DONE interrupt */ +#define LL_I2C_INTR_MASK_TX_ABRT I2C_INTR_TX_ABRT /**< TX_ABRT interrupt */ +#define LL_I2C_INTR_MASK_RD_REQ I2C_INTR_RD_REQ /**< RD_REQ interrupt */ +#define LL_I2C_INTR_MASK_TX_EMPTY I2C_INTR_TX_EMPTY /**< TX_EMPTY interrupt */ +#define LL_I2C_INTR_MASK_TX_OVER I2C_INTR_TX_OVER /**< TX_OVER interrupt */ +#define LL_I2C_INTR_MASK_RX_FULL I2C_INTR_RX_FULL /**< RX_FULL interrupt */ +#define LL_I2C_INTR_MASK_RX_OVER I2C_INTR_RX_OVER /**< RX_OVER interrupt */ +#define LL_I2C_INTR_MASK_RX_UNDER I2C_INTR_RX_UNDER /**< RX_UNDER interrupt */ + +#define LL_I2C_INTR_MASK_ALL 0x00000FFFU /**< All interrupt */ +/** @} */ + +/** @defgroup I2C_LL_EC_ADDRESSING_MODE Master Addressing Mode + * @{ + */ +#define LL_I2C_ADDRESSING_MODE_7BIT 0x00000000U /**< Master operates in 7-bit addressing mode. */ +#define LL_I2C_ADDRESSING_MODE_10BIT I2C_CON_10BITADDR_MST /**< Master operates in 10-bit addressing mode.*/ +/** @} */ + +/** @defgroup I2C_LL_EC_OWNADDRESS Own Address Length + * @{ + */ +#define LL_I2C_OWNADDRESS_7BIT 0x00000000U /**< Own address 1 is a 7-bit address. */ +#define LL_I2C_OWNADDRESS_10BIT I2C_CON_10BITADDR_SLV /**< Own address 1 is a 10-bit address.*/ +/** @} */ + + +/** @defgroup I2C_LL_EC_GENERATE Start And Stop Generation + * @{ + */ +#define LL_I2C_CMD_SLV_NONE 0x00000000U /**< Slave No command. */ +#define LL_I2C_CMD_MST_WRITE 0x00000000U /**< Master write command. */ +#define LL_I2C_CMD_MST_READ I2C_DATA_CMD_CMD /**< Master read command. */ +#define LL_I2C_CMD_MST_GEN_STOP I2C_DATA_CMD_STOP /**< Master issue STOP after this command. */ +#define LL_I2C_CMD_MST_GEN_RESTART I2C_DATA_CMD_RESTART /**< Master issue RESTART before this command. */ +/** @} */ + +/** @defgroup I2C_LL_EC_SPEED_MODE Transfer Speed Mode + * @{ + */ +#define LL_I2C_SPEED_MODE_STANDARD I2C_CON_SPEED_STANDARD /**< Standard Speed mode(0 to 100 Kb/s) of operation. */ +#define LL_I2C_SPEED_MODE_FAST I2C_CON_SPEED_FAST /**< Fast (鈮?400 Kb/s) or Fast Plus mode (鈮?1000 èžb/s) of operation. */ +#define LL_I2C_SPEED_MODE_HIGH I2C_CON_SPEED_HIGH /**< High Speed mode (鈮?3.4 Mb/s) of operation. */ +/** @} */ + +/** @defgroup I2C_LL_EC_SPEED Transfer Speed + * @{ + */ +#define LL_I2C_SPEED_100K (100000ul) /**< Standard Speed. */ +#define LL_I2C_SPEED_400K (400000ul) /**< Fast Speed. */ +#define LL_I2C_SPEED_1000K (1000000ul) /**< Fast Plus Speed. */ +#define LL_I2C_SPEED_2000K (2000000ul) /**< High Speed. */ +/** @} */ + +/** @defgroup I2C_LL_EC_DIRECTION Read Write Direction + * @{ + */ +#define LL_I2C_DIRECTION_NONE 0x00000000U /**< No transfer request by master. */ +#define LL_I2C_DIRECTION_WRITE I2C_INTR_RX_FULL /**< Write transfer request by master, slave enters receiver mode. */ +#define LL_I2C_DIRECTION_READ I2C_INTR_RD_REQ /**< Read transfer request by master, slave enters transmitter mode.*/ +#define LL_I2C_DIRECTION_ERROR I2C_INTR_RX_FULL | I2C_INTR_RD_REQ /**< Transfer request error. */ +/** @} */ + + +/** @defgroup I2C_LL_EC_TX_FIFO_TH TX FIFO Threshold + * @{ + */ +#define LL_I2C_TX_FIFO_TH_EMPTY 0x00000000U /**< TX FIFO empty */ +#define LL_I2C_TX_FIFO_TH_CHAR_1 0x00000001U /**< 1 character in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_2 0x00000002U /**< 2 characters in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_3 0x00000003U /**< 3 characters in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_4 0x00000004U /**< 4 characters in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_5 0x00000005U /**< 5 characters in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_6 0x00000006U /**< 6 characters in TX FIFO */ +#define LL_I2C_TX_FIFO_TH_CHAR_7 0x00000007U /**< 7 characters in TX FIFO */ +/** @} */ + +/** @defgroup I2C_LL_EC_RX_FIFO_TH RX FIFO Threshold + * @{ + */ +#define LL_I2C_RX_FIFO_TH_CHAR_1 0x00000000U /**< 1 character in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_2 0x00000001U /**< 2 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_3 0x00000002U /**< 3 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_4 0x00000003U /**< 4 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_5 0x00000004U /**< 5 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_6 0x00000005U /**< 6 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_CHAR_7 0x00000006U /**< 7 characters in RX FIFO */ +#define LL_I2C_RX_FIFO_TH_FULL 0x00000007U /**< RX FIFO full */ +/** @} */ + +/** @defgroup I2C_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL I2C InitStrcut default configuartion + */ +#define LL_I2C_DEFAULT_CONFIG \ +{ \ + .speed = LL_I2C_SPEED_400K, \ + .own_address = 0x55U, \ + .own_addr_size = LL_I2C_OWNADDRESS_7BIT, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_LL_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @defgroup I2C_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in I2C register + * @param __instance__ I2C instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None. + */ +#define LL_I2C_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I2C register + * @param __instance__ I2C instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I2C_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) +/** @} */ + +/** @defgroup I2C_LL_EM_Exported_Macros_Helper Exported_Macros_Helper + * @{ + */ + +/** + * @brief Compute CLK_SSL_CNT value according to Peripheral Clock and expected Speed. + * @param __PERIPHCLK__ Peripheral Clock frequency used for I2C instance + * @param __SPEED__ Speed value to achieve + * @retval CLK_SSL_CNT value to be used for XS_SCL_HCNT, XS_SCL_LCNT registers where X can be (S, F, H) + */ +#define __LL_I2C_CONVERT_CLK_SSL_CNT(__PERIPHCLK__, __SPEED__) ((__PERIPHCLK__) / 2 / (__SPEED__)) + +/** + * @brief Get Speed Mode according to expected Speed. + * @param __SPEED__ Speed value to achieve + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_SPEED_MODE_STANDARD + * @arg @ref LL_I2C_SPEED_MODE_FAST + * @arg @ref LL_I2C_SPEED_MODE_HIGH + */ +#define __LL_I2C_CONVERT_SPEED_MODE(__SPEED__) ((__SPEED__ <= LL_I2C_SPEED_100K) ? LL_I2C_SPEED_MODE_STANDARD : \ + ((__SPEED__ <= LL_I2C_SPEED_1000K) ? LL_I2C_SPEED_MODE_FAST : LL_I2C_SPEED_MODE_HIGH)) +/** @} */ + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2C_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup I2C_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable I2C peripheral (ENABLE = 1). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->ENABLE, I2C_ENABLE_ENABLE); +} + +/** + * @brief Disable I2C peripheral (ENABLE = 0). + * @note When ENABLE = 0, the TX FIFO and RX FIFO get flushed. + * Status bits in the IC_INTR_STAT register are still active until DW_apb_i2c goes into IDLE state. + * If the module is transmitting, it stops as well as deletes the contents of the transmit buffer + * after the current transfer is complete. If the module is receiving, the DW_apb_i2c stops + * the current transfer at the end of the current byte and does not acknowledge the transfer.. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE | ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->ENABLE, I2C_ENABLE_ENABLE); +} + +/** + * @brief Check if the I2C peripheral is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE_STATUS | IC_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->ENABLE_STATUS, I2C_ENABLE_STATUS_IC_EN) == (I2C_ENABLE_STATUS_IC_EN)); +} + +/** + * @brief Enable I2C master mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | MASTER_ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + * IC_CON | SLAVE_DISABLE + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_master_mode(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->CON, I2C_CON_MST_MODE | I2C_CON_SLV_DIS); +} + +/** + * @brief Disable I2C master mode and enable slave mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | MASTER_ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + * IC_CON | SLAVE_DISABLE + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_master_mode(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->CON, I2C_CON_MST_MODE | I2C_CON_SLV_DIS); +} + +/** + * @brief Check if I2C master mode is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | MASTER_ENABLE | + * +----------------------+-----------------------------------+ + * \endrst + * IC_CON | SLAVE_DISABLE + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_master_mode(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->CON, I2C_CON_MST_MODE | I2C_CON_SLV_DIS) == (I2C_CON_MST_MODE | I2C_CON_SLV_DIS)); +} + +/** + * @brief Enable General Call(slave mode). + * @note When enabled, the Address 0x00 is ACKed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ACK_GENERAL_CALL | ACK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_general_call(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->ACK_GENERAL_CALL, I2C_ACK_GENERAL_CALL_ACK_GC); +} + +/** + * @brief Disable General Call(slave mode). + * @note When disabled, the Address 0x00 is NACKed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ACK_GENERAL_CALL | ACK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_general_call(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->ACK_GENERAL_CALL, I2C_ACK_GENERAL_CALL_ACK_GC); +} + +/** + * @brief Check if General Call is enabled or disabled(slave mode). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ACK_GENERAL_CALL | ACK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_general_call(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->ACK_GENERAL_CALL, I2C_ACK_GENERAL_CALL_ACK_GC) == (I2C_ACK_GENERAL_CALL_ACK_GC)); +} + +/** + * @brief Enable Master Restart. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * This bit determines whether RESTART conditions may be sent when acting as a master. + * Some older slaves do not support handling RESTART conditions. + * When RESTART is disabled, the master is prohibited from performing the following functions: + * - Performing any high-speed mode operation. + * - Performing direction changes in combined format mode. + * - Performing a read operation with a 10-bit address. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_RESTART_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_master_restart(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->CON, I2C_CON_RESTART_EN); +} + +/** + * @brief Disable Master Restart. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_RESTART_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_master_restart(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->CON, I2C_CON_RESTART_EN); +} + +/** + * @brief Check if Master Restart is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_RESTART_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_master_restart(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->CON, I2C_CON_RESTART_EN) == (I2C_CON_RESTART_EN)); +} + +/** + * @brief Enable Slave issues STOP_DET interrupt only if addressed function. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * During a general call address, the slave does not issue the STOP_DET interrupt if + * STOP_DET_IF_ADDRESSED = 1'b1, even if the slave responds to the general call address + * by generating ACK. The STOP_DET interrupt is generated only when the transmitted + * address matches the slave address (SAR). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | STOP_DET_IF_ADDRESSED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_stop_det_if_addressed(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->CON, I2C_CON_STOP_DET_IF_ADDRESSED); +} + +/** + * @brief Disable Slave issues STOP_DET interrupt only if addressed function. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | STOP_DET_IF_ADDRESSED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_stop_det_if_addressed(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->CON, I2C_CON_STOP_DET_IF_ADDRESSED); +} + +/** + * @brief Check if Slave issues STOP_DET interrupt only if addressed function is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | STOP_DET_IF_ADDRESSED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_stop_det_if_addressed(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->CON, I2C_CON_STOP_DET_IF_ADDRESSED) == (I2C_CON_STOP_DET_IF_ADDRESSED)); +} + +/** + * @brief Configure the Master to transfers in 7-bit or 10-bit addressing mode. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_10BITADDR_MST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param addressing_mode This parameter can be one of the following values: + * @arg @ref LL_I2C_ADDRESSING_MODE_7BIT + * @arg @ref LL_I2C_ADDRESSING_MODE_10BIT + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_master_addressing_mode(i2c_regs_t *I2Cx, uint32_t addressing_mode) +{ + MODIFY_REG(I2Cx->CON, I2C_CON_10BITADDR_MST, addressing_mode); +} + +/** + * @brief Get the Master addressing mode. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_10BITADDR_MST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_ADDRESSING_MODE_7BIT + * @arg @ref LL_I2C_ADDRESSING_MODE_10BIT + */ +__STATIC_INLINE uint32_t ll_i2c_get_master_addressing_mode(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->CON, I2C_CON_10BITADDR_MST)); +} + +/** + * @brief Set the Own Address. + * @note The register IC_CON and IC_SAR can only be programmed when the I2C is disabled (IC_ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_10BITADDR_SLV | + * +----------------------+-----------------------------------+ + * \endrst + * IC_SAR | SAR + * + * @param I2Cx I2C instance. + * @param own_address This parameter must be a value range between 0 ~ 0x3FF(10-bit mode) or 0 ~ 0x7F(7-bit mode). + * Reserved address 0x00 to 0x07, or 0x78 to 0x7f should not be configured. + * @param own_addr_size This parameter can be one of the following values: + * @arg @ref LL_I2C_OWNADDRESS_7BIT + * @arg @ref LL_I2C_OWNADDRESS_10BIT + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_own_address(i2c_regs_t *I2Cx, uint32_t own_address, uint32_t own_addr_size) +{ + MODIFY_REG(I2Cx->CON, I2C_CON_10BITADDR_SLV, own_addr_size); + WRITE_REG(I2Cx->SAR, own_address); +} + +/** + * @brief Set the SCL clock high-period count for standard speed. + * @note The register IC_SS_SCL_HCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SS_SCL_HCNT | SS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count This parameter must be a value range between 6 ~ 0xFFF5. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_high_period_ss(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->SS_SCL_HCNT, count); +} + +/** + * @brief Get the SCL clock high-period count for standard speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SS_SCL_HCNT | SS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x6 and 0xFFF5. + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_high_period_ss(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->SS_SCL_HCNT, I2C_SS_SCL_HCNT)); +} + +/** + * @brief Set the SCL clock low-period count for standard speed. + * @note The register IC_SS_SCL_LCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SS_SCL_LCNT | SS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count This parameter must be a value range between 0x8 and 0xFFFF. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_low_period_ss(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->SS_SCL_LCNT, count); +} + +/** + * @brief Get the SCL clock low-period count for standard speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SS_SCL_LCNT | SS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x8 and 0xFFFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_low_period_ss(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->SS_SCL_LCNT, I2C_SS_SCL_LCNT)); +} + +/** + * @brief Set the SCL clock high-period count for fast speed. + * @note The register IC_FS_SCL_HCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SCL_HCNT | FS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count range between 0x6 and 0xFFFF. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_high_period_fs(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->FS_SCL_HCNT, count); +} + +/** + * @brief Get the SCL clock high-period count for fast speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SCL_HCNT | FS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x6 and 0xFFFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_high_period_fs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->FS_SCL_HCNT, I2C_FS_SCL_HCNT)); +} + +/** + * @brief Set the SCL clock low-period count for fast speed. + * @note The register IC_FS_SCL_LCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SCL_LCNT | FS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count range between 0x8 and 0xFFFF + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_low_period_fs(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->FS_SCL_LCNT, count); +} + +/** + * @brief Get the SCL clock low-period count for fast speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SCL_LCNT | FS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x8 and 0xFFFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_low_period_fs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->FS_SCL_LCNT, I2C_FS_SCL_LCNT)); +} + +/** + * @brief Get the SCL clock high-period count for high speed. + * @note The register IC_HS_SCL_HCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SCL_HCNT | HS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count range between 0x6 and 0xFFFF, should be larger than IC_HS_SPKLEN + 5. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_high_period_hs(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->HS_SCL_HCNT, count); +} + +/** + * @brief Get the SCL clock high-period count for high speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SCL_HCNT | HS_SCL_HCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval range between 0x6 and 0xFFFF, should be larger than IC_HS_SPKLEN + 7. + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_high_period_hs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->HS_SCL_HCNT, I2C_HS_SCL_HCNT)); +} + +/** + * @brief Get the SCL clock low-period count for high speed. + * @note The register IC_HS_SCL_LCNT can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SCL_LCNT | HS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param count range between 0x8 and 0xFFFF + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_clock_low_period_hs(i2c_regs_t *I2Cx, uint32_t count) +{ + WRITE_REG(I2Cx->HS_SCL_LCNT, count); +} + +/** + * @brief Get the SCL clock low-period count for high speed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SCL_LCNT | HS_SCL_LCNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x8 and 0xFFFF + */ +__STATIC_INLINE uint32_t ll_i2c_get_clock_low_period_hs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->HS_SCL_LCNT, I2C_HS_SCL_LCNT)); +} + +/** + * @brief Set the spike len in fast speed mode. + * @note The register FS_SPKLEN can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SPKLEN | FS_SPKLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param length Spike len. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_spike_len_fs(i2c_regs_t *I2Cx, uint32_t length) +{ + MODIFY_REG(I2Cx->FS_SPKLEN, I2C_FS_SPKLEN_FS_SPKLEN, length); +} + +/** + * @brief Get the spike len in fast speed mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_FS_SPKLEN | FS_SPKLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x2 and 0xFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_spike_len_fs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->FS_SPKLEN, I2C_FS_SPKLEN_FS_SPKLEN)); +} + +/** + * @brief Set the spike len in high speed mode. + * @note The register FS_SPKLEN can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SPKLEN | HS_SPKLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param length Spike len. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_spike_len_hs(i2c_regs_t *I2Cx, uint32_t length) +{ + MODIFY_REG(I2Cx->HS_SPKLEN, I2C_HS_SPKLEN_HS_SPKLEN, length); +} + +/** + * @brief Get the spike len in high speed mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_SPKLEN | HS_SPKLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x2 and 0xFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_spike_len_hs(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->HS_SPKLEN, I2C_HS_SPKLEN_HS_SPKLEN)); +} + +/** + * @brief Set I2C Speed mode. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | SPEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param speed_mode This parameter can be one of the following values: + * @arg @ref LL_I2C_SPEED_MODE_STANDARD + * @arg @ref LL_I2C_SPEED_MODE_FAST + * @arg @ref LL_I2C_SPEED_MODE_HIGH + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_speed_mode(i2c_regs_t *I2Cx, uint32_t speed_mode) +{ + MODIFY_REG(I2Cx->CON, I2C_CON_SPEED, speed_mode); +} + +/** + * @brief Get I2C Speed mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | SPEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value can be one of the following values: + * @arg @ref LL_I2C_SPEED_MODE_STANDARD + * @arg @ref LL_I2C_SPEED_MODE_FAST + * @arg @ref LL_I2C_SPEED_MODE_HIGH + */ +__STATIC_INLINE uint32_t ll_i2c_get_speed_mode(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->CON, I2C_CON_SPEED)); +} + +/** + * @brief Set I2C High Speed Master Code Address. + * @note The register IC_CON can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_MADDR | HS_MAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param code HS mode master code, range between 0x00 and 0x07. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_high_speed_master_code(i2c_regs_t *I2Cx, uint32_t code) +{ + WRITE_REG(I2Cx->HS_MADDR, code); +} + +/** + * @brief Get I2C Speed mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_HS_MADDR | HS_MAR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Returned value range between 0x00 and 0x07. + */ +__STATIC_INLINE uint32_t ll_i2c_get_high_speed_master_code(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->HS_MADDR, I2C_HS_MADDR_HS_MAR)); +} + +/** + * @brief Set the required transmit SDA hold time in units of ic_clk period. + * @note The register IC_SDA_HOLD can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_HOLD | TX_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param time SDA Tx hold time in units of ic_clk period. + * Time should range between 1 and (N_SCL_LOW - 2) in master mode or 7 and (N_SCL_LOW - 2) in slave mode. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_data_tx_hold_time(i2c_regs_t *I2Cx, uint32_t time) +{ + MODIFY_REG(I2Cx->SDA_HOLD, I2C_SDA_HOLD_TX_HOLD, time << I2C_SDA_HOLD_TX_HOLD_Pos); +} + +/** + * @brief Get the required transmit SDA hold time in units of ic_clk period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_HOLD | TX_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 1 and (N_SCL_LOW - 2) in master mode or 7 and (N_SCL_LOW - 2) in slave mode + */ +__STATIC_INLINE uint32_t ll_i2c_get_data_tx_hold_time(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->SDA_HOLD, I2C_SDA_HOLD_TX_HOLD) >> I2C_SDA_HOLD_TX_HOLD_Pos); +} + +/** + * @brief Set the required receive SDA hold time in units of ic_clk period. + * @note The register IC_SDA_HOLD can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_HOLD | RX_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param time SDA Tx hold time in units of ic_clk period. + * Time should range between 1 and (N_SCL_LOW - 2) in master mode or 7 and (N_SCL_LOW - 2) in slave mode. + * @retval Value between Min_Data=0x0 and Max_Data=0xF + */ +__STATIC_INLINE void ll_i2c_set_data_rx_hold_time(i2c_regs_t *I2Cx, uint32_t time) +{ + MODIFY_REG(I2Cx->SDA_HOLD, I2C_SDA_HOLD_RX_HOLD, time << I2C_SDA_HOLD_RX_HOLD_Pos); +} + +/** + * @brief Get the required receive SDA hold time in units of ic_clk period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_HOLD | RX_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 1 and (N_SCL_LOW - 2) in master mode or 7 and (N_SCL_LOW - 2) in slave mode + */ +__STATIC_INLINE uint32_t ll_i2c_get_data_rx_hold_time(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->SDA_HOLD, I2C_SDA_HOLD_RX_HOLD) >> I2C_SDA_HOLD_RX_HOLD_Pos); +} + +/** + * @brief Set the SDA setup time when operating as a slave transmitter. + * @note The register IC_SDA_SETUP can only be programmed when the I2C is disabled (ENABLE = 0). + * The length of setup time is calculated using [(IC_SDA_SETUP - 1) * (ic_clk_period)], so if the + * user requires 10 ic_clk periods of setup time, they should program a value of 11. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_SETUP | SDA_SETUP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param time SDA data setup time in units of ic_clk period, range between 2 ~ 0xFF. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_data_setup_time(i2c_regs_t *I2Cx, uint32_t time) +{ + MODIFY_REG(I2Cx->SDA_SETUP, I2C_SDA_SETUP_SDA_SETUP, time); +} + +/** + * @brief Get the SDA setup time when operating as a slave transmitter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_SDA_SETUP | SDA_SETUP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value range between 0x02 and 0xFF. + */ +__STATIC_INLINE uint32_t ll_i2c_get_data_setup_time(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->SDA_SETUP, I2C_SDA_SETUP_SDA_SETUP)); +} + +/** + * @brief Set threshold of entries (or below) that trigger the TX_EMPTY interrupt + * @note TX FIFO threshold only can be configured after FIFO was enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TX_TL | TX_TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_I2C_TX_FIFO_TH_EMPTY + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_1 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_2 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_3 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_4 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_5 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_6 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_7 + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_tx_fifo_threshold(i2c_regs_t *I2Cx, uint32_t threshold) +{ + WRITE_REG(I2Cx->TX_TL, threshold); +} + +/** + * @brief Get threshold of TX FIFO that triggers an THRE interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TX_TL | TX_TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_TX_FIFO_TH_EMPTY + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_1 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_2 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_3 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_4 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_5 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_6 + * @arg @ref LL_I2C_TX_FIFO_TH_CHAR_7 + */ +__STATIC_INLINE uint32_t ll_i2c_get_tx_fifo_threshold(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->TX_TL, I2C_TX_TL_TXTL)); +} + +/** + * @brief Set threshold of RX FIFO that triggers an RDA interrupt + * @note TX FIFO threshold only can be configured after FIFO was enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RX_TL | RX_TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_1 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_2 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_3 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_4 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_5 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_6 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_7 + * @arg @ref LL_I2C_RX_FIFO_TH_FULL + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_rx_fifo_threshold(i2c_regs_t *I2Cx, uint32_t threshold) +{ + WRITE_REG(I2Cx->RX_TL, threshold); +} + +/** + * @brief Get threshold of RX FIFO that triggers an RDA interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RX_TL | RX_TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_1 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_2 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_3 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_4 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_5 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_6 + * @arg @ref LL_I2C_RX_FIFO_TH_CHAR_7 + * @arg @ref LL_I2C_RX_FIFO_TH_FULL + */ +__STATIC_INLINE uint32_t ll_i2c_get_rx_fifo_threshold(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->RX_TL, I2C_RX_TL_RXTL)); +} + +/** + * @brief Get FIFO Transmission Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TXFLR | TXFLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Value range between 0x0 and 0x8. + */ +__STATIC_INLINE uint32_t ll_i2c_get_tx_fifo_level(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->TXFLR, I2C_TXFLR_TXFLR)); +} + +/** + * @brief Get FIFO reception Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RXFLR | RXFLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Value range between 0x0 and 0x8. + */ +__STATIC_INLINE uint32_t ll_i2c_get_rx_fifo_level(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->RXFLR, I2C_RXFLR_RXFLR)); +} + +/** + * @brief Enable DMA reception requests. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE | ABORT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_transfer_abort(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->ENABLE, I2C_ENABLE_ABORT); +} + +/** + * @brief Check if DMA reception requests are enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE | ABORT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_transfer_abort(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->ENABLE, I2C_ENABLE_ABORT) == (I2C_ENABLE_ABORT)); +} + +/** + * @brief Get the transmit abort source. + * @note This can be used to retrieve source of TX_ABRT interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TX_ABRT_SOURCE | ABRT_USER_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * IC_TX_ABRT_SOURCE | ABRT_SLVRD_INTX + * IC_TX_ABRT_SOURCE | ABRT_SLV_ARBLOST + * IC_TX_ABRT_SOURCE | ABRT_SLVFLUSH_TXFIFO + * IC_TX_ABRT_SOURCE | ABRT_ARB_LOST + * IC_TX_ABRT_SOURCE | ABRT_MST_DIS + * IC_TX_ABRT_SOURCE | ABRT_10B_RD_NORSTRT + * IC_TX_ABRT_SOURCE | ABRT_SBYTE_NORSTRT + * IC_TX_ABRT_SOURCE | ABRT_HS_NORSTRT + * IC_TX_ABRT_SOURCE | ABRT_SBYTE_ACKDET + * IC_TX_ABRT_SOURCE | ABRT_HS_ACKDET + * IC_TX_ABRT_SOURCE | ABRT_GCALL_READ + * IC_TX_ABRT_SOURCE | ABRT_GCALL_NOACK + * IC_TX_ABRT_SOURCE | ABRT_TXDATA_NOACK + * IC_TX_ABRT_SOURCE | ABRT_10ADDR2_NOACK + * IC_TX_ABRT_SOURCE | ABRT_10ADDR1_NOACK + * IC_TX_ABRT_SOURCE | ABRT_7B_ADDR_NOACK + * + * @param I2Cx I2C instance + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_I2C_ABRT_USER_ABRT + * @arg @ref LL_I2C_ABRT_SLVRD_INTX + * @arg @ref LL_I2C_ABRT_SLV_ARBLOST + * @arg @ref LL_I2C_ABRT_SLVFLUSH_TXFIFO + * @arg @ref LL_I2C_ABRT_ARB_LOST + * @arg @ref LL_I2C_ABRT_MST_DIS + * @arg @ref LL_I2C_ABRT_10B_RD_NORSTRT + * @arg @ref LL_I2C_ABRT_SBYTE_NORSTRT + * @arg @ref LL_I2C_ABRT_HS_NORSTRT + * @arg @ref LL_I2C_ABRT_SBYTE_ACKDET + * @arg @ref LL_I2C_ABRT_HS_ACKDET + * @arg @ref LL_I2C_ABRT_GCALL_READ + * @arg @ref LL_I2C_ABRT_GCALL_NOACK + * @arg @ref LL_I2C_ABRT_TXDATA_NOACK + * @arg @ref LL_I2C_ABRT_10ADDR2_NOACK + * @arg @ref LL_I2C_ABRT_10ADDR1_NOACK + * @arg @ref LL_I2C_ABRT_7B_ADDR_NOACK + * + * @note @arg @ref LL_I2C_ABRT_TX_FLUSH_CNT can be used as a mask to get the + * number of Tx FIFO Data Commands which are flushed due to TX_ABRT + * interrupt. + */ +__STATIC_INLINE uint32_t ll_i2c_get_abort_source(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_REG(I2Cx->TX_ABRT_SOURCE) & (~I2C_TX_ABRT_SRC_TX_FLUSH_CNT)); +} + +/** + * @brief Get the number of Tx FIFO Data Commands which are flushed due to TX_ABRT interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TX_ABRT_SOURCE | TX_FLUSH_CNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Tx flush count. + */ +__STATIC_INLINE uint32_t ll_i2c_get_tx_flush_count(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->TX_ABRT_SOURCE, I2C_TX_ABRT_SRC_TX_FLUSH_CNT) >> I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Pos); +} + +/** @} */ + +/** @defgroup I2C_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable specified interrupts. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | INTR_MASK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * INTR_MASK | INTR_MASK_START_DET + * INTR_MASK | INTR_MASK_STOP_DET + * INTR_MASK | INTR_MASK_ACTIVITY + * INTR_MASK | INTR_MASK_RX_DONE + * INTR_MASK | INTR_MASK_TX_ABRT + * INTR_MASK | INTR_MASK_RD_REQ + * INTR_MASK | INTR_MASK_TX_EMPTY + * INTR_MASK | INTR_MASK_TX_OVER + * INTR_MASK | INTR_MASK_RX_FULL + * INTR_MASK | INTR_MASK_RX_OVER + * INTR_MASK | INTR_MASK_RX_UNDER + * + * @param I2Cx I2C instance. + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_I2C_INTR_MASK_GEN_CALL + * @arg @ref LL_I2C_INTR_MASK_START_DET + * @arg @ref LL_I2C_INTR_MASK_STOP_DET + * @arg @ref LL_I2C_INTR_MASK_ACTIVITY + * @arg @ref LL_I2C_INTR_MASK_RX_DONE + * @arg @ref LL_I2C_INTR_MASK_TX_ABRT + * @arg @ref LL_I2C_INTR_MASK_RD_REQ + * @arg @ref LL_I2C_INTR_MASK_TX_EMPTY + * @arg @ref LL_I2C_INTR_MASK_TX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_FULL + * @arg @ref LL_I2C_INTR_MASK_RX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_UNDER + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it(i2c_regs_t *I2Cx, uint32_t mask) +{ + SET_BITS(I2Cx->INTR_MASK, mask); +} + +/** + * @brief Disable specified interrupts. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | INTR_MASK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * INTR_MASK | INTR_MASK_START_DET + * INTR_MASK | INTR_MASK_STOP_DET + * INTR_MASK | INTR_MASK_ACTIVITY + * INTR_MASK | INTR_MASK_RX_DONE + * INTR_MASK | INTR_MASK_TX_ABRT + * INTR_MASK | INTR_MASK_RD_REQ + * INTR_MASK | INTR_MASK_TX_EMPTY + * INTR_MASK | INTR_MASK_TX_OVER + * INTR_MASK | INTR_MASK_RX_FULL + * INTR_MASK | INTR_MASK_RX_OVER + * INTR_MASK | INTR_MASK_RX_UNDER + * + * @param I2Cx I2C instance. + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_I2C_INTR_MASK_GEN_CALL + * @arg @ref LL_I2C_INTR_MASK_START_DET + * @arg @ref LL_I2C_INTR_MASK_STOP_DET + * @arg @ref LL_I2C_INTR_MASK_ACTIVITY + * @arg @ref LL_I2C_INTR_MASK_RX_DONE + * @arg @ref LL_I2C_INTR_MASK_TX_ABRT + * @arg @ref LL_I2C_INTR_MASK_RD_REQ + * @arg @ref LL_I2C_INTR_MASK_TX_EMPTY + * @arg @ref LL_I2C_INTR_MASK_TX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_FULL + * @arg @ref LL_I2C_INTR_MASK_RX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_UNDER + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it(i2c_regs_t *I2Cx, uint32_t mask) +{ + CLEAR_BITS(I2Cx->INTR_MASK, mask); +} + +/** + * @brief Check if the specified interrupts are enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | INTR_MASK_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * INTR_MASK | INTR_MASK_START_DET + * INTR_MASK | INTR_MASK_STOP_DET + * INTR_MASK | INTR_MASK_ACTIVITY + * INTR_MASK | INTR_MASK_RX_DONE + * INTR_MASK | INTR_MASK_TX_ABRT + * INTR_MASK | INTR_MASK_RD_REQ + * INTR_MASK | INTR_MASK_TX_EMPTY + * INTR_MASK | INTR_MASK_TX_OVER + * INTR_MASK | INTR_MASK_RX_FULL + * INTR_MASK | INTR_MASK_RX_OVER + * INTR_MASK | INTR_MASK_RX_UNDER + * + * @param I2Cx I2C instance. + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_I2C_INTR_MASK_GEN_CALL + * @arg @ref LL_I2C_INTR_MASK_START_DET + * @arg @ref LL_I2C_INTR_MASK_STOP_DET + * @arg @ref LL_I2C_INTR_MASK_ACTIVITY + * @arg @ref LL_I2C_INTR_MASK_RX_DONE + * @arg @ref LL_I2C_INTR_MASK_TX_ABRT + * @arg @ref LL_I2C_INTR_MASK_RD_REQ + * @arg @ref LL_I2C_INTR_MASK_TX_EMPTY + * @arg @ref LL_I2C_INTR_MASK_TX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_FULL + * @arg @ref LL_I2C_INTR_MASK_RX_OVER + * @arg @ref LL_I2C_INTR_MASK_RX_UNDER + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it(i2c_regs_t *I2Cx, uint32_t mask) +{ + return (READ_BITS(I2Cx->INTR_MASK, mask) == (mask)); +} + +/** + * @brief Enable MASTER_ON_HOLD interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_master_on_hold(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_MST_ON_HOLD); +} + +/** + * @brief Disable MASTER_ON_HOLD interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_master_om_hold(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_MST_ON_HOLD); +} + +/** + * @brief Check if the MASTER_ON_HOLD Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_master_on_hold(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_MST_ON_HOLD) == (I2C_INTR_MST_ON_HOLD)); +} + +/** + * @brief Enable RESTART_DET interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RESTART_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_restart_det(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RESTART_DET); +} + +/** + * @brief Disable RESTART_DET interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RESTART_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_restart_det(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RESTART_DET); +} + +/** + * @brief Check if the RESTART_DET Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RESTART_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_restart_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RESTART_DET) == (I2C_INTR_RESTART_DET)); +} + +/** + * @brief Enable GEN_CALL interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_gen_call(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_GEN_CALL); +} + +/** + * @brief Disable GEN_CALL interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_gen_call(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_GEN_CALL); +} + +/** + * @brief Check if GEN_CALL interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_gen_call(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_GEN_CALL) == (I2C_INTR_GEN_CALL)); +} + +/** + * @brief Enable START_DET received interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_start_det(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_START_DET); +} + +/** + * @brief Disable START_DET received interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_start_det(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_START_DET); +} + +/** + * @brief Check if START_DET received interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_start_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_START_DET) == (I2C_INTR_START_DET)); +} + +/** + * @brief Enable STOP_DET interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_stop_det(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_STOP_DET); +} + +/** + * @brief Disable STOP_DET interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_stop_det(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_STOP_DET); +} + +/** + * @brief Check if STOP_DET interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_stop_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_STOP_DET) == (I2C_INTR_STOP_DET)); +} + +/** + * @brief Enable ACTIVITY interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_activity(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_ACTIVITY); +} + +/** + * @brief Disable ACTIVITY interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_activity(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_ACTIVITY); +} + +/** + * @brief Check if ACTIVITY interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_ACTIVITY) == (I2C_INTR_ACTIVITY)); +} + +/** + * @brief Enable RX_DONE interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void ll_i2c_enable_it_rx_done(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_DONE); +} + +/** + * @brief Disable RX_DONE interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_rx_done(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_DONE); +} + +/** + * @brief Check if RX_DONE interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enable_it_rx_done(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_DONE) == (I2C_INTR_RX_DONE)); +} + +/** + * @brief Enable TX_ABRT interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_rx_abort(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_ABRT); +} + +/** + * @brief Disable TX_ABRT interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_tx_abort(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_ABRT); +} + +/** + * @brief Check if TX_ABRT interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_tx_abort(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_ABRT) == (I2C_INTR_TX_ABRT)); +} + +/** + * @brief Enable RD_REQ interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_read_req(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RD_REQ); +} + +/** + * @brief Disable RD_REQ interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_read_req(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RD_REQ); +} + +/** + * @brief Check if RD_REQ interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_read_req(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RD_REQ) == (I2C_INTR_RD_REQ)); +} + +/** + * @brief Enable TX_EMPTY interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_tx_empty(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_EMPTY); +} + +/** + * @brief Disable TX_EMPTY interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_tx_empty(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_EMPTY); +} + +/** + * @brief Check if TX_EMPTY interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_tx_empty(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_EMPTY) == (I2C_INTR_TX_EMPTY)); +} + +/** + * @brief Enable TX_OVER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_tx_over(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_OVER); +} + +/** + * @brief Disable TX_OVER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_tx_over(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_OVER); +} + +/** + * @brief Check if TX_OVER interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_tx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_TX_OVER) == (I2C_INTR_TX_OVER)); +} + +/** + * @brief Enable RX_FULL interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_FULL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_rx_full(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_FULL); +} + +/** + * @brief Disable RX_FULL interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_FULL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disbale_it_rx_full(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_FULL); +} + +/** + * @brief Check if RX_FULL interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_FULL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE uint32_t ll_i2c_ls_enabled_it_rx_full(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_FULL) == (I2C_INTR_RX_FULL)); +} + +/** + * @brief Enable RX_OVER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_rx_over(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_OVER); +} + +/** + * @brief Disable RX_OVER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_rx_over(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_OVER); +} + +/** + * @brief Check if RX_OVER interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_rx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_OVER) == (I2C_INTR_RX_OVER)); +} + +/** + * @brief Enable RX_UNDER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_it_rx_under(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_UNDER); +} + +/** + * @brief Disable RX_UNDER interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_it_rx_under(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_UNDER); +} + +/** + * @brief Check if RX_UNDER interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTR_MASK | RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_it_rx_under(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_MASK, I2C_INTR_RX_UNDER) == (I2C_INTR_RX_UNDER)); +} + +/** @} */ + +/** @defgroup I2C_LL_EF_FLAG_management FLAG_management + * @{ + */ + +/** + * @brief Get I2C interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * IC_INTR_STAT | RESTART_DET + * IC_INTR_STAT | GEN_CALL + * IC_INTR_STAT | START_DET + * IC_INTR_STAT | STOP_DET + * IC_INTR_STAT | ACTIVITY + * IC_INTR_STAT | RX_DONE + * IC_INTR_STAT | TX_ABRT + * IC_INTR_STAT | RD_REQ + * IC_INTR_STAT | TX_EMPTY + * IC_INTR_STAT | TX_OVER + * IC_INTR_STAT | RX_FULL + * IC_INTR_STAT | RX_OVER + * IC_INTR_STAT | RX_UNDER + * + * @param I2Cx I2C instance. + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_I2C_INTR_STAT_MST_ON_HOLD + * @arg @ref LL_I2C_INTR_STAT_RESTART_DET + * @arg @ref LL_I2C_INTR_STAT_GEN_CALL + * @arg @ref LL_I2C_INTR_STAT_START_DET + * @arg @ref LL_I2C_INTR_STAT_STOP_DET + * @arg @ref LL_I2C_INTR_STAT_ACTIVITY + * @arg @ref LL_I2C_INTR_STAT_RX_DONE + * @arg @ref LL_I2C_INTR_STAT_TX_ABRT + * @arg @ref LL_I2C_INTR_STAT_RD_REQ + * @arg @ref LL_I2C_INTR_STAT_TX_EMPTY + * @arg @ref LL_I2C_INTR_STAT_TX_OVER + * @arg @ref LL_I2C_INTR_STAT_RX_FULL + * @arg @ref LL_I2C_INTR_STAT_RX_OVER + * @arg @ref LL_I2C_INTR_STAT_RX_UNDER + */ +__STATIC_INLINE uint32_t ll_i2c_get_it_flag(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_REG(I2Cx->INTR_STAT)); +} + +/** + * @brief Get I2C RAW interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * IC_RAW_INTR_STAT | RAW_RESTART_DET + * IC_RAW_INTR_STAT | RAW_GEN_CALL + * IC_RAW_INTR_STAT | RAW_START_DET + * IC_RAW_INTR_STAT | RAW_STOP_DET + * IC_RAW_INTR_STAT | RAW_ACTIVITY + * IC_RAW_INTR_STAT | RAW_RX_DONE + * IC_RAW_INTR_STAT | RAW_TX_ABRT + * IC_RAW_INTR_STAT | RAW_RD_REQ + * IC_RAW_INTR_STAT | RAW_TX_EMPTY + * IC_RAW_INTR_STAT | RAW_TX_OVER + * IC_RAW_INTR_STAT | RAW_RX_FULL + * IC_RAW_INTR_STAT | RAW_RX_OVER + * IC_RAW_INTR_STAT | RAW_RX_UNDER + * + * @param I2Cx I2C instance. + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_I2C_INTR_STAT_MST_ON_HOLD + * @arg @ref LL_I2C_INTR_STAT_RESTART_DET + * @arg @ref LL_I2C_INTR_STAT_GEN_CALL + * @arg @ref LL_I2C_INTR_STAT_START_DET + * @arg @ref LL_I2C_INTR_STAT_STOP_DET + * @arg @ref LL_I2C_INTR_STAT_ACTIVITY + * @arg @ref LL_I2C_INTR_STAT_RX_DONE + * @arg @ref LL_I2C_INTR_STAT_TX_ABRT + * @arg @ref LL_I2C_INTR_STAT_RD_REQ + * @arg @ref LL_I2C_INTR_STAT_TX_EMPTY + * @arg @ref LL_I2C_INTR_STAT_TX_OVER + * @arg @ref LL_I2C_INTR_STAT_RX_FULL + * @arg @ref LL_I2C_INTR_STAT_RX_OVER + * @arg @ref LL_I2C_INTR_STAT_RX_UNDER + */ +__STATIC_INLINE uint32_t ll_i2c_get_raw_it_flag(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_REG(I2Cx->RAW_INTR_STAT)); +} + +/** + * @brief Indicate the status of MST_ON_HOLD flag. + * @note RESET: Clear default value. + * SET : When MST_ON_HOLD interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_INTR_STAT | MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_master_on_hold(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_MST_ON_HOLD) == (I2C_INTR_MST_ON_HOLD)); +} + +/** + * @brief Indicate the status of RAW_MST_ON_HOLD flag. + * @note RESET: Clear default value. + * SET : When unmasked MST_ON_HOLD interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_MST_ON_HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_master_on_hold(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_MST_ON_HOLD) == (I2C_INTR_MST_ON_HOLD)); +} + +/** + * @brief Indicate the status of RESTART_DET flag. + * @note RESET: Clear default value. + * SET : When masked RESTART_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RESTART_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_restart_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RESTART_DET) == (I2C_INTR_RESTART_DET)); +} + +/** + * @brief Indicate the status of RAW_RESTART_DET flag. + * @note RESET: Clear default value. + * SET : When unmasked RESTART_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RESTART_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_restart_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RESTART_DET) == (I2C_INTR_RESTART_DET)); +} + +/** + * @brief Indicate the status of GEN_CALL flag. + * @note RESET: Clear default value. + * SET : When masked GEN_CALL interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_gen_call(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_GEN_CALL) == (I2C_INTR_GEN_CALL)); +} + +/** + * @brief Indicate the status of RAW_GEN_CALL flag. + * @note RESET: Clear default value. + * SET : When unmasked GEN_CALL interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_gen_call(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_GEN_CALL) == (I2C_INTR_GEN_CALL)); +} + +/** + * @brief Indicate the status of START_DET flag. + * @note RESET: Clear default value. + * SET : When masked START_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_start_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_START_DET) == (I2C_INTR_START_DET)); +} + +/** + * @brief Indicate the status of RAW_START_DET flag. + * @note RESET: Clear default value. + * SET : When unmasked START_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_start_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_START_DET) == (I2C_INTR_START_DET)); +} + +/** + * @brief Indicate the status of STOP_DET flag. + * @note RESET: Clear default value. + * SET : When masked STOP_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_stop_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_STOP_DET) == (I2C_INTR_STOP_DET)); +} + +/** + * @brief Indicate the status of RAW_STOP_DET flag. + * @note RESET: Clear default value. + * SET : When unmasked STOP_DET interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_stop_det(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_STOP_DET) == (I2C_INTR_STOP_DET)); +} + +/** + * @brief Indicate the status of ACTIVITY flag. + * @note RESET: Clear default value. + * SET : When masked ACTIVITY interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_ACTIVITY) == (I2C_INTR_ACTIVITY)); +} + +/** + * @brief Indicate the status of RAW_ACTIVITY flag. + * @note RESET: Clear default value. + * SET : When unmasked ACTIVITY interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_ACTIVITY) == (I2C_INTR_ACTIVITY)); +} + +/** + * @brief Indicate the status of RX_DONE flag. + * @note RESET: Clear default value. + * SET : When masked RX_DONE interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_rx_done(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RX_DONE) == (I2C_INTR_RX_DONE)); +} + +/** + * @brief Indicate the status of RAW_RX_DONE flag. + * @note RESET: Clear default value. + * SET : When unmasked RX_DONE interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_rx_done(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RX_DONE) == (I2C_INTR_RX_DONE)); +} + +/** + * @brief Indicate the status of TX_ABRT flag. + * @note RESET: Clear default value. + * SET : When masked TX_ABRT interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_tx_abort(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_TX_ABRT) == (I2C_INTR_TX_ABRT)); +} + +/** + * @brief Indicate the status of RAW_TX_ABRT flag. + * @note RESET: Clear default value. + * SET : When unmasked TX_ABRT interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_tx_abort(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_TX_ABRT) == (I2C_INTR_TX_ABRT)); +} + +/** + * @brief Indicate the status of RD_REQ flag. + * @note RESET: Clear default value. + * SET : When masked RD_REQ interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_read_req(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RD_REQ) == (I2C_INTR_RD_REQ)); +} + +/** + * @brief Indicate the status of RAW_RD_REQ flag. + * @note RESET: Clear default value. + * SET : When unmasked RD_REQ interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_read_req(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RD_REQ) == (I2C_INTR_RD_REQ)); +} + +/** + * @brief Indicate the status of TX_EMPTY flag. + * @note RESET: Clear default value. + * SET : When masked TX_EMPTY interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | TX_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_tx_empty(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_TX_EMPTY) == (I2C_INTR_TX_EMPTY)); +} + +/** + * @brief Indicate the status of RAW_TX_EMPTY flag. + * @note RESET: Clear default value. + * SET : When unmasked TX_EMPTY interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_TX_EMPTY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_tx_empty(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_TX_EMPTY) == (I2C_INTR_TX_EMPTY)); +} + +/** + * @brief Indicate the status of TX_OVER flag. + * @note RESET: Clear default value. + * SET : When masked TX_OVER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_tx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_TX_OVER) == (I2C_INTR_TX_OVER)); +} + +/** + * @brief Indicate the status of RAW_TX_OVER flag. + * @note RESET: Clear default value. + * SET : When unmasked TX_OVER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_tx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_TX_OVER) == (I2C_INTR_TX_OVER)); +} + +/** + * @brief Indicate the status of RX_FULL flag. + * @note RESET: Clear default value. + * SET : When masked RX_FULL interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RX_FULL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_rx_full(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RX_FULL) == (I2C_INTR_RX_FULL)); +} + +/** + * @brief Indicate the status of RAW_RX_FULL flag. + * @note RESET: Clear default value. + * SET : When unmasked RX_FULL interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RX_FULL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_rx_full(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RX_FULL) == (I2C_INTR_RX_FULL)); +} + +/** + * @brief Indicate the status of RX_OVER flag. + * @note RESET: Clear default value. + * SET : When masked RX_OVER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_rx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RX_OVER) == (I2C_INTR_RX_OVER)); +} + +/** + * @brief Indicate the status of RAW_RX_OVER flag. + * @note RESET: Clear default value. + * SET : When unmasked RX_OVER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_rx_over(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RX_OVER) == (I2C_INTR_RX_OVER)); +} + +/** + * @brief Indicate the status of RX_UNDER flag. + * @note RESET: Clear default value. + * SET : When masked RX_UNDER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_INTR_STAT | RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_rx_under(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->INTR_STAT, I2C_INTR_RX_UNDER) == (I2C_INTR_RX_UNDER)); +} + +/** + * @brief Indicate the status of RAW_RX_UNDER flag. + * @note RESET: Clear default value. + * SET : When unmasked RX_UNDER interrupt is actived. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | RAW_RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_raw_rx_under(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RX_UNDER) == (I2C_INTR_RX_UNDER)); +} + +/** + * @brief Clear the combined interrupt, all individual interrupts, and the IC_TX_ABRT_SOURCE register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_INTR | CLR_INTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_intr(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_INTR); + (void) tmpreg; +} + +/** + * @brief Clear GEN_CALL flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_GEN_CALL | CLR_GEN_CALL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_gen_call(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_GEN_CALL); + (void) tmpreg; +} + +/** + * @brief Clear START_DET flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_START_DET | CLR_START_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_start_det(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_START_DET); + (void) tmpreg; +} + +/** + * @brief Clear STOP_DET flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_STOP_DET | CLR_STOP_DET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_stop_det(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_STOP_DET); + (void) tmpreg; +} + +/** + * @brief Clear ACTIVITY flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_ACTIVITY | CLR_ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_activity(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_ACTIVITY); + (void) tmpreg; +} + +/** + * @brief Clear RX_DONE flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_RX_DONE | CLR_RX_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_rx_done(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_RX_DONE); + (void) tmpreg; +} + +/** + * @brief Clear TX_ABRT flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_TX_ABRT | CLR_TX_ABRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_tx_abort(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_TX_ABRT); + (void) tmpreg; +} + +/** + * @brief Clear RD_REQ flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_RD_REQ | CLR_RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_read_req(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_RD_REQ); + (void) tmpreg; +} + +/** + * @brief Clear TX_OVER flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_TX_OVER | CLR_TX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_tx_over(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_TX_OVER); + (void) tmpreg; +} + +/** + * @brief Clear RX_OVER flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_RX_OVER | CLR_RX_OVER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_rx_over(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_RX_OVER); + (void) tmpreg; +} + +/** + * @brief Clear RX_UNDER flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CLR_RX_UNDER | CLR_RX_UNDER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_clear_flag_rx_under(i2c_regs_t *I2Cx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(I2Cx->CLR_RX_UNDER); + (void) tmpreg; +} + +/** + * @brief Indicate the status of IC_STATUS Slave FSM Activity Status flag. + * @note RESET: Slave FSM is in IDLE state. + * SET : When Slave FSM is not in IDLE state. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | SLV_ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_slave_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_SLV_ACTIVITY) == (I2C_STATUS_SLV_ACTIVITY)); +} + +/** + * @brief Indicate the status of IC_STATUS Master FSM Activity Status flag. + * @note RESET: Master FSM is in IDLE state. + * SET : When Master FSM is not in IDLE state. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | MST_ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_master_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_MST_ACTIVITY) == (I2C_STATUS_MST_ACTIVITY)); +} + +/** + * @brief Indicate the status of IC_STATUS Receive FIFO Completely Full flag. + * @note RESET: Receive FIFO is not full. + * SET : When Receive FIFO is full. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | RFF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_rff(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_RFF) == (I2C_STATUS_RFF)); +} + +/** + * @brief Indicate the status of IC_STATUS Receive FIFO Not Empty flag. + * @note RESET: Receive FIFO is empty. + * SET : When Receive FIFO is not empty. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | RFNE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_rfne(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_RFNE) == (I2C_STATUS_RFNE)); +} + +/** + * @brief Indicate the status of IC_STATUS Transmit FIFO Completely Empty flag. + * @note RESET: Transmit FIFO is not empty. + * SET : When Transmit FIFO is empty. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | TFE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_tfe(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_TFE) == (I2C_STATUS_TFE)); +} + +/** + * @brief Indicate the status of IC_STATUS Transmit FIFO Not Full flag. + * @note RESET: Transmit FIFO is full. + * SET : When Transmit FIFO is not full. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | TFNF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_tfnf(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_TFNF) == (I2C_STATUS_TFNF)); +} + +/** + * @brief Indicate the status of IC_STATUS ACTIVITY flag. + * @note RESET: I2C is idle. + * SET : When I2C is active. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_STATUS | ACTIVITY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_status_activity(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->STATUS, I2C_STATUS_ACTIVITY) == (I2C_STATUS_ACTIVITY)); +} + +/** + * @brief Indicate the status of Slave Received Data Lost flag. + * @note RESET: Slave RX Data is not lost. + * SET : Slave RX Data is lost. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE_STATUS | SLV_RX_LOST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_slave_rx_data_lost(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->ENABLE_STATUS, I2C_ENABLE_STATUS_SLV_RX_LOST) == (I2C_ENABLE_STATUS_SLV_RX_LOST)); +} + +/** + * @brief Indicate the status of Slave Disabled While Busy flag. + * @note RESET: Slave is disabled when it is idle. + * SET : Slave is disabled when it is active. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_ENABLE_STATUS | SLV_DIS_WHL_BUSY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_active_flag_slave_dis_whl_busy(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->ENABLE_STATUS, I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY) == (I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY)); +} +/** @} */ + +/** @defgroup I2C_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable DMA transmission requests. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Value range between 0 ~ 0x8. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_dma_req_tx(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->DMA_CR, I2C_DMA_CR_TDMAE); +} + +/** + * @brief Disable DMA transmission requests. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_dma_req_tx(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->DMA_CR, I2C_DMA_CR_TDMAE); +} + +/** + * @brief Check if DMA transmission requests are enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_dma_req_tx(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->DMA_CR, I2C_DMA_CR_TDMAE) == (I2C_DMA_CR_TDMAE)); +} + +/** + * @brief Enable DMA reception requests. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_enable_dma_req_rx(i2c_regs_t *I2Cx) +{ + SET_BITS(I2Cx->DMA_CR, I2C_DMA_CR_RDMAE); +} + +/** + * @brief Disable DMA reception requests. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_disable_dma_req_rx(i2c_regs_t *I2Cx) +{ + CLEAR_BITS(I2Cx->DMA_CR, I2C_DMA_CR_RDMAE); +} + +/** + * @brief Check if DMA reception requests are enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_CR | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2c_is_enabled_dma_req_rx(i2c_regs_t *I2Cx) +{ + return (READ_BITS(I2Cx->DMA_CR, I2C_DMA_CR_RDMAE) == (I2C_DMA_CR_RDMAE)); +} + +/** + * @brief Set level of TX FIFO that requests a DMA transmit. + * @note TX data level should equal to the watermark level, that is, the dma_tx_req + * signal is generated when the number of valid data entries in the transmit + * FIFO is equal to or below this field value, and TDMAE = 1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_TDLR | DMATDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @param level This parameter should range between 0x0 and 0x8. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_dma_tx_data_level(i2c_regs_t *I2Cx, uint32_t level) +{ + WRITE_REG(I2Cx->DMA_TDLR, level); +} + +/** + * @brief Get level of TX FIFO that request a DMA transmit. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_TDLR | DMATDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Returned value should range between 0x0 and 0x8. + */ +__STATIC_INLINE uint32_t ll_i2c_get_dma_tx_data_level(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->DMA_TDLR, I2C_DMA_TDLR_DMATDL)); +} + +/** + * @brief Set level of RX FIFO that requests a DMA receive. + * @note The watermark level = DMARDL + 1, that is, dma_rx_req is generated when + * the number of valid data entries in the receive FIFO is equal to or + * more than this field value + 1, and RDMAE = 1. For instance, when DMARDL + * is 0, then dma_rx_req is asserted when 1 or more data entries are present + * in the receive FIFO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_RDLR | DMARDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @param level This parameter should range between 0x0 and 0x8. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_dma_rx_data_level(i2c_regs_t *I2Cx, uint32_t level) +{ + WRITE_REG(I2Cx->DMA_RDLR, level); +} + +/** + * @brief Get level of RX FIFO that request a DMA receive. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DMA_RDLR | DMARDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Returned value should range between 0x0 and 0x8. + */ +__STATIC_INLINE uint32_t ll_i2c_get_dma_rx_data_level(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->DMA_RDLR, I2C_DMA_RDLR_DMARDL)); +} + +/** + * @brief Get the data register address used for DMA transfer + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DATA_CMD | DAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance + * @retval Address of data register + */ +__STATIC_INLINE uint32_t ll_i2c_dma_get_register_address(i2c_regs_t *I2Cx) +{ + return ((uint32_t) & (I2Cx->DATA_CMD)); +} + +/** @} */ + +/** @defgroup I2C_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Configure the slave address for transfer (master mode). + * @note The register IC_TAR can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TAR | TAR_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @param slave_addr This parameter must be a value between 0x00 and 0x3F. + * @retval None. + */ +__STATIC_INLINE void ll_i2c_set_slave_address(i2c_regs_t *I2Cx, uint32_t slave_addr) +{ + MODIFY_REG(I2Cx->TAR, I2C_TAR_ADDR, slave_addr << I2C_TAR_ADDR_Pos); +} + +/** + * @brief Get the slave address programmed for transfer (master mode). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_TAR | TAR_ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value between 0x0 and0x3F + */ +__STATIC_INLINE uint32_t ll_i2c_get_slave_address(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->TAR, I2C_TAR_ADDR) >> I2C_TAR_ADDR_Pos); +} + +/** + * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @note The register IC_CON and IC_TAR can only be programmed when the I2C is disabled (ENABLE = 0). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_CON | CON_10BITADDR_MST | + * +----------------------+-----------------------------------+ + * \endrst + * IC_TAR | TAR_ADDR + * + * @param I2Cx I2C instance. + * @param slave_addr Specifies the slave address to be programmed. + * @param slave_addr_size This parameter can be one of the following values: + * @arg @ref LL_I2C_ADDRESSING_MODE_7BIT + * @arg @ref LL_I2C_ADDRESSING_MODE_10BIT + * @note SlaveAddrSize in IC_CON register can only be programmed when the I2C is disabled (IC_ENABLE = 0). + * @retval None. + */ +__STATIC_INLINE void ll_i2c_handle_transfer(i2c_regs_t *I2Cx, uint32_t slave_addr, uint32_t slave_addr_size) +{ + MODIFY_REG(I2Cx->TAR, I2C_TAR_ADDR, slave_addr << I2C_TAR_ADDR_Pos); + ll_i2c_set_master_addressing_mode(I2Cx, slave_addr_size); +} + +/** + * @brief Indicate the value of transfer direction (slave mode). + * @note RESET: Write transfer, Slave enters in receiver mode. + * SET: Read transfer, Slave enters in transmitter mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_RAW_INTR_STAT | INTR_RD_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * IC_RAW_INTR_STAT | INTR_RX_FULL + * + * @param I2Cx I2C instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_DIRECTION_WRITE + * @arg @ref LL_I2C_DIRECTION_READ + */ +__STATIC_INLINE uint32_t ll_i2c_get_transfer_direction(i2c_regs_t *I2Cx) +{ + return (uint32_t)(READ_BITS(I2Cx->RAW_INTR_STAT, I2C_INTR_RD_REQ | I2C_INTR_RX_FULL)); +} + +/** + * @brief Read Receive Data register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DATA_CMD | DAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Cx I2C instance. + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t ll_i2c_receive_data8(i2c_regs_t *I2Cx) +{ + return (uint8_t)(READ_BITS(I2Cx->DATA_CMD, I2C_DATA_CMD_DAT)); +} + +/** + * @brief Write in Transmit Data Register . + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IC_DATA_CMD | STOP | + * +----------------------+-----------------------------------+ + * \endrst + * IC_DATA_CMD | CMD + * IC_DATA_CMD | DAT + * + * @param I2Cx I2C instance. + * @param data Value range between 0x00 and 0xFF. + * @param cmd This parameter can be one of the following values: + * @arg @ref LL_I2C_CMD_SLV_NONE + * @arg @ref LL_I2C_CMD_MST_WRITE + * @arg @ref LL_I2C_CMD_MST_READ + * @arg @ref LL_I2C_CMD_MST_GEN_STOP + * @arg @ref LL_I2C_CMD_MST_GEN_RESTART + * @retval None. + */ +__STATIC_INLINE void ll_i2c_transmit_data8(i2c_regs_t *I2Cx, uint8_t data, uint32_t cmd) +{ + WRITE_REG(I2Cx->DATA_CMD, data | cmd); +} + +/** @} */ + +/** @defgroup I2C_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize I2C registers (Registers restored to their default values). + * @param I2Cx I2C instance + * @retval An error_status_t enumeration value: + * - SUCCESS: I2C registers are de-initialized + * - ERROR: I2C registers are not de-initialized + */ +error_status_t ll_i2c_deinit(i2c_regs_t *I2Cx); + +/** + * @brief Initialize I2C registers according to the specified + * parameters in p_i2c_init. + * @param I2Cx I2C instance + * @param p_i2c_init Pointer to a ll_i2c_init_t structure that contains the configuration + * information for the specified I2C peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: I2C registers are initialized according to p_i2c_init content + * - ERROR: Problem occurred during I2C Registers initialization + */ +error_status_t ll_i2c_init(i2c_regs_t *I2Cx, ll_i2c_init_t *p_i2c_init); + +/** + * @brief Set each field of a @ref ll_i2c_init_t type structure to default value. + * @param p_i2c_init Pointer to a @ref ll_i2c_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_i2c_struct_init(ll_i2c_init_t *p_i2c_init); + +/** @} */ + +/** @} */ + +#endif /* I2C0 || I2C1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_I2C_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2s.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2s.h new file mode 100644 index 0000000..c076bd8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_i2s.h @@ -0,0 +1,1906 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_i2s.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of I2S LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_I2S I2S + * @brief I2S LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_I2S_H__ +#define __GR55xx_LL_I2S_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (I2S_M) || defined (I2S_S) + +/** @defgroup LL_I2S_DRIVER_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2S_LL_ES_INIT I2S Exported init structure + * @{ + */ + +/** + * @brief LL I2S init structures definition + */ +typedef struct _ll_i2s_init_t +{ + uint32_t rxdata_size; /**< Specifies the I2S receive data size. + This parameter can be a value of @ref I2S_LL_EC_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_rxsize().*/ + + uint32_t txdata_size; /**< Specifies the I2S transmit data size. + This parameter can be a value of @ref I2S_LL_EC_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_txsize().*/ + + uint32_t rx_threshold; /**< Specifies the I2S receive FIFO threshold. + This parameter can be a value of @ref I2S_LL_EC_FIFO_THRESHOLD. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_rx_fifo_threshold().*/ + + uint32_t tx_threshold; /**< Specifies the I2S transmit FIFO threshold. + This parameter can be a value of @ref I2S_LL_EC_FIFO_THRESHOLD. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_tx_fifo_threshold().*/ + + uint32_t clock_source; /**< Specifies the source of the I2S clock. + This parameter can be a value of @ref I2S_LL_EC_CLOCK_SOURCE. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_clock_src().*/ + + uint32_t audio_freq; /**< Specifies the frequency selected for the I2S communication. + + This feature can be modified afterwards using unitary function @ref ll_i2s_set_clock_div().*/ + +} ll_i2s_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup I2S_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup I2S_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags definitions which can be used with LL_I2S_ReadReg function + * @{ + */ +#define LL_I2S_STATUS_TXFO I2S_INTSTAT_TXFO /**< TX FIFO write overflow flag */ +#define LL_I2S_STATUS_TXFE I2S_INTSTAT_TXFE /**< TX FIFO threshold level is not reached flag */ +#define LL_I2S_STATUS_RXFO I2S_INTSTAT_RXFO /**< RX FIFO receive overflow flag */ +#define LL_I2S_STATUS_RXDA I2S_INTSTAT_RXDA /**< RX FIFO threshold level is reached flag */ +/** @} */ + +/** @defgroup I2S_LL_EC_INTERRUPT Interrupt Defines + * @brief Interrupt definitions which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions + * @{ + */ +#define LL_I2S_INT_TXFO I2S_INTMASK_TXFO /**< TX FIFO write overflow interrupt */ +#define LL_I2S_INT_TXFE I2S_INTMASK_TXFE /**< TX FIFO threshold level is not reached interrupt */ +#define LL_I2S_INT_RXFO I2S_INTMASK_RXFO /**< RX FIFO receive overflow interrupt */ +#define LL_I2S_INT_RXDA I2S_INTMASK_RXDA /**< RX FIFO threshold level is reached interrupt */ +/** @} */ + +/** @defgroup I2S_LL_EC_CLOCK_SOURCE I2S Clock Source + * @{ + */ +#define LL_I2S_CLOCK_SRC_96M (0x00000000UL) /**< I2S clock source select: 96M */ +#define LL_I2S_CLOCK_SRC_32M (1UL << 18) /**< I2S clock source select: 32M */ +/** @} */ + +/** @defgroup I2S_LL_EC_DATASIZE Transfer Data width + * @{ + */ +#define LL_I2S_DATASIZE_IGNORE (0x00000000UL) /**< Data size for I2S transfer: 32 bits */ +#define LL_I2S_DATASIZE_12BIT (1UL << I2S_RXSIZE_WLEN_Pos) /**< Data size for I2S transfer: 12 bits */ +#define LL_I2S_DATASIZE_16BIT (2UL << I2S_RXSIZE_WLEN_Pos) /**< Data size for I2S transfer: 16 bits */ +#define LL_I2S_DATASIZE_20BIT (3UL << I2S_RXSIZE_WLEN_Pos) /**< Data size for I2S transfer: 20 bits */ +#define LL_I2S_DATASIZE_24BIT (4UL << I2S_RXSIZE_WLEN_Pos) /**< Data size for I2S transfer: 24 bits */ +#define LL_I2S_DATASIZE_32BIT (5UL << I2S_RXSIZE_WLEN_Pos) /**< Data size for I2S transfer: 32 bits */ +/** @} */ + +/** @defgroup I2S_LL_EC_TRANSFER_MODE Transfer Mode + * @{ + */ +#define LL_I2S_SIMPLEX_TX (1UL) /**< Simplex TX mode. */ +#define LL_I2S_SIMPLEX_RX (2UL) /**< Simplex RX mode. */ +#define LL_I2S_FULL_DUPLEX (3UL) /**< Full-Duplex mode. */ +/** @} */ + +/** @defgroup I2S_LL_EC_FIFO_THRESHOLD FIFO Threshold + * @{ + */ +#define LL_I2S_THRESHOLD_1FIFO (0x00000000UL) /**< Trigger level for FIFO: 1 depth. */ +#define LL_I2S_THRESHOLD_2FIFO (1UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 2 depth. */ +#define LL_I2S_THRESHOLD_3FIFO (2UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 3 depth. */ +#define LL_I2S_THRESHOLD_4FIFO (3UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 4 depth. */ +#define LL_I2S_THRESHOLD_5FIFO (4UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 5 depth. */ +#define LL_I2S_THRESHOLD_6FIFO (5UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 6 depth. */ +#define LL_I2S_THRESHOLD_7FIFO (6UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 7 depth. */ +#define LL_I2S_THRESHOLD_8FIFO (7UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 8 depth. */ +#define LL_I2S_THRESHOLD_9FIFO (8UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 9 depth. */ +#define LL_I2S_THRESHOLD_10FIFO (9UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 10 depth. */ +#define LL_I2S_THRESHOLD_11FIFO (10UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 11 depth. */ +#define LL_I2S_THRESHOLD_12FIFO (11UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 12 depth. */ +#define LL_I2S_THRESHOLD_13FIFO (12UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 13 depth. */ +#define LL_I2S_THRESHOLD_14FIFO (13UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 14 depth. */ +#define LL_I2S_THRESHOLD_15FIFO (14UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 15 depth. */ +#define LL_I2S_THRESHOLD_16FIFO (15UL << I2S_RXFIFO_TL_Pos) /**< Trigger level for FIFO: 16 depth. */ +/** @} */ + +/** @defgroup I2S_LL_EC_WS_CYCLES Word Select Line Cycles + * @{ + */ +#define LL_I2S_WS_CYCLES_16 (0x00000000UL) /**< 16 SCLK cycles in word select line. */ +#define LL_I2S_WS_CYCLES_24 (0x1UL << I2S_CLKCONFIG_WSS_Pos) /**< 24 SCLK cycles in word select line. */ +#define LL_I2S_WS_CYCLES_32 (0x2UL << I2S_CLKCONFIG_WSS_Pos) /**< 32 SCLK cycles in word select line. */ +/** @} */ + +/** @defgroup I2S_LL_EC_SCLK_GATE SCLK Gate + * @{ + */ +#define LL_I2S_SCLKG_NONE (0x00000000UL) /**< Clock gating is disabled. */ +#define LL_I2S_SCLKG_CYCLES_12 (0x1UL << I2S_CLKCONFIG_SCLKG_Pos) /**< Gating after 12 sclk cycles. */ +#define LL_I2S_SCLKG_CYCLES_16 (0x2UL << I2S_CLKCONFIG_SCLKG_Pos) /**< Gating after 16 sclk cycles. */ +#define LL_I2S_SCLKG_CYCLES_20 (0x3UL << I2S_CLKCONFIG_SCLKG_Pos) /**< Gating after 20 sclk cycles. */ +#define LL_I2S_SCLKG_CYCLES_24 (0x4UL << I2S_CLKCONFIG_SCLKG_Pos) /**< Gating after 24 sclk cycles. */ +/** @} */ + +/** @defgroup I2S_LL_EC_RESOLUTION RX/TX resolution of one channel + * @{ + */ +#define LL_I2S_RESOLUTION_12BIT (0UL) /**< 12 bits resolution. */ +#define LL_I2S_RESOLUTION_16BIT (1UL) /**< 16 bits resolution. */ +#define LL_I2S_RESOLUTION_20BIT (2UL) /**< 20 bits resolution. */ +#define LL_I2S_RESOLUTION_24BIT (3UL) /**< 24 bits resolution. */ +#define LL_I2S_RESOLUTION_32BIT (4UL) /**< 32 bits resolution. */ +/** @} */ + +/** @defgroup I2S_LL_EC_CHANNELS the number of RX/TX channels + * @{ + */ +#define LL_I2S_CHANNEL_NUM_1 (0UL) /**< 1 channel. */ +#define LL_I2S_CHANNEL_NUM_2 (1UL) /**< 2 channels. */ +#define LL_I2S_CHANNEL_NUM_3 (2UL) /**< 3 channels. */ +#define LL_I2S_CHANNEL_NUM_4 (3UL) /**< 4 channels. */ +/** @} */ + +/** @defgroup I2S_LL_EC_FIFO_DEPTH RX/TX FIFO depth + * @{ + */ +#define LL_I2S_FIFO_DEPTH_2 (0UL) /**< FIFO depth is 2 . */ +#define LL_I2S_FIFO_DEPTH_4 (1UL) /**< FIFO depth is 4 . */ +#define LL_I2S_FIFO_DEPTH_8 (2UL) /**< FIFO depth is 8 . */ +#define LL_I2S_FIFO_DEPTH_16 (3UL) /**< FIFO depth is 16. */ +/** @} */ + +/** @defgroup I2S_LL_EC_APB_WIDTH APB data width + * @{ + */ +#define LL_I2S_APB_WIDTH_8BIT (0UL) /**< 8 bits APB data width. */ +#define LL_I2S_APB_WIDTH_16BIT (1UL) /**< 16 bits APB data width. */ +#define LL_I2S_APB_WIDTH_32BIT (2UL) /**< 32 bits APB data width. */ +/** @} */ + +/** @} */ + +/** @defgroup I2S_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL I2S InitStrcut default configuartion + */ +#define LL_I2S_DEFAULT_CONFIG \ +{ \ + .rxdata_size = LL_I2S_DATASIZE_16BIT, \ + .txdata_size = LL_I2S_DATASIZE_16BIT, \ + .rx_threshold = LL_I2S_THRESHOLD_1FIFO, \ + .tx_threshold = LL_I2S_THRESHOLD_9FIFO, \ + .clock_source = LL_I2S_CLOCK_SRC_32M, \ + .audio_freq = 48000 \ +} + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros + * @{ + */ + +/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in I2S register + * @param __instance__ I2S instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_I2S_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I2S register + * @param __instance__ I2S instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I2S_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2S_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup I2S_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable I2S + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | ENABLE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable(i2s_regs_t *I2Sx) +{ + SET_BITS(I2Sx->ENABLE, I2S_ENABLE_EN); +} + +/** + * @brief Disable I2S + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | ENABLE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable(i2s_regs_t *I2Sx) +{ + CLEAR_BITS(I2Sx->ENABLE, I2S_ENABLE_EN); +} + +/** + * @brief Check if I2S is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | ENABLE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled(i2s_regs_t *I2Sx) +{ + return (READ_BITS(I2Sx->ENABLE, I2S_ENABLE_EN) == (I2S_ENABLE_EN)); +} + +/** + * @brief Enable I2S RX block + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_rxblock(i2s_regs_t *I2Sx) +{ + SET_BITS(I2Sx->RBEN, I2S_RBEN_EN); +} + +/** + * @brief Disable I2S RX block + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_rxblock(i2s_regs_t *I2Sx) +{ + CLEAR_BITS(I2Sx->RBEN, I2S_RBEN_EN); +} + +/** + * @brief Check if I2S RX block is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_rxblock(i2s_regs_t *I2Sx) +{ + return (READ_BITS(I2Sx->RBEN, I2S_RBEN_EN) == (I2S_RBEN_EN)); +} + +/** + * @brief Enable I2S TX block + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_txblock(i2s_regs_t *I2Sx) +{ + SET_BITS(I2Sx->TBEN, I2S_TBEN_EN); +} + +/** + * @brief Disable I2S TX block + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_txblock(i2s_regs_t *I2Sx) +{ + CLEAR_BITS(I2Sx->TBEN, I2S_TBEN_EN); +} + +/** + * @brief Check if I2S TX block is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TBEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_txblock(i2s_regs_t *I2Sx) +{ + return (READ_BITS(I2Sx->TBEN, I2S_TBEN_EN) == (I2S_TBEN_EN)); +} + +/** + * @brief Enable I2S clock + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_clock(i2s_regs_t *I2Sx) +{ + SET_BITS(I2Sx->CLKEN, I2S_CLKEN_EN); +} + +/** + * @brief Disable I2S clock + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_clock(i2s_regs_t *I2Sx) +{ + CLEAR_BITS(I2Sx->CLKEN, I2S_CLKEN_EN); +} + +/** + * @brief Check if I2S clock is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_clock(i2s_regs_t *I2Sx) +{ + return (READ_BITS(I2Sx->CLKEN, I2S_CLKEN_EN) == (I2S_CLKEN_EN)); +} + +/** + * @brief Set word select line cycles for left or right sample + * @note This bit should be written only when I2S is disabled (I2S_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKCONFIG | WSS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param cycles This parameter can be one of the following values: + * @arg @ref LL_I2S_WS_CYCLES_16 + * @arg @ref LL_I2S_WS_CYCLES_24 + * @arg @ref LL_I2S_WS_CYCLES_32 + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_wss(i2s_regs_t *I2Sx, uint32_t cycles) +{ + MODIFY_REG(I2Sx->CLKCONFIG, I2S_CLKCONFIG_WSS, cycles); +} + +/** + * @brief Get word select line cycles for left or right sample + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKCONFIG | WSS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_WS_CYCLES_16 + * @arg @ref LL_I2S_WS_CYCLES_24 + * @arg @ref LL_I2S_WS_CYCLES_32 + */ +__STATIC_INLINE uint32_t ll_i2s_get_wss(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->CLKCONFIG, I2S_CLKCONFIG_WSS)); +} + +/** + * @brief Set the gating of sclk + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKCONFIG | SCLKG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param cycles This parameter can be one of the following values: + * @arg @ref LL_I2S_SCLKG_NONE + * @arg @ref LL_I2S_SCLKG_CYCLES_12 + * @arg @ref LL_I2S_SCLKG_CYCLES_16 + * @arg @ref LL_I2S_SCLKG_CYCLES_20 + * @arg @ref LL_I2S_SCLKG_CYCLES_24 + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_sclkg(i2s_regs_t *I2Sx, uint32_t cycles) +{ + MODIFY_REG(I2Sx->CLKCONFIG, I2S_CLKCONFIG_SCLKG, cycles); +} + +/** + * @brief Get the gating of sclk + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLKCONFIG | SCLKG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_SCLKG_NONE + * @arg @ref LL_I2S_SCLKG_CYCLES_12 + * @arg @ref LL_I2S_SCLKG_CYCLES_16 + * @arg @ref LL_I2S_SCLKG_CYCLES_20 + * @arg @ref LL_I2S_SCLKG_CYCLES_24 + */ +__STATIC_INLINE uint32_t ll_i2s_get_sclkg(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->CLKCONFIG, I2S_CLKCONFIG_SCLKG)); +} + +/** + * @brief Clear I2S RX FIFO in all channels + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFIFO_RST | RST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_clr_rxfifo_all(i2s_regs_t *I2Sx) +{ + WRITE_REG(I2Sx->RXFIFO_RST, I2S_RXFIFO_RST); +} + +/** + * @brief Clear I2S TX FIFO in all channels + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFIFO_RST | RST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_clr_txfifo_all(i2s_regs_t *I2Sx) +{ + WRITE_REG(I2Sx->TXFIFO_RST, I2S_TXFIFO_RST); +} + +/** + * @brief Set I2S clock divider + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param div This parameter can between: 0 ~ 0xFFF + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_clock_div(uint32_t div) +{ + MODIFY_REG(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_DIV_CNT, div); +} + +/** + * @brief Get I2S clock divider + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned Value can between: 0 ~ 0xFFF + */ +__STATIC_INLINE uint32_t ll_i2s_get_clock_div(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_DIV_CNT)); +} + +/** + * @brief Enable I2S clock divider + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | DIV_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_clock_div(void) +{ + SET_BITS(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN); +} + +/** + * @brief Disable I2S clock divider + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | DIV_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_clock_div(void) +{ + CLEAR_BITS(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN); +} + +/** + * @brief Check if I2S clock divider is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | DIV_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_clock_div(void) +{ + return (READ_BITS(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN) == (MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN)); +} + +/** + * @brief Set I2S clock source + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | SRC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param src This parameter can be one of the following values: + * @arg @ref LL_I2S_CLOCK_SRC_96M + * @arg @ref LL_I2S_CLOCK_SRC_32M + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_clock_src(uint32_t src) +{ + MODIFY_REG(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL, src); +} + +/** + * @brief Get I2S clock source + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_CLK_CFG | SRC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_CLOCK_SRC_96M + * @arg @ref LL_I2S_CLOCK_SRC_32M + */ +__STATIC_INLINE uint32_t ll_i2s_get_clock_src(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->I2S_CLK_CFG, MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL)); +} + +/** @} */ + +/** @defgroup I2S_LL_EF_Channel Channel Configuration functions + * @{ + */ + +/** + * @brief Read one data from left RX FIFO in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_L | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE uint32_t ll_i2s_receive_ldata(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_REG(I2Sx->I2S_CHANNEL[channel].DATA_L)); +} + +/** + * @brief Read one data from right RX FIFO in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_R | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE uint32_t ll_i2s_receive_rdata(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_REG(I2Sx->I2S_CHANNEL[channel].DATA_R)); +} + +/** + * @brief Write one data to left TX FIFO in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_L | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param data The data to send + * @retval None + */ +__STATIC_INLINE void ll_i2s_transmit_ldata(i2s_regs_t *I2Sx, uint8_t channel, uint32_t data) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].DATA_L, data); +} + +/** + * @brief Write one data to right TX FIFO in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_R | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param data The data to send + * @retval None + */ +__STATIC_INLINE void ll_i2s_transmit_rdata(i2s_regs_t *I2Sx, uint8_t channel, uint32_t data) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].DATA_R, data); +} + +/** + * @brief Enable RX in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_rx(i2s_regs_t *I2Sx, uint8_t channel) +{ + SET_BITS(I2Sx->I2S_CHANNEL[channel].RXEN, I2S_RXEN_EN); +} + +/** + * @brief Disable RX in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_rx(i2s_regs_t *I2Sx, uint8_t channel) +{ + CLEAR_BITS(I2Sx->I2S_CHANNEL[channel].RXEN, I2S_RXEN_EN); +} + +/** + * @brief Check if RX in a channel is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_rx(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (READ_BITS(I2Sx->I2S_CHANNEL[channel].RXEN, I2S_RXEN_EN) != (I2S_RXEN_EN)); +} + +/** + * @brief Enable TX in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_tx(i2s_regs_t *I2Sx, uint8_t channel) +{ + SET_BITS(I2Sx->I2S_CHANNEL[channel].TXEN, I2S_TXEN_EN); +} + +/** + * @brief Disable TX in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_tx(i2s_regs_t *I2Sx, uint8_t channel) +{ + CLEAR_BITS(I2Sx->I2S_CHANNEL[channel].TXEN, I2S_TXEN_EN); +} + +/** + * @brief Check if TX in a channel is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_tx(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (READ_BITS(I2Sx->I2S_CHANNEL[channel].TXEN, I2S_TXEN_EN) != (I2S_TXEN_EN)); +} + +/** + * @brief Set receive data width in a channel + * @note These bits should not be changed when channel is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXSIZE | WLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param size This parameter can be one of the following values: + * @arg @ref LL_I2S_DATASIZE_IGNORE + * @arg @ref LL_I2S_DATASIZE_12BIT + * @arg @ref LL_I2S_DATASIZE_16BIT + * @arg @ref LL_I2S_DATASIZE_20BIT + * @arg @ref LL_I2S_DATASIZE_24BIT + * @arg @ref LL_I2S_DATASIZE_32BIT + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_rxsize(i2s_regs_t *I2Sx, uint8_t channel, uint32_t size) +{ + MODIFY_REG(I2Sx->I2S_CHANNEL[channel].RXSIZE, I2S_RXSIZE_WLEN, size); +} + +/** + * @brief Get receive data width in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXSIZE | WLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_DATASIZE_IGNORE + * @arg @ref LL_I2S_DATASIZE_12BIT + * @arg @ref LL_I2S_DATASIZE_16BIT + * @arg @ref LL_I2S_DATASIZE_20BIT + * @arg @ref LL_I2S_DATASIZE_24BIT + * @arg @ref LL_I2S_DATASIZE_32BIT + */ +__STATIC_INLINE uint32_t ll_i2s_get_rxsize(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].RXSIZE, I2S_RXSIZE_WLEN)); +} + +/** + * @brief Set transmit data width in a channel + * @note These bits should not be changed when channel is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXSIZE | WLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param size This parameter can be one of the following values: + * @arg @ref LL_I2S_DATASIZE_IGNORE + * @arg @ref LL_I2S_DATASIZE_12BIT + * @arg @ref LL_I2S_DATASIZE_16BIT + * @arg @ref LL_I2S_DATASIZE_20BIT + * @arg @ref LL_I2S_DATASIZE_24BIT + * @arg @ref LL_I2S_DATASIZE_32BIT + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_txsize(i2s_regs_t *I2Sx, uint8_t channel, uint32_t size) +{ + MODIFY_REG(I2Sx->I2S_CHANNEL[channel].TXSIZE, I2S_TXSIZE_WLEN, size); +} + +/** + * @brief Get transmit data width in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXSIZE | WLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_DATASIZE_IGNORE + * @arg @ref LL_I2S_DATASIZE_12BIT + * @arg @ref LL_I2S_DATASIZE_16BIT + * @arg @ref LL_I2S_DATASIZE_20BIT + * @arg @ref LL_I2S_DATASIZE_24BIT + * @arg @ref LL_I2S_DATASIZE_32BIT + */ +__STATIC_INLINE uint32_t ll_i2s_get_txsize(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].TXSIZE, I2S_TXSIZE_WLEN)); +} + +/** + * @brief Get interrupt flag in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | TXFO | + * +----------------------+-----------------------------------+ + * \endrst + * INTSTAT | TXFE + * INTSTAT | RXFO + * INTSTAT | RXDA + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one or more of the following values: + * @arg @ref LL_I2S_STATUS_TXFO + * @arg @ref LL_I2S_STATUS_TXFE + * @arg @ref LL_I2S_STATUS_RXFO + * @arg @ref LL_I2S_STATUS_RXDA + */ +__STATIC_INLINE uint32_t ll_i2s_get_it_flag(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].INTSTAT, I2S_INTSTAT_TXFO | I2S_INTSTAT_TXFE | \ + I2S_INTSTAT_RXFO | I2S_INTSTAT_RXDA)); +} + +/** + * @brief Check interrupt flag in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | TXFO | + * +----------------------+-----------------------------------+ + * \endrst + * INTSTAT | TXFE + * INTSTAT | RXFO + * INTSTAT | RXDA + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param flag This parameter can be one or more of the following values: + * @arg @ref LL_I2S_STATUS_TXFO + * @arg @ref LL_I2S_STATUS_TXFE + * @arg @ref LL_I2S_STATUS_RXFO + * @arg @ref LL_I2S_STATUS_RXDA + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_active_it_flag(i2s_regs_t *I2Sx, uint8_t channel, uint32_t flag) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].INTSTAT, flag) == flag); +} + +/** + * @brief Enable interrupt in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | TXFO | + * +----------------------+-----------------------------------+ + * \endrst + * INTMASK | TXFE + * INTMASK | RXFO + * INTMASK | RXDA + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param mask This parameter can be one or more of the following values: + * @arg @ref LL_I2S_INT_TXFO + * @arg @ref LL_I2S_INT_TXFE + * @arg @ref LL_I2S_INT_RXFO + * @arg @ref LL_I2S_INT_RXDA + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_it(i2s_regs_t *I2Sx, uint8_t channel, uint32_t mask) +{ + CLEAR_BITS(I2Sx->I2S_CHANNEL[channel].INTMASK, mask); +} + +/** + * @brief Disable interrupt in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | TXFO | + * +----------------------+-----------------------------------+ + * \endrst + * INTMASK | TXFE + * INTMASK | RXFO + * INTMASK | RXDA + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param mask This parameter can be one or more of the following values: + * @arg @ref LL_I2S_INT_TXFO + * @arg @ref LL_I2S_INT_TXFE + * @arg @ref LL_I2S_INT_RXFO + * @arg @ref LL_I2S_INT_RXDA + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_it(i2s_regs_t *I2Sx, uint8_t channel, uint32_t mask) +{ + SET_BITS(I2Sx->I2S_CHANNEL[channel].INTMASK, mask); +} + +/** + * @brief Check if interrupt in a channel is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | TXFO | + * +----------------------+-----------------------------------+ + * \endrst + * INTMASK | TXFE + * INTMASK | RXFO + * INTMASK | RXDA + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param mask This parameter can be one or more of the following values: + * @arg @ref LL_I2S_INT_TXFO + * @arg @ref LL_I2S_INT_TXFE + * @arg @ref LL_I2S_INT_RXFO + * @arg @ref LL_I2S_INT_RXDA + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_it(i2s_regs_t *I2Sx, uint8_t channel, uint32_t mask) +{ + return ((READ_BITS(I2Sx->I2S_CHANNEL[channel].INTMASK, mask) ^ (mask)) == (mask)); +} + +/** + * @brief Clear RX FIFO data overrun interrupt flag in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXOVR | RXCHO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_clear_it_rxovr(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (READ_BITS(I2Sx->I2S_CHANNEL[channel].RXOVR, I2S_RXOVR_RXCHO)); +} + +/** + * @brief Clear TX FIFO data overrun interrupt flag in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXOVR | TXCHO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_clear_it_txovr(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (READ_BITS(I2Sx->I2S_CHANNEL[channel].TXOVR, I2S_TXOVR_TXCHO)); +} + +/** + * @brief Set threshold of RXFIFO in a channel that triggers an RXDA event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFIFO_TL | TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_I2S_THRESHOLD_1FIFO + * @arg @ref LL_I2S_THRESHOLD_2FIFO + * @arg @ref LL_I2S_THRESHOLD_3FIFO + * @arg @ref LL_I2S_THRESHOLD_4FIFO + * @arg @ref LL_I2S_THRESHOLD_5FIFO + * @arg @ref LL_I2S_THRESHOLD_6FIFO + * @arg @ref LL_I2S_THRESHOLD_7FIFO + * @arg @ref LL_I2S_THRESHOLD_8FIFO + * @arg @ref LL_I2S_THRESHOLD_9FIFO + * @arg @ref LL_I2S_THRESHOLD_10FIFO + * @arg @ref LL_I2S_THRESHOLD_11FIFO + * @arg @ref LL_I2S_THRESHOLD_12FIFO + * @arg @ref LL_I2S_THRESHOLD_13FIFO + * @arg @ref LL_I2S_THRESHOLD_14FIFO + * @arg @ref LL_I2S_THRESHOLD_15FIFO + * @arg @ref LL_I2S_THRESHOLD_16FIFO + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_rx_fifo_threshold(i2s_regs_t *I2Sx, uint8_t channel, uint32_t threshold) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].RXFIFO_TL, threshold); +} + +/** + * @brief Get threshold of RXFIFO in a channel that triggers an RXDA event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFIFO_TL | TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_THRESHOLD_1FIFO + * @arg @ref LL_I2S_THRESHOLD_2FIFO + * @arg @ref LL_I2S_THRESHOLD_3FIFO + * @arg @ref LL_I2S_THRESHOLD_4FIFO + * @arg @ref LL_I2S_THRESHOLD_5FIFO + * @arg @ref LL_I2S_THRESHOLD_6FIFO + * @arg @ref LL_I2S_THRESHOLD_7FIFO + * @arg @ref LL_I2S_THRESHOLD_8FIFO + * @arg @ref LL_I2S_THRESHOLD_9FIFO + * @arg @ref LL_I2S_THRESHOLD_10FIFO + * @arg @ref LL_I2S_THRESHOLD_11FIFO + * @arg @ref LL_I2S_THRESHOLD_12FIFO + * @arg @ref LL_I2S_THRESHOLD_13FIFO + * @arg @ref LL_I2S_THRESHOLD_14FIFO + * @arg @ref LL_I2S_THRESHOLD_15FIFO + * @arg @ref LL_I2S_THRESHOLD_16FIFO + */ +__STATIC_INLINE uint32_t ll_i2s_get_rx_fifo_threshold(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].RXFIFO_TL, I2S_RXFIFO_TL)); +} + +/** + * @brief Set threshold of TXFIFO in a channel that triggers an TXFE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFIFO_TL | TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_I2S_THRESHOLD_1FIFO + * @arg @ref LL_I2S_THRESHOLD_2FIFO + * @arg @ref LL_I2S_THRESHOLD_3FIFO + * @arg @ref LL_I2S_THRESHOLD_4FIFO + * @arg @ref LL_I2S_THRESHOLD_5FIFO + * @arg @ref LL_I2S_THRESHOLD_6FIFO + * @arg @ref LL_I2S_THRESHOLD_7FIFO + * @arg @ref LL_I2S_THRESHOLD_8FIFO + * @arg @ref LL_I2S_THRESHOLD_9FIFO + * @arg @ref LL_I2S_THRESHOLD_10FIFO + * @arg @ref LL_I2S_THRESHOLD_11FIFO + * @arg @ref LL_I2S_THRESHOLD_12FIFO + * @arg @ref LL_I2S_THRESHOLD_13FIFO + * @arg @ref LL_I2S_THRESHOLD_14FIFO + * @arg @ref LL_I2S_THRESHOLD_15FIFO + * @arg @ref LL_I2S_THRESHOLD_16FIFO + * @retval None + */ +__STATIC_INLINE void ll_i2s_set_tx_fifo_threshold(i2s_regs_t *I2Sx, uint8_t channel, uint32_t threshold) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].TXFIFO_TL, threshold); +} + +/** + * @brief Get threshold of TXFIFO in a channel that triggers an TXFE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFIFO_TL | TL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_THRESHOLD_1FIFO + * @arg @ref LL_I2S_THRESHOLD_2FIFO + * @arg @ref LL_I2S_THRESHOLD_3FIFO + * @arg @ref LL_I2S_THRESHOLD_4FIFO + * @arg @ref LL_I2S_THRESHOLD_5FIFO + * @arg @ref LL_I2S_THRESHOLD_6FIFO + * @arg @ref LL_I2S_THRESHOLD_7FIFO + * @arg @ref LL_I2S_THRESHOLD_8FIFO + * @arg @ref LL_I2S_THRESHOLD_9FIFO + * @arg @ref LL_I2S_THRESHOLD_10FIFO + * @arg @ref LL_I2S_THRESHOLD_11FIFO + * @arg @ref LL_I2S_THRESHOLD_12FIFO + * @arg @ref LL_I2S_THRESHOLD_13FIFO + * @arg @ref LL_I2S_THRESHOLD_14FIFO + * @arg @ref LL_I2S_THRESHOLD_15FIFO + * @arg @ref LL_I2S_THRESHOLD_16FIFO + */ +__STATIC_INLINE uint32_t ll_i2s_get_tx_fifo_threshold(i2s_regs_t *I2Sx, uint8_t channel) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_CHANNEL[channel].TXFIFO_TL, I2S_TXFIFO_TL)); +} + +/** + * @brief Clear RX FIFO data in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFIFO_FLUSH | FLUSH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_clr_rxfifo_channel(i2s_regs_t *I2Sx, uint8_t channel) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].RXFIFO_FLUSH, I2S_RXFIFO_FLUSH); +} + +/** + * @brief Clear TX FIFO data in a channel + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFIFO_FLUSH | FLUSH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval None + */ +__STATIC_INLINE void ll_i2s_clr_txfifo_channel(i2s_regs_t *I2Sx, uint8_t channel) +{ + WRITE_REG(I2Sx->I2S_CHANNEL[channel].TXFIFO_FLUSH, I2S_TXFIFO_FLUSH); +} + +/** @} */ + +/** @defgroup I2S_LL_EF_DMA_Management DMA Management Functions + * @{ + */ + +/** + * @brief Reset RX block DMA + * @note The RX DMA can be reset to the lowest channel via this register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXDMA_RST | RST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_rst_rxdma(i2s_regs_t *I2Sx) +{ + WRITE_REG(I2Sx->RXDMA_RST, I2S_RXDMA_RST); +} + +/** + * @brief Reset TX block DMA + * @note The TX DMA can be reset to the lowest channel via this register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXDMA_RST | RST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_rst_txdma(i2s_regs_t *I2Sx) +{ + WRITE_REG(I2Sx->TXDMA_RST, I2S_TXDMA_RST); +} + + +/** + * @brief Enable I2S DMA + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMA_ACC_SEL | QSPI1_I2S_M_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * DMA_ACC_SEL | I2C1_I2S_S_SEL + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_enable_dma(i2s_regs_t *I2Sx) +{ + if (I2S_M == I2Sx) + SET_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM); + else + SET_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_I2C1_I2SS); +} + +/** + * @brief Disable I2S DMA + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMA_ACC_SEL | QSPI1_I2S_M_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * DMA_ACC_SEL | I2C1_I2S_S_SEL + * + * @param I2Sx I2S instance + * @retval None + */ +__STATIC_INLINE void ll_i2s_disable_dma(i2s_regs_t *I2Sx) +{ + if (I2S_M == I2Sx) + CLEAR_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM); + else + CLEAR_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_I2C1_I2SS); +} + +/** + * @brief Check if I2S DMA is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMA_ACC_SEL | QSPI1_I2S_M_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * DMA_ACC_SEL | I2C1_I2S_S_SEL + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_is_enabled_dma(i2s_regs_t *I2Sx) +{ + if (I2S_M == I2Sx) + return (READ_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM) == MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM); + else + return (READ_BITS(MCU_SUB->DMA_ACC_SEL, MCU_SUB_DMA_ACC_SEL_I2C1_I2SS) == MCU_SUB_DMA_ACC_SEL_I2C1_I2SS); +} + + +/** @} */ + +/** @defgroup I2S_LL_EF_Component Component Paraments Functions + * @{ + */ + +/** + * @brief Get I2S component paramenters: rx resolution + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM2 | RXSIZE_3 | + * +----------------------+-----------------------------------+ + * \endrst + * I2S_PARAM2 | RXSIZE_2 + * I2S_PARAM2 | RXSIZE_1 + * I2S_PARAM2 | RXSIZE_0 + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_RESOLUTION_12BIT + * @arg @ref LL_I2S_RESOLUTION_16BIT + * @arg @ref LL_I2S_RESOLUTION_20BIT + * @arg @ref LL_I2S_RESOLUTION_24BIT + * @arg @ref LL_I2S_RESOLUTION_32BIT + */ +__STATIC_INLINE uint32_t ll_i2s_get_rx_resolution(i2s_regs_t *I2Sx, uint8_t channel) +{ + uint32_t pos[4] = {I2S_PARAM2_RXSIZE_0_Pos, I2S_PARAM2_RXSIZE_1_Pos, \ + I2S_PARAM2_RXSIZE_2_Pos, I2S_PARAM2_RXSIZE_3_Pos + }; + uint32_t mask[4] = {I2S_PARAM2_RXSIZE_0, I2S_PARAM2_RXSIZE_1, I2S_PARAM2_RXSIZE_2, I2S_PARAM2_RXSIZE_3}; + + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM2, mask[channel]) >> pos[channel]); +} + +/** + * @brief Get I2S component paramenters: tx resolution + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | TXSIZE_3 | + * +----------------------+-----------------------------------+ + * \endrst + * I2S_PARAM1 | TXSIZE_2 + * I2S_PARAM1 | TXSIZE_1 + * I2S_PARAM1 | TXSIZE_0 + * + * @param I2Sx I2S instance + * @param channel The special channel: 0 ~ 3 + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_RESOLUTION_12BIT + * @arg @ref LL_I2S_RESOLUTION_16BIT + * @arg @ref LL_I2S_RESOLUTION_20BIT + * @arg @ref LL_I2S_RESOLUTION_24BIT + * @arg @ref LL_I2S_RESOLUTION_32BIT + */ +__STATIC_INLINE uint32_t ll_i2s_get_tx_resolution(i2s_regs_t *I2Sx, uint8_t channel) +{ + uint32_t pos[4] = {I2S_PARAM1_TXSIZE_0_Pos, I2S_PARAM1_TXSIZE_1_Pos, \ + I2S_PARAM1_TXSIZE_2_Pos, I2S_PARAM1_TXSIZE_3_Pos + }; + uint32_t mask[4] = {I2S_PARAM1_TXSIZE_0, I2S_PARAM1_TXSIZE_1, I2S_PARAM1_TXSIZE_2, I2S_PARAM1_TXSIZE_3}; + + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, mask[channel]) >> pos[channel]); +} + +/** + * @brief Get I2S component paramenters: the number of tx channels + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | TXCHN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_CHANNEL_NUM_1 + * @arg @ref LL_I2S_CHANNEL_NUM_2 + * @arg @ref LL_I2S_CHANNEL_NUM_3 + * @arg @ref LL_I2S_CHANNEL_NUM_4 + */ +__STATIC_INLINE uint32_t ll_i2s_get_tx_channels(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_TXCHN) >> I2S_PARAM1_TXCHN_Pos); +} + +/** + * @brief Get I2S component paramenters: the number of rx channels + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | RXCHN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_CHANNEL_NUM_1 + * @arg @ref LL_I2S_CHANNEL_NUM_2 + * @arg @ref LL_I2S_CHANNEL_NUM_3 + * @arg @ref LL_I2S_CHANNEL_NUM_4 + */ +__STATIC_INLINE uint32_t ll_i2s_get_rx_channels(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_RXCHN) >> I2S_PARAM1_RXCHN_Pos); +} + +/** + * @brief Get I2S component paramenters: whether the receiver block is enabled or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | RXBLOCK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_get_rx_block(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_RXBLOCK) == I2S_PARAM1_RXBLOCK); +} + +/** + * @brief Get I2S component paramenters: whether the transmitter block is enabled or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | TXBLOCK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_get_tx_block(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_TXBLOCK) == I2S_PARAM1_TXBLOCK); +} + +/** + * @brief Get I2S component paramenters: whether the master mode is enabled or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_i2s_get_master_mode(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_MODE) == I2S_PARAM1_MODE); +} + +/** + * @brief Get I2S component paramenters: FIOF depth + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | FIFO_DEPTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_FIFO_DEPTH_2 + * @arg @ref LL_I2S_FIFO_DEPTH_4 + * @arg @ref LL_I2S_FIFO_DEPTH_8 + * @arg @ref LL_I2S_FIFO_DEPTH_16 + */ +__STATIC_INLINE uint32_t ll_i2s_get_fifo_depth(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_FIFO_DEPTH) >> I2S_PARAM1_FIFO_DEPTH_Pos); +} + +/** + * @brief Get I2S component paramenters: APB data width + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_PARAM1 | APB_DATA_WIDTH | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_I2S_APB_WIDTH_8BIT + * @arg @ref LL_I2S_APB_WIDTH_16BIT + * @arg @ref LL_I2S_APB_WIDTH_32BIT + */ +__STATIC_INLINE uint32_t ll_i2s_get_apb_width(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_BITS(I2Sx->I2S_PARAM1, I2S_PARAM1_APB_DATA_WIDTH) >> I2S_PARAM1_APB_DATA_WIDTH_Pos); +} + +/** + * @brief Get I2S component version + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_VERSION | VERSION | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value is const. + */ +__STATIC_INLINE uint32_t ll_i2s_get_version(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_REG(I2Sx->I2S_VERSION)); +} + +/** + * @brief Get I2S component type + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | I2S_TYPE | TYPE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param I2Sx I2S instance + * @retval Returned Value is const. + */ +__STATIC_INLINE uint32_t ll_i2s_get_type(i2s_regs_t *I2Sx) +{ + return (uint32_t)(READ_REG(I2Sx->I2S_TYPE)); +} + +/** @} */ + +/** @defgroup I2S_LL_EF_Init I2S_M Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize I2S registers (Registers restored to their default values). + * @param I2Sx I2S instance + * @retval An error_status_t enumeration value: + * - SUCCESS: I2S registers are de-initialized + * - ERROR: I2S registers are not de-initialized + */ +error_status_t ll_i2s_deinit(i2s_regs_t *I2Sx); + +/** + * @brief Initialize I2S_M registers according to the specified + * parameters in p_i2s_init. + * @param I2Sx I2S instance + * @param p_i2s_init Pointer to a ll_i2s_init_t structure that contains the configuration + * information for the specified I2S_M peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: I2S registers are initialized according to p_i2s_init content + * - ERROR: Problem occurred during I2S Registers initialization + */ +error_status_t ll_i2s_init(i2s_regs_t *I2Sx, ll_i2s_init_t *p_i2s_init); + +/** + * @brief Set each field of a @ref ll_i2s_init_t type structure to default value. + * @param p_i2s_init Pointer to a @ref ll_i2s_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_i2s_struct_init(ll_i2s_init_t *p_i2s_init); + +/** @} */ + +/** @} */ + +#endif /* I2S_M || I2S_S */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_I2S_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_iso7816.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_iso7816.h new file mode 100644 index 0000000..00975e3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_iso7816.h @@ -0,0 +1,1435 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_iso7816.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of ISO7816 LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_ISO7816 ISO7816 + * @brief ISO7816 LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_ISO7816_H__ +#define __GR55xx_LL_ISO7816_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (ISO7816) +/** @defgroup ISO7816_LL_STRUCTURES Structures + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ISO7816_LL_ES_INIT ISO7816 Exported init structure + * @{ + */ +/** + * @brief ISO7816_LL_init_structure LL ISO7816 init Structure definition + */ +typedef struct _ll_iso7816_init +{ + uint32_t clk_div; /*!< clk_div is used for dividing the system clock, + and ISO7816 output clock is equal to (system clock)/(clk_div+1).*/ + uint32_t wait_time; /*!< Specifies the guard time value in terms of number of baud clocks */ + uint16_t guard_time; /*!< Specifies the maximum card response time (leading edge to leading edge) */ + uint8_t detect_coding; /*!< Specifies whether automatically detect coding convention during ATR receiption. */ +} ll_iso7816_init_t; +/** @} */ +/** @} */ + +/** + * @defgroup ISO7816_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ISO7816_LL_Exported_Constants ISO7816 Exported Constants + * @{ + */ + +/** @defgroup ISO7816_LL_EC_ACTION Action state. + * @{ + */ +#define LL_ISO7816_ACTION_NONE 0x00000000U /**< Do Nothing. */ +#define LL_ISO7816_ACTION_OFF 0x00000001U /**< Switch Off. */ +#define LL_ISO7816_ACTION_STOPCLK 0x00000002U /**< Stop the clock. */ +#define LL_ISO7816_ACTION_ON 0x00000003U /**< Switch on and receive ATR. */ +#define LL_ISO7816_ACTION_WARMRST 0x00000004U /**< Trigger warm reset and receive ATR.*/ +#define LL_ISO7816_ACTION_RX 0x00000005U /**< Receive. */ +#define LL_ISO7816_ACTION_TX 0x00000006U /**< Transmit. */ +#define LL_ISO7816_ACTION_TXRX 0x00000007U /**< Transmit, followed by RX. */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_IT IT Defines + * @brief Interrupt definitions which can be used with LL_ISO7816_ReadReg and LL_ISO7816_WriteReg functions + * @{ + */ +#define LL_ISO7816_INTR_TEST ISO7816_STAT_IRQ_TEST /**< Test interrupt */ +#define LL_ISO7816_INTR_PRESENCE ISO7816_STAT_IRQ_PRESENCE /**< Source presence interrupt */ +#define LL_ISO7816_INTR_STATE_ERR ISO7816_STAT_IRQ_STAT_ERR /**< Source state error interrupt */ +#define LL_ISO7816_INTR_DMA_ERR ISO7816_STAT_IRQ_DMA_ERR /**< Source dma error interrupt */ +#define LL_ISO7816_INTR_RETRY_ERR ISO7816_STAT_IRQ_RETRY_ERR /**< Source retry error interrupt */ +#define LL_ISO7816_INTR_RX_ERR ISO7816_STAT_IRQ_RX_ERR /**< Source rx error interrupt */ +#define LL_ISO7816_INTR_DONE ISO7816_STAT_IRQ_DONE /**< Source done error interrupt */ + +#define LL_ISO7816_INTR_MASK_ALL ISO7816_INTR_ALL /**< All interrupt */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_PRESENCE Card Presence Defines + * @{ + */ +#define LL_ISO7816_CARD_ABSENT 0x00000000U /**< SIM Card is absent. */ +#define LL_ISO7816_CARD_PRESENT 0x00000001U /**< SIM Card is present. */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_IO_STATES IO States Defines + * @{ + */ +#define LL_ISO7816_IO_STATE_OFF (0x0UL << ISO7816_STAT_IO_STAT_POS) /**< Off */ +#define LL_ISO7816_IO_STATE_IDLE (0x1UL << ISO7816_STAT_IO_STAT_POS) /**< Idle */ +#define LL_ISO7816_IO_STATE_RX_WAIT (0x4UL << ISO7816_STAT_IO_STAT_POS) /**< Receive Wait */ +#define LL_ISO7816_IO_STATE_RX (0x5UL << ISO7816_STAT_IO_STAT_POS) /**< Receive */ +#define LL_ISO7816_IO_STATE_TX (0x6UL << ISO7816_STAT_IO_STAT_POS) /**< Transmit */ +#define LL_ISO7816_IO_STATE_TX_GUARD (0x7UL << ISO7816_STAT_IO_STAT_POS) /**< Transmit Guard */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_PWR_STATES Power States Defines + * @{ + */ +#define LL_ISO7816_PWR_STATE_OFF (0x0UL << ISO7816_STAT_PWR_STAT_POS) /**< Off */ +#define LL_ISO7816_PWR_STATE_PWRUP_VCC (0x1UL << ISO7816_STAT_PWR_STAT_POS) /**< Power up VCC */ +#define LL_ISO7816_PWR_STATE_PWRUP_RST (0x2UL << ISO7816_STAT_PWR_STAT_POS) /**< Power up reset */ +#define LL_ISO7816_PWR_STATE_PWRDN_RST (0x3UL << ISO7816_STAT_PWR_STAT_POS) /**< Power Down reset */ +#define LL_ISO7816_PWR_STATE_PWRDN_VCC (0x4UL << ISO7816_STAT_PWR_STAT_POS) /**< Power Down VCC */ +#define LL_ISO7816_PWR_STATE_STOP_PRE (0x5UL << ISO7816_STAT_PWR_STAT_POS) /**< Preparing Clock Stop */ +#define LL_ISO7816_PWR_STATE_STOP (0x6UL << ISO7816_STAT_PWR_STAT_POS) /**< Clock Stopped */ +#define LL_ISO7816_PWR_STATE_STOP_POST (0x7UL << ISO7816_STAT_PWR_STAT_POS) /**< Exiting Clock Stop */ +#define LL_ISO7816_PWR_STATE_IDLE (0x8UL << ISO7816_STAT_PWR_STAT_POS) /**< Idle */ +#define LL_ISO7816_PWR_STATE_RX_TS0 (0x9UL << ISO7816_STAT_PWR_STAT_POS) /**< RX TS Character */ +#define LL_ISO7816_PWR_STATE_RX_TS1 (0xAUL << ISO7816_STAT_PWR_STAT_POS) /**< RX TS Character */ +#define LL_ISO7816_PWR_STATE_RX (0xBUL << ISO7816_STAT_PWR_STAT_POS) /**< Receive */ +#define LL_ISO7816_PWR_STATE_TX (0xCUL << ISO7816_STAT_PWR_STAT_POS) /**< Transmit */ +#define LL_ISO7816_PWR_STATE_TX_RX (0xDUL << ISO7816_STAT_PWR_STAT_POS) /**< Transmit and Receive */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_CLKSTOP Clock Stop Select Defines + * @{ + */ +#define LL_ISO7816_CLKSTOP_LOW (0x00000000UL) /**< Stop the clock at low level. */ +#define LL_ISO7816_CLKSTOP_HIGH (0x80000000UL) /**< Stop the clock at high level. */ +/** @} */ + +/** @defgroup ISO7816_LL_EC_CODING Coding Convention Defines + * @{ + */ +#define LL_ISO7816_CODING_DEFAULT (0x00000000UL) /**< High=1, LSB first. */ +#define LL_ISO7816_CODING_INVERSE (0x00000001UL) /**< High=0, MSB first. */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ISO7816_LL_Exported_Macros ISO7816 Exported Macros + * @{ + */ + +/** @defgroup ISO7816_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ISO7816 register + * @param __instance__ ISO7816 instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None. + */ +#define LL_ISO7816_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ISO7816 register + * @param __instance__ ISO7816 instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ISO7816_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ISO7816_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup ISO7816_LL_EF_Configuration Configuration + * @{ + */ +/** + * @brief Request ISO7816 to go to the next action. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ACTION | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @param action This parameter can be one of the following values: + * @arg @ref LL_ISO7816_ACTION_NONE + * @arg @ref LL_ISO7816_ACTION_OFF + * @arg @ref LL_ISO7816_ACTION_STOPCLK + * @arg @ref LL_ISO7816_ACTION_ON + * @arg @ref LL_ISO7816_ACTION_WARMRST + * @arg @ref LL_ISO7816_ACTION_RX + * @arg @ref LL_ISO7816_ACTION_TX + * @arg @ref LL_ISO7816_ACTION_TXRX + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_action(iso7816_regs_t *ISO7816x, uint32_t action) +{ + WRITE_REG(ISO7816x->CTRL, action); +} + + +/** + * @brief Get ISO7816 states. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | ACTION | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval ISO7816 states + */ +__STATIC_INLINE uint32_t ll_iso7816_is_busy(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_BUSY) == (ISO7816_STAT_BUSY)); +} + +/** + * @brief Clear Transmit Retries Maximum. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | TX_RETRY_MAX_CLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_tx_retry_max(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_TX_RETYR_MC); +} + +/** + * @brief Clear Receive Retries Maximum. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RX_RETRY_MAX_CLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_rx_retry_max(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_RX_RETYR_MC); +} + +/** + * @brief Check Card presence. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | PRESENCE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ISO7816_CARD_ABSENT + * @arg @ref LL_ISO7816_CARD_PRESENT + */ +__STATIC_INLINE uint32_t ll_iso7816_check_card_presence(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->STAT, ISO7816_STAT_PRESENCE_STAT) >> ISO7816_STAT_PRESENCE_STAT_POS); +} + +/** + * @brief Get Maximum number of seen transmit retries after error signaling by ISO7816. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | TX_RETRY_MAX | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Value range between 0x1 and 0x7. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_tx_retry_max(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->STAT, ISO7816_STAT_TX_RETRY_MAX) >> ISO7816_STAT_RX_RETRY_MAX_POS); +} + +/** + * @brief Get Maximum number of seen receive retries after error signaling by ISO7816. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | RX_RETRY_MAX | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Value range between 0x1 and 0x7. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_rx_retry_max(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->STAT, ISO7816_STAT_RX_RETRY_MAX) >> ISO7816_STAT_RX_RETRY_MAX_POS); +} + +/** + * @brief Get ISO7816 IO States. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | IO_STATE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_ISO7816_IO_STATE_OFF + * @arg @ref LL_ISO7816_IO_STATE_IDLE + * @arg @ref LL_ISO7816_IO_STATE_RX_WAIT + * @arg @ref LL_ISO7816_IO_STATE_RX + * @arg @ref LL_ISO7816_IO_STATE_TX + * @arg @ref LL_ISO7816_IO_STATE_TX_GUARD + */ +__STATIC_INLINE uint32_t ll_iso7816_get_io_states(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->STAT, ISO7816_STAT_IO_STAT) >> ISO7816_STAT_IO_STAT_POS); +} + +/** + * @brief Get ISO7816 Power States. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | PWR_STATE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ISO7816_PWR_STATE_OFF + * @arg @ref LL_ISO7816_PWR_STATE_PWRUP_VCC + * @arg @ref LL_ISO7816_PWR_STATE_PWRUP_RST + * @arg @ref LL_ISO7816_PWR_STATE_PWRDN_RST + * @arg @ref LL_ISO7816_PWR_STATE_PWRDN_VCC + * @arg @ref LL_ISO7816_PWR_STATE_STOP_PRE + * @arg @ref LL_ISO7816_PWR_STATE_STOP + * @arg @ref LL_ISO7816_PWR_STATE_STOP_POST + * @arg @ref LL_ISO7816_PWR_STATE_IDLE + * @arg @ref LL_ISO7816_PWR_STATE_RX_TS0 + * @arg @ref LL_ISO7816_PWR_STATE_RX_TS1 + * @arg @ref LL_ISO7816_PWR_STATE_RX + * @arg @ref LL_ISO7816_PWR_STATE_TX + * @arg @ref LL_ISO7816_PWR_STATE_TX_RX + */ +__STATIC_INLINE uint32_t ll_iso7816_get_power_states(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->STAT, ISO7816_STAT_PWR_STAT)); +} + +/** + * @brief Set value of the clock output during stopped Clock. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | CLK_STOP_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @param level This parameter can be one of the following values: + * @arg @ref LL_ISO7816_CLKSTOP_LOW + * @arg @ref LL_ISO7816_CLKSTOP_HIGH + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_clkstop_level(iso7816_regs_t *ISO7816x, uint32_t level) +{ + MODIFY_REG(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_CLK_STOP_SEL, level); +} + +/** + * @brief Get value of the clock output during stopped Clock. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | CLK_STOP_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ISO7816_CLKSTOP_LOW + * @arg @ref LL_ISO7816_CLKSTOP_HIGH + */ +__STATIC_INLINE uint32_t ll_iso7816_get_clkstop_level(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_CLK_STOP_SEL)); +} + +/** + * @brief Set clock division. + * @note Divide system clock by this value+1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | CLK_DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @param value This parameter should range between 0x0 and 0xFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_clkdiv(iso7816_regs_t *ISO7816x, uint32_t value) +{ + MODIFY_REG(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_CLK_DIV, value << ISO7816_CLK_CFG_CLK_DIV_POS); +} + +/** + * @brief Get clock division. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | CLK_DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value should range between 0x0 and 0xFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_clkdiv(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_CLK_DIV) >> ISO7816_CLK_CFG_CLK_DIV_POS); +} + +/** + * @brief Set divide ISO7816 clock. + * @note Divide SIM clock by this value+1 to define ETU length. The reset value + * is the one, needed for theATR. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | ETU_DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @param divide This parameter should range between 0x0 and 0x3FF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_etudiv(iso7816_regs_t *ISO7816x, uint32_t divide) +{ + MODIFY_REG(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_ETU_DIV, divide); +} + +/** + * @brief Get divide ISO7816 clock. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CLK_CFG | ETU_DIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value should range between 0x0 and 0x3FF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_etudiv(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->CLK_CFG, ISO7816_CLK_CFG_ETU_DIV)); +} + +/** + * @brief Set ISO7816 wait_time in ETU. + + * @note Time between the leading edges of two consecutive characters + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMES | WAIT_TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @param wait_time This parameter should range between 0x0 and 0x3FFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_waittime(iso7816_regs_t *ISO7816x, uint32_t wait_time) +{ + MODIFY_REG(ISO7816x->TIMES_CFG, ISO7816_TIMES_CFG_WAIT_TIME, wait_time << ISO7816_TIMES_CFG_WAIT_TIME_POS); +} + +/** + * @brief Get maximum card response time(leading edge to leading edge) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMES | WAIT_TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value should range between 0x0 and 0x3FFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_waittime(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->TIMES_CFG, ISO7816_TIMES_CFG_WAIT_TIME) >> ISO7816_TIMES_CFG_WAIT_TIME_POS); +} + +/** + * @brief Set ISO7816 guard_time in ETU. + + * @note Set time between the leading edges of two consecutive characters + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMES | GUARD_TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @param guardtime Time between the leading edges of two consecutive characters + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_guardtime(iso7816_regs_t *ISO7816x, uint32_t guardtime) +{ + MODIFY_REG(ISO7816x->TIMES_CFG, ISO7816_TIMES_CFG_GUARD_TIME, guardtime); +} +/** + * @brief Get time between the leading edges of two consecutive characters. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMES | GUARDTIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value should range between 0x0 and 0x3FF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_guardtime(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->TIMES_CFG, ISO7816_TIMES_CFG_GUARD_TIME)); +} + +/** + * @brief Set maximum number of issued retries before giving up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | RETRY_LIMIT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @param number This parameter should range between 0x0 and 0x7. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_retry_limit(iso7816_regs_t *ISO7816x, uint32_t number) +{ + MODIFY_REG(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_RETRY_LIMIT, number << ISO7816_DATA_CFG_RETRY_LIMIT_POS); +} + +/** + * @brief Get maximum number of issued retries before giving up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | RETRY_LIMIT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value should range between 0x0 and 0x7. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_retry_limit(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_RETRY_LIMIT) >> ISO7816_DATA_CFG_RETRY_LIMIT_POS); +} + +/** + * @brief Enable coding detection. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | DETECT_CODING | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_enable_coding_detection(iso7816_regs_t *ISO7816x) +{ + SET_BITS(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_DETECT_CODING); +} + +/** + * @brief Disable coding detection. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | DETECT_CODING | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_disable_coding_detection(iso7816_regs_t *ISO7816x) +{ + CLEAR_BITS(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_DETECT_CODING); +} + +/** + * @brief Set coding convention. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | CODING | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @param convention This parameter can be one of the following values: + * @arg @ref LL_ISO7816_CODING_DEFAULT + * @arg @ref LL_ISO7816_CODING_INVERSE + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_coding_convention(iso7816_regs_t *ISO7816x, uint32_t convention) +{ + MODIFY_REG(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_CODING, convention); +} + +/** + * @brief Get coding convention. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA_CFG | CODING | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ISO7816_CODING_DEFAULT + * @arg @ref LL_ISO7816_CODING_INVERSE + */ +__STATIC_INLINE uint32_t ll_iso7816_get_coding_convention(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->DATA_CFG, ISO7816_DATA_CFG_CODING)); +} + +/** + * @brief Get current address relative to base_addr. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | ADDR | ADDR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3FFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_current_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->ADDR, ISO7816_ADDR_ADDR) >> ISO7816_ADDR_ADDR_POS); +} + +/** + * @brief Get address fraction. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | ADDR | ADDR_FRAC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_current_addr_frac(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->ADDR, ISO7816_ADDR_ADDR_FRAC)); +} + +/** + * @brief Set start address for RX and TX buffer. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| BASE_ADDR+START_ADDR + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0xFFFFFFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_buffer_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + WRITE_REG(ISO7816x->START_ADDR, addr); +} + +/** + * @brief Get start address for RX and TX buffer. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| BASE_ADDR+START_ADDR + * + * @param ISO7816x ISO7816 instance + */ +__STATIC_INLINE uint32_t ll_iso7816_get_buffer_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_REG(ISO7816x->START_ADDR)); +} + +/** + * @brief Set base address for RX and TX buffer. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| BASE_ADDR + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0xFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_base_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + MODIFY_REG(ISO7816x->START_ADDR, ISO7816_START_ADDR_BASE_ADDR, addr << ISO7816_START_ADDR_BASE_ADDR_POS); +} + +/** + * @brief Get base address for RX and TX buffer. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| BASE_ADDR + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0xFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_base_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->START_ADDR, ISO7816_START_ADDR_BASE_ADDR) >> ISO7816_START_ADDR_BASE_ADDR_POS); +} + +/** + * @brief Set start address for RX and TX buffer, relative to base_addr. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| STRT_ADDR + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0x3FFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_start_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + MODIFY_REG(ISO7816x->START_ADDR, ISO7816_START_ADDR_START_ADDR, addr << ISO7816_START_ADDR_START_ADDR_POS); +} + +/** + * @brief Get start address for RX and TX buffer, relative to base_addr. + * + * Register |BitsName + * ---------|-------- + * STRT_ADDR| STRT_ADDR + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3FFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_start_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->START_ADDR, ISO7816_START_ADDR_START_ADDR) >> ISO7816_START_ADDR_START_ADDR_POS); +} + +/** + * @brief Set end address of receive buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * RX_END_ADDR| RX_END_ADDR+ + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0x3FFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_rx_end_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + MODIFY_REG(ISO7816x->RX_END_ADDR, ISO7816_RX_END_ADDR_RX_END_ADDR, addr << ISO7816_RX_END_ADDR_RX_END_ADDR_POS); +} + +/** + * @brief Set RX endbyte address of receive buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * RX_END_ADDR| RX_END_ADDR+RX_END_AF + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0x3FFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_rx_endbyte_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + WRITE_REG(ISO7816x->RX_END_ADDR, addr); +} + +/** + * @brief Get RX end address of receive buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * RX_END_ADDR| RX_END_ADDR + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3FFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_rx_end_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->RX_END_ADDR, ISO7816_RX_END_ADDR_RX_END_ADDR) >> ISO7816_RX_END_ADDR_RX_END_ADDR_POS); +} + +/** + * @brief Set RX end address fraction. + * + * Register | BitsName + * -----------|-------- + * RX_END_ADDR| RX_END_AF + * + * @param ISO7816x ISO7816 instance + * @param frac This parameter should range between 0x0 and 0x3. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_rx_end_addr_frac(iso7816_regs_t *ISO7816x, uint32_t frac) +{ + MODIFY_REG(ISO7816x->RX_END_ADDR, ISO7816_RX_END_ADDR_RX_END_AF, frac); +} + +/** + * @brief Set TX endbyte address of buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_ADDR+TX_END_AF + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0x3FFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_tx_endbyte_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + WRITE_REG(ISO7816x->TX_END_ADDR, addr); +} + +/** + * @brief Get TX endbyte address of buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_ADDR+TX_END_AF + * + * @param ISO7816x ISO7816 instance + * @retval TX endbyte address. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_tx_endbyte_addr(iso7816_regs_t *ISO7816x) +{ + return READ_REG(ISO7816x->TX_END_ADDR); +} + +/** + * @brief Get RX endbyte address of buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_ADDR+TX_END_AF + * + * @param ISO7816x ISO7816 instance + * @retval RX endbyte address. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_rx_endbyte_addr(iso7816_regs_t *ISO7816x) +{ + return READ_REG(ISO7816x->RX_END_ADDR); +} + +/** + * @brief Get RX end address fraction. + * + * Register | BitsName + * -----------|-------- + * RX_END_ADDR| RX_END_AF + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_rx_end_addr_frac(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->RX_END_ADDR, ISO7816_RX_END_ADDR_RX_END_AF)); +} + +/** + * @brief Set end address of transmit buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_ADDR + * + * @param ISO7816x ISO7816 instance + * @param addr This parameter should range between 0x0 and 0x3FFFF. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_tx_end_addr(iso7816_regs_t *ISO7816x, uint32_t addr) +{ + MODIFY_REG(ISO7816x->TX_END_ADDR, ISO7816_TX_END_ADDR_TX_END_ADDR, addr << ISO7816_TX_END_ADDR_TX_END_ADDR_POS); +} + +/** + * @brief Get end address of transmit buffer, relative to base_addr. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_ADDR + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3FFFF. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_tx_end_addr(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->TX_END_ADDR, ISO7816_TX_END_ADDR_TX_END_ADDR) >> ISO7816_TX_END_ADDR_TX_END_ADDR_POS); +} + +/** + * @brief Set TX end address fraction. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_AF + * + * @param ISO7816x ISO7816 instance + * @param frac This parameter should range between 0x0 and 0x3. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_set_tx_end_addr_frac(iso7816_regs_t *ISO7816x, uint32_t frac) +{ + MODIFY_REG(ISO7816x->TX_END_ADDR, ISO7816_TX_END_ADDR_TX_END_AF, frac); +} + +/** + * @brief Get TX end address fraction. + * + * Register | BitsName + * -----------|-------- + * TX_END_ADDR| TX_END_AF + * + * @param ISO7816x ISO7816 instance + * @retval Value between 0x0 and 0x3. + */ +__STATIC_INLINE uint32_t ll_iso7816_get_tx_end_addr_frac(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_BITS(ISO7816x->TX_END_ADDR, ISO7816_TX_END_ADDR_TX_END_AF)); +} + +/** @} */ + +/** @defgroup ISO7816_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Get ISO7816 interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_TEST | + * +----------------------+-----------------------------------+ + * \endrst + * STAT | STAT_PRESENCE + * STAT | STAT_STATE_ERR + * STAT | STAT_DMA_ERR + * STAT | STAT_RETRY_ERR + * STAT | STAT_RX_ERR + * STAT | STAT_DONE + * + * @param ISO7816x ISO7816 instance. + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_ISO7816_INTR_TEST + * @arg @ref LL_ISO7816_INTR_PRESENCE + * @arg @ref LL_ISO7816_INTR_STATE_ERR + * @arg @ref LL_ISO7816_INTR_DMA_ERR + * @arg @ref LL_ISO7816_INTR_RETRY_ERR + * @arg @ref LL_ISO7816_INTR_RX_ERR + * @arg @ref LL_ISO7816_INTR_DONE +*/ +__STATIC_INLINE uint32_t ll_iso7816_get_it_flag(iso7816_regs_t *ISO7816x) +{ + return (uint32_t)(READ_REG(ISO7816x->STAT) & ISO7816_INTR_ALL); +} + +/** + * @brief Indicate the status of STAT_TEST flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_TEST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_test(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_TEST) == (ISO7816_STAT_IRQ_TEST)); +} + +/** + * @brief Indicate the status of STAT_PRESENCE flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_PRESENCE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_presence(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_PRESENCE) == (ISO7816_STAT_IRQ_PRESENCE)); +} + +/** + * @brief Indicate the status of STAT_STATE_ERR flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_STATE_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_state_err(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_STAT_ERR) == (ISO7816_STAT_IRQ_STAT_ERR)); +} + +/** + * @brief Indicate the status of STAT_DMA_ERR flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_DMA_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_dma_err(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_DMA_ERR) == (ISO7816_STAT_IRQ_DMA_ERR)); +} + +/** + * @brief Indicate the status of STAT_RETRY_ERR flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_RETRY_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_retry_err(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_RETRY_ERR) == (ISO7816_STAT_IRQ_RETRY_ERR)); +} + +/** + * @brief Indicate the status of STAT_RX_ERR flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_RX_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_rx_err(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_RX_ERR) == (ISO7816_STAT_IRQ_RX_ERR)); +} + +/** + * @brief Indicate the status of STAT_DONE flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_iso7816_is_active_flag_done(iso7816_regs_t *ISO7816x) +{ + return (READ_BITS(ISO7816x->STAT, ISO7816_STAT_IRQ_DONE) == (ISO7816_STAT_IRQ_DONE)); +} + +/** + * @brief Clear the combined interrupt, all individual interrupts, and the STAT register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT_TEST | + * +----------------------+-----------------------------------+ + * \endrst + * STAT | STAT_PRESENCE + * STAT | STAT_STATE_ERR + * STAT | STAT_DMA_ERR + * STAT | STAT_RETRY_ERR + * STAT | STAT_RX_ERR + * STAT | STAT_DONE + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_all_intr(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_INTR_ALL); +} + +/** + * @brief Clear test flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_TEST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_test(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_TEST_CLR); +} + +/** + * @brief Clear presence flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_PRESENCE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_presence(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_PRESENCE_CLR); +} + +/** + * @brief Clear state error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_STATE_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_state_err(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_STAT_EC); +} + +/** + * @brief Clear dma error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_DMA_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_dma_err(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_DMA_EC); +} + +/** + * @brief Clear retry error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_RETRY_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_retry_err(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_RETYR_EC); +} + +/** + * @brief Clear RX error flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_RX_ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_rx_err(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_RX_EC); +} + +/** + * @brief Clear done flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CTRL_DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param ISO7816x ISO7816 instance. + * @retval None. + */ +__STATIC_INLINE void ll_iso7816_clear_flag_done(iso7816_regs_t *ISO7816x) +{ + WRITE_REG(ISO7816x->CTRL, ISO7816_CTRL_IRQ_DONE_CLR); +} + +/** @} */ + + +/** @defgroup ISO7816_LL_Init ISO7816 Initialization and de-initialization functions + * @{ + */ + +/** + * @brief Initialize the ISO7816 registers according to the specified parameters in p_iso7816_init. + * @param ISO7816x ISO7816 instance. + * @param p_iso7816_init pointer to a @ref ll_iso7816_init_t structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ISO7816 registers are initialized + * - ERROR: Not applicable + */ +error_status_t ll_iso7816_init(iso7816_regs_t *ISO7816x, ll_iso7816_init_t *p_iso7816_init); + +/** + * @brief De-initialize the ISO7816 registers to their default reset values. + * @param ISO7816x ISO7816 instance. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ISO7816 registers are de-initialized + * - ERROR: ISO7816 registers are not de-initialized + */ +error_status_t ll_iso7816_deinit(iso7816_regs_t *ISO7816x); + +/** @} */ +/** @} */ + +#endif /* ISO7816 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_ISO7816_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_msio.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_msio.h new file mode 100644 index 0000000..07c7c7a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_msio.h @@ -0,0 +1,793 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_msio.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of MSIO LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_MSIO MSIO + * @brief MSIO LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_MSIO_H__ +#define __GR55XX_LL_MSIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** @defgroup MSIO_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup MSIO_LL_ES_INIT MSIO Exported init structures + * @{ + */ + +/** + * @brief MSIO pad Enumerations definition + */ +typedef enum +{ + MSIOA = 0x00, /**< MSIO_A_PAD */ +} msio_pad_t; + +/** + * @brief LL MSIO init Structure definition + */ +typedef struct _ll_msio_init +{ + uint32_t pin; /**< Specifies the MSIO pins to be MSIO_InitStructured. + This parameter can be any value of @ref MSIO_LL_EC_PIN */ + + uint32_t direction; /**< Specifies the direction for the selected pins. + This parameter can be a value of @ref MSIO_LL_EC_DIRECTION. + + MSIO HW MSIO_InitStructuration can be modified afterwards using unitary function @ref ll_msio_set_pin_direction(). */ + + uint32_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref MSIO_LL_EC_MODE. + + MSIO HW MSIO_InitStructuration can be modified afterwards using unitary function @ref ll_msio_set_pin_mode(). */ + + uint32_t pull; /**< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref MSIO_LL_EC_PULL. + + MSIO HW configuration can be modified afterwards using unitary function @ref ll_msio_set_pin_pull().*/ + + uint32_t mux; /*!< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref MSIO_LL_EC_MUX. + + GPIO HW MSIO_InitStructuration can be modified afterwards using unitary function + @ref ll_msio_set_pin_mux(). */ + +} ll_msio_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup MSIO_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup MSIO_LL_Exported_Constants MSIO Exported Constants + * @{ + */ + +/** @defgroup MSIO_LL_EC_PIN PIN + * @{ + */ +#define LL_MSIO_PIN_0 ((uint32_t)0x01U) /**< Select pin 0 */ +#define LL_MSIO_PIN_1 ((uint32_t)0x02U) /**< Select pin 1 */ +#define LL_MSIO_PIN_2 ((uint32_t)0x04U) /**< Select pin 2 */ +#define LL_MSIO_PIN_3 ((uint32_t)0x08U) /**< Select pin 3 */ +#define LL_MSIO_PIN_4 ((uint32_t)0x10U) /**< Select pin 4 */ +#define LL_MSIO_PIN_ALL ((uint32_t)0x1FU) /**< Select all pins */ +/** @} */ + +/** @defgroup MSIO_LL_EC_DIRECTION Direction + * @{ + */ +#define LL_MSIO_DIRECTION_NONE ((uint32_t)0x0U) /**< Disable input/output */ +#define LL_MSIO_DIRECTION_INPUT ((uint32_t)0x1U) /**< Enable input */ +#define LL_MSIO_DIRECTION_OUTPUT ((uint32_t)0x2U) /**< Enable output */ +#define LL_MSIO_DIRECTION_INOUT ((uint32_t)0x3U) /**< Enable input&output */ +/** @} */ + +/** @defgroup MSIO_LL_EC_MODE Mode + * @{ + */ +#define LL_MSIO_MODE_ANALOG ((uint32_t)0x0U) /**< Select analog mode */ +#define LL_MSIO_MODE_DIGITAL ((uint32_t)0x1U) /**< Enable digital mode */ +/** @} */ + +/** @defgroup MSIO_LL_EC_PULL Pull Up Pull Down + * @{ + */ +#define LL_MSIO_PULL_NO ((uint32_t)0x0U) /**< Select I/O no pull */ +#define LL_MSIO_PULL_UP ((uint32_t)0x1U) /**< Select I/O pull up */ +#define LL_MSIO_PULL_DOWN ((uint32_t)0x2U) /**< Select I/O pull down */ +/** @} */ + +/** @defgroup MSIO_LL_EC_MUX Alternate Function + * @{ + */ +#define LL_MSIO_MUX_0 ((uint32_t)0x0U) /*!< Select alternate function 0 */ +#define LL_MSIO_MUX_1 ((uint32_t)0x1U) /*!< Select alternate function 1 */ +#define LL_MSIO_MUX_2 ((uint32_t)0x2U) /*!< Select alternate function 2 */ +#define LL_MSIO_MUX_3 ((uint32_t)0x3U) /*!< Select alternate function 3 */ +#define LL_MSIO_MUX_4 ((uint32_t)0x4U) /*!< Select alternate function 4 */ +#define LL_MSIO_MUX_5 ((uint32_t)0x5U) /*!< Select alternate function 5 */ +#define LL_MSIO_MUX_6 ((uint32_t)0x6U) /*!< Select alternate function 6 */ +#define LL_MSIO_MUX_7 ((uint32_t)0x7U) /*!< Select alternate function 7 */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup MSIO_LL_Exported_Macros MSIO Exported Macros + * @{ + */ + +/** @defgroup MSIO_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in MSIO register + * @param __instance__ MSIO instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_MSIO_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in MSIO register + * @param __instance__ MSIO instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_MSIO_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup MSIO_LL_Private_Macros MSIO Private Macros + * @{ + */ + +/** @defgroup MSIO_LL_EC_DEFAULT_CONFIG InitStruct default configuartion + * @{ + */ + +/** + * @brief LL MSIO InitStrcut default configuartion + */ +#define LL_MSIO_DEFAULT_CONFIG \ +{ \ + .pin = LL_MSIO_PIN_ALL, \ + .direction = LL_MSIO_DIRECTION_INPUT, \ + .mode = LL_MSIO_MODE_DIGITAL, \ + .pull = LL_MSIO_PULL_DOWN, \ + .mux = LL_MSIO_MUX_7, \ +} +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup MSIO_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup MSIO_LL_EF_Port_Configuration Port Configuration + * @{ + */ + +/** + * @brief Set several MSIO pins to input/output direction. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | OE_N | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_0 | IE_N + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @param direction This parameter can be one of the following values: + * @arg @ref LL_MSIO_DIRECTION_NONE + * @arg @ref LL_MSIO_DIRECTION_INPUT + * @arg @ref LL_MSIO_DIRECTION_OUTPUT + * @arg @ref LL_MSIO_DIRECTION_INOUT + * @retval None + */ +__STATIC_INLINE void ll_msio_set_pin_direction(uint32_t pin_mask, uint32_t direction) +{ + uint32_t oe_mask = (pin_mask << AON_MSIO_PAD_CFG_0_OE_N_Pos) & AON_MSIO_PAD_CFG_0_OE_N; + uint32_t ie_mask = (pin_mask << AON_MSIO_PAD_CFG_0_IE_N_Pos) & AON_MSIO_PAD_CFG_0_IE_N; + if (direction != LL_MSIO_DIRECTION_NONE) + { + if (direction != LL_MSIO_DIRECTION_INOUT) + MODIFY_REG(AON->MSIO_PAD_CFG_0, (ie_mask | oe_mask), (direction != LL_MSIO_DIRECTION_INPUT) ? ie_mask : oe_mask); + else + CLEAR_BITS(AON->MSIO_PAD_CFG_0, (ie_mask | oe_mask)); + } + else + SET_BITS(AON->MSIO_PAD_CFG_0, (ie_mask | oe_mask)); +} + +/** + * @brief Return gpio direction for a MSIO pin. + * @note I/O direction can be Input direction, General purpose output. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | OE_N | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_0 | IE_N + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_MSIO_DIRECTION_NONE + * @arg @ref LL_MSIO_DIRECTION_INPUT + * @arg @ref LL_MSIO_DIRECTION_OUTPUT + * @arg @ref LL_MSIO_DIRECTION_INOUT + */ +__STATIC_INLINE uint32_t ll_msio_get_pin_direction(uint32_t pin) +{ + uint32_t oe_mask = (pin << AON_MSIO_PAD_CFG_0_OE_N_Pos) & AON_MSIO_PAD_CFG_0_OE_N; + uint32_t ie_mask = (pin << AON_MSIO_PAD_CFG_0_IE_N_Pos) & AON_MSIO_PAD_CFG_0_IE_N; + uint32_t mask = READ_BITS(AON->MSIO_PAD_CFG_0, (ie_mask | oe_mask)); + if (mask == (ie_mask | oe_mask)) + return LL_MSIO_DIRECTION_NONE; + else + { + if (mask == 0) + return LL_MSIO_DIRECTION_INOUT; + else + return ((mask == ie_mask) ? LL_MSIO_DIRECTION_OUTPUT : LL_MSIO_DIRECTION_INPUT); + } +} + +/** + * @brief Set several MSIO pins to analog/digital mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | AE_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @param mode This parameter can be one of the following values: + * @arg @ref LL_MSIO_MODE_ANALOG + * @arg @ref LL_MSIO_MODE_DIGITAL + * @retval None + */ +__STATIC_INLINE void ll_msio_set_pin_mode(uint32_t pin_mask, uint32_t mode) +{ + uint32_t ae_mask = (pin_mask << AON_MSIO_PAD_CFG_1_AE_N_Pos) & AON_MSIO_PAD_CFG_1_AE_N; + uint32_t ae_n = (mode != LL_MSIO_MODE_DIGITAL) ? 0U : ae_mask; + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->MSIO_PAD_CFG_1, ae_mask, ae_n); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Return gpio mode for a MSIO pin. + * @note I/O mode can be analog or digital. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | AE_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_MSIO_MODE_ANALOG + * @arg @ref LL_MSIO_MODE_DIGITAL + */ +__STATIC_INLINE uint32_t ll_msio_get_pin_mode(uint32_t pin) +{ + uint32_t ae_mask = (pin << AON_MSIO_PAD_CFG_1_AE_N_Pos) & AON_MSIO_PAD_CFG_1_AE_N; + return ((READ_BITS(AON->MSIO_PAD_CFG_1, ae_mask) == ae_mask) ? LL_MSIO_MODE_DIGITAL : LL_MSIO_MODE_ANALOG); +} + +/** + * @brief Configure gpio pull-up or pull-down for a dedicated MSIO pin. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_1 | RTYPE + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @param pull This parameter can be one of the following values: + * @arg @ref LL_MSIO_PULL_NO + * @arg @ref LL_MSIO_PULL_UP + * @arg @ref LL_MSIO_PULL_DOWN + * @retval None + */ +__STATIC_INLINE void ll_msio_set_pin_pull(uint32_t pin_mask, uint32_t pull) +{ + if (pull != LL_MSIO_PULL_NO) + { + uint32_t rtype_mask = (pin_mask << AON_MSIO_PAD_CFG_1_RTYPE_Pos) & AON_MSIO_PAD_CFG_1_RTYPE; + uint32_t rtype = (pull != LL_MSIO_PULL_UP) ? 0U : rtype_mask; + CLEAR_BITS(AON->MSIO_PAD_CFG_0, (pin_mask << AON_MSIO_PAD_CFG_0_RE_N_Pos) & AON_MSIO_PAD_CFG_0_RE_N); + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->MSIO_PAD_CFG_1, rtype_mask, rtype); + GLOBAL_EXCEPTION_ENABLE(); + } + else + { + SET_BITS(AON->MSIO_PAD_CFG_0, (pin_mask << AON_MSIO_PAD_CFG_0_RE_N_Pos) & AON_MSIO_PAD_CFG_0_RE_N); + } +} + +/** + * @brief Return gpio pull-up or pull-down for a dedicated MSIO pin. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | RE_N | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_1 | RTYPE + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_MSIO_PULL_NO + * @arg @ref LL_MSIO_PULL_UP + * @arg @ref LL_MSIO_PULL_DOWN + */ +__STATIC_INLINE uint32_t ll_msio_get_pin_pull(uint32_t pin) +{ + if (READ_BITS(AON->MSIO_PAD_CFG_0, (pin << AON_MSIO_PAD_CFG_0_RE_N_Pos) & AON_MSIO_PAD_CFG_0_RE_N)) + { + return LL_MSIO_PULL_NO; + } + else + { + uint32_t rtype_mask = (pin << AON_MSIO_PAD_CFG_1_RTYPE_Pos) & AON_MSIO_PAD_CFG_1_RTYPE; + return ((READ_BITS(AON->MSIO_PAD_CFG_1, rtype_mask) != RESET) ? LL_MSIO_PULL_UP : LL_MSIO_PULL_DOWN); + } +} + +/** + * @brief Configure gpio pinmux number of a dedicated pin from 0 to 4 for a dedicated port. + * @note Possible values are from AF0 to AF7 depending on target. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_MUX_CTL | CTL_00_04 | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_1 | MCU_OVR + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @param mux This parameter can be one of the following values: + * @arg @ref LL_MSIO_MUX_0 + * @arg @ref LL_MSIO_MUX_1 + * @arg @ref LL_MSIO_MUX_2 + * @arg @ref LL_MSIO_MUX_3 + * @arg @ref LL_MSIO_MUX_4 + * @arg @ref LL_MSIO_MUX_5 + * @arg @ref LL_MSIO_MUX_6 + * @arg @ref LL_MSIO_MUX_7 + * @retval None + */ +__STATIC_INLINE void ll_msio_set_pin_mux(uint32_t pin, uint32_t mux) +{ + uint32_t pos = POSITION_VAL(pin) << 2; + MODIFY_REG(MCU_SUB->MSIO_PAD_MUX_CTL, 0xF << pos, mux << pos); + if(LL_MSIO_MUX_7 == mux) + { + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, pin << AON_MSIO_PAD_CFG_1_MCU_OVR_Pos); + GLOBAL_EXCEPTION_ENABLE(); + } + else + { + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, pin << AON_MSIO_PAD_CFG_1_MCU_OVR_Pos); + GLOBAL_EXCEPTION_ENABLE(); + } +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 4 for a dedicated port. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_MUX_CTL | CTL_00_04 | + * +----------------------+-----------------------------------+ + * \endrst + * MSIO_PAD_CFG_1 | MCU_OVR + * + * @param pin This parameter can be one of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_MSIO_MUX_0 + * @arg @ref LL_MSIO_MUX_1 + * @arg @ref LL_MSIO_MUX_2 + * @arg @ref LL_MSIO_MUX_3 + * @arg @ref LL_MSIO_MUX_4 + * @arg @ref LL_MSIO_MUX_5 + * @arg @ref LL_MSIO_MUX_6 + * @arg @ref LL_MSIO_MUX_7 + */ +__STATIC_INLINE uint32_t ll_msio_get_pin_mux(uint32_t pin) +{ + if(READ_BITS(AON->MSIO_PAD_CFG_1, pin << AON_MSIO_PAD_CFG_1_MCU_OVR_Pos)) + { + uint32_t pos = POSITION_VAL(pin) << 2; + return (READ_BITS(MCU_SUB->MSIO_PAD_MUX_CTL, 0xF << pos) >> pos); + } + else + { + return LL_MSIO_MUX_7; + } +} + +/** @} */ + +/** @defgroup MSIO_LL_EF_Data_Access Data Access + * @{ + */ + +/** + * @brief Return full input data register value of MSIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_REG0 | MSIO_C | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Input data register value of port + */ +__STATIC_INLINE uint32_t ll_msio_read_input_port(void) +{ + return (uint32_t)(READ_BITS(MCU_SUB->MSIO_REG0, MCU_SUB_MSIO_REG0_MSIO_C)); +} + +/** + * @brief Return if input data level of several MSIO pins is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_REG0 | MSIO_C | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_msio_is_input_pin_set(uint32_t pin_mask) +{ + return (uint32_t)(READ_BITS(MCU_SUB->MSIO_REG0, pin_mask) == pin_mask); +} + +/** + * @brief Write output data register of MSIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param port_value Level value for each pin of the port + * @retval None + */ +__STATIC_INLINE void ll_msio_write_output_port(uint32_t port_value) +{ + MODIFY_REG(AON->MSIO_PAD_CFG_0, AON_MSIO_PAD_CFG_0_IN, (port_value << AON_MSIO_PAD_CFG_0_IN_Pos) & AON_MSIO_PAD_CFG_0_IN); +} + +/** + * @brief Return full output data register value of MSIO. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Output data register value of port + */ +__STATIC_INLINE uint32_t ll_msio_read_output_port(void) +{ + return (uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_0, AON_MSIO_PAD_CFG_0_IN) >> AON_MSIO_PAD_CFG_0_IN_Pos); +} + +/** + * @brief Return if input data level of several MSIO pins is high or low. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_msio_is_output_pin_set(uint32_t pin_mask) +{ + pin_mask = (pin_mask << AON_MSIO_PAD_CFG_0_IN_Pos) & AON_MSIO_PAD_CFG_0_IN; + return (uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_0, pin_mask) == pin_mask); +} + +/** + * @brief Set specified MSIO pins to high level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_msio_set_output_pin(uint32_t pin_mask) +{ + SET_BITS(AON->MSIO_PAD_CFG_0, (pin_mask << AON_MSIO_PAD_CFG_0_IN_Pos) & AON_MSIO_PAD_CFG_0_IN); +} + +/** + * @brief Set specified MSIO pins to low level. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_msio_reset_output_pin(uint32_t pin_mask) +{ + CLEAR_BITS(AON->MSIO_PAD_CFG_0, (pin_mask << AON_MSIO_PAD_CFG_0_IN_Pos) & AON_MSIO_PAD_CFG_0_IN); +} + +/** + * @brief Toggle data value of specified MSIO pins. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_0 | IN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param pin_mask This parameter can be a combination of the following values: + * @arg @ref LL_MSIO_PIN_0 + * @arg @ref LL_MSIO_PIN_1 + * @arg @ref LL_MSIO_PIN_2 + * @arg @ref LL_MSIO_PIN_3 + * @arg @ref LL_MSIO_PIN_4 + * @arg @ref LL_MSIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_msio_toggle_pin(uint32_t pin_mask) +{ + WRITE_REG(AON->MSIO_PAD_CFG_0, (READ_REG(AON->MSIO_PAD_CFG_0) ^ ((pin_mask << AON_MSIO_PAD_CFG_0_IN_Pos) & AON_MSIO_PAD_CFG_0_IN))); +} + +/** @} */ + +/** @defgroup MSIO_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize MSIO registers (Registers restored to their default values). + * @retval An error_status_t enumeration value: + * - SUCCESS: MSIO registers are de-initialized + * - ERROR: MSIO registers are not de-initialized + */ +error_status_t ll_msio_deinit(void); + +/** + * @brief Initialize MSIO registers according to the specified. + * parameters in p_msio_init. + * @param p_msio_init Pointer to a ll_msio_init_t structure that contains the configuration + * information for the specified MSIO peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: MSIO registers are initialized according to p_msio_init content + * - ERROR: Problem occurred during MSIO Registers initialization + */ +error_status_t ll_msio_init(ll_msio_init_t *p_msio_init); + +/** + * @brief Set each field of a @ref ll_msio_init_t type structure to default value. + * @param p_msio_init Pointer to a @ref ll_msio_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_msio_struct_init(ll_msio_init_t *p_msio_init); + +/** @} */ + +/** @} */ + +#endif /* AON */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_MSIO_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pkc.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pkc.h new file mode 100644 index 0000000..a2eed55 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pkc.h @@ -0,0 +1,3024 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_pkc.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PKC LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_PKC PKC + * @brief PKC LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_PKC_H__ +#define __GR55XX_LL_PKC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (PKC) + +/** @addtogroup PKC_LL_MACRO + * @{ + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PKC_LL_Private_Macro PKC Private Macros + * @{ + */ +#define ECC_U32_LENGTH (8) /**< ECC Array Length */ +#define RSA_U32_LENGTH (64) /**< RSA Array Length */ + +/** @} */ + +/** @} */ + +/** @defgroup PKC_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PKC_LL_ES_INIT PKC Exported Init structures + * @{ + */ + +/** + * @brief LL PKC ECC Point Structure definition + */ +typedef struct _ll_ecc_point +{ + uint32_t X[ECC_U32_LENGTH]; /**< Specifies the point in x-axis */ + + uint32_t Y[ECC_U32_LENGTH]; /**< Specifies the point in y-axis */ + +} ll_ecc_point_t; + +/** + * @brief LL PKC ECC P-256 Elliptic Curve Init Structure definition + */ +typedef struct _ll_ecc_curve_init +{ + uint32_t A[ECC_U32_LENGTH]; /**< Operand A array */ + uint32_t B[ECC_U32_LENGTH]; /**< Operand B array */ + + uint32_t P[ECC_U32_LENGTH]; /**< Prime number P array */ + uint32_t PRSquare[ECC_U32_LENGTH]; /**< R^2 mod P, where R = 2^256 */ + uint32_t ConstP; /**< Montgomery multiplication constant in prime field P, ConstP = 1 */ + + uint32_t N[ECC_U32_LENGTH]; /**< Prime number N array */ + uint32_t NRSquare[ECC_U32_LENGTH]; /**< R^2 mod N, where R = 2^256 */ + uint32_t ConstN; /**< Montgomery multiplication constant in prime field N, ConstN = 0xee00bc4f */ + + uint32_t H; /**< H */ + + ll_ecc_point_t G; /**< ECC Point G */ + +} ll_ecc_curve_init_t; + +/** + * @brief LL PKC Init Structure definition + */ +typedef struct _ll_pkc_init +{ + ll_ecc_curve_init_t *p_ecc_curve; /**< Specifies the pointer to elliptic curve description */ + + uint32_t data_bits; /**< Specifies the Data size: 256 ~ 2048bits */ + +} ll_pkc_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup PKC_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PKC_LL_Exported_Constants PKC Exported Constants + * @{ + */ + +/** @defgroup PKC_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_PKC_ReadReg function + * @{ + */ +#define LL_PKC_WORKSTAT_BUSY PKC_WORKSTAT_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup PKC_LL_EC_IT IT Defines + * @brief Interrupt defines which can be used with LL_PKC_ReadReg and LL_PKC_WriteReg functions + * @{ + */ +#define LL_PKC_INTEN_DONE PKC_INTEN_DONE /**< Operation Done Interrupt source */ +#define LL_PKC_INTEN_ERR PKC_INTEN_ERR /**< Operation Error Interrupt source */ +#define LL_PKC_INTEN_BAOVF PKC_INTEN_BAOVF /**< Big Integer Result Overflow Interrupt source */ +/** @} */ + +/** @defgroup PKC_LL_EC_BITS_LENGTH Bits Length + * @{ + */ +#define LL_PKC_BITS_LENGTH_MIN (256U) /**< Bits length min value */ +#define LL_PKC_BITS_LENGTH_MAX (2048U) /**< Bits length max value */ +#define LL_PKC_BIGMULTI_BITS_LENGTH_MAX (1024U) /**< Big number multiplication bits Length max value */ +/** @} */ + +/** @defgroup PKC_LL_EC_OPERATION_MODE Operation Mode + * @{ + */ +#define LL_PKC_operation_mode_MULTIPLY (0x00000000U) /**< Multiplication operation mode */ +#define LL_PKC_operation_mode_INVERTION (1UL << PKC_SW_CTRL_OPMODE_Pos) /**< Inversion operation mode */ +#define LL_PKC_operation_mode_ADD (2UL << PKC_SW_CTRL_OPMODE_Pos) /**< Addition operation mode */ +#define LL_PKC_operation_mode_SUB (3UL << PKC_SW_CTRL_OPMODE_Pos) /**< Subtraction operation mode */ +#define LL_PKC_operation_mode_COMPARE (4UL << PKC_SW_CTRL_OPMODE_Pos) /**< Comparison operation mode */ +#define LL_PKC_operation_mode_LEFTSHIFT (5UL << PKC_SW_CTRL_OPMODE_Pos) /**< Left Shift operation mode */ +#define LL_PKC_operation_mode_BIGINTEGERMULTIPLY (6UL << PKC_SW_CTRL_OPMODE_Pos) /**< Big Number Multiplication operation mode */ +#define LL_PKC_operation_mode_BIGINTEGERADD (7UL << PKC_SW_CTRL_OPMODE_Pos) /**< Big Number Addition operation mode */ +/** @} */ + +/** @defgroup PKC_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL PKC ECC Curve default configuretion. + */ +#define LL_ECC_CURVE_DEFAULT_CONFIG LL_ECC_CURVE_SECP256R1_CONFIG + +/** + * @brief LL PKC ECC Curve SECP256R1 configuretion. + */ +#define LL_ECC_CURVE_SECP256R1_CONFIG \ +{ \ + .A = {0xFFFFFFFC, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC}, \ + .B = {0xDC30061D, 0x04874834, 0xE5A220AB, 0xF7212ED6, 0xACF005CD, 0x78843090, 0xD89CDF62, 0x29C4BDDF}, \ + .P = {0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, \ + .PRSquare = {0x00000004, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFB, 0xFFFFFFFF, 0x00000000, 0x00000003}, \ + .ConstP = 1, \ + .N = {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xBCE6FAAD, 0xA7179E84, 0xF3B9CAC2, 0xFC632551}, \ + .NRSquare = {0x66E12D94, 0xF3D95620, 0x2845B239, 0x2B6BEC59, 0x4699799C, 0x49BD6FA6, 0x83244C95, 0xBE79EEA2}, \ + .ConstN = 0xEE00BC4F, \ + .H = 1, \ + .G.X = {0x6B17D1F2, 0xE12C4247, 0xF8BCE6E5, 0x63A440F2, 0x77037D81, 0x2DEB33A0, 0xF4A13945, 0xD898C296}, \ + .G.Y = {0x4FE342E2, 0xFE1A7F9B, 0x8EE7EB4A, 0x7C0F9E16, 0x2BCE3357, 0x6B315ECE, 0xCBB64068, 0x37BF51F5}, \ +} + +/** + * @brief LL PKC ECC Curve SECP256K1 configuretion. + */ +#define LL_ECC_CURVE_SECP256K1_CONFIG \ +{ \ + .A = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, \ + .B = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00001AB7}, \ + .P = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFC2F}, \ + .PRSquare = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x000007A2, 0x000E90A1}, \ + .ConstP = 0XD2253531, \ + .N = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xBAAEDCE6, 0xAF48A03B, 0xBFD25E8C, 0xD0364141}, \ + .NRSquare = {0x9D671CD5, 0x81C69BC5, 0xE697F5E4, 0x5BCD07C6, 0x741496C2, 0x0E7CF878, 0x896CF214, 0x67D7D140}, \ + .ConstN = 0X5588B13F, \ + .H = 1, \ + .G.X = {0x79BE667E, 0xF9DCBBAC, 0x55A06295, 0xCE870B07, 0x029BFCDB, 0x2DCE28D9, 0x59F2815B, 0x16F81798}, \ + .G.Y = {0x483ADA77, 0x26A3C465, 0x5DA4FBFC, 0x0E1108A8, 0xFD17B448, 0xA6855419, 0x9C47D08F, 0xFB10D4B8}, \ +} + +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PKC_LL_Exported_Macros PKC Exported Macros + * @{ + */ + +/** @defgroup PKC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in PKC register + * @param __INSTANCE__ PKC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_PKC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PKC register + * @param __INSTANCE__ PKC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_PKC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PKC_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup PKC_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable pkc. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->CTRL, PKC_CTRL_EN); +} + +/** + * @brief Disable pkc. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->CTRL, PKC_CTRL_EN); +} + +/** + * @brief Indicate whether the pkc is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CTRL, PKC_CTRL_EN) == (PKC_CTRL_EN)); +} + +/** + * @brief Enable pkc start in hardware mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_hardware_start(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->CTRL, PKC_CTRL_START); +} + +/** + * @brief Disable pkc start in hardware mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_hardware_start(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->CTRL, PKC_CTRL_START); +} + +/** + * @brief Indicate whether the pkc start in hardware mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | START | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_hardware_start(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CTRL, PKC_CTRL_START) == (PKC_CTRL_START)); +} + +/** + * @brief Enable pkc software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_software(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->CTRL, PKC_CTRL_SWCTRL); +} + +/** + * @brief Disable pkc software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_software(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->CTRL, PKC_CTRL_SWCTRL); +} + +/** + * @brief Indicate whether the pkc software mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_software(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CTRL, PKC_CTRL_SWCTRL) == (PKC_CTRL_SWCTRL)); +} + +/** + * @brief Enable pkc reset. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWRST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_reset(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->CTRL, PKC_CTRL_SWRST); +} + +/** + * @brief Disable pkc reset. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWRST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_reset(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->CTRL, PKC_CTRL_SWRST); +} + +/** + * @brief Indicate whether the pkc reset is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | SWRST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_reset(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CTRL, PKC_CTRL_SWRST) == (PKC_CTRL_SWRST)); +} + +/** + * @brief Set PKC parameter k pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG0 | KPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_k_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG0, PKC_CONFIG0_KPTR, pointer << PKC_CONFIG0_KPTR_Pos); +} + +/** + * @brief Get PKC parameter k pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG0 | KPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_k_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG0, PKC_CONFIG0_KPTR) >> PKC_CONFIG0_KPTR_Pos); +} + +/** + * @brief Set PKC parameter r pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG0 | RPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG0, PKC_CONFIG0_RPTR, pointer << PKC_CONFIG0_RPTR_Pos); +} + +/** + * @brief Get PKC parameter r pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG0 | RPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG0, PKC_CONFIG0_RPTR) >> PKC_CONFIG0_RPTR_Pos); +} + +/** + * @brief Set PKC parameter p pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG1 | PPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_p_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG1, PKC_CONFIG1_PPTR, pointer << PKC_CONFIG1_PPTR_Pos); +} + +/** + * @brief Get PKC parameter p pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG1 | PPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_p_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG1, PKC_CONFIG1_PPTR) >> PKC_CONFIG1_PPTR_Pos); +} + +/** + * @brief Set PKC parameter R^2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG1 | RSQPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_rsq_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG1, PKC_CONFIG1_RSQPTR, pointer << PKC_CONFIG1_RSQPTR_Pos); +} + +/** + * @brief Get PKC parameter R^2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG1 | RSQPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_rsq_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG1, PKC_CONFIG1_RSQPTR) >> PKC_CONFIG1_RSQPTR_Pos); +} + +/** + * @brief Set PKC parameter Gx pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG2 | GXPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_gx_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG2, PKC_CONFIG2_GXPTR, pointer << PKC_CONFIG2_GXPTR_Pos); +} + +/** + * @brief Get PKC parameter Gx pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG2 | GXPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_gx_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG2, PKC_CONFIG2_GXPTR) >> PKC_CONFIG2_GXPTR_Pos); +} + +/** + * @brief Set PKC parameter Gy pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG2 | GYPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_gy_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG2, PKC_CONFIG2_GYPTR, pointer << PKC_CONFIG2_GYPTR_Pos); +} + +/** + * @brief Get PKC parameter Gy pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG2 | GYPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_gy_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG2, PKC_CONFIG2_GYPTR) >> PKC_CONFIG2_GYPTR_Pos); +} + +/** + * @brief Set PKC parameter Gz pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG3 | GZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_gz_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG3, PKC_CONFIG3_GZPTR, pointer << PKC_CONFIG3_GZPTR_Pos); +} + +/** + * @brief Get PKC parameter Gz pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG3 | GZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_gz_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG3, PKC_CONFIG3_GZPTR) >> PKC_CONFIG3_GZPTR_Pos); +} + +/** + * @brief Set PKC parameter R0x pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG3 | R0XPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r0x_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG3, PKC_CONFIG3_R0XPTR, pointer << PKC_CONFIG3_R0XPTR_Pos); +} + +/** + * @brief Get PKC parameter R0x pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG3 | R0XPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r0x_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG3, PKC_CONFIG3_R0XPTR) >> PKC_CONFIG3_R0XPTR_Pos); +} + +/** + * @brief Set PKC parameter R0y pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG4 | R0YPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r0y_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG4, PKC_CONFIG4_R0YPTR, pointer << PKC_CONFIG4_R0YPTR_Pos); +} + +/** + * @brief Get PKC parameter R0y pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG4 | R0YPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r0y_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG4, PKC_CONFIG4_R0YPTR) >> PKC_CONFIG4_R0YPTR_Pos); +} + +/** + * @brief Set PKC parameter R0z pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG4 | R0ZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r0z_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG4, PKC_CONFIG4_R0ZPTR, pointer << PKC_CONFIG4_R0ZPTR_Pos); +} + +/** + * @brief Get PKC parameter R0z pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG4 | R0ZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r0z_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG4, PKC_CONFIG4_R0ZPTR) >> PKC_CONFIG4_R0ZPTR_Pos); +} + +/** + * @brief Set PKC parameter R1x pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG5 | R1XPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r1x_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG5, PKC_CONFIG5_R1XPTR, pointer << PKC_CONFIG5_R1XPTR_Pos); +} + +/** + * @brief Get PKC parameter R1x pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG5 | R1XPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r1x_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG5, PKC_CONFIG5_R1XPTR) >> PKC_CONFIG5_R1XPTR_Pos); +} + +/** + * @brief Set PKC parameter R1y pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG5 | R1YPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r1y_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG5, PKC_CONFIG5_R1YPTR, pointer << PKC_CONFIG5_R1YPTR_Pos); +} + +/** + * @brief Get PKC parameter R1y pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG5 | R1YPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r1y_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG5, PKC_CONFIG5_R1YPTR) >> PKC_CONFIG5_R1YPTR_Pos); +} + +/** + * @brief Set PKC parameter R1z pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG6 | R1ZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_r1z_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG6, PKC_CONFIG6_R1ZPTR, pointer << PKC_CONFIG6_R1ZPTR_Pos); +} + +/** + * @brief Get PKC parameter R1z pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG6 | R1ZPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_r1z_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG6, PKC_CONFIG6_R1ZPTR) >> PKC_CONFIG6_R1ZPTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG6 | TMP1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp1_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG6, PKC_CONFIG6_TMP1PTR, pointer << PKC_CONFIG6_TMP1PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG6 | TMP1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp1_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG6, PKC_CONFIG6_TMP1PTR) >> PKC_CONFIG6_TMP1PTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG7 | TMP2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp2_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG7, PKC_CONFIG7_TMP2PTR, pointer << PKC_CONFIG7_TMP2PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG7 | TMP2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp2_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG7, PKC_CONFIG7_TMP2PTR) >> PKC_CONFIG7_TMP2PTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp3 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG7 | TMP3PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp3_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG7, PKC_CONFIG7_TMP3PTR, pointer << PKC_CONFIG7_TMP3PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp3 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG7 | TMP3PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp3_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG7, PKC_CONFIG7_TMP3PTR) >> PKC_CONFIG7_TMP3PTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp4 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG8 | TMP4PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp4_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG8, PKC_CONFIG8_TMP4PTR, pointer << PKC_CONFIG8_TMP4PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp4 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG8 | TMP4PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp4_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG8, PKC_CONFIG8_TMP4PTR) >> PKC_CONFIG8_TMP4PTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp5 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG8 | TMP5PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp5_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG8, PKC_CONFIG8_TMP5PTR, pointer << PKC_CONFIG8_TMP5PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp5 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG8 | TMP5PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp5_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG8, PKC_CONFIG8_TMP5PTR) >> PKC_CONFIG8_TMP5PTR_Pos); +} + +/** + * @brief Set PKC parameter Tmp6 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG9 | TMP6PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmp6_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG9, PKC_CONFIG9_TMP6PTR, pointer << PKC_CONFIG9_TMP6PTR_Pos); +} + +/** + * @brief Get PKC parameter Tmp6 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG9 | TMP6PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmp6_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG9, PKC_CONFIG9_TMP6PTR) >> PKC_CONFIG9_TMP6PTR_Pos); +} + +/** + * @brief Set PKC parameter Constant1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG9 | CONST1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_constant1_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG9, PKC_CONFIG9_CONST1PTR, pointer << PKC_CONFIG9_CONST1PTR_Pos); +} + +/** + * @brief Get PKC parameter Constant1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG9 | CONST1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_constant1_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG9, PKC_CONFIG9_CONST1PTR) >> PKC_CONFIG9_CONST1PTR_Pos); +} + +/** + * @brief Set PKC parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG10 | X1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_x1_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG10, PKC_CONFIG10_X1PTR, pointer << PKC_CONFIG10_X1PTR_Pos); +} + +/** + * @brief Get PKC parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG10 | X1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_x1_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG10, PKC_CONFIG10_X1PTR) >> PKC_CONFIG10_X1PTR_Pos); +} + +/** + * @brief Set PKC parameter X2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG10 | X2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_x2_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG10, PKC_CONFIG10_X2PTR, pointer << PKC_CONFIG10_X2PTR_Pos); +} + +/** + * @brief Get PKC parameter X2 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG10 | X2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_x2_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG10, PKC_CONFIG10_X2PTR) >> PKC_CONFIG10_X2PTR_Pos); +} + +/** + * @brief Set PKC parameter MITmp pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG11 | MITMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mitmp_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG11, PKC_CONFIG11_MITMPPTR, pointer << PKC_CONFIG11_MITMPPTR_Pos); +} + +/** + * @brief Get PKC parameter MITmp pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG11 | MITMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mitmp_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG11, PKC_CONFIG11_MITMPPTR) >> PKC_CONFIG11_MITMPPTR_Pos); +} + +/** + * @brief Set PKC parameter TmpK pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG11 | TMPKPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_tmpk_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG11, PKC_CONFIG11_TMPKPTR, pointer << PKC_CONFIG11_TMPKPTR_Pos); +} + +/** + * @brief Get PKC parameter TmpK pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG11 | TMPKPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_tmpk_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG11, PKC_CONFIG11_TMPKPTR) >> PKC_CONFIG11_TMPKPTR_Pos); +} + +/** + * @brief Set ECC parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG12 | APTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_ecc_a_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG12, PKC_CONFIG12_APTR, pointer << PKC_CONFIG12_APTR_Pos); +} + +/** + * @brief Get ECC parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG12 | APTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_ecc_a_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG12, PKC_CONFIG12_APTR) >> PKC_CONFIG12_APTR_Pos); +} + +/** + * @brief Set ECC parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG12 | BPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_ecc_b_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->CONFIG12, PKC_CONFIG12_BPTR, pointer << PKC_CONFIG12_BPTR_Pos); +} + +/** + * @brief Get ECC parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG12 | BPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_ecc_b_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->CONFIG12, PKC_CONFIG12_BPTR) >> PKC_CONFIG12_BPTR_Pos); +} + +/** + * @brief Set constant value for montgomery multiply in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG13 | CONSTP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param ConstP This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_constp(pkc_regs_t *PKCx, uint32_t ConstP) +{ + WRITE_REG(PKCx->CONFIG13, ConstP); +} + +/** + * @brief Get constant value for montgomery multiply in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG13 | CONSTP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_constp(pkc_regs_t *PKCx) +{ + return (READ_REG(PKCx->CONFIG13)); +} + +/** + * @brief Enable pkc start in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | OPSTART | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_software_start(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_OPSTART); +} + +/** + * @brief Disable pkc start in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | OPSTART | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_software_start(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_OPSTART); +} + +/** + * @brief Indicate whether the pkc start in software mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | OPSTART | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_software_start(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_OPSTART) == (PKC_SW_CTRL_OPSTART)); +} + +/** + * @brief Set operation mode in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | OPMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param operation_mode This parameter can be one of the following values: + * @arg @ref LL_PKC_operation_mode_MULTIPLY + * @arg @ref LL_PKC_operation_mode_INVERTION + * @arg @ref LL_PKC_operation_mode_ADD + * @arg @ref LL_PKC_operation_mode_SUB + * @arg @ref LL_PKC_operation_mode_COMPARE + * @arg @ref LL_PKC_operation_mode_LEFTSHIFT + * @arg @ref LL_PKC_operation_mode_BIGINTEGERMULTIPLY + * @arg @ref LL_PKC_operation_mode_BIGINTEGERADD + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_operation_mode(pkc_regs_t *PKCx, uint32_t operation_mode) +{ + MODIFY_REG(PKCx->SW_CTRL, PKC_SW_CTRL_OPMODE, operation_mode); +} + +/** + * @brief Get operation mode in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | OPMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PKC_operation_mode_MULTIPLY + * @arg @ref LL_PKC_operation_mode_INVERTION + * @arg @ref LL_PKC_operation_mode_ADD + * @arg @ref LL_PKC_operation_mode_SUB + * @arg @ref LL_PKC_operation_mode_COMPARE + * @arg @ref LL_PKC_operation_mode_LEFTSHIFT + * @arg @ref LL_PKC_operation_mode_BIGINTEGERMULTIPLY + * @arg @ref LL_PKC_operation_mode_BIGINTEGERADD + */ +__STATIC_INLINE uint32_t ll_pkc_get_operation_mode(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_OPMODE)); +} + +/** + * @brief Enable Dummy Multi in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | STARTDM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_dummy_multi(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_STARTDM); +} + +/** + * @brief Disable Dummy Multi in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | STARTDM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_dummy_multi(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_STARTDM); +} + +/** + * @brief Indicate whether the Dummy Multi in software mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | STARTDM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_dummy_multi(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_STARTDM) == (PKC_SW_CTRL_STARTDM)); +} + +/** + * @brief Enable Random Clock Gating in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | RANDEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_enable_random_clock_gating(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_RANDEN); +} + +/** + * @brief Disable Random Clock Gating in software mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | RANDEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval None + */ +__STATIC_INLINE void ll_pkc_disable_random_clock_gating(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_RANDEN); +} + +/** + * @brief Indicate whether the Random Clock Gating in software mode is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CTRL | RANDEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enabled_random_clock_gating(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CTRL, PKC_SW_CTRL_RANDEN) == (PKC_SW_CTRL_RANDEN)); +} + +/** + * @brief Set modular multiplication parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG0 | MMAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mm_a_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG0, PKC_SW_CONFIG0_MMAPTR, pointer << PKC_SW_CONFIG0_MMAPTR_Pos); +} + +/** + * @brief Get modular multiplication parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG0 | MMAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mm_a_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG0, PKC_SW_CONFIG0_MMAPTR) >> PKC_SW_CONFIG0_MMAPTR_Pos); +} + +/** + * @brief Set modular multiplication parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG0 | MMBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mm_b_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG0, PKC_SW_CONFIG0_MMBPTR, pointer << PKC_SW_CONFIG0_MMBPTR_Pos); +} + +/** + * @brief Get modular multiplication parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG0 | MMBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mm_b_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG0, PKC_SW_CONFIG0_MMBPTR) >> PKC_SW_CONFIG0_MMBPTR_Pos); +} + +/** + * @brief Set modular multiplication parameter P pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG1 | MMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mm_p_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG1, PKC_SW_CONFIG1_MMPPTR, pointer << PKC_SW_CONFIG1_MMPPTR_Pos); +} + +/** + * @brief Get modular multiplication parameter P pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG1 | MMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mm_p_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG1, PKC_SW_CONFIG1_MMPPTR) >> PKC_SW_CONFIG1_MMPPTR_Pos); +} + +/** + * @brief Set modular multiplication parameter C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG1 | MMCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mm_c_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG1, PKC_SW_CONFIG1_MMCPTR, pointer << PKC_SW_CONFIG1_MMCPTR_Pos); +} + +/** + * @brief Get modular multiplication parameter C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG1 | MMCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mm_c_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG1, PKC_SW_CONFIG1_MMCPTR) >> PKC_SW_CONFIG1_MMCPTR_Pos); +} + +/** + * @brief Set modular add/sub parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG2 | MASAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mas_a_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG2, PKC_SW_CONFIG2_MASAPTR, pointer << PKC_SW_CONFIG2_MASAPTR_Pos); +} + +/** + * @brief Get modular add/sub parameter A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG2 | MASAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mas_a_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG2, PKC_SW_CONFIG2_MASAPTR) >> PKC_SW_CONFIG2_MASAPTR_Pos); +} + +/** + * @brief Set modular add/sub parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG2 | MASBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mas_b_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG2, PKC_SW_CONFIG2_MASBPTR, pointer << PKC_SW_CONFIG2_MASBPTR_Pos); +} + +/** + * @brief Get modular add/sub parameter B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG2 | MASBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mas_b_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG2, PKC_SW_CONFIG2_MASBPTR) >> PKC_SW_CONFIG2_MASBPTR_Pos); +} + +/** + * @brief Set modular add/sub parameter P pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG3 | MASPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mas_p_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG3, PKC_SW_CONFIG3_MASPPTR, pointer << PKC_SW_CONFIG3_MASPPTR_Pos); +} + +/** + * @brief Get modular add/sub parameter P pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG3 | MASPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mas_p_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG3, PKC_SW_CONFIG3_MASPPTR) >> PKC_SW_CONFIG3_MASPPTR_Pos); +} + +/** + * @brief Set modular add/sub parameter C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG3 | MASCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mas_c_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG3, PKC_SW_CONFIG3_MASCPTR, pointer << PKC_SW_CONFIG3_MASCPTR_Pos); +} + +/** + * @brief Get modular add/sub parameter C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG3 | MASCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mas_c_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG3, PKC_SW_CONFIG3_MASCPTR) >> PKC_SW_CONFIG3_MASCPTR_Pos); +} + +/** + * @brief Set modular invertion parameter U pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG4 | MIUPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mi_u_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG4, PKC_SW_CONFIG4_MIUPTR, pointer << PKC_SW_CONFIG4_MIUPTR_Pos); +} + +/** + * @brief Get modular invertion parameter U pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG4 | MIUPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mi_u_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG4, PKC_SW_CONFIG4_MIUPTR) >> PKC_SW_CONFIG4_MIUPTR_Pos); +} + +/** + * @brief Set modular invertion parameter V pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG4 | MIVPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mi_v_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG4, PKC_SW_CONFIG4_MIVPTR, pointer << PKC_SW_CONFIG4_MIVPTR_Pos); +} + +/** + * @brief Get modular invertion parameter V pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG4 | MIVPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mi_v_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG4, PKC_SW_CONFIG4_MIVPTR) >> PKC_SW_CONFIG4_MIVPTR_Pos); +} + +/** + * @brief Set modular invertion parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG5 | MIX1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mi_x1_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG5, PKC_SW_CONFIG5_MIX1PTR, pointer << PKC_SW_CONFIG5_MIX1PTR_Pos); +} + +/** + * @brief Get modular invertion parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG5 | MIX1PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mi_x1_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG5, PKC_SW_CONFIG5_MIX1PTR) >> PKC_SW_CONFIG5_MIX1PTR_Pos); +} + +/** + * @brief Set modular invertion parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG5 | MIX2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_mi_x2_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG5, PKC_SW_CONFIG5_MIX2PTR, pointer << PKC_SW_CONFIG5_MIX2PTR_Pos); +} + +/** + * @brief Get modular invertion parameter X1 pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG5 | MIX2PTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_mi_x2_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG5, PKC_SW_CONFIG5_MIX2PTR) >> PKC_SW_CONFIG5_MIX2PTR_Pos); +} + +/** + * @brief Set modular invertion parameter Tmp pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG6 | MITMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter is the offset in pkc sram, and the value can between: 0 ~ 0x200 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_swmi_tmp_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG6, PKC_SW_CONFIG6_MITMPPTR, pointer << PKC_SW_CONFIG6_MITMPPTR_Pos); +} + +/** + * @brief Get modular invertion parameter Tmp pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG6 | MITMPPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x200 + */ +__STATIC_INLINE uint32_t ll_pkc_get_swmi_tmp_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG6, PKC_SW_CONFIG6_MITMPPTR) >> PKC_SW_CONFIG6_MITMPPTR_Pos); +} + +/** + * @brief Set operation word length-bits. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG7 | WORDLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param WordLength This parameter can be one of the following values: 256 ~ 2048 + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_operation_word_length(pkc_regs_t *PKCx, uint32_t WordLength) +{ + MODIFY_REG(PKCx->SW_CONFIG7, PKC_SW_CONFIG7_WORDLEN, (WordLength >> 5) - 1); +} + +/** + * @brief Get operation word length-bits. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG7 | WORDLEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 256 ~ 2048 + */ +__STATIC_INLINE uint32_t ll_pkc_get_operation_word_length(pkc_regs_t *PKCx) +{ + return ((READ_BITS(PKCx->SW_CONFIG7, PKC_SW_CONFIG7_WORDLEN) + 1) << 5); +} + +/** + * @brief Get K output in invertion operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG8 | MIKOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FFF + */ +__STATIC_INLINE uint32_t ll_pkc_get_mik_output(pkc_regs_t *PKCx) +{ + return (READ_REG(PKCx->SW_CONFIG8) & PKC_SW_CONFIG8_MIKOUT_Msk); +} + +/** + * @brief Set dummy multiply seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG9 | DMRNGSEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param seed This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_dummy_multiply_seed(pkc_regs_t *PKCx, uint32_t seed) +{ + WRITE_REG(PKCx->SW_CONFIG9, seed); +} + +/** + * @brief Get dummy multiply seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG9 | DMRNGSEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pkc_get_dummy_multiply_seed(pkc_regs_t *PKCx) +{ + return (READ_REG(PKCx->SW_CONFIG9)); +} + +/** + * @brief Set big integer operand A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG10 | BMAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_bm_a_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG10, PKC_SW_CONFIG10_BMAPTR, pointer << PKC_SW_CONFIG10_BMAPTR_Pos); +} + +/** + * @brief Get big integer operand A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG10 | BMAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_bm_a_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG10, PKC_SW_CONFIG10_BMAPTR) >> PKC_SW_CONFIG10_BMAPTR_Pos); +} + +/** + * @brief Set big integer operand B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG10 | BMBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_bm_b_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG10, PKC_SW_CONFIG10_BMBPTR, pointer << PKC_SW_CONFIG10_BMBPTR_Pos); +} + +/** + * @brief Get big integer operand B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG10 | BMBPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_bm_b_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG10, PKC_SW_CONFIG10_BMBPTR) >> PKC_SW_CONFIG10_BMBPTR_Pos); +} + +/** + * @brief Set big integer result C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG11 | BMCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_bm_c_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG11, PKC_SW_CONFIG11_BMCPTR, pointer << PKC_SW_CONFIG11_BMCPTR_Pos); +} + +/** + * @brief Get big integer result C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG11 | BMCPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_bm_c_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG11, PKC_SW_CONFIG11_BMCPTR) >> PKC_SW_CONFIG11_BMCPTR_Pos); +} + +/** + * @brief Set big integer operand A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG11 | BAAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_ba_a_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG11, PKC_SW_CONFIG11_BAAPTR, pointer << PKC_SW_CONFIG11_BAAPTR_Pos); +} + +/** + * @brief Get big integer operand A pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG11 | BAAPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_ba_a_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG11, PKC_SW_CONFIG11_BAAPTR) >> PKC_SW_CONFIG11_BAAPTR_Pos); +} + +/** + * @brief Set big integer operand B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG12 | BABPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_ba_b_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG12, PKC_SW_CONFIG12_BABPTR, pointer << PKC_SW_CONFIG12_BABPTR_Pos); +} + +/** + * @brief Get big integer operand B pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG12 | BABPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_ba_b_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG12, PKC_SW_CONFIG12_BABPTR) >> PKC_SW_CONFIG12_BABPTR_Pos); +} + +/** + * @brief Set big integer result C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG12 | BACPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param pointer This parameter can be one of the following values: 0 ~ 0x1FF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_ba_c_pointer(pkc_regs_t *PKCx, uint32_t pointer) +{ + MODIFY_REG(PKCx->SW_CONFIG12, PKC_SW_CONFIG12_BACPTR, pointer << PKC_SW_CONFIG12_BACPTR_Pos); +} + +/** + * @brief Get big integer result C pointer in pkc sram. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG12 | BACPTR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0x1FF + */ +__STATIC_INLINE uint32_t ll_pkc_get_ba_c_pointer(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->SW_CONFIG12, PKC_SW_CONFIG12_BACPTR) >> PKC_SW_CONFIG12_BACPTR_Pos); +} + +/** + * @brief Set random clock gating seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG13 | RANDSEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @param seed This parameter can be one of the following values: 0 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pkc_set_random_clock_gating_seed(pkc_regs_t *PKCx, uint32_t seed) +{ + WRITE_REG(PKCx->SW_CONFIG13, seed); +} + +/** + * @brief Get random clock gating seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SW_CONFIG13 | RANDSEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval Return value is between: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pkc_get_random_clock_gating_seed(pkc_regs_t *PKCx) +{ + return (READ_REG(PKCx->SW_CONFIG13)); +} + +/** @} */ + +/** @defgroup PKC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable the operation done interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_enable_it_done(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTEN, PKC_INTEN_DONE); +} + +/** + * @brief Enable the operation error interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_enable_it_err(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTEN, PKC_INTEN_ERR); +} + +/** + * @brief Enable the big integer overflow interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | BAOVF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_enable_it_big_add_overflow(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTEN, PKC_INTEN_BAOVF); +} + +/** + * @brief Disable the operation done interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_disable_it_done(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->INTEN, PKC_INTEN_DONE); +} + +/** + * @brief Disable the operation error interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_disable_it_err(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->INTEN, PKC_INTEN_ERR); +} + +/** + * @brief Disable the big integer overflow interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | BAOVF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_disable_it_big_add_overflow(pkc_regs_t *PKCx) +{ + CLEAR_BITS(PKCx->INTEN, PKC_INTEN_BAOVF); +} + +/** + * @brief Indicate whether the operation done interrupt is enable. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enable_it_done(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTEN, PKC_INTEN_DONE) == PKC_INTEN_DONE); +} + +/** + * @brief Indicate whether the operation error interrupt is enable. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enable_it_err(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTEN, PKC_INTEN_ERR) == PKC_INTEN_ERR); +} + +/** + * @brief Indicate whether the big integer overflow interrupt is enable. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | BAOVF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_enable_it_big_add_overflow(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTEN, PKC_INTEN_BAOVF) == PKC_INTEN_BAOVF); +} + +/** @} */ + +/** @defgroup PKC_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate whether the operation done interrupt is pending. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_action_flag_it_done(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTSTAT, PKC_INTSTAT_DONE) == PKC_INTSTAT_DONE); +} + +/** + * @brief Indicate whether the operation error interrupt is pending. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_action_flag_it_err(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTSTAT, PKC_INTSTAT_ERR) == PKC_INTSTAT_ERR); +} + +/** + * @brief Indicate whether the big integer overflow interrupt is pending. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | BAOVF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_action_flag_it_big_add_overflow(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->INTSTAT, PKC_INTSTAT_BAOVF) == PKC_INTSTAT_BAOVF); +} + +/** + * @brief Clear the operation done interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | DONE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_clear_flag_it_done(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTSTAT, PKC_INTSTAT_DONE); +} + +/** + * @brief Clear the operation error interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | ERR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_clear_flag_it_err(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTSTAT, PKC_INTSTAT_ERR); +} + +/** + * @brief Clear the big integer overflow interrupt flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | BAOVF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval none. + */ +__STATIC_INLINE void ll_pkc_clear_flag_it_big_add_overflow(pkc_regs_t *PKCx) +{ + SET_BITS(PKCx->INTSTAT, PKC_INTSTAT_BAOVF); +} + +/** + * @brief Indicate whether the busy flag is set. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | WORKSTAT | BUSY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PKCx PKC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pkc_is_action_flag_busy(pkc_regs_t *PKCx) +{ + return (READ_BITS(PKCx->WORKSTAT, PKC_WORKSTAT_BUSY) == PKC_WORKSTAT_BUSY); +} + +/** @} */ + +/** @defgroup PKC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize PKC registers (Registers restored to their default values). + * @param PKCx PKC Instance + * @retval An error_status_t enumeration value: + * - SUCCESS: PKC registers are de-initialized + * - ERROR: PKC registers are not de-initialized + */ +error_status_t ll_pkc_deinit(pkc_regs_t *PKCx); + +/** + * @brief Initialize PKC registers according to the specified + * parameters in p_pkc_init. + * @param PKCx PKC Instance + * @param p_pkc_init pointer to a ll_pkc_init_t structure that contains the configuration + * information for the specified PKC peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: PKC registers are initialized according to p_pkc_init content + * - ERROR: Problem occurred during PKC Registers initialization + */ +error_status_t ll_pkc_init(pkc_regs_t *PKCx, ll_pkc_init_t *p_pkc_init); + +/** + * @brief Set each field of a @ref ll_pkc_init_t type structure to default value. + * @param p_pkc_init pointer to a @ref ll_pkc_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_pkc_struct_init(ll_pkc_init_t *p_pkc_init); + +/** @} */ + +/** @} */ + +#endif /* PKC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_PKC_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwm.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwm.h new file mode 100644 index 0000000..b8a1bd1 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwm.h @@ -0,0 +1,1971 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_pwm.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWM LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_PWM PWM + * @brief PWM LL module driver. + * @{ + */ + +#ifndef __GR55XX_LL_PWM_H__ +#define __GR55XX_LL_PWM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gr55xx.h" + +#if defined (PWM0) || defined (PWM1) + +/** @defgroup PWM_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PWM_LL_ES_INIT PWM Exported init structures + * @{ + */ + +/** + * @brief LL PWM Output Channel init Structure definition. + */ +typedef struct _ll_pwm_channel_init_t +{ + uint8_t duty; /**< Specifies the duty in PWM output mode. + This parameter must be a number ranges between Min_Data=0 and Max_Data=100. + + This feature can be modified afterwards using unitary function ll_pwm_set_compare_xn() + where X can be (A, B, C) and n can be (0, 1).*/ + + uint8_t drive_polarity; /**< Specifies the drive polarity in PWM output mode. + This parameter can be a value of @ref PWM_LL_EC_DRIVEPOLARITY. + + This feature can be modified afterwards using unitary function ll_pwm_enable_positive_drive_channel_x() + and ll_pwm_disable_positive_drive_channel_x() where X can be (A, B, C).*/ + +} ll_pwm_channel_init_t; + +/** + * @brief LL PWM init Structure definition. + */ +typedef struct _ll_pwm_init_t +{ + uint32_t mode; /**< Specifies the PWM output mode. + This parameter can be a value of @ref PWM_LL_EC_MODE. + + This feature can be modified afterwards using unitary function @ref ll_pwm_set_mode().*/ + + uint32_t align; /**< Specifies the PWM alignment pulses. + This parameter can be a value of @ref PWM_LL_EC_ALIGN.*/ + + uint32_t prescaler; /**< Specifies the prescaler value which will be used configure PWM output frequency. + This parameter must be a number ranges between Min_Data = 0 and Max_Data = 0xFFFFFFFF. + This parameter should be larger than 128. + + This feature can be modified afterwards using unitary function @ref ll_pwm_set_prescaler().*/ + + uint32_t bprescaler; /**< Specifies the required prescaler that the duty changes from 0% to 100% in breath mode. + This parameter must be a number ranges between Min_Data=0 and Max_Data=0xFFFFFFFF. + This parameter is recommended to be larger than 128*prescaler to guarantee an ideal breath effect. + + This feature can be modified afterwards using unitary function @ref ll_pwm_set_breath_prescaler().*/ + + uint32_t hprescaler; /**< Specifies the required prescaler in breath hold state. + This parameter must be a number ranges between Min_Data=0 and Max_Data=0xFFFFFF. + + This feature can be modified afterwards using unitary function @ref ll_pwm_set_hold_prescaler().*/ + + ll_pwm_channel_init_t channel_a; /**< Specifies the configuration of channelA. + This parameter can be a value of @ref ll_pwm_channel_init_t.*/ + + ll_pwm_channel_init_t channel_b; /**< Specifies the configuration of channelB. + This parameter can be a value of @ref ll_pwm_channel_init_t.*/ + + ll_pwm_channel_init_t channel_c; /**< Specifies the configuration of channelC. + This parameter can be a value of @ref ll_pwm_channel_init_t.*/ + +} ll_pwm_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup PWM_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWM_LL_Exported_Constants PWM Exported Constants + * @{ + */ + +/** @defgroup PWM_LL_EC_MODE PWM mode + * @{ + */ +#define LL_PWM_FLICKER_MODE (0x00000000U) /**< PWM flicker mode */ +#define LL_PWM_BREATH_MODE PWM_MODE_BREATHEN /**< PWM breath mode */ +/** @} */ + +/** @defgroup PWM_LL_EC_ALIGN PWM alignment pulses + * @{ + */ +#define LL_PWM_EDGE_ALIGNED (0x00000000U) /**< PWM edge-aligned */ +#define LL_PWM_CENTER_ALIGNED (0x00000001U) /**< PWM center-aligned */ +/** @} */ + +/** @defgroup PWM_LL_EC_DRIVEPOLARITY PWM drive polarity + * @{ + */ +#define LL_PWM_DRIVEPOLARITY_NEGATIVE (0x00000000U) /**< PWM led-negative-drive mode */ +#define LL_PWM_DRIVEPOLARITY_POSITIVE (0x00000001U) /**< PWM led-positive-drive mode */ +/** @} */ + +/** @defgroup PWM_LL_EC_ACTIONEVENT PWM action event + * @{ + */ +#define LL_PWM_ACTIONEVENT_NONE (0x00000000U) /**< No action event */ +#define LL_PWM_ACTIONEVENT_CLEAR (0x00000001U) /**< Action event CLEAR */ +#define LL_PWM_ACTIONEVENT_SET (0x00000002U) /**< Action event SET */ +#define LL_PWM_ACTIONEVENT_TOGGLE (0x00000003U) /**< Action event TOGGLE */ +/** @} */ + +/** @defgroup PWM_LL_EC_PERIOD_UNIT PWM period unit default configuretion + * @{ + */ +#define LL_PWM_PRESCALER_UNIT (128) /**< The unit of prescaler is 128 */ +#define LL_PWM_BREATH_PRESCALER_UNIT (128) /**< The unit of breath prescaler is 128 */ +#define LL_PWM_HOLD_PRESCALER_UNIT (10) /**< The unit of hold prescaler is 10 */ +/** @} */ + +/** @defgroup PWM_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL PWM Channel InitStrcut default configuartion + */ +#define LL_PWM_CHANNEL_DEFAULT_CONFIG \ +{ \ + .duty = 50, \ + .drive_polarity = LL_PWM_DRIVEPOLARITY_POSITIVE, \ +} + +/** + * @brief LL PWM InitStrcut default configuartion + */ +#define LL_PWM_DEFAULT_CONFIG \ +{ \ + .mode = LL_PWM_FLICKER_MODE, \ + .align = LL_PWM_EDGE_ALIGNED, \ + .prescaler = 10 * LL_PWM_PRESCALER_UNIT, \ + .bprescaler = 10 * LL_PWM_BREATH_PRESCALER_UNIT * 10 * LL_PWM_PRESCALER_UNIT, \ + .hprescaler = 10 * LL_PWM_HOLD_PRESCALER_UNIT * 10 * LL_PWM_PRESCALER_UNIT, \ + .channel_a = LL_PWM_CHANNEL_DEFAULT_CONFIG, \ + .channel_b = LL_PWM_CHANNEL_DEFAULT_CONFIG, \ + .channel_c = LL_PWM_CHANNEL_DEFAULT_CONFIG, \ +} + +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWM_LL_Exported_Macros PWM Exported Macros + * @{ + */ + +/** @defgroup PWM_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in PWM register + * @param __instance__ PWM instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_PWM_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PWM register + * @param __instance__ PWM instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_PWM_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PWM_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup PWM_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable PWM. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->MODE, PWM_MODE_EN); +} + +/** + * @brief Disable PWM. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->MODE, PWM_MODE_EN); +} + +/** + * @brief Indicate whether the PWM is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_EN) == (PWM_MODE_EN)); +} + +/** + * @brief Enable PWM pause. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | PAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_pause(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->MODE, PWM_MODE_PAUSE); +} + +/** + * @brief Disable PWM pause. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | PAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_pause(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->MODE, PWM_MODE_PAUSE); +} + +/** + * @brief Indicate whether the PWM pause is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | PAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_pause(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_PAUSE) == (PWM_MODE_PAUSE)); +} + +/** + * @brief Set PWM mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | BREATHEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param mode This parameter can be one of the following values: + * @arg @ref LL_PWM_FLICKER_MODE + * @arg @ref LL_PWM_BREATH_MODE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_mode(pwm_regs_t *PWMx, uint32_t mode) +{ + MODIFY_REG(PWMx->MODE, PWM_MODE_BREATHEN, mode); +} + +/** + * @brief Get PWM mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | BREATHEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_FLICKER_MODE + * @arg @ref LL_PWM_BREATH_MODE + */ +__STATIC_INLINE uint32_t ll_pwm_get_mode(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_BREATHEN)); +} + +/** + * @brief Enable positive drive mode in channelA. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_positive_drive_channel_a(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->MODE, PWM_MODE_DPENA); +} + +/** + * @brief Disable positive drive mode in channelA. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_positive_drive_channel_a(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->MODE, PWM_MODE_DPENA); +} + +/** + * @brief Indicate whether the positive drive mode in channelA is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_positive_drive_channel_a(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_DPENA) == (PWM_MODE_DPENA)); +} + +/** + * @brief Enable positive drive mode in channelB. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_positive_drive_channel_b(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->MODE, PWM_MODE_DPENB); +} + +/** + * @brief Disable positive drive mode in channelB. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_positive_drive_channel_b(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->MODE, PWM_MODE_DPENB); +} + +/** + * @brief Indicate whether the positive drive mode in channelB is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_positive_drive_channel_b(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_DPENB) == (PWM_MODE_DPENB)); +} + +/** + * @brief Enable positive drive mode in channelC. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_positive_drive_channel_c(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->MODE, PWM_MODE_DPENC); +} + +/** + * @brief Disable positive drive mode in channelC. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_positive_drive_channel_c(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->MODE, PWM_MODE_DPENC); +} + +/** + * @brief Indicate whether the positive drive mode in channelC is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MODE | DPENC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_positive_drive_channel_c(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->MODE, PWM_MODE_DPENC) == (PWM_MODE_DPENC)); +} + +/** + * @brief Check update active flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SAG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_active_flag_update_all(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SAG) == (PWM_UPDATE_SAG)); +} + +/** + * @brief Enable update all parameters. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_all(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SA); +} + +/** + * @brief Disable update all parameters. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_all(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SA); +} + +/** + * @brief Indicate whether the update all parameters is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_all(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SA) == (PWM_UPDATE_SA)); +} + +/** + * @brief Enable update period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_period(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSPRD); +} + +/** + * @brief Disable update period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_period(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSPRD); +} + +/** + * @brief Indicate whether the update period is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_period(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSPRD) == (PWM_UPDATE_SSPRD)); +} + +/** + * @brief Enable update compareA0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_a0(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA0); +} + +/** + * @brief Disable update compareA0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_a0(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA0); +} + +/** + * @brief Indicate whether the update compareA0 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_a0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA0) == (PWM_UPDATE_SSCMPA0)); +} + +/** + * @brief Enable update compareA1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_a1(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA1); +} + +/** + * @brief Disable update compareA1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_a1(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA1); +} + +/** + * @brief Indicate whether the update compareA1 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPA1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_a1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPA1) == (PWM_UPDATE_SSCMPA1)); +} + +/** + * @brief Enable update compareB0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_b0(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB0); +} + +/** + * @brief Disable update compareB0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_b0(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB0); +} + +/** + * @brief Indicate whether the update compareB0 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_b0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB0) == (PWM_UPDATE_SSCMPB0)); +} + +/** + * @brief Enable update compareB1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_b1(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB1); +} + +/** + * @brief Disable update compareB1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_b1(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB1); +} + +/** + * @brief Indicate whether the update compareB1 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPB1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_b1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPB1) == (PWM_UPDATE_SSCMPB1)); +} + +/** + * @brief Enable update compareC0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_c0(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC0); +} + +/** + * @brief Disable update compareC0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_c0(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC0); +} + +/** + * @brief Indicate whether the update compareC0 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_c0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC0) == (PWM_UPDATE_SSCMPC0)); +} + +/** + * @brief Enable update compareC1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_compare_c1(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC1); +} + +/** + * @brief Disable update compareC1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_compare_c1(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC1); +} + +/** + * @brief Indicate whether the update compareC1 is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSCMPC1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_compare_c1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSCMPC1) == (PWM_UPDATE_SSCMPC1)); +} + +/** + * @brief Enable update pause. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_pause(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSPAUSE); +} + +/** + * @brief Disable update pause. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_pause(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSPAUSE); +} + +/** + * @brief Indicate whether the update pause is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSPAUSE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_pause(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSPAUSE) == (PWM_UPDATE_SSPAUSE)); +} + +/** + * @brief Enable update breath period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSBRPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_breath_period(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSBRPRD); +} + +/** + * @brief Disable update breath period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSBRPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_breath_period(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSBRPRD); +} + +/** + * @brief Indicate whether the update breath period is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSBRPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_breath_period(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSBRPRD) == (PWM_UPDATE_SSBRPRD)); +} + +/** + * @brief Enable update hold period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSHOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_hold_period(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSHOLD); +} + +/** + * @brief Disable update hold period. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSHOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_hold_period(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSHOLD); +} + +/** + * @brief Indicate whether the update hold period is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSHOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_hold_period(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSHOLD) == (PWM_UPDATE_SSHOLD)); +} + +/** + * @brief Enable update active event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSAQCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_enable_update_active_event(pwm_regs_t *PWMx) +{ + SET_BITS(PWMx->UPDATE, PWM_UPDATE_SSAQCTRL); +} + +/** + * @brief Disable update active event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSAQCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval None + */ +__STATIC_INLINE void ll_pwm_disable_update_active_event(pwm_regs_t *PWMx) +{ + CLEAR_BITS(PWMx->UPDATE, PWM_UPDATE_SSAQCTRL); +} + +/** + * @brief Indicate whether the update active event is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | UPDATE | SSAQCTRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwm_is_enabled_update_active_event(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->UPDATE, PWM_UPDATE_SSAQCTRL) == (PWM_UPDATE_SSAQCTRL)); +} + +/** + * @brief Set the PWM prescaler. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PRD | PRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param prescaler This parameter ranges between Min_Data=1 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_prescaler(pwm_regs_t *PWMx, uint32_t prescaler) +{ + WRITE_REG(PWMx->PRD, prescaler); +} + +/** + * @brief Get the PWM prescaler. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PRD | PRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=1 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_prescaler(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->PRD)); +} + +/** + * @brief Set the PWM compare counter A0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPA0 | CMPA0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_a0(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPA0, compare); +} + +/** + * @brief Get the PWM compare counter A0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPA0 | CMPA0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_a0(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPA0)); +} + +/** + * @brief Set the PWM compare counter A1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPA1 | CMPA1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_a1(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPA1, compare); +} + +/** + * @brief Get the PWM compare counter A1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPA1 | CMPA1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_a1(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPA1)); +} + +/** + * @brief Set the PWM compare counter B0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPB0 | CMPB0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_b0(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPB0, compare); +} + +/** + * @brief Get the PWM compare counter B0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPB0 | CMPB0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_b0(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPB0)); +} + +/** + * @brief Set the PWM compare counter B1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPB1 | CMPB1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_b1(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPB1, compare); +} + +/** + * @brief Get the PWM compare counter B1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPB1 | CMPB1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_b1(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPB1)); +} + +/** + * @brief Set the PWM compare counter C0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPC0 | CMPC0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_c0(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPC0, compare); +} + +/** + * @brief Get the PWM compare counter C0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPC0 | CMPC0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_c0(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPC0)); +} + +/** + * @brief Set the PWM compare counter C1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPC1 | CMPC1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param compare This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_compare_c1(pwm_regs_t *PWMx, uint32_t compare) +{ + WRITE_REG(PWMx->CMPC1, compare); +} + +/** + * @brief Get the PWM compare counter C1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CMPC1 | CMPC1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_compare_c1(pwm_regs_t *PWMx) +{ + return (READ_REG(PWMx->CMPC1)); +} + +/** + * @brief Set the channel A0 action event when PWM counter value reaches compare counter A0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | A0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_a0(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_A0, action_event << PWM_AQCTRL_A0_Pos); +} + +/** + * @brief Get the channel A0 action event when PWM counter value reaches compare counter A0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | A0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_a0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_A0) >> PWM_AQCTRL_A0_Pos); +} + +/** + * @brief Set the channel A1 action event when PWM counter value reaches compare counter A1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | A1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_a1(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_A1, action_event << PWM_AQCTRL_A1_Pos); +} + +/** + * @brief Get the channel A1 action event when PWM counter value reaches compare counter A1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | A1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_a1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_A1) >> PWM_AQCTRL_A1_Pos); +} + +/** + * @brief Set the channel B0 action event when PWM counter value reaches compare counter B0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | B0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_b0(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_B0, action_event << PWM_AQCTRL_B0_Pos); +} + +/** + * @brief Get the channel B0 action event when PWM counter value reaches compare counter B0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | B0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_b0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_B0) >> PWM_AQCTRL_B0_Pos); +} + +/** + * @brief Set the channel B1 action event when PWM counter value reaches compare counter B1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | B1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_b1(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_B1, action_event << PWM_AQCTRL_B1_Pos); +} + +/** + * @brief Get the channel B1 action event when PWM counter value reaches compare counter B1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | B1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_b1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_B1) >> PWM_AQCTRL_B1_Pos); +} + +/** + * @brief Set the channel C0 action event when PWM counter value reaches compare counter C0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | C0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_c0(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_C0, action_event << PWM_AQCTRL_C0_Pos); +} + +/** + * @brief Get the channel C0 action event when PWM counter value reaches compare counter C0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | C0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_c0(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_C0) >> PWM_AQCTRL_C0_Pos); +} + +/** + * @brief Set the channel C1 action event when PWM counter value reaches compare counter C1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | C1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param action_event This parameter can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_action_event_cmp_c1(pwm_regs_t *PWMx, uint32_t action_event) +{ + MODIFY_REG(PWMx->AQCTRL, PWM_AQCTRL_C1, action_event << PWM_AQCTRL_C1_Pos); +} + +/** + * @brief Get the channel C1 action event when PWM counter value reaches compare counter C1. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AQCTRL | C1 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value can be one of the following values: + * @arg @ref LL_PWM_ACTIONEVENT_NONE + * @arg @ref LL_PWM_ACTIONEVENT_CLEAR + * @arg @ref LL_PWM_ACTIONEVENT_SET + * @arg @ref LL_PWM_ACTIONEVENT_TOGGLE + */ +__STATIC_INLINE uint32_t ll_pwm_get_action_event_cmp_c1(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->AQCTRL, PWM_AQCTRL_C1) >> PWM_AQCTRL_C1_Pos); +} + +/** + * @brief Set the breath prescaler in breath mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BRPRD | BRPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param bprescaler This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_breath_prescaler(pwm_regs_t *PWMx, uint32_t bprescaler) +{ + MODIFY_REG(PWMx->BRPRD, PWM_BRPRD_BRPRD, bprescaler); +} + +/** + * @brief Get the breath prescaler in breath mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BRPRD | BRPRD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_breath_prescaler(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->BRPRD, PWM_BRPRD_BRPRD)); +} + +/** + * @brief Set the hold prescaler in breath mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | HOLD | HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @param hprescaler This parameter ranges between Min_Data=0 and Max_Data=0xFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_pwm_set_hold_prescaler(pwm_regs_t *PWMx, uint32_t hprescaler) +{ + MODIFY_REG(PWMx->HOLD, PWM_HOLD_HOLD, hprescaler); +} + +/** + * @brief Get the hold prescaler in breath mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | HOLD | HOLD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param PWMx PWM instance + * @retval Return value ranges between Min_Data=0 and Max_Data=0xFFFFFF + */ +__STATIC_INLINE uint32_t ll_pwm_get_hold_prescaler(pwm_regs_t *PWMx) +{ + return (READ_BITS(PWMx->HOLD, PWM_HOLD_HOLD)); +} + +/** @} */ + +/** @defgroup PWM_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize PWM registers (Registers restored to their default values). + * @param PWMx PWM instance + * @retval An error_status_t enumeration value: + * - SUCCESS: PWM registers are de-initialized + * - ERROR: PWM registers are not de-initialized + */ +error_status_t ll_pwm_deinit(pwm_regs_t *PWMx); + +/** + * @brief Initialize PWM registers according to the specified + * parameters in PWM_InitStruct. + * @param PWMx PWM instance + * @param p_pwm_init Pointer to a ll_pwm_init_t structure that contains the configuration + * information for the specified PWM peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: PWM registers are initialized according to p_pwm_init content + * - ERROR: Problem occurred during PWM Registers initialization + */ +error_status_t ll_pwm_init(pwm_regs_t *PWMx, ll_pwm_init_t *p_pwm_init); + +/** + * @brief Set each field of a @ref ll_pwm_init_t type structure to default value. + * @param p_pwm_init Pointer to a @ref ll_pwm_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_pwm_struct_init(ll_pwm_init_t *p_pwm_init); + +/** @} */ + +/** @} */ + +#endif /* PWM0 || PWM1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_PWM_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwr.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwr.h new file mode 100644 index 0000000..3831c10 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_pwr.h @@ -0,0 +1,1531 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_pwr.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of PWR LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_PWR PWR + * @brief PWR LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_PWR_H__ +#define __GR55xx_LL_PWR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined(AON) + +/** + * @defgroup PWR_LL_MACRO Defines + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PWR_LL_Private_Constants PWR Private Constants + * @{ + */ + +/** @defgroup PWR_LL_PC_EXT_WAKEUP_CTL_LSB External Wakeup Control Low Significant Bit Defines + * @{ + */ +#define LL_PWR_EXTWKUP_TYPE_LSB (0x01U << AON_EXT_WKUP_CTL_TYPE_Pos) /**< External wakeup level type */ +#define LL_PWR_EXTWKUP_INVERT_LSB (0x01U << AON_EXT_WKUP_CTL_INVERT_Pos) /**< External wakeup level invert */ +#define LL_PWR_EXTWKUP_SRC_EN_LSB (0x01U << AON_EXT_WKUP_CTL_SRC_EN_Pos) /**< External wakeup source enable */ +/** @} */ + +/** @} */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWR_LL_Private_Macro PWR Private Macros + * @{ + */ + +/** @defgroup PWR_LL_PM_EXT_WAKEUP_CTL_LSB External Wakeup Control Low Significant Bit Defines + * @{ + */ + +/** + * @brief PWR_LL_PM_GET_MEM_PWR_MSK PWR Get Memory Power Value Mask + */ +#define __LL_PWR_GET_MEM_PWR_MASK(__POWER__) (((__POWER__) == LL_PWR_MEM_POWER_OFF) ? 0x0U : \ + (((__POWER__) == LL_PWR_MEM_POWER_FULL) ? 0xAAAAAAAAU : 0xFFFFFFFFU)) + +/** @} */ + +/** @} */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWR_LL_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_LL_EC_WAKEUP_COND Wakeup Condition + * @{ + */ +#define LL_PWR_WKUP_COND_EXT AON_PWR_REG01_WAKE_UP_SEL_EXTWKUP /**< External wakeup: AON_GPIO */ +#define LL_PWR_WKUP_COND_TIMER AON_PWR_REG01_WAKE_UP_SEL_TIMER /**< AON Timer wakeup */ +#define LL_PWR_WKUP_COND_BLE AON_PWR_REG01_WAKE_UP_SEL_BLE /**< BLE wakeup */ +#define LL_PWR_WKUP_COND_CALENDAR AON_PWR_REG01_WAKE_UP_SEL_CALENDAR /**< Calendar wakeup */ +#define LL_PWR_WKUP_COND_BOD_FEDGE AON_PWR_REG01_WAKE_UP_SEL_PMU_BOD_FEDGE /**< PMU Bod falling edge wakeup */ +#define LL_PWR_WKUP_COND_MSIO_COMP AON_PWR_REG01_WAKE_UP_SEL_MSIO_COMP /**< Msio comparator wakeup */ +#define LL_PWR_WKUP_COND_ALL AON_PWR_REG01_WAKE_UP_SEL /**< All wakeup sources mask */ +/** @} */ + + +/** @defgroup PWR_LL_EC_WAKEUP_EVT Wakeup Event + * @note Only available on GR5515_C and later version + * @{ + */ +#define LL_PWR_WKUP_EVENT_BLE AON_SLP_EVENT_SMCOSCEN /**< BLE Timer wakeup event */ +#define LL_PWR_WKUP_EVENT_TIMER AON_SLP_EVENT_TIMER /**< AON Timer wakeup event */ +#define LL_PWR_WKUP_EVENT_EXT AON_SLP_EVENT_EXTWKUP /**< External wakeup event: AON_GPIO */ +#define LL_PWR_WKUP_EVENT_BOD_FEDGE AON_SLP_EVENT_PMU_BOD_FEDGE /**< PMU Bod wakeup event */ +#define LL_PWR_WKUP_EVENT_MSIO_COMP AON_SLP_EVENT_PMU_MSIO_COMP /**< Msio comparator wakeup event */ +#define LL_PWR_WKUP_EVENT_WDT AON_SLP_EVENT_WDT_REBOOT /**< AON WDT wakeup event */ +#define LL_PWR_WKUP_EVENT_CALENDAR AON_SLP_EVENT_CALENDAR_TIMER_ALARM /**< Calendar wakeup event */ +#define LL_PWR_WKUP_EVENT_ALL (AON_SLP_EVENT_SMCOSCEN | \ + AON_SLP_EVENT_TIMER | \ + AON_SLP_EVENT_EXTWKUP | \ + AON_SLP_EVENT_PMU_BOD_FEDGE | \ + AON_SLP_EVENT_PMU_MSIO_COMP | \ + AON_SLP_EVENT_WDT_REBOOT | \ + AON_SLP_EVENT_CALENDAR_TIMER_ALARM) /**< All event mask */ +/** @} */ + +/** @defgroup PWR_LL_EC_EXTWAKEUP_PIN External Wakeup Pins + * @{ + */ +#define LL_PWR_EXTWKUP_PIN0 (0x00000001U) /**< WKUP pin 0 : AON_GPIO_PIN0 */ +#define LL_PWR_EXTWKUP_PIN1 (0x00000002U) /**< WKUP pin 1 : AON_GPIO_PIN1 */ +#define LL_PWR_EXTWKUP_PIN2 (0x00000004U) /**< WKUP pin 2 : AON_GPIO_PIN2 */ +#define LL_PWR_EXTWKUP_PIN3 (0x00000008U) /**< WKUP pin 3 : AON_GPIO_PIN3 */ +#define LL_PWR_EXTWKUP_PIN4 (0x00000010U) /**< WKUP pin 4 : AON_GPIO_PIN4 */ +#define LL_PWR_EXTWKUP_PIN5 (0x00000020U) /**< WKUP pin 5 : AON_GPIO_PIN5 */ +#define LL_PWR_EXTWKUP_PIN6 (0x00000040U) /**< WKUP pin 6 : AON_GPIO_PIN6 */ +#define LL_PWR_EXTWKUP_PIN7 (0x00000080U) /**< WKUP pin 7 : AON_GPIO_PIN7 */ +#define LL_PWR_EXTWKUP_PIN_ALL (0x000000FFU) /**< WKUP pin all : AON_GPIO_PIN0 ~ AON_GPIO_PIN7 */ +/** @} */ + +/** @defgroup PWR_LL_EC_EXTWAKEUP_TYPE External Wakeup Type + * @{ + */ +#define LL_PWR_EXTWKUP_TYPE_LOW (LL_PWR_EXTWKUP_INVERT_LSB | LL_PWR_EXTWKUP_TYPE_LSB | LL_PWR_EXTWKUP_SRC_EN_LSB) /**< Low level wakeup */ +#define LL_PWR_EXTWKUP_TYPE_HIGH (LL_PWR_EXTWKUP_TYPE_LSB | LL_PWR_EXTWKUP_SRC_EN_LSB) /**< High level wakeup */ +#define LL_PWR_EXTWKUP_TYPE_RISING (0x00000000U) /**< Rising edge wakeup */ +#define LL_PWR_EXTWKUP_TYPE_FALLING (LL_PWR_EXTWKUP_INVERT_LSB | LL_PWR_EXTWKUP_SRC_EN_LSB) /**< Falling edge wakeup */ +/** @} */ + +/** @defgroup PWR_LL_EC_PSC_CMD Power State Control Commands + * @{ + */ +#define LL_PWR_CMD_LOOPBACK AON_PSC_CMD_OPC_OPCODE_LOOPBACK /**< Reserved command 0 */ +#define LL_PWR_CMD_EF_DIR_ON AON_PSC_CMD_OPC_OPCODE_EF_DIR_ON /**< Reserved command 1 */ +#define LL_PWR_CMD_32_TIMER_LD AON_PSC_CMD_OPC_OPCODE_32_TIMER_LD /**< Load sleep timer command */ +#define LL_PWR_CMD_DEEP_SLEEP AON_PSC_CMD_OPC_OPCODE_DEEP_SLEEP /**< Enter Deep Sleep Mode command */ +#define LL_PWR_CMD_EF_DIR_OFF AON_PSC_CMD_OPC_OPCODE_EF_DIR_OFF /**< Reserved command 2 */ +#define LL_PWR_CMD_EXT_CLK AON_PSC_CMD_OPC_OPCODE_EXT_CLK /**< Select external clock (xo_32KHz) command */ +#define LL_PWR_CMD_RNG_CLK AON_PSC_CMD_OPC_OPCODE_RNG_CLK /**< Select RING OSC clock command */ +#define LL_PWR_CMD_RTC_CLK AON_PSC_CMD_OPC_OPCODE_RTC_CLK /**< Select RTC clock command */ +#define LL_PWR_CMD_RNG2_CLK AON_PSC_CMD_OPC_OPCODE_RNG2_CLK /**< Select RING OSC clock command */ +#define LL_PWR_CMD_LD_MEM_SLP_CFG AON_PSC_CMD_OPC_OPCODE_LD_MEM_SLP_CFG /**< Load memory sleep settings command */ +#define LL_PWR_CMD_LD_MEM_WKUP_CFG AON_PSC_CMD_OPC_OPCODE_LD_MEM_WKUP_CFG /**< Load memory wakeup settings command */ +#define LL_PWR_CMD_DPAD_LE_HI AON_PSC_CMD_OPC_OPCODE_DPAD_LE_HI /**< Force dpad_le high */ +#define LL_PWR_CMD_DPAD_LE_LO AON_PSC_CMD_OPC_OPCODE_DPAD_LE_LO /**< Force dpad_le low */ +#define LL_PWR_CMD_SLP_TIMER_MODE_NORMAL AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_0 /**< Enable sleep timer mode 0 command */ +#define LL_PWR_CMD_SLP_TIMER_MODE_SINGLE AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_1 /**< Enable sleep timer mode 1 command */ +#define LL_PWR_CMD_SLP_TIMER_MODE_RELOAD AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_2 /**< Enable sleep timer mode 2 command */ +#define LL_PWR_CMD_SLP_TIMER_MODE_DISABLE AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_3 /**< Enable sleep timer mode 3 command */ +/** @} */ + + +/** @} */ + +/** @defgroup PWR_LL_EC_DPAD_VALUE Dpad LE State + * @{ + */ +#define LL_PWR_DPAD_LE_OFF (0x00000000U) /**< Dpad LE LOW */ +#define LL_PWR_DPAD_LE_ON (0x00000001U) /**< Dpad LE High */ +/** @} */ + +/** @defgroup PWR_LL_EC_TIMER_READ_SEL Timer Read Select + * @note Only available on GR5515_C and later version + * @{ + */ +#define LL_PWR_TIMER_READ_SEL_CAL_TIMER AON_PAD_CTL1_TIMER_READ_SEL_CAL_TIMER /**< Calendar timer */ +#define LL_PWR_TIMER_READ_SEL_AON_WDT AON_PAD_CTL1_TIMER_READ_SEL_AON_WDT /**< AON watchdog timer */ +#define LL_PWR_TIMER_READ_SEL_SLP_TIMER AON_PAD_CTL1_TIMER_READ_SEL_SLP_TIMER /**< Sleep timer */ +#define LL_PWR_TIMER_READ_SEL_CAL_ALARM AON_PAD_CTL1_TIMER_READ_SEL_CAL_ALARM /**< Calendar alarm */ +/** @} */ + +/** @} */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup PWR_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in PWR register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_PWR_WriteReg(__REG__, __VALUE__) WRITE_REG(AON->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PWR register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_PWR_ReadReg(__REG__) READ_REG(AON->__REG__) +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PWR_LL_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @defgroup PWR_LL_EF_Low_Power_Mode_Configuration Low power mode configuration + * @{ + */ + +/** + * @brief Set the DeepSleep WakeUp Condition + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WAKE_UP_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param condition This parameter can be one of the following values: + * @arg @ref LL_PWR_WKUP_COND_EXT + * @arg @ref LL_PWR_WKUP_COND_TIMER + * @arg @ref LL_PWR_WKUP_COND_BLE + * @arg @ref LL_PWR_WKUP_COND_CALENDAR + * @arg @ref LL_PWR_WKUP_COND_BOD_FEDGE + * @arg @ref LL_PWR_WKUP_COND_MSIO_COMP + * @arg @ref LL_PWR_WKUP_COND_ALL + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_wakeup_condition(uint32_t condition) +{ + MODIFY_REG(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL, condition); +} + +/** + * @brief Get the Selected DeepSleep WakeUp Condition + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | WAKE_UP_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_WKUP_COND_EXT + * @arg @ref LL_PWR_WKUP_COND_TIMER + * @arg @ref LL_PWR_WKUP_COND_BLE + * @arg @ref LL_PWR_WKUP_COND_CALENDAR + * @arg @ref LL_PWR_WKUP_COND_BOD_FEDGE + * @arg @ref LL_PWR_WKUP_COND_MSIO_COMP + * @arg @ref LL_PWR_WKUP_COND_ALL + */ +__STATIC_INLINE uint32_t ll_pwr_get_wakeup_condition(void) +{ + return ((uint32_t)READ_BITS(AON->PWR_RET01, AON_PWR_REG01_WAKE_UP_SEL)); +} + +/** + * @brief Get the Event that triggered the DeepSleep WakeUp. + * @note Only available on GR5515_C and later version + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | SMCOSCEN_EVENT | + * +----------------------+-----------------------------------+ + * \endrst + * SLP_EVENT | TIMER_EVENT + * SLP_EVENT | EXT_WKUP_EVENT + * SLP_EVENT | WATCHDOG_EVENT + * + * @retval Returned value can be combination of the following values: + * @arg @ref LL_PWR_WKUP_EVENT_BLE + * @arg @ref LL_PWR_WKUP_EVENT_TIMER + * @arg @ref LL_PWR_WKUP_EVENT_EXT + * @arg @ref LL_PWR_WKUP_EVENT_BOD_FEDGE + * @arg @ref LL_PWR_WKUP_EVENT_MSIO_COMP + * @arg @ref LL_PWR_WKUP_EVENT_WDT + * @arg @ref LL_PWR_WKUP_EVENT_CALENDAR + */ +__STATIC_INLINE uint32_t ll_pwr_get_wakeup_event(void) +{ + return ((uint32_t)READ_BITS(AON->SLP_EVENT, LL_PWR_WKUP_EVENT_ALL)); +} + +/** + * @brief Enable the External WakeUp PINx functionality + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | MASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param wakeup_pin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_ext_wakeup_pin(uint32_t wakeup_pin) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->EXT_WKUP_CTL, wakeup_pin); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable the External WakeUp PINx functionality + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | MASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param wakeup_pin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_ext_wakeup_pin(uint32_t wakeup_pin) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->EXT_WKUP_CTL, wakeup_pin); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the External WakeUp PINx functionality is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | MASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param wakeup_pin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_ext_wakeup_pin(uint32_t wakeup_pin) +{ + return (READ_BITS(AON->EXT_WKUP_CTL, wakeup_pin) == wakeup_pin); +} + +/** + * @brief Set the WakeUp Type of External WakeUp PINx. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | INVERT | + * +----------------------+-----------------------------------+ + * \endrst + * EXT_WKUP_CTL | TYPE + * + * @param wakeup_pin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @param wakeup_type This parameter can be one of the following values: + * @arg @ref LL_PWR_EXTWKUP_TYPE_LOW + * @arg @ref LL_PWR_EXTWKUP_TYPE_HIGH + * @arg @ref LL_PWR_EXTWKUP_TYPE_RISING + * @arg @ref LL_PWR_EXTWKUP_TYPE_FALLING + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_ext_wakeup_type(uint32_t wakeup_pin, uint32_t wakeup_type) +{ + uint32_t invert = ((wakeup_type & LL_PWR_EXTWKUP_INVERT_LSB) == LL_PWR_EXTWKUP_INVERT_LSB) ? (wakeup_pin << AON_EXT_WKUP_CTL_INVERT_Pos) : 0; + uint32_t type = ((wakeup_type & LL_PWR_EXTWKUP_TYPE_LSB) == LL_PWR_EXTWKUP_TYPE_LSB) ? (wakeup_pin << AON_EXT_WKUP_CTL_TYPE_Pos) : 0; + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->EXT_WKUP_CTL, (wakeup_pin << AON_EXT_WKUP_CTL_INVERT_Pos) | (wakeup_pin << AON_EXT_WKUP_CTL_TYPE_Pos), invert | type); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Get the WakeUp Type of External WakeUp PINx. + * @note Warning: only one pin can be passed as parameter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | EXT_WKUP_CTL | INVERT | + * +----------------------+-----------------------------------+ + * \endrst + * EXT_WKUP_CTL | TYPE + * + * @param wakeup_pin This parameter can be one of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_EXTWKUP_TYPE_LOW + * @arg @ref LL_PWR_EXTWKUP_TYPE_HIGH + * @arg @ref LL_PWR_EXTWKUP_TYPE_RISING + * @arg @ref LL_PWR_EXTWKUP_TYPE_FALLING + */ +__STATIC_INLINE uint32_t ll_pwr_get_ext_wakeup_type(uint32_t wakeup_pin) +{ + return ((uint32_t)(READ_BITS(AON->EXT_WKUP_CTL, AON_EXT_WKUP_CTL_INVERT | AON_EXT_WKUP_CTL_TYPE) >> POSITION_VAL(wakeup_pin))); +} + +/** + * @brief Set the 32 bits AON Sleep Timer Value to WakeUp the MCU from DeepSleep Mode. + * @note After the value was set, use @arg @ref LL_PWR_CMD_32_TIMER_LD command to + * load the configuration into Power State Controller. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMER_VALUE | PWR_CTL_TIMER_32B | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param value 32 bits count value loaded into the t32bit_timer + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_sleep_timer_value(uint32_t value) +{ + WRITE_REG(AON->TIMER_VALUE, value); +} + +/** + * @brief Get the 32 bit AON Sleep Timer Value to WakeUp the MCU from DeepSleep Mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TIMER_VALUE | PWR_CTL_TIMER_32B | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval 32 bit AON Timer Count Value + */ +__STATIC_INLINE uint32_t ll_pwr_get_sleep_timer_value(void) +{ + return READ_REG(AON->TIMER_VALUE); +} + +/** + * @brief Enable the SMC WakeUp Request. + * @note Once this is set up, MCU will wake up SMC, and this bit need to be cleared by MCU. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | SMC_WAKEUP_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_smc_wakeup_req(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_SMC_WAKEUP_REQ); +} + +/** + * @brief Disable the SMC WakeUp Request. + * @note This function is used to clear SMC WakeUp Request. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | SMC_WAKEUP_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_smc_wakeup_req(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_SMC_WAKEUP_REQ); +} + +/** + * @brief Check if the SMC WakeUp Request was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | SMC_WAKEUP_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_smc_wakeup_req(void) +{ + return (READ_BITS(AON->PWR_RET01, AON_PWR_REG01_SMC_WAKEUP_REQ) == AON_PWR_REG01_SMC_WAKEUP_REQ); +} + +/** + * @brief Set the DPAD LE value during sleep and after wake up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MEM_N_SLP_CTL | DPAD_LE_SLP_VAL | + * +----------------------+-----------------------------------+ + * | MEM_N_SLP_CTL | DPAD_LE_WKUP_VAL | + * +----------------------+-----------------------------------+ + * \endrst + * + * + * @param sleep This parameter can be one of the following values: + * @arg @ref LL_PWR_DPAD_LE_OFF + * @arg @ref LL_PWR_DPAD_LE_ON + * @param wakeup This parameter can be one of the following values: + * @arg @ref LL_PWR_DPAD_LE_OFF + * @arg @ref LL_PWR_DPAD_LE_ON + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_dpad_le_value(uint32_t sleep, uint32_t wakeup) +{ + MODIFY_REG(AON->MEM_N_SLP_CTL, AON_MEM_CTL_DPAD_LE_SLP_VAL, (sleep << AON_MEM_CTL_DPAD_LE_SLP_VAL_Pos)); + MODIFY_REG(AON->MEM_N_SLP_CTL, AON_MEM_CTL_DPAD_LE_WKUP_VAL, (wakeup << AON_MEM_CTL_DPAD_LE_WKUP_VAL_Pos)); +} + +/** + * @brief Request to excute the Power State Controller Command. + * @note The PSC command can only be excuted when Power State Controller is not in busy state. + * Use @ref ll_pwr_is_active_flag_psc_cmd_busy() to check the busy status, and make sure + * the last command has been finished. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PSC_CMD_OPC | OPCODE | + * +----------------------+-----------------------------------+ + * | PSC_CMD | MCU_PWR_REQ | + * +----------------------+-----------------------------------+ + * \endrst + + * + * @param command This parameter can be one of the following values: + * @arg @ref LL_PWR_CMD_LOOPBACK + * @arg @ref LL_PWR_CMD_EF_DIR_ON + * @arg @ref LL_PWR_CMD_32_TIMER_LD + * @arg @ref LL_PWR_CMD_DEEP_SLEEP + * @arg @ref LL_PWR_CMD_EF_DIR_OFF + * @arg @ref LL_PWR_CMD_EXT_CLK + * @arg @ref LL_PWR_CMD_RNG_CLK + * @arg @ref LL_PWR_CMD_RTC_CLK + * @arg @ref LL_PWR_CMD_LD_MEM_SLP_CFG + * @arg @ref LL_PWR_CMD_LD_MEM_WKUP_CFG + * @arg @ref LL_PWR_CMD_DPAD_LE_HI (*) + * @arg @ref LL_PWR_CMD_DPAD_LE_LO (*) + * @arg @ref LL_PWR_CMD_SLP_TIMER_MODE_NORMAL (*) + * @arg @ref LL_PWR_CMD_SLP_TIMER_MODE_SINGLE (*) + * @arg @ref LL_PWR_CMD_SLP_TIMER_MODE_RELOAD (*) + * @arg @ref LL_PWR_CMD_SLP_TIMER_MODE_DISABLE (*) + * + * (*) Not available in A0 and B0 + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_req_excute_psc_command(uint32_t command) +{ + WRITE_REG(AON->PSC_CMD_OPC, (uint8_t)command); + SET_BITS(AON->PSC_CMD, AON_PSC_CMD_MCU_PWR_REQ); +} + +/** @} */ + +/** @addtogroup PWR_LL_EF_Communication_Configuration BLE Communication timer and core configuration function + * @{ + */ + +/** + * @brief Enable the Communication Timer Reset. + * @note Comm timer can be reset when all ble connection were disconnected and + * MCU was ready to enter into deepsleep mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_TIMER_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_timer_reset(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_TIMER_RST_N); +} + +/** + * @brief Disable the Communication Timer Reset, and set Communication Timer to running state. + * @note After powered up, Comm Timer need to enter into running mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_TIMER_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_timer_reset(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_TIMER_RST_N); +} + +/** + * @brief Check if the Communication Timer Reset was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_TIMER_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_timer_reset(void) +{ + return ((uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_TIMER_RST_N) == 0x0U)); +} + +/** + * @brief Enable the Communication Core Reset. + * @note Comm Core can be reset when all ble connection were disconnected and + * MCU was ready to enter into deepsleep mode, and When COMM_CORE_RST_N + * is 0, the ble is held in reset. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_CORE_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_core_reset(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_CORE_RST_N); +} + +/** + * @brief Disable the Communication Core Reset, and set Communication Core to running state. + * @note After powered up, Comm Core need to enter into running mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_CORE_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_core_reset(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_CORE_RST_N); +} + +/** + * @brief Check if the Communication Core Reset was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | COMM_CORE_RST_N | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_core_reset(void) +{ + return ((uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_COMM_CORE_RST_N) == 0x0U)); +} + +/** + * @brief Enable the Communication Timer Power, the Communication Timer will be Powered Up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * \endrst + + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_timer_power(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_ISO_EN_PD_COMM_TIMER); + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_TIMER); + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_ISO_EN_PD_COMM_TIMER); +} + +/** + * @brief Disable the Communication Timer Power, the Communication Timer will be Powered Down. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * \endrst + + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_timer_power(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_TIMER); + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_ISO_EN_PD_COMM_TIMER); + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_TIMER); +} + +/** + * @brief Check if the Communication Timer Power was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_TIMER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_timer_power(void) +{ + return ((uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_TIMER) == AON_PWR_REG01_PWR_EN_PD_COMM_TIMER)); +} + +/** + * @brief Enable the Communication Core Power, the Communication Core will be Powered Up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_core_power(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_CORE); + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_ISO_EN_PD_COMM_CORE); +} + +/** + * @brief Disable the Communication Core Power, the Communication Core will be Powered Down. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_core_power(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_CORE); + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_ISO_EN_PD_COMM_CORE); + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_CORE); +} + +/** + * @brief Check if the Communication Core Power was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CALENDAR_TIMER_CTL | ISO_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * | CALENDAR_TIMER_CTL | PWR_EN_PD_COMM_CORE | + * +----------------------+-----------------------------------+ + * \endrst + * + * + * @retval None + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_core_power(void) +{ + return ((uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_PWR_EN_PD_COMM_CORE) == AON_PWR_REG01_PWR_EN_PD_COMM_CORE)); +} + +/** + * @brief Select which timer value to read + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PAD_CTL1 | TIMER_READ_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param select This parameter can be one of the following values: + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_AON_WDT + * @arg @ref LL_PWR_TIMER_READ_SEL_SLP_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_ALARM + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_timer_read_select(uint32_t select) +{ + GLOBAL_EXCEPTION_DISABLE(); + MODIFY_REG(AON->AON_PAD_CTL1, AON_PAD_CTL1_TIMER_READ_SEL, select); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Get which timer value was selected to read. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PAD_CTL1 | TIMER_READ_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_AON_WDT + * @arg @ref LL_PWR_TIMER_READ_SEL_SLP_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_ALARM + */ +__STATIC_INLINE uint32_t ll_pwr_get_timer_read_select(void) +{ + return ((uint32_t)READ_BITS(AON->AON_PAD_CTL1, AON_PAD_CTL1_TIMER_READ_SEL)); +} + +/** + * @brief Get current timer value based on the selection. + * @note Please read multiple times until get a stable value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PAD_CTL1 | TIMER_READ_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_AON_WDT + * @arg @ref LL_PWR_TIMER_READ_SEL_SLP_TIMER + * @arg @ref LL_PWR_TIMER_READ_SEL_CAL_ALARM + */ +__STATIC_INLINE uint32_t ll_pwr_get_timer_read_value(void) +{ + return ((uint32_t)READ_REG(AON->TIMER_VAL)); +} + +/** + * @brief Enable high frequency crystal oscillator sleep mode, and diable OSC. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_OSC_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_osc_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + + +/** + * @brief Disable high frequency crystal oscillator sleep mode. + * @note Switch OSC from sleep mode into normal active mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_OSC_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_osc_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the OSC sleep mode was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_OSC_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_osc_sleep(void) +{ + return ((uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN) == AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN)); +} + +/** + * @brief Enable Radio sleep mode, and disable Radio module. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_RADIO_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_radio_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable Radio sleep mode. + * @note Switch Radio from sleep mode into normal active mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_RADIO_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_radio_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the Radio sleep mode was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_RADIO_SLEEP_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_radio_sleep(void) +{ + return ((uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN) == AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN)); +} + +/** + * @brief Enable Communication Core Deep Sleep Mode. + * @note This bit is reset on DEEP_SLEEP_STAT falling edge. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_DEEP_SLEEP_ON | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_core_deep_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable Communication Core Deep Sleep Mode. + * @note Switch Communication Core from sleep mode into normal active mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_DEEP_SLEEP_ON | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_core_deep_sleep(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the Communication Core Deep Sleep Mode was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_DEEP_SLEEP_ON | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_core_deep_sleep(void) +{ + return ((uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON) == AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON)); +} + +/** + * @brief Enable Wake Up Request from Software. + * @note Applies when system is in Deep Sleep Mode. It wakes up the Communication Core + * when written with a 1. No action happens if it is written with 0. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_soft_wakeup_req(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the Wake Up Request was enabled or disabled. + * @note Resets at 0 means request action is performed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_soft_wakeup_req(void) +{ + return ((uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ) == AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ)); +} + +/** + * @brief Enable Communication Core external wakeup. + * @note After this configuration, Communication Core can be woken up by external wake-up + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_EXTWKUPDSB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_enable_comm_core_ext_wakeup(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + CLEAR_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_EXTWKUPDSB); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Disable Communication Core external wakeup. + * @note After this configuration, Communication Core cannot be woken up by external wake-up + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_EXTWKUPDSB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_comm_core_ext_wakeup(void) +{ + GLOBAL_EXCEPTION_DISABLE(); + SET_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_EXTWKUPDSB); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Check if the Communication Core external wakeup was enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_EXTWKUPDSB | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_enabled_comm_core_ext_wakeup(void) +{ + return ((uint32_t)(READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_EXTWKUPDSB) == 0x0U)); +} + +/** + * @brief Set the time in low_power_clk clock cycles to spend in Deep Sleep Mode before waking-up the device. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMM_TMR_DEEPSLWKUP | AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME| + * +----------------------+-----------------------------------+ + * \endrst + * + * @param time 32 bit clock cycles loaded into the AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_comm_core_wakeup_time(uint32_t time) +{ + WRITE_REG(AON->PWR_RET28, time); +} + +/** + * @brief Get the time in low_power_clk clock cycles to spend in Deep Sleep Mode before waking-up the device. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMM_TMR_DEEPSLWKUP | AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME| + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Clock cycles to spend in Deep Sleep Mode before waking-up the device + */ +__STATIC_INLINE uint32_t ll_pwr_get_comm_wakeup_time(void) +{ + return ((uint32_t)READ_REG(AON->PWR_RET28)); +} + + +/** + * @brief Get the actual duration of the last deep sleep phase measured in low_power_clk clock cycle. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMM_TMR_DEEPSLPSTAT | DEEPSLDUR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Sleep duration + */ +__STATIC_INLINE uint32_t ll_pwr_get_comm_sleep_duration(void) +{ + return ((uint32_t)READ_REG(MCU_SUB->COMM_TMR_DEEPSLPSTAT)); +} + +/** + * @brief Set the wakeup timing in low_power_clk clock cycles to spend when waking-up the device. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMM_TMR_ENBPRESET | TWEXT | + * +----------------------+-----------------------------------+ + * | COMM_TMR_ENBPRESET | TWOSC | + * +----------------------+-----------------------------------+ + * | COMM_TMR_ENBPRESET | TWRM | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param twext Time in low power oscillator cycles allowed for stabilization of the high frequency + * oscillator following an external wake–up request (signal wakeup_req). + * @param twosc Time in low power oscillator cycles allowed for stabilization of the high frequency + * oscillator when the deep–sleep mode has been left due to sleep–timer expiry. + * @param twrm Time in low power oscillator cycles allowed for the radio module to leave low–power mode. + * @retval None + */ +__STATIC_INLINE void ll_pwr_set_comm_wakeup_timing(uint32_t twext, uint32_t twosc, uint32_t twrm) +{ + WRITE_REG(AON->PWR_RET29, (twext << AON_COMM_TMR_ENBPRESET_TWEXT_Pos) | + (twosc << AON_COMM_TMR_ENBPRESET_TWOSC_Pos) | + (twrm << AON_COMM_TMR_ENBPRESET_TWRM_Pos)); +} + + +/** + * @brief Read the wakeup timing in low_power_clk clock cycles to spend when waking-up the device. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMM_TMR_ENBPRESET | TWEXT | + * +----------------------+-----------------------------------+ + * | COMM_TMR_ENBPRESET | TWOSC | + * +----------------------+-----------------------------------+ + * | COMM_TMR_ENBPRESET | TWRM | + * +----------------------+-----------------------------------+ + * \endrst + * + * + * @retval COMM_TMR_ENBPRESET Register value + */ +__STATIC_INLINE uint32_t ll_pwr_read_comm_wakeup_timing(void) +{ + return ((uint32_t)READ_REG(AON->PWR_RET29)); +} + +/** + * @brief Read the Twosc of the wakeup timing in low_power_clk clock cycles to spend when waking-up the device. + * + * @retval TWOSC value + */ +__STATIC_INLINE uint32_t ll_pwr_read_comm_wakeup_timing_twosc(void) +{ + return ((((uint32_t)READ_REG(AON->PWR_RET29) & AON_COMM_TMR_ENBPRESET_TWOSC_Msk)) >> AON_COMM_TMR_ENBPRESET_TWOSC_Pos); +} + + +/** @} */ + +/** @defgroup PWR_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Get the External Wake Up Status. + * @note 0 means not waked up and 1 means waked up. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | EXT_WKUP_STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + */ +__STATIC_INLINE uint32_t ll_pwr_get_ext_wakeup_status(void) +{ + return ((uint32_t)(READ_BITS(AON->SLP_EVENT, AON_SLP_EVENT_EXT_WKUP_STATUS) >> AON_SLP_EVENT_EXT_WKUP_STATUS_Pos) & \ + (uint32_t)(READ_BITS(AON->EXT_WKUP_CTL, LL_PWR_EXTWKUP_PIN_ALL))); +} + +/** + * @brief Clear the External Wake Up Status. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | EXT_WKUP_STATUS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param wakeup_pin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_EXTWKUP_PIN0 + * @arg @ref LL_PWR_EXTWKUP_PIN1 + * @arg @ref LL_PWR_EXTWKUP_PIN2 + * @arg @ref LL_PWR_EXTWKUP_PIN3 + * @arg @ref LL_PWR_EXTWKUP_PIN4 + * @arg @ref LL_PWR_EXTWKUP_PIN5 + * @arg @ref LL_PWR_EXTWKUP_PIN_ALL + * @retval None + */ +__STATIC_INLINE void ll_pwr_clear_ext_wakeup_status(uint32_t wakeup_pin) +{ + GLOBAL_EXCEPTION_DISABLE(); + WRITE_REG(AON->SLP_EVENT, ~(wakeup_pin << AON_SLP_EVENT_EXT_WKUP_STATUS_Pos)); + GLOBAL_EXCEPTION_ENABLE(); +} + +/** + * @brief Clear the Event that triggered the DeepSleep WakeUp. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLP_EVENT | SMCOSCEN_EVENT | + * +----------------------+-----------------------------------+ + * \endrst + * SLP_EVENT | TIMER_EVENT + * SLP_EVENT | EXT_WKUP_EVENT + * SLP_EVENT | WATCHDOG_EVENT + * + * @param event This parameter can be a combination of the following values: + * @arg @ref LL_PWR_WKUP_EVENT_BLE + * @arg @ref LL_PWR_WKUP_EVENT_TIMER + * @arg @ref LL_PWR_WKUP_EVENT_EXT + * @arg @ref LL_PWR_WKUP_EVENT_BOD_FEDGE + * @arg @ref LL_PWR_WKUP_EVENT_MSIO_COMP + * @arg @ref LL_PWR_WKUP_EVENT_WDT + * @arg @ref LL_PWR_WKUP_EVENT_CALENDAR + * @retval None + */ +__STATIC_INLINE void ll_pwr_clear_wakeup_event(uint32_t event) +{ + WRITE_REG(AON->SLP_EVENT, ~(event & LL_PWR_WKUP_EVENT_ALL)); +} + +/** + * @brief Indicate if the Power State Controller is in busy state. + * @note This is bit set 1 when the PSC_CMD_REQ[0] is set to 1, and will remain 1 until + * the PSC_CMD_OPC has been transferred to the PSC. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PSC_CMD | MCU_PWR_BUSY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_active_flag_psc_cmd_busy(void) +{ + return (READ_BITS(AON->PSC_CMD, AON_PSC_CMD_MCU_PWR_BUSY) == AON_PSC_CMD_MCU_PWR_BUSY); +} + +/** + * @brief Indicate if the Communication Core is in Deep Sleep Mode. + * @note When Communication Core is in Deep Sleep Mode, only low_power_clk is running. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSIO_PAD_CFG_1 | COMM_DEEPSLCNTL_DEEP_SLEEP_STAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_pwr_is_active_flag_comm_deep_sleep_stat(void) +{ + return (READ_BITS(AON->MSIO_PAD_CFG_1, AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT) == AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT); +} + +/** + * @brief Disable cache function + * @note The cache should be closed before chip go to deepsleep. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_pwr_disable_cache_module(void) +{ + SET_BITS(XQSPI->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); +} + +/** @} */ + +/** @} */ +/** @} */ + +#endif /* defined(AON) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_PWR_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_rng.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_rng.h new file mode 100644 index 0000000..5f4264b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_rng.h @@ -0,0 +1,759 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_rng.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of RNG LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + + /** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_RNG RNG + * @brief RNG LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_RNG_H__ +#define __GR55XX_LL_RNG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (RNG) + +/** @defgroup RNG_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RNG_LL_ES_INIT RNG Exported Init structures + * @{ + */ + +/** + * @brief LL RNG Init Structure definition + */ +typedef struct _ll_rng_init +{ + uint32_t seed; /**< Specifies the seed source for the LFSR. + This parameter can be a value of @ref RNG_LL_EC_SEED_SOURCE */ + + uint32_t lfsr_mode; /**< Specifies the configuration mode for the LFSR. + This parameter can be a value of @ref RNG_LL_EC_LFSR_MODE */ + + uint32_t out_mode; /**< Specifies the Output mode for the RNG. + This parameter can be a value of @ref RNG_LL_EC_OUTPUT_MODE */ + + uint32_t post_mode; /**< Specifies post-process configuration for the RNG. + This parameter can be a value of @ref RNG_LL_EC_POST_PRO */ + + uint32_t interrupt; /**< Specifies interrupt configuration for the RNG. + This parameter can be a value of @ref RNG_LL_EC_IT */ + +} ll_rng_init_t; + +/** @} */ + +/** @} */ + +/** @defgroup RNG_LL_MACRO Defines + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Constants RNG Exported Constants + * @{ + */ + +/** @defgroup RNG_LL_EC_SEED_SOURCE LFSR seed source + * @{ + */ +#define LL_RNG_SEED_FR0_S0 (4UL << RNG_CONFIG_LFSR_SEED_SEL_Pos) /**< LFSR seed is from the switching oscillator s0. */ +#define LL_RNG_SEED_USER (6UL << RNG_CONFIG_LFSR_SEED_SEL_Pos) /**< LFSR seed is configured by users. */ +/** @} */ + + +/** @defgroup RNG_LL_EC_LFSR_MODE LFSR configuration mode + * @{ + */ +#define LL_RNG_LFSR_MODE_59BIT (0x00000000UL) /**< 59 bit LFSR. */ +#define LL_RNG_LFSR_MODE_128BIT (1UL << RNG_CONFIG_LFSR_MODE_Pos) /**< 128 bit LFSR. */ +/** @} */ + +/** @defgroup RNG_LL_EC_POST_PRO Post-process mode + * @{ + */ +#define LL_RNG_POST_PRO_NOT (0x00000000UL) /**< No post process. */ +#define LL_RNG_POST_PRO_SKIPPING (1UL << RNG_CONFIG_POST_MODE_Pos) /**< bit skipping. */ +#define LL_RNG_POST_PRO_COUNTING (2UL << RNG_CONFIG_POST_MODE_Pos) /**< bit counting. */ +#define LL_RNG_POST_PRO_NEUMANN (3UL << RNG_CONFIG_POST_MODE_Pos) /**< Von-Neumann. */ +/** @} */ + +/** @defgroup RNG_LL_EC_IT RNG hardware interrupt enable. + * @{ + */ +#define LL_RNG_IT_DISABLE (0x00000000UL) /**< Disable RNG interrupt. */ +#define LL_RNG_IT_ENABLE (1UL << RNG_CONFIG_IRQ_EN_Pos) /**< Enable RNG interrupt. */ +/** @} */ + +/** @defgroup RNG_LL_EC_OUTPUT_MODE RNG Output mode + * @{ + */ +#define LL_RNG_OUTPUT_FR0_S0 (4UL << RNG_CONFIG_OUT_MODE_Pos) /**< Digital RNG direct output, ring oscillator s0. */ +#define LL_RNG_OUTPUT_CYCLIC_PARITY (6UL << RNG_CONFIG_OUT_MODE_Pos) /**< LFSR and RNG cyclic sampling and parity generation. */ +#define LL_RNG_OUTPUT_CYCLIC (7UL << RNG_CONFIG_OUT_MODE_Pos) /**< LFSR and RNG cyclic sampling. */ +#define LL_RNG_OUTPUT_LFSR_RNG (8UL << RNG_CONFIG_OUT_MODE_Pos) /**< LFSR ⊕ RNG. */ +#define LL_RNG_OUTPUT_LFSR (9UL << RNG_CONFIG_OUT_MODE_Pos) /**< LFSR direct output. */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Macros RNG Exported Macros + * @{ + */ + +/** @defgroup RNG_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in RNG register + * @param __instance__ RNG instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None. + */ +#define LL_RNG_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in RNG register + * @param __instance__ RNG instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_RNG_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) +/** @} */ + +/** @} */ +/** @} */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Functions Functions + * @{ + */ + +/** @defgroup RNG_LL_EF_Configuration RNG Configuration functions + * @{ + */ + +/** + * @brief Enable Random Number Generation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RNG_RUN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_enable(rng_regs_t *RNGx) +{ + SET_BITS(RNGx->CTRL, RNG_CTRL_RUN_EN); +} + +/** + * @brief Disable Random Number Generation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RNG_RUN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_disable(rng_regs_t *RNGx) +{ + CLEAR_BITS(RNGx->CTRL, RNG_CTRL_RUN_EN); +} + +/** + * @brief Check if Random Number Generator is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RNG_RUN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_rng_is_enabled(rng_regs_t *RNGx) +{ + return (READ_BITS(RNGx->CTRL, RNG_CTRL_RUN_EN) == (RNG_CTRL_RUN_EN)); +} + +/** + * @brief Enable Ring oscillator TRNG enabled signal. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_FRO_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_enable_fro(rng_regs_t *RNGx) +{ + SET_BITS(RNGx->CONFIG, RNG_CONFIG_FRO_EN); +} + +/** + * @brief Disable Ring oscillator TRNG enabled signal. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RNG_RUN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_disable_fro(rng_regs_t *RNGx) +{ + CLEAR_BITS(RNGx->CONFIG, RNG_CONFIG_FRO_EN); +} + +/** + * @brief Check if Ring oscillator TRNG enabled signal is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RNG_RUN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_rng_fro_is_enabled(rng_regs_t *RNGx) +{ + return (READ_BITS(RNGx->CONFIG, RNG_CONFIG_FRO_EN) == (RNG_CONFIG_FRO_EN)); +} + +/** + * @brief Set source of LFSR seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_LFSR_SEED_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param seed This parameter can be one of the following values: + * @arg @ref LL_RNG_SEED_FR0_S0 + * @arg @ref LL_RNG_SEED_USER + * @retval None + */ +__STATIC_INLINE void ll_rng_set_lfsr_seed(rng_regs_t *RNGx, uint32_t seed) +{ + MODIFY_REG(RNGx->CONFIG, RNG_CONFIG_LFSR_SEED_SEL, seed); +} + +/** + * @brief Get source of LFSR seed. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_LFSR_SEED_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RNG_SEED_FR0_S0 + * @arg @ref LL_RNG_SEED_USER + */ +__STATIC_INLINE uint32_t ll_rng_get_lfsr_seed(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->CONFIG, RNG_CONFIG_LFSR_SEED_SEL); +} + +/** + * @brief Set LFSR configuration mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_LFSR_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param mode This parameter can be one of the following values: + * @arg @ref LL_RNG_LFSR_MODE_59BIT + * @arg @ref LL_RNG_LFSR_MODE_128BIT + * @retval None + */ +__STATIC_INLINE void ll_rng_set_lfsr_mode(rng_regs_t *RNGx, uint32_t mode) +{ + MODIFY_REG(RNGx->CONFIG, RNG_CONFIG_LFSR_MODE, mode); +} + +/** + * @brief Get LFSR configuration mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_LFSR_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RNG_LFSR_MODE_59BIT + * @arg @ref LL_RNG_LFSR_MODE_128BIT + */ +__STATIC_INLINE uint32_t ll_rng_get_lfsr_mode(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->CONFIG, RNG_CONFIG_LFSR_MODE); +} + +/** + * @brief Set RNG post-process configuration. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_POST_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param post This parameter can be one of the following values: + * @arg @ref LL_RNG_POST_PRO_NOT + * @arg @ref LL_RNG_POST_PRO_SKIPPING + * @arg @ref LL_RNG_POST_PRO_COUNTING + * @arg @ref LL_RNG_POST_PRO_NEUMANN + * @retval None + */ +__STATIC_INLINE void ll_rng_set_post_mode(rng_regs_t *RNGx, uint32_t post) +{ + MODIFY_REG(RNGx->CONFIG, RNG_CONFIG_POST_MODE, post); +} + +/** + * @brief Get RNG post-process configuration. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_POST_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RNG_POST_PRO_NOT + * @arg @ref LL_RNG_POST_PRO_SKIPPING + * @arg @ref LL_RNG_POST_PRO_COUNTING + * @arg @ref LL_RNG_POST_PRO_NEUMANN + */ +__STATIC_INLINE uint32_t ll_rng_get_post_mode(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->CONFIG, RNG_CONFIG_POST_MODE); +} + +/** + * @brief set RNG output mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_OUT_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param mode This parameter can be one of the following values: + * @arg @ref LL_RNG_OUTPUT_FR0_S0 + * @arg @ref LL_RNG_OUTPUT_CYCLIC_PARITY + * @arg @ref LL_RNG_OUTPUT_CYCLIC + * @arg @ref LL_RNG_OUTPUT_LFSR_RNG + * @arg @ref LL_RNG_OUTPUT_LFSR + * @retval None + */ +__STATIC_INLINE void ll_rng_set_output_mode(rng_regs_t *RNGx, uint32_t mode) +{ + MODIFY_REG(RNGx->CONFIG, RNG_CONFIG_OUT_MODE, mode); +} + +/** + * @brief get RNG output mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_OUT_MODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RNG_OUTPUT_FR0_S0 + * @arg @ref LL_RNG_OUTPUT_CYCLIC_PARITY + * @arg @ref LL_RNG_OUTPUT_CYCLIC + * @arg @ref LL_RNG_OUTPUT_LFSR_RNG + * @arg @ref LL_RNG_OUTPUT_LFSR + */ +__STATIC_INLINE uint32_t ll_rng_get_output_mode(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->CONFIG, RNG_CONFIG_OUT_MODE); +} + +/** + * @brief set the waiting time that RNG input reaches stable. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TSCON | RNG_TRDY_TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param time range between 0x1 and 0xFF. + * @retval None + */ +__STATIC_INLINE void ll_rng_set_trdy_time(rng_regs_t *RNGx, uint32_t time) +{ + MODIFY_REG(RNGx->TSCON, RNG_TSCON_TRDY_TIME, time); +} + +/** + * @brief get the waiting time that RNG input reaches stable. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TSCON | RNG_TRDY_TIME | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Between Min_Time = 0 and Max_Time = 0xFF + */ +__STATIC_INLINE uint32_t ll_rng_get_trdy_time(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->TSCON, RNG_TSCON_TRDY_TIME); +} + + +/** + * @brief set RNG seed configured by user. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USER | RNG_USER_SEED | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @param seed range between 0x1 and 0xFFFF. + * @retval None + */ +__STATIC_INLINE void ll_rng_set_user_seed(rng_regs_t *RNGx, uint32_t seed) +{ + WRITE_REG(RNGx->USER_SEED, seed); +} + +/** @} */ + +/** @defgroup RNG_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Indicate if the Flag of RNG long run test is set or not. + * + * Register |BitsName + * ---------|-------- + * LR_STATUS| RNG_LR_FLAG + * + * @param RNGx RNG instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_rng_is_active_flag_lr(rng_regs_t *RNGx) +{ + return (READ_BITS(RNGx->LR_STATUS, RNG_LR_STATUS_FLAG) == (RNG_LR_STATUS_FLAG)); +} + +/** + * @brief Indicate if the RNG Status Flag is set or not. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | RNG_READY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_rng_is_active_flag_sts(rng_regs_t *RNGx) +{ + return (READ_BITS(RNGx->STATUS, RNG_STATUS_READY) == (RNG_STATUS_READY)); +} + +/** + * @brief Clear RNG Status flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STATUS | RNG_READY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_clear_flag_sts(rng_regs_t *RNGx) +{ + WRITE_REG(RNGx->STATUS, RNG_STATUS_READY); +} + +/** @} */ + +/** @defgroup RNG_LL_EF_IT_Management IT Management + * @{ + */ + +/** + * @brief Enable Random Number Generator Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_IRQ_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_enable_it(rng_regs_t *RNGx) +{ + SET_BITS(RNGx->CONFIG, RNG_CONFIG_IRQ_EN); +} + +/** + * @brief Disable Random Number Generator Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_IRQ_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval None + */ +__STATIC_INLINE void ll_rng_disable_it(rng_regs_t *RNGx) +{ + CLEAR_BITS(RNGx->CONFIG, RNG_CONFIG_IRQ_EN); +} + +/** + * @brief Check if Random Number Generator Interrupt is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CONFIG | RNG_IRQ_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_rng_is_enabled_it(rng_regs_t *RNGx) +{ + return (READ_BITS(RNGx->CONFIG, RNG_CONFIG_IRQ_EN) == (RNG_CONFIG_IRQ_EN)); +} + +/** @} */ + +/** @defgroup RNG_LL_EF_Data_Management Data Management + * @{ + */ + +/** + * @brief Return32-bit Random Number value + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | RNG_DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param RNGx RNG instance. + * @retval Generated 32-bit random value + */ +__STATIC_INLINE uint32_t ll_rng_read_random_data32(rng_regs_t *RNGx) +{ + return (uint32_t)(READ_REG(RNGx->DATA)); +} + +/** + * @brief Return8-bit RNG Long Run Test counts. + * + * Register |BitsName + * ---------|-------- + * LR_STATUS| RNG_LR_CNT + * + * @param RNGx RNG instance. + * @retval Output Data[7:0] + */ +__STATIC_INLINE uint32_t ll_rng_read_lr_count(rng_regs_t *RNGx) +{ + return READ_BITS(RNGx->LR_STATUS, RNG_LR_STATUS_CNT) >> RNG_LR_STATUS_CNT_Pos; +} + +/** @} */ + +/** @defgroup RNG_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize the RNG registers to their default reset values. + * @param RNGx RNG instance. + * @retval An error_status_t enumeration value: + * - SUCCESS: RNG registers are de-initialized + * - ERROR: RNG registers are not de-initialized + */ +error_status_t ll_rng_deinit(rng_regs_t *RNGx); + +/** + * @brief Initialize RNG registers according to the specified + * parameters in p_rng_init. + * @param RNGx RNG Instance + * @param p_rng_init Pointer to a ll_rng_init_t structure that contains the configuration + * information for the specified RNG peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: RNG registers are initialized according to p_rng_init content + * - ERROR: Problem occurred during RNG Registers initialization + */ +error_status_t ll_rng_init(rng_regs_t *RNGx, ll_rng_init_t *p_rng_init); + +/** + * @brief Set each field of a @ref ll_rng_init_t type structure to default value. + * @param p_rng_init Pointer to a @ref ll_rng_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_rng_struct_init(ll_rng_init_t *p_rng_init); + +/** @} */ + +/** @} */ + +#endif /* RNG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_RNG_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_spi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_spi.h new file mode 100644 index 0000000..aa380c7 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_spi.h @@ -0,0 +1,2631 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_spi.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of SPI LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_SPI SPI + * @brief SPI LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_SPI_H__ +#define __GR55xx_LL_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (SPIM) || defined (SPIS) || defined (QSPI0) || defined (QSPI1) + +/** @defgroup LL_SPI_DRIVER_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPI_LL_ES_INIT SPI Exported init structure + * @{ + */ + +/** + * @brief LL SPIM init structures definition + */ +typedef struct _ll_spim_init_t +{ + uint32_t transfer_direction; /**< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_transfer_direction().*/ + + uint32_t data_size; /**< Specifies the SPI data size. + This parameter can be a value of @ref SPI_LL_EC_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_data_size().*/ + + uint32_t clock_polarity; /**< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_LL_EC_POLARITY. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_polarity().*/ + + uint32_t clock_phase; /**< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_LL_EC_PHASE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_phase().*/ + + uint32_t slave_select; /**< Specifies the SPI slave select. + This parameter can be a value of @ref SPI_LL_EC_SLAVESELECT. + + This feature can be modified afterwards using unitary function @ref ll_spi_enable_ss().*/ + + uint32_t baud_rate; /**< Specifies the BaudRate prescaler value which will be used to configure the transmit and receive SCK clock. + This parameter can be one even value between 2 and 65534, if the value is 0, the SCLK is disable. + @note The communication clock is derived from the master clock. The slave clock does not need to be set. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_baud_rate_prescaler().*/ +} ll_spim_init_t; + +/** + * @brief SPIS init structures definition + */ +typedef struct _ll_spis_init_t +{ + uint32_t data_size; /**< Specifies the SPI data width. + This parameter can be a value of @ref SPI_LL_EC_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_data_size().*/ + + uint32_t clock_polarity; /**< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_LL_EC_POLARITY. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_polarity().*/ + + uint32_t clock_phase; /**< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_LL_EC_PHASE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_phase().*/ + +} ll_spis_init_t; + +/** + * @brief QSPI init structures definition + */ +typedef struct _ll_qspi_init_t +{ + uint32_t transfer_direction; /**< Specifies the QSPI transfer or receive mode. + This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_transfer_direction().*/ + + uint32_t instruction_size; /**< Specifies the QSPI instruction width. + This parameter can be a value of @ref SPI_LL_EC_INSTRUCTIONSIZE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_instruction_size().*/ + + uint32_t address_size; /**< Specifies the QSPI address width. + This parameter can be a value of @ref SPI_LL_EC_ADDRESSSIZE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_address_size().*/ + + uint32_t inst_addr_transfer_format; /**< Specifies the QSPI instruction and address transfer format. + This parameter can be a value of @ref SPI_LL_EC_ADDRINSTTRNASFERFORMAT. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_add_inst_transfer_format().*/ + + uint32_t wait_cycles; /**< Specifies the QSPI dummy clock. + This parameter can be one of the following values: 0 ~ 31. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_wait_cycles().*/ + + uint32_t data_size; /**< Specifies the SPI data width. + This parameter can be a value of @ref SPI_LL_EC_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_data_size().*/ + + uint32_t clock_polarity; /**< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_LL_EC_POLARITY. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_polarity().*/ + + uint32_t clock_phase; /**< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_LL_EC_PHASE. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_clock_phase().*/ + + uint32_t baud_rate; /**< Specifies the BaudRate prescaler value which will be used to configure the transmit and receive SCK clock. + This parameter can be one even value between 2 and 65534, if the value is 0, the SCLK is disable. + @note The communication clock is derived from the master clock. The slave clock does not need to be set. + + This feature can be modified afterwards using unitary function @ref ll_spi_set_baud_rate_prescaler().*/ + + uint32_t rx_sample_delay; /**< Specifies the RX sample delay. It is used to delay the sample of the RX input port. + This parameter can be a number between 0 and 0x7 */ +} ll_qspi_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup SPI_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags definitions which can be used with LL_SPI_ReadReg function + * @{ + */ +#define LL_SSI_SR_DCOL SSI_STAT_DCOL /**< Data collision error flag */ +#define LL_SSI_SR_TXE SSI_STAT_TXE /**< Transmission error flag */ +#define LL_SSI_SR_RFF SSI_STAT_RFF /**< Rx FIFO full flag */ +#define LL_SSI_SR_RFNE SSI_STAT_RFNE /**< Rx FIFO not empty flag */ +#define LL_SSI_SR_TFE SSI_STAT_TFE /**< Tx FIFO empty flag */ +#define LL_SSI_SR_TFNF SSI_STAT_TFNF /**< Tx FIFO not full flag */ +#define LL_SSI_SR_BUSY SSI_STAT_BUSY /**< Busy flag */ +/** @} */ + +/** @defgroup SPI_LL_EC_IT IT Defines + * @brief Interrupt definitions which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions + * @{ + */ +#define LL_SSI_IM_MST SSI_INTMASK_MSTIM /**< Multi-Master Contention Interrupt enable */ +#define LL_SSI_IM_RXF SSI_INTMASK_RXFIM /**< Receive FIFO Full Interrupt enable */ +#define LL_SSI_IM_RXO SSI_INTMASK_RXOIM /**< Receive FIFO Overflow Interrupt enable */ +#define LL_SSI_IM_RXU SSI_INTMASK_RXUIM /**< Receive FIFO Underflow Interrupt enable */ +#define LL_SSI_IM_TXO SSI_INTMASK_TXOIM /**< Transmit FIFO Overflow Interrupt enable */ +#define LL_SSI_IM_TXE SSI_INTMASK_TXEIM /**< Transmit FIFO Empty Interrupt enable */ + +#define LL_SSI_IS_MST SSI_INTSTAT_MSTIS /**< Multi-Master Contention Interrupt flag */ +#define LL_SSI_IS_RXF SSI_INTSTAT_RXFIS /**< Receive FIFO Full Interrupt flag */ +#define LL_SSI_IS_RXO SSI_INTSTAT_RXOIS /**< Receive FIFO Overflow Interrupt flag */ +#define LL_SSI_IS_RXU SSI_INTSTAT_RXUIS /**< Receive FIFO Underflow Interrupt flag */ +#define LL_SSI_IS_TXO SSI_INTSTAT_TXOIS /**< Transmit FIFO Overflow Interrupt flag */ +#define LL_SSI_IS_TXE SSI_INTSTAT_TXEIS /**< Transmit FIFO Empty Interrupt flag */ + +#define LL_SSI_RIS_MST SSI_RAW_INTSTAT_MSTIR /**< Multi-Master Contention RAW Interrupt flag */ +#define LL_SSI_RIS_RXF SSI_RAW_INTSTAT_RXFIR /**< Receive FIFO Full RAW Interrupt flag */ +#define LL_SSI_RIS_RXO SSI_RAW_INTSTAT_RXOIR /**< Receive FIFO Overflow RAW Interrupt flag */ +#define LL_SSI_RIS_RXU SSI_RAW_INTSTAT_RXUIR /**< Receive FIFO Underflow RAW Interrupt flag */ +#define LL_SSI_RIS_TXO SSI_RAW_INTSTAT_TXOIR /**< Transmit FIFO Overflow RAW Interrupt flag */ +#define LL_SSI_RIS_TXE SSI_RAW_INTSTAT_TXEIR /**< Transmit FIFO Empty RAW Interrupt flag */ +/** @} */ + +/** @defgroup SPI_LL_EC_SPIFRAMEFORMAT SPI Frame Format + * @{ + */ +#define LL_SSI_FRF_SPI 0x00000000UL /**< SPI frame format for transfer */ +#define LL_SSI_FRF_DUALSPI (1UL << SSI_CTRL0_SPIFRF_Pos) /**< Dual-SPI frame format for transfer */ +#define LL_SSI_FRF_QUADSPI (2UL << SSI_CTRL0_SPIFRF_Pos) /**< Quad-SPI frame format for transfer */ +/** @} */ + +/** @defgroup SPI_LL_EC_DATASIZE Datawidth + * @{ + */ +#define LL_SSI_DATASIZE_4BIT (3UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 4 bits */ +#define LL_SSI_DATASIZE_5BIT (4UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 5 bits */ +#define LL_SSI_DATASIZE_6BIT (5UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 6 bits */ +#define LL_SSI_DATASIZE_7BIT (6UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 7 bits */ +#define LL_SSI_DATASIZE_8BIT (7UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 8 bits */ +#define LL_SSI_DATASIZE_9BIT (8UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 9 bits */ +#define LL_SSI_DATASIZE_10BIT (9UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 10 bits */ +#define LL_SSI_DATASIZE_11BIT (10UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 11 bits */ +#define LL_SSI_DATASIZE_12BIT (11UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 12 bits */ +#define LL_SSI_DATASIZE_13BIT (12UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 13 bits */ +#define LL_SSI_DATASIZE_14BIT (13UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 14 bits */ +#define LL_SSI_DATASIZE_15BIT (14UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 15 bits */ +#define LL_SSI_DATASIZE_16BIT (15UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 16 bits */ +#define LL_SSI_DATASIZE_17BIT (16UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 17 bits */ +#define LL_SSI_DATASIZE_18BIT (17UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 18 bits */ +#define LL_SSI_DATASIZE_19BIT (18UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 19 bits */ +#define LL_SSI_DATASIZE_20BIT (19UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 20 bits */ +#define LL_SSI_DATASIZE_21BIT (20UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 21 bits */ +#define LL_SSI_DATASIZE_22BIT (21UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 22 bits */ +#define LL_SSI_DATASIZE_23BIT (22UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 23 bits */ +#define LL_SSI_DATASIZE_24BIT (23UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 24 bits */ +#define LL_SSI_DATASIZE_25BIT (24UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 25 bits */ +#define LL_SSI_DATASIZE_26BIT (25UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 26 bits */ +#define LL_SSI_DATASIZE_27BIT (26UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 27 bits */ +#define LL_SSI_DATASIZE_28BIT (27UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 28 bits */ +#define LL_SSI_DATASIZE_29BIT (28UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 29 bits */ +#define LL_SSI_DATASIZE_30BIT (29UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 30 bits */ +#define LL_SSI_DATASIZE_31BIT (30UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 31 bits */ +#define LL_SSI_DATASIZE_32BIT (31UL << SSI_CTRL0_DFS32_Pos) /**< Data length for SPI transfer: 32 bits */ +/** @} */ + +/** @defgroup SPI_LL_EC_MICROWIRECOMMANDSIZE MicroWire CommandSize + * @{ + */ +#define LL_SSI_MW_CMDSIZE_1BIT 0x00000000UL /**< CMD length for Microwire transfer: 1 bits */ +#define LL_SSI_MW_CMDSIZE_2BIT (1UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 2 bits */ +#define LL_SSI_MW_CMDSIZE_3BIT (2UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 3 bits */ +#define LL_SSI_MW_CMDSIZE_4BIT (3UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 4 bits */ +#define LL_SSI_MW_CMDSIZE_5BIT (4UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 5 bits */ +#define LL_SSI_MW_CMDSIZE_6BIT (5UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 6 bits */ +#define LL_SSI_MW_CMDSIZE_7BIT (6UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 7 bits */ +#define LL_SSI_MW_CMDSIZE_8BIT (7UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 8 bits */ +#define LL_SSI_MW_CMDSIZE_9BIT (8UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 9 bits */ +#define LL_SSI_MW_CMDSIZE_10BIT (9UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 10 bits */ +#define LL_SSI_MW_CMDSIZE_11BIT (10UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 11 bits */ +#define LL_SSI_MW_CMDSIZE_12BIT (11UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 12 bits */ +#define LL_SSI_MW_CMDSIZE_13BIT (12UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 13 bits */ +#define LL_SSI_MW_CMDSIZE_14BIT (13UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 14 bits */ +#define LL_SSI_MW_CMDSIZE_15BIT (14UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 15 bits */ +#define LL_SSI_MW_CMDSIZE_16BIT (15UL << SSI_CTRL0_CFS_Pos) /**< CMD length for Microwire transfer: 16 bits */ +/** @} */ + +/** @defgroup SPI_LL_EC_TEST_MODE Test Mode + * @{ + */ +#define LL_SSI_NORMAL_MODE 0x00000000UL /**< Normal mode for SPI transfer */ +#define LL_SSI_TEST_MODE (1UL << SSI_CTRL0_SRL_Pos) /**< Test mode for SPI transfer: Rx and Tx connected inside */ +/** @} */ + +/** @defgroup SPI_LL_EC_SLAVEOUT_ENABLE Slave Out Enable + * @{ + */ +#define LL_SSI_SLAVE_OUTDIS 0x00000000UL /**< Output enable for SPI transfer as slave */ +#define LL_SSI_SLAVE_OUTEN (1UL << SSI_CTRL0_SLVOE_Pos) /**< Output disable for SPI transfer as slave */ +/** @} */ + +/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode + * @{ + */ +#define LL_SSI_FULL_DUPLEX 0x00000000UL /**< Full-Duplex mode. Rx and Tx transfer on 2 lines */ +#define LL_SSI_SIMPLEX_TX (1UL << SSI_CTRL0_TMOD_Pos) /**< Simplex Tx mode. Tx transfer only on 1 line */ +#define LL_SSI_SIMPLEX_RX (2UL << SSI_CTRL0_TMOD_Pos) /**< Simplex Rx mode. Rx transfer only on 1 line */ +#define LL_SSI_READ_EEPROM (3UL << SSI_CTRL0_TMOD_Pos) /**< Read EEPROM mode. Rx transfer only on 1 line */ +/** @} */ + +/** @defgroup SPI_LL_EC_PHASE Clock Phase + * @{ + */ +#define LL_SSI_SCPHA_1EDGE 0x00000000UL /**< First clock transition is the first data capture edge */ +#define LL_SSI_SCPHA_2EDGE (1UL << SSI_CTRL0_SCPHA_Pos) /**< Second clock transition is the first data capture edge */ +/** @} */ + +/** @defgroup SPI_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_SSI_SCPOL_LOW 0x00000000UL /**< Clock to 0 when idle */ +#define LL_SSI_SCPOL_HIGH (1UL << SSI_CTRL0_SCPOL_Pos) /**< Clock to 1 when idle */ +/** @} */ + +/** @defgroup SPI_LL_EC_PROTOCOL Serial Protocol + * @{ + */ +#define LL_SSI_PROTOCOL_MOTOROLA 0x00000000UL /**< Motorola mode. Used as default value */ +#define LL_SSI_PROTOCOL_TI (1UL << SSI_CTRL0_FRF_Pos) /**< TI mode */ +#define LL_SSI_PROTOCOL_MICROWIRE (2UL << SSI_CTRL0_FRF_Pos) /**< Microwire mode */ +/** @} */ + +/** @defgroup SPI_LL_EC_MICROWIRECONTROL MicroWire Control + * @{ + */ +#define LL_SSI_MICROWIRE_HANDSHAKE_DIS 0x00000000UL /**< Enable Handshake for Microwire transfer */ +#define LL_SSI_MICROWIRE_HANDSHAKE_EN (1UL << SSI_MWC_MHS_Pos) /**< Disable Handshake for Microwire transfer */ + +#define LL_SSI_MICROWIRE_RX 0x00000000UL /**< Rx mode. Rx transfer at Microwire mode */ +#define LL_SSI_MICROWIRE_TX (1UL << SSI_MWC_MDD_Pos) /**< Tx mode. Tx transfer at Microwire mode */ + +#define LL_SSI_MICROWIRE_NON_SEQUENTIAL 0x00000000UL /**< Non-sequential for Microwire transfer */ +#define LL_SSI_MICROWIRE_SEQUENTIAL (1UL << SSI_MWC_MWMOD_Pos) /**< Sequential for Microwire transfer */ +/** @} */ + +/** @defgroup SPI_LL_EC_SLAVESELECT Slave Select + * @{ + */ +#define LL_SSI_SLAVE1 SSI_SE_SLAVE1 /**< Enable slave1 select pin for SPI transfer */ +#define LL_SSI_SLAVE0 SSI_SE_SLAVE0 /**< Enable slave0 select pin for SPI transfer */ +/** @} */ + +/** @defgroup SPI_LL_EC_DMA DMA Defines + * @{ + */ +#define LL_SSI_DMA_TX_DIS 0x00000000UL /**< Disable the transmit FIFO DMA channel */ +#define LL_SSI_DMA_TX_EN SSI_DMAC_TDMAE /**< Enable the transmit FIFO DMA channel */ + +#define LL_SSI_DMA_RX_DIS 0x00000000UL /**< Disable the receive FIFO DMA channel */ +#define LL_SSI_DMA_RX_EN SSI_DMAC_RDMAE /**< Enable the receive FIFO DMA channel */ +/** @} */ + +/** @defgroup SPI_LL_EC_INSTRUCTIONSIZE QSPI Instruction Size + * @{ + */ +#define LL_SSI_INSTSIZE_0BIT 0x00000000UL /**< Instruction length for QSPI transfer: 0 bits */ +#define LL_SSI_INSTSIZE_4BIT (1UL << SSI_SCTRL0_INSTL_Pos) /**< Instructoin length for QSPI transfer: 4 bits */ +#define LL_SSI_INSTSIZE_8BIT (2UL << SSI_SCTRL0_INSTL_Pos) /**< Instructoin length for QSPI transfer: 8 bits */ +#define LL_SSI_INSTSIZE_16BIT (3UL << SSI_SCTRL0_INSTL_Pos) /**< Instructoin length for QSPI transfer: 16 bits */ +/** @} */ + +/** @defgroup SPI_LL_EC_ADDRESSSIZE QSPI Address Size + * @{ + */ +#define LL_SSI_ADDRSIZE_0BIT 0x00000000UL /**< Address length for QSPI transfer: 0 bits */ +#define LL_SSI_ADDRSIZE_4BIT (1UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 4 bits */ +#define LL_SSI_ADDRSIZE_8BIT (2UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 8 bits */ +#define LL_SSI_ADDRSIZE_12BIT (3UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 12 bits */ +#define LL_SSI_ADDRSIZE_16BIT (4UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 16 bits */ +#define LL_SSI_ADDRSIZE_20BIT (5UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 20 bits */ +#define LL_SSI_ADDRSIZE_24BIT (6UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 24 bits */ +#define LL_SSI_ADDRSIZE_28BIT (7UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 28 bits */ +#define LL_SSI_ADDRSIZE_32BIT (8UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 32 bits */ +#define LL_SSI_ADDRSIZE_36BIT (9UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 36 bits */ +#define LL_SSI_ADDRSIZE_40BIT (10UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 40 bits */ +#define LL_SSI_ADDRSIZE_44BIT (11UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 44 bits */ +#define LL_SSI_ADDRSIZE_48BIT (12UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 48 bits */ +#define LL_SSI_ADDRSIZE_52BIT (13UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 52 bits */ +#define LL_SSI_ADDRSIZE_56BIT (14UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 56 bits */ +#define LL_SSI_ADDRSIZE_60BIT (15UL << SSI_SCTRL0_ADDRL_Pos) /**< Address length for QSPI transfer: 60 bits */ +/** @} */ + +/** @defgroup SPI_LL_EC_ADDRINSTTRNASFERFORMAT QSPI Address and Instruction Transfer Format + * @{ + */ +#define LL_SSI_INST_ADDR_ALL_IN_SPI 0x00000000UL /**< Instruction and address are sent in SPI mode */ +#define LL_SSI_INST_IN_SPI_ADDR_IN_SPIFRF (1UL << SSI_SCTRL0_TRANSTYPE_Pos) /**< Instruction is in sent in SPI mode and address is sent in Daul/Quad SPI mode */ +#define LL_SSI_INST_ADDR_ALL_IN_SPIFRF (2UL << SSI_SCTRL0_TRANSTYPE_Pos) /**< Instruction and address are sent in Daul/Quad SPI mode */ +/** @} */ + +/** @defgroup SPI_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL SPIM InitStrcut default configuartion + */ +#define LL_SPIM_DEFAULT_CONFIG \ +{ \ + .transfer_direction = LL_SSI_FULL_DUPLEX, \ + .data_size = LL_SSI_DATASIZE_8BIT, \ + .clock_polarity = LL_SSI_SCPOL_LOW, \ + .clock_phase = LL_SSI_SCPHA_1EDGE, \ + .slave_select = LL_SSI_SLAVE0, \ + .baud_rate = SystemCoreClock / 2000000, \ +} + +/** + * @brief LL SPIS InitStrcut default configuartion + */ +#define LL_SPIS_DEFAULT_CONFIG \ +{ \ + .data_size = LL_SSI_DATASIZE_8BIT, \ + .clock_polarity = LL_SSI_SCPOL_LOW, \ + .clock_phase = LL_SSI_SCPHA_1EDGE, \ +} + +/** + * @brief LL QSPI InitStrcut default configuartion + */ +#define LL_QSPI_DEFAULT_CONFIG \ +{ \ + .transfer_direction = LL_SSI_SIMPLEX_TX, \ + .instruction_size = LL_SSI_INSTSIZE_8BIT, \ + .address_size = LL_SSI_ADDRSIZE_24BIT, \ + .inst_addr_transfer_format = LL_SSI_INST_ADDR_ALL_IN_SPI,\ + .wait_cycles = 0, \ + .data_size = LL_SSI_DATASIZE_8BIT, \ + .clock_polarity = LL_SSI_SCPOL_LOW, \ + .clock_phase = LL_SSI_SCPHA_1EDGE, \ + .baud_rate = SystemCoreClock / 1000000, \ + .rx_sample_delay = 0, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in SPI register + * @param __instance__ SPI instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_SPI_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in SPI register + * @param __instance__ SPI instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_SPI_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SPI_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup SPI_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable slave select toggle + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_ss_toggle(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->CTRL0, SSI_CTRL0_SSTEN); +} + +/** + * @brief Disable slave select toggle + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_ss_toggle(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->CTRL0, SSI_CTRL0_SSTEN); +} + +/** + * @brief Check if slave select toggle is enabled + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_ss_toggle(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->CTRL0, SSI_CTRL0_SSTEN) == (SSI_CTRL0_SSTEN)); +} + +/** + * @brief Set data frame format for transmitting/receiving the data + * @note This bit should be written only when SPI is disabled (SSI_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SPIFRF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param frf This parameter can be one of the following values: + * @arg @ref LL_SSI_FRF_SPI + * @arg @ref LL_SSI_FRF_DUALSPI + * @arg @ref LL_SSI_FRF_QUADSPI + * @retval None + */ +__STATIC_INLINE void ll_spi_set_frame_format(ssi_regs_t *SPIx, uint32_t frf) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_SPIFRF, frf); +} + +/** + * @brief Get data frame format for transmitting/receiving the data + * @note This bit should be written only when SPI is disabled (SSI_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SPIFRF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_FRF_SPI + * @arg @ref LL_SSI_FRF_DUALSPI + * @arg @ref LL_SSI_FRF_QUADSPI + */ +__STATIC_INLINE uint32_t ll_spi_get_frame_format(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_SPIFRF)); +} + +/** + * @brief Set frame data size + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | DFS32 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param size This parameter can be one of the following values: + * @arg @ref LL_SSI_DATASIZE_4BIT + * @arg @ref LL_SSI_DATASIZE_5BIT + * @arg @ref LL_SSI_DATASIZE_6BIT + * @arg @ref LL_SSI_DATASIZE_7BIT + * @arg @ref LL_SSI_DATASIZE_8BIT + * @arg @ref LL_SSI_DATASIZE_9BIT + * @arg @ref LL_SSI_DATASIZE_10BIT + * @arg @ref LL_SSI_DATASIZE_11BIT + * @arg @ref LL_SSI_DATASIZE_12BIT + * @arg @ref LL_SSI_DATASIZE_13BIT + * @arg @ref LL_SSI_DATASIZE_14BIT + * @arg @ref LL_SSI_DATASIZE_15BIT + * @arg @ref LL_SSI_DATASIZE_16BIT + * @arg @ref LL_SSI_DATASIZE_17BIT + * @arg @ref LL_SSI_DATASIZE_18BIT + * @arg @ref LL_SSI_DATASIZE_19BIT + * @arg @ref LL_SSI_DATASIZE_20BIT + * @arg @ref LL_SSI_DATASIZE_21BIT + * @arg @ref LL_SSI_DATASIZE_22BIT + * @arg @ref LL_SSI_DATASIZE_23BIT + * @arg @ref LL_SSI_DATASIZE_24BIT + * @arg @ref LL_SSI_DATASIZE_25BIT + * @arg @ref LL_SSI_DATASIZE_26BIT + * @arg @ref LL_SSI_DATASIZE_27BIT + * @arg @ref LL_SSI_DATASIZE_28BIT + * @arg @ref LL_SSI_DATASIZE_29BIT + * @arg @ref LL_SSI_DATASIZE_30BIT + * @arg @ref LL_SSI_DATASIZE_31BIT + * @arg @ref LL_SSI_DATASIZE_32BIT + * @retval None + */ +__STATIC_INLINE void ll_spi_set_data_size(ssi_regs_t *SPIx, uint32_t size) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_DFS32, size); +} + +/** + * @brief Get frame data size + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | DFS32 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_DATASIZE_4BIT + * @arg @ref LL_SSI_DATASIZE_5BIT + * @arg @ref LL_SSI_DATASIZE_6BIT + * @arg @ref LL_SSI_DATASIZE_7BIT + * @arg @ref LL_SSI_DATASIZE_8BIT + * @arg @ref LL_SSI_DATASIZE_9BIT + * @arg @ref LL_SSI_DATASIZE_10BIT + * @arg @ref LL_SSI_DATASIZE_11BIT + * @arg @ref LL_SSI_DATASIZE_12BIT + * @arg @ref LL_SSI_DATASIZE_13BIT + * @arg @ref LL_SSI_DATASIZE_14BIT + * @arg @ref LL_SSI_DATASIZE_15BIT + * @arg @ref LL_SSI_DATASIZE_16BIT + * @arg @ref LL_SSI_DATASIZE_17BIT + * @arg @ref LL_SSI_DATASIZE_18BIT + * @arg @ref LL_SSI_DATASIZE_19BIT + * @arg @ref LL_SSI_DATASIZE_20BIT + * @arg @ref LL_SSI_DATASIZE_21BIT + * @arg @ref LL_SSI_DATASIZE_22BIT + * @arg @ref LL_SSI_DATASIZE_23BIT + * @arg @ref LL_SSI_DATASIZE_24BIT + * @arg @ref LL_SSI_DATASIZE_25BIT + * @arg @ref LL_SSI_DATASIZE_26BIT + * @arg @ref LL_SSI_DATASIZE_27BIT + * @arg @ref LL_SSI_DATASIZE_28BIT + * @arg @ref LL_SSI_DATASIZE_29BIT + * @arg @ref LL_SSI_DATASIZE_30BIT + * @arg @ref LL_SSI_DATASIZE_31BIT + * @arg @ref LL_SSI_DATASIZE_32BIT + */ +__STATIC_INLINE uint32_t ll_spi_get_data_size(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_DFS32)); +} + +/** + * @brief Set the length of the control word for the Microwire frame format + * @note This bit should be written only when SPI is disabled (SSI_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | CFS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param size This parameter can be one of the following values: + * @arg @ref LL_SSI_MW_CMDSIZE_1BIT + * @arg @ref LL_SSI_MW_CMDSIZE_2BIT + * @arg @ref LL_SSI_MW_CMDSIZE_3BIT + * @arg @ref LL_SSI_MW_CMDSIZE_4BIT + * @arg @ref LL_SSI_MW_CMDSIZE_5BIT + * @arg @ref LL_SSI_MW_CMDSIZE_6BIT + * @arg @ref LL_SSI_MW_CMDSIZE_7BIT + * @arg @ref LL_SSI_MW_CMDSIZE_8BIT + * @arg @ref LL_SSI_MW_CMDSIZE_9BIT + * @arg @ref LL_SSI_MW_CMDSIZE_10BIT + * @arg @ref LL_SSI_MW_CMDSIZE_11BIT + * @arg @ref LL_SSI_MW_CMDSIZE_12BIT + * @arg @ref LL_SSI_MW_CMDSIZE_13BIT + * @arg @ref LL_SSI_MW_CMDSIZE_14BIT + * @arg @ref LL_SSI_MW_CMDSIZE_15BIT + * @arg @ref LL_SSI_MW_CMDSIZE_16BIT + * @retval None + */ +__STATIC_INLINE void ll_spi_set_control_frame_size(ssi_regs_t *SPIx, uint32_t size) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_CFS, size); +} + +/** + * @brief Get the length of the control word for the Microwire frame format + * @note This bit should be written only when SPI is disabled (SSI_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | CFS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_MW_CMDSIZE_1BIT + * @arg @ref LL_SSI_MW_CMDSIZE_2BIT + * @arg @ref LL_SSI_MW_CMDSIZE_3BIT + * @arg @ref LL_SSI_MW_CMDSIZE_4BIT + * @arg @ref LL_SSI_MW_CMDSIZE_5BIT + * @arg @ref LL_SSI_MW_CMDSIZE_6BIT + * @arg @ref LL_SSI_MW_CMDSIZE_7BIT + * @arg @ref LL_SSI_MW_CMDSIZE_8BIT + * @arg @ref LL_SSI_MW_CMDSIZE_9BIT + * @arg @ref LL_SSI_MW_CMDSIZE_10BIT + * @arg @ref LL_SSI_MW_CMDSIZE_11BIT + * @arg @ref LL_SSI_MW_CMDSIZE_12BIT + * @arg @ref LL_SSI_MW_CMDSIZE_13BIT + * @arg @ref LL_SSI_MW_CMDSIZE_14BIT + * @arg @ref LL_SSI_MW_CMDSIZE_15BIT + * @arg @ref LL_SSI_MW_CMDSIZE_16BIT + */ +__STATIC_INLINE uint32_t ll_spi_get_control_frame_size(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_CFS)); +} + +/** + * @brief Enable SPI test mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_test_mode(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->CTRL0, SSI_CTRL0_SRL); +} + +/** + * @brief Disable SPI test mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_test_mode(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->CTRL0, SSI_CTRL0_SRL); +} + +/** + * @brief Check if SPI test mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_test_mode(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->CTRL0, SSI_CTRL0_SRL) == (SSI_CTRL0_SRL)); +} + +/** + * @brief Enable slave output + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SLVOE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_slave_out(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->CTRL0, SSI_CTRL0_SLVOE); +} + +/** + * @brief Disable slave output + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SLVOE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_salve_out(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->CTRL0, SSI_CTRL0_SLVOE); +} + +/** + * @brief Check if slave output is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SLVOE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_slave_out(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->CTRL0, SSI_CTRL0_SLVOE) != (SSI_CTRL0_SLVOE)); +} + +/** + * @brief Set transfer direction mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | TMOD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param transfer_direction This parameter can be one of the following values: + * @arg @ref LL_SSI_FULL_DUPLEX + * @arg @ref LL_SSI_SIMPLEX_TX + * @arg @ref LL_SSI_SIMPLEX_RX + * @arg @ref LL_SSI_READ_EEPROM + * @retval None + */ +__STATIC_INLINE void ll_spi_set_transfer_direction(ssi_regs_t *SPIx, uint32_t transfer_direction) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_TMOD, transfer_direction); +} + +/** + * @brief Get transfer direction mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | TMOD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_FULL_DUPLEX + * @arg @ref LL_SSI_SIMPLEX_TX + * @arg @ref LL_SSI_SIMPLEX_RX + * @arg @ref LL_SSI_READ_EEPROM + */ +__STATIC_INLINE uint32_t ll_spi_get_transfer_direction(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_TMOD)); +} + +/** + * @brief Set clock polarity + * @note This bit should not be changed when communication is ongoing. + * This bit is not used in SPI TI mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SCPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param clock_polarity This parameter can be one of the following values: + * @arg @ref LL_SSI_SCPOL_LOW + * @arg @ref LL_SSI_SCPOL_HIGH + * @retval None + */ +__STATIC_INLINE void ll_spi_set_clock_polarity(ssi_regs_t *SPIx, uint32_t clock_polarity) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_SCPOL, clock_polarity); +} + +/** + * @brief Get clock polarity + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SCPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_SCPOL_LOW + * @arg @ref LL_SSI_SCPOL_HIGH + */ +__STATIC_INLINE uint32_t ll_spi_get_clock_polarity(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_SCPOL)); +} + +/** + * @brief Set clock phase + * @note This bit should not be changed when communication is ongoing. + * This bit is not used in SPI TI mode. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SCPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param clock_phase This parameter can be one of the following values: + * @arg @ref LL_SSI_SCPHA_1EDGE + * @arg @ref LL_SSI_SCPHA_2EDGE + * @retval None + */ +__STATIC_INLINE void ll_spi_set_clock_phase(ssi_regs_t *SPIx, uint32_t clock_phase) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_SCPHA, clock_phase); +} + +/** + * @brief Get clock phase + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | SCPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_SCPHA_1EDGE + * @arg @ref LL_SSI_SCPHA_2EDGE + */ +__STATIC_INLINE uint32_t ll_spi_get_clock_phase(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_SCPHA)); +} + +/** + * @brief Set serial protocol used + * @note This bit should be written only when SPI is disabled (SSI_EN = 0) for correct operation. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | FRF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param standard This parameter can be one of the following values: + * @arg @ref LL_SSI_PROTOCOL_MOTOROLA + * @arg @ref LL_SSI_PROTOCOL_TI + * @arg @ref LL_SSI_PROTOCOL_MICROWIRE + * @retval None + */ +__STATIC_INLINE void ll_spi_set_standard(ssi_regs_t *SPIx, uint32_t standard) +{ + MODIFY_REG(SPIx->CTRL0, SSI_CTRL0_FRF, standard); +} + +/** + * @brief Get serial protocol used + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | FRF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_PROTOCOL_MOTOROLA + * @arg @ref LL_SSI_PROTOCOL_TI + * @arg @ref LL_SSI_PROTOCOL_MICROWIRE + */ +__STATIC_INLINE uint32_t ll_spi_get_standard(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL0, SSI_CTRL0_FRF)); +} + +/** + * @brief Set the number of data frames to be continuously received + * @note These bits should not be changed when communication is ongoing. + This bits are effect when TMOD = 2b10 or 2b11. + This bits are not effect in SPIS. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | NDF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param size This parameter can be one of the following values: 0 ~ 65535 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_receive_size(ssi_regs_t *SPIx, uint32_t size) +{ + MODIFY_REG(SPIx->CTRL1, SSI_CTRL1_NDF, size); +} + +/** + * @brief Get the number of data frames to be continuously received + * @note These bits should not be changed when communication is ongoing. + This bits are effect when TMOD = 2b10 or 2b11. + This bits are not effect in SPIS. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | NDF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 65535 + */ +__STATIC_INLINE uint32_t ll_spi_get_receive_size(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->CTRL1, SSI_CTRL1_NDF)); +} + +/** + * @brief Enable SPI peripheral + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SSI_EN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->SSI_EN, SSI_SSIEN_EN); +} + +/** + * @brief Disable SPI peripheral + * @note When disabling the SPI, follow the procedure described in the Reference Manual. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SSI_EN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->SSI_EN, SSI_SSIEN_EN); +} + +/** + * @brief Check if SPI peripheral is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SSI_EN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->SSI_EN, SSI_SSIEN_EN) == (SSI_SSIEN_EN)); +} + +/** + * @brief Enable Handshake in Microwire mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MHS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_micro_handshake(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->MWC, SSI_MWC_MHS); +} + +/** + * @brief Disable Handshake in Microwire mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MHS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_micro_handshake(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->MWC, SSI_MWC_MHS); +} + +/** + * @brief Check if Handshake in Microwire mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MHS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_micro_handshake(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->MWC, SSI_MWC_MHS) == (SSI_MWC_MHS)); +} + +/** + * @brief Set transfer direction mode in Microwire mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MDD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param transfer_direction This parameter can be one of the following values: + * @arg @ref LL_SSI_MICROWIRE_RX + * @arg @ref LL_SSI_MICROWIRE_TX + * @retval None + */ +__STATIC_INLINE void ll_spi_set_micro_transfer_direction(ssi_regs_t *SPIx, uint32_t transfer_direction) +{ + MODIFY_REG(SPIx->MWC, SSI_MWC_MDD, transfer_direction); +} + +/** + * @brief Get transfer direction mode in Microwire mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MDD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_MICROWIRE_RX + * @arg @ref LL_SSI_MICROWIRE_TX + */ +__STATIC_INLINE uint32_t ll_spi_get_micro_transfer_direction(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->MWC, SSI_MWC_MDD)); +} + +/** + * @brief Set transfer mode in Microwire mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MWMOD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param transfer_mode This parameter can be one of the following values: + * @arg @ref LL_SSI_MICROWIRE_NON_SEQUENTIAL + * @arg @ref LL_SSI_MICROWIRE_SEQUENTIAL + * @retval None + */ +__STATIC_INLINE void ll_spi_set_micro_transfer_mode(ssi_regs_t *SPIx, uint32_t transfer_mode) +{ + MODIFY_REG(SPIx->MWC, SSI_MWC_MWMOD, transfer_mode); +} + +/** + * @brief Get transfer mode in Microwire mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MWC | MWMOD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_MICROWIRE_NON_SEQUENTIAL + * @arg @ref LL_SSI_MICROWIRE_SEQUENTIAL + */ +__STATIC_INLINE uint32_t ll_spi_get_micro_transfer_mode(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->MWC, SSI_MWC_MWMOD)); +} + +/** + * @brief Enable slave select + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SE | SLAVE1 | + * +----------------------+-----------------------------------+ + * \endrst + * SE | SLAVE0 + * + * @param SPIx SPI instance + * @param ss This parameter can be one of the following values: + * @arg @ref LL_SSI_SLAVE1 + * @arg @ref LL_SSI_SLAVE0 + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_ss(ssi_regs_t *SPIx, uint32_t ss) +{ + SET_BITS(SPIx->SE, ss); +} + +/** + * @brief Disable slave select + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SE | SLAVE1 | + * +----------------------+-----------------------------------+ + * \endrst + * SE | SLAVE0 + * + * @param SPIx SPI instance + * @param ss This parameter can be one of the following values: + * @arg @ref LL_SSI_SLAVE1 + * @arg @ref LL_SSI_SLAVE0 + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_ss(ssi_regs_t *SPIx, uint32_t ss) +{ + CLEAR_BITS(SPIx->SE, ss); +} + +/** + * @brief Check if slave select is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SE | SLAVE1 | + * +----------------------+-----------------------------------+ + * \endrst + * SE | SLAVE0 + * + * @param SPIx SPI instance + * @param ss This parameter can be one of the following values: + * @arg @ref LL_SSI_SLAVE1 + * @arg @ref LL_SSI_SLAVE0 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_ss(ssi_regs_t *SPIx, uint32_t ss) +{ + return (READ_BITS(SPIx->SE, ss) == ss); +} + +/** + * @brief Set baud rate prescaler + * @note These bits should not be changed when communication is ongoing. SPI BaudRate = fPCLK/Prescaler. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BAUD | SCKDIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param baud_rate This parameter can be one even value between 2 and 65534, if the value is 0, the SCLK is disable. + * @retval None + */ +__STATIC_INLINE void ll_spi_set_baud_rate_prescaler(ssi_regs_t *SPIx, uint32_t baud_rate) +{ + WRITE_REG(SPIx->BAUD, baud_rate); +} + +/** + * @brief Get baud rate prescaler + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BAUD | SCKDIV | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one even value between 2 and 65534. + */ +__STATIC_INLINE uint32_t ll_spi_get_baud_rate_prescaler(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->BAUD, SSI_BAUD_SCKDIV)); +} + +/** + * @brief Set threshold of TXFIFO that triggers an TXE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFTL | TFT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param threshold This parameter can be one of the following values: 0 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_tx_fifo_threshold(ssi_regs_t *SPIx, uint32_t threshold) +{ + WRITE_REG(SPIx->TX_FTL, threshold); +} + +/** + * @brief Get threshold of TXFIFO that triggers an TXE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFTL | TFT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 7 + */ +__STATIC_INLINE uint32_t ll_spi_get_tx_fifo_threshold(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->TX_FTL, SSI_TXFTL_TFT)); +} + +/** + * @brief Set threshold of RXFIFO that triggers an RXNE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFTL | RFT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param threshold This parameter can be one of the following values: 0 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_rx_fifo_threshold(ssi_regs_t *SPIx, uint32_t threshold) +{ + WRITE_REG(SPIx->RX_FTL, threshold); +} + +/** + * @brief Get threshold of RXFIFO that triggers an RXNE event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFTL | RFT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 7 + */ +__STATIC_INLINE uint32_t ll_spi_get_rx_fifo_threshold(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->RX_FTL, SSI_RXFTL_RFT)); +} + +/** + * @brief Get FIFO Transmission Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXFL | TXTFL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 8 + */ +__STATIC_INLINE uint32_t ll_spi_get_tx_fifo_level(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->TX_FL, SSI_TXFL_TXTFL)); +} + +/** + * @brief Get FIFO reception Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXFL | RXTFL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 8 + */ +__STATIC_INLINE uint32_t ll_spi_get_rx_fifo_level(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->RX_FL, SSI_RXFL_RXTFL)); +} + +/** + * @brief Get ID code + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IDCODE | ID | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value is const. + */ +__STATIC_INLINE uint32_t ll_spi_get_id_code(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->ID, SSI_IDCODE_ID)); +} + +/** + * @brief Get IP version + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | COMP | VERSION | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value is const. + */ +__STATIC_INLINE uint32_t ll_spi_get_version(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->VERSION_ID, SSI_COMP_VERSION)); +} + +/** @} */ + +/** @defgroup SPI_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable interrupt + * @note This bit controls the generation of an interrupt when an event occurs. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | INTMASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_SSI_IM_MST(not effect in SPIS) + * @arg @ref LL_SSI_IM_RXF + * @arg @ref LL_SSI_IM_RXO + * @arg @ref LL_SSI_IM_RXU + * @arg @ref LL_SSI_IM_TXO + * @arg @ref LL_SSI_IM_TXE + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_it(ssi_regs_t *SPIx, uint32_t mask) +{ + SET_BITS(SPIx->INTMASK, mask); +} + +/** + * @brief Disable interrupt + * @note This bit controls the generation of an interrupt when an event occurs. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | INTMASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_SSI_IM_MST(not effect in SPIS) + * @arg @ref LL_SSI_IM_RXF + * @arg @ref LL_SSI_IM_RXO + * @arg @ref LL_SSI_IM_RXU + * @arg @ref LL_SSI_IM_TXO + * @arg @ref LL_SSI_IM_TXE + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_it(ssi_regs_t *SPIx, uint32_t mask) +{ + CLEAR_BITS(SPIx->INTMASK, mask); +} + +/** + * @brief Check if interrupt is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTMASK | INTMASK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_SSI_IM_MST(not effect in SPIS) + * @arg @ref LL_SSI_IM_RXF + * @arg @ref LL_SSI_IM_RXO + * @arg @ref LL_SSI_IM_RXU + * @arg @ref LL_SSI_IM_TXO + * @arg @ref LL_SSI_IM_TXE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_it(ssi_regs_t *SPIx, uint32_t mask) +{ + return (READ_BITS(SPIx->INTMASK, mask) == mask); +} + +/** @} */ + +/** @defgroup SPI_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Get SPI status + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_SSI_SR_DCOL(no effect in SPIS) + * @arg @ref LL_SSI_SR_TXE + * @arg @ref LL_SSI_SR_RFF + * @arg @ref LL_SSI_SR_RFNE + * @arg @ref LL_SSI_SR_TFE + * @arg @ref LL_SSI_SR_TFNF + * @arg @ref LL_SSI_SR_BUSY + */ +__STATIC_INLINE uint32_t ll_spi_get_status(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->STAT)); +} + +/** + * @brief Check active flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | DCOL | + * +----------------------+-----------------------------------+ + * | STAT | TXE | + * +----------------------+-----------------------------------+ + * | STAT | RFF | + * +----------------------+-----------------------------------+ + * | STAT | RFNE | + * +----------------------+-----------------------------------+ + * | STAT | TFE | + * +----------------------+-----------------------------------+ + * | STAT | TFNF | + * +----------------------+-----------------------------------+ + * | STAT | BUSY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_SSI_SR_DCOL(no effect in SPIS) + * @arg @ref LL_SSI_SR_TXE + * @arg @ref LL_SSI_SR_RFF + * @arg @ref LL_SSI_SR_RFNE + * @arg @ref LL_SSI_SR_TFE + * @arg @ref LL_SSI_SR_TFNF + * @arg @ref LL_SSI_SR_BUSY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_active_flag(ssi_regs_t *SPIx, uint32_t flag) +{ + return (READ_BITS(SPIx->STAT, flag) == (flag)); +} + +/** + * @brief Get SPI interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_SSI_IS_MST(no effect in SPIS) + * @arg @ref LL_SSI_IS_RXF + * @arg @ref LL_SSI_IS_RXO + * @arg @ref LL_SSI_IS_RXU + * @arg @ref LL_SSI_IS_TXO + * @arg @ref LL_SSI_IS_TXE + */ +__STATIC_INLINE uint32_t ll_spi_get_it_flag(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->INTSTAT)); +} + +/** + * @brief Check interrupt flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | MSTIS | + * +----------------------+-----------------------------------+ + * \endrst + * INTSTAT | RXFIS + * INTSTAT | RXOIS + * INTSTAT | RXUIS + * INTSTAT | TXOIS + * INTSTAT | TXEIS + * + * @param SPIx SPI instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_SSI_IS_MST(no effect in SPIS) + * @arg @ref LL_SSI_IS_RXF + * @arg @ref LL_SSI_IS_RXO + * @arg @ref LL_SSI_IS_RXU + * @arg @ref LL_SSI_IS_TXO + * @arg @ref LL_SSI_IS_TXE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_it_flag(ssi_regs_t *SPIx, uint32_t flag) +{ + return (READ_BITS(SPIx->INTSTAT, flag) == flag); +} + +/** + * @brief Get SPI raw interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RAW_INTSTAT | RAW_INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_SSI_RIS_MST(no effect in SPIS) + * @arg @ref LL_SSI_RIS_RXF + * @arg @ref LL_SSI_RIS_RXO + * @arg @ref LL_SSI_RIS_RXU + * @arg @ref LL_SSI_RIS_TXO + * @arg @ref LL_SSI_RIS_TXE + */ +__STATIC_INLINE uint32_t ll_spi_get_raw_if_flag(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->RAW_INTSTAT)); +} + +/** + * @brief Clear transmit FIFO overflow error flag + * @note Clearing this flag is done by reading TXOIC register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TXOIC | TXOIC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_clear_flag_txo(ssi_regs_t *SPIx) +{ + __IOM uint32_t tmpreg; + tmpreg = SPIx->TXOIC; + (void) tmpreg; +} + +/** + * @brief Clear receive FIFO overflow error flag + * @note Clearing this flag is done by reading RXOIC register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXOIC | RXOIC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_clear_flag_rxo(ssi_regs_t *SPIx) +{ + __IOM uint32_t tmpreg; + tmpreg = SPIx->RXOIC; + (void) tmpreg; +} + +/** + * @brief Clear receive FIFO underflow error flag + * @note Clearing this flag is done by reading RXUIC register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RXUIC | RXUIC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_clear_flag_rxu(ssi_regs_t *SPIx) +{ + __IOM uint32_t tmpreg; + tmpreg = SPIx->RXUIC; + (void) tmpreg; +} + +/** + * @brief Clear multi-master error flag + * @note Clearing this flag is done by reading MSTIC register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSTIC | MSTIC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_clear_flag_mst(ssi_regs_t *SPIx) +{ + __IOM uint32_t tmpreg; + tmpreg = SPIx->MSTIC; + (void) tmpreg; +} + +/** + * @brief Clear all error flag + * @note Clearing this flag is done by reading INTCLR register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INTCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_clear_flag_all(ssi_regs_t *SPIx) +{ + __IOM uint32_t tmpreg; + tmpreg = SPIx->INTCLR; + (void) tmpreg; +} + +/** @} */ + +/** @defgroup SPI_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable DMA Tx + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_dma_req_tx(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->DMAC, SSI_DMAC_TDMAE); +} + +/** + * @brief Disable DMA Tx + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_dma_req_tx(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->DMAC, SSI_DMAC_TDMAE); +} + +/** + * @brief Check if DMA Tx is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | TDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_dma_req_tx(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->DMAC, SSI_DMAC_TDMAE) == (SSI_DMAC_TDMAE)); +} + +/** + * @brief Enable DMA Rx + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_enable_dma_req_rx(ssi_regs_t *SPIx) +{ + SET_BITS(SPIx->DMAC, SSI_DMAC_RDMAE); +} + +/** + * @brief Disable DMA Rx + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval None + */ +__STATIC_INLINE void ll_spi_disable_dma_req_rx(ssi_regs_t *SPIx) +{ + CLEAR_BITS(SPIx->DMAC, SSI_DMAC_RDMAE); +} + +/** + * @brief Check if DMA Rx is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMAC | RDMAE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_spi_is_enabled_dma_req_rx(ssi_regs_t *SPIx) +{ + return (READ_BITS(SPIx->DMAC, SSI_DMAC_RDMAE) == (SSI_DMAC_RDMAE)); +} + +/** + * @brief Set threshold of TXFIFO that triggers an DMA Tx request event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMATDL | DMATDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param threshold This parameter can be one of the following values: 0 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_dma_tx_fifo_threshold(ssi_regs_t *SPIx, uint32_t threshold) +{ + WRITE_REG(SPIx->DMA_TDL, threshold); +} + +/** + * @brief Get threshold of TXFIFO that triggers an DMA Tx request event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMATDL | DMATDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 7 + */ +__STATIC_INLINE uint32_t ll_spi_get_dma_tx_fifo_threshold(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->DMA_TDL, SSI_DMATDL_DMATDL)); +} + +/** + * @brief Set threshold of RXFIFO that triggers an DMA Rx request event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMARDL | DMARDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param threshold This parameter can be one of the following values: 0 ~ 7 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_dma_rx_fifo_threshold(ssi_regs_t *SPIx, uint32_t threshold) +{ + WRITE_REG(SPIx->DMA_RDL, threshold); +} + +/** + * @brief Get threshold of RXFIFO that triggers an DMA Rx request event + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DMARDL | DMARDL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 7 + */ +__STATIC_INLINE uint32_t ll_spi_get_dma_rx_fifo_threshold(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->DMA_RDL, SSI_DMARDL_DMARDL)); +} + +/** @} */ + +/** @defgroup SPI_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Write 8-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param tx_data Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void ll_spi_transmit_data8(ssi_regs_t *SPIx, uint8_t tx_data) +{ + *((__IOM uint8_t *)&SPIx->DATA) = tx_data; +} + +/** + * @brief Write 16-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param tx_data Value between Min_Data=0x0000 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void ll_spi_transmit_data16(ssi_regs_t *SPIx, uint16_t tx_data) +{ + *((__IOM uint16_t *)&SPIx->DATA) = tx_data; +} + +/** + * @brief Write 32-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param tx_data Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_spi_transmit_data32(ssi_regs_t *SPIx, uint32_t tx_data) +{ + *((__IOM uint32_t *)&SPIx->DATA) = tx_data; +} + +/** + * @brief Read 8-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Rerturned Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t ll_spi_receive_data8(ssi_regs_t *SPIx) +{ + return (uint8_t)(READ_REG(SPIx->DATA)); +} + +/** + * @brief Read 16-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned Value between Min_Data=0x0000 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint16_t ll_spi_receive_data16(ssi_regs_t *SPIx) +{ + return (uint16_t)(READ_REG(SPIx->DATA)); +} + +/** + * @brief Read 32-Bits in the data register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DATA | DATA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_spi_receive_data32(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->DATA)); +} + +/** + * @brief Set Rx sample delay + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RX_SAMPLEDLY | RX_SAMPLEDLY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param delay This parameter can be one of the following values: 0 ~ 256 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_rx_sample_delay(ssi_regs_t *SPIx, uint32_t delay) +{ + WRITE_REG(SPIx->RX_SAMPLE_DLY, delay); +} + +/** + * @brief Get Rx sample delay + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RX_SAMPLEDLY | RX_SAMPLEDLY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 256 + */ +__STATIC_INLINE uint32_t ll_spi_get_rx_sample_delay(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->RX_SAMPLE_DLY)); +} + +/** + * @brief Set number of wait cycles in Dual/Quad SPI mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | WAITCYCLES | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param wait_cycles This parameter can be one of the following values: 0 ~ 31 + * @retval None + */ +__STATIC_INLINE void ll_spi_set_wait_cycles(ssi_regs_t *SPIx, uint32_t wait_cycles) +{ + MODIFY_REG(SPIx->SPI_CTRL0, SSI_SCTRL0_WAITCYCLES, wait_cycles << SSI_SCTRL0_WAITCYCLES_Pos); +} + +/** + * @brief Get number of wait cycles in Dual/Quad SPI mode + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | WAITCYCLES | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: 0 ~ 31 + */ +__STATIC_INLINE uint32_t ll_spi_get_wait_cycles(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->SPI_CTRL0, SSI_SCTRL0_WAITCYCLES) >> SSI_SCTRL0_WAITCYCLES_Pos); +} + +/** + * @brief Set Dual/Quad SPI mode instruction length in bits + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | INSTL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param size This parameter can be one of the following values: + * @arg @ref LL_SSI_INSTSIZE_0BIT + * @arg @ref LL_SSI_INSTSIZE_4BIT + * @arg @ref LL_SSI_INSTSIZE_8BIT + * @arg @ref LL_SSI_INSTSIZE_16BIT + * @retval None + */ +__STATIC_INLINE void ll_spi_set_instruction_size(ssi_regs_t *SPIx, uint32_t size) +{ + MODIFY_REG(SPIx->SPI_CTRL0, SSI_SCTRL0_INSTL, size); +} + +/** + * @brief Get Dual/Quad SPI mode instruction length in bits + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | INSTL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_INSTSIZE_0BIT + * @arg @ref LL_SSI_INSTSIZE_4BIT + * @arg @ref LL_SSI_INSTSIZE_8BIT + * @arg @ref LL_SSI_INSTSIZE_16BIT + */ +__STATIC_INLINE uint32_t ll_spi_get_instruction_size(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->SPI_CTRL0, SSI_SCTRL0_INSTL)); +} + +/** + * @brief Set Dual/Quad SPI mode address length in bits + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | ADDRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param size This parameter can be one of the following values: + * @arg @ref LL_SSI_ADDRSIZE_0BIT + * @arg @ref LL_SSI_ADDRSIZE_4BIT + * @arg @ref LL_SSI_ADDRSIZE_8BIT + * @arg @ref LL_SSI_ADDRSIZE_12BIT + * @arg @ref LL_SSI_ADDRSIZE_16BIT + * @arg @ref LL_SSI_ADDRSIZE_20BIT + * @arg @ref LL_SSI_ADDRSIZE_24BIT + * @arg @ref LL_SSI_ADDRSIZE_28BIT + * @arg @ref LL_SSI_ADDRSIZE_32BIT + * @arg @ref LL_SSI_ADDRSIZE_36BIT + * @arg @ref LL_SSI_ADDRSIZE_40BIT + * @arg @ref LL_SSI_ADDRSIZE_44BIT + * @arg @ref LL_SSI_ADDRSIZE_48BIT + * @arg @ref LL_SSI_ADDRSIZE_52BIT + * @arg @ref LL_SSI_ADDRSIZE_56BIT + * @arg @ref LL_SSI_ADDRSIZE_60BIT + * @retval None + */ +__STATIC_INLINE void ll_spi_set_address_size(ssi_regs_t *SPIx, uint32_t size) +{ + MODIFY_REG(SPIx->SPI_CTRL0, SSI_SCTRL0_ADDRL, size); +} + +/** + * @brief Get Dual/Quad SPI mode address length in bits + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | ADDRL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_ADDRSIZE_0BIT + * @arg @ref LL_SSI_ADDRSIZE_4BIT + * @arg @ref LL_SSI_ADDRSIZE_8BIT + * @arg @ref LL_SSI_ADDRSIZE_12BIT + * @arg @ref LL_SSI_ADDRSIZE_16BIT + * @arg @ref LL_SSI_ADDRSIZE_20BIT + * @arg @ref LL_SSI_ADDRSIZE_24BIT + * @arg @ref LL_SSI_ADDRSIZE_28BIT + * @arg @ref LL_SSI_ADDRSIZE_32BIT + * @arg @ref LL_SSI_ADDRSIZE_36BIT + * @arg @ref LL_SSI_ADDRSIZE_40BIT + * @arg @ref LL_SSI_ADDRSIZE_44BIT + * @arg @ref LL_SSI_ADDRSIZE_48BIT + * @arg @ref LL_SSI_ADDRSIZE_52BIT + * @arg @ref LL_SSI_ADDRSIZE_56BIT + * @arg @ref LL_SSI_ADDRSIZE_60BIT + */ +__STATIC_INLINE uint32_t ll_spi_get_address_size(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->SPI_CTRL0, SSI_SCTRL0_ADDRL)); +} + +/** + * @brief Set Dual/Quad SPI mode address and instruction transfer format + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | TRANSTYPE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @param format This parameter can be one of the following values: + * @arg @ref LL_SSI_INST_ADDR_ALL_IN_SPI + * @arg @ref LL_SSI_INST_IN_SPI_ADDR_IN_SPIFRF + * @arg @ref LL_SSI_INST_ADDR_ALL_IN_SPIFRF + * @retval None + */ +__STATIC_INLINE void ll_spi_set_add_inst_transfer_format(ssi_regs_t *SPIx, uint32_t format) +{ + MODIFY_REG(SPIx->SPI_CTRL0, SSI_SCTRL0_TRANSTYPE, format); +} + +/** + * @brief Get Dual/Quad SPI mode address and instruction transfer format + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SCTRL0 | TRANSTYPE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param SPIx SPI instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SSI_INST_ADDR_ALL_IN_SPI + * @arg @ref LL_SSI_INST_IN_SPI_ADDR_IN_SPIFRF + * @arg @ref LL_SSI_INST_ADDR_ALL_IN_SPIFRF + */ +__STATIC_INLINE uint32_t ll_spi_get_addr_inst_transfer_format(ssi_regs_t *SPIx) +{ + return (uint32_t)(READ_BITS(SPIx->SPI_CTRL0, SSI_SCTRL0_TRANSTYPE)); +} + +/** @} */ + +/** @defgroup SPI_LL_EF_Init SPIM Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize SSI registers (Registers restored to their default values). + * @param SPIx SSI instance + * @retval An error_status_t enumeration value: + * - SUCCESS: SSI registers are de-initialized + * - ERROR: SSI registers are not de-initialized + */ +error_status_t ll_spim_deinit(ssi_regs_t *SPIx); + +/** + * @brief Initialize SPIM registers according to the specified + * parameters in p_spi_init. + * @param SPIx SSI instance + * @param p_spi_init Pointer to a ll_spim_init_t structure that contains the configuration + * information for the specified SPIM peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: SSI registers are initialized according to p_spi_init content + * - ERROR: Problem occurred during SSI Registers initialization + */ +error_status_t ll_spim_init(ssi_regs_t *SPIx, ll_spim_init_t *p_spi_init); + +/** + * @brief Set each field of a @ref ll_spim_init_t type structure to default value. + * @param p_spi_init Pointer to a @ref ll_spim_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_spim_struct_init(ll_spim_init_t *p_spi_init); + +/** @} */ + +/** @defgroup SPIS_LL_Init SPIS Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize SSI registers (Registers restored to their default values). + * @param SPIx SSI instance + * @retval An error_status_t enumeration value: + * - SUCCESS: SSI registers are de-initialized + * - ERROR: SSI registers are not de-initialized + */ +error_status_t ll_spis_deinit(ssi_regs_t *SPIx); + +/** + * @brief Initialize SSI registers according to the specified + * parameters in p_spi_init. + * @param SPIx SSI instance + * @param p_spi_init Pointer to a ll_spis_init_t structure that contains the configuration + * information for the specified SPIS peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: SSI registers are initialized according to p_spi_init content + * - ERROR: Problem occurred during SPI Registers initialization + */ +error_status_t ll_spis_init(ssi_regs_t *SPIx, ll_spis_init_t *p_spi_init); + +/** + * @brief Set each field of a @ref ll_spis_init_t type structure to default value. + * @param p_spi_init Pointer to a @ref ll_spis_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_spis_struct_init(ll_spis_init_t *p_spi_init); +/** @} */ + +/** @defgroup QSPI_LL_Init QSPI Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize SSI registers (Registers restored to their default values). + * @param SPIx SSI instance + * @retval An error_status_t enumeration value: + * - SUCCESS: SSI registers are de-initialized + * - ERROR: SSI registers are not de-initialized + */ +error_status_t ll_qspi_deinit(ssi_regs_t *SPIx); + +/** + * @brief Initialize SSI registers according to the specified + * parameters in SPI_InitStruct. + * @param SPIx SSI instance + * @param p_spi_init Pointer to a ll_qspi_init_t structure that contains the configuration + * information for the specified QSPI peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: SPI registers are initialized according to p_spi_init content + * - ERROR: Problem occurred during SPI Registers initialization + */ +error_status_t ll_qspi_init(ssi_regs_t *SPIx, ll_qspi_init_t *p_spi_init); + +/** + * @brief Set each field of a @ref ll_qspi_init_t type structure to default value. + * @param p_spi_init Pointer to a @ref ll_qspi_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_qspi_struct_init(ll_qspi_init_t *p_spi_init); + +/** @} */ + +/** @} */ + +#endif /* SPIM || SPIS || QSPI0 || QSPI1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_SPI_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_tim.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_tim.h new file mode 100644 index 0000000..2ecffe5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_tim.h @@ -0,0 +1,448 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_tim.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of TIMER LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_TIMER TIMER + * @brief TIMER LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_TIMER_H__ +#define __GR55XX_LL_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (TIMER0) || defined (TIMER1) + +/** @defgroup TIMER_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIMER_LL_ES_INIT TIMER Exported init structures + * @{ + */ + +/** + * @brief LL TIMER init Structure definition + */ +typedef struct _ll_timer_init_t +{ + uint32_t auto_reload; /**< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF. + Some timer instances may support 32 bits counters. In that case this parameter must be a number between 0x0000 and 0xFFFFFFFF. + + This feature can be modified afterwards using unitary function @ref ll_timer_set_auto_reload().*/ +} ll_timer_init_t; +/** @} */ + +/** @} */ + +/** + * @defgroup TIMER_LL_TIMER_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMER_LL_Exported_Constants TIMER Exported Constants + * @{ + */ + +/** @defgroup TIMER_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ +/** + * @brief LL TIMER InitStrcut default configuartion + */ +#define TIMER_DEFAULT_CONFIG \ +{ \ + .auto_reload = SystemCoreClock - 1, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMER_LL_Exported_Macros TIMER Exported Macros + * @{ + */ + +/** @defgroup TIMER_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in TIMER register + * @param __instance__ TIMER instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_TIMER_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in TIMER register + * @param __instance__ TIMER instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_TIMER_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIMER_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup TIMER_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable timer counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_timer_enable_counter(timer_regs_t *TIMERx) +{ + SET_BITS(TIMERx->CTRL, TIMER_CTRL_EN); +} + +/** + * @brief Disable timer counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_timer_disable_counter(timer_regs_t *TIMERx) +{ + CLEAR_BITS(TIMERx->CTRL, TIMER_CTRL_EN); +} + +/** + * @brief Indicate whether the timer counter is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_timer_is_enabled_counter(timer_regs_t *TIMERx) +{ + return (READ_BITS(TIMERx->CTRL, TIMER_CTRL_EN) == (TIMER_CTRL_EN)); +} + +/** + * @brief Set the counter value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | VALUE | VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @param counter Counter value (between Min_Data=0 and Max_Data=0xFFFFFFFF) + * @retval None + */ +__STATIC_INLINE void ll_timer_set_counter(timer_regs_t *TIMERx, uint32_t counter) +{ + WRITE_REG(TIMERx->VALUE, counter); +} + +/** + * @brief Get the counter value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | VALUE | VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFFFFFF) + */ +__STATIC_INLINE uint32_t ll_timer_get_counter(timer_regs_t *TIMERx) +{ + return (uint32_t)(READ_REG(TIMERx->VALUE)); +} + +/** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RELOAD | RELOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @param auto_reload between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_timer_set_auto_reload(timer_regs_t *TIMERx, uint32_t auto_reload) +{ + WRITE_REG(TIMERx->RELOAD, auto_reload); +} + +/** + * @brief Get the auto-reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RELOAD | RELOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t ll_timer_get_auto_reload(timer_regs_t *TIMERx) +{ + return (uint32_t)(READ_REG(TIMERx->RELOAD)); +} + +/** @} */ + +/** @defgroup TIM_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable timer interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_timer_enable_it(timer_regs_t *TIMERx) +{ + SET_BITS(TIMERx->CTRL, TIMER_CTRL_INTEN); +} + +/** + * @brief Disable timer interrput. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_timer_disable_it(timer_regs_t *TIMERx) +{ + CLEAR_BITS(TIMERx->CTRL, TIMER_CTRL_INTEN); +} + +/** + * @brief Indicate whether the timer interrput is enabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_timer_is_enabled_it(timer_regs_t *TIMERx) +{ + return (READ_BITS(TIMERx->CTRL, TIMER_CTRL_INTEN) == (TIMER_CTRL_INTEN)); +} + +/** @} */ + +/** @defgroup TIM_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Clear the interrupt flag (INTSTAT). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval None + */ +__STATIC_INLINE void ll_timer_clear_flag_it(timer_regs_t *TIMERx) +{ + WRITE_REG(TIMERx->INTSTAT, TIMER_INT_STAT); +} + +/** + * @brief Indicate whether interrupt flag (INTSTAT) is set (interrupt is pending). + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param TIMERx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_timer_is_active_flag_it(timer_regs_t *TIMERx) +{ + return (READ_BITS(TIMERx->INTSTAT, TIMER_INT_STAT) == (TIMER_INT_STAT)); +} + +/** @} */ + +/** @defgroup TIM_LL_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize TIMER registers (Registers restored to their default values). + * @param TIMERx TIMER instance + * @retval An error_status_t enumeration value: + * - SUCCESS: TIMER registers are de-initialized + * - ERROR: TIMER registers are not de-initialized + */ +error_status_t ll_timer_deinit(timer_regs_t *TIMERx); + +/** + * @brief Initialize TIMER registers according to the specified + * parameters in TIMER_InitStruct. + * @param TIMERx TIMER instance + * @param p_timer_init Pointer to a ll_timer_init_t structure that contains the configuration + * information for the specified TIM peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: TIMER registers are initialized according to p_timer_init content + * - ERROR: Problem occurred during TIMER Registers initialization + */ +error_status_t ll_timer_init(timer_regs_t *TIMERx, ll_timer_init_t *p_timer_init); + +/** + * @brief Set each field of a @ref ll_timer_init_t type structure to default value. + * @param p_timer_init Pointer to a @ref ll_timer_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_timer_struct_init(ll_timer_init_t *p_timer_init); + +/** @} */ + +/** @} */ + +#endif /* TIMER0 || TIMER1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_TIMER_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_uart.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_uart.h new file mode 100644 index 0000000..ca29095 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_uart.h @@ -0,0 +1,1621 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_uart.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of UART LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_UART UART + * @brief UART LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_UART_H__ +#define __GR55xx_LL_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (UART0) || defined (UART1) + +/** @defgroup UART_LL_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UART_LL_ES_INIT UART Exported init structures + * @{ + */ + +/** + * @brief LL UART init Structure definition + */ +typedef struct _ll_uart_init_t +{ + uint32_t baud_rate; /**< This field defines expected Usart communication baud rate. + + This feature can be modified afterwards using unitary function @ref ll_uart_set_baud_rate().*/ + + uint32_t data_bits; /**< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref UART_LL_EC_DATABITS. + + This feature can be modified afterwards using unitary function @ref ll_uart_set_data_bits_length().*/ + + uint32_t stop_bits; /**< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_LL_EC_STOPBITS. + + This feature can be modified afterwards using unitary function @ref ll_uart_set_stop_bits_length().*/ + + uint32_t parity; /**< Specifies the parity mode. + This parameter can be a value of @ref UART_LL_EC_PARITY. + + This feature can be modified afterwards using unitary function @ref ll_uart_set_parity().*/ + + uint32_t hw_flow_ctrl; /**< Specifies whether the hardware flow control mode is enabled or disabled. + This parameter can be a value of @ref UART_LL_EC_HWCONTROL. + + This feature can be modified afterwards using unitary function @ref ll_uart_set_hw_flow_ctrl().*/ +} ll_uart_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup UART_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UART_LL_Exported_Constants UART Exported Constants + * @{ + */ + +/** @defgroup UART_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags definitions which can be used with LL_UART_ReadReg function + * @{ + */ +#define LL_UART_LSR_OE UART_LSR_OE /**< Overrun error flag */ +#define LL_UART_LSR_PE UART_LSR_PE /**< Parity error flag */ +#define LL_UART_LSR_FE UART_LSR_FE /**< Framing error flag */ +#define LL_UART_LSR_BI UART_LSR_BI /**< Break detection flag */ +#define LL_UART_LSR_THRE UART_LSR_THRE /**< Transmit holding register empty flag */ +#define LL_UART_LSR_TEMT UART_LSR_TEMT /**< Transmitter empty flag */ +#define LL_UART_LSR_RFE UART_LSR_RFE /**< Rx FIFO error flag */ + +#define LL_UART_IIR_MS UART_IIR_IID_MS /**< Modem Status flag */ +#define LL_UART_IIR_NIP UART_IIR_IID_NIP /**< No Interrupt Pending flag */ +#define LL_UART_IIR_THRE UART_IIR_IID_THRE /**< THR Empty flag */ +#define LL_UART_IIR_RDA UART_IIR_IID_RDA /**< Received Data Available flag */ +#define LL_UART_IIR_RLS UART_IIR_IID_RLS /**< Receiver Line Status flag */ +#define LL_UART_IIR_CTO UART_IIR_IID_CTO /**< Character Timeout flag */ + +#define LL_UART_USR_RFF UART_USR_RFF /**< Rx FIFO Full flag */ +#define LL_UART_USR_RFNE UART_USR_RFNE /**< Rx FIFO Not Empty flag */ +#define LL_UART_USR_TFE UART_USR_TFE /**< Tx FIFO Empty flag */ +#define LL_UART_USR_TFNF UART_USR_TFNF /**< Tx FIFO Not Full flag */ +/** @} */ + +/** @defgroup UART_LL_EC_IT IT Defines + * @brief Interrupt definitions which can be used with LL_UART_ReadReg and LL_UART_WriteReg functions + * @{ + */ +#define LL_UART_IER_MS UART_IER_EDSSI /**< Enable Modem Status Interrupt */ +#define LL_UART_IER_RLS UART_IER_ERLS /**< Enable Receiver Line Status Interrupt */ +#define LL_UART_IER_THRE (UART_IER_ETBEI | UART_IER_PTIME) /**< Enable Transmit Holding Register Empty Interrupt */ +#define LL_UART_IER_RDA UART_IER_ERBFI /**< Enable Received Data Available Interrupt and Character Timeout Interrupt */ +/** @} */ + +/** @defgroup UART_LL_EC_PARITY Parity Control + * @{ + */ +#define LL_UART_PARITY_NONE UART_LCR_PARITY_NONE /**< Parity control disabled */ +#define LL_UART_PARITY_ODD UART_LCR_PARITY_ODD /**< Parity control enabled and Odd Parity is selected */ +#define LL_UART_PARITY_EVEN UART_LCR_PARITY_EVEN /**< Parity control enabled and Even Parity is selected */ +#define LL_UART_PARITY_SP0 UART_LCR_PARITY_SP0 /**< Parity control enabled and Stick Parity 0 is selected */ +#define LL_UART_PARITY_SP1 UART_LCR_PARITY_SP1 /**< Parity control enabled and Stick Parity 1 is selected */ +/** @} */ + +/** @defgroup UART_LL_EC_DATABITS Data Bits + * @{ + */ +#define LL_UART_DATABITS_5B UART_LCR_DLS_5 /**< 5 bits word length : Start bit, 5 data bits, n stop bits */ +#define LL_UART_DATABITS_6B UART_LCR_DLS_6 /**< 6 bits word length : Start bit, 6 data bits, n stop bits */ +#define LL_UART_DATABITS_7B UART_LCR_DLS_7 /**< 7 bits word length : Start bit, 7 data bits, n stop bits */ +#define LL_UART_DATABITS_8B UART_LCR_DLS_8 /**< 8 bits word length : Start bit, 8 data bits, n stop bits */ +/** @} */ + +/** @defgroup UART_LL_EC_STOPBITS Stop Bits + * @{ + */ +#define LL_UART_STOPBITS_1 UART_LCR_STOP_1 /**< 1 stop bit */ +#define LL_UART_STOPBITS_1_5 UART_LCR_STOP_1_5 /**< 1.5 stop bits */ +#define LL_UART_STOPBITS_2 UART_LCR_STOP_2 /**< 2 stop bits */ +/** @} */ + +/** @defgroup UART_LL_EC_HWCONTROL Hardware Flow Control + * @{ + */ +#define LL_UART_HWCONTROL_NONE 0x00000000U /**< CTS and RTS hardware flow control disabled */ +#define LL_UART_HWCONTROL_RTS_CTS (UART_MCR_AFCE | UART_MCR_RTS) /**< CTS and RTS hardware flow control enabled */ +/** @} */ + +/** @defgroup UART_LL_EC_TX_FIFO_TH TX FIFO Threshold + * @{ + */ +#define LL_UART_TX_FIFO_TH_EMPTY 0x00000000U /**< TX FIFO empty */ +#define LL_UART_TX_FIFO_TH_CHAR_2 0x00000001U /**< 2 characters in TX FIFO */ +#define LL_UART_TX_FIFO_TH_QUARTER_FULL 0x00000002U /**< TX FIFO 1/4 full */ +#define LL_UART_TX_FIFO_TH_HALF_FULL 0x00000003U /**< TX FIFO 1/2 full */ +/** @} */ + +/** @defgroup UART_LL_EC_RX_FIFO_TH RX FIFO Threshold + * @{ + */ +#define LL_UART_RX_FIFO_TH_CHAR_1 0x00000000U /**< 1 character in RX FIFO */ +#define LL_UART_RX_FIFO_TH_QUARTER_FULL 0x00000001U /**< RX FIFO 1/4 full */ +#define LL_UART_RX_FIFO_TH_HALF_FULL 0x00000002U /**< RX FIFO 1/2 full */ +#define LL_UART_RX_FIFO_TH_FULL_2 0x00000003U /**< RX FIFO 2 less than full */ +/** @} */ + +/** @defgroup UART_LL_EC_RTSPIN_STATE RTS Pin State + * @{ + */ +#define LL_UART_RTSPIN_STATE_ACTIVE 0x00000001U /**< RTS pin active(Logic 1) */ +#define LL_UART_RTSPIN_STATE_INACTIVE 0x00000000U /**< RTS pin inactive(Logic 0) */ +/** @} */ + +/** @defgroup UART_LL_EC_CTSPIN_STATE CTS Pin State + * @{ + */ +#define LL_UART_CTSPIN_STATE_ACTIVE 0x00000001U /**< CTS pin active(Logic 1) */ +#define LL_UART_CTSPIN_STATE_INACTIVE 0x00000000U /**< CTS pin pin inactive(Logic 0) */ +/** @} */ + +/** @defgroup UART_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL UART InitStrcut default configuartion + */ +#define LL_UART_DEFAULT_CONFIG \ +{ \ + .baud_rate = 9600U, \ + .data_bits = LL_UART_DATABITS_8B, \ + .stop_bits = LL_UART_STOPBITS_1, \ + .parity = LL_UART_PARITY_NONE, \ + .hw_flow_ctrl = LL_UART_HWCONTROL_NONE, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup UART_LL_Exported_Macros UART Exported Macros + * @{ + */ + +/** @defgroup UART_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in UART register + * @param __instance__ UART instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_UART_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in UART register + * @param __instance__ UART instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_UART_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @defgroup UART_LL_EM_Exported_Macros_Helper Exported_Macros_Helper + * @{ + */ + +/** + * @brief Compute UARTDIV value according to Peripheral Clock and + * expected Baud Rate (32 bits value of UARTDIV is returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for UART instance + * @param __BAUDRATE__ Baud rate value to achieve + * @retval UARTDIV value to be used for DLL,DLH registers + */ +#define __LL_UART_DIV(__PERIPHCLK__, __BAUDRATE__) ((__PERIPHCLK__) / (__BAUDRATE__) / 16) + +/** + * @brief Compute UARTDLF value according to Peripheral Clock and + * expected Baud Rate (32 bits value of UARTDLF is returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for UART instance + * @param __BAUDRATE__ Baud rate value to achieve + * @retval UARTDLF value to be used for DLL,DLH registers + */ +#define __LL_UART_DLF(__PERIPHCLK__, __BAUDRATE__) ((__PERIPHCLK__) / (__BAUDRATE__) % 16) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup UART_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup UART_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Configure UART DLF and DLH register for achieving expected Baud Rate value. + * @note Peripheral clock and Baud rate values provided as function parameters should be valid + * (Baud rate value != 0) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DLL | DLL | + * +----------------------+-----------------------------------+ + * \endrst + * DLH | DLH + * + * @param UARTx UART instance + * @param peripheral_clock Peripheral Clock + * @param baud_rate Baud Rate + * @retval None + */ +__STATIC_INLINE void ll_uart_set_baud_rate(uart_regs_t *UARTx, uint32_t peripheral_clock, uint32_t baud_rate) +{ + register uint32_t uartdiv = __LL_UART_DIV(peripheral_clock, baud_rate); + + SET_BITS(UARTx->LCR, UART_LCR_DLAB); + WRITE_REG(UARTx->RBR_DLL_THR.DLL, uartdiv & UART_DLL_DLL); + WRITE_REG(UARTx->DLH_IER.DLH, (uartdiv >> 8) & UART_DLH_DLH); + CLEAR_BITS(UARTx->LCR, UART_LCR_DLAB); + WRITE_REG(UARTx->DLF, __LL_UART_DLF(peripheral_clock, baud_rate)); +} + +/** + * @brief Return current Baud Rate value + * @note In case of non-initialized or invalid value stored in DLL,DLH and DLF register, the value 0 will be returned.. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | DLL | DLL | + * +----------------------+-----------------------------------+ + * \endrst + * DLH | DLH + * + * @param UARTx UART instance + * @param peripheral_clock Peripheral Clock + * @retval Baud Rate + */ +__STATIC_INLINE uint32_t ll_uart_get_baud_rate(uart_regs_t *UARTx, uint32_t peripheral_clock) +{ + register uint32_t uartdiv = 0x0U; + register uint32_t baud = 0x0U; + + SET_BITS(UARTx->LCR, UART_LCR_DLAB); + uartdiv = UARTx->RBR_DLL_THR.DLL | (UARTx->DLH_IER.DLH << 8); + CLEAR_BITS(UARTx->LCR, UART_LCR_DLAB); + + if ((uartdiv != 0) && (UARTx->DLF != 0x0U)) + { + baud = peripheral_clock / (16 * uartdiv + UARTx->DLF); + } + + return baud; +} + +/** + * @brief Set the length of the data bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | DLS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @param data_bits This parameter can be one of the following values: + * @arg @ref LL_UART_DATABITS_5B + * @arg @ref LL_UART_DATABITS_6B + * @arg @ref LL_UART_DATABITS_7B + * @arg @ref LL_UART_DATABITS_8B + * + * @retval None + */ +__STATIC_INLINE void ll_uart_set_data_bits_length(uart_regs_t *UARTx, uint32_t data_bits) +{ + MODIFY_REG(UARTx->LCR, UART_LCR_DLS, data_bits); +} + +/** + * @brief Return the length of the data bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | DLS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_DATABITS_5B + * @arg @ref LL_UART_DATABITS_6B + * @arg @ref LL_UART_DATABITS_7B + * @arg @ref LL_UART_DATABITS_8B + */ +__STATIC_INLINE uint32_t ll_uart_get_data_bits_length(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->LCR, UART_LCR_DLS)); +} + +/** + * @brief Set the length of the stop bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | STOP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @param stop_bits This parameter can be one of the following values: + * @arg @ref LL_UART_STOPBITS_1 + * @arg @ref LL_UART_STOPBITS_1_5 (*) + * @arg @ref LL_UART_STOPBITS_2 (*) + * + * (*) STOPBITS_1_5 only valid when DataBits = 5 + * (*) STOPBITS_2 is invalid when DataBits = 5 + * @retval None + */ +__STATIC_INLINE void ll_uart_set_stop_bits_length(uart_regs_t *UARTx, uint32_t stop_bits) +{ + MODIFY_REG(UARTx->LCR, UART_LCR_STOP, stop_bits); +} + +/** + * @brief Retrieve the length of the stop bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | STOP | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_STOPBITS_1 + * @arg @ref LL_UART_STOPBITS_1_5 + * @arg @ref LL_UART_STOPBITS_2 + */ +__STATIC_INLINE uint32_t ll_uart_get_stop_bits_length(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->LCR, UART_LCR_STOP)); +} + +/** + * @brief Configure Parity. + * @note This function selects if hardware parity control (generation and detection) is enabled or disabled. + * When the parity control is enabled (Odd,Even,0,1), computed parity bit is inserted at the MSB position + * and parity is checked on the received data. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | SP | + * +----------------------+-----------------------------------+ + * \endrst + * LCR | EPS + * LCR | PEN + * + * @param UARTx UART instance + * @param parity This parameter can be one of the following values: + * @arg @ref LL_UART_PARITY_NONE + * @arg @ref LL_UART_PARITY_EVEN + * @arg @ref LL_UART_PARITY_ODD + * @arg @ref LL_UART_PARITY_SP0 + * @arg @ref LL_UART_PARITY_SP1 + * @retval None + */ +__STATIC_INLINE void ll_uart_set_parity(uart_regs_t *UARTx, uint32_t parity) +{ + MODIFY_REG(UARTx->LCR, UART_LCR_PARITY, parity); +} + +/** + * @brief Return Parity configuration + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | SP | + * +----------------------+-----------------------------------+ + * \endrst + * LCR | EPS + * LCR | PEN + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_PARITY_NONE + * @arg @ref LL_UART_PARITY_EVEN + * @arg @ref LL_UART_PARITY_ODD + * @arg @ref LL_UART_PARITY_SP0 + * @arg @ref LL_UART_PARITY_SP1 + */ +__STATIC_INLINE uint32_t ll_uart_get_parity(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->LCR, UART_LCR_PARITY)); +} + +/** + * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) + * @note This function call is equivalent to the following function call sequence : + * - Data Width configuration using @ref ll_uart_set_data_bits_length() function + * - Parity Control and mode configuration using @ref ll_uart_set_parity() function + * - Stop bits configuration using @ref ll_uart_set_stop_bits_length() function + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | PS | + * +----------------------+-----------------------------------+ + * \endrst + * LCR | EPS + * LCR | PEN + * LCR | STOP + * LCR | DLS + * + * @param UARTx UART instance + * @param data_bits This parameter can be one of the following values: + * @arg @ref LL_UART_DATABITS_5B + * @arg @ref LL_UART_DATABITS_6B + * @arg @ref LL_UART_DATABITS_7B + * @arg @ref LL_UART_DATABITS_8B + * @param parity This parameter can be one of the following values: + * @arg @ref LL_UART_PARITY_NONE + * @arg @ref LL_UART_PARITY_EVEN + * @arg @ref LL_UART_PARITY_ODD + * @arg @ref LL_UART_PARITY_SP0 + * @arg @ref LL_UART_PARITY_SP1 + * @param stop_bits This parameter can be one of the following values: + * @arg @ref LL_UART_STOPBITS_1 + * @arg @ref LL_UART_STOPBITS_1_5 (*) + * @arg @ref LL_UART_STOPBITS_2 (*) + * + * (*) STOPBITS_1_5 only valid when DataBits = 5 + * (*) STOPBITS_2 is invalid when DataBits = 5 + * @retval None + */ +__STATIC_INLINE void ll_uart_config_character(uart_regs_t *UARTx, + uint32_t data_bits, + uint32_t parity, + uint32_t stop_bits) +{ + MODIFY_REG(UARTx->LCR, UART_LCR_PARITY | UART_LCR_STOP | UART_LCR_DLS, parity | stop_bits | data_bits); +} + +/** + * @brief Set UART RTS pin state to Active/Inactive + * @note The RTS pin is ACTIVE when logic level is low, and INACTIVE when logic level is high. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRTS | SRTS | + * +----------------------+-----------------------------------+ + * \endrst + * MCR | RTS + * + * @param UARTx UART instance + * @param pin_state This parameter can be one of the following values: + * @arg @ref LL_UART_RTSPIN_STATE_ACTIVE + * @arg @ref LL_UART_RTSPIN_STATE_INACTIVE + * @retval None + */ +__STATIC_INLINE void ll_uart_set_rts_pin_state(uart_regs_t *UARTx, uint32_t pin_state) +{ + WRITE_REG(UARTx->SRTS, pin_state); +} + +/** + * @brief Get UART RTS pin state + * @note The RTS pin is ACTIVE when logic level is low, and INACTIVE when logic level is high. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRTS | SRTS | + * +----------------------+-----------------------------------+ + * \endrst + * MCR | RTS + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_RTSPIN_STATE_ACTIVE + * @arg @ref LL_UART_RTSPIN_STATE_INACTIVE + */ +__STATIC_INLINE uint32_t ll_uart_get_rts_pin_state(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_REG(UARTx->SRTS)); +} + +/** + * @brief Get UART CTS pin state + * @note The CTS pin is ACTIVE when logic level is low, and INACTIVE when logic level is high. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSR | CTS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_CTSPIN_STATE_ACTIVE + * @arg @ref LL_UART_CTSPIN_STATE_INACTIVE + */ +__STATIC_INLINE uint32_t ll_uart_get_cts_pin_state(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->MSR, UART_MSR_CTS) >> UART_MSR_CTS_Pos); +} + +/** + * @brief Indicate if CTS is changed since the last time the MSR was read + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSR | DCTS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_changed_cts(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->MSR, UART_MSR_DCTS) >> UART_MSR_DCTS_Pos); +} + +/** + * @brief Configure HW Flow Control mode (None or Both CTS and RTS) + * @note This function is used to Enable/Disable UART Auto Flow Control. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MCR | AFCE | + * +----------------------+-----------------------------------+ + * \endrst + * MCR | RTS + * + * @param UARTx UART instance + * @param hw_flow_ctrl This parameter can be one of the following values: + * @arg @ref LL_UART_HWCONTROL_NONE + * @arg @ref LL_UART_HWCONTROL_RTS_CTS + * @retval None + */ +__STATIC_INLINE void ll_uart_set_hw_flow_ctrl(uart_regs_t *UARTx, uint32_t hw_flow_ctrl) +{ + MODIFY_REG(UARTx->MCR, UART_MCR_AFCE | UART_MCR_RTS, hw_flow_ctrl); +} + +/** + * @brief Return HW Flow Control configuration (None or Both CTS and RTS) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MCR | AFCE | + * +----------------------+-----------------------------------+ + * \endrst + * MCR | RTS + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_HWCONTROL_NONE + * @arg @ref LL_UART_HWCONTROL_RTS_CTS + */ +__STATIC_INLINE uint32_t ll_uart_get_hw_flow_ctrl(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->MCR, UART_MCR_AFCE | UART_MCR_RTS)); +} + +/** + * @brief Enable Break sending + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | BC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_break_sending(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SBCR, 0x1U); +} + +/** + * @brief Disable Break sending + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | BC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_break_sending(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SBCR, 0x0U); +} + +/** + * @brief Indicate if Break sending is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LCR | BC | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_break_sending(uart_regs_t *UARTx) +{ + return READ_REG(UARTx->SBCR); +} + +/** + * @brief Enable TX FIFO and RX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SFE | SFE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_fifo(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SFE, 0x1U); +} + +/** + * @brief Disable TX FIFO and RX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SFE | SFE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_fifo(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SFE, 0x0U); +} + +/** + * @brief Indicate if TX FIFO and RX FIFO is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SFE | SFE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_fifo(uart_regs_t *UARTx) +{ + return READ_REG(UARTx->SFE); +} + +/** + * @brief Set threshold of TX FIFO that triggers an THRE interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STET | STET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_UART_TX_FIFO_TH_EMPTY + * @arg @ref LL_UART_TX_FIFO_TH_CHAR_2 + * @arg @ref LL_UART_TX_FIFO_TH_QUARTER_FULL + * @arg @ref LL_UART_TX_FIFO_TH_HALF_FULL + * @retval None + */ +__STATIC_INLINE void ll_uart_set_tx_fifo_threshold(uart_regs_t *UARTx, uint32_t threshold) +{ + WRITE_REG(UARTx->STET, threshold); +} + +/** + * @brief Get threshold of TX FIFO that triggers an THRE interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STET | STET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_TX_FIFO_TH_EMPTY + * @arg @ref LL_UART_TX_FIFO_TH_CHAR_2 + * @arg @ref LL_UART_TX_FIFO_TH_QUARTER_FULL + * @arg @ref LL_UART_TX_FIFO_TH_HALF_FULL + */ +__STATIC_INLINE uint32_t ll_uart_get_tx_fifo_threshold(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_REG(UARTx->STET)); +} + +/** + * @brief Set threshold of RX FIFO that triggers an RDA interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRT | SRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_UART_RX_FIFO_TH_CHAR_1 + * @arg @ref LL_UART_RX_FIFO_TH_QUARTER_FULL + * @arg @ref LL_UART_RX_FIFO_TH_HALF_FULL + * @arg @ref LL_UART_RX_FIFO_TH_FULL_2 + * @retval None + */ +__STATIC_INLINE void ll_uart_set_rx_fifo_threshold(uart_regs_t *UARTx, uint32_t threshold) +{ + WRITE_REG(UARTx->SRT, threshold); +} + +/** + * @brief Get threshold of RX FIFO that triggers an RDA interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRT | SRT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UART_RX_FIFO_TH_CHAR_1 + * @arg @ref LL_UART_RX_FIFO_TH_QUARTER_FULL + * @arg @ref LL_UART_RX_FIFO_TH_HALF_FULL + * @arg @ref LL_UART_RX_FIFO_TH_FULL_2 + */ +__STATIC_INLINE uint32_t ll_uart_get_rx_fifo_threshold(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_REG(UARTx->SRT)); +} + +/** + * @brief Get FIFO Transmission Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TFL | TFL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + */ +__STATIC_INLINE uint32_t ll_uart_get_tx_fifo_level(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_REG(UARTx->TFL)); +} + +/** + * @brief Get FIFO reception Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RFL | RFL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one of the following values: + */ +__STATIC_INLINE uint32_t ll_uart_get_rx_fifo_level(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_REG(UARTx->RFL)); +} + +/** + * @brief Flush Receive FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRR | RFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_flush_rx_fifo(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SRR, UART_SRR_RFR); +} + +/** + * @brief Flush Transmit FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRR | XFR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_flush_tx_fifo(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SRR, UART_SRR_XFR); +} + +/** + * @brief Reset UART + * @note This function asynchronously resets the DW_apb_uart and synchronously + * removes the reset assertion. For a two clock implementation, both pclk + * and sclk domains will be reset. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SRR | UR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_reset(uart_regs_t *UARTx) +{ + WRITE_REG(UARTx->SRR, UART_SRR_UR); +} + +/** @} */ + +/** @defgroup UART_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Modem Status Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enabled_it_ms(uart_regs_t *UARTx) +{ + SET_BITS(UARTx->DLH_IER.IER, UART_IER_EDSSI); +} + +/** + * @brief Enable Receiver Line Status Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | RLS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_it_rls(uart_regs_t *UARTx) +{ + SET_BITS(UARTx->DLH_IER.IER, UART_IER_ERLS); +} + +/** + * @brief Enable Transmit Holding Register Empty Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | PTIME | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ETBEI + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_it_thre(uart_regs_t *UARTx) +{ + SET_BITS(UARTx->DLH_IER.IER, UART_IER_PTIME | UART_IER_ETBEI); +} + +/** + * @brief Enable Received Data Available Interrupt and Character Timeout Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | ERBFI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_it_rda(uart_regs_t *UARTx) +{ + SET_BITS(UARTx->DLH_IER.IER, UART_IER_ERBFI); +} + +/** + * @brief Disable Modem Status Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_it_ms(uart_regs_t *UARTx) +{ + CLEAR_BITS(UARTx->DLH_IER.IER, UART_IER_EDSSI); +} + +/** + * @brief Disable Receiver Line Status Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | RLS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_it_rls(uart_regs_t *UARTx) +{ + CLEAR_BITS(UARTx->DLH_IER.IER, UART_IER_ERLS); +} + +/** + * @brief Disable Transmit Holding Register Empty Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | PTIME | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ETBEI + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_it_thre(uart_regs_t *UARTx) +{ + CLEAR_BITS(UARTx->DLH_IER.IER, UART_IER_PTIME | UART_IER_ETBEI); +} + +/** + * @brief Disable Received Data Available Interrupt and Character Timeout Interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | ERBFI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_it_rda(uart_regs_t *UARTx) +{ + CLEAR_BITS(UARTx->DLH_IER.IER, UART_IER_ERBFI); +} + +/** + * @brief Check if the UART Modem Status Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_it_ms(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->DLH_IER.IER, UART_IER_EDSSI) == (UART_IER_EDSSI)); +} + +/** + * @brief Check if the UART Receiver Line Status Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | RLS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_it_rls(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->DLH_IER.IER, UART_IER_ERLS) == (UART_IER_ERLS)); +} + +/** + * @brief Check if the UART Transmit Holding Register Empty Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | PTIME | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ETBEI + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_it_thre(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->DLH_IER.IER, UART_IER_PTIME | UART_IER_ETBEI) == (UART_IER_PTIME | UART_IER_ETBEI)); +} + +/** + * @brief Check if the UART Received Data Available Interrupt and Character Timeout Interrupt + * is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | ERBFI | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_it_rda(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->DLH_IER.IER, UART_IER_ERBFI) == (UART_IER_ERBFI)); +} + +/** + * @brief Enable the specified UART Interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ERLS + * IER | PTIME + * IER | ETBEI + * IER | ERBFI + * + * @param UARTx UART instance + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_UART_IER_MS + * @arg @ref LL_UART_IER_RLS + * @arg @ref LL_UART_IER_THRE + * @arg @ref LL_UART_IER_RDA + * @retval None + */ +__STATIC_INLINE void ll_uart_enable_it(uart_regs_t *UARTx, uint32_t mask) +{ + SET_BITS(UARTx->DLH_IER.IER, mask); +} + +/** + * @brief Disable the specified UART Interrupt. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ERLS + * IER | PTIME + * IER | ETBEI + * IER | ERBFI + * + * @param UARTx UART instance + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_UART_IER_MS + * @arg @ref LL_UART_IER_RLS + * @arg @ref LL_UART_IER_THRE + * @arg @ref LL_UART_IER_RDA + * @retval None + */ +__STATIC_INLINE void ll_uart_disable_it(uart_regs_t *UARTx, uint32_t mask) +{ + CLEAR_BITS(UARTx->DLH_IER.IER, mask); +} + +/** + * @brief Check if the specified UART Interrupt is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IER | EDSSI | + * +----------------------+-----------------------------------+ + * \endrst + * IER | ERLS + * IER | PTIME + * IER | ETBEI + * IER | ERBFI + * + * @param UARTx UART instance + * @param mask This parameter can be a combination of the following values: + * @arg @ref LL_UART_IER_MS + * @arg @ref LL_UART_IER_RLS + * @arg @ref LL_UART_IER_THRE + * @arg @ref LL_UART_IER_RDA + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_enabled_it(uart_regs_t *UARTx, uint32_t mask) +{ + return (READ_BITS(UARTx->DLH_IER.IER, mask) == (mask)); +} + +/** @} */ + +/** @defgroup UART_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Get UART Receive Line Status Flag + * @note This function is used to get OE/PE/FE/BI/THRE/TEMT/RFE flags in LSR register. + * After LSR register was read, OE/PE/FE/BI/RFE flags will be cleared. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LSR | OE | + * +----------------------+-----------------------------------+ + * \endrst + * LSR | PE + * LSR | FE + * LSR | BI + * LSR | THRE + * LSR | TEMT + * LSR | RFE + * + * @param UARTx UART instance + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_UART_LSR_OE + * @arg @ref LL_UART_LSR_PE + * @arg @ref LL_UART_LSR_FE + * @arg @ref LL_UART_LSR_BI + * @arg @ref LL_UART_LSR_THRE + * @arg @ref LL_UART_LSR_TEMT + * @arg @ref LL_UART_LSR_RFE + */ +__STATIC_INLINE uint32_t ll_uart_get_line_status_flag(uart_regs_t *UARTx) +{ + return ((uint32_t)READ_REG(UARTx->LSR)); +} + +/** + * @brief Clear UART Receive Line Status Flag + * @note OE/PE/FE/BI/RFE flags can be cleared by reading LSR register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LSR | OE | + * +----------------------+-----------------------------------+ + * \endrst + * LSR | PE + * LSR | FE + * LSR | BI + * LSR | RFE + * + * @param UARTx UART instance + * @retval None + */ +__STATIC_INLINE void ll_uart_clear_line_status_flag(uart_regs_t *UARTx) +{ + __IO uint32_t tmpreg; + tmpreg = READ_REG(UARTx->LSR); + (void) tmpreg; +} + +/** + * @brief Check if the UART Receive FIFO Full Flag is set or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USR | RFF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_active_flag_rff(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->USR, UART_USR_RFF) == UART_USR_RFF); +} + +/** + * @brief Check if the UART Receive FIFO Not Empty Flag is set or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USR | RFNE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_active_flag_rfne(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->USR, UART_USR_RFNE) == UART_USR_RFNE); +} + +/** + * @brief Check if the UART Transmit FIFO Empty Flag is set or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USR | TFE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_active_flag_tfe(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->USR, UART_USR_TFE) == UART_USR_TFE); +} + +/** + * @brief Check if the UART Transmit FIFO Not Full Flag is set or not + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | USR | TFNF | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_uart_is_active_flag_tfnf(uart_regs_t *UARTx) +{ + return (READ_BITS(UARTx->USR, UART_USR_TFNF) == UART_USR_TFNF); +} + +/** + * @brief Get UART interrupt flags + * @note The interrupt flags will be cleared after reading IIR. + * If interrupt was triggered when reading IIR register, the interrupt will be pended, + * and No Interrupt Pending Flag will be RESET, read IIR again can get the pended interrupt + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | IIR | IID | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Returned value can be one or combination of the following values: + * @arg @ref LL_UART_IIR_MS + * @arg @ref LL_UART_IIR_NIP + * @arg @ref LL_UART_IIR_THRE + * @arg @ref LL_UART_IIR_RDA + * @arg @ref LL_UART_IIR_RLS + * @arg @ref LL_UART_IIR_CTO + */ +__STATIC_INLINE uint32_t ll_uart_get_it_flag(uart_regs_t *UARTx) +{ + return (uint32_t)(READ_BITS(UARTx->FCR_IIR.IIR, UART_IIR_IID)); +} + +/** @} */ + +/** @defgroup UART_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Get the data register address used for DMA transfer + * @note The address of data register RBR is the same as the address of THR. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RBR | RBR | + * +----------------------+-----------------------------------+ + * \endrst + * THR | THR + * + * @param UARTx UART instance + * @retval Address of data register + */ +__STATIC_INLINE uint32_t ll_uart_dma_get_register_address(uart_regs_t *UARTx) +{ + return ((uint32_t) &(UARTx->RBR_DLL_THR)); +} + +/** @} */ + +/** @defgroup UART_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Read Receiver Data register (Receive Data value, 8 bits) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RBR | RBR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t ll_uart_receive_data8(uart_regs_t *UARTx) +{ + return (uint8_t)(READ_REG(UARTx->RBR_DLL_THR.RBR)); +} + +/** + * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | THR | THR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param UARTx UART instance + * @param value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void ll_uart_transmit_data8(uart_regs_t *UARTx, uint8_t value) +{ + WRITE_REG(UARTx->RBR_DLL_THR.THR, value); +} + +/** @} */ + +/** @defgroup UART_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize UART registers (Registers restored to their default values). + * @param UARTx UART instance + * @retval An error_status_t enumeration value: + * - SUCCESS: UART registers are de-initialized + * - ERROR: UART registers are not de-initialized + */ +error_status_t ll_uart_deinit(uart_regs_t *UARTx); + +/** + * @brief Initialize UART registers according to the specified + * parameters in p_uart_init. + * @param UARTx UART instance + * @param p_uart_init Pointer to a ll_uart_init_t structure that contains the configuration + * information for the specified UART peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: UART registers are initialized according to p_uart_init content + * - ERROR: Problem occurred during UART Registers initialization + */ +error_status_t ll_uart_init(uart_regs_t *UARTx, ll_uart_init_t *p_uart_init); + +/** + * @brief Set each field of a @ref ll_uart_init_t type structure to default value. + * @param p_uart_init Pointer to a @ref ll_uart_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_uart_struct_init(ll_uart_init_t *p_uart_init); + +/** @} */ + +/** @} */ + +#endif /* UART0 || UART1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_UART_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_wdt.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_wdt.h new file mode 100644 index 0000000..301731e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_wdt.h @@ -0,0 +1,415 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_wdt.h + * @author BLE Driver Team + * @brief Header file containing functions prototypes of WDT LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_WDT WDT + * @brief WDT LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55XX_LL_WDT_H__ +#define __GR55XX_LL_WDT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (WDT) + +/** + * @defgroup WDT_LL_MACRO Defines + * @{ + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup WDT_LL_Private_Constants WDT Private Constants + * @{ + */ + +/** @defgroup WDT_LL_PC_WR_ACCESS Write Access Defines + * @{ + */ +#define LL_WDT_LOCK_WR_ACCESS_ENABLE 0x1ACCE551 /**< WDT LOCK Write Access Enable */ +#define LL_WDT_LOCK_WR_ACCESS_DISABLE (~0x1ACCE551) /**< WDT LOCK Write Access Disable */ +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup WDT_LL_Exported_Macros WDT Exported Macros + * @{ + */ + +/** @defgroup WDT_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in WDT register + * @param __instance__ WDT instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_WDT_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in WDT register + * @param __instance__ WDT instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_WDT_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup WDT_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup WDT_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief Enable write access to WDT_LOAD, WDT_CTRL and WDT_INTCLR registers. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LOCK | ENRW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @retval None + */ +__STATIC_INLINE void ll_wdt_enable_write_access(wdt_regs_t *WDTx) +{ + WRITE_REG(WDTx->LOCK, LL_WDT_LOCK_WR_ACCESS_ENABLE); +} + +/** + * @brief Disable write access to WDT_LOAD, WDT_CTRL and WDT_INTCLR registers. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LOCK | ENRW | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @retval None + */ +__STATIC_INLINE void ll_wdt_disable_write_access(wdt_regs_t *WDTx) +{ + WRITE_REG(WDTx->LOCK, LL_WDT_LOCK_WR_ACCESS_DISABLE); +} + +/** + * @brief Enable watchdog counter and interrupt event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval None + */ +__STATIC_INLINE void ll_wdt_enable(wdt_regs_t *WDTx) +{ + SET_BITS(WDTx->CTRL, WDT_CTRL_INTEN); +} + +/** + * @brief Disable watchdog counter and interrupt event. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval None + */ +__STATIC_INLINE void ll_wdt_disable(wdt_regs_t *WDTx) +{ + CLEAR_BITS(WDTx->CTRL, WDT_CTRL_INTEN); +} + +/** + * @brief Check if the WDT peripheral is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | INTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_wdt_is_enabled(wdt_regs_t *WDTx) +{ + return (READ_BITS(WDTx->CTRL, WDT_CTRL_INTEN) == (WDT_CTRL_INTEN)); +} + +/** + * @brief Enable reset output. + * @note RSTEN acts as a mask for the reset output. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval None + */ +__STATIC_INLINE void ll_wdt_enable_reset(wdt_regs_t *WDTx) +{ + SET_BITS(WDTx->CTRL, WDT_CTRL_RSTEN); +} + +/** + * @brief Disable reset output. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval None + */ +__STATIC_INLINE void ll_wdt_disable_reset(wdt_regs_t *WDTx) +{ + CLEAR_BITS(WDTx->CTRL, WDT_CTRL_RSTEN); +} + +/** + * @brief Check if the WDT reset is enabled or disabled. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RSTEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_wdt_is_enabled_reset(wdt_regs_t *WDTx) +{ + return (READ_BITS(WDTx->CTRL, WDT_CTRL_RSTEN) == (WDT_CTRL_RSTEN)); +} + +/** + * @brief Specify the WDT down-counter reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LOAD | LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @param counter Value range between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_wdt_set_counter_load(wdt_regs_t *WDTx, uint32_t counter) +{ + WRITE_REG(WDTx->LOAD, counter); +} + +/** + * @brief Get the specified WDT down-counter reload value. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | LOAD | LOAD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @retval Value range between Min_Data=0 and Max_Data=0x0FFF + */ +__STATIC_INLINE uint32_t ll_wdt_get_counter_load(wdt_regs_t *WDTx) +{ + return (uint32_t)(READ_REG(WDTx->LOAD)); +} + +/** + * @brief Get current value of the specified WDT decrementing down-counter. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | VALUE | VALUE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @retval Value range between Min_Data=0 and Max_Data=0x0FFF + */ +__STATIC_INLINE uint32_t ll_wdt_get_counter_value(wdt_regs_t *WDTx) +{ + return (uint32_t)(READ_REG(WDTx->VALUE)); +} + +/** + * @brief Reloads WDT counter with value defined in the reload register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INTCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance + * @retval None + */ +__STATIC_INLINE void ll_wdt_reload_counter(wdt_regs_t *WDTx) +{ + WRITE_REG(WDTx->INTCLR, WDT_INTCLR); +} + +/** @} */ + +/** @defgroup WDT_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate if the WDT Interrupt Flag is set or not. + * @note This bit is set by hardware when the counter has reached 0. It can + * be cleared by software by writing any value to the INTCLR Register. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MIS | INTSTAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_wdt_is_active_flag_it(wdt_regs_t *WDTx) +{ + return (READ_BITS(WDTx->MIS, WDT_MIS_INTSTAT) == (WDT_MIS_INTSTAT)); +} + +/** + * @brief Clear Interrupt Status flag. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INTCLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param WDTx WDT instance. + * @retval None + */ +__STATIC_INLINE void ll_wdt_clear_flag_it(wdt_regs_t *WDTx) +{ + WRITE_REG(WDTx->INTCLR, WDT_INTCLR); +} + +/** @} */ + +/** @} */ + +#endif /* WDT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55XX_LL_WDT_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_xqspi.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_xqspi.h new file mode 100644 index 0000000..e0c0aab --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/gr55xx_ll_xqspi.h @@ -0,0 +1,2902 @@ +/** + **************************************************************************************** + * + * @file gr55xx_ll_xqspi.h + * @author BLE SDK Team + * @brief Header file containing functions prototypes of XQSPI LL library. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/** @addtogroup PERIPHERAL Peripheral Driver + * @{ + */ + +/** @addtogroup LL_DRIVER LL Driver + * @{ + */ + +/** @defgroup LL_XQSPI XQSPI + * @brief XQSPI LL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GR55xx_LL_XQSPI_H__ +#define __GR55xx_LL_XQSPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx.h" + +#if defined (XQSPI) + +/** @defgroup LL_XQSPI_DRIVER_STRUCTURES Structures + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup XQSPI_LL_ES_INIT XQSPI Exported init structure + * @{ + */ + +/** + * @brief XQSPI init structures definition + */ +typedef struct _ll_xqspi_init_t +{ + uint32_t mode; /**< Specifies the work mode, XIP mode or QSPI mode. + This parameter can be a value of @ref XQSPI_LL_EC_MODE.*/ + + uint32_t cache_mode; /**< Specifies the cache mode in XIP mode. + This parameter can be a value of @ref XQSPI_LL_EC_CACHE_MODE. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_enable_cache().*/ + + uint32_t read_cmd; /**< Specifies the XQSPI read command in XIP mode. + This parameter can be a value of @ref XQSPI_LL_EC_XIP_READ_CMD. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_xip_cmd().*/ + + uint32_t data_size; /**< Specifies the XQSPI data width, only in QSPI mode. + This parameter can be a value of @ref XQSPI_LL_EC_QSPI_DATASIZE. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_qspi_datasize().*/ + + uint32_t data_order; /**< Specifies the XQSPI data order, MSB oe LSB, only in QSPI mode. + This parameter can be a value of @ref XQSPI_LL_EC_QSPI_DATAORDER. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_qspi_data_order().*/ + + uint32_t clock_polarity; /**< Specifies the serial clock steady state. + This parameter can be a value of @ref XQSPI_LL_EC_QSPI_POLARITY in XIP mode or @ref XQSPI_LL_EC_QSPI_POLARITY in QSPI mode. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_xip_cpol() or @ref ll_xqspi_set_qspi_cpol().*/ + + uint32_t clock_phase; /**< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref XQSPI_LL_EC_QSPI_PHASE in XIP mode or @ref XQSPI_LL_EC_QSPI_PHASE in QSPI mode. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_xip_cpha() or @ref ll_xqspi_set_qspi_cpha().*/ + + uint32_t baud_rate; /**< Specifies the BaudRate be used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref XQSPI_LL_EC_QSPI_BAUD_REAT. + + This feature can be modified afterwards using unitary function @ref ll_xqspi_set_qspi_speed().*/ + +} ll_xqspi_init_t; + +/** @} */ + +/** @} */ + +/** + * @defgroup XQSPI_LL_MACRO Defines + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup XQSPI_LL_Exported_Constants XQSPI Exported Constants + * @{ + */ + +/** @defgroup XQSPI_LL_EC_MODE XQSPI work mode + * @{ + */ +#define LL_XQSPI_MODE_XIP 0 /**< XIP mode */ +#define LL_XQSPI_MODE_QSPI 1 /**< QSPI mode */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_XIP_READ_CMD XIP read command + * @{ + */ +#define LL_XQSPI_XIP_CMD_READ 0x03 /**< Read mode */ +#define LL_XQSPI_XIP_CMD_FAST_READ 0x0B /**< Fast Read mode */ +#define LL_XQSPI_XIP_CMD_DUAL_OUT_READ 0x3B /**< Dual-Out Fast Read mode */ +#define LL_XQSPI_XIP_CMD_DUAL_IO_READ 0xBB /**< Dual-IO Fast Read mode */ +#define LL_XQSPI_XIP_CMD_QUAD_OUT_READ 0x6B /**< Quad-Out Fast Read mode */ +#define LL_XQSPI_XIP_CMD_QUAD_IO_READ 0xEB /**< Quad-IO Fast Read mode */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_XIP_SS Slave select + * @{ + */ +#define LL_XQSPI_XIP_SS0 (1UL << XQSPI_XIP_CFG_SS_Pos) /**< Slave select 0 */ +#define LL_XQSPI_XIP_SS1 (2UL << XQSPI_XIP_CFG_SS_Pos) /**< Slave select 1 */ +#define LL_XQSPI_XIP_SS2 (4UL << XQSPI_XIP_CFG_SS_Pos) /**< Slave select 2 */ +#define LL_XQSPI_XIP_SS3 (8UL << XQSPI_XIP_CFG_SS_Pos) /**< Slave select 3 */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_XIP_ADDR_MODE Address bytes in command + * @{ + */ +#define LL_XQSPI_XIP_ADDR_3BYTES 0x00000000UL /**< Address command is 3 bytes */ +#define LL_XQSPI_XIP_ADDR_4BYTES XQSPI_XIP_CFG_ADDR4 /**< Address command is 4 bytes */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_XIP_ENDIAN Read data endian mode + * @{ + */ +#define LL_XQSPI_XIP_ENDIAN_BIG 0x00000000UL /**< Read data in big endian */ +#define LL_XQSPI_XIP_ENDIAN_LITTLE XQSPI_XIP_CFG_LE32 /**< Read data in little endian */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_CACHE_MODE XIP cache mode + * @{ + */ +#define LL_XQSPI_CACHE_DIS 0 /**< Cache OFF */ +#define LL_XQSPI_CACHE_EN 1 /**< Cache ON */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_CACHE_FIFO_MODE Cache FIFO mode + * @{ + */ +#define LL_XQSPI_CACHE_FIFO_NORMAL 0x00000000UL /**< FIFO in normal mode */ +#define LL_XQSPI_CACHE_FIFO_CLEAR XQSPI_CACHE_CTRL0_FIFO /**< FIFO in clear mode */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_CACHE_HITMISS_COUNTER_MODE Cache hit/miss counters mode + * @{ + */ +#define LL_XQSPI_CACHE_HITMISS_NORMAL 0x00000000UL /**< Hit/Miss counters in normal mode */ +#define LL_XQSPI_CACHE_HITMISS_CLEAR XQSPI_CACHE_CTRL0_HITMISS /**< Hit/Miss counters in clear mode */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_FLAG QSPI Flags Defines + * @brief Flags defines which can be used with LL_XQSPI_ReadReg function + * @{ + */ +#define LL_XQSPI_QSPI_STAT_RFTF XQSPI_QSPI_STAT_RXWMARK /**< Rx FIFO watermark flag */ +#define LL_XQSPI_QSPI_STAT_RFF XQSPI_QSPI_STAT_RXFULL /**< Rx FIFO full flag */ +#define LL_XQSPI_QSPI_STAT_RFE XQSPI_QSPI_STAT_RXEMPTY /**< Rx FIFO empty flag */ +#define LL_XQSPI_QSPI_STAT_TFTF XQSPI_QSPI_STAT_TXWMARK /**< Tx FIFO watermark flag */ +#define LL_XQSPI_QSPI_STAT_TFF XQSPI_QSPI_STAT_TXFULL /**< Tx FIFO full flag */ +#define LL_XQSPI_QSPI_STAT_TFE XQSPI_QSPI_STAT_TXEMPTY /**< Tx FIFO empty flag */ +#define LL_XQSPI_QSPI_STAT_BUSY XQSPI_QSPI_STAT_XFERIP /**< Busy flag */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_IT QSPI interrupt Defines + * @brief Interrupt defines which can be used with LL_XQSPI_ReadReg and LL_XQSPI_WriteReg functions + * @{ + */ +#define LL_XQSPI_QSPI_IM_DONE XQSPI_QSPI_XFER_DPULSE_Msk /**< Transmite Done Interrupt enable */ +#define LL_XQSPI_QSPI_IM_RFF XQSPI_QSPI_RX_FPULSE_Msk /**< Receive FIFO Full Interrupt enable */ +#define LL_XQSPI_QSPI_IM_RFTF XQSPI_QSPI_RX_WPULSE_Msk /**< Receive FIFO Watermark Interrupt enable */ +#define LL_XQSPI_QSPI_IM_TFTF XQSPI_QSPI_TX_WPULSE_Msk /**< Transmit FIFO Watermark Interrupt enable */ +#define LL_XQSPI_QSPI_IM_TFE XQSPI_QSPI_TX_EPULSE_Msk /**< Transmit FIFO Empty Interrupt enable */ + +#define LL_XQSPI_QSPI_IS_DONE XQSPI_QSPI_XFER_DPULSE_Msk /**< Transmite Done Interrupt flag */ +#define LL_XQSPI_QSPI_IS_RFF XQSPI_QSPI_RX_FPULSE_Msk /**< Receive FIFO Full Interrupt flag */ +#define LL_XQSPI_QSPI_IS_RFTF XQSPI_QSPI_RX_WPULSE_Msk /**< Receive FIFO Watermark Interrupt flag */ +#define LL_XQSPI_QSPI_IS_TFTF XQSPI_QSPI_TX_WPULSE_Msk /**< Transmit FIFO Watermark Interrupt flag */ +#define LL_XQSPI_QSPI_IS_TFE XQSPI_QSPI_TX_EPULSE_Msk /**< Transmit FIFO Empty Interrupt flag */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_FIFO_WATERMARK QSPI FIFO Watermark + * @{ + */ +#define LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 0UL /**< FIFO depth/8 */ +#define LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 1UL /**< FIFO depth/4 */ +#define LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 2UL /**< FIFO depth/2 */ +#define LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 3UL /**< FIFO depth*3/4 */ +#define LL_XQSPI_QSPI_FIFO_DEPTH 16UL /**< FIFO full depth */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_FRAMEFORMAT QSPI Frame Format + * @{ + */ +#define LL_XQSPI_QSPI_FRF_SPI 0x00000000UL /**< SPI frame format for transfer */ +#define LL_XQSPI_QSPI_FRF_DUALSPI (2UL << XQSPI_QSPI_AUXCTRL_QMODE_Pos) /**< Dual-SPI frame format for transfer */ +#define LL_XQSPI_QSPI_FRF_QUADSPI (3UL << XQSPI_QSPI_AUXCTRL_QMODE_Pos) /**< Quad-SPI frame format for transfer */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_DATAORDER QSPI Data Order + * @{ + */ +#define LL_XQSPI_QSPI_LSB 0x00000000UL /**< LSB first for transfer */ +#define LL_XQSPI_QSPI_MSB XQSPI_QSPI_CTRL_MSB1ST /**< MSB first for transfer */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_DATASIZE QSPI Datawidth + * @{ + */ +#define LL_XQSPI_QSPI_DATASIZE_4BIT 0x00000000UL /**< Data length for XQSPI transfer: 4 bits */ +#define LL_XQSPI_QSPI_DATASIZE_8BIT (1UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 8 bits */ +#define LL_XQSPI_QSPI_DATASIZE_12BIT (2UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 12 bits */ +#define LL_XQSPI_QSPI_DATASIZE_16BIT (3UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 16 bits */ +#define LL_XQSPI_QSPI_DATASIZE_20BIT (4UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 20 bits */ +#define LL_XQSPI_QSPI_DATASIZE_24BIT (5UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 24 bits */ +#define LL_XQSPI_QSPI_DATASIZE_28BIT (6UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 28 bits */ +#define LL_XQSPI_QSPI_DATASIZE_32BIT (7UL << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) /**< Data length for XQSPI transfer: 32 bits */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_PHASE QSPI Clock Phase + * @{ + */ +#define LL_XQSPI_SCPHA_1EDGE 0 /**< First clock transition is the first data capture edge */ +#define LL_XQSPI_SCPHA_2EDGE 1 /**< Second clock transition is the first data capture edge */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_POLARITY QSPI Clock Polarity + * @{ + */ +#define LL_XQSPI_SCPOL_LOW 0 /**< Clock to 0 when idle */ +#define LL_XQSPI_SCPOL_HIGH 1 /**< Clock to 1 when idle */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_BAUD_REAT QSPI Buad Rate + * @{ + */ +#define LL_XQSPI_BAUD_RATE_64M 0x00000000UL /**< Clock to 64MHz */ +#define LL_XQSPI_BAUD_RATE_48M (1UL << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos) /**< Clock to 48MHz */ +#define LL_XQSPI_BAUD_RATE_32M (2UL << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos) /**< Clock to 32MHz */ +#define LL_XQSPI_BAUD_RATE_24M (3UL << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos) /**< Clock to 24MHz */ +#define LL_XQSPI_BAUD_RATE_16M (4UL << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos) /**< Clock to 16MHz */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_PRESENT QSPI Present Bypass + * @{ + */ +#define LL_XQSPI_ENABLE_PRESENT 0 /**< Enable Present Bypass */ +#define LL_XQSPI_DISABLE_PRESENT 1 /**< Disable Present Bypass */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_QSPI_FLASH_WRITE QSPI Flash write bits + * @{ + */ +#define LL_XQSPI_FLASH_WRITE_128BIT 0 /**< 128bits flash write */ +#define LL_XQSPI_FLASH_WRITE_32BIT 1 /**< 32bits flash write */ +/** @} */ + +/** @defgroup XQSPI_LL_EC_DEFAULT_CONFIG InitStrcut default configuartion + * @{ + */ + +/** + * @brief LL XQSPI InitStrcut default configuartion + */ +#define LL_XQSPI_DEFAULT_CONFIG \ +{ \ + .mode = LL_XQSPI_MODE_QSPI, \ + .cache_mode = LL_XQSPI_CACHE_EN, \ + .read_cmd = LL_XQSPI_XIP_CMD_READ, \ + .data_size = LL_XQSPI_QSPI_DATASIZE_8BIT, \ + .data_order = LL_XQSPI_QSPI_MSB, \ + .clock_polarity = LL_XQSPI_SCPOL_HIGH, \ + .clock_phase = LL_XQSPI_SCPHA_2EDGE, \ + .baud_rate = LL_XQSPI_BAUD_RATE_16M, \ +} +/** @} */ + +/** @} */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup XQSPI_LL_Exported_Macros XQSPI Exported Macros + * @{ + */ + +/** @defgroup XQSPI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in XQSPI register + * @param __instance__ XQSPI instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_XQSPI_WriteReg(__instance__, __REG__, __VALUE__) WRITE_REG(__instance__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in XQSPI register + * @param __instance__ XQSPI instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_XQSPI_ReadReg(__instance__, __REG__) READ_REG(__instance__->__REG__) + +/** @} */ + +/** @} */ + +/** @} */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup XQSPI_LL_DRIVER_FUNCTIONS Functions + * @{ + */ + +/** @defgroup XQSPI_LL_XQSPI_Configuration Cache driver functions + * @{ + */ + +/** + * @brief Enable cache function + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_cache(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); +} + +/** + * @brief Disable cache function + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_cache(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); +} + +/** + * @brief Check if cache function is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_cache(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_DIS) != (XQSPI_CACHE_CTRL0_DIS)); +} + +/** + * @brief Enable tag memory flush + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | TAG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_cache_flush(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_FLUSH); +} + +/** + * @brief Disable tag memory flush + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | TAG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_cache_flush(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_FLUSH); +} + +/** + * @brief Check if tag memory flush is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | TAG | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_cache_flush(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_FLUSH) == (XQSPI_CACHE_CTRL0_FLUSH)); +} + +/** + * @brief Set FIFO mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | FIFO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param mode This parameter can be one of the following values: + * @arg @ref LL_XQSPI_CACHE_FIFO_NORMAL + * @arg @ref LL_XQSPI_CACHE_FIFO_CLEAR + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_cache_fifo(xqspi_regs_t *XQSPIx, uint32_t mode) +{ + MODIFY_REG(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_FIFO, mode); +} + +/** + * @brief Get FIFO mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | FIFO | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_CACHE_FIFO_NORMAL + * @arg @ref LL_XQSPI_CACHE_FIFO_CLEAR + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_fifo(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_FIFO)); +} + +/** + * @brief Set HIT/MISS mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | HITMISS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param mode This parameter can be one of the following values: + * @arg @ref LL_XQSPI_CACHE_HITMISS_NORMAL + * @arg @ref LL_XQSPI_CACHE_HITMISS_CLEAR + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_cache_hitmiss(xqspi_regs_t *XQSPIx, uint32_t mode) +{ + MODIFY_REG(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_HITMISS, mode); +} + +/** + * @brief Get HIT/MISS mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | HITMISS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_CACHE_HITMISS_NORMAL + * @arg @ref LL_XQSPI_CACHE_HITMISS_CLEAR + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_hitmiss(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->CACHE.CTRL0, XQSPI_CACHE_CTRL0_HITMISS)); +} + +/** + * @brief Set debugbus configurations signals + * @note These bits should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | DBGBUS_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param sel This parameter can between: 0 ~ 0x7 + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_cache_dbgbus(xqspi_regs_t *XQSPIx, uint32_t sel) +{ + MODIFY_REG(XQSPIx->CACHE.CTRL1, XQSPI_CACHE_CTRL1_DBGBUS_SEL, sel << XQSPI_CACHE_CTRL1_DBGBUS_SEL_Pos); +} + +/** + * @brief Get debugbus configurations signals + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | DBGBUS_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0x7 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_dbgbus(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->CACHE.CTRL1, XQSPI_CACHE_CTRL1_DBGBUS_SEL) >> XQSPI_CACHE_CTRL1_DBGBUS_SEL_Pos); +} + +/** + * @brief Enable debug bus mux + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | DBGMUX_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_cache_dbgmux(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->CACHE.CTRL1, XQSPI_CACHE_CTRL1_DBGMUX_EN); +} + +/** + * @brief Disable debug bus mux + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | DBGMUX_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_cache_dbgmux(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->CACHE.CTRL1, XQSPI_CACHE_CTRL1_DBGMUX_EN); +} + +/** + * @brief Check if debug bus mux is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | DBGMUX_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_cache_dbgmux(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->CACHE.CTRL1, XQSPI_CACHE_CTRL1_DBGMUX_EN) != (XQSPI_CACHE_CTRL1_DBGMUX_EN)); +} + +/** + * @brief Get hit counter + * @note This bit only be read. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | HIT_COUNT | HITCOUNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_hitcount(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->CACHE.HIT_COUNT)); +} + +/** + * @brief Get miss counter + * @note This bit only be read. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MISS_COUNT | MISSCOUNT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_misscount(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->CACHE.MISS_COUNT)); +} + +/** + * @brief Get cache status + * @note This bit only be read. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | STAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 1 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_cache_flag(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->CACHE.STAT, XQSPI_CACHE_STAT)); +} + +/** @} */ + +/** @defgroup XQSPI_LL_XIP_Configuration XIP LL driver functions + * @{ + */ + +/** + * @brief Set read command + * @note These bits should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | CFG_CMD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cmd This parameter can be one of the following values: + * @arg @ref LL_XQSPI_XIP_CMD_READ + * @arg @ref LL_XQSPI_XIP_CMD_FAST_READ + * @arg @ref LL_XQSPI_XIP_CMD_DUAL_OUT_READ + * @arg @ref LL_XQSPI_XIP_CMD_DUAL_IO_READ + * @arg @ref LL_XQSPI_XIP_CMD_QUAD_OUT_READ + * @arg @ref LL_XQSPI_XIP_CMD_QUAD_IO_READ + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_cmd(xqspi_regs_t *XQSPIx, uint32_t cmd) +{ + MODIFY_REG(XQSPIx->XIP.CTRL0, XQSPI_XIP_CFG_CMD, cmd); +} + +/** + * @brief Get read command + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL0 | CFG_CMD | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_XIP_CMD_READ + * @arg @ref LL_XQSPI_XIP_CMD_FAST_READ + * @arg @ref LL_XQSPI_XIP_CMD_DUAL_OUT_READ + * @arg @ref LL_XQSPI_XIP_CMD_DUAL_IO_READ + * @arg @ref LL_XQSPI_XIP_CMD_QUAD_OUT_READ + * @arg @ref LL_XQSPI_XIP_CMD_QUAD_IO_READ + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_cmd(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL0, XQSPI_XIP_CFG_CMD)); +} + +/** + * @brief Enable high performance mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_HPEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_xip_hp(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_HPEN); +} + +/** + * @brief Disable high performance mode + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_HPEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_xip_hp(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_HPEN); +} + +/** + * @brief Check if high performance mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_HPEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_xip_hp(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_HPEN) == (XQSPI_XIP_CFG_HPEN)); +} + +/** + * @brief Set slave select + * @note These bits should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_SS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param ss This parameter can be one or more of the following values: + * @arg @ref LL_XQSPI_XIP_SS0 + * @arg @ref LL_XQSPI_XIP_SS1 + * @arg @ref LL_XQSPI_XIP_SS2 + * @arg @ref LL_XQSPI_XIP_SS3 + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_ss(xqspi_regs_t *XQSPIx, uint32_t ss) +{ + MODIFY_REG(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_SS, ss); +} + +/** + * @brief Get slave select + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_SS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_XIP_SS0 + * @arg @ref LL_XQSPI_XIP_SS1 + * @arg @ref LL_XQSPI_XIP_SS2 + * @arg @ref LL_XQSPI_XIP_SS3 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_ss(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_SS)); +} + +/** + * @brief Set clock phase + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_CPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cpha This parameter can be one or more of the following values: + * @arg @ref LL_XQSPI_SCPHA_1EDGE + * @arg @ref LL_XQSPI_SCPHA_2EDGE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_cpha(xqspi_regs_t *XQSPIx, uint32_t cpha) +{ + MODIFY_REG(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_CPHA, cpha << XQSPI_XIP_CFG_CPHA_Pos); +} + +/** + * @brief Get clock phase + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_CPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_SCPHA_1EDGE + * @arg @ref LL_XQSPI_SCPHA_2EDGE + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_cpha(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_CPHA) >> XQSPI_XIP_CFG_CPHA_Pos); +} + +/** + * @brief Set clock polarity + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_CPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cpol This parameter can be one or more of the following values: + * @arg @ref LL_XQSPI_SCPOL_LOW + * @arg @ref LL_XQSPI_SCPOL_HIGH + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_cpol(xqspi_regs_t *XQSPIx, uint32_t cpol) +{ + MODIFY_REG(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_CPOL, cpol << XQSPI_XIP_CFG_CPOL_Pos); +} + +/** + * @brief Get clock polarity + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_CPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_SCPOL_LOW + * @arg @ref LL_XQSPI_SCPOL_HIGH + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_cpol(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_CPOL) >> XQSPI_XIP_CFG_CPOL_Pos); +} + +/** + * @brief Set address bytes in command + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_ADDR4 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param size This parameter can be one or more of the following values: + * @arg @ref LL_XQSPI_XIP_ADDR_3BYTES + * @arg @ref LL_XQSPI_XIP_ADDR_4BYTES + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_addr_size(xqspi_regs_t *XQSPIx, uint32_t size) +{ + MODIFY_REG(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_ADDR4, size); +} + +/** + * @brief Get address bytes in command + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_ADDR4 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_XIP_ADDR_3BYTES + * @arg @ref LL_XQSPI_XIP_ADDR_4BYTES + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_addr_size(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_ADDR4)); +} + +/** + * @brief Set endian in reading data + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_LE32 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param endian This parameter can be one or more of the following values: + * @arg @ref LL_XQSPI_XIP_ENDIAN_BIG + * @arg @ref LL_XQSPI_XIP_ENDIAN_LITTLE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_endian(xqspi_regs_t *XQSPIx, uint32_t endian) +{ + MODIFY_REG(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_LE32, endian); +} + +/** + * @brief Get endian in reading data + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL1 | CFG_LE32 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_XIP_ENDIAN_BIG + * @arg @ref LL_XQSPI_XIP_ENDIAN_LITTLE + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_endian(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL1, XQSPI_XIP_CFG_LE32)); +} + +/** + * @brief Set high performance command + * @note These bits should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_HPMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cmd This value is specified by different QSPI FLASH memory vendor to enter into its status register + * to activate HP mode in dual I/O and Quad I/O access. This parameter can between: 0 ~ 0xFF. + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_hp_cmd(xqspi_regs_t *XQSPIx, uint32_t cmd) +{ + MODIFY_REG(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_HPMODE, cmd << XQSPI_XIP_CFG_HPMODE_Pos); +} + +/** + * @brief Get high performance command + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_HPMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0xFF. + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_hp_cmd(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_HPMODE) >> XQSPI_XIP_CFG_HPMODE_Pos); +} + +/** + * @brief Set dummy cycles in command + * @note These bits should not be changed when XIP is ongoing. + * - Fast Read Dual I/O: dummycycles = 4 * cycles + 4 + * - Fast Read Quad I/O: dummycycles = 2 * cycles + 2 + * - Fast Read Dual Out: dummycycles = 8 * cycles + * - Fast Read Quad Out: dummycycles = 8 * cycles + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_DUMMYCYCLES | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cycles This parameter can between: 0 ~ 0xF. + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_dummycycles(xqspi_regs_t *XQSPIx, uint32_t cycles) +{ + MODIFY_REG(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_DUMMYCYCLES, cycles << XQSPI_XIP_CFG_DUMMYCYCLES_Pos); +} + +/** + * @brief Get dummy cycles in command + * @note - Fast Read Dual I/O: dummycycles = 4 * cycles + 4 + * - Fast Read Quad I/O: dummycycles = 2 * cycles + 2 + * - Fast Read Dual Out: dummycycles = 8 * cycles + * - Fast Read Quad Out: dummycycles = 8 * cycles + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_DUMMYCYCLES | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0xF. + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_dummycycles(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_DUMMYCYCLES)); +} + +/** + * @brief Set dummy cycles in high performance end + * @note These bits should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_ENDDUMMY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cycles This parameter can between: 0 ~ 3. + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_xip_dummy_hp(xqspi_regs_t *XQSPIx, uint32_t cycles) +{ + MODIFY_REG(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_ENDDUMMY, cycles << XQSPI_XIP_CFG_ENDDUMMY_Pos); +} + +/** + * @brief Get dummy cycles in high performance end + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL2 | CFG_ENDDUMMY | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 3. + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_dummy_hp(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.CTRL2, XQSPI_XIP_CFG_ENDDUMMY) >> XQSPI_XIP_CFG_ENDDUMMY_Pos); +} + +/** + * @brief Enable XIP mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL3 | EN_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_xip(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->XIP.CTRL3, XQSPI_XIP_EN_REQ); +} + +/** + * @brief Disable XIP mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL3 | EN_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_xip(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->XIP.CTRL3, XQSPI_XIP_EN_REQ); +} + +/** + * @brief Check if XIP mode is enabled + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL3 | EN_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_xip(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->XIP.CTRL3, XQSPI_XIP_EN_REQ) == (XQSPI_XIP_EN_REQ)); +} + +/** + * @brief Get XIP status + * @note This bit is read-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | STAT | EN_OUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 1 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_xip_flag(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.STAT, XQSPI_XIP_EN_OUT)); +} + +/** + * @brief Check if XIP interrupt is enabled + * @note This bit is read-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 1 + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_xip_it(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.INTEN, XQSPI_XIP_INT_EN)); +} + +/** + * @brief Get XIP interrupt flag + * @note This bit is read-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INT_STAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 1 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_flag_xip_it(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.INTSTAT, XQSPI_XIP_INT_STAT)); +} + +/** + * @brief Get XIP interrupt request + * @note This bit is read-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTREQ | INT_REQ | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 1 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_req_xip_it(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->XIP.INTREQ, XQSPI_XIP_INT_REQ)); +} + +/** + * @brief Set XIP interrupt enable + * @note This bit is write-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSET | INT_SET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_xip_it(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->XIP.INTSET, XQSPI_XIP_INT_SET); +} + +/** + * @brief Set XIP interrupt disable + * @note This bit is write-only. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INT_CLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_xip_it(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->XIP.INTCLR, XQSPI_XIP_INT_CLR); +} + +/** @} */ + +/** @defgroup XQSPI_LL_QSPI_Configuration QSPI driver functions + * @{ + */ + +/** + * @brief Write 8-bit in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | TX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param tx_data This parameter can between: 0x00 ~ 0xFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_qspi_transmit_data8(xqspi_regs_t *XQSPIx, uint8_t tx_data) +{ + *((__IOM uint8_t *)&XQSPIx->QSPI.TX_DATA) = tx_data; +} + +/** + * @brief Write 16-bit in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | TX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param tx_data This parameter can between: 0x00 ~ 0xFFFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_qspi_transmit_data16(xqspi_regs_t *XQSPIx, uint16_t tx_data) +{ + *((__IOM uint16_t *)&XQSPIx->QSPI.TX_DATA) = tx_data; +} + +/** + * @brief Write 32-bit in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | TX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param tx_data This parameter can between: 0x00 ~ 0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_qspi_transmit_data32(xqspi_regs_t *XQSPIx, uint32_t tx_data) +{ + *((__IOM uint32_t *)&XQSPIx->QSPI.TX_DATA) = tx_data; +} + +/** + * @brief Read 8 bits in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | RX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value between: 0x00 ~ 0xFF + */ +__STATIC_INLINE uint8_t ll_xqspi_qspi_receive_data8(xqspi_regs_t *XQSPIx) +{ + return (uint8_t)(READ_REG(XQSPIx->QSPI.RX_DATA)); +} + +/** + * @brief Read 16 bits in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | RX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value between: 0x00 ~ 0xFFFF + */ +__STATIC_INLINE uint16_t ll_xqspi_qspi_receive_data16(xqspi_regs_t *XQSPIx) +{ + return (uint16_t)(READ_REG(XQSPIx->QSPI.RX_DATA)); +} + +/** + * @brief Read 32 bits in the data register + * + * \rst + * +----------------------+-----------------------------+ + * | Register | BitsName | + * +======================+=============================+ + * | RX_DATA | DATA | + * +----------------------+-----------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value between: 0x00 ~ 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t ll_xqspi_qspi_receive_data32(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->QSPI.RX_DATA)); +} + +/** + * @brief Set TX FIFO threshold level + * @note FIFO maximum depth is 16 units. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | TXWMARK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_tft(xqspi_regs_t *XQSPIx, uint32_t threshold) +{ + MODIFY_REG(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_TXWMARK, threshold << XQSPI_QSPI_CTRL_TXWMARK_Pos); +} + +/** + * @brief Get TX FIFO threshold level + * @note FIFO maximum depth is 16 units. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | TXWMARK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_tft(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_TXWMARK) >> XQSPI_QSPI_CTRL_TXWMARK_Pos); +} + +/** + * @brief Set RX FIFO threshold level + * @note FIFO maximum depth is 16 units. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RXWMARK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param threshold This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_rft(xqspi_regs_t *XQSPIx, uint32_t threshold) +{ + MODIFY_REG(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_RXWMARK, threshold << XQSPI_QSPI_CTRL_RXWMARK_Pos); +} + +/** + * @brief Get RX FIFO threshold level + * @note FIFO maximum depth is 16 units. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | RXWMARK | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_8 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_4 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_1_2 + * @arg @ref LL_XQSPI_QSPI_FIFO_WATERMARK_3_4 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_rft(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_RXWMARK) >> XQSPI_QSPI_CTRL_RXWMARK_Pos); +} + +/** + * @brief Enable dummy cycles + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MWAITEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_dummy(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_MWAITEN); +} + +/** + * @brief Disable dummy cycles + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MWAITEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_dummy(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_MWAITEN); +} + +/** + * @brief Check if dummy cycles is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MWAITEN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi_dummy(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_MWAITEN) == (XQSPI_QSPI_CTRL_MWAITEN)); +} + +/** + * @brief Enable DMA mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | DMA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_dma(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_DMA); +} + +/** + * @brief Disable DMA mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | DMA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_dma(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_DMA); +} + +/** + * @brief Check if DMA mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | DMA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi_dma(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_DMA) == (XQSPI_QSPI_CTRL_DMA)); +} + +/** + * @brief Set clock polarity + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cpol This parameter can be one of the following values: + * @arg @ref LL_XQSPI_SCPOL_LOW + * @arg @ref LL_XQSPI_SCPOL_HIGH + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_cpol(xqspi_regs_t *XQSPIx, uint32_t cpol) +{ + MODIFY_REG(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CPOL, cpol << XQSPI_QSPI_CTRL_CPOL_Pos); +} + +/** + * @brief Get clock polarity + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CPOL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_SCPOL_LOW + * @arg @ref LL_XQSPI_SCPOL_HIGH + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_cpol(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CPOL) >> XQSPI_QSPI_CTRL_CPOL_Pos); +} + +/** + * @brief Set clock phase + * @note This bit should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param cpha This parameter can be one of the following values: + * @arg @ref LL_XQSPI_SCPHA_1EDGE + * @arg @ref LL_XQSPI_SCPHA_2EDGE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_cpha(xqspi_regs_t *XQSPIx, uint32_t cpha) +{ + MODIFY_REG(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CPHA, cpha << XQSPI_QSPI_CTRL_CPHA_Pos); +} + +/** + * @brief Get clock phase + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CPHA | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_SCPHA_1EDGE + * @arg @ref LL_XQSPI_SCPHA_2EDGE + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_cpha(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CPHA) >> XQSPI_QSPI_CTRL_CPHA_Pos); +} + +/** + * @brief Set serial data order + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MSB1ST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param order This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_LSB + * @arg @ref LL_XQSPI_QSPI_MSB + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_data_order(xqspi_regs_t *XQSPIx, uint32_t order) +{ + MODIFY_REG(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_MSB1ST, order); +} + +/** + * @brief Get serial data order + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | MSB1ST | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_LSB + * @arg @ref LL_XQSPI_QSPI_MSB + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_data_order(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_MSB1ST)); +} + +/** + * @brief Enable continuous transfer mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CONTXFER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_contxfer(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CONTXFER); +} + +/** + * @brief Disable continuous transfer mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CONTXFER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_contxfer(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CONTXFER); +} + +/** + * @brief Check if continuous transfer mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | CTRL | CONTXFER | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi_contxfer(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.CTRL, XQSPI_QSPI_CTRL_CONTXFER) == (XQSPI_QSPI_CTRL_CONTXFER)); +} + +/** + * @brief Enable continuous transfer extend mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | CONTXFERX | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_contxfer_extend(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_CONTXFERX); +} + +/** + * @brief Disable continuous transfer extend mode + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | CONTXFERX | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_contxfer_extend(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_CONTXFERX); +} + +/** + * @brief Check if continuous transfer extend mode is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | CONTXFERX | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi_contxfer_extend(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_CONTXFERX) == (XQSPI_QSPI_AUXCTRL_CONTXFERX)); +} + +/** + * @brief Set data size + * @note These bits should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | BITSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param szie This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_DATASIZE_4BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_8BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_12BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_16BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_20BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_24BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_28BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_32BIT + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_datasize(xqspi_regs_t *XQSPIx, uint32_t szie) +{ + MODIFY_REG(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_BITSIZE, szie); +} + +/** + * @brief Get data size + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | BITSIZE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_DATASIZE_4BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_8BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_12BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_16BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_20BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_24BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_28BIT + * @arg @ref LL_XQSPI_QSPI_DATASIZE_32BIT + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_datasize(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_BITSIZE)); +} + +/** + * @brief Enable inhibt data input to RX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDIN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_inhibt_rx(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDIN); +} + +/** + * @brief Disable inhibt data input to RX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDIN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_inhibt_rx(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDIN); +} + +/** + * @brief Check if inhibt data input to RX FIFO is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDIN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_inhibt_rx(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDIN) == XQSPI_QSPI_AUXCTRL_INHIBITDIN); +} + +/** + * @brief Enable inhibt data output to TX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_inhibt_tx(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDOUT); +} + +/** + * @brief Disable inhibt data output to TX FIFO + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_inhibt_tx(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDOUT); +} + +/** + * @brief Check if inhibt data input to TX FIFO is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | INHIBITDOUT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_inhibt_tx(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_INHIBITDOUT) == XQSPI_QSPI_AUXCTRL_INHIBITDOUT); +} + +/** + * @brief Set frame format + * @note These bits should not be changed when communication is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | QMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param format This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_FRF_SPI + * @arg @ref LL_XQSPI_QSPI_FRF_DUALSPI + * @arg @ref LL_XQSPI_QSPI_FRF_QUADSPI + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_frf(xqspi_regs_t *XQSPIx, uint32_t format) +{ + MODIFY_REG(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_QMODE, format); +} + +/** + * @brief Get frame format + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | AUX_CTRL | QMODE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one even value: + * @arg @ref LL_XQSPI_QSPI_FRF_SPI + * @arg @ref LL_XQSPI_QSPI_FRF_DUALSPI + * @arg @ref LL_XQSPI_QSPI_FRF_QUADSPI + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_frf(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.AUX_CTRL, XQSPI_QSPI_AUXCTRL_QMODE)); +} + +/** + * @brief Get QSPI status + * + * \rst + * +----------------------+------------------------------------------------------+ + * | Register | BitsName | + * +======================+======================================================+ + * | STATUS | RXFULL RXWMARK RXEMPTY TXFULL TXWMARK TXEMPTY XFERIP | + * +----------------------+------------------------------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one or combination of the following values: + * @arg @ref LL_XQSPI_QSPI_STAT_RFTF + * @arg @ref LL_XQSPI_QSPI_STAT_RFF + * @arg @ref LL_XQSPI_QSPI_STAT_RFE + * @arg @ref LL_XQSPI_QSPI_STAT_TFTF + * @arg @ref LL_XQSPI_QSPI_STAT_TFF + * @arg @ref LL_XQSPI_QSPI_STAT_TFE + * @arg @ref LL_XQSPI_QSPI_STAT_BUSY + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_status(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->QSPI.STAT)); +} + +/** + * @brief Check active flag + * + * \rst + * +----------------------+------------------------------------------------------+ + * | Register | BitsName | + * +======================+======================================================+ + * | STATUS | RXFULL RXWMARK RXEMPTY TXFULL TXWMARK TXEMPTY XFERIP | + * +----------------------+------------------------------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_STAT_RFTF + * @arg @ref LL_XQSPI_QSPI_STAT_RFF + * @arg @ref LL_XQSPI_QSPI_STAT_RFE + * @arg @ref LL_XQSPI_QSPI_STAT_TFTF + * @arg @ref LL_XQSPI_QSPI_STAT_TFF + * @arg @ref LL_XQSPI_QSPI_STAT_TFE + * @arg @ref LL_XQSPI_QSPI_STAT_BUSY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_active_qspi_flag(xqspi_regs_t *XQSPIx, uint32_t flag) +{ + return (READ_BITS(XQSPIx->QSPI.STAT, flag) == (flag)); +} + +/** + * @brief Enable slave select output + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLAVE_SEL | OUT3 OUT2 OUT1 OUT0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param ssout This parameter can between: 0 ~ 0xFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_ssout(xqspi_regs_t *XQSPIx, uint32_t ssout) +{ + SET_BITS(XQSPIx->QSPI.SLAVE_SEL, ssout); +} + +/** + * @brief Disable slave select output + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLAVE_SEL | OUT3 OUT2 OUT1 OUT0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param ssout This parameter can between: 0 ~ 0xFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_ssout(xqspi_regs_t *XQSPIx, uint32_t ssout) +{ + CLEAR_BITS(XQSPIx->QSPI.SLAVE_SEL, ssout); +} + +/** + * @brief Set slave select output polarity + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLAVE_SEL_POL | POL3 POL2 POL1 POL0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param sspol This parameter can between: 0 ~ 0xFF + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_sspol(xqspi_regs_t *XQSPIx, uint32_t sspol) +{ + SET_BITS(XQSPIx->QSPI.SLAVE_SEL_POL, sspol); +} + +/** + * @brief Get slave select output polarity + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SLAVE_SEL_POL | POL3 POL2 POL1 POL0 | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 0xFF + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_sspol(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->QSPI.SLAVE_SEL_POL)); +} + +/** + * @brief Get FIFO Transmission Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | TX_FIFO_LVL | TXFIFOLVL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 16 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_tx_fifo_level(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.TX_FIFO_LVL, XQSPI_QSPI_TXFIFOLVL)); +} + +/** + * @brief Get FIFO reception Level + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | RX_FIFO_LVL | RXFIFOLVL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 16 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_rx_fifo_level(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.RX_FIFO_LVL, XQSPI_QSPI_RXFIFOLVL)); +} + +/** + * @brief Enable interrupt + * @note This bit controls the generation of an interrupt when an event occurs. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_IM_DONE + * @arg @ref LL_XQSPI_QSPI_IM_RFF + * @arg @ref LL_XQSPI_QSPI_IM_RFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi_it(xqspi_regs_t *XQSPIx, uint32_t mask) +{ + SET_BITS(XQSPIx->QSPI.INTEN, mask); +} + +/** + * @brief Disable interrupt + * @note This bit controls the generation of an interrupt when an event occurs. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_IM_DONE + * @arg @ref LL_XQSPI_QSPI_IM_RFF + * @arg @ref LL_XQSPI_QSPI_IM_RFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi_it(xqspi_regs_t *XQSPIx, uint32_t mask) +{ + CLEAR_BITS(XQSPIx->QSPI.INTEN, mask); +} + +/** + * @brief Check if interrupt is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTEN | INT_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param mask This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_IM_DONE + * @arg @ref LL_XQSPI_QSPI_IM_RFF + * @arg @ref LL_XQSPI_QSPI_IM_RFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi_it(xqspi_regs_t *XQSPIx, uint32_t mask) +{ + return (READ_BITS(XQSPIx->QSPI.INTEN, mask) == (mask)); +} + +/** + * @brief Get XQSPI interrupt flags + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | INT_STAT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one or combination of the following values: + * @arg @ref LL_XQSPI_QSPI_IS_DONE + * @arg @ref LL_XQSPI_QSPI_IS_RFF + * @arg @ref LL_XQSPI_QSPI_IS_RFTF + * @arg @ref LL_XQSPI_QSPI_IS_TFTF + * @arg @ref LL_XQSPI_QSPI_IS_TFE + */ +__STATIC_INLINE uint32_t ll_xqspi_get_it_flag(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_REG(XQSPIx->QSPI.INTSTAT)); +} + +/** + * @brief Check interrupt flag + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTSTAT | XFER_DPULSE | + * +----------------------+-----------------------------------+ + * \endrst + * INTSTAT | RX_FPULSE + * INTSTAT | RX_WPULSE + * INTSTAT | TX_WPULSE + * INTSTAT | TX_EPULSE + * + * @param XQSPIx XQSPI instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_IS_DONE + * @arg @ref LL_XQSPI_QSPI_IS_RFF + * @arg @ref LL_XQSPI_QSPI_IS_RFTF + * @arg @ref LL_XQSPI_QSPI_IS_TFTF + * @arg @ref LL_XQSPI_QSPI_IS_TFE + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_qspi_it_flag(xqspi_regs_t *XQSPIx, uint32_t flag) +{ + return (READ_BITS(XQSPIx->QSPI.INTSTAT, flag) == (flag)); +} + +/** + * @brief Clear interrupt flag + * @note Clearing interrupt flag is done by writting INTCLR register + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | INTCLR | INT_CLR | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param flag This parameter can be one of the following values: + * @arg @ref LL_XQSPI_QSPI_IM_DONE + * @arg @ref LL_XQSPI_QSPI_IM_RFF + * @arg @ref LL_XQSPI_QSPI_IM_RFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFTF + * @arg @ref LL_XQSPI_QSPI_IM_TFE + * @retval None + */ +__STATIC_INLINE void ll_xqspi_clear_qspi_flag(xqspi_regs_t *XQSPIx, uint32_t flag) +{ + WRITE_REG(XQSPIx->QSPI.INTCLR, flag); +} + +/** + * @brief Set master inter-transfer delay + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSTR_IT_DELAY | MWAIT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param wait This parameter can between: 0 ~ 255 + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_wait(xqspi_regs_t *XQSPIx, uint32_t wait) +{ + MODIFY_REG(XQSPIx->QSPI.MSTR_IT_DELAY, XQSPI_QSPI_MWAIT_MWAIT, wait << XQSPI_QSPI_MWAIT_MWAIT_Pos); +} + +/** + * @brief Get master inter-transfer delay + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | MSTR_IT_DELAY | MWAIT | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can between: 0 ~ 255 + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_wait(xqspi_regs_t *XQSPIx) +{ + return (uint32_t)(READ_BITS(XQSPIx->QSPI.MSTR_IT_DELAY, XQSPI_QSPI_MWAIT_MWAIT) >> XQSPI_QSPI_MWAIT_MWAIT_Pos); +} + +/** + * @brief Enable QSPI + * @note This bit should not be enable when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SPIEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_qspi(xqspi_regs_t *XQSPIx) +{ + SET_BITS(XQSPIx->QSPI.SPIEN, XQSPI_QSPI_EN_EN); +} + +/** + * @brief Disable QSPI + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SPIEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_qspi(xqspi_regs_t *XQSPIx) +{ + CLEAR_BITS(XQSPIx->QSPI.SPIEN, XQSPI_QSPI_EN_EN); +} + +/** + * @brief Check if QSPI is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | SPIEN | EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enabled_qspi(xqspi_regs_t *XQSPIx) +{ + return (READ_BITS(XQSPIx->QSPI.SPIEN, XQSPI_QSPI_EN_EN) == (XQSPI_QSPI_EN_EN)); +} + +/** + * @brief Set QSPI Flash write bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | FLASH_WRITE | FLASH_WRITE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param bits This parameter can be one of the following values: + * @arg @ref LL_XQSPI_FLASH_WRITE_128BIT + * @arg @ref LL_XQSPI_FLASH_WRITE_32BIT + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_flash_write(xqspi_regs_t *XQSPIx, uint32_t bits) +{ + WRITE_REG(XQSPIx->QSPI.FLASH_WRITE, bits); +} + +/** + * @brief Get QSPI Flash write bits + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | FLASH_WRITE | FLASH_WRITE | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_FLASH_WRITE_128BIT + * @arg @ref LL_XQSPI_FLASH_WRITE_32BIT + */ +__STATIC_INLINE uint32_t ll_xqspi_get_flash_write(xqspi_regs_t *XQSPIx) +{ + //GR5515_C and future version. + return READ_REG(XQSPIx->QSPI.FLASH_WRITE); +} + +/** + * @brief Set QSPI Present Bypass + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BYPASS | BYPASS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @param bypass This parameter can be one of the following values: + * @arg @ref LL_XQSPI_ENABLE_PRESENT + * @arg @ref LL_XQSPI_DISABLE_PRESENT + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_present_bypass(xqspi_regs_t *XQSPIx, uint32_t bypass) +{ + WRITE_REG(XQSPIx->QSPI.BYPASS, bypass); +} + +/** + * @brief Get QSPI Present Bypass + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | BYPASS | BYPASS | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param XQSPIx XQSPI instance + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_ENABLE_PRESENT + * @arg @ref LL_XQSPI_DISABLE_PRESENT + */ +__STATIC_INLINE uint32_t ll_xqspi_get_present_bypass(xqspi_regs_t *XQSPIx) +{ + return READ_REG(XQSPIx->QSPI.BYPASS); +} + +/** + * @brief Enable exflash power + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | EFLASH_PAD_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_exflash_power(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_EFLASH_PAD_EN); +} + +/** + * @brief Disable exflash power + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | EFLASH_PAD_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_exflash_power(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_EFLASH_PAD_EN); +} + +/** + * @brief Check if exflash power is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | EFLASH_PAD_EN | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enable_exflash_power(void) +{ + return (READ_BITS(AON->PWR_RET01, AON_PWR_REG01_EFLASH_PAD_EN) == (AON_PWR_REG01_EFLASH_PAD_EN)); +} + +/** + * @brief Set XQSPI serial clock + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XF_SCK_CLK_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @param speed This parameter can be one of the following values: + * @arg @ref LL_XQSPI_BAUD_RATE_64M + * @arg @ref LL_XQSPI_BAUD_RATE_48M + * @arg @ref LL_XQSPI_BAUD_RATE_32M + * @arg @ref LL_XQSPI_BAUD_RATE_24M + * @arg @ref LL_XQSPI_BAUD_RATE_16M + * @retval None + */ +__STATIC_INLINE void ll_xqspi_set_qspi_speed(uint32_t speed) +{ + MODIFY_REG(AON->PWR_RET01, AON_PWR_REG01_XF_SCK_CLK_SEL, speed); +} + +/** + * @brief Get XQSPI serial clock + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XF_SCK_CLK_SEL | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval Returned Value can be one of the following values: + * @arg @ref LL_XQSPI_BAUD_RATE_64M + * @arg @ref LL_XQSPI_BAUD_RATE_48M + * @arg @ref LL_XQSPI_BAUD_RATE_32M + * @arg @ref LL_XQSPI_BAUD_RATE_24M + * @arg @ref LL_XQSPI_BAUD_RATE_16M + */ +__STATIC_INLINE uint32_t ll_xqspi_get_qspi_speed(void) +{ + return (uint32_t)(READ_BITS(AON->PWR_RET01, AON_PWR_REG01_XF_SCK_CLK_SEL)); +} + +/** + * @brief Enable cache data retention. + * @note This bit should not be changed when XIP is ongoing.. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XF_TAG_RET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_xqspi_enable_cache_retention(void) +{ + SET_BITS(AON->PWR_RET01, AON_PWR_REG01_XF_TAG_RET); +} + +/** + * @brief Disable cache data retention. + * @note This bit should not be changed when XIP is ongoing. + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XF_TAG_RET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval None + */ +__STATIC_INLINE void ll_xqspi_disable_cache_retention(void) +{ + CLEAR_BITS(AON->PWR_RET01, AON_PWR_REG01_XF_TAG_RET); +} + +/** + * @brief Check if tag memory retention is enabled + * + * \rst + * +----------------------+-----------------------------------+ + * | Register | BitsName | + * +======================+===================================+ + * | PWR_RET01 | XF_TAG_RET | + * +----------------------+-----------------------------------+ + * \endrst + * + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t ll_xqspi_is_enable_cache_retention(void) +{ + return (READ_BITS(AON->PWR_RET01, AON_PWR_REG01_XF_TAG_RET) == (AON_PWR_REG01_XF_TAG_RET)); +} + + + +/** @} */ + +/** @defgroup XQSPI_LL_Init XQSPI Initialization and de-initialization functions + * @{ + */ + +/** + * @brief De-initialize XQSPI registers (Registers restored to their default values). + * @param XQSPIx XQSPI instance + * @retval An error_status_t enumeration value: + * - SUCCESS: XQSPI registers are de-initialized + * - ERROR: XQSPI registers are not de-initialized + */ +error_status_t ll_xqspi_deinit(xqspi_regs_t *XQSPIx); + +/** + * @brief Initialize XQSPI registers according to the specified + * parameters in default. + * @param XQSPIx XQSPI instance + * @param p_xqspi_init Pointer to a ll_xqspi_init_t structure that contains the configuration + * information for the specified XQPSI peripheral. + * @retval An error_status_t enumeration value: + * - SUCCESS: XQSPI registers are initialized according to default + * - ERROR: Problem occurred during XQSPI Registers initialization + */ +error_status_t ll_xqspi_init(xqspi_regs_t *XQSPIx, ll_xqspi_init_t *p_xqspi_init); + +/** + * @brief Set each field of a @ref ll_xqspi_init_t type structure to default value. + * @param p_xqspi_init Pointer to a @ref ll_xqspi_init_t structure + * whose fields will be set to default values. + * @retval None + */ +void ll_xqspi_struct_init(ll_xqspi_init_t *p_xqspi_init); + +/** @} */ + +/** @} */ + +#endif /* XQSPI */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_LL_XQSPI_H__ */ + +/** @} */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/grx_hal.h b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/grx_hal.h new file mode 100644 index 0000000..267342c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/inc/hal/grx_hal.h @@ -0,0 +1,71 @@ +/** + **************************************************************************************** + * + * @file grx_hal.h + * @author BLE Driver Team + * @brief This file contains all the functions prototypes for the HAL + * module driver. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + + + +/** @addtogroup HAL_DRIVER HAL Driver + * @{ + */ + +/** @defgroup HAL_HAL HAL + * @brief HAL module driver. + * @{ + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GRX_HAL_H__ +#define __GRX_HAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "gr55xx_hal.h" + + +#ifdef __cplusplus +} +#endif + +#endif /* __GRX_HAL_H__ */ + +/** @} */ + +/** @} */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc.c new file mode 100644 index 0000000..6066e5b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc.c @@ -0,0 +1,489 @@ +/** + **************************************************************************************** + * @file app_adc.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "grx_sys.h" +#include "app_adc.h" + +#ifdef HAL_ADC_MODULE_ENABLED + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +bool adc_prepare_for_sleep(void); +void adc_wake_up_ind(void); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +static const uint32_t s_io_to_input_src[ADC_INPUT_SRC_REF+1] = +{ + MSIO_PIN_0, MSIO_PIN_1, MSIO_PIN_2, MSIO_PIN_3, MSIO_PIN_4, NULL, NULL, NULL +}; +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +adc_env_t *p_adc_env = NULL; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_adc_pwr_id = -1; + +const static app_sleep_callbacks_t adc_sleep_cb = +{ + .app_prepare_for_sleep = adc_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = adc_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +bool adc_prepare_for_sleep(void) +{ + hal_adc_state_t state; + + if (p_adc_env->adc_state == APP_ADC_ACTIVITY) + { + state = hal_adc_get_state(&p_adc_env->handle); + if ((state != HAL_ADC_STATE_READY) && (state != HAL_ADC_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_adc_suspend_reg(&p_adc_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_adc_env.adc_state = APP_ADC_SLEEP; +#endif + } + + return true; +} + +SECTION_RAM_CODE void adc_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + if (p_adc_env->adc_state == APP_ADC_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_adc_resume_reg(&p_adc_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void adc_wake_up(void) +{ + if (p_adc_env->adc_state == APP_ADC_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_adc_resume_reg(&p_adc_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + + p_adc_env->adc_state = APP_ADC_ACTIVITY; + } + + if(p_adc_env->type == APP_ADC_TYPE_DMA) + { + dma_wake_up(p_adc_env->dma_id); + } +} +#endif + +static uint16_t adc_config_gpio(uint32_t input_mode, app_adc_pin_cfg_t pin_cfg, uint32_t ref_source) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.mode = APP_IO_MODE_ANALOG; + io_init.pull = APP_IO_NOPULL; + if (input_mode == LL_ADC_INPUT_DIFFERENTIAL) + { + io_init.pin = pin_cfg.channel_p.pin; + io_init.mux = pin_cfg.channel_p.mux; + err_code = app_io_init(pin_cfg.channel_p.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + io_init.pin = pin_cfg.channel_n.pin; + io_init.mux = pin_cfg.channel_n.mux; + err_code = app_io_init(pin_cfg.channel_n.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + if (ref_source >= LL_ADC_REF_SRC_IO0) + { + io_init.pin = pin_cfg.extern_ref.pin; + io_init.mux = pin_cfg.extern_ref.mux; + err_code = app_io_init(pin_cfg.extern_ref.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_adc_init(app_adc_params_t *p_params, app_adc_evt_handler_t evt_handler) +{ + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + p_adc_env = &(p_params->adc_env); + + app_err_code = adc_config_gpio(p_params->init.input_mode, p_params->pin_cfg, p_params->init.ref_source); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + p_adc_env->evt_handler = evt_handler; + memcpy(&p_adc_env->handle.init, &p_params->init, sizeof(adc_init_t)); + hal_err_code = hal_adc_deinit(&p_adc_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + hal_err_code = hal_adc_init(&p_adc_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if(!s_sleep_cb_registered_flag) // register sleep callback + { + s_sleep_cb_registered_flag = true; + s_adc_pwr_id = pwr_register_sleep_cb(&adc_sleep_cb, APP_DRIVER_ADC_WAPEUP_PRIORITY); + if (s_adc_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_adc_env->adc_state = APP_ADC_ACTIVITY; + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_deinit(void) +{ + hal_status_t hal_err_code; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + p_adc_env->adc_state = APP_ADC_INVALID; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_adc_env->p_current_sample_node = NULL; + p_adc_env->multi_channel = 0; +#endif + + GLOBAL_EXCEPTION_DISABLE(); + pwr_unregister_sleep_cb(s_adc_pwr_id); + s_adc_pwr_id = -1; + s_sleep_cb_registered_flag = false; + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_adc_deinit(&p_adc_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + if (p_adc_env->adc_dma_state == APP_ADC_DMA_INVALID) + { + p_adc_env = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_conversion_sync(uint16_t *p_data, uint32_t length, uint32_t timeout) +{ + hal_status_t err_code; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + err_code = hal_adc_poll_for_conversion(&p_adc_env->handle, p_data, length); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_conversion_async(uint16_t *p_data, uint32_t length) +{ + hal_status_t err_code; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_adc_env->adc_dma_state == APP_ADC_DMA_INVALID) + { + return APP_DRV_ERR_INVALID_MODE; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + err_code = hal_adc_start_dma(&p_adc_env->handle, p_data, length); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_adc_multi_channel_conversion_async(app_adc_sample_node_t *p_begin_node, uint32_t total_nodes) +{ + hal_status_t err_code; + uint32_t check_node_num; + app_adc_sample_node_t *p_check_node; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_begin_node == NULL || total_nodes == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_adc_env->adc_dma_state == APP_ADC_DMA_INVALID) + { + return APP_DRV_ERR_INVALID_MODE; + } + + check_node_num = total_nodes; + p_check_node = p_begin_node; + while (check_node_num)//check samle link node + { + if( (p_check_node->channel > ADC_INPUT_SRC_REF) || (p_check_node->p_buf == NULL) || ((check_node_num>1)&&(p_check_node->next == NULL))) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (--check_node_num) + { + p_check_node = p_check_node->next; + } + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + if(HAL_ADC_STATE_READY != hal_adc_get_state(&p_adc_env->handle)) + { + return APP_DRV_ERR_BUSY; + } + + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + io_init.mode = APP_IO_MODE_ANALOG; + io_init.mux = APP_IO_MUX_7; + check_node_num = total_nodes; + p_check_node = p_begin_node; + while (check_node_num)//config all msios + { + if (s_io_to_input_src[p_check_node->channel] != NULL) + { + io_init.pin = s_io_to_input_src[p_check_node->channel]; + app_io_init(APP_IO_TYPE_MSIO, &io_init); + } + + if (--check_node_num) + { + p_check_node = p_check_node->next; + } + } + + p_adc_env->handle.init.input_mode = ADC_INPUT_SINGLE;//multi sample must under single mode + p_adc_env->handle.init.channel_n = p_begin_node->channel; + err_code = hal_adc_init(&p_adc_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_adc_env->p_current_sample_node = p_begin_node; + p_adc_env->multi_channel = total_nodes; + err_code = hal_adc_start_dma(&p_adc_env->handle, p_begin_node->p_buf, p_begin_node->len); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} +#endif + +uint16_t app_adc_voltage_intern(uint16_t *inbuf, double *outbuf, uint32_t buflen) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (inbuf == NULL || outbuf == NULL || buflen == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_adc_voltage_intern(&p_adc_env->handle, inbuf, outbuf, buflen); + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_voltage_extern(double ref, uint16_t *inbuf, double *outbuf, uint32_t buflen) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (inbuf == NULL || outbuf == NULL || buflen == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_adc_voltage_extern(&p_adc_env->handle, ref, inbuf, outbuf, buflen); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +uint16_t app_adc_temperature_conv(uint16_t *inbuf, double *outbuf, uint32_t buflen) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (inbuf == NULL || outbuf == NULL || buflen == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_adc_temperature_conv(&p_adc_env->handle, inbuf, outbuf, buflen); + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_vbat_conv(uint16_t *inbuf, double *outbuf, uint32_t buflen) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (inbuf == NULL || outbuf == NULL || buflen == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + hal_adc_vbat_conv(&p_adc_env->handle, inbuf, outbuf, buflen); + + return APP_DRV_SUCCESS; +} +#endif + +adc_handle_t *app_adc_get_handle(void) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + return &p_adc_env->handle; +} + +void hal_adc_conv_cplt_callback(adc_handle_t *p_adc) +{ + app_adc_evt_t evt; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if(p_adc_env->multi_channel > 0) + { + p_adc_env->multi_channel--; + } + + if(p_adc_env->multi_channel == 0) + { +#endif + evt.type = APP_ADC_EVT_CONV_CPLT; + + if (p_adc_env->evt_handler != NULL) + { + p_adc_env->evt_handler(&evt); + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + } + else + { + p_adc_env->p_current_sample_node = p_adc_env->p_current_sample_node->next; + ll_adc_set_channeln(p_adc_env->p_current_sample_node->channel); + hal_adc_start_dma(&p_adc_env->handle, p_adc_env->p_current_sample_node->p_buf, p_adc_env->p_current_sample_node->len); + } +#endif +} + +uint16_t adc_get_trim_func(adc_trim_info_t *p_adc_trim) +{ + return sys_adc_trim_get(p_adc_trim); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc_dma.c new file mode 100644 index 0000000..bb626d3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_adc_dma.c @@ -0,0 +1,239 @@ +/** + **************************************************************************************** + * @file app_adc_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include + +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "grx_sys.h" +#include "app_adc.h" +#include "app_adc_dma.h" + +#ifdef HAL_ADC_MODULE_ENABLED + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +extern void adc_wake_up(void); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +static const uint32_t s_io_to_input_src[ADC_INPUT_SRC_REF + 1] = +{ + MSIO_PIN_0, MSIO_PIN_1, MSIO_PIN_2, MSIO_PIN_3, MSIO_PIN_4, NULL, NULL, NULL +}; +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern adc_env_t *p_adc_env; + +static uint16_t adc_config_dma(app_adc_params_t *p_params) +{ + app_dma_params_t dma_params = { 0 }; + + dma_params.p_instance = p_params->dma_cfg.dma_instance; + if (dma_params.p_instance != DMA0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + dma_params.channel_number = p_params->dma_cfg.dma_channel; + dma_params.init.src_request = DMA0_REQUEST_SNSADC; + dma_params.init.direction = DMA_PERIPH_TO_MEMORY; + dma_params.init.src_increment = DMA_SRC_NO_CHANGE; + dma_params.init.dst_increment = DMA_DST_INCREMENT; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + dma_params.init.mode = DMA_NORMAL; +#endif + dma_params.init.priority = DMA_PRIORITY_LOW; + + p_adc_env->dma_id = app_dma_init(&dma_params, NULL); + if (p_adc_env->dma_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + p_adc_env->handle.p_dma = app_dma_get_handle(p_adc_env->dma_id); + p_adc_env->handle.p_dma->p_parent = (void*)&p_adc_env->handle; + + return APP_DRV_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_adc_dma_init(app_adc_params_t *p_params) +{ + app_drv_err_t app_err_code; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + GLOBAL_EXCEPTION_DISABLE(); + p_adc_env->dma_id = -1; + app_err_code = adc_config_dma(p_params); + GLOBAL_EXCEPTION_ENABLE(); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + GLOBAL_EXCEPTION_DISABLE(); + p_adc_env->adc_dma_state = APP_ADC_DMA_ACTIVITY; + GLOBAL_EXCEPTION_ENABLE(); + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_dma_deinit(void) +{ + if ((p_adc_env == NULL) || (p_adc_env->adc_dma_state != APP_ADC_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_adc_env->dma_id); + + GLOBAL_EXCEPTION_DISABLE(); + p_adc_env->adc_dma_state = APP_ADC_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + if (p_adc_env->adc_state == APP_ADC_INVALID) + { + p_adc_env = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_adc_dma_conversion_async(uint16_t *p_data, uint32_t length) +{ + hal_status_t err_code; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + err_code = hal_adc_start_dma(&p_adc_env->handle, p_data, length); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_adc_dma_multi_channel_conversion_async(app_adc_sample_node_t *p_begin_node, uint32_t total_nodes) +{ + hal_status_t err_code; + uint32_t check_node_num; + app_adc_sample_node_t *p_check_node; + + if ((p_adc_env == NULL) || (p_adc_env->adc_state == APP_ADC_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_begin_node == NULL || total_nodes == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + check_node_num = total_nodes; + p_check_node = p_begin_node; + while (check_node_num) //check samle link node + { + if ((p_check_node->channel > ADC_INPUT_SRC_REF) || (p_check_node->p_buf == NULL) || ((check_node_num>1)&&(p_check_node->next == NULL))) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (--check_node_num) + { + p_check_node = p_check_node->next; + } + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + adc_wake_up(); +#endif + + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + io_init.mode = APP_IO_MODE_ANALOG; + io_init.mux = APP_IO_MUX_7; + check_node_num = total_nodes; + p_check_node = p_begin_node; + while (check_node_num)//config all msios + { + if (s_io_to_input_src[p_check_node->channel] != NULL) + { + io_init.pin = s_io_to_input_src[p_check_node->channel]; + app_io_init(APP_IO_TYPE_MSIO, &io_init); + } + + if (--check_node_num) + { + p_check_node = p_check_node->next; + } + } + + p_adc_env->handle.init.input_mode = ADC_INPUT_SINGLE;//multi sample must under single mode + p_adc_env->handle.init.channel_n = p_begin_node->channel; + err_code = hal_adc_init(&p_adc_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_adc_env->p_current_sample_node = p_begin_node; + p_adc_env->multi_channel = total_nodes; + err_code = hal_adc_start_dma(&p_adc_env->handle, p_begin_node->p_buf, p_begin_node->len); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_aon_wdt.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_aon_wdt.c new file mode 100644 index 0000000..a5bbb53 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_aon_wdt.c @@ -0,0 +1,166 @@ +/** + **************************************************************************************** + * @file app_aon_wdt.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_aon_wdt.h" +#include "app_drv.h" +#include "gr_soc.h" +#include + +#ifdef HAL_AON_WDT_MODULE_ENABLED + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * EXTERN VARIABLE + ***************************************************************************************** + */ + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +extern uint32_t SystemSlowClock; +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +aon_aon_wdt_env_t *p_aon_wdt_env = NULL; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ + +void AON_WDT_IRQHandler(void); + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_aon_wdt_event_call(aon_wdt_handle_t *p_aon_wdt) +{ + if(p_aon_wdt_env->evt_handler != NULL) + { + p_aon_wdt_env->evt_handler(); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_aon_wdt_init(app_aon_wdt_params_t *p_params, app_aon_wdt_evt_handler_t evt_handler) +{ + hal_status_t err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + p_aon_wdt_env = &p_params->aon_aon_wdt_env; + + memcpy(&p_aon_wdt_env->handle.init, &p_params->init, sizeof(aon_wdt_init_t)); + err_code = hal_aon_wdt_deinit(&p_aon_wdt_env->handle); + HAL_ERR_CODE_CHECK(err_code); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + p_aon_wdt_env->handle.SystemCoreLowClock = &SystemSlowClock; +#endif + + err_code = hal_aon_wdt_init(&p_aon_wdt_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_aon_wdt_env->evt_handler = evt_handler; + p_aon_wdt_env->aon_wdt_state = APP_AON_WDT_ACTIVITY; + + soc_register_nvic(AON_WDT_IRQn, (uint32_t)AON_WDT_IRQHandler); + NVIC_ClearPendingIRQ(AON_WDT_IRQn); + NVIC_EnableIRQ(AON_WDT_IRQn); + + return APP_DRV_SUCCESS; +} + +uint16_t app_aon_wdt_deinit(void) +{ + hal_status_t err_code; + + if ((p_aon_wdt_env == NULL) || (p_aon_wdt_env->aon_wdt_state == APP_AON_WDT_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_aon_wdt_deinit(&p_aon_wdt_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_aon_wdt_env = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_aon_wdt_refresh(void) +{ + hal_status_t err_code; + + if ((p_aon_wdt_env == NULL) || (p_aon_wdt_env->aon_wdt_state == APP_AON_WDT_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_aon_wdt_refresh(&p_aon_wdt_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +void hal_aon_wdt_alarm_callback(aon_wdt_handle_t *p_aon_wdt) +{ + app_aon_wdt_event_call(p_aon_wdt); +} + +SECTION_RAM_CODE void AON_WDT_IRQHandler(void) +{ + hal_aon_wdt_irq_handler(&p_aon_wdt_env->handle); +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_bod.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_bod.c new file mode 100644 index 0000000..7935764 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_bod.c @@ -0,0 +1,239 @@ +/** + **************************************************************************************** + * @file app_bod.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_bod.h" +#include "gr_soc.h" +#include + +#ifdef HAL_BOD_MODULE_ENABLED + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +bod_env_t *p_bod_env = NULL; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ + +void BOD_ASSERT_IRQHandler(void); +void BOD_DEASSERT_IRQHandler(void); + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_bod_event_call(bod_handle_t *p_calendar, app_bod_evt_type_t evt_type) +{ + app_bod_evt_t bod_evt; + + bod_evt.type = evt_type; + if(p_bod_env->evt_handler != NULL) + { + p_bod_env->evt_handler(&bod_evt); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_bod_init(app_bod_params_t *p_params, app_bod_evt_handler_t evt_handler) +{ + hal_status_t err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + p_bod_env = &p_params->bod_env; + + memcpy(&p_bod_env->handle.init, &p_params->init, sizeof(bod_init_t)); + err_code = hal_bod_deinit(&p_bod_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + err_code = hal_bod_init(&p_bod_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_bod_env->evt_handler = evt_handler; + p_bod_env->bod_state = APP_BOD_ACTIVITY; + + + soc_register_nvic(BOD_ASSERT_IRQn, (uint32_t)BOD_ASSERT_IRQHandler); + NVIC_ClearPendingIRQ(BOD_ASSERT_IRQn); + NVIC_EnableIRQ(BOD_ASSERT_IRQn); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) ||(APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + soc_register_nvic(BOD_DEASSERT_IRQn, (uint32_t)BOD_DEASSERT_IRQHandler); + NVIC_ClearPendingIRQ(BOD_DEASSERT_IRQn); + NVIC_EnableIRQ(BOD_DEASSERT_IRQn); +#endif + + return APP_DRV_SUCCESS; +} + +uint16_t app_bod_deinit(void) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod_deinit(&p_bod_env->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_bod_env->bod_state = APP_BOD_INVALID; + p_bod_env = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_bod_enable(uint8_t enable) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod_enable(&p_bod_env->handle, enable); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_bod_event_enable(uint8_t enable) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod2_enable(&p_bod_env->handle, enable); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_bod_event_set_level(uint8_t level) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod2_set_level(&p_bod_env->handle, level); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_bod_static_mode_enable(uint8_t enable) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod_static_mode_enable(&p_bod_env->handle, enable); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +uint16_t app_bod_event_auto_power_bypass_enable(uint8_t enable) +{ + hal_status_t err_code; + + if ((p_bod_env == NULL) || (p_bod_env->bod_state == APP_BOD_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_bod2_auto_power_bypass_enable(&p_bod_env->handle, enable); + + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#endif + +void hal_bod_fedge_callback(bod_handle_t *p_bod) +{ + app_bod_event_call(p_bod, APP_BOD_EVT_TRIGGERED); +} + +SECTION_RAM_CODE void BOD_ASSERT_IRQHandler(void) +{ + hal_bod_fedge_irq_handler(&p_bod_env->handle); +} + +/* BOD disappear event */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) ||(APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) +void hal_bod_redge_callback(bod_handle_t *p_bod) +{ + app_bod_event_call(p_bod, APP_BOD_EVT_REMOVED); +} + +SECTION_RAM_CODE void BOD_DEASSERT_IRQHandler(void) +{ + hal_bod_redge_irq_handler(&p_bod_env->handle); +} +#endif +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_comp.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_comp.c new file mode 100644 index 0000000..71c5861 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_comp.c @@ -0,0 +1,354 @@ +/** + **************************************************************************************** + * @file app_comp.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_comp.h" +#include "app_pwr_mgmt.h" +#include "string.h" +#include "gr_soc.h" + +#ifdef HAL_COMP_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool comp_prepare_for_sleep(void); +static void comp_wake_up_ind(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +comp_env_t *p_comp_env = NULL; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_comp_pwr_id = -1; + +const static app_sleep_callbacks_t comp_sleep_cb = +{ + .app_prepare_for_sleep = comp_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = comp_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool comp_prepare_for_sleep(void) +{ + if (p_comp_env->comp_state == APP_COMP_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_comp_suspend_reg(&p_comp_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_comp_env->comp_state = APP_COMP_SLEEP; +#endif + } + + return true; +} + +SECTION_RAM_CODE static void comp_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + if (p_comp_env->comp_state == APP_COMP_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_comp_resume_reg(&p_comp_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + hal_nvic_clear_pending_irq(COMP_IRQn); + hal_nvic_enable_irq(COMP_IRQn); +#endif + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +static void comp_wake_up(void) +{ + if (p_comp_env->comp_state == APP_COMP_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_comp_resume_reg(&p_comp_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + hal_nvic_clear_pending_irq(COMP_IRQn); + hal_nvic_enable_irq(COMP_IRQn); +#else + hal_nvic_clear_pending_irq(COMP_EXT_IRQn); + hal_nvic_enable_irq(COMP_EXT_IRQn); +#endif + p_comp_env->comp_state = APP_COMP_ACTIVITY; + } +} +#endif + +static uint16_t comp_config_gpio(uint32_t ref_source, app_comp_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.mode = APP_IO_MODE_ANALOG; + io_init.pull = APP_IO_NOPULL; + io_init.pin = pin_cfg.input.pin; + io_init.mux = pin_cfg.input.mux; + err_code = app_io_init(pin_cfg.input.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + if (ref_source != COMP_REF_SRC_VBAT && ref_source != COMP_REF_SRC_VREF) + { + io_init.pin = pin_cfg.vref.pin; + io_init.mux = pin_cfg.vref.mux; + err_code = app_io_init(pin_cfg.vref.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +void hal_comp_rising_trigger_callback(comp_handle_t *p_comp) +{ + app_comp_evt_t comp_evt = APP_COMP_EVT_RISING; + + if (p_comp_env->evt_handler != NULL) + { + p_comp_env->evt_handler(&comp_evt); + } +} + +void hal_comp_falling_trigger_callback(comp_handle_t *p_comp) +{ + app_comp_evt_t comp_evt = APP_COMP_EVT_FALLING; + + if (p_comp_env->evt_handler != NULL) + { + p_comp_env->evt_handler(&comp_evt); + } +} +#else +static void app_comp_event_call(comp_handle_t *p_comp, app_comp_evt_t evt_type) +{ + app_comp_evt_t comp_evt = APP_COMP_EVT_ERROR; + + if (evt_type == APP_COMP_EVT_DONE) + { + comp_evt = APP_COMP_EVT_DONE; + } + + if (p_comp_env->evt_handler != NULL) + { + p_comp_env->evt_handler(&comp_evt); + } +} +void hal_comp_trigger_callback(comp_handle_t *p_comp) +{ + app_comp_event_call(p_comp, APP_COMP_EVT_DONE); +} +#endif + +SECTION_RAM_CODE void COMP_IRQHandler(void) +{ + hal_comp_irq_handler(&p_comp_env->handle); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_comp_init(app_comp_params_t *p_params, app_comp_evt_handler_t evt_handler) +{ + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + p_comp_env = &p_params->comp_env; + app_err_code = comp_config_gpio(p_params->init.ref_source, p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + soc_register_nvic(COMP_EXT_IRQn, (uint32_t)COMP_IRQHandler); + hal_nvic_clear_pending_irq(COMP_EXT_IRQn); + hal_nvic_enable_irq(COMP_EXT_IRQn); +#else + soc_register_nvic(COMP_IRQn, (uint32_t)COMP_IRQHandler); + hal_nvic_clear_pending_irq(COMP_IRQn); + hal_nvic_enable_irq(COMP_IRQn); +#endif + + p_comp_env->p_pin_cfg = &p_params->pin_cfg; + p_comp_env->evt_handler = evt_handler; + memcpy(&p_comp_env->handle.init, &p_params->init, sizeof(comp_init_t)); + hal_err_code = hal_comp_deinit(&p_comp_env->handle); + APP_DRV_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_comp_init(&p_comp_env->handle); + APP_DRV_ERR_CODE_CHECK(hal_err_code); + + if(s_sleep_cb_registered_flag == false) // register sleep callback + { + s_sleep_cb_registered_flag = true; + s_comp_pwr_id = pwr_register_sleep_cb(&comp_sleep_cb, APP_DRIVER_COMP_WAPEUP_PRIORITY); + if (s_comp_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_comp_env->comp_state = APP_COMP_ACTIVITY; + + return 0; +} + +uint16_t app_comp_deinit(void) +{ + hal_status_t hal_err_code; + + if ((p_comp_env == NULL) || (p_comp_env->comp_state == APP_COMP_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + app_drv_err_t app_err_code; + app_err_code = app_io_deinit(p_comp_env->p_pin_cfg->input.type, p_comp_env->p_pin_cfg->input.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + if (p_comp_env->handle.init.ref_source != COMP_REF_SRC_VBAT && + p_comp_env->handle.init.ref_source != COMP_REF_SRC_VREF) + { + app_err_code = app_io_deinit(p_comp_env->p_pin_cfg->vref.type, p_comp_env->p_pin_cfg->vref.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + hal_nvic_disable_irq(COMP_IRQn); +#else + hal_nvic_disable_irq(COMP_EXT_IRQn); +#endif + + p_comp_env->comp_state = APP_COMP_INVALID; + + GLOBAL_EXCEPTION_DISABLE(); + pwr_unregister_sleep_cb(s_comp_pwr_id); + s_comp_pwr_id = -1; + s_sleep_cb_registered_flag = false; + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_comp_deinit(&p_comp_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + p_comp_env = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_comp_start(void) +{ + hal_status_t hal_err_code = HAL_ERROR; + + if ((p_comp_env == NULL) || (p_comp_env->comp_state == APP_COMP_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + comp_wake_up(); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + pwr_mgmt_wakeup_source_setup(PWR_WKUP_COND_MSIO_COMP); +#endif + + hal_err_code = hal_comp_start(&p_comp_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_comp_stop(void) +{ + hal_status_t hal_err_code = HAL_ERROR; + + if ((p_comp_env == NULL) || (p_comp_env->comp_state == APP_COMP_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + comp_wake_up(); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + pwr_mgmt_wakeup_source_clear(PWR_WKUP_COND_MSIO_COMP); +#endif + + hal_err_code = hal_comp_stop(&p_comp_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} + +comp_handle_t *app_comp_get_handle(void) +{ + if ((p_comp_env == NULL) || (p_comp_env->comp_state == APP_COMP_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + comp_wake_up(); +#endif + + return &p_comp_env->handle; +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dma.c new file mode 100644 index 0000000..bbe9aa6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dma.c @@ -0,0 +1,561 @@ +/** + **************************************************************************************** + * @file app_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include +#include +#include "gr_soc.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +#define DMA_HANDLE_MAX 5 +#elif (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define DMA_HANDLE_MAX 8 +#elif (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#define DMA_HANDLE_MAX 12 +#endif + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool dma_prepare_for_sleep(void); +static void dma_wake_up_ind(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static bool s_sleep_cb_registered_flag = false; +dma_env_t s_dma_env[DMA_HANDLE_MAX]; +static pwr_id_t s_dma_pwr_id = -1; + +static const app_sleep_callbacks_t dma_sleep_cb = +{ + .app_prepare_for_sleep = dma_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = dma_wake_up_ind, +}; + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +SECTION_RAM_CODE void DMA0_IRQHandler(void) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if ((s_dma_env[i].dma_state == APP_DMA_ACTIVITY) && (s_dma_env[i].handle.p_instance == DMA0)) + { + hal_dma_irq_handler(&s_dma_env[i].handle); + } + } +} +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +SECTION_RAM_CODE void DMA1_IRQHandler(void) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if ((s_dma_env[i].dma_state == APP_DMA_ACTIVITY) && (s_dma_env[i].handle.p_instance == DMA1)) + { + hal_dma_irq_handler(&s_dma_env[i].handle); + } + } +} +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +SECTION_RAM_CODE void DMA_IRQHandler(void) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if (s_dma_env[i].dma_state == APP_DMA_ACTIVITY) + { + hal_dma_irq_handler(&s_dma_env[i].handle); + } + } +} +#endif + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool dma_prepare_for_sleep(void) +{ + hal_dma_state_t state; + + for (uint8_t i = 0; i < DMA_HANDLE_MAX; i++) + { + if (s_dma_env[i].dma_state == APP_DMA_ACTIVITY) + { + state = hal_dma_get_state(&s_dma_env[i].handle); + if ((state != HAL_DMA_STATE_RESET) && (state != HAL_DMA_STATE_READY)) + { + return false; + } + hal_dma_suspend_reg(&s_dma_env[i].handle); + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + s_dma_env[i].dma_state = APP_DMA_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE static void dma_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + bool find = false; +#endif + + for (uint8_t i = 0; i < DMA_HANDLE_MAX; i++) + { + if (s_dma_env[i].dma_state == APP_DMA_ACTIVITY) + { + hal_dma_resume_reg(&s_dma_env[i].handle); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + find = true; +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + if (DMA0 == s_dma_env[i].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA0_IRQn)) + { + hal_nvic_clear_pending_irq(DMA0_IRQn); + hal_nvic_enable_irq(DMA0_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (DMA1 == s_dma_env[i].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA1_IRQn)) + { + hal_nvic_clear_pending_irq(DMA1_IRQn); + hal_nvic_enable_irq(DMA1_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (find) + { + hal_nvic_clear_pending_irq(DMA_IRQn); + hal_nvic_enable_irq(DMA_IRQn); + } +#endif + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void dma_wake_up(dma_id_t id) +{ + if (id < 0 || id >= DMA_HANDLE_MAX) + return; + + if (s_dma_env[id].dma_state == APP_DMA_SLEEP) + { + hal_dma_resume_reg(&s_dma_env[id].handle); + s_dma_env[id].dma_state = APP_DMA_ACTIVITY; + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + if(DMA0 == s_dma_env[id].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA0_IRQn)) + { + hal_nvic_clear_pending_irq(DMA0_IRQn); + hal_nvic_enable_irq(DMA0_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if(DMA1 == s_dma_env[id].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA1_IRQn)) + { + hal_nvic_clear_pending_irq(DMA1_IRQn); + hal_nvic_enable_irq(DMA1_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (!NVIC_GetEnableIRQ(DMA_IRQn)) + { + hal_nvic_clear_pending_irq(DMA_IRQn); + hal_nvic_enable_irq(DMA_IRQn); + } +#endif + } +} +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void dma_tfr_callback(struct _dma_handle *hdma) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if ((s_dma_env[i].dma_state == APP_DMA_ACTIVITY) && + (s_dma_env[i].handle.channel == hdma->channel) +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + && (s_dma_env[i].handle.p_instance == hdma->p_instance) +#endif + ) + { + if(NULL != s_dma_env[i].evt_handler) + { + s_dma_env[i].evt_handler(APP_DMA_EVT_TFR); + } + break; + } + } +} + +void dma_err_callback(struct _dma_handle * hdma) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if ((s_dma_env[i].dma_state == APP_DMA_ACTIVITY) && + (s_dma_env[i].handle.channel == hdma->channel) +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + && (s_dma_env[i].handle.p_instance == hdma->p_instance) +#endif + ) + + { + if(NULL != s_dma_env[i].evt_handler) + { + s_dma_env[i].evt_handler(APP_DMA_EVT_ERROR); + } + break; + } + } +} + +void dma_blk_callback(struct _dma_handle * hdma) +{ + uint8_t i; + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if ((s_dma_env[i].dma_state == APP_DMA_ACTIVITY) && + (s_dma_env[i].handle.channel == hdma->channel) +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + && (s_dma_env[i].handle.p_instance == hdma->p_instance) +#endif + ) + { + if(NULL != s_dma_env[i].evt_handler) + { + s_dma_env[i].evt_handler(APP_DMA_EVT_BLK); + } + break; + } + } +} + +dma_id_t app_dma_init(app_dma_params_t *p_params, app_dma_evt_handler_t evt_handler) +{ + uint8_t i = 0; + dma_id_t id = -1; + hal_status_t status = HAL_ERROR; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + soc_register_nvic(DMA_IRQn, (uint32_t)DMA_IRQHandler); +#else + soc_register_nvic(DMA0_IRQn, (uint32_t)DMA0_IRQHandler); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + soc_register_nvic(DMA1_IRQn, (uint32_t)DMA1_IRQHandler); +#endif + + if (NULL != p_params) + { + if(!IS_DMA_ALL_INSTANCE(p_params->channel_number)) + { + return -1; + } + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < DMA_HANDLE_MAX; i++) + { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (s_dma_env[i].dma_state == APP_DMA_INVALID || \ + s_dma_env[i].handle.channel == p_params->channel_number) +#else + if (s_dma_env[i].dma_state == APP_DMA_INVALID || \ + (s_dma_env[i].handle.p_instance == p_params->p_instance && \ + s_dma_env[i].handle.channel == p_params->channel_number)) +#endif + { + if(HAL_DMA_STATE_BUSY == s_dma_env[i].handle.state) + { + i = DMA_HANDLE_MAX; + break; + } + else + { + id = i; + s_dma_env[i].dma_state = APP_DMA_ACTIVITY; + break; + } + } + } + GLOBAL_EXCEPTION_ENABLE(); + + if (i < DMA_HANDLE_MAX) + { + if (s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_dma_pwr_id = pwr_register_sleep_cb(&dma_sleep_cb, APP_DRIVER_DMA_WAPEUP_PRIORITY); + } +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + s_dma_env[i].handle.p_instance = p_params->p_instance; +#endif + s_dma_env[i].handle.channel = p_params->channel_number; + memcpy(&s_dma_env[i].handle.init, &p_params->init, sizeof(dma_init_t)); + s_dma_env[i].handle.xfer_tfr_callback = dma_tfr_callback; + s_dma_env[i].handle.xfer_error_callback = dma_err_callback; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + s_dma_env[i].handle.xfer_blk_callback = dma_blk_callback; +#endif + s_dma_env[i].handle.xfer_abort_callback = NULL; + s_dma_env[i].evt_handler = evt_handler; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + if(DMA0 == s_dma_env[i].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA0_IRQn)) + { + hal_nvic_clear_pending_irq(DMA0_IRQn); + hal_nvic_enable_irq(DMA0_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (DMA1 == s_dma_env[i].handle.p_instance) + { + if (!NVIC_GetEnableIRQ(DMA1_IRQn)) + { + hal_nvic_clear_pending_irq(DMA1_IRQn); + hal_nvic_enable_irq(DMA1_IRQn); + } + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + hal_nvic_clear_pending_irq(DMA_IRQn); + hal_nvic_enable_irq(DMA_IRQn); +#endif + + status = hal_dma_init(&s_dma_env[i].handle); + } + } + + if (HAL_OK != status) + { + id = -1; + } + + return id; +} + +uint16_t app_dma_deinit(dma_id_t id) +{ + uint8_t i; + + if ((id < 0) || (id >= DMA_HANDLE_MAX)) + { + return APP_DRV_ERR_INVALID_ID; + } + + if (s_dma_env[id].dma_state == APP_DMA_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_dma_deinit(&s_dma_env[id].handle); + s_dma_env[id].dma_state = APP_DMA_INVALID; + s_dma_env[id].handle.channel = (dma_channel_t)(-1); + + for (i = 0; i < DMA_HANDLE_MAX; i++) + { + if (s_dma_env[i].dma_state == APP_DMA_ACTIVITY) + { + break; + } + } + + if (i == DMA_HANDLE_MAX) + { + pwr_unregister_sleep_cb(s_dma_pwr_id); + s_dma_pwr_id = -1; + s_sleep_cb_registered_flag = false; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + hal_nvic_disable_irq(DMA0_IRQn); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + hal_nvic_disable_irq(DMA1_IRQn); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + hal_nvic_disable_irq(DMA_IRQn); +#endif + } + GLOBAL_EXCEPTION_ENABLE(); + + return APP_DRV_SUCCESS; +} + +dma_handle_t *app_dma_get_handle(dma_id_t id) +{ + if ((id < 0) || (id >= DMA_HANDLE_MAX)) + { + return NULL; + } + + if (s_dma_env[id].dma_state == APP_DMA_INVALID) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dma_wake_up(id); +#endif + + return &s_dma_env[id].handle; +} + +uint16_t app_dma_start(dma_id_t id, uint32_t src_address, uint32_t dst_address, uint32_t data_length) +{ + hal_status_t status = HAL_ERROR; + + if ((id < 0) || (id >= DMA_HANDLE_MAX)) + { + return APP_DRV_ERR_INVALID_ID; + } + + if (s_dma_env[id].dma_state == APP_DMA_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((data_length < 1) || (data_length > 0xFFF)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dma_wake_up(id); +#endif + + status = hal_dma_start_it(&s_dma_env[id].handle, src_address, dst_address, data_length); + if (HAL_OK != status) + { + return (uint16_t)status; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +uint16_t app_dma_start_sg_llp(dma_id_t id, uint32_t src_address, uint32_t dst_address, uint32_t data_length, dma_sg_llp_config_t *sg_llp_config) +{ + hal_status_t status = HAL_ERROR; + + if ((id < 0) || (id >= DMA_HANDLE_MAX)) + { + return APP_DRV_ERR_INVALID_ID; + } + + if (s_dma_env[id].dma_state == APP_DMA_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((data_length < 1) || (data_length > 0xFFF)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dma_wake_up(id); +#endif + + status = hal_dma_start_sg_llp_it(&s_dma_env[id].handle, src_address, dst_address, data_length, sg_llp_config); + if (HAL_OK != status) + { + return (uint16_t)status; + } + + return APP_DRV_SUCCESS; +} +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dual_tim.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dual_tim.c new file mode 100644 index 0000000..7cee17a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_dual_tim.c @@ -0,0 +1,701 @@ +/** + **************************************************************************************** + * @file app_dual_tim.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_dual_tim.h" +#include "app_drv.h" +#include "string.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" + +#ifdef HAL_DUAL_TIMER_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool dual_tim_prepare_for_sleep(void); +static void dual_tim_wake_up_ind(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const IRQn_Type s_dual_tim_irq[APP_DUAL_TIM_ID_MAX] = { DUAL_TIMER_IRQn, DUAL_TIMER_IRQn }; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +static const uint32_t s_dual_tim_instance[APP_DUAL_TIM_ID_MAX] = { DUAL_TIMER0_BASE, DUAL_TIMER1_BASE }; +#else +static const uint32_t s_dual_tim_instance[APP_DUAL_TIM_ID_MAX] = { DUAL_TIM0_BASE, DUAL_TIM1_BASE }; +#endif + +static bool s_sleep_cb_registered_flag = false; +static dual_tim_env_t *p_dual_tim_env[APP_DUAL_TIM_ID_MAX]; +static pwr_id_t s_dual_tim_pwr_id; + +const static app_sleep_callbacks_t dual_tim_sleep_cb = +{ + .app_prepare_for_sleep = dual_tim_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = dual_tim_wake_up_ind, +}; + +SECTION_RAM_CODE void DUAL_TIMER_IRQHandler(void) +{ + if (p_dual_tim_env[0] != NULL) + { + if (p_dual_tim_env[0]->dual_tim_state != APP_DUAL_TIM_INVALID) + { + hal_dual_timer_irq_handler(&p_dual_tim_env[0]->handle); + } + } + + if (p_dual_tim_env[1] != NULL) + { + if (p_dual_tim_env[1]->dual_tim_state != APP_DUAL_TIM_INVALID) + { + hal_dual_timer_irq_handler(&p_dual_tim_env[1]->handle); + } + } +} + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool dual_tim_prepare_for_sleep(void) +{ +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + for (uint8_t i = 0; i < APP_DUAL_TIM_ID_MAX; i++) + { + if (p_dual_tim_env[i] == NULL) + { + continue; + } + if (p_dual_tim_env[i]->dual_tim_state == APP_DUAL_TIM_ACTIVITY) + { + p_dual_tim_env[i]->dual_tim_state = APP_DUAL_TIM_SLEEP; + } + } +#endif + + return true; +} + +SECTION_RAM_CODE static void dual_tim_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + for (uint8_t i = 0; i < APP_DUAL_TIM_ID_MAX; i++) + { + if (p_dual_tim_env[i] == NULL) + { + continue; + } + + if (p_dual_tim_env[i]->dual_tim_state == APP_DUAL_TIM_ACTIVITY) + { + hal_nvic_clear_pending_irq(s_dual_tim_irq[i]); + hal_nvic_enable_irq(s_dual_tim_irq[i]); + + hal_dual_timer_base_deinit(&p_dual_tim_env[i]->handle); + hal_dual_timer_base_init(&p_dual_tim_env[i]->handle); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +static void dual_tim_wake_up(app_dual_tim_id_t id) +{ + if (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_SLEEP) + { + hal_nvic_clear_pending_irq(s_dual_tim_irq[id]); + hal_nvic_enable_irq(s_dual_tim_irq[id]); + + hal_dual_timer_base_deinit(&p_dual_tim_env[id]->handle); + hal_dual_timer_base_init(&p_dual_tim_env[id]->handle); + p_dual_tim_env[id]->dual_tim_state = APP_DUAL_TIM_ACTIVITY; + } +} +#endif + +static void app_dual_tim_event_call(dual_timer_handle_t *p_dual_tim, app_dual_tim_evt_t evt_type) +{ + app_dual_tim_evt_t dual_tim_evt = APP_DUAL_TIM_EVT_ERROR; + app_dual_tim_id_t id = APP_DUAL_TIM_ID_0; + + if (p_dual_tim->p_instance == DUAL_TIMER0) + { + id = APP_DUAL_TIM_ID_0; + } + else if (p_dual_tim->p_instance == DUAL_TIMER1) + { + id = APP_DUAL_TIM_ID_1; + } + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + if (evt_type == APP_DUAL_TIM_EVT_DONE) + { + dual_tim_evt = APP_DUAL_TIM_EVT_DONE; + } + else if(evt_type == APP_DUAL_TIM_EVT_ACT_START) + { + dual_tim_evt = APP_DUAL_TIM_EVT_ACT_START; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOA_ACT_C1) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOA_ACT_C1; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOA_ACT_C2) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOA_ACT_C2; + } + else if(evt_type == APP_DUAL_TIM_EVT_ACT_PERIOD) + { + dual_tim_evt = APP_DUAL_TIM_EVT_ACT_PERIOD; + } + else if(evt_type == APP_DUAL_TIM_EVT_ACT_STOP) + { + dual_tim_evt = APP_DUAL_TIM_EVT_ACT_STOP; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOB_ACT_C1) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOB_ACT_C1; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOB_ACT_C2) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOB_ACT_C2; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOC_ACT_C1) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOC_ACT_C1; + } + else if(evt_type == APP_DUAL_TIM_EVT_IOC_ACT_C2) + { + dual_tim_evt = APP_DUAL_TIM_EVT_IOC_ACT_C2; + } +#else + if (evt_type == APP_DUAL_TIM_EVT_DONE) + { + dual_tim_evt = APP_DUAL_TIM_EVT_DONE; + } +#endif + + if (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID) + { + dual_tim_evt = APP_DUAL_TIM_EVT_ERROR; + } + + if (p_dual_tim_env[id]->evt_handler != NULL) + { + p_dual_tim_env[id]->evt_handler(&dual_tim_evt); + } +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +static uint16_t dual_timer_gpio_config(dual_timer_io_ctrl_cfg_t *io_crtl_cfg, app_dual_tim_id_t id, app_dual_tim_pin_t *pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (id == APP_DUAL_TIM_ID_0) + { + switch (io_crtl_cfg->channel) + { + case HAL_DUAL_TIMER_CHANNEL_A: + io_init.mux = APP_IO_MUX_49; + break; + case HAL_DUAL_TIMER_CHANNEL_B: + io_init.mux = APP_IO_MUX_50; + break; + case HAL_DUAL_TIMER_CHANNEL_C: + io_init.mux = APP_IO_MUX_51; + break; + default: + return APP_DRV_ERR_INVALID_PARAM; + } + } + else if (id == APP_DUAL_TIM_ID_1) + { + switch (io_crtl_cfg->channel) + { + case HAL_DUAL_TIMER_CHANNEL_A: + io_init.mux = APP_IO_MUX_52; + break; + case HAL_DUAL_TIMER_CHANNEL_B: + io_init.mux = APP_IO_MUX_53; + break; + case HAL_DUAL_TIMER_CHANNEL_C: + io_init.mux = APP_IO_MUX_54; + break; + default: + return APP_DRV_ERR_INVALID_PARAM; + } + } + else + { + return APP_DRV_ERR_INVALID_PARAM; + } + + io_init.pull = APP_IO_NOPULL; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg->pin; + err_code = app_io_init(pin_cfg->type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + return err_code; +} +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_dual_tim_init(app_dual_tim_params_t *p_params, app_dual_tim_evt_handler_t evt_handler) +{ + app_dual_tim_id_t id = p_params->id; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if (0x0 == p_params->init.auto_reload) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + p_dual_tim_env[id] = &(p_params->dual_tim_env); + + soc_register_nvic(DUAL_TIMER_IRQn, (uint32_t)DUAL_TIMER_IRQHandler); + hal_nvic_clear_pending_irq(s_dual_tim_irq[id]); + hal_nvic_enable_irq(s_dual_tim_irq[id]); + + p_dual_tim_env[id]->evt_handler = evt_handler; + + memcpy(&p_dual_tim_env[id]->handle.init, &p_params->init, sizeof(dual_timer_init_t)); + p_dual_tim_env[id]->handle.p_instance = (dual_timer_regs_t *)s_dual_tim_instance[id]; + hal_err_code = hal_dual_timer_base_deinit(&p_dual_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_dual_timer_base_init(&p_dual_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if(s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_dual_tim_pwr_id = pwr_register_sleep_cb(&dual_tim_sleep_cb, APP_DRIVER_DUAL_TIM_WAPEUP_PRIORITY); + + if (s_dual_tim_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_dual_tim_env[id]->dual_tim_state = APP_DUAL_TIM_ACTIVITY; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + p_dual_tim_env[id]->is_cha_enable = false; + p_dual_tim_env[id]->is_chb_enable = false; + p_dual_tim_env[id]->is_chc_enable = false; +#endif + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_deinit(app_dual_tim_id_t id) +{ + uint8_t i; + hal_status_t hal_err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ( (p_dual_tim_env[0]->dual_tim_state == APP_DUAL_TIM_INVALID) && + (p_dual_tim_env[1]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + hal_nvic_disable_irq(s_dual_tim_irq[id]); + } + + p_dual_tim_env[id]->dual_tim_state = APP_DUAL_TIM_INVALID; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + if (p_dual_tim_env[id]->is_cha_enable == true) + { + app_io_deinit(p_dual_tim_env[id]->cha_pin_cfg.type, p_dual_tim_env[id]->cha_pin_cfg.pin); + } + if (p_dual_tim_env[id]->is_chb_enable == true) + { + app_io_deinit(p_dual_tim_env[id]->chb_pin_cfg.type, p_dual_tim_env[id]->chb_pin_cfg.pin); + } + if (p_dual_tim_env[id]->is_chc_enable == true) + { + app_io_deinit(p_dual_tim_env[id]->chc_pin_cfg.type, p_dual_tim_env[id]->chc_pin_cfg.pin); + } + p_dual_tim_env[id]->is_cha_enable = false; + p_dual_tim_env[id]->is_chb_enable = false; + p_dual_tim_env[id]->is_chc_enable = false; +#endif + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_DUAL_TIM_ID_MAX; i++) + { + if (p_dual_tim_env[i] != NULL && (p_dual_tim_env[i]->dual_tim_state) != APP_DUAL_TIM_INVALID) + { + break; + } + } + if (APP_DUAL_TIM_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_dual_tim_pwr_id); + s_dual_tim_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_dual_timer_base_deinit(&p_dual_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + p_dual_tim_env[id] = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_start(app_dual_tim_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_base_start_it(&p_dual_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_stop(app_dual_tim_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_base_stop_it(&p_dual_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_set_params(app_dual_tim_params_t *p_params, app_dual_tim_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_set_config(&p_dual_tim_env[id]->handle, &p_params->init); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_set_background_reload(app_dual_tim_id_t id, uint32_t reload_value) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (reload_value == 0x0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_set_background_reload(&p_dual_tim_env[id]->handle, reload_value); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +uint16_t app_dual_tim_set_onetime_reload(app_dual_tim_id_t id, uint32_t reload_value) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (reload_value == 0x0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_set_onetime_reload(&p_dual_tim_env[id]->handle, reload_value); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_set_period_count(app_dual_tim_id_t id, uint32_t count_value) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_dual_tim_env[id]->is_cha_enable == false && + p_dual_tim_env[id]->is_chb_enable == false && + p_dual_tim_env[id]->is_chc_enable == false) || + count_value < 0x2 || + count_value > 0xFFFF) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + err_code = hal_dual_timer_set_period_count(&p_dual_tim_env[id]->handle, count_value); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_dual_tim_io_crtl_config(app_dual_tim_id_t id, app_dual_tim_io_crtl_params_t *io_crtl_params) +{ + hal_status_t err_code; + + if (id >= APP_DUAL_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (io_crtl_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + switch (io_crtl_params->io_crtl_cfg.channel) + { + case HAL_DUAL_TIMER_CHANNEL_A: + p_dual_tim_env[id]->is_cha_enable = true; + memcpy(&p_dual_tim_env[id]->cha_pin_cfg, &io_crtl_params->pin_cfg, sizeof(app_dual_tim_pin_t)); + break; + case HAL_DUAL_TIMER_CHANNEL_B: + p_dual_tim_env[id]->is_chb_enable = true; + memcpy(&p_dual_tim_env[id]->chb_pin_cfg, &io_crtl_params->pin_cfg, sizeof(app_dual_tim_pin_t)); + break; + case HAL_DUAL_TIMER_CHANNEL_C: + p_dual_tim_env[id]->is_chc_enable = true; + memcpy(&p_dual_tim_env[id]->chc_pin_cfg, &io_crtl_params->pin_cfg, sizeof(app_dual_tim_pin_t)); + break; + default: + return APP_DRV_ERR_INVALID_PARAM; + } + + err_code = (hal_status_t)dual_timer_gpio_config(&io_crtl_params->io_crtl_cfg, id, &io_crtl_params->pin_cfg); + HAL_ERR_CODE_CHECK(err_code); + + err_code = hal_dual_timer_io_crtl_config(&p_dual_tim_env[id]->handle, &io_crtl_params->io_crtl_cfg); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} +#endif + +dual_timer_handle_t *app_dual_tim_get_handle(app_dual_tim_id_t id) +{ + if (id >= APP_DUAL_TIM_ID_MAX) + { + return NULL; + } + + if ((p_dual_tim_env[id] == NULL) || (p_dual_tim_env[id]->dual_tim_state == APP_DUAL_TIM_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + dual_tim_wake_up(id); +#endif + + return &p_dual_tim_env[id]->handle; +} + +void hal_dual_timer_period_elapsed_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_DONE); +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +void hal_dual_timer_act_start_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_ACT_START); +} + +void hal_dual_timer_ioa_act_c1_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOA_ACT_C1); +} + +void hal_dual_timer_ioa_act_c2_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOA_ACT_C2); +} + +void hal_dual_timer_act_period_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_ACT_PERIOD); +} + +void hal_dual_timer_act_stop_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_ACT_STOP); +} + +void hal_dual_timer_iob_act_c1_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOB_ACT_C1); +} + +void hal_dual_timer_iob_act_c2_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOB_ACT_C2); +} + +void hal_dual_timer_ioc_act_c1_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOC_ACT_C1); +} + +void hal_dual_timer_ioc_act_c2_event_callback(dual_timer_handle_t *p_dual_timer) +{ + app_dual_tim_event_call(p_dual_timer, APP_DUAL_TIM_EVT_IOC_ACT_C2); +} + +#endif + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_gpiote.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_gpiote.c new file mode 100644 index 0000000..d146a45 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_gpiote.c @@ -0,0 +1,94 @@ +/** + **************************************************************************************** + * @file app_gpiote.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "app_gpiote.h" + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_gpiote_init(const app_gpiote_param_t *p_params, uint8_t table_cnt) +{ + app_io_init_t io_init; + app_drv_err_t err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + for (uint8_t idx = 0; idx < table_cnt; idx++) + { + io_init.pin = p_params[idx].pin; + io_init.mode = p_params[idx].mode; + io_init.pull = p_params[idx].pull; + io_init.mux = APP_IO_MUX; + err_code = app_io_event_register_cb(p_params[idx].type, &io_init, p_params[idx].io_evt_cb, NULL); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_gpiote_config(const app_gpiote_param_t *p_config) +{ + app_io_init_t io_init; + app_drv_err_t err_code; + + if (NULL == p_config) + { + return APP_DRV_ERR_POINTER_NULL; + } + + io_init.pin = p_config->pin; + io_init.mode = p_config->mode; + io_init.pull = p_config->pull; + io_init.mux = APP_IO_MUX; + + err_code = app_io_event_register_cb(p_config->type, &io_init, p_config->io_evt_cb, NULL); + APP_DRV_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_gpiote_deinit(app_io_type_t type, uint32_t pin) +{ + return app_io_event_unregister(type, pin); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_graphics_qspi.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_graphics_qspi.c new file mode 100644 index 0000000..212a176 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_graphics_qspi.c @@ -0,0 +1,1543 @@ +/** + **************************************************************************************** + * @file app_graphics_qspi.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_assert.h" +#include "app_qspi.h" +#include "app_qspi_dma.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include +#include "platform_sdk.h" +#include "app_drv.h" +#include "gr_soc.h" + +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) +#include "app_graphics_qspi.h" +#include "gr55xx_ll_qspi.h" + +#ifdef HAL_QSPI_MODULE_ENABLED +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_QSPI_EXCEPT_DEBUG_EN 1u +#define APP_QSPI_IN_DEBUG_MODE 0 +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) +static bool app_qspi_switch_dma_mode(app_qspi_id_t id, bool is_m2m_mode); +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) +static bool app_qspi_cmd_llp_transmit(app_qspi_id_t screen_id, app_qspi_command_t * p_cmd, dma_llp_config_t * p_llp_config, bool is_sync); +static bool app_qspi_llp_transmit(app_qspi_id_t screen_id, dma_llp_config_t * p_llp_config, uint32_t data_mode, uint32_t data_len, bool is_sync); +#endif +static void app_qspi_dma_evt_handler_0(app_dma_evt_type_t type); +static void app_qspi_dma_evt_handler_1(app_dma_evt_type_t type); +static void app_qspi_dma_evt_handler_2(app_dma_evt_type_t type); +extern bool app_qspi_mmap_set_prefetch(app_qspi_id_t id, bool prefetch_en); +extern void app_qspi_force_cs(app_qspi_id_t screen_id, bool low_level); +#endif +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const app_dma_evt_handler_t s_dma_evt_handler[APP_QSPI_ID_MAX] = {app_qspi_dma_evt_handler_0, app_qspi_dma_evt_handler_1, app_qspi_dma_evt_handler_2}; +extern const uint32_t s_qspi_instance[APP_QSPI_ID_MAX]; +extern qspi_env_t *p_qspi_env[APP_QSPI_ID_MAX]; + +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) + static dma_block_config_t s_dma_llp_block[DMA_LLP_BLOCKS_FOR_WRITE*2 + 1]; + app_qspi_async_draw_screen_info_t s_async_write_screen_info; +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) +bool app_qspi_dma_mmap_read_block(app_qspi_id_t id, uint32_t address, uint8_t * buffer, uint32_t length) { + hal_status_t status; + bool ret = true; + APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + + app_qspi_mmap_set_endian_mode(id, APP_QSPI_MMAP_ENDIAN_MODE_0); + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_mmap_set_prefetch(id, true); + ret = app_qspi_switch_dma_mode(id, true); + if(ret) { + p_qspi_env[id]->is_dma_done = 0; + p_qspi_env[id]->is_xfer_err = 0; + status = hal_dma_start_it(p_qspi_env[id]->handle.p_dma, ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]) + address, (uint32_t)buffer, length); + if(HAL_OK == status) { + while(!p_qspi_env[id]->is_dma_done && !p_qspi_env[id]->is_xfer_err); + if(p_qspi_env[id]->is_xfer_err) { + ret = false; + } + } else { + ret = false; + } + } + + app_qspi_mmap_set_prefetch(id, false); + return ret; +} + + +#if APP_QSPI_IN_DEBUG_MODE +bool app_qspi_sync_draw_screen(app_qspi_id_t screen_id, app_qspi_id_t storage_id, const app_qspi_screen_command_t * const p_screen_cmd, const app_qspi_screen_info_t * const p_screen_info, app_qspi_screen_scroll_t * p_scroll_config) { + +#if (QSPI_SYNC_SCROLL_DRAW_SCREEN_SUPPORT > 0u) + + app_qspi_command_t app_scrn_cmd; + dma_llp_config_t scrn_llp_config; + app_qspi_screen_scroll_t s_scroll_config; + uint32_t this_send_lines = 0; + uint32_t sent_lines = 0; + uint32_t image_start_address = 0; + uint32_t j = 0; + uint32_t llp_cfg_right_shift_bit = 0; + uint32_t llp_cfg_ctrl_low = 0; + uint32_t sent_line_order = 0; + bool ret = false; + bool is_lead_addr = true; + bool is_stored_in_qspi_storage = false; + + const uint32_t scrn_pixel_height = p_screen_info->scrn_pixel_height; + const uint32_t scrn_pixel_width = p_screen_info->scrn_pixel_width; + const uint32_t scrn_pixel_depth = p_screen_info->scrn_pixel_depth; + const uint32_t scrn_line_size = (scrn_pixel_width * scrn_pixel_depth); + const uint32_t scrn_refresh_lines_once = (QSPI_MAX_XFER_SIZE_ONCE/scrn_line_size); + const uint32_t send_lines_once = DMA_LLP_BLOCKS_FOR_WRITE < scrn_refresh_lines_once ? DMA_LLP_BLOCKS_FOR_WRITE : scrn_refresh_lines_once; + + if((p_screen_cmd == NULL) || (p_screen_info == NULL) || (p_scroll_config == NULL)) { + return false; + } + + if(storage_id <= APP_QSPI_ID_2) { + is_stored_in_qspi_storage = true; + } else if (storage_id == APP_STORAGE_RAM_ID) { + is_stored_in_qspi_storage = false; + } else { + return false; + } + + if(screen_id == storage_id) { + return false; + } + + if ((p_qspi_env[screen_id] == NULL) || (p_qspi_env[screen_id]->qspi_state == APP_QSPI_INVALID) || + (p_qspi_env[storage_id] == NULL) || (p_qspi_env[storage_id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + /* check screen height/width/depth */ + if((scrn_pixel_width % 2 != 0) || + (scrn_pixel_height % 2 != 0) || + (scrn_pixel_depth != 2)) { + return false; + } + + if (p_qspi_env[screen_id]->start_flag || (is_stored_in_qspi_storage && p_qspi_env[storage_id]->start_flag)) { + return false; + } + + p_qspi_env[screen_id]->start_flag = true; + if(is_stored_in_qspi_storage) p_qspi_env[storage_id]->start_flag = true; + + if(is_stored_in_qspi_storage) + { + app_qspi_mmap_set_prefetch(storage_id, true); + } + + APP_ASSERT_CHECK(p_qspi_env[screen_id]->is_used_dma); + app_qspi_switch_dma_mode(screen_id, false); + + if(QSPI_DATASIZE_08_BITS == p_screen_cmd->data_size) { + llp_cfg_right_shift_bit = 0; + llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_BYTE, DMA_DDATAALIGN_BYTE, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_0); + } else if (QSPI_DATASIZE_16_BITS == p_screen_cmd->data_size) { + llp_cfg_right_shift_bit = 1; + llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_HALFWORD, DMA_DDATAALIGN_HALFWORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_1); + } else if (QSPI_DATASIZE_32_BITS == p_screen_cmd->data_size) { + llp_cfg_right_shift_bit = 2; + llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_2); + } else { + p_qspi_env[screen_id]->start_flag = false; + if(is_stored_in_qspi_storage) p_qspi_env[storage_id]->start_flag = false; + + return false; + } + + memcpy(&s_scroll_config, p_scroll_config, sizeof(app_qspi_screen_scroll_t)); + + /* check and adjust start & end coordinate */ + if(s_scroll_config.is_horizontal_scroll) { + if(s_scroll_config.scroll_coordinate > scrn_pixel_width) { + s_scroll_config.scroll_coordinate = scrn_pixel_width; + } + + } else { + if(s_scroll_config.scroll_coordinate > scrn_pixel_height) { + s_scroll_config.scroll_coordinate = scrn_pixel_height; + } + } + + /* adjust scroll_coordinate to even number */ + s_scroll_config.scroll_coordinate = (s_scroll_config.scroll_coordinate >> 1) << 1; + + const uint32_t image_1_ahb_address = p_scroll_config->first_frame_start_address; + const uint32_t image_2_ahb_address = p_scroll_config->second_frame_start_address; + + APP_ASSERT_CHECK(p_qspi_env[screen_id]->is_used_dma); + app_qspi_mmap_set_prefetch(storage_id, true); + + /* prepare llp config */ + scrn_llp_config.llp_src_writeback = 1; + scrn_llp_config.llp_dst_writeback = 1; + scrn_llp_config.llp_src_en = DMA_LLP_SRC_ENABLE; + scrn_llp_config.llp_dst_en = DMA_LLP_DST_DISABLE; + scrn_llp_config.head_lli = &s_dma_llp_block[0]; + + app_scrn_cmd.instruction = p_screen_cmd->instruction; + app_scrn_cmd.instruction_size = p_screen_cmd->instruction_size; + app_scrn_cmd.address = p_screen_cmd->leading_address; + app_scrn_cmd.address_size = p_screen_cmd->address_size; + app_scrn_cmd.dummy_cycles = p_screen_cmd->dummy_cycles; + app_scrn_cmd.data_size = p_screen_cmd->data_size; + app_scrn_cmd.instruction_address_mode = p_screen_cmd->instruction_address_mode; + app_scrn_cmd.data_mode = p_screen_cmd->data_mode; + app_scrn_cmd.length = 0x00; + app_scrn_cmd.clock_stretch_en = 1; + + is_lead_addr = true; + + if(s_scroll_config.is_horizontal_scroll) { + + if((s_scroll_config.scroll_coordinate == 0) || /* Only left image */ + (s_scroll_config.scroll_coordinate == scrn_pixel_width)) { /* Only right image */ + this_send_lines = 0; + sent_lines = 0; + + if(0 == s_scroll_config.scroll_coordinate) { + image_start_address = image_1_ahb_address; + } else { + image_start_address = image_2_ahb_address; + } + + while(sent_lines < scrn_pixel_height) { + this_send_lines = (scrn_pixel_height - sent_lines) < send_lines_once ? (scrn_pixel_height - sent_lines) : send_lines_once; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (this_send_lines*2 + 1)); + + for(j = 0; j < this_send_lines; j++) { + s_dma_llp_block[j].src_address = image_start_address + (sent_lines + j) * scrn_line_size ; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j + 1]; + s_dma_llp_block[j].CTL_L = llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + if(is_lead_addr) { + app_scrn_cmd.address = p_screen_cmd->leading_address; + is_lead_addr = false; + } else { + app_scrn_cmd.address = p_screen_cmd->ongoing_address; + } + + app_scrn_cmd.length = this_send_lines * scrn_line_size; + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, true); + + if(!ret) { + goto __fail; + } + + sent_lines += this_send_lines; + } + } else { /* part of left image, part of right image */ + this_send_lines = 0; + sent_lines = 0; + + while(sent_lines < scrn_pixel_height) { + this_send_lines = (scrn_pixel_height - sent_lines) < send_lines_once ? (scrn_pixel_height - sent_lines) : send_lines_once; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (this_send_lines*2 + 1)); + + for(j = 0; j < this_send_lines; j++) { + /* first image */ + s_dma_llp_block[2*j].src_address = image_1_ahb_address + (sent_lines + j) * scrn_line_size + s_scroll_config.scroll_coordinate * scrn_pixel_depth; + s_dma_llp_block[2*j].dst_address = 0; + s_dma_llp_block[2*j].p_lli = &s_dma_llp_block[2*j + 1]; + s_dma_llp_block[2*j].CTL_L = llp_cfg_ctrl_low; + s_dma_llp_block[2*j].CTL_H = (uint32_t)(((scrn_pixel_width - s_scroll_config.scroll_coordinate)*scrn_pixel_depth) >> llp_cfg_right_shift_bit); + s_dma_llp_block[2*j].src_status = 0x0; + s_dma_llp_block[2*j].dst_status = 0x0; + + /* second image */ + s_dma_llp_block[2*j + 1].src_address = image_2_ahb_address + (sent_lines + j) * scrn_line_size ; + s_dma_llp_block[2*j + 1].dst_address = 0; + s_dma_llp_block[2*j + 1].p_lli = &s_dma_llp_block[2*j + 2]; + s_dma_llp_block[2*j + 1].CTL_L = llp_cfg_ctrl_low; + s_dma_llp_block[2*j + 1].CTL_H = (uint32_t)((s_scroll_config.scroll_coordinate * scrn_pixel_depth) >> llp_cfg_right_shift_bit); + s_dma_llp_block[2*j + 1].src_status = 0x0; + s_dma_llp_block[2*j + 1].dst_status = 0x0; + + } + s_dma_llp_block[2*j - 1].p_lli = NULL; + + if(is_lead_addr) { + app_scrn_cmd.address = p_screen_cmd->leading_address; + is_lead_addr = false; + } else { + app_scrn_cmd.address = p_screen_cmd->ongoing_address; + } + app_scrn_cmd.length = this_send_lines * scrn_line_size; + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, true); + + if(!ret) { + goto __fail; + } + + sent_lines += this_send_lines; + } + } + } else { /* Scroll vertically */ + sent_line_order = s_scroll_config.scroll_coordinate; + this_send_lines = 0; + sent_lines = 0; + + while(sent_lines < scrn_pixel_height) { + + this_send_lines = (scrn_pixel_height - sent_lines) < send_lines_once ? (scrn_pixel_height - sent_lines) : send_lines_once; + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (this_send_lines*2 + 1)); + + for(j = 0; j < this_send_lines; j++) { + + image_start_address = sent_line_order < scrn_pixel_height ? image_1_ahb_address : image_2_ahb_address; + + s_dma_llp_block[j].src_address = image_start_address + (sent_line_order % scrn_pixel_height) * scrn_line_size ; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j + 1]; + s_dma_llp_block[j].CTL_L = llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + + sent_line_order ++; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + if(is_lead_addr) { + app_scrn_cmd.address = p_screen_cmd->leading_address; + is_lead_addr = false; + } else { + app_scrn_cmd.address = p_screen_cmd->ongoing_address; + } + + app_scrn_cmd.length = this_send_lines * scrn_line_size; + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, true); + + if(!ret) { + goto __fail; + } + + sent_lines += this_send_lines; + } + } + + p_qspi_env[screen_id]->start_flag = false; + if(is_stored_in_qspi_storage) p_qspi_env[storage_id]->start_flag = false; + return true; + +__fail: + p_qspi_env[screen_id]->start_flag = false; + if(is_stored_in_qspi_storage) p_qspi_env[storage_id]->start_flag = false; + return false; + +#else + return false; +#endif +} +#endif + +bool app_qspi_async_draw_screen(app_qspi_id_t screen_id, app_qspi_id_t storage_id, const app_qspi_screen_command_t * const p_screen_cmd, const app_qspi_screen_info_t * const p_screen_info, app_qspi_screen_scroll_t * p_scroll_config, bool is_first_call) { + +#if (QSPI_ASYNC_SCROLL_DRAW_SCREEN_SUPPORT > 0u) + + app_qspi_command_t app_scrn_cmd; + dma_llp_config_t scrn_llp_config; + uint32_t image_start_address = 0; + uint32_t j = 0; + bool ret = false; + bool is_stored_in_qspi_storage = false; + + if((p_screen_cmd == NULL) || (p_screen_info == NULL) || (p_scroll_config == NULL)) { + return false; + } + + if(screen_id > APP_QSPI_ID_2) { + return false; + } + + if((storage_id > APP_QSPI_ID_2) && (storage_id != APP_STORAGE_RAM_ID)) { + return false; + } + + if(screen_id == storage_id) { + return false; + } + + if(storage_id <= APP_QSPI_ID_2) { + is_stored_in_qspi_storage = true; + } else if (storage_id == APP_STORAGE_RAM_ID) { + is_stored_in_qspi_storage = false; + } else { + return false; + } + + if ((p_qspi_env[screen_id] == NULL) || (p_qspi_env[screen_id]->qspi_state == APP_QSPI_INVALID) || + (p_qspi_env[storage_id] == NULL) || (p_qspi_env[storage_id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if(p_qspi_env[screen_id]->is_async_write_screen && is_first_call) { + printf("RE-CALLED !\r\n"); + return false; + } + + if(is_first_call) { + if (p_qspi_env[screen_id]->start_flag || (is_stored_in_qspi_storage && p_qspi_env[storage_id]->start_flag)) { + printf("BUSY... !\r\n"); + return false; + } + + p_qspi_env[screen_id]->start_flag = true; + if(is_stored_in_qspi_storage){ + p_qspi_env[storage_id]->start_flag = true; + } + + memset(&s_async_write_screen_info, 0, sizeof(app_qspi_async_draw_screen_info_t)); + + s_async_write_screen_info.if_type = DRAW_TYPE_IF_DUAL_SCREEN; + s_async_write_screen_info.screen_id = screen_id; + s_async_write_screen_info.storage_id = storage_id; + + memcpy(&s_async_write_screen_info.qspi_screen_command, p_screen_cmd, sizeof(app_qspi_screen_command_t)); + memcpy(&s_async_write_screen_info.screen_info, p_screen_info, sizeof(app_qspi_screen_info_t)); + memcpy(&s_async_write_screen_info.ss.dual_ss.scroll_config, p_scroll_config, sizeof(app_qspi_screen_scroll_t)); + + /* check and adjust start & end coordinate */ + if(s_async_write_screen_info.ss.dual_ss.scroll_config.is_horizontal_scroll) { + if(s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate > p_screen_info->scrn_pixel_width) { + s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate = p_screen_info->scrn_pixel_width; + } + } else { + if(s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate > p_screen_info->scrn_pixel_height) { + s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate = p_screen_info->scrn_pixel_height; + } + } + + /* adjust scroll_coordinate to even number */ + s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate = (s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate >> 1) << 1; + + if(is_stored_in_qspi_storage) { + app_qspi_mmap_set_prefetch(storage_id, true); + } + APP_ASSERT_CHECK(p_qspi_env[screen_id]->is_used_dma); + app_qspi_switch_dma_mode(screen_id, false); + + if(QSPI_DATASIZE_08_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 0; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_BYTE, DMA_DDATAALIGN_BYTE, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_0); + } else if (QSPI_DATASIZE_16_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 1; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_HALFWORD, DMA_DDATAALIGN_HALFWORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_1); + } else if (QSPI_DATASIZE_32_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 2; + if(is_stored_in_qspi_storage) + { + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_4, LL_DMA_DST_BURST_LENGTH_4, DMA_SRC_GATHER_DISABLE);//BALIPRO-226:LL_DMA_SRC_BURST_LENGTH_8 will cause exception for qspi-psram data + } + else + { + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + } + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_2); + } else { + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } + + s_async_write_screen_info.ss.dual_ss.image_1_ahb_address = p_scroll_config->first_frame_start_address; + s_async_write_screen_info.ss.dual_ss.image_2_ahb_address = p_scroll_config->second_frame_start_address; + s_async_write_screen_info.ss.dual_ss.total_sent_lines = 0; + s_async_write_screen_info.ss.dual_ss.this_send_lines = 0; + s_async_write_screen_info.ss.dual_ss.sent_line_order = s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate; + } + + const uint32_t scrn_pixel_height = s_async_write_screen_info.screen_info.scrn_pixel_height; + const uint32_t scrn_pixel_width = s_async_write_screen_info.screen_info.scrn_pixel_width; + const uint32_t scrn_pixel_depth = s_async_write_screen_info.screen_info.scrn_pixel_depth; + const uint32_t scrn_line_size = (scrn_pixel_width * scrn_pixel_depth); + const uint32_t scrn_refresh_lines_once = (QSPI_MAX_XFER_SIZE_ONCE/scrn_line_size); + const uint32_t send_lines_once = DMA_LLP_BLOCKS_FOR_WRITE < scrn_refresh_lines_once ? DMA_LLP_BLOCKS_FOR_WRITE : scrn_refresh_lines_once; + + /* check screen height/width/depth */ + if((scrn_pixel_width % 2 != 0) || + (scrn_pixel_height % 2 != 0) || + (scrn_pixel_depth != 2) ) { + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } + + /* prepare llp config */ + scrn_llp_config.llp_src_writeback = 1; + scrn_llp_config.llp_dst_writeback = 1; + scrn_llp_config.llp_src_en = DMA_LLP_SRC_ENABLE; + scrn_llp_config.llp_dst_en = DMA_LLP_DST_DISABLE; + scrn_llp_config.head_lli = &s_dma_llp_block[0]; + + app_scrn_cmd.instruction = s_async_write_screen_info.qspi_screen_command.instruction; + app_scrn_cmd.instruction_size = s_async_write_screen_info.qspi_screen_command.instruction_size; + app_scrn_cmd.address = is_first_call ? s_async_write_screen_info.qspi_screen_command.leading_address : s_async_write_screen_info.qspi_screen_command.ongoing_address; + app_scrn_cmd.address_size = s_async_write_screen_info.qspi_screen_command.address_size; + app_scrn_cmd.dummy_cycles = s_async_write_screen_info.qspi_screen_command.dummy_cycles; + app_scrn_cmd.data_size = s_async_write_screen_info.qspi_screen_command.data_size; + app_scrn_cmd.instruction_address_mode = s_async_write_screen_info.qspi_screen_command.instruction_address_mode; + app_scrn_cmd.data_mode = s_async_write_screen_info.qspi_screen_command.data_mode; + app_scrn_cmd.length = 0x00; + app_scrn_cmd.clock_stretch_en = 1; + + if(s_async_write_screen_info.ss.dual_ss.scroll_config.is_horizontal_scroll) { + + if((s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate == 0) || /* Only left image */ + (s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate == scrn_pixel_width)) { /* Only right image */ + + if(0 == s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate) { + image_start_address = s_async_write_screen_info.ss.dual_ss.image_1_ahb_address; + } else { + image_start_address = s_async_write_screen_info.ss.dual_ss.image_2_ahb_address; + } + + if(s_async_write_screen_info.ss.dual_ss.total_sent_lines < scrn_pixel_height) { + s_async_write_screen_info.ss.dual_ss.this_send_lines = (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) < send_lines_once ? (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) : send_lines_once; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (s_async_write_screen_info.ss.dual_ss.this_send_lines*2 + 1)); + + for(j = 0; j < s_async_write_screen_info.ss.dual_ss.this_send_lines; j++) { + s_dma_llp_block[j].src_address = image_start_address + (s_async_write_screen_info.ss.dual_ss.total_sent_lines + j) * scrn_line_size ; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j + 1]; + s_dma_llp_block[j].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + app_scrn_cmd.length = s_async_write_screen_info.ss.dual_ss.this_send_lines * scrn_line_size; + + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + if(is_first_call) { + app_qspi_force_cs(screen_id, true); + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } else { + ret = app_qspi_llp_transmit(screen_id, &scrn_llp_config, app_scrn_cmd.data_mode, app_scrn_cmd.length, false); + } + } else { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + + if(!ret) { + goto __fail; + } + } + } else { /* part of left image, part of right image */ + + if(s_async_write_screen_info.ss.dual_ss.total_sent_lines < scrn_pixel_height) { + s_async_write_screen_info.ss.dual_ss.this_send_lines = (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) < send_lines_once ? (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) : send_lines_once; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (s_async_write_screen_info.ss.dual_ss.this_send_lines*2 + 1)); + + for(j = 0; j < s_async_write_screen_info.ss.dual_ss.this_send_lines; j++) { + /* first image */ + s_dma_llp_block[2*j].src_address = s_async_write_screen_info.ss.dual_ss.image_1_ahb_address + (s_async_write_screen_info.ss.dual_ss.total_sent_lines + j) * scrn_line_size + s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate * scrn_pixel_depth; + s_dma_llp_block[2*j].dst_address = 0; + s_dma_llp_block[2*j].p_lli = &s_dma_llp_block[2*j + 1]; + s_dma_llp_block[2*j].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[2*j].CTL_H = (uint32_t)(((scrn_pixel_width - s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate)*scrn_pixel_depth) >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[2*j].src_status = 0x0; + s_dma_llp_block[2*j].dst_status = 0x0; + + /* second image */ + s_dma_llp_block[2*j + 1].src_address = s_async_write_screen_info.ss.dual_ss.image_2_ahb_address + (s_async_write_screen_info.ss.dual_ss.total_sent_lines + j) * scrn_line_size ; + s_dma_llp_block[2*j + 1].dst_address = 0; + s_dma_llp_block[2*j + 1].p_lli = &s_dma_llp_block[2*j + 2]; + s_dma_llp_block[2*j + 1].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[2*j + 1].CTL_H = (uint32_t)((s_async_write_screen_info.ss.dual_ss.scroll_config.scroll_coordinate * scrn_pixel_depth) >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[2*j + 1].src_status = 0x0; + s_dma_llp_block[2*j + 1].dst_status = 0x0; + + } + s_dma_llp_block[2*j - 1].p_lli = NULL; + + app_scrn_cmd.length = s_async_write_screen_info.ss.dual_ss.this_send_lines * scrn_line_size; + + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + if(is_first_call) { + app_qspi_force_cs(screen_id, true); + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } else { + ret = app_qspi_llp_transmit(screen_id, &scrn_llp_config, app_scrn_cmd.data_mode, app_scrn_cmd.length, false); + } + } else { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + + if(!ret) { + goto __fail; + } + } + } + } else { /* Scroll vertically */ + + if(s_async_write_screen_info.ss.dual_ss.total_sent_lines < scrn_pixel_height) { + + s_async_write_screen_info.ss.dual_ss.this_send_lines = (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) < send_lines_once ? (scrn_pixel_height - s_async_write_screen_info.ss.dual_ss.total_sent_lines) : send_lines_once; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (s_async_write_screen_info.ss.dual_ss.this_send_lines*2 + 1)); + + for(j = 0; j < s_async_write_screen_info.ss.dual_ss.this_send_lines; j++) { + + image_start_address = s_async_write_screen_info.ss.dual_ss.sent_line_order < scrn_pixel_height ? s_async_write_screen_info.ss.dual_ss.image_1_ahb_address : s_async_write_screen_info.ss.dual_ss.image_2_ahb_address; + + s_dma_llp_block[j].src_address = image_start_address + (s_async_write_screen_info.ss.dual_ss.sent_line_order % scrn_pixel_height) * scrn_line_size ; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j + 1]; + s_dma_llp_block[j].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + + s_async_write_screen_info.ss.dual_ss.sent_line_order ++; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + app_scrn_cmd.length = s_async_write_screen_info.ss.dual_ss.this_send_lines * scrn_line_size; + + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + if(is_first_call) { + app_qspi_force_cs(screen_id, true); + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } else { + ret = app_qspi_llp_transmit(screen_id, &scrn_llp_config, app_scrn_cmd.data_mode, app_scrn_cmd.length, false); + } + } else { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + + if(!ret) { + goto __fail; + } + } + } + return true; + +__fail: + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + app_qspi_force_cs(s_async_write_screen_info.screen_id, false); + } + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + +#else + return false; +#endif +} + +bool app_qspi_async_veri_draw_screen(app_qspi_id_t screen_id, + app_qspi_id_t storage_id, + const app_qspi_screen_command_t * const p_screen_cmd, + const app_qspi_screen_info_t * const p_screen_info, + app_qspi_screen_veri_link_scroll_t * p_link_scroll, + bool is_first_call) { + +#if (QSPI_ASYNC_VERI_LINK_DRAW_SCREEN_SUPPORT > 0u) + + app_qspi_command_t app_scrn_cmd; + dma_llp_config_t scrn_llp_config; + bool ret = false; + uint32_t j = 0; + bool is_stored_in_qspi_storage = false; + app_qspi_screen_veri_link_scroll_t * p_cur_scroll = NULL; + + if((p_screen_cmd == NULL) || (p_screen_info == NULL) || (p_link_scroll == NULL)) { + return false; + } + + if(screen_id > APP_QSPI_ID_2) { + return false; + } + + if((storage_id > APP_QSPI_ID_2) && (storage_id != APP_STORAGE_RAM_ID)) { + return false; + } + + if(screen_id == storage_id) { + return false; + } + + if ((p_qspi_env[screen_id] == NULL) || (p_qspi_env[screen_id]->qspi_state == APP_QSPI_INVALID) || + (p_qspi_env[storage_id] == NULL) || (p_qspi_env[storage_id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if(p_qspi_env[screen_id]->is_async_write_screen && is_first_call) { + printf("RE-CALLED !\r\n"); + return false; + } + + if(is_first_call) { + + if (p_qspi_env[screen_id]->start_flag) { + printf("BUSY... !\r\n"); + return false; + } + p_qspi_env[screen_id]->start_flag = true; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = true; + } + + memset(&s_async_write_screen_info, 0, sizeof(app_qspi_async_draw_screen_info_t)); + + is_stored_in_qspi_storage = (storage_id <= APP_QSPI_ID_2) ? true : false; + s_async_write_screen_info.if_type = DRAW_TYPE_IF_VERI_LINKED_SCREEN; + s_async_write_screen_info.screen_id = screen_id; + s_async_write_screen_info.storage_id = storage_id; + + memcpy(&s_async_write_screen_info.screen_info, p_screen_info, sizeof(app_qspi_screen_info_t)); + memcpy(&s_async_write_screen_info.qspi_screen_command, p_screen_cmd , sizeof(app_qspi_command_t)); + memcpy(&s_async_write_screen_info.ss.veri_linked_ss.vl_scroll, p_link_scroll, sizeof(app_qspi_screen_veri_link_scroll_t)); + + s_async_write_screen_info.ss.veri_linked_ss.total_sent_lines = 0; + s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll = p_link_scroll; + + if(is_stored_in_qspi_storage) { + app_qspi_mmap_set_prefetch(storage_id, true); + } + APP_ASSERT_CHECK(p_qspi_env[screen_id]->is_used_dma); + app_qspi_switch_dma_mode(screen_id, false); + + if(QSPI_DATASIZE_08_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 0; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_BYTE, DMA_DDATAALIGN_BYTE, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_0); + } else if (QSPI_DATASIZE_16_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 1; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_HALFWORD, DMA_DDATAALIGN_HALFWORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_1); + } else if (QSPI_DATASIZE_32_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 2; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if(is_stored_in_qspi_storage) app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_2); + } else { + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } + } + + const uint32_t scrn_pixel_height = s_async_write_screen_info.screen_info.scrn_pixel_height; + const uint32_t scrn_pixel_width = s_async_write_screen_info.screen_info.scrn_pixel_width; + const uint32_t scrn_pixel_depth = s_async_write_screen_info.screen_info.scrn_pixel_depth; + const uint32_t scrn_line_size = (scrn_pixel_width * scrn_pixel_depth); + const uint32_t scrn_refresh_lines_once = (QSPI_MAX_XFER_SIZE_ONCE/scrn_line_size); + const uint32_t max_lines = (sizeof(s_dma_llp_block)/sizeof(dma_block_config_t) - 2); + const uint32_t send_lines_once = max_lines < scrn_refresh_lines_once ? max_lines : scrn_refresh_lines_once; + + p_cur_scroll = s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll; + + /* check screen height/width/depth */ + if((p_cur_scroll == NULL) || + (scrn_pixel_width % 2 != 0) || + (scrn_pixel_height % 2 != 0) || + (scrn_pixel_depth != 2) ) { + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } + + if(p_cur_scroll->frame_draw_lines > send_lines_once) { + + if(APP_QSPI_EXCEPT_DEBUG_EN) printf("+++ ERR: Set psram(frame_draw_lines) <= %d in each Link Point\r\n", send_lines_once); + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } + + /* prepare llp config */ + scrn_llp_config.llp_src_writeback = 1; + scrn_llp_config.llp_dst_writeback = 1; + scrn_llp_config.llp_src_en = DMA_LLP_SRC_ENABLE; + scrn_llp_config.llp_dst_en = DMA_LLP_DST_DISABLE; + scrn_llp_config.head_lli = &s_dma_llp_block[0]; + + app_scrn_cmd.instruction = s_async_write_screen_info.qspi_screen_command.instruction; + app_scrn_cmd.instruction_size = s_async_write_screen_info.qspi_screen_command.instruction_size; + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.leading_address; + app_scrn_cmd.address_size = s_async_write_screen_info.qspi_screen_command.address_size; + app_scrn_cmd.dummy_cycles = s_async_write_screen_info.qspi_screen_command.dummy_cycles; + app_scrn_cmd.data_size = s_async_write_screen_info.qspi_screen_command.data_size; + app_scrn_cmd.instruction_address_mode = s_async_write_screen_info.qspi_screen_command.instruction_address_mode; + app_scrn_cmd.data_mode = s_async_write_screen_info.qspi_screen_command.data_mode; + app_scrn_cmd.length = 0x00; + app_scrn_cmd.clock_stretch_en = 1; + + memset(&s_dma_llp_block[0], 0, sizeof(dma_block_config_t) * (p_cur_scroll->frame_draw_lines + 1)); + + for(j = 0; j < p_cur_scroll->frame_draw_lines; j++) { + s_dma_llp_block[j].src_address = p_cur_scroll->frame_ahb_start_address + (p_cur_scroll->frame_offset_lines + j) * scrn_line_size ; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j + 1]; + s_dma_llp_block[j].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + if(is_first_call) { + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.leading_address; + } else { + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.ongoing_address; + } + + app_scrn_cmd.length = p_cur_scroll->frame_draw_lines * scrn_line_size; + + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + if(is_first_call) { + app_qspi_force_cs(screen_id, true); + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } else { + ret = app_qspi_llp_transmit(screen_id, &scrn_llp_config, app_scrn_cmd.data_mode, app_scrn_cmd.length, false); + } + } else { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + + if(ret) { + return true; + } else { + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + app_qspi_force_cs(s_async_write_screen_info.screen_id, false); + } + p_qspi_env[screen_id]->start_flag = false; + if(storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + return false; + } +#else + return false; +#endif +} + +bool app_qspi_async_llp_draw_block(app_qspi_id_t screen_id, + app_qspi_id_t storage_id, + const app_qspi_screen_command_t *const p_screen_cmd, + const app_qspi_screen_info_t *const p_screen_info, + app_qspi_screen_block_t *p_block_info, + bool is_first_call) { + +#if (QSPI_ASYNC_VERI_LINK_DRAW_SCREEN_SUPPORT > 0u) + + app_qspi_command_t app_scrn_cmd; + dma_llp_config_t scrn_llp_config; + bool ret = false; + uint32_t j = 0; + bool is_stored_in_qspi_storage = false; + app_qspi_screen_block_t *p_cur_block = NULL; + if ((p_screen_cmd == NULL) || (p_screen_info == NULL) || (p_block_info == NULL)) { + return false; + } + + if (screen_id > APP_QSPI_ID_2) { + return false; + } + + if ((storage_id > APP_QSPI_ID_2) && (storage_id != APP_STORAGE_RAM_ID)) { + return false; + } + + if (screen_id == storage_id) { + return false; + } + + if ((p_qspi_env[screen_id] == NULL) || (p_qspi_env[screen_id]->qspi_state == APP_QSPI_INVALID) || (p_qspi_env[storage_id] == NULL) || (p_qspi_env[storage_id]->qspi_state == APP_QSPI_INVALID)) { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_qspi_env[screen_id]->start_flag) { + printf("BUSY... !\r\n"); + return false; + } + + p_qspi_env[screen_id]->start_flag = true; + + if (storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = true; + } + + memset(&s_async_write_screen_info, 0, sizeof(app_qspi_async_draw_screen_info_t)); + + is_stored_in_qspi_storage = (storage_id <= APP_QSPI_ID_2) ? true : false; + + s_async_write_screen_info.screen_id = screen_id; + + s_async_write_screen_info.storage_id = storage_id; + + memcpy(&s_async_write_screen_info.screen_info, p_screen_info, sizeof(app_qspi_screen_info_t)); + + memcpy(&s_async_write_screen_info.qspi_screen_command, p_screen_cmd, sizeof(app_qspi_command_t)); + + memcpy(&s_async_write_screen_info.ss.veri_linked_ss.vl_scroll, p_block_info, sizeof(app_qspi_screen_block_t)); + + s_async_write_screen_info.ss.veri_linked_ss.total_sent_lines = 0; + + s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll = (app_qspi_screen_veri_link_scroll_t*)p_block_info; + + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + + if (is_stored_in_qspi_storage) { + app_qspi_mmap_set_prefetch(storage_id, true); + } + + APP_ASSERT_CHECK(p_qspi_env[screen_id]->is_used_dma); + app_qspi_switch_dma_mode(screen_id, false); + + if (QSPI_DATASIZE_08_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 0; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_BYTE, DMA_DDATAALIGN_BYTE, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if (is_stored_in_qspi_storage) + app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_0); + } + else if (QSPI_DATASIZE_16_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 1; + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_HALFWORD, DMA_DDATAALIGN_HALFWORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + if (is_stored_in_qspi_storage) + app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_1); + } + else if (QSPI_DATASIZE_32_BITS == p_screen_cmd->data_size) { + s_async_write_screen_info.llp_cfg_right_shift_bit = 2; + if(is_stored_in_qspi_storage) + { + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_4, LL_DMA_DST_BURST_LENGTH_4, DMA_SRC_GATHER_DISABLE);//BALIPRO-226:LL_DMA_SRC_BURST_LENGTH_8 will cause exception for qspi-psram data + } + else + { + s_async_write_screen_info.llp_cfg_ctrl_low = QSPI_DMA_CRTL_LOW_REGISTER_CFG(DMA_SRC_INCREMENT, DMA_SDATAALIGN_WORD, DMA_DDATAALIGN_WORD, LL_DMA_SRC_BURST_LENGTH_8, LL_DMA_DST_BURST_LENGTH_8, DMA_SRC_GATHER_DISABLE); + } + if (is_stored_in_qspi_storage) + app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_2); + } + else { + p_qspi_env[screen_id]->start_flag = false; + if (storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + return false; + } + + const uint32_t scrn_pixel_height = s_async_write_screen_info.screen_info.scrn_pixel_height; + const uint32_t scrn_pixel_width = s_async_write_screen_info.screen_info.scrn_pixel_width; + const uint32_t scrn_pixel_depth = s_async_write_screen_info.screen_info.scrn_pixel_depth; + const uint32_t scrn_line_size = (scrn_pixel_width * scrn_pixel_depth); + const uint32_t scrn_refresh_lines_once = (QSPI_MAX_XFER_SIZE_ONCE / scrn_line_size); + const uint32_t max_lines = (sizeof(s_dma_llp_block) / sizeof(dma_block_config_t) -2); + const uint32_t send_lines_once = max_lines < scrn_refresh_lines_once ? max_lines : scrn_refresh_lines_once; + p_cur_block = p_block_info; + + /* check screen height/width/depth */ + if ((p_cur_block == NULL) || (scrn_pixel_width % 2 != 0) || (scrn_pixel_height % 2 != 0) || (scrn_pixel_depth != 2)) { + p_qspi_env[screen_id]->start_flag = false; + if (storage_id <= APP_QSPI_ID_2) + { + p_qspi_env[storage_id]->start_flag = false; + } + return false; + } + + if (p_cur_block->frame_draw_lines > send_lines_once) { + if (APP_QSPI_EXCEPT_DEBUG_EN) + printf("+++ ERR: Set psram(frame_draw_lines) <= %d in each Link Point\r\n", send_lines_once); + + p_qspi_env[screen_id]->start_flag = false; + + if (storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + + return false; + } + + /* prepare llp config */ + scrn_llp_config.llp_src_writeback = 1; + scrn_llp_config.llp_dst_writeback = 1; + scrn_llp_config.llp_src_en = DMA_LLP_SRC_ENABLE; + scrn_llp_config.llp_dst_en = DMA_LLP_DST_DISABLE; + scrn_llp_config.head_lli = &s_dma_llp_block[0]; + + app_scrn_cmd.instruction = s_async_write_screen_info.qspi_screen_command.instruction; + app_scrn_cmd.instruction_size = s_async_write_screen_info.qspi_screen_command.instruction_size; + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.leading_address; + app_scrn_cmd.address_size = s_async_write_screen_info.qspi_screen_command.address_size; + app_scrn_cmd.dummy_cycles = s_async_write_screen_info.qspi_screen_command.dummy_cycles; + app_scrn_cmd.data_size = s_async_write_screen_info.qspi_screen_command.data_size; + app_scrn_cmd.instruction_address_mode = s_async_write_screen_info.qspi_screen_command.instruction_address_mode; + app_scrn_cmd.data_mode = s_async_write_screen_info.qspi_screen_command.data_mode; + app_scrn_cmd.length = 0x00; + app_scrn_cmd.clock_stretch_en = 1; + + memset(&s_dma_llp_block[0],0, sizeof(dma_block_config_t) * (p_cur_block->frame_draw_lines +1)); + + for (j = 0; j < p_cur_block->frame_draw_lines; j++) { + s_dma_llp_block[j].src_address = p_cur_block->frame_ahb_start_address + (p_cur_block->frame_offset_lines + j) * scrn_line_size; + s_dma_llp_block[j].dst_address = 0; + s_dma_llp_block[j].p_lli = &s_dma_llp_block[j +1]; + s_dma_llp_block[j].CTL_L = s_async_write_screen_info.llp_cfg_ctrl_low; + s_dma_llp_block[j].CTL_H = (uint32_t)(scrn_line_size >> s_async_write_screen_info.llp_cfg_right_shift_bit); + s_dma_llp_block[j].src_status = 0x0; + s_dma_llp_block[j].dst_status = 0x0; + } + s_dma_llp_block[j - 1].p_lli = NULL; + + if (is_first_call) { + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.leading_address; + } + else { + app_scrn_cmd.address = s_async_write_screen_info.qspi_screen_command.ongoing_address; + } + + app_scrn_cmd.length = p_cur_block->frame_draw_lines * scrn_line_size; + + if (s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + if (is_first_call) { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + else { + ret = app_qspi_llp_transmit(screen_id, &scrn_llp_config, app_scrn_cmd.data_mode, app_scrn_cmd.length, false); + } + } + else { + ret = app_qspi_cmd_llp_transmit(screen_id, &app_scrn_cmd, &scrn_llp_config, false); + } + + if (ret) { + return true; + } + else { + p_qspi_env[screen_id]->start_flag = false; + + if (storage_id <= APP_QSPI_ID_2) { + p_qspi_env[storage_id]->start_flag = false; + } + + return false; + } +#else + return false; +#endif +} + +bool app_qspi_mmap_blit_image(app_qspi_id_t storage_id, blit_image_config_t * p_blit_config, blit_xfer_type_e xfer_type) { +#if QSPI_BLIT_RECT_IMAGE_SUPPORT > 0u + bool ret = true; + bool is_dma_sg_xfer = false; + hal_status_t status = HAL_OK; + uint32_t sent_lines = 0; + uint32_t this_sent_lines = 0; + uint32_t src_addr = 0; + uint32_t dst_addr = 0; + dma_sg_llp_config_t sg_llp_config; + + if ((p_qspi_env[storage_id] == NULL) || (p_qspi_env[storage_id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if(p_blit_config == NULL) { + return false; + } + + if(p_blit_config->src_img_x + p_blit_config->src_img_x_delta > p_blit_config->src_img_w) { + return false; + } + + if(p_blit_config->src_img_y + p_blit_config->src_img_y_delta > p_blit_config->src_img_h) { + return false; + } + + const uint32_t src_image_address = ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[storage_id]) + p_blit_config->src_img_address; + const uint32_t src_start_address = src_image_address + (p_blit_config->src_img_y * p_blit_config->src_img_w + p_blit_config->src_img_x) * p_blit_config->pixel_depth; + const uint32_t dst_start_address = p_blit_config->dst_buff_address + (p_blit_config->dst_buff_y * p_blit_config->dst_buff_width + p_blit_config->dst_buff_x) * p_blit_config->pixel_depth; + const uint32_t line_length = p_blit_config->src_img_x_delta * p_blit_config->pixel_depth; + const uint32_t send_lines_once = DMA_MAX_XFER_SIZE_ONCE/(line_length); + const uint32_t total_lines = p_blit_config->src_img_y_delta; + + APP_ASSERT_CHECK(p_qspi_env[storage_id]->is_used_dma); + app_qspi_mmap_set_prefetch(storage_id, true); + app_qspi_switch_dma_mode(storage_id, true); + + if(BLIT_BY_DMA_SG == xfer_type) { + + is_dma_sg_xfer = true; + + if(is_dma_sg_xfer) { + /* source - gather */ + sg_llp_config.gather_config.src_sgc = p_blit_config->src_img_x_delta * p_blit_config->pixel_depth; + sg_llp_config.gather_config.src_sgi = (p_blit_config->src_img_w - p_blit_config->src_img_x_delta) * p_blit_config->pixel_depth; + sg_llp_config.gather_config.src_gather_en = DMA_SRC_GATHER_ENABLE; + + /* dest - scatter */ + sg_llp_config.scatter_config.dst_dsc = p_blit_config->src_img_x_delta * p_blit_config->pixel_depth; + sg_llp_config.scatter_config.dst_dsi = (p_blit_config->dst_buff_width - p_blit_config->src_img_x_delta) * p_blit_config->pixel_depth; + sg_llp_config.scatter_config.dst_scatter_en = DMA_DST_SCATTER_ENABLE; + + sg_llp_config.llp_config.head_lli = NULL; + sg_llp_config.llp_config.llp_src_en = DMA_LLP_SRC_DISABLE; + sg_llp_config.llp_config.llp_dst_en = DMA_LLP_DST_DISABLE; + sg_llp_config.llp_config.llp_src_writeback = 0; + sg_llp_config.llp_config.llp_dst_writeback = 0; + } + + ret = true; + sent_lines = 0; + src_addr = src_start_address; + dst_addr = dst_start_address; + while(sent_lines < total_lines) { + + this_sent_lines = (total_lines - sent_lines) < send_lines_once ? (total_lines - sent_lines) : send_lines_once; + + p_qspi_env[storage_id]->is_dma_done = 0; + p_qspi_env[storage_id]->is_xfer_err = 0; + + status = hal_dma_start_sg_llp_it(p_qspi_env[storage_id]->handle.p_dma, src_addr, dst_addr, this_sent_lines*line_length, &sg_llp_config); + + if(status == HAL_OK) { + while(!p_qspi_env[storage_id]->is_dma_done && !p_qspi_env[storage_id]->is_xfer_err); + if(p_qspi_env[storage_id]->is_xfer_err) { + ret = false; + } + } else { + ret = false; + } + + if(!ret) { + break; + } + + sent_lines += this_sent_lines; + src_addr += this_sent_lines*p_blit_config->src_img_w*p_blit_config->pixel_depth; + dst_addr += this_sent_lines*p_blit_config->dst_buff_width*p_blit_config->pixel_depth; + } + } else if(BLIT_BY_DMA_LLP == xfer_type) { + +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) + + static dma_block_config_t dma_llp_block[DMA_LLP_BLOCKS_FOR_BLIT + 1]; + + const uint32_t sent_blocks_once = DMA_LLP_BLOCKS_FOR_BLIT; + uint32_t i = 0; + + app_qspi_mmap_set_endian_mode(storage_id, APP_QSPI_MMAP_ENDIAN_MODE_0); + + sg_llp_config.gather_config.src_gather_en = DMA_SRC_GATHER_DISABLE; + sg_llp_config.scatter_config.dst_scatter_en = DMA_DST_SCATTER_DISABLE; + sg_llp_config.llp_config.llp_src_en = DMA_LLP_SRC_ENABLE; + sg_llp_config.llp_config.llp_dst_en = DMA_LLP_DST_ENABLE; + sg_llp_config.llp_config.llp_src_writeback = 1; + sg_llp_config.llp_config.llp_dst_writeback = 1; + sg_llp_config.llp_config.head_lli = &dma_llp_block[0]; + + sent_lines = 0; + while(sent_lines < total_lines) { + this_sent_lines = (total_lines - sent_lines) < sent_blocks_once ? (total_lines - sent_lines) : sent_blocks_once; + + memset(&dma_llp_block[0], 0, sizeof(dma_block_config_t) * (sent_blocks_once + 1)); + for(i = 0; i < this_sent_lines; i++) { + dma_llp_block[i].src_address = src_start_address + (sent_lines + i) * p_blit_config->src_img_w*p_blit_config->pixel_depth; + dma_llp_block[i].dst_address = dst_start_address + (sent_lines + i) * p_blit_config->dst_buff_width*p_blit_config->pixel_depth; + dma_llp_block[i].p_lli = &dma_llp_block[i + 1]; + dma_llp_block[i].CTL_L = DMA_CTLL_INI_EN | DMA_MEMORY_TO_MEMORY | DMA_LLP_SRC_ENABLE | \ + DMA_LLP_DST_ENABLE | DMA_SRC_GATHER_DISABLE | DMA_DST_SCATTER_DISABLE | \ + DMA_DST_INCREMENT | DMA_SRC_INCREMENT | DMA_SDATAALIGN_BYTE | \ + DMA_DDATAALIGN_BYTE | LL_DMA_SRC_BURST_LENGTH_8 | LL_DMA_DST_BURST_LENGTH_8 ; + dma_llp_block[i].CTL_H = (uint32_t)(line_length); + dma_llp_block[i].src_status = 0x0; + dma_llp_block[i].dst_status = 0x0; + } + + dma_llp_block[i - 1].p_lli = NULL; + + p_qspi_env[storage_id]->is_dma_done = 0; + p_qspi_env[storage_id]->is_xfer_err = 0; + + status = hal_dma_start_sg_llp_it(p_qspi_env[storage_id]->handle.p_dma, src_start_address, dst_start_address, this_sent_lines*line_length, &sg_llp_config); + + if(status == HAL_OK) { + while(!p_qspi_env[storage_id]->is_dma_done && !p_qspi_env[storage_id]->is_xfer_err); + if(p_qspi_env[storage_id]->is_xfer_err) { + ret = false; + } + } else { + ret = false; + } + + if(!ret) { + break; + } + + sent_lines += this_sent_lines; + } +#else + ret = false; +#endif + } + + return ret; + +#else /* QSPI_BLIT_RECT_IMAGE_SUPPORT */ + + return false; + +#endif /* QSPI_BLIT_RECT_IMAGE_SUPPORT */ +} + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ + +static bool app_qspi_switch_dma_mode(app_qspi_id_t id, bool is_m2m_mode) { + app_dma_params_t dma_params = {0}; + + if(p_qspi_env[id]->is_dma_mode_m2m == is_m2m_mode) { + return true; + } else { + if(is_m2m_mode) { + dma_params.p_instance = p_qspi_env[id]->dma_cfg.dma_instance; + dma_params.channel_number = p_qspi_env[id]->dma_cfg.dma_channel; + dma_params.init.direction = DMA_MEMORY_TO_MEMORY; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_INCREMENT; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + dma_params.init.mode = DMA_NORMAL; + dma_params.init.priority = DMA_PRIORITY_LOW; + } else { + dma_params.p_instance = p_qspi_env[id]->dma_cfg.dma_instance; + dma_params.channel_number = p_qspi_env[id]->dma_cfg.dma_channel; + dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + dma_params.init.mode = DMA_NORMAL; + dma_params.init.priority = DMA_PRIORITY_LOW; + } + + p_qspi_env[id]->dma_id = app_dma_init(&dma_params, s_dma_evt_handler[id]); + if (p_qspi_env[id]->dma_id < 0) + { + return false; + } + p_qspi_env[id]->handle.p_dma = app_dma_get_handle(p_qspi_env[id]->dma_id); + p_qspi_env[id]->handle.p_dma->p_parent = (void*)&p_qspi_env[id]->handle; + } + + p_qspi_env[id]->is_dma_mode_m2m = is_m2m_mode; + return true; +} + +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) + +static bool app_qspi_cmd_llp_transmit(app_qspi_id_t screen_id, app_qspi_command_t * p_cmd, dma_llp_config_t * p_llp_config, bool is_sync) { + hal_status_t status = HAL_OK; + + if(is_sync) { /* sync mode */ + p_qspi_env[screen_id]->is_async_write_screen = false; + p_qspi_env[screen_id]->is_tx_done = 0; + p_qspi_env[screen_id]->is_xfer_err = 0; + status = hal_qspi_command_transmit_dma_llp(&(p_qspi_env[screen_id]->handle), p_cmd, p_llp_config); + + if(HAL_OK == status) { + while(!p_qspi_env[screen_id]->is_tx_done && !p_qspi_env[screen_id]->is_xfer_err); + + if(p_qspi_env[screen_id]->is_xfer_err) { + return false; + } + return true; + } + } else { /* async mode */ + p_qspi_env[screen_id]->is_async_write_screen = true; + status = hal_qspi_command_transmit_dma_llp(&(p_qspi_env[screen_id]->handle), p_cmd, p_llp_config); + + if(HAL_OK == status) { + return true; + } else { + p_qspi_env[screen_id]->is_async_write_screen = false; + } + } + + return false; +} +static bool app_qspi_llp_transmit(app_qspi_id_t screen_id, dma_llp_config_t * p_llp_config, uint32_t data_mode, uint32_t data_len, bool is_sync) { + hal_status_t status = HAL_OK; + + if(is_sync) { /* sync mode */ + p_qspi_env[screen_id]->is_async_write_screen = false; + p_qspi_env[screen_id]->is_tx_done = 0; + p_qspi_env[screen_id]->is_xfer_err = 0; + status = hal_qspi_transmit_dma_llp(&(p_qspi_env[screen_id]->handle), p_llp_config, data_mode, data_len, true); + + if(HAL_OK == status) { + while(!p_qspi_env[screen_id]->is_tx_done && !p_qspi_env[screen_id]->is_xfer_err); + + if(p_qspi_env[screen_id]->is_xfer_err) { + return false; + } + return true; + } + } else { /* async mode */ + p_qspi_env[screen_id]->is_async_write_screen = true; + status = hal_qspi_transmit_dma_llp(&(p_qspi_env[screen_id]->handle), p_llp_config, data_mode, data_len, true); + + if(HAL_OK == status) { + return true; + } else { + p_qspi_env[screen_id]->is_async_write_screen = false; + } + } + + return false; +} + +bool app_graphics_qspi_draw_screen_continue(app_qspi_id_t id, app_qspi_evt_t qspi_evt) +//if return true, you immediately should return from app_qspi_event_call too. +{ + if(p_qspi_env[id]->is_async_write_screen) { + if(p_qspi_env[id]->is_tx_done && !p_qspi_env[id]->is_xfer_err) { + + if(DRAW_TYPE_IF_DUAL_SCREEN == s_async_write_screen_info.if_type) { + + s_async_write_screen_info.ss.dual_ss.total_sent_lines += s_async_write_screen_info.ss.dual_ss.this_send_lines; + + if(s_async_write_screen_info.ss.dual_ss.total_sent_lines >= s_async_write_screen_info.screen_info.scrn_pixel_height) { + p_qspi_env[id]->is_async_write_screen = false; + qspi_evt.type = APP_QSPI_EVT_ASYNC_WR_SCRN_CPLT; + goto Label_async_scrn_notify; + } else { + bool ret = app_qspi_async_draw_screen(s_async_write_screen_info.screen_id, + s_async_write_screen_info.storage_id, + &s_async_write_screen_info.qspi_screen_command, + &s_async_write_screen_info.screen_info, + &s_async_write_screen_info.ss.dual_ss.scroll_config, + false); + if(!ret) { + p_qspi_env[id]->is_async_write_screen = false; + qspi_evt.type = APP_QSPI_EVT_ASYNC_WR_SCRN_FAIL; + goto Label_async_scrn_notify; + } else { + return true; + } + } + } else if(DRAW_TYPE_IF_VERI_LINKED_SCREEN == s_async_write_screen_info.if_type) { + s_async_write_screen_info.ss.veri_linked_ss.total_sent_lines += s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll->frame_draw_lines; + if(s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll->next != NULL) { + s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll = s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll->next; + bool ret = app_qspi_async_veri_draw_screen(s_async_write_screen_info.screen_id, + s_async_write_screen_info.storage_id, + &s_async_write_screen_info.qspi_screen_command, + &s_async_write_screen_info.screen_info, + s_async_write_screen_info.ss.veri_linked_ss.p_cur_scroll, + false); + if(!ret) { + p_qspi_env[id]->is_async_write_screen = false; + qspi_evt.type = APP_QSPI_EVT_ASYNC_WR_SCRN_FAIL; + goto Label_async_scrn_notify; + } else { + return true; + } + } else { + p_qspi_env[id]->is_async_write_screen = false; + qspi_evt.type = APP_QSPI_EVT_ASYNC_WR_SCRN_CPLT; + goto Label_async_scrn_notify; + } + } else { + p_qspi_env[id]->is_async_write_screen = false; + p_qspi_env[id]->start_flag = false; + if(s_async_write_screen_info.storage_id <= APP_QSPI_ID_2) { + p_qspi_env[s_async_write_screen_info.storage_id]->start_flag = false; + } + return false; + } + } else { + p_qspi_env[id]->is_async_write_screen = false; + qspi_evt.type = APP_QSPI_EVT_ASYNC_WR_SCRN_FAIL; + } +Label_async_scrn_notify: + if(s_async_write_screen_info.qspi_screen_command.is_one_take_cs) { + app_qspi_force_cs(s_async_write_screen_info.screen_id, false); + } + p_qspi_env[id]->start_flag = false; + if(s_async_write_screen_info.storage_id <= APP_QSPI_ID_2) { + p_qspi_env[s_async_write_screen_info.storage_id]->start_flag = false; + } + s_async_write_screen_info.if_type = DRAW_TYPE_IF_NONE; + if(p_qspi_env[id]->evt_handler != NULL) + { + p_qspi_env[id]->evt_handler(&qspi_evt); + } + return true; + } + else { + return false; + } +} + +#endif + +static void app_qspi_dma_evt_handler_0(app_dma_evt_type_t type) { + switch(type) { + case APP_DMA_EVT_TFR: + case APP_DMA_EVT_BLK: + { + p_qspi_env[APP_QSPI_ID_0]->is_xfer_err = 0; + p_qspi_env[APP_QSPI_ID_0]->is_dma_done = 1; + } + break; + + default: + case APP_DMA_EVT_ERROR: + { + p_qspi_env[APP_QSPI_ID_0]->is_xfer_err = 1; + p_qspi_env[APP_QSPI_ID_0]->is_dma_done = 1; + } + break; + } +} + +static void app_qspi_dma_evt_handler_1(app_dma_evt_type_t type) { + switch(type) { + case APP_DMA_EVT_TFR: + case APP_DMA_EVT_BLK: + { + p_qspi_env[APP_QSPI_ID_1]->is_xfer_err = 0; + p_qspi_env[APP_QSPI_ID_1]->is_dma_done = 1; + } + break; + + default: + case APP_DMA_EVT_ERROR: + { + p_qspi_env[APP_QSPI_ID_1]->is_xfer_err = 1; + p_qspi_env[APP_QSPI_ID_1]->is_dma_done = 1; + } + break; + } +} + +static void app_qspi_dma_evt_handler_2(app_dma_evt_type_t type) { + switch(type) { + case APP_DMA_EVT_TFR: + case APP_DMA_EVT_BLK: + { + p_qspi_env[APP_QSPI_ID_2]->is_xfer_err = 0; + p_qspi_env[APP_QSPI_ID_2]->is_dma_done = 1; + } + break; + + default: + case APP_DMA_EVT_ERROR: + { + p_qspi_env[APP_QSPI_ID_2]->is_xfer_err = 1; + p_qspi_env[APP_QSPI_ID_2]->is_dma_done = 1; + } + break; + } +} + +#endif +#endif +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c.c new file mode 100644 index 0000000..6391af0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c.c @@ -0,0 +1,958 @@ +/** + **************************************************************************************** + * @file app_i2c.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_i2c.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include +#include "gr_soc.h" +#include "app_drv.h" + +#ifdef HAL_I2C_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +typedef struct { + app_i2c_id_t id; + IRQn_Type irq; + i2c_regs_t *instance; +} i2c_info_t; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool i2c_prepare_for_sleep(void); +static void i2c_wake_up_ind(void); +static uint16_t i2c_gpio_config(app_i2c_pin_cfg_t pin_cfg); +void I2C0_IRQHandler(void); +void I2C1_IRQHandler(void); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +void I2C2_IRQHandler(void); +void I2C3_IRQHandler(void); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) +void I2C4_IRQHandler(void); +void I2C5_IRQHandler(void); +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const i2c_info_t s_i2c_info[APP_I2C_ID_MAX] = +{ + { + .id = APP_I2C_ID_0, + .irq = I2C0_IRQn, + .instance = I2C0, + }, + { + .id = APP_I2C_ID_1, + .irq = I2C1_IRQn, + .instance = I2C1, + }, +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + { + .id = APP_I2C_ID_2, + .irq = I2C2_IRQn, + .instance = I2C2, + }, + { + .id = APP_I2C_ID_3, + .irq = I2C3_IRQn, + .instance = I2C3, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + { + .id = APP_I2C_ID_4, + .irq = I2C4_IRQn, + .instance = I2C4, + }, + { + .id = APP_I2C_ID_5, + .irq = I2C5_IRQn, + .instance = I2C5, + }, +#endif +}; + +i2c_env_t *p_i2c_env[APP_I2C_ID_MAX]; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_i2c_pwr_id = -1; +static const app_sleep_callbacks_t i2c_sleep_cb = +{ + .app_prepare_for_sleep = i2c_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = i2c_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool i2c_prepare_for_sleep(void) +{ + hal_i2c_state_t state; + for (uint8_t i = 0; i < APP_I2C_ID_MAX; i++) + { + if (p_i2c_env[i] == NULL) + { + continue; + } + + if (p_i2c_env[i]->i2c_state == APP_I2C_ACTIVITY) + { + state = hal_i2c_get_state(&(p_i2c_env[i]->handle)); + if ((state != HAL_I2C_STATE_READY) && (state != HAL_I2C_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_i2c_suspend_reg(&p_i2c_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_i2c_env[i]->i2c_state = APP_I2C_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE static void i2c_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + for (uint8_t i = 0; i < APP_I2C_ID_MAX; i++) + { + if (p_i2c_env[i] == NULL) + { + continue; + } + + if (p_i2c_env[i]->i2c_state == APP_I2C_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_i2c_resume_reg(&p_i2c_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_i2c_info[i].irq); + hal_nvic_enable_irq(s_i2c_info[i].irq); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void i2c_wake_up(app_i2c_id_t id) +{ + if (p_i2c_env[id]->i2c_state == APP_I2C_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_i2c_resume_reg(&p_i2c_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_i2c_irq[id]); + hal_nvic_enable_irq(s_i2c_irq[id]); + p_i2c_env[id]->i2c_state = APP_I2C_ACTIVITY; + + dma_wake_up(p_i2c_env[id]->dma_id[0]); + dma_wake_up(p_i2c_env[id]->dma_id[1]); + } +} +#endif + +static uint16_t i2c_gpio_config(app_i2c_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.pull = pin_cfg.scl.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.scl.pin; + io_init.mux = pin_cfg.scl.mux; + err_code = app_io_init(pin_cfg.scl.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.sda.pull; + io_init.pin = pin_cfg.sda.pin; + io_init.mux = pin_cfg.sda.mux; + err_code = app_io_init(pin_cfg.sda.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + return err_code; +} + +static app_i2c_id_t i2c_get_id(i2c_handle_t *p_i2c) +{ + int i = 0; + + for (i = 0; i < APP_I2C_ID_MAX; i++) + { + if (p_i2c->p_instance == s_i2c_info[i].instance) + { + return s_i2c_info[i].id; + } + } + + return APP_I2C_ID_MAX; +} + +static void app_i2c_event_call(i2c_handle_t *p_i2c, app_i2c_evt_type_t evt_type) +{ + app_i2c_evt_t i2c_evt; + app_i2c_id_t id = i2c_get_id(p_i2c); + + i2c_evt.type = evt_type; + if (evt_type == APP_I2C_EVT_ERROR) + { + i2c_evt.data.error_code = p_i2c->error_code; + } + else + { + i2c_evt.data.size = p_i2c->xfer_size - p_i2c->xfer_count; + } + + i2c_evt.slave_addr = p_i2c_env[id]->slv_dev_addr; + p_i2c_env[id]->start_flag = false; + if (p_i2c_env[id]->evt_handler != NULL) + { + p_i2c_env[id]->evt_handler(&i2c_evt); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_i2c_init(app_i2c_params_t *p_params, app_i2c_evt_handler_t evt_handler) +{ + + app_i2c_id_t id = p_params->id; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + p_i2c_env[id] = &(p_params->i2c_dev); + + soc_register_nvic(I2C0_IRQn, (uint32_t)I2C0_IRQHandler); + soc_register_nvic(I2C1_IRQn, (uint32_t)I2C1_IRQHandler); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + soc_register_nvic(I2C2_IRQn, (uint32_t)I2C2_IRQHandler); + soc_register_nvic(I2C3_IRQn, (uint32_t)I2C3_IRQHandler); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + soc_register_nvic(I2C4_IRQn, (uint32_t)I2C4_IRQHandler); + soc_register_nvic(I2C5_IRQn, (uint32_t)I2C5_IRQHandler); +#endif + + app_err_code = i2c_gpio_config(p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + hal_nvic_clear_pending_irq(s_i2c_info[p_params->id].irq); + hal_nvic_enable_irq(s_i2c_info[p_params->id].irq); + + p_params->i2c_dev.role = p_params->role; + p_params->i2c_dev.p_pin_cfg = &p_params->pin_cfg; + p_params->i2c_dev.evt_handler = evt_handler; + + memcpy(&p_params->i2c_dev.handle.init, &p_params->init, sizeof(i2c_init_t)); + p_params->i2c_dev.handle.p_instance = s_i2c_info[p_params->id].instance; + hal_err_code = hal_i2c_deinit(&p_params->i2c_dev.handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_i2c_init(&p_params->i2c_dev.handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if(s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_i2c_pwr_id = pwr_register_sleep_cb(&i2c_sleep_cb, APP_DRIVER_I2C_WAPEUP_PRIORITY); + + if (s_i2c_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + p_params->i2c_dev.i2c_state = APP_I2C_ACTIVITY; + p_params->i2c_dev.start_flag = false; + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_deinit(app_i2c_id_t id) +{ + uint8_t i; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + hal_nvic_disable_irq(s_i2c_info[id].irq); + + p_i2c_env[id]->i2c_state = APP_I2C_INVALID; + p_i2c_env[id]->start_flag = false; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_I2C_ID_MAX; i++) + { + if (p_i2c_env[i] != NULL && (p_i2c_env[i]->i2c_state) != APP_I2C_INVALID) + { + break; + } + } + if (APP_I2C_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_i2c_pwr_id); + s_i2c_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + app_err_code = app_io_deinit(p_i2c_env[id]->p_pin_cfg->scl.type, p_i2c_env[id]->p_pin_cfg->scl.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_i2c_env[id]->p_pin_cfg->sda.type, p_i2c_env[id]->p_pin_cfg->sda.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + hal_err_code = hal_i2c_deinit(&p_i2c_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if (p_i2c_env[id]->i2c_dma_state == APP_I2C_DMA_INVALID) + { + p_i2c_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) +uint16_t app_i2c_timing_adjust(app_i2c_id_t id, uint32_t timing_type, int32_t delta) +{ + hal_status_t hal_err_code; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + hal_err_code = hal_i2c_timing_adjust(&p_i2c_env[id]->handle, timing_type, delta); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_timing_get(app_i2c_id_t id, uint32_t timing_type, uint32_t *p_timing_value) +{ + hal_status_t hal_err_code; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + hal_err_code = hal_i2c_timing_get(&p_i2c_env[id]->handle, timing_type, p_timing_value); + HAL_ERR_CODE_CHECK(hal_err_code); + + return APP_DRV_SUCCESS; +} +#endif /* ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) */ + +uint16_t app_i2c_receive_sync(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_receive(&p_i2c_env[id]->handle, target_address, p_data, size, timeout); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_receive(&p_i2c_env[id]->handle, p_data, size, timeout); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_receive_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_receive_it(&p_i2c_env[id]->handle, target_address, p_data, size); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_receive_it(&p_i2c_env[id]->handle, p_data, size); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_transmit_sync(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_transmit(&p_i2c_env[id]->handle, target_address, p_data, size, timeout); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_transmit(&p_i2c_env[id]->handle, p_data, size, timeout); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_transmit_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + + if (p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_transmit_it(&p_i2c_env[id]->handle, target_address, p_data, size); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_transmit_it(&p_i2c_env[id]->handle, p_data, size); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + + +uint16_t app_i2c_mem_read_sync(app_i2c_id_t id, + uint16_t dev_address, + uint16_t mem_address, + uint16_t mem_addr_size, + uint8_t *p_data, + uint16_t size, + uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = dev_address; + + err_code = hal_i2c_mem_read(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size, timeout); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_mem_read_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = dev_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + err_code = hal_i2c_mem_read_it(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size); + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_mem_write_sync(app_i2c_id_t id, + uint16_t dev_address, + uint16_t mem_address, + uint16_t mem_addr_size, + uint8_t *p_data, + uint16_t size, + uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = dev_address; + + err_code = hal_i2c_mem_write(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size, timeout); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_mem_write_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = dev_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + err_code = hal_i2c_mem_write_it(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size); + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_i2c_transmit_receive_sync(app_i2c_id_t id, uint16_t dev_address, uint8_t *p_tdata, uint16_t tsize, uint8_t *p_rdata, uint16_t rsize, uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tdata == NULL || p_rdata == NULL || tsize == 0 || rsize == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = dev_address; + + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_transmit_receive(&p_i2c_env[id]->handle, dev_address, p_tdata, tsize, p_rdata, rsize, timeout); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_receive_transmit(&p_i2c_env[id]->handle, p_tdata, tsize, p_rdata, rsize, timeout); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} +#endif + +i2c_handle_t *app_i2c_get_handle(app_i2c_id_t id) +{ + if (id >= APP_I2C_ID_MAX) + { + return NULL; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + return &p_i2c_env[id]->handle; +} + +uint16_t app_i2c_master_abort_it(app_i2c_id_t id) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_i2c_master_abort_it(&(p_i2c_env[id]->handle)); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +void hal_i2c_master_tx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_TX_CPLT); +} + +void hal_i2c_master_rx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_RX_DATA); +} + +void hal_i2c_slave_tx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_TX_CPLT); +} + +void hal_i2c_slave_rx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_RX_DATA); +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +void hal_i2c_mem_tx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_TX_CPLT); +} + +void hal_i2c_mem_rx_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_RX_DATA); +} +#endif + +void hal_i2c_error_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_EVT_ERROR); +} + +void hal_i2c_abort_cplt_callback(i2c_handle_t *p_i2c) +{ + app_i2c_event_call(p_i2c, APP_I2C_ABORT); +} + +#define I2C_HANDLER(index, val) \ +SECTION_RAM_CODE void I2C##index##_IRQHandler(void)\ +{\ + hal_i2c_irq_handler(&p_i2c_env[val]->handle);\ +} + +I2C_HANDLER(0, APP_I2C_ID_0) +I2C_HANDLER(1, APP_I2C_ID_1) +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) | (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) +I2C_HANDLER(2, APP_I2C_ID_2) +I2C_HANDLER(3, APP_I2C_ID_3) +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) +I2C_HANDLER(4, APP_I2C_ID_4) +I2C_HANDLER(5, APP_I2C_ID_5) +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c_dma.c new file mode 100644 index 0000000..da63a19 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2c_dma.c @@ -0,0 +1,563 @@ +/** + **************************************************************************************** + * @file app_i2c_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_i2c_dma.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include + +#ifdef HAL_I2C_MODULE_ENABLED +/* + * DEFINES + ***************************************************************************************** + */ + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +struct dma_request { + uint32_t tx; + uint32_t rx; +}; + +typedef struct { + struct dma_request dma0_request; + struct dma_request dma1_request; +} i2c_dma_info_t; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const i2c_dma_info_t s_i2c_dma_info[APP_I2C_ID_MAX] = { + { /* I2C 0 */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + .dma0_request = { + .tx = DMA0_REQUEST_I2C0_TX, + .rx = DMA0_REQUEST_I2C0_RX, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + .dma1_request = { + .tx = DMA1_REQUEST_I2C0_TX, + .rx = DMA1_REQUEST_I2C0_RX, + }, +#endif + }, + { /* I2C 1 */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + .dma0_request = { + .tx = DMA0_REQUEST_I2C1_TX, + .rx = DMA0_REQUEST_I2C1_RX, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + .dma1_request = { + .tx = DMA1_REQUEST_I2C1_TX, + .rx = DMA1_REQUEST_I2C1_RX, + }, +#endif + }, +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + { /* I2C 2 */ + .dma0_request = { + .tx = DMA0_REQUEST_I2C2_TX, + .rx = DMA0_REQUEST_I2C2_RX, + }, + }, + { /* I2C 3 */ + .dma0_request = { + .tx = DMA0_REQUEST_I2C3_TX, + .rx = DMA0_REQUEST_I2C3_RX, + }, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + { /* I2C 4 */ + .dma0_request = { + .tx = DMA0_REQUEST_I2C4_TX, + .rx = DMA0_REQUEST_I2C4_RX, + }, + }, + { /* I2C 5 */ + .dma0_request = { + .tx = DMA0_REQUEST_I2C5_TX, + .rx = DMA0_REQUEST_I2C5_RX, + }, + }, +#endif +}; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +extern void i2c_wake_up(app_i2c_id_t id); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern i2c_env_t *p_i2c_env[APP_I2C_ID_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint16_t app_i2c_config_dma_tx(app_i2c_params_t *p_params) +{ + app_dma_params_t tx_dma_params = { 0 }; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (p_params->dma_cfg.tx_dma_instance == DMA0) + { + if (p_params->id < APP_I2C_ID_2) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + else if (p_params->dma_cfg.tx_dma_instance == DMA1) + { + if (p_params->id > APP_I2C_ID_1) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } +#endif + + tx_dma_params.p_instance = p_params->dma_cfg.tx_dma_instance; + tx_dma_params.channel_number = p_params->dma_cfg.tx_dma_channel; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + tx_dma_params.init.src_request = DMA0_REQUEST_MEM; + tx_dma_params.init.dst_request = s_i2c_dma_info[p_params->id].dma0_request.tx; +#else + if (tx_dma_params.p_instance == DMA0) + { + tx_dma_params.init.src_request = DMA0_REQUEST_MEM; + tx_dma_params.init.dst_request = s_i2c_dma_info[p_params->id].dma0_request.tx; + } + else if (tx_dma_params.p_instance == DMA1) + { + tx_dma_params.init.src_request = DMA1_REQUEST_MEM; + tx_dma_params.init.dst_request = s_i2c_dma_info[p_params->id].dma1_request.tx; + } +#endif + tx_dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + tx_dma_params.init.src_increment = DMA_SRC_INCREMENT; + tx_dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + tx_dma_params.init.mode = DMA_NORMAL; +#endif + tx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_i2c_env[p_params->id]->dma_id[0] = app_dma_init(&tx_dma_params, NULL); + if (p_i2c_env[p_params->id]->dma_id[0] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + p_i2c_env[p_params->id]->handle.p_dmatx = app_dma_get_handle(p_i2c_env[p_params->id]->dma_id[0]); + p_i2c_env[p_params->id]->handle.p_dmatx->p_parent = (void *)&p_i2c_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_i2c_config_dma_rx(app_i2c_params_t *p_params) +{ + app_dma_params_t rx_dma_params = { 0 }; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (p_params->dma_cfg.rx_dma_instance == DMA0) + { + if (p_params->id < APP_I2C_ID_2) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + else if (p_params->dma_cfg.rx_dma_instance == DMA1) + { + if (p_params->id > APP_I2C_ID_1) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } +#endif + + rx_dma_params.p_instance = p_params->dma_cfg.rx_dma_instance; + rx_dma_params.channel_number = p_params->dma_cfg.rx_dma_channel; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + rx_dma_params.init.src_request = s_i2c_dma_info[p_params->id].dma0_request.rx; + rx_dma_params.init.dst_request = DMA0_REQUEST_MEM; +#else + if (rx_dma_params.p_instance == DMA0) + { + rx_dma_params.init.src_request = s_i2c_dma_info[p_params->id].dma0_request.rx; + rx_dma_params.init.dst_request = DMA0_REQUEST_MEM; + } + else if (rx_dma_params.p_instance == DMA1) + { + rx_dma_params.init.src_request = s_i2c_dma_info[p_params->id].dma1_request.rx; + rx_dma_params.init.dst_request = DMA1_REQUEST_MEM; + } +#endif + rx_dma_params.init.direction = DMA_PERIPH_TO_MEMORY; + rx_dma_params.init.src_increment = DMA_SRC_NO_CHANGE; + rx_dma_params.init.dst_increment = DMA_DST_INCREMENT; + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + rx_dma_params.init.mode = DMA_NORMAL; +#endif + rx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_i2c_env[p_params->id]->dma_id[1] = app_dma_init(&rx_dma_params, NULL); + if (p_i2c_env[p_params->id]->dma_id[1] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + p_i2c_env[p_params->id]->handle.p_dmarx = app_dma_get_handle(p_i2c_env[p_params->id]->dma_id[1]); + p_i2c_env[p_params->id]->handle.p_dmarx->p_parent = (void *)&p_i2c_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_i2c_config_dma(app_i2c_params_t *p_params) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + + p_i2c_env[p_params->id]->dma_id[0] = -1; + p_i2c_env[p_params->id]->dma_id[1] = -1; + + if (p_params->dma_cfg.tx_dma_instance == NULL && + p_params->dma_cfg.rx_dma_instance == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_params->dma_cfg.tx_dma_instance != NULL) + { + app_err_code = app_i2c_config_dma_tx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + if (p_params->dma_cfg.rx_dma_instance != NULL) + { + app_err_code = app_i2c_config_dma_rx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + + return app_err_code; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_i2c_dma_init(app_i2c_params_t *p_params) +{ + app_i2c_id_t id = p_params->id; + app_drv_err_t app_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + GLOBAL_EXCEPTION_DISABLE(); + app_err_code = app_i2c_config_dma(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + goto __exit; + } + p_i2c_env[id]->i2c_dma_state = APP_I2C_DMA_ACTIVITY; + +__exit: + GLOBAL_EXCEPTION_ENABLE(); + + return app_err_code; +} + +uint16_t app_i2c_dma_deinit(app_i2c_id_t id) +{ + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || + (p_i2c_env[id]->i2c_dma_state != APP_I2C_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_i2c_env[id]->dma_id[0]); + app_dma_deinit(p_i2c_env[id]->dma_id[1]); + + GLOBAL_EXCEPTION_DISABLE(); + p_i2c_env[id]->i2c_dma_state = APP_I2C_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + if (p_i2c_env[id]->i2c_state == APP_I2C_INVALID) + { + p_i2c_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_dma_receive_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_receive_dma(&p_i2c_env[id]->handle, target_address, p_data, size); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_receive_dma(&p_i2c_env[id]->handle, p_data, size); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_dma_transmit_async(app_i2c_id_t id, uint16_t target_address, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = target_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + switch(p_i2c_env[id]->role) + { + case APP_I2C_ROLE_MASTER: + err_code = hal_i2c_master_transmit_dma(&p_i2c_env[id]->handle, target_address, p_data, size); + break; + + case APP_I2C_ROLE_SLAVE: + err_code = hal_i2c_slave_transmit_dma(&p_i2c_env[id]->handle, p_data, size); + break; + + default: + break; + } + + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_dma_mem_read_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = mem_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + err_code = hal_i2c_mem_read_dma(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size); + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2c_dma_mem_write_async(app_i2c_id_t id, uint16_t dev_address, uint16_t mem_address, uint16_t mem_addr_size, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2C_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2c_env[id] == NULL) || (p_i2c_env[id]->i2c_state == APP_I2C_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2c_wake_up(id); +#endif + + p_i2c_env[id]->slv_dev_addr = mem_address; + + if(p_i2c_env[id]->start_flag == false) + { + p_i2c_env[id]->start_flag = true; + + err_code = hal_i2c_mem_write_dma(&p_i2c_env[id]->handle, dev_address, mem_address, mem_addr_size, p_data, size); + if (err_code != HAL_OK) + { + p_i2c_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s.c new file mode 100644 index 0000000..9142a77 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s.c @@ -0,0 +1,819 @@ +/** + **************************************************************************************** + * @file app_i2s.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_i2s.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" +#include + +#ifdef HAL_I2S_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_I2S_CALLBACK(id, evt) \ + do \ + { \ + p_i2s_env[id]->start_flag = false; \ + if (p_i2s_env[id]->evt_handler != NULL) \ + { \ + p_i2s_env[id]->evt_handler(&evt); \ + } \ + } while(0) + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool i2s_prepare_for_sleep(void); +static void i2s_wake_up_ind(void); +static uint16_t i2s_gpio_config(app_i2s_id_t id, app_i2s_pin_cfg_t pin_cfg); +void I2S_M_IRQHandler(void); +void I2S_S_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const IRQn_Type s_i2s_irq[APP_I2S_ID_MAX] = {I2S_S_IRQn, I2S_M_IRQn}; +static const uint32_t s_i2s_instance[APP_I2S_ID_MAX] = {I2S_S_BASE, I2S_M_BASE}; + +i2s_env_t *p_i2s_env[APP_I2S_ID_MAX]; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_i2s_pwr_id; + +const static app_sleep_callbacks_t i2s_sleep_cb = +{ + .app_prepare_for_sleep = i2s_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = i2s_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool i2s_prepare_for_sleep(void) +{ + hal_i2s_state_t state; + uint8_t i; + + for (i = 0; i < APP_I2S_ID_MAX; i++) + { + if (p_i2s_env[i] == NULL) + { + continue; + } + + if (p_i2s_env[i]->i2s_state == APP_I2S_ACTIVITY) + { + state = hal_i2s_get_state(&p_i2s_env[i]->handle); + if ((state != HAL_I2S_STATE_READY) && (state != HAL_I2S_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_i2s_suspend_reg(&p_i2s_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_i2s_env[i]->i2s_state = APP_I2S_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE static void i2s_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_I2S_ID_MAX; i++) + { + if (p_i2s_env[i] == NULL) + { + continue; + } + + if (p_i2s_env[i]->i2s_state == APP_I2S_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_i2s_resume_reg(&p_i2s_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_i2s_irq[i]); + hal_nvic_enable_irq(s_i2s_irq[i]); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void i2s_wake_up(app_i2s_id_t id) +{ + if (p_i2s_env[id]->i2s_state == APP_I2S_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_i2s_resume_reg(&p_i2s_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_i2s_irq[id]); + hal_nvic_enable_irq(s_i2s_irq[id]); + + p_i2s_env[id]->i2s_state = APP_I2S_ACTIVITY; + dma_wake_up(p_i2s_env[id]->dma_id[0]); + dma_wake_up(p_i2s_env[id]->dma_id[1]); + } +} +#endif + +static uint16_t i2s_gpio_config(app_i2s_id_t id, app_i2s_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.pull = pin_cfg.ws.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.ws.pin; + io_init.mux = pin_cfg.ws.mux; + err_code = app_io_init(pin_cfg.ws.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.sdo.pull; + io_init.pin = pin_cfg.sdo.pin; + io_init.mux = pin_cfg.sdo.mux; + err_code = app_io_init(pin_cfg.sdo.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.sdi.pull; + io_init.pin = pin_cfg.sdi.pin; + io_init.mux = pin_cfg.sdi.mux; + err_code = app_io_init(pin_cfg.sdi.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.sclk.pull; + io_init.pin = pin_cfg.sclk.pin; + io_init.mux = pin_cfg.sclk.mux; + err_code = app_io_init(pin_cfg.sclk.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + return err_code; +} + +static app_i2s_id_t i2s_get_id(i2s_handle_t *p_i2s) +{ + app_i2s_id_t id = APP_I2S_ID_MAX; + + if (p_i2s->p_instance == I2S_S) + { + id = APP_I2S_ID_SLAVE; + } + else if (p_i2s->p_instance == I2S_M) + { + id = APP_I2S_ID_MASTER; + } + + return id; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_i2s_init(app_i2s_params_t *p_params, app_i2s_evt_handler_t evt_handler) +{ + app_i2s_id_t id = p_params->id; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + p_i2s_env[id] = &(p_params->i2s_env); + app_err_code = i2s_gpio_config(p_params->id, p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + soc_register_nvic(I2S_S_IRQn, (uint32_t)I2S_S_IRQHandler); + soc_register_nvic(I2S_M_IRQn, (uint32_t)I2S_M_IRQHandler); + + hal_nvic_clear_pending_irq(s_i2s_irq[id]); + hal_nvic_enable_irq(s_i2s_irq[id]); + p_i2s_env[id]->p_pin_cfg = &p_params->pin_cfg; + p_i2s_env[id]->evt_handler = evt_handler; + + memcpy(&p_i2s_env[id]->handle.init, &p_params->init, sizeof(i2s_init_t)); + p_i2s_env[id]->handle.p_instance = (i2s_regs_t *)s_i2s_instance[id]; + + hal_err_code = hal_i2s_deinit(&p_i2s_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + hal_err_code = hal_i2s_init(&p_i2s_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if (s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_i2s_pwr_id = pwr_register_sleep_cb(&i2s_sleep_cb, APP_DRIVER_I2S_WAPEUP_PRIORITY); + if (s_i2s_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_i2s_env[id]->i2s_state = APP_I2S_ACTIVITY; + p_i2s_env[id]->start_flag = false; + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_deinit(app_i2s_id_t id) +{ + uint8_t i; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_err_code = app_io_deinit(p_i2s_env[id]->p_pin_cfg->ws.type, p_i2s_env[id]->p_pin_cfg->ws.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_i2s_env[id]->p_pin_cfg->sdo.type, p_i2s_env[id]->p_pin_cfg->sdo.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_i2s_env[id]->p_pin_cfg->sdi.type, p_i2s_env[id]->p_pin_cfg->sdi.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_i2s_env[id]->p_pin_cfg->sclk.type, p_i2s_env[id]->p_pin_cfg->sclk.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + hal_nvic_disable_irq(s_i2s_irq[id]); + + p_i2s_env[id]->i2s_state = APP_I2S_INVALID; + p_i2s_env[id]->start_flag = false; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_I2S_ID_MAX; i++) + { + if (p_i2s_env[i] != NULL && (p_i2s_env[i]->i2s_state) != APP_I2S_INVALID) + { + break; + } + } + if (APP_I2S_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_i2s_pwr_id); + s_i2s_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_i2s_deinit(&p_i2s_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + if (p_i2s_env[id]->i2s_dma_state == APP_I2S_DMA_INVALID) + { + p_i2s_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_receive_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (p_i2s_env[id]->start_flag == false) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_receive_it(&p_i2s_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_receive_sync(app_i2s_id_t id, uint16_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + err_code = hal_i2s_receive(&p_i2s_env[id]->handle, p_data, size, timeout); + + __HAL_I2S_DISABLE_RX_BLOCK(&p_i2s_env[id]->handle); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} +uint16_t app_i2s_transmit_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (p_i2s_env[id]->start_flag == false) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_transmit_it(&p_i2s_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_transmit_receive_sync(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length, + uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (p_i2s_env[id]->start_flag == false) + { + p_i2s_env[id]->start_flag = true; + + err_code = hal_i2s_transmit_receive(&p_i2s_env[id]->handle, p_tx_data, p_rx_data, length, timeout); + + __HAL_I2S_DISABLE_RX_BLOCK(&p_i2s_env[id]->handle); + + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + p_i2s_env[id]->start_flag = false; + + return APP_DRV_SUCCESS; +} + + +uint16_t app_i2s_transmit_receive_async(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (false == p_i2s_env[id]->start_flag) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_transmit_receive_it(&p_i2s_env[id]->handle, p_tx_data, p_rx_data, length); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + return APP_DRV_SUCCESS; +} + +/** + * @brief Abort ongoing transfer (blocking mode). + * @param id I2S ID + * @note This procedure is executed in blocking mode: When exiting + * function, Abort is considered as completed. + * @retval ::APP_DRV_SUCCESS: Operation is OK. + * @retval ::HAL_ERROR: Parameter error or operation not supported. + * @retval ::HAL_BUSY: Driver is busy. + * @retval ::HAL_TIMEOUT: Timeout occurred. + */ +uint16_t app_i2s_abort(app_i2s_id_t id) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + err_code = hal_i2s_abort(&p_i2s_env[id]->handle); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + p_i2s_env[id]->start_flag = false; + + return APP_DRV_SUCCESS; +} + + +uint16_t app_i2s_transmit_sync(app_i2s_id_t id, uint16_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + err_code = hal_i2s_transmit(&p_i2s_env[id]->handle, p_data, size, timeout); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_enable(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_ENABLE(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_disable(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_DISABLE(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_enable_clock(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_ENABLE_CLOCK(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_disable_clock(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_DISABLE_CLOCK(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_flush_tx_fifo(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_FLUSH_TX_FIFO(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_flush_rx_fifo(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + __HAL_I2S_FLUSH_RX_FIFO(&p_i2s_env[id]->handle); + + return APP_DRV_SUCCESS; +} + +i2s_handle_t *app_i2s_get_handle(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return NULL; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + return &p_i2s_env[id]->handle; +} + +void hal_i2s_tx_cplt_callback(i2s_handle_t *p_i2s) +{ + app_i2s_evt_t i2s_evt; + app_i2s_id_t id = i2s_get_id(p_i2s); + + i2s_evt.type = APP_I2S_EVT_TX_CPLT; + i2s_evt.data.size = p_i2s->tx_xfer_size - p_i2s->tx_xfer_count; + APP_I2S_CALLBACK(id, i2s_evt); +} + +void hal_i2s_rx_cplt_callback(i2s_handle_t *p_i2s) +{ + app_i2s_evt_t i2s_evt; + app_i2s_id_t id = i2s_get_id(p_i2s); + + i2s_evt.type = APP_I2S_EVT_RX_DATA; + i2s_evt.data.size = p_i2s->rx_xfer_size - p_i2s->rx_xfer_count; + __HAL_I2S_DISABLE_RX_BLOCK(p_i2s); + APP_I2S_CALLBACK(id, i2s_evt); +} + +void hal_i2s_tx_rx_cplt_callback(i2s_handle_t *p_i2s) +{ + app_i2s_evt_t i2s_evt; + app_i2s_id_t id = i2s_get_id(p_i2s); + + i2s_evt.type = APP_I2S_EVT_TX_RX; + i2s_evt.data.size = p_i2s->rx_xfer_size - p_i2s->rx_xfer_count; + __HAL_I2S_DISABLE_RX_BLOCK(p_i2s); + APP_I2S_CALLBACK(id, i2s_evt); +} + +void hal_i2s_error_callback(i2s_handle_t *p_i2s) +{ + app_i2s_evt_t i2s_evt; + app_i2s_id_t id = i2s_get_id(p_i2s); + + i2s_evt.type = APP_I2S_EVT_ERROR; + i2s_evt.data.error_code = p_i2s->error_code; + APP_I2S_CALLBACK(id, i2s_evt); +} + +SECTION_RAM_CODE void I2S_S_IRQHandler(void) +{ + hal_i2s_irq_handler(&p_i2s_env[APP_I2S_ID_SLAVE]->handle); +} + +SECTION_RAM_CODE void I2S_M_IRQHandler(void) +{ + hal_i2s_irq_handler(&p_i2s_env[APP_I2S_ID_MASTER]->handle); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s_dma.c new file mode 100644 index 0000000..1a5a820 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_i2s_dma.c @@ -0,0 +1,390 @@ +/** + **************************************************************************************** + * @file app_i2s_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_i2s_dma.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include + +#ifdef HAL_I2S_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +extern void i2s_wake_up(app_i2s_id_t id); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern i2s_env_t *p_i2s_env[APP_I2S_ID_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint16_t app_i2s_config_dma_tx(app_i2s_params_t *p_params) +{ + app_dma_params_t tx_dma_params = { 0 }; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (p_params->dma_cfg.tx_dma_instance == DMA0) + { + return APP_DRV_ERR_INVALID_PARAM; + } +#endif + + tx_dma_params.p_instance = p_params->dma_cfg.tx_dma_instance; + tx_dma_params.channel_number = p_params->dma_cfg.tx_dma_channel; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + tx_dma_params.init.src_request = DMA1_REQUEST_MEM; + tx_dma_params.init.dst_request = (p_params->id == APP_I2S_ID_SLAVE) ? DMA1_REQUEST_I2S_S_TX : DMA1_REQUEST_I2S_M_TX; +#else + tx_dma_params.init.src_request = DMA0_REQUEST_MEM; + tx_dma_params.init.dst_request = (p_params->id == APP_I2S_ID_SLAVE) ? DMA0_REQUEST_I2S_S_TX : DMA0_REQUEST_I2S_M_TX; +#endif + + tx_dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + tx_dma_params.init.src_increment = DMA_SRC_INCREMENT; + tx_dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + if (p_params->init.data_size <= I2S_DATASIZE_16BIT) + { + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD; + } + else + { + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; + } + tx_dma_params.init.mode = DMA_NORMAL; + tx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_i2s_env[p_params->id]->dma_id[0] = app_dma_init(&tx_dma_params, NULL); + if (p_i2s_env[p_params->id]->dma_id[0] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + p_i2s_env[p_params->id]->handle.p_dmatx = app_dma_get_handle(p_i2s_env[p_params->id]->dma_id[0]); + p_i2s_env[p_params->id]->handle.p_dmatx->p_parent = (void*)&p_i2s_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_i2s_config_dma_rx(app_i2s_params_t *p_params) +{ + app_dma_params_t rx_dma_params = { 0 }; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (p_params->dma_cfg.rx_dma_instance == DMA0) + { + return APP_DRV_ERR_INVALID_PARAM; + } +#endif + + rx_dma_params.p_instance = p_params->dma_cfg.rx_dma_instance; + rx_dma_params.channel_number = p_params->dma_cfg.rx_dma_channel; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + rx_dma_params.init.src_request = (p_params->id == APP_I2S_ID_SLAVE) ? DMA1_REQUEST_I2S_S_RX : DMA1_REQUEST_I2S_M_RX; + rx_dma_params.init.dst_request = DMA1_REQUEST_MEM; +#else + rx_dma_params.init.src_request = (p_params->id == APP_I2S_ID_SLAVE) ? DMA0_REQUEST_I2S_S_RX : DMA0_REQUEST_I2S_M_RX; + rx_dma_params.init.dst_request = DMA0_REQUEST_MEM; +#endif + rx_dma_params.init.direction = DMA_PERIPH_TO_MEMORY; + rx_dma_params.init.src_increment = DMA_SRC_NO_CHANGE; + rx_dma_params.init.dst_increment = DMA_DST_INCREMENT; + if (p_params->init.data_size <= I2S_DATASIZE_16BIT) + { + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD; + } + else + { + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; + } + rx_dma_params.init.mode = DMA_NORMAL; + rx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_i2s_env[p_params->id]->dma_id[1] = app_dma_init(&rx_dma_params, NULL); + if (p_i2s_env[p_params->id]->dma_id[1] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + p_i2s_env[p_params->id]->handle.p_dmarx = app_dma_get_handle(p_i2s_env[p_params->id]->dma_id[1]); + p_i2s_env[p_params->id]->handle.p_dmarx->p_parent = (void*)&p_i2s_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_i2s_config_dma(app_i2s_params_t *p_params) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + + p_i2s_env[p_params->id]->dma_id[0] = -1; + p_i2s_env[p_params->id]->dma_id[1] = -1; + + if (p_params->dma_cfg.tx_dma_instance == NULL && + p_params->dma_cfg.rx_dma_instance == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_params->dma_cfg.tx_dma_instance != NULL) + { + app_err_code = app_i2s_config_dma_tx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + if (p_params->dma_cfg.rx_dma_instance != NULL) + { + app_err_code = app_i2s_config_dma_rx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + + return APP_DRV_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_i2s_dma_init(app_i2s_params_t *p_params) +{ + app_i2s_id_t id = p_params->id; + app_drv_err_t app_err_code; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + GLOBAL_EXCEPTION_DISABLE(); + app_err_code = app_i2s_config_dma(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + goto __exit; + } + p_i2s_env[id]->i2s_dma_state = APP_I2S_DMA_ACTIVITY; +__exit: + GLOBAL_EXCEPTION_ENABLE(); + + return app_err_code; +} + +uint16_t app_i2s_dma_deinit(app_i2s_id_t id) +{ + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || + (p_i2s_env[id]->i2s_dma_state != APP_I2S_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_i2s_env[id]->dma_id[0]); + app_dma_deinit(p_i2s_env[id]->dma_id[1]); + + GLOBAL_EXCEPTION_DISABLE(); + p_i2s_env[id]->i2s_dma_state = APP_I2S_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + if (p_i2s_env[id]->i2s_state == APP_I2S_INVALID) + { + p_i2s_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_dma_receive_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (p_i2s_env[id]->start_flag == false) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_receive_dma(&p_i2s_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_dma_transmit_async(app_i2s_id_t id, uint16_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (p_i2s_env[id]->start_flag == false) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_transmit_dma(&p_i2s_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_i2s_dma_transmit_receive_async(app_i2s_id_t id, + uint16_t *p_tx_data, + uint16_t *p_rx_data, + uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_I2S_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_i2s_env[id] == NULL) || (p_i2s_env[id]->i2s_state == APP_I2S_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (NULL == p_tx_data || NULL == p_rx_data || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + i2s_wake_up(id); +#endif + + if (false == p_i2s_env[id]->start_flag) + { + p_i2s_env[id]->start_flag = true; + err_code = hal_i2s_transmit_receive_dma(&p_i2s_env[id]->handle, p_tx_data, p_rx_data, length); + if (err_code != HAL_OK) + { + p_i2s_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + return APP_DRV_SUCCESS; +} +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_io.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_io.c new file mode 100644 index 0000000..a2b9f6c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_io.c @@ -0,0 +1,845 @@ +/** + **************************************************************************************** + * @file app_io.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_drv.h" +#include "app_io.h" +#include "grx_hal.h" +#include "gr_soc.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define IO_MODE_NONE 0x0 +#define IO_GROUP_MAX (3) +#define IO_GROUP_MAX_PINS (16) +#define IO_GROUP_MAX_PINS_GR551X (32) +#define IO_GROUP_TYPE_MAX (3) +#define GPIO_INT_PIN_MAX (SOC_GPIO_PINS_MAX) +#define AON_INT_PIN_MAX (SOC_AON_PINS_MAX) +#define PIN_MASK (0x1) +#define PIN_SHIF (1) +#define IRQ_NUM_NONE (0) +#define GET_HANDLE(type) ((gpio_regs_t *)io_info[type].handle) +#define GET_PIN_IRQ(type) (io_info[type].irq) + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +typedef struct { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + uint8_t io_type; +#endif + app_io_callback_t callback_func; + void *arg; +} io_evt_info_t; + +typedef struct { + gpio_regs_t *handle; + IRQn_Type irq; +} io_dev_info_t; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const uint16_t s_io_pull[IO_GROUP_TYPE_MAX][APP_IO_PULL_MAX] = +{ + { GPIO_NOPULL, GPIO_PULLUP, GPIO_PULLDOWN }, + { AON_GPIO_NOPULL, AON_GPIO_PULLUP, AON_GPIO_PULLDOWN }, + { MSIO_NOPULL, MSIO_PULLUP, MSIO_PULLDOWN }, +}; + +static io_evt_info_t gpio_evt_info[GPIO_INT_PIN_MAX]; +static io_evt_info_t aon_evt_info[AON_INT_PIN_MAX]; + +static const io_dev_info_t io_info[IO_GROUP_MAX] = +{ + { + .handle = GPIO0, + .irq = EXT0_IRQn, + }, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + { + .handle = GPIO1, + .irq = EXT1_IRQn, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + { + .handle = GPIO2, + .irq = EXT2_IRQn, + }, +#endif +}; + +static const uint16_t s_io_mode[IO_GROUP_TYPE_MAX][APP_IO_MODE_MAX] = +{ + { + IO_MODE_NONE, + GPIO_MODE_INPUT, + GPIO_MODE_OUTPUT, + GPIO_MODE_MUX, + GPIO_MODE_IT_RISING, + GPIO_MODE_IT_FALLING, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + GPIO_MODE_IT_BOTH_EDGE, +#endif + GPIO_MODE_IT_HIGH, + GPIO_MODE_IT_LOW, + IO_MODE_NONE + }, + { + IO_MODE_NONE, + AON_GPIO_MODE_INPUT, + AON_GPIO_MODE_OUTPUT, + AON_GPIO_MODE_MUX, + AON_GPIO_MODE_IT_RISING, + AON_GPIO_MODE_IT_FALLING, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + AON_GPIO_MODE_IT_BOTH_EDGE, +#endif + AON_GPIO_MODE_IT_HIGH, + AON_GPIO_MODE_IT_LOW, + IO_MODE_NONE + }, + { + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + MSIO_MODE_DIGITAL, +#endif + MSIO_MODE_DIGITAL, + MSIO_MODE_DIGITAL, + MSIO_MODE_ANALOG + }, +}; + +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) +static const uint16_t s_io_strength[IO_GROUP_TYPE_MAX][APP_IO_STRENGTH_MAX] = +{ + { + GPIO_STRENGTH_LOW, + GPIO_STRENGTH_MEDIUM, + GPIO_STRENGTH_HIGH, + GPIO_STRENGTH_ULTRA, + }, + { + AON_GPIO_STRENGTH_LOW, + AON_GPIO_STRENGTH_MEDIUM, + AON_GPIO_STRENGTH_HIGH, + AON_GPIO_STRENGTH_ULTRA, + }, + { + MSIO_STRENGTH_LOW, + MSIO_STRENGTH_MEDIUM, + MSIO_STRENGTH_HIGH, + MSIO_STRENGTH_ULTRA, + } +}; + +static const uint16_t s_io_speed[IO_GROUP_TYPE_MAX][APP_IO_SPPED_MAX] = +{ + {GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH}, + {AON_GPIO_SPEED_MEDIUM, AON_GPIO_SPEED_HIGH}, + {MSIO_SPEED_MEDIUM, MSIO_SPEED_HIGH}, +}; + +static const uint16_t s_io_input_type[IO_GROUP_TYPE_MAX][APP_IO_INPUT_TYPE_MAX] = +{ + {GPIO_INPUT_TYPE_CMOS, GPIO_INPUT_TYPE_SCHMITT}, + {AON_GPIO_INPUT_TYPE_CMOS, AON_GPIO_INPUT_TYPE_SCHMITT}, + {MSIO_INPUT_TYPE_CMOS, MSIO_INPUT_TYPE_SCHMITT}, +}; +#endif + +void EXT0_IRQHandler(void); +void EXT1_IRQHandler(void); +void EXT2_IRQHandler(void); +void AON_EXT_IRQHandler(void); + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +static int get_pin_index(uint32_t pin) +{ + int index = 0; + while ((pin & PIN_MASK) != PIN_MASK) + { + index++; + pin = pin >> PIN_SHIF; + } + return index; +} + +uint16_t app_io_init(app_io_type_t type, app_io_init_t *p_init) +{ + gpio_init_t io_config = GPIO_DEFAULT_CONFIG; + aon_gpio_init_t aon_io_config = AON_GPIO_DEFAULT_CONFIG; + msio_init_t msio_config = MSIO_DEFAULT_CONFIG; + gpio_regs_t *p_handle = NULL; + + if (NULL == p_init) + { + return APP_DRV_ERR_POINTER_NULL; + } + + soc_register_nvic(EXT0_IRQn, (uint32_t)EXT0_IRQHandler); +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + soc_register_nvic(EXT1_IRQn, (uint32_t)EXT1_IRQHandler); +#endif + soc_register_nvic(AON_EXT_IRQn, (uint32_t)AON_EXT_IRQHandler); +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) + soc_register_nvic(EXT2_IRQn, (uint32_t)EXT2_IRQHandler); +#endif + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + io_config.mode = s_io_mode[0][p_init->mode]; + io_config.pull = s_io_pull[0][p_init->pull]; + io_config.mux = p_init->mux; + io_config.pin = p_init->pin; + p_handle = GET_HANDLE(type); + if ((!(p_init->pin & APP_IO_PINS_0_15)) || (p_handle == NULL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_gpio_init(p_handle, &io_config); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + io_config.mode = s_io_mode[0][p_init->mode]; + io_config.pull = s_io_pull[0][p_init->pull]; + io_config.mux = p_init->mux; + io_config.pin = p_init->pin; + + if (APP_IO_PINS_0_15 & p_init->pin) + { + io_config.pin = (APP_IO_PINS_0_15 & p_init->pin); + hal_gpio_init(GPIO0, &io_config); + } + if (APP_IO_PINS_16_31 & p_init->pin) + { + io_config.pin = (APP_IO_PINS_16_31 & p_init->pin) >> 16; + hal_gpio_init(GPIO1, &io_config); + } + break; +#endif + case APP_IO_TYPE_AON: + aon_io_config.mode = s_io_mode[1][p_init->mode]; + aon_io_config.pull = s_io_pull[1][p_init->pull]; + aon_io_config.mux = p_init->mux; + aon_io_config.pin = p_init->pin; + if (!(p_init->pin & APP_AON_IO_PIN_ALL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_aon_gpio_init(&aon_io_config); + break; + + case APP_IO_TYPE_MSIO: + if (p_init->mode >= APP_IO_MODE_IT_RISING && p_init->mode <= APP_IO_MODE_IT_LOW) + { + return APP_DRV_ERR_INVALID_MODE; + } + if (APP_IO_MODE_OUTPUT == p_init->mode) + { + msio_config.direction = MSIO_DIRECTION_OUTPUT; + } + else + { + msio_config.direction = MSIO_DIRECTION_INPUT; + } + msio_config.mode = s_io_mode[2][p_init->mode]; + msio_config.pull = s_io_pull[2][p_init->pull]; + msio_config.mux = p_init->mux; + msio_config.pin = p_init->pin; + if (!(p_init->pin & APP_MSIO_IO_PIN_ALL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_msio_init(MSIOA, &msio_config); + break; + + default: + return APP_DRV_ERR_INVALID_TYPE; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_io_deinit(app_io_type_t type, uint32_t pin) +{ + gpio_regs_t *p_handle = NULL; + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if ((!(pin & APP_IO_PINS_0_15)) || (p_handle == NULL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_gpio_deinit(p_handle, pin); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + if (APP_IO_PINS_0_15 & pin) + { + hal_gpio_deinit(GPIO0, (APP_IO_PINS_0_15 & pin)); + } + if (APP_IO_PINS_16_31 & pin) + { + hal_gpio_deinit(GPIO1, (APP_IO_PINS_16_31 & pin) >> 16); + } + break; +#endif + case APP_IO_TYPE_AON: + if (!(pin & APP_AON_IO_PIN_ALL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_aon_gpio_deinit(pin); + break; + + case APP_IO_TYPE_MSIO: + if (!(pin & APP_MSIO_IO_PIN_ALL)) + return APP_DRV_ERR_INVALID_PARAM; + hal_msio_deinit(MSIOA, pin); + break; + + default: + return APP_DRV_ERR_INVALID_TYPE; + } + + return APP_DRV_SUCCESS; +} + +app_io_pin_state_t app_io_read_pin(app_io_type_t type, uint32_t pin) +{ + app_io_pin_state_t pin_state = APP_IO_PIN_RESET; + gpio_regs_t *p_handle = NULL; + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + pin_state = (app_io_pin_state_t)hal_gpio_read_pin(p_handle, pin); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + if (APP_IO_PINS_0_15 & pin) + { + pin_state = (app_io_pin_state_t)hal_gpio_read_pin(GPIO0, pin); + } + if (APP_IO_PINS_16_31 & pin) + { + pin_state = (app_io_pin_state_t)hal_gpio_read_pin(GPIO1, pin >> 16); + } + break; +#endif + case APP_IO_TYPE_AON: + pin_state = (app_io_pin_state_t)hal_aon_gpio_read_pin(pin); + break; + + case APP_IO_TYPE_MSIO: + pin_state = (app_io_pin_state_t)hal_msio_read_pin(MSIOA, pin); + break; + + default: + break; + } + + return pin_state; +} + +uint16_t app_io_write_pin(app_io_type_t type, uint32_t pin, app_io_pin_state_t pin_state) +{ + gpio_regs_t *p_handle = NULL; + + if (pin_state != APP_IO_PIN_RESET && pin_state != APP_IO_PIN_SET) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if (p_handle == NULL) + return APP_DRV_ERR_INVALID_PARAM; + hal_gpio_write_pin(p_handle, pin, (gpio_pin_state_t)pin_state); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + if (APP_IO_PINS_0_15 & pin) + { + hal_gpio_write_pin(GPIO0, (uint16_t)(APP_IO_PINS_0_15 & pin), (gpio_pin_state_t)pin_state); + } + if (APP_IO_PINS_16_31 & pin) + { + hal_gpio_write_pin(GPIO1, (uint16_t)((APP_IO_PINS_16_31 & pin) >> 16), (gpio_pin_state_t)pin_state); + } + break; +#endif + case APP_IO_TYPE_AON: + hal_aon_gpio_write_pin(pin, (aon_gpio_pin_state_t)pin_state); + break; + + case APP_IO_TYPE_MSIO: + hal_msio_write_pin(MSIOA, pin, (msio_pin_state_t)pin_state); + break; + + default: + return APP_DRV_ERR_INVALID_TYPE; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_io_toggle_pin(app_io_type_t type, uint32_t pin) +{ + gpio_regs_t *p_handle = NULL; + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if (p_handle == NULL) + return APP_DRV_ERR_INVALID_PARAM; + hal_gpio_toggle_pin(p_handle, pin); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + if (APP_IO_PINS_0_15 & pin) + { + hal_gpio_toggle_pin(GPIO0, (uint16_t)(APP_IO_PINS_0_15 & pin)); + } + if (APP_IO_PINS_16_31 & pin) + { + hal_gpio_toggle_pin(GPIO1, (uint16_t)((APP_IO_PINS_16_31 & pin) >> 16)); + } + break; +#endif + case APP_IO_TYPE_AON: + hal_aon_gpio_toggle_pin(pin); + break; + + case APP_IO_TYPE_MSIO: + hal_msio_toggle_pin(MSIOA, pin); + break; + default: + return APP_DRV_ERR_INVALID_TYPE; + } + + return APP_DRV_SUCCESS; +} + + +uint16_t app_io_set_speed(app_io_type_t type, uint32_t pin, app_io_speed_t speed) +{ +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) + gpio_regs_t *p_handle = NULL; + uint32_t io_speed; + + if (speed > APP_IO_SPPED_MAX) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if (p_handle == NULL) + return APP_DRV_ERR_INVALID_PARAM; + + io_speed = s_io_speed[0][speed]; + ll_gpio_set_pin_speed(p_handle, pin, io_speed); + break; + + case APP_IO_TYPE_AON: + io_speed = s_io_speed[1][speed]; + ll_aon_gpio_set_pin_speed(pin, io_speed); + break; + case APP_IO_TYPE_MSIO: + io_speed = s_io_speed[2][speed]; + ll_msio_set_pin_speed(MSIOA, pin, io_speed); + break; + default: + return APP_DRV_ERR_INVALID_TYPE; + } + return APP_DRV_SUCCESS; +#else + return APP_DRV_ERR_INVALID_MODE; +#endif +} + + +uint16_t app_io_set_strength(app_io_type_t type, uint32_t pin, app_io_strength_t strength) +{ +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) + gpio_regs_t *p_handle = NULL; + uint32_t io_strength; + + if (strength >= APP_IO_STRENGTH_MAX) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if (p_handle == NULL) + return APP_DRV_ERR_INVALID_PARAM; + + io_strength = s_io_strength[0][strength]; + ll_gpio_set_pin_strength(p_handle, pin, io_strength); + break; + + case APP_IO_TYPE_AON: + io_strength = s_io_strength[1][strength]; + ll_aon_gpio_set_pin_strength(pin, io_strength); + break; + case APP_IO_TYPE_MSIO: + io_strength = s_io_strength[2][strength]; + ll_msio_set_pin_strength(MSIOA, pin, io_strength); + break; + default: + return APP_DRV_ERR_INVALID_TYPE; + } + return APP_DRV_SUCCESS; +#else + return APP_DRV_ERR_INVALID_MODE; +#endif +} + +uint16_t app_io_set_intput_type(app_io_type_t type, uint32_t pin, app_io_input_type_t input_type) +{ +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X)) + gpio_regs_t *p_handle = NULL; + uint32_t io_input_type; + + if (input_type > APP_IO_INPUT_TYPE_MAX) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + p_handle = GET_HANDLE(type); + if (p_handle == NULL) + return APP_DRV_ERR_INVALID_PARAM; + + io_input_type = s_io_input_type[0][input_type]; + ll_gpio_set_pin_input_type(p_handle, pin, io_input_type); + break; + + case APP_IO_TYPE_AON: + io_input_type = s_io_input_type[1][input_type]; + ll_aon_gpio_set_pin_input_type(pin, io_input_type); + break; + case APP_IO_TYPE_MSIO: + io_input_type = s_io_input_type[2][input_type]; + ll_msio_set_pin_input_type(MSIOA, pin, io_input_type); + break; + default: + return APP_DRV_ERR_INVALID_TYPE; + } + return APP_DRV_SUCCESS; +#else + return APP_DRV_ERR_INVALID_MODE; +#endif +} + +uint16_t app_io_event_register_cb(app_io_type_t type, app_io_init_t *p_init, app_io_callback_t io_evt_cb, void *arg) +{ + uint16_t ret; + uint32_t pin = p_init->pin; + uint8_t pin_index; + uint8_t base_pins = 0; + uint16_t group_pins; + IRQn_Type irq; + + if (type == APP_IO_TYPE_MSIO) + { + return APP_DRV_ERR_INVALID_TYPE; + } + + app_io_deinit(type, pin); + ret = app_io_init(type, p_init); + APP_DRV_ERR_CODE_CHECK(ret); + + if (type == APP_IO_TYPE_AON) + { + group_pins = AON_INT_PIN_MAX; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + switch (p_init->mode) + { + case APP_IO_MODE_IT_RISING: + hal_pwr_config_ext_wakeup(pin, PWR_EXTWKUP_TYPE_RISING); + break; + + case APP_IO_MODE_IT_FALLING: + hal_pwr_config_ext_wakeup(pin, PWR_EXTWKUP_TYPE_FALLING); + break; + + case APP_IO_MODE_IT_HIGH: + hal_pwr_config_ext_wakeup(pin, PWR_EXTWKUP_TYPE_HIGH); + break; + + case APP_IO_MODE_IT_LOW: + hal_pwr_config_ext_wakeup(pin, PWR_EXTWKUP_TYPE_LOW); + break; + + default: break; + } + extern void pwr_mgmt_wakeup_source_setup(uint32_t wakeup_source); + pwr_mgmt_wakeup_source_setup(PWR_WKUP_COND_EXT); +#endif + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + else if (type == APP_IO_TYPE_NORMAL) + { + group_pins = IO_GROUP_MAX_PINS_GR551X; + base_pins = 0; + } +#endif + else + { + group_pins = IO_GROUP_MAX_PINS; + base_pins = IO_GROUP_MAX_PINS * type; + } + for (pin_index = 0; pin_index < group_pins; pin_index++) + { + if (pin & PIN_MASK) + { + switch(type) + { + case APP_IO_TYPE_GPIOA: + case APP_IO_TYPE_GPIOB: + case APP_IO_TYPE_GPIOC: + irq = GET_PIN_IRQ(type); + if (irq == IRQ_NUM_NONE) + return APP_DRV_ERR_INVALID_PARAM; + GLOBAL_EXCEPTION_DISABLE(); + gpio_evt_info[pin_index + base_pins].callback_func = io_evt_cb; + gpio_evt_info[pin_index + base_pins].arg = arg; + GLOBAL_EXCEPTION_ENABLE(); + hal_nvic_clear_pending_irq(irq); + hal_nvic_enable_irq(irq); + break; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + case APP_IO_TYPE_NORMAL: + GLOBAL_EXCEPTION_DISABLE(); + gpio_evt_info[pin_index + base_pins].callback_func = io_evt_cb; + gpio_evt_info[pin_index + base_pins].arg = arg; + gpio_evt_info[pin_index + base_pins].io_type = APP_IO_TYPE_NORMAL; + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(EXT0_IRQn); + hal_nvic_enable_irq(EXT0_IRQn); + hal_nvic_clear_pending_irq(EXT1_IRQn); + hal_nvic_enable_irq(EXT1_IRQn); + break; +#endif + case APP_IO_TYPE_AON: + GLOBAL_EXCEPTION_DISABLE(); + aon_evt_info[pin_index + base_pins].callback_func = io_evt_cb; + aon_evt_info[pin_index + base_pins].arg = arg; + GLOBAL_EXCEPTION_ENABLE(); + hal_nvic_clear_pending_irq(AON_EXT_IRQn); + hal_nvic_enable_irq(AON_EXT_IRQn); + break; + default: + return APP_DRV_ERR_INVALID_TYPE; + } + } + pin >>= PIN_SHIF; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_io_event_unregister(app_io_type_t type, uint32_t pin) +{ + uint16_t group_pins; + uint8_t pin_index; + uint8_t base_pins = 0; + uint32_t pin_tmp = pin; + io_evt_info_t *p_evt_cb = NULL; + + if (type == APP_IO_TYPE_MSIO) + { + return APP_DRV_ERR_INVALID_TYPE; + } + + if (type == APP_IO_TYPE_AON) + { + group_pins = AON_INT_PIN_MAX; + p_evt_cb = aon_evt_info; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + else if (type == APP_IO_TYPE_NORMAL) + { + group_pins = IO_GROUP_MAX_PINS_GR551X; + base_pins = 0; + p_evt_cb = gpio_evt_info; + } +#endif + else + { + group_pins = IO_GROUP_MAX_PINS; + base_pins = IO_GROUP_MAX_PINS * type; + p_evt_cb = gpio_evt_info; + } + + for (pin_index = 0; pin_index < group_pins; pin_index++) + { + if (pin_tmp & PIN_MASK) + { + GLOBAL_EXCEPTION_DISABLE(); + p_evt_cb[pin_index + base_pins].callback_func = NULL; + p_evt_cb[pin_index + base_pins].arg = NULL; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + gpio_evt_info[pin_index + base_pins].io_type = 0; +#endif + GLOBAL_EXCEPTION_ENABLE(); + } + pin_tmp >>= PIN_SHIF; + } + + return app_io_deinit(type, pin); +} + +void hal_gpio_exti_callback(gpio_regs_t *GPIOx, uint16_t gpio_pin) +{ + uint16_t pin_index = get_pin_index(gpio_pin); + app_io_evt_t io_evt; + int idx; + + for (idx = 0; idx < IO_GROUP_MAX; idx++) + { + if (GPIOx != io_info[idx].handle) + continue; + + pin_index += idx * IO_GROUP_MAX_PINS; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (gpio_evt_info[pin_index].io_type == APP_IO_TYPE_NORMAL) + { + io_evt.type = APP_IO_TYPE_NORMAL; + } + else + { + io_evt.type = (app_io_type_t)idx; + } + if (GPIO1 == GPIOx) + { + io_evt.pin = (uint32_t)(gpio_pin << 16); + } + else + { + io_evt.pin = gpio_pin; + } +#else + io_evt.type = (app_io_type_t)idx; + io_evt.pin = gpio_pin; +#endif + io_evt.arg = gpio_evt_info[pin_index].arg; + if (gpio_evt_info[pin_index].callback_func != NULL) + gpio_evt_info[pin_index].callback_func(&io_evt); + } +} + +void hal_aon_gpio_callback(uint16_t aon_gpio_pin) +{ + app_io_evt_t io_evt; + uint16_t pin_index = 0; + uint16_t aon_pin = aon_gpio_pin; + int i; + + io_evt.type = APP_IO_TYPE_AON; + for (i = 0; i < AON_INT_PIN_MAX; i++) + { + if (aon_pin & PIN_MASK) + { + io_evt.pin = 0x1U << pin_index; + io_evt.arg = aon_evt_info[pin_index].arg; + if (aon_evt_info[pin_index].callback_func != NULL) + aon_evt_info[pin_index].callback_func(&io_evt); + } + pin_index++; + aon_pin >>= PIN_SHIF; + } +} + +#define EXT_IQR_HANDLER(index) \ +SECTION_RAM_CODE void EXT##index##_IRQHandler(void)\ +{\ + hal_gpio_exti_irq_handler(io_info[index].handle);\ +} + +SECTION_RAM_CODE void AON_EXT_IRQHandler(void) +{ + hal_aon_gpio_irq_handler(); +} + +EXT_IQR_HANDLER(0) +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) +EXT_IQR_HANDLER(1) +EXT_IQR_HANDLER(2) +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_iso7816.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_iso7816.c new file mode 100644 index 0000000..eb30b85 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_iso7816.c @@ -0,0 +1,645 @@ +/** + **************************************************************************************** + * @file app_iso7816.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_iso7816.h" +#include "app_io.h" +#include "app_drv.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" +#include + +#ifdef HAL_ISO7816_MODULE_ENABLED + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool iso7816_prepare_for_sleep(void); +static void iso7816_wake_up_ind(void); +static uint16_t iso7816_gpio_config(app_iso7816_pin_cfg_t pin_cfg); +void ISO7816_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const uint32_t s_iso7816_instance = ISO7816_BASE; + +iso7816_env_t *p_iso7816_env = NULL; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_iso7816_pwr_id; + +/* sim card command and response data buffer */ +#define ISO7816_BUFFER_SIZE 33 +static __ALIGNED(4) uint8_t iso7816_buffer[ISO7816_BUFFER_SIZE]; +static const app_sleep_callbacks_t iso7816_sleep_cb = +{ + .app_prepare_for_sleep = iso7816_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = iso7816_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool iso7816_prepare_for_sleep(void) +{ + hal_iso7816_state_t state; + + if (p_iso7816_env->iso7816_state == APP_ISO7816_ACTIVITY) + { + state = hal_iso7816_get_state(&p_iso7816_env->handle); + if ((state != HAL_ISO7816_STATE_READY) && (state != HAL_ISO7816_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_iso7816_suspend_reg(&p_iso7816_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_iso7816_env->iso7816_state = APP_ISO7816_SLEEP; + #endif + } + return true; +} + +SECTION_RAM_CODE static void iso7816_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + if (p_iso7816_env->iso7816_state == APP_ISO7816_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_iso7816_resume_reg(&p_iso7816_env->handle); //TODO + GLOBAL_EXCEPTION_ENABLE(); + + if(p_iso7816_env->use_mode!= APP_ISO7816_TYPE_POLLING) + { + hal_nvic_clear_pending_irq(ISO7816_IRQn); + hal_nvic_enable_irq(ISO7816_IRQn); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +static void iso7816_wake_up(void) +{ + if (p_iso7816_env->iso7816_state == APP_ISO7816_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_iso7816_resume_reg(&p_iso7816_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + + if(p_iso7816_env->use_mode != APP_ISO7816_TYPE_POLLING) + { + hal_nvic_clear_pending_irq(ISO7816_IRQn); + hal_nvic_enable_irq(ISO7816_IRQn); + } + p_iso7816_env->iso7816_state = APP_ISO7816_ACTIVITY; + } +} +#endif + +static uint16_t iso7816_gpio_config(app_iso7816_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.pull = pin_cfg.clk.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.clk.pin; + io_init.mux = pin_cfg.clk.mux; + err_code = app_io_init(pin_cfg.clk.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.rst.pull; + io_init.pin = pin_cfg.rst.pin; + io_init.mux = pin_cfg.rst.mux; + err_code = app_io_init(pin_cfg.rst.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.io.pull; + io_init.pin = pin_cfg.io.pin; + io_init.mux = pin_cfg.io.mux; + err_code = app_io_init(pin_cfg.io.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.presence.pull; + io_init.pin = pin_cfg.presence.pin; + io_init.mux = pin_cfg.presence.mux; + err_code = app_io_init(pin_cfg.presence.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + return err_code; +} + +static void app_iso7816_event_call(iso7816_handle_t *p_iso7816, app_iso7816_evt_type_t evt_type) +{ + app_iso7816_evt_t iso7816_evt; + iso7816_evt.type = evt_type; + if(evt_type == APP_ISO7816_EVT_ERROR) + { + iso7816_evt.data.error_code = p_iso7816->error_code; + } + else if(evt_type == APP_ISO7816_EVT_TX_CPLT) + { + iso7816_evt.data.size = p_iso7816->tx_xfer_size - p_iso7816->rx_xfer_count; + } + else if(evt_type == APP_ISO7816_EVT_RX_CPLT) + { + iso7816_evt.data.size = p_iso7816->tx_xfer_size - p_iso7816->rx_xfer_count; + } + + p_iso7816_env->start_flag = false; + if (p_iso7816_env->evt_handler != NULL) + { + p_iso7816_env->evt_handler(&iso7816_evt); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_iso7816_init(app_iso7816_params_t *p_params, app_iso7816_evt_handler_t evt_handler) +{ + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + p_iso7816_env = &p_params->iso7816_env; + app_err_code = iso7816_gpio_config(p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + p_iso7816_env->use_mode = p_params->use_mode; + p_iso7816_env->p_pin_cfg = &p_params->pin_cfg; + p_iso7816_env->evt_handler = evt_handler; + + memcpy(&p_iso7816_env->handle.init, &p_params->init, sizeof(iso7816_init_t)); + p_iso7816_env->handle.p_instance = (iso7816_regs_t *)s_iso7816_instance; + p_iso7816_env->handle.buffer_size = ISO7816_BUFFER_SIZE; + p_iso7816_env->handle.tx_xfer_size = ISO7816_BUFFER_SIZE; + p_iso7816_env->handle.rx_xfer_size = ISO7816_BUFFER_SIZE; + p_iso7816_env->handle.p_tx_rx_buffer = iso7816_buffer; + + hal_err_code = hal_iso7816_init(&p_iso7816_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if(p_params->use_mode != APP_ISO7816_TYPE_POLLING) + { + soc_register_nvic(ISO7816_IRQn, (uint32_t)ISO7816_IRQHandler); + hal_nvic_clear_pending_irq(ISO7816_IRQn); + hal_nvic_enable_irq(ISO7816_IRQn); + } + + if (s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_iso7816_pwr_id = pwr_register_sleep_cb(&iso7816_sleep_cb, APP_DRIVER_ISO7816_WAPEUP_PRIORITY); + + if (s_iso7816_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + p_iso7816_env->iso7816_state = APP_ISO7816_ACTIVITY; + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_deinit(void) +{ + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_err_code = app_io_deinit(p_iso7816_env->p_pin_cfg->clk.type, p_iso7816_env->p_pin_cfg->clk.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_iso7816_env->p_pin_cfg->rst.type, p_iso7816_env->p_pin_cfg->rst.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_iso7816_env->p_pin_cfg->io.type, p_iso7816_env->p_pin_cfg->io.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + app_err_code = app_io_deinit(p_iso7816_env->p_pin_cfg->presence.type, p_iso7816_env->p_pin_cfg->presence.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + hal_nvic_disable_irq(ISO7816_IRQn); + + p_iso7816_env->iso7816_state = APP_ISO7816_INVALID; + p_iso7816_env->start_flag = false; + + GLOBAL_EXCEPTION_DISABLE(); + if(p_iso7816_env->iso7816_state == APP_ISO7816_INVALID) + { + pwr_unregister_sleep_cb(s_iso7816_pwr_id); + s_iso7816_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_iso7816_deinit(&p_iso7816_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + p_iso7816_env = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_receive_sync(uint16_t size, uint32_t timeout) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + err_code = hal_iso7816_receive(&p_iso7816_env->handle, size, timeout); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_receive_async(uint16_t size) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_iso7816_env->use_mode == APP_ISO7816_TYPE_POLLING) + { + return APP_DRV_ERR_INVALID_MODE; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + if(p_iso7816_env->start_flag == false) + { + p_iso7816_env->start_flag = true; + err_code = hal_iso7816_receive_it(&p_iso7816_env->handle, size); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_transmit_sync(uint16_t size, uint32_t timeout) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + err_code = hal_iso7816_transmit(&p_iso7816_env->handle, size, timeout); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_transmit_async(uint16_t size) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_iso7816_env->use_mode == APP_ISO7816_TYPE_POLLING) + { + return APP_DRV_ERR_INVALID_MODE; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + if(p_iso7816_env->start_flag == false) + { + p_iso7816_env->start_flag = true; + + switch(p_iso7816_env->use_mode) + { + case APP_ISO7816_TYPE_INTERRUPT: + err_code = hal_iso7816_transmit_it(&p_iso7816_env->handle, size); + break; + case APP_ISO7816_TYPE_POLLING: + err_code = hal_iso7816_transmit(&p_iso7816_env->handle, size,100); + break; + default: + break; + } + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_transmit_receive_async(uint16_t tx_size, uint16_t rx_size) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (tx_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_iso7816_env->use_mode == APP_ISO7816_TYPE_POLLING) + { + return APP_DRV_ERR_INVALID_MODE; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + if(p_iso7816_env->start_flag == false) + { + p_iso7816_env->start_flag = true; + + err_code = hal_iso7816_transmit_receive_it(&p_iso7816_env->handle, tx_size, rx_size); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_transmit_receive_sync(uint16_t tx_size, uint16_t rx_size, uint32_t timeout) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (tx_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + err_code = hal_iso7816_transmit_receive(&p_iso7816_env->handle, tx_size, rx_size, timeout); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint32_t app_iso7816_get_power_states(void) +{ + uint32_t power_states; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + power_states = hal_iso7816_get_power_states(&p_iso7816_env->handle); + + return power_states; +} + +uint16_t app_iso7816_set_action(uint32_t action) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (action > APP_ISO7816_ACTION_TXRX) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + err_code = hal_iso7816_set_action(&p_iso7816_env->handle, action); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_iso7816_set_etudiv(uint32_t devide) +{ + hal_status_t err_code = HAL_OK; + + if ((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + + if(p_iso7816_env->start_flag == false) + { + p_iso7816_env->start_flag = true; + + err_code = hal_iso7816_set_etudiv(&p_iso7816_env->handle, devide); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +iso7816_handle_t *app_iso7816_get_handle(void) +{ + if((p_iso7816_env == NULL) || (p_iso7816_env->iso7816_state == APP_ISO7816_INVALID)) + { + return NULL; + } +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + iso7816_wake_up(); +#endif + return &p_iso7816_env->handle; +} + +void hal_iso7816_error_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_ERROR); +} + +void hal_iso7816_abort_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_ABORT); +} + +void hal_iso7816_presence_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_PRESENCE); +} + +void hal_iso7816_atr_cplt_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_ATR_CPLT); +} + +void hal_iso7816_tx_cplt_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_TX_CPLT); +} + +void hal_iso7816_rx_cplt_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_RX_CPLT); +} + +void hal_iso7816_tx_rx_cplt_callback(iso7816_handle_t *p_iso7816) +{ + app_iso7816_event_call(p_iso7816, APP_ISO7816_EVT_TX_RX_CPLT); +} + +void ISO7816_IRQHandler(void) +{ + hal_iso7816_irq_handler(&p_iso7816_env->handle); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm.c new file mode 100644 index 0000000..488048d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm.c @@ -0,0 +1,695 @@ +/** + **************************************************************************************** + * @file app_pwm.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_pwm.h" +#include "app_io.h" +#include "app_pwr_mgmt.h" +#include +#include "gr_soc.h" + +#ifdef HAL_CALENDAR_MODULE_ENABLED + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool pwm_prepare_for_sleep(void); +static void pwm_wake_up_ind(void); +static uint16_t pwm_gpio_config(app_pwm_pin_cfg_t pin_cfg); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +pwm_env_t *p_pwm_env[APP_PWM_ID_MAX]; +static const uint32_t s_pwm_instance[APP_PWM_ID_MAX] = {PWM0_BASE, PWM1_BASE}; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_pwm_pwr_id; + +static const app_sleep_callbacks_t pwm_sleep_cb = +{ + .app_prepare_for_sleep = pwm_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = pwm_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +bool pwm_prepare_for_sleep(void) +{ + hal_pwm_state_t state; + uint8_t i; + + for (i = 0; i < APP_PWM_ID_MAX; i++) + { + if (p_pwm_env[i] == NULL) + { + continue; + } + + if (p_pwm_env[i] != NULL && p_pwm_env[i]->pwm_state == APP_PWM_ACTIVITY) + { + state = hal_pwm_get_state(&p_pwm_env[i]->handle); + if ((state != HAL_PWM_STATE_RESET) && (state != HAL_PWM_STATE_READY)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_pwm_suspend_reg(&p_pwm_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_pwm_env[i]->pwm_state = APP_PWM_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE void pwm_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_PWM_ID_MAX; i++) + { + if (p_pwm_env[i] == NULL) + { + continue; + } + + if (p_pwm_env[i] != NULL && p_pwm_env[i]->pwm_state == APP_PWM_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_pwm_resume_reg(&p_pwm_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + if (p_pwm_env[i]->pwm_module_state == APP_PWM_START) + { + hal_pwm_start(&p_pwm_env[i]->handle); + } + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void pwm_wake_up(app_pwm_id_t id) +{ + if (p_pwm_env[id] != NULL && p_pwm_env[id]->pwm_state == APP_PWM_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_pwm_resume_reg(&p_pwm_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + if (p_pwm_env[id]->pwm_module_state == APP_PWM_START) + { + hal_pwm_start(&p_pwm_env[id]->handle); + } + } +} +#endif + +static uint16_t pwm_gpio_config(app_pwm_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.pull = APP_IO_PULLUP; + io_init.mode = APP_IO_MODE_MUX; + + if (pin_cfg.channel_a.enable == APP_PWM_PIN_ENABLE) + { + io_init.pin = pin_cfg.channel_a.pin; + io_init.mux = pin_cfg.channel_a.mux; + err_code = app_io_init(pin_cfg.channel_a.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + if (pin_cfg.channel_b.enable == APP_PWM_PIN_ENABLE) + { + io_init.pin = pin_cfg.channel_b.pin; + io_init.mux = pin_cfg.channel_b.mux; + err_code = app_io_init(pin_cfg.channel_b.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + if (pin_cfg.channel_c.enable == APP_PWM_PIN_ENABLE) + { + io_init.pin = pin_cfg.channel_c.pin; + io_init.mux = pin_cfg.channel_c.mux; + err_code = app_io_init(pin_cfg.channel_c.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + +static void app_pwm_event_call(pwm_handle_t *p_pwm, app_pwm_evt_type_t evt_type) +{ + app_pwm_evt_t pwm_evt; + app_pwm_id_t id = APP_PWM_ID_0; + + pwm_evt.type = evt_type; + if(pwm_evt.type == APP_PWM_CHANNEL_A_ERROR) { + pwm_evt.error_code = HAL_PWM_CHANNEL_A_ERROR; + } else if (pwm_evt.type == APP_PWM_CHANNEL_B_ERROR) { + pwm_evt.error_code = HAL_PWM_CHANNEL_B_ERROR; + } else if (pwm_evt.type == APP_PWM_CHANNEL_C_ERROR) { + pwm_evt.error_code = HAL_PWM_CHANNEL_C_ERROR; + } else { + pwm_evt.error_code = HAL_PWM_ERROR_NONE; + } + + p_pwm_env[id]->evt_handler(&pwm_evt); +} + +void PWM0_IRQHandler(void) +{ + hal_pwm_irq_handler(&p_pwm_env[APP_PWM_ID_0]->handle); +} + +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +uint16_t app_pwm_init(app_pwm_params_t *p_params, app_pwm_evt_handler_t evt_handler) +#else +uint16_t app_pwm_init(app_pwm_params_t *p_params) +#endif +{ + app_pwm_id_t id = p_params->id; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + p_pwm_env[id] = &(p_params->pwm_env); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + soc_register_nvic(PWM0_IRQn, (uint32_t)PWM0_IRQHandler); + + NVIC_ClearPendingIRQ(PWM0_IRQn); + NVIC_EnableIRQ(PWM0_IRQn); +#endif + + app_err_code = pwm_gpio_config(p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + memcpy(&p_pwm_env[id]->handle.init, &p_params->init, sizeof(pwm_init_t)); + + p_pwm_env[id]->p_pin_cfg = &p_params->pin_cfg; + p_pwm_env[id]->handle.active_channel = (hal_pwm_active_channel_t)p_params->active_channel; + p_pwm_env[id]->handle.p_instance = (pwm_regs_t *)s_pwm_instance[id]; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + p_pwm_env[id]->evt_handler = evt_handler; +#endif + + hal_err_code = hal_pwm_deinit(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_pwm_init(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + if (!s_sleep_cb_registered_flag) + { + s_sleep_cb_registered_flag = true; + + s_pwm_pwr_id = pwr_register_sleep_cb(&pwm_sleep_cb, APP_DRIVER_PWM_WAPEUP_PRIORITY); + if (s_pwm_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_pwm_env[id]->pwm_state = APP_PWM_ACTIVITY; + p_pwm_env[id]->pwm_module_state = APP_PWM_STOP; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_deinit(app_pwm_id_t id) +{ + uint8_t i; + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + p_pwm_env[id]->pwm_state = APP_PWM_INVALID; + p_pwm_env[id]->pwm_module_state = APP_PWM_STOP; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_PWM_ID_MAX; i++) + { + if (p_pwm_env[i] != NULL && (p_pwm_env[i]->pwm_state) != APP_PWM_INVALID) + { + break; + } + } + if (APP_PWM_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_pwm_pwr_id); + s_pwm_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + if (p_pwm_env[id]->p_pin_cfg->channel_a.enable == APP_PWM_PIN_ENABLE) + { + app_io_deinit(p_pwm_env[id]->p_pin_cfg->channel_a.type, p_pwm_env[id]->p_pin_cfg->channel_a.pin); + } + if (p_pwm_env[id]->p_pin_cfg->channel_b.enable == APP_PWM_PIN_ENABLE) + { + app_io_deinit(p_pwm_env[id]->p_pin_cfg->channel_b.type, p_pwm_env[id]->p_pin_cfg->channel_b.pin); + } + if (p_pwm_env[id]->p_pin_cfg->channel_c.enable == APP_PWM_PIN_ENABLE) + { + app_io_deinit(p_pwm_env[id]->p_pin_cfg->channel_c.type, p_pwm_env[id]->p_pin_cfg->channel_c.pin); + } + + err_code = hal_pwm_deinit(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_start(app_pwm_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_start(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_START; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_stop(app_pwm_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_stop(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_STOP; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_update_freq(app_pwm_id_t id, uint32_t freq) +{ + hal_status_t err_code; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_update_freq(&p_pwm_env[id]->handle, freq); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_config_channel(app_pwm_id_t id, app_pwm_active_channel_t channel, app_pwm_channel_init_t *p_config) +{ + hal_status_t err_code; + + hal_pwm_active_channel_t active_channel; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + pwm_none_coding_channel_init_t channel_cfg; +#else + pwm_channel_init_t channel_cfg; +#endif + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + active_channel = (hal_pwm_active_channel_t)channel; + channel_cfg.duty = p_config->duty; + channel_cfg.drive_polarity = p_config->drive_polarity; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + channel_cfg.fstoplvl = p_config->fstoplvl; +#endif + + err_code = hal_pwm_config_channel(&p_pwm_env[id]->handle, &channel_cfg, active_channel); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + +uint16_t app_pwm_resume(app_pwm_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_resume(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_START; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_pause(app_pwm_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_pause(&p_pwm_env[id]->handle); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_STOP; + + return APP_DRV_SUCCESS; +} + +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + +uint16_t app_pwm_inactive_channel(app_pwm_id_t id, app_pwm_active_channel_t channel) +{ + hal_status_t err_code; + + hal_pwm_active_channel_t active_channel; + + if (id >= APP_PWM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + active_channel = (hal_pwm_active_channel_t)channel; + + err_code = hal_pwm_inactive_channel(&p_pwm_env[id]->handle, active_channel); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#endif + +pwm_handle_t *app_pwm_get_handle(app_pwm_id_t id) +{ + if (id >= APP_PWM_ID_MAX) + { + return NULL; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + return &p_pwm_env[id]->handle; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + +uint16_t app_pwm_set_coding_data_in_one_channel(app_pwm_id_t id, uint32_t coding_data) +{ + hal_status_t err_code; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_set_coding_data_in_one_channel(&p_pwm_env[id]->handle, coding_data); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_set_coding_data_in_three_channels(app_pwm_id_t id, uint32_t coding_data0, uint32_t coding_data1, uint32_t coding_data2) +{ + hal_status_t err_code; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_set_coding_data_in_three_channels(&p_pwm_env[id]->handle, coding_data0, coding_data1, coding_data2); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_start_coding_in_one_channel(app_pwm_id_t id, uint32_t coding_data) +{ + hal_status_t err_code; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_start_coding_in_one_channel(&p_pwm_env[id]->handle, coding_data); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_START; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_start_coding_in_three_channels(app_pwm_id_t id, uint32_t coding_data0, uint32_t coding_data1, uint32_t coding_data2) +{ + hal_status_t err_code; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_start_coding_in_three_channels(&p_pwm_env[id]->handle, coding_data0, coding_data1, coding_data2); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_START; + + return APP_DRV_SUCCESS; +} + +void hal_pwm_channel_a_error_callback(pwm_handle_t *p_pwm) +{ + app_pwm_event_call(p_pwm, APP_PWM_CHANNEL_A_ERROR); +} + +void hal_pwm_channel_b_error_callback(pwm_handle_t *p_pwm) +{ + app_pwm_event_call(p_pwm, APP_PWM_CHANNEL_B_ERROR); +} + +void hal_pwm_channel_c_error_callback(pwm_handle_t *p_pwm) +{ + app_pwm_event_call(p_pwm, APP_PWM_CHANNEL_C_ERROR); +} + +void hal_pwm_coding_done_callback(pwm_handle_t *p_pwm) +{ + app_pwm_event_call(p_pwm, APP_PWM_CODING_DONE); +} + +void hal_pwm_coding_load_callback(pwm_handle_t *p_pwm) +{ + app_pwm_event_call(p_pwm, APP_PWM_CODING_LOAD); +} + +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm_dma.c new file mode 100644 index 0000000..1e42847 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwm_dma.c @@ -0,0 +1,201 @@ +/** + **************************************************************************************** + * @file app_pwm_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_pwm_dma.h" +#include "app_dma.h" +#include "app_drv_config.h" +#include "app_pwr_mgmt.h" +#include +#include "gr_soc.h" + +#ifdef HAL_PWM_MODULE_ENABLED + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + +/* + * DEFINES + ***************************************************************************************** + */ + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +extern bool pwm_prepare_for_sleep(void); +extern void pwm_sleep_canceled(void); +extern void pwm_wake_up_ind(void); +extern void pwm_wake_up(app_pwm_id_t id); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern pwm_env_t *p_pwm_env[APP_PWM_ID_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint16_t app_pwm_config_dma(app_pwm_params_t *p_params) +{ + app_dma_params_t dma_params; + + dma_params.p_instance = p_params->use_mode.pwm_dma_instance; + dma_params.channel_number = p_params->use_mode.pwm_dma_channel; + + if(dma_params.p_instance != DMA0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if(p_params->id >= APP_PWM_ID_1) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + dma_params.init.src_request = DMA0_REQUEST_MEM; + dma_params.init.dst_request = DMA0_REQUEST_PWM0; + dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; + dma_params.init.priority = DMA_PRIORITY_LOW; + p_pwm_env[p_params->id]->dma_id[0] = app_dma_init(&dma_params, NULL); + + if (p_pwm_env[p_params->id]->dma_id[0] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + /* Associate the initialized DMA handle to the UART handle */ + p_pwm_env[p_params->id]->handle.p_dma = app_dma_get_handle(p_pwm_env[p_params->id]->dma_id[0]); + p_pwm_env[p_params->id]->handle.p_dma->p_parent = (void*)&p_pwm_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_pwm_dma_init(app_pwm_params_t *p_params) +{ + app_drv_err_t err_code = APP_DRV_SUCCESS; + uint8_t id = p_params->id; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || (p_pwm_env[id]->pwm_state == APP_PWM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + GLOBAL_EXCEPTION_DISABLE(); + p_pwm_env[p_params->id]->dma_id[0] = -1; + err_code = app_pwm_config_dma(p_params); + GLOBAL_EXCEPTION_ENABLE(); + APP_DRV_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->use_mode.pwm_dma_instance = p_params->use_mode.pwm_dma_instance; + p_pwm_env[id]->use_mode.pwm_dma_channel = p_params->use_mode.pwm_dma_channel; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_dma_deinit(app_pwm_id_t id) +{ + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if (p_pwm_env[id] == NULL) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_pwm_env[id]->dma_id[0]); + + p_pwm_env[id]->dma_id[0] = -1; + p_pwm_env[id]->handle.p_dma = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_pwm_start_coding_with_dma(app_pwm_id_t id, uint32_t *p_data, uint16_t size) +{ + hal_status_t err_code; + + if (id != APP_PWM_ID_0) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_pwm_env[id] == NULL) || + (p_pwm_env[id]->pwm_state == APP_PWM_INVALID) || + (p_pwm_env[id]->handle.p_dma == NULL)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + pwm_wake_up(id); +#endif + + err_code = hal_pwm_start_coding_with_dma(&p_pwm_env[id]->handle, p_data, size); + HAL_ERR_CODE_CHECK(err_code); + + p_pwm_env[id]->pwm_module_state = APP_PWM_START; + + return APP_DRV_SUCCESS; +} + +#endif + +#endif /* HAL_PWM_MODULE_ENABLED */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwr_mgmt.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwr_mgmt.c new file mode 100644 index 0000000..962b8db --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_pwr_mgmt.c @@ -0,0 +1,279 @@ +/** + **************************************************************************************** + * @file app_pwr_mgmt.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_pwr_mgmt.h" +#include "grx_hal.h" +#include "grx_sys.h" + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +struct pwr_env_t +{ + app_sleep_callbacks_t *pwr_sleep_cb[APP_SLEEP_CB_MAX]; + wakeup_priority_t wakeup_priority[APP_SLEEP_CB_MAX]; + bool is_pwr_callback_reg; +}; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +struct pwr_env_t s_pwr_env; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) +pwr_mgmt_dev_state_t pwr_enter_sleep_check_new(void) +{ + uint32_t i; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + if (g_devices_state == 0x0) +#else + if((g_devices_state == 0x0) && (g_extra_devices_state == 0x0)) +#endif + { + if (g_devices_renew > 0) + { + for (i = 0x0; i < MAX_PERIPH_DEVICE_NUM; i++) + { + if (devices_suspend_cb[i] == NULL) + continue; + + if (devices_handle[i] == NULL) + continue; + + if (g_devices_renew & (1 << i)) + { + devices_suspend_cb[i](devices_handle[i]); + } + } + + g_devices_renew = ALL_DEVICES_BACKUP; + } + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + if (g_extra_devices_renew > 0) + { + for (i = 0x0; i < MAX_EXTRA_DEVICE_NUM; i++) + { + if (extra_devices_suspend_cb[i] == NULL) + continue; + + if (g_extra_devices_renew & (1 << i)) + { + extra_devices_suspend_cb[i](extra_devices_handle[i]); + } + } + + g_extra_devices_renew = ALL_DEVICES_BACKUP; + } +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + if (g_devices_state == 0x0) +#else + if((g_devices_state == 0x0) && (g_extra_devices_state == 0x0)) +#endif + { + #ifdef HAL_RECOVER_WHEN_USING + g_devices_sleep = ALL_DEVICES_SLEEP; + #endif + } + else + { + return DEVICE_BUSY; + } + + return DEVICE_IDLE; + } + + return DEVICE_BUSY; +} + +SECTION_RAM_CODE void pwr_wake_up_ind_new(void) +{ + uint32_t i; + +#ifndef HAL_RECOVER_WHEN_USING + for (i = 0x0; i < MAX_PERIPH_DEVICE_NUM; i++) + { + if (devices_resume_cb[i] == NULL) + continue; + + if (devices_handle[i] == NULL) + continue; + + devices_resume_cb[i](devices_handle[i]); + } +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + for (i = 0x0; i < MAX_EXTRA_DEVICE_NUM; i++) + { + if (extra_devices_resume_cb[i] == NULL) + continue; + + extra_devices_resume_cb[i](extra_devices_handle[i]); + } +#endif +} +#endif + +pwr_id_t pwr_register_sleep_cb(const app_sleep_callbacks_t *p_cb, wakeup_priority_t wakeup_priority) +{ + pwr_id_t id = -1; + uint8_t i = 0; + + GLOBAL_EXCEPTION_DISABLE(); + + if (!s_pwr_env.is_pwr_callback_reg) + { +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + pwr_mgmt_dev_init(pwr_wake_up_ind_new); + pwr_mgmt_set_callback(pwr_enter_sleep_check_new, NULL); +#else + pwr_mgmt_dev_init(pwr_wake_up_ind); + pwr_mgmt_set_callback(pwr_enter_sleep_check, NULL); +#endif + + s_pwr_env.is_pwr_callback_reg = true; + } + + if (p_cb == NULL || wakeup_priority > WAPEUP_PRIORITY_HIGH || wakeup_priority < WAPEUP_PRIORITY_LOW) + { + goto exit; + } + + while ((i < APP_SLEEP_CB_MAX) && (s_pwr_env.pwr_sleep_cb[i] != NULL)) + { + i++; + } + if (i < APP_SLEEP_CB_MAX) + { + s_pwr_env.pwr_sleep_cb[i] = (app_sleep_callbacks_t *)p_cb; + s_pwr_env.wakeup_priority[i] = wakeup_priority; + id = i; + } + +exit: + GLOBAL_EXCEPTION_ENABLE(); + + return id; +} + +void pwr_unregister_sleep_cb(pwr_id_t id) +{ + if((id >= 0) && (id < APP_SLEEP_CB_MAX))// Is id valid? + { + s_pwr_env.pwr_sleep_cb[id] = NULL; + } +} + +SECTION_RAM_CODE void pwr_wake_up_ind(void) +{ + uint8_t i; + app_sleep_callbacks_t *p_cb; + wakeup_priority_t priority; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + uint8_t hal_init_mark = 0; +#endif + + for (priority = WAPEUP_PRIORITY_HIGH; priority != 0; priority--) + { + for (i = 0; i < APP_SLEEP_CB_MAX; i++) + { + p_cb = s_pwr_env.pwr_sleep_cb[i]; + if ((p_cb != NULL) && (p_cb ->app_wake_up_ind != NULL) && (priority == s_pwr_env.wakeup_priority[i])) + { + p_cb ->app_wake_up_ind(); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if(hal_init_mark == 0) + { + hal_init_mark = 1; + hal_init(); + } +#endif + } + } + } +} + +pwr_mgmt_dev_state_t pwr_enter_sleep_check(void) +{ + int16_t i; + pwr_mgmt_dev_state_t allow_entering_sleep = DEVICE_IDLE; + app_sleep_callbacks_t *p_cb; + + // 1. Inquiry Adapters + for (i = APP_SLEEP_CB_MAX - 1; i >= 0; i--) + { + p_cb = s_pwr_env.pwr_sleep_cb[i]; + if (( p_cb != NULL) && (p_cb->app_prepare_for_sleep != NULL) ) + { + if (!p_cb->app_prepare_for_sleep()) + { + allow_entering_sleep = DEVICE_BUSY; + break; + } + } + } + + // 2. If an Adapter rejected sleep, resume any Adapters that have already accepted it. + if ( allow_entering_sleep == DEVICE_BUSY ) + { + i++; + while (i < APP_SLEEP_CB_MAX) + { + p_cb = s_pwr_env.pwr_sleep_cb[i]; + if ( (p_cb != NULL) && (p_cb->app_sleep_canceled != NULL) ) + { + p_cb->app_sleep_canceled(); + } + i++; + } + } + + return allow_entering_sleep; +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi.c new file mode 100644 index 0000000..7cb0004 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi.c @@ -0,0 +1,1550 @@ +/** + **************************************************************************************** + * @file app_qspi.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ + +#include "app_assert.h" +#include "app_qspi.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "platform_sdk.h" +#include "app_drv.h" +#include "gr_soc.h" +#include + +#ifdef HAL_QSPI_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define QSPI_SMART_CS_LOW(id) \ + do { \ + if(p_qspi_env[id]->p_pin_cfg->cs.enable == APP_QSPI_PIN_ENABLE) \ + { \ + app_io_write_pin(p_qspi_env[id]->p_pin_cfg->cs.type, \ + p_qspi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_RESET); \ + } \ + } while(0) + +#define QSPI_SMART_CS_HIGH(id) \ + do { \ + if(p_qspi_env[id]->p_pin_cfg->cs.enable == APP_QSPI_PIN_ENABLE) \ + { \ + app_io_write_pin(p_qspi_env[id]->p_pin_cfg->cs.type, \ + p_qspi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_SET); \ + } \ + } while(0) +#else +#define QSPI_SMART_CS_LOW(id) +#define QSPI_SMART_CS_HIGH(id) +#endif + +#define APP_QSPI_EXCEPT_DEBUG_EN 1u + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/******************************************************************** + * QUAD_WRITE_32b_PATCH : just exist in QUAD/DATASIZE_32BITS/DMA scene + * if enable, MUST Control the CS By Software. + */ +#define QSPI_QUAD_WRITE_32b_PATCH_EN 0u + +/******************************************************************** + * DATA Endian Mode Optional Value : + * 0 : data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) + * 1 : data[1] | (data[0] << 8) | (data[3] << 16) | (data[2] << 24) + * 2 : data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24) + * 3 : data[2] | (data[3] << 8) | (data[0] << 16) | (data[1] << 24) + */ +#define QSPI_QUAD_WRITE_DATA_ENDIAN_MODE 0u +#endif +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +bool qspi_prepare_for_sleep(void); +void qspi_wake_up_ind(void); +static uint16_t qspi_gpio_config(app_qspi_pin_cfg_t pin_cfg); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +void app_qspi_force_cs(app_qspi_id_t screen_id, bool low_level); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +extern volatile bool is_dma_access; +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +const qspi_memorymapped_t g_flash_typical_mmap_read_cmd[FLASH_MMAP_CMD_READ_MAX] = +{ + /************************************************************** + * FOLLOWING DEFINES ARE TYPICAL FLASH CMDs, + * SUPPORTED BY MANY FLASH DEVICES, + * IF DEFINES ARE NOT MATCHING WITH THE USED FLASH, + * PLEASE MODIFY CAREFULLY + **************************************************************/ + [FLASH_MMAP_CMD_DREAD_3BH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPI, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x00, + .x_dummy_cycles = 8, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_DUAL_SPI, + .x_instruction = 0x3B, + }, + [FLASH_MMAP_CMD_2READ_BBH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_IN_SPI_ADDR_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x00, + .x_dummy_cycles = 4, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_DUAL_SPI, + .x_instruction = 0xBB, + }, + [FLASH_MMAP_CMD_2READ_BBH_SIOO] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_IN_SPI_ADDR_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_ENABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x20, + .x_dummy_cycles = 0, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_ONLY_FIRST_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_DUAL_SPI, + .x_instruction = 0xBB, + }, + [FLASH_MMAP_CMD_QREAD_6BH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPI, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x20, + .x_dummy_cycles = 8, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + .x_instruction = 0x6B, + }, + [FLASH_MMAP_CMD_4READ_EBH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_IN_SPI_ADDR_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x00, + .x_dummy_cycles = 6, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + .x_instruction = 0xEB, + }, + [FLASH_MMAP_CMD_4READ_EBH_SIOO] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_IN_SPI_ADDR_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_ENABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x20, + .x_dummy_cycles = 4, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_ONLY_FIRST_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + .x_instruction = 0xEB, + } +}; + +const qspi_memorymapped_t g_psram_typical_mmap_qread_cmd[PSRAM_MMAP_CMD_READ_MAX] = +{ + /************************************************************** + * IF DEFINES ARE NOT MATCHING WITH THE USED PSRAM, + * PLEASE MODIFY CAREFULLY + **************************************************************/ + [PSRAM_MMAP_CMD_QREAD_0BH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x00, + .x_dummy_cycles = 4, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + .x_instruction = 0x0B, + }, + [PSRAM_MMAP_CMD_QREAD_EBH] = { + .x_endian_mode = QSPI_CONCURRENT_XIP_ENDIAN_MODE_0, + .x_prefetch_en = QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + .x_continous_xfer_en = QSPI_CONCURRENT_XIP_CONT_XFER_DISABLE, + .x_instruction_en = QSPI_CONCURRENT_XIP_INST_ENABLE, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPIFRF, + .x_mode_bits_en = QSPI_CONCURRENT_XIP_MODE_BITS_DISABLE, + .x_mode_bits_length = QSPI_CONCURRENT_XIP_MBL_8, + .x_mode_bits_data = 0x00, + .x_dummy_cycles = 6, + .x_continous_xfer_toc = 0, + .x_sioo_mode = QSPI_CONCURRENT_XIP_INST_SENT_EVERY_ACCESS, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + .x_instruction = 0xEB, + }, +}; + +const qspi_memorymapped_write_t g_psram_typical_mmap_qwrite_cmd[PSRAM_MMAP_CMD_WRITE_MAX] = +{ + /************************************************************** + * IF DEFINES ARE NOT MATCHING WITH THE USED PSRAM, + * PLEASE MODIFY CAREFULLY + **************************************************************/ + [PSRAM_MMAP_CMD_QWRITE_02H] = { + .x_instruction = 0x02, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPIFRF, + .x_dummy_cycles = 0, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + }, + [PSRAM_MMAP_CMD_QWRITE_38H] = { + .x_instruction = 0x38, + .x_instruction_size = QSPI_CONCURRENT_XIP_INSTSIZE_8BIT, + .x_address_size = QSPI_CONCURRENT_XIP_ADDRSIZE_24BIT, + .x_inst_addr_transfer_format = QSPI_CONCURRENT_XIP_INST_ADDR_ALL_IN_SPIFRF, + .x_dummy_cycles = 0, + .x_data_frame_format = QSPI_CONCURRENT_XIP_FRF_QUAD_SPI, + } +}; + +#define APP_QSPI_PIN_CONFIG(pin_type, pin_mux, pin_number, pin_mode, pin_pull, pin_enable) \ + { \ + .type = pin_type, \ + .mux = pin_mux, \ + .pin = pin_number, \ + .mode = pin_mode, \ + .pull = pin_pull, \ + .enable = pin_enable, \ + } +#define APP_QSPI_IO_PULL_DEFAULT APP_IO_NOPULL +const app_qspi_pin_cfg_t g_qspi_pin_groups[QSPIx_PIN_GROUP_MAX] = { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + /* DON'T MODIFY THE FOLLOWING CONFIGS FOR GR5526 */ + [QSPI0_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_10, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_5, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_6, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_7, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_8, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_9, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + }, + [QSPI1_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_10, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_15, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_14, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_13, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_12, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_11, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + }, + [QSPI2_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_11, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_0, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_1, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_2, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_3, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_4, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + } +#else + /* CAN MODIFY THE FOLLOWING CONFIGS FOR GR5525 */ + [QSPI0_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_15, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_2, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_0, APP_IO_PIN_3, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_14, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_13, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_0, APP_IO_PIN_12, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + }, + [QSPI1_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_7, APP_IO_PIN_5, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_7, APP_IO_PIN_6, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_7, APP_IO_PIN_4, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOB, APP_IO_MUX_7, APP_IO_PIN_7, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOC, APP_IO_MUX_7, APP_IO_PIN_0, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOC, APP_IO_MUX_7, APP_IO_PIN_1, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + }, + [QSPI2_PIN_GROUP_0] = { + .cs = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_6, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .clk = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_3, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_0 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_4, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_1 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_5, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_2 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_2, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + .io_3 = APP_QSPI_PIN_CONFIG(APP_IO_TYPE_GPIOA, APP_IO_MUX_7, APP_IO_PIN_7, APP_IO_MODE_MUX, APP_QSPI_IO_PULL_DEFAULT, APP_QSPI_PIN_ENABLE), + } +#endif +}; +#endif + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +static const IRQn_Type s_qspi_irq[APP_QSPI_ID_MAX] = { QSPI0_IRQn, QSPI1_IRQn, QSPI2_IRQn }; +const uint32_t s_qspi_instance[APP_QSPI_ID_MAX] = { QSPI0_BASE, QSPI1_BASE, QSPI2_BASE }; +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +static const IRQn_Type s_qspi_irq[APP_QSPI_ID_MAX] = { QSPI0_IRQn, QSPI1_IRQn }; +static const uint32_t s_qspi_instance[APP_QSPI_ID_MAX] = { QSPI0_BASE, QSPI1_BASE }; +#endif + +qspi_env_t *p_qspi_env[APP_QSPI_ID_MAX]; + +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_qspi_pwr_id = -1; + +static const app_sleep_callbacks_t qspi_sleep_cb = +{ + .app_prepare_for_sleep = qspi_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = qspi_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +bool qspi_prepare_for_sleep(void) +{ + hal_qspi_state_t state; + uint8_t i; + + for (i = 0; i < APP_QSPI_ID_MAX; i++) + { + if (p_qspi_env[i] == NULL) + { + continue; + } + + if (p_qspi_env[i]->qspi_state == APP_QSPI_ACTIVITY) + { + state = hal_qspi_get_state(&p_qspi_env[i]->handle); + if ((state != HAL_QSPI_STATE_RESET) && (state != HAL_QSPI_STATE_READY)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_qspi_suspend_reg(&p_qspi_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_qspi_env[i]->qspi_state = APP_QSPI_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE void qspi_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_QSPI_ID_MAX; i++) + { + if (p_qspi_env[i] == NULL) + { + continue; + } + + if (p_qspi_env[i]->qspi_state == APP_QSPI_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_qspi_resume_reg(&p_qspi_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_qspi_irq[i]); + hal_nvic_enable_irq(s_qspi_irq[i]); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void qspi_wake_up(app_qspi_id_t id) +{ + if (p_qspi_env[id]->qspi_state == APP_QSPI_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_qspi_resume_reg(&p_qspi_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_qspi_irq[id]); + hal_nvic_enable_irq(s_qspi_irq[id]); + p_qspi_env[id]->qspi_state = APP_QSPI_ACTIVITY; + } + + if(p_qspi_env[id]->use_mode.type == APP_QSPI_TYPE_DMA) + { + dma_wake_up(p_qspi_env[id]->dma_id); + } +} +#endif + + +#define QSPI_HANDLER(index, val) \ +SECTION_RAM_CODE void QSPI##index##_IRQHandler(void)\ +{\ + hal_qspi_irq_handler(&p_qspi_env[val]->handle);\ +} + +QSPI_HANDLER(0, APP_QSPI_ID_0) +QSPI_HANDLER(1, APP_QSPI_ID_1) +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +QSPI_HANDLER(2, APP_QSPI_ID_2) +#endif +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_qspi_init(app_qspi_params_t *p_params, app_qspi_evt_handler_t evt_handler) +{ + app_qspi_id_t id = p_params->id; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + p_qspi_env[id] = &p_params->qspi_env; + soc_register_nvic(QSPI0_IRQn, (uint32_t)QSPI0_IRQHandler); + soc_register_nvic(QSPI1_IRQn, (uint32_t)QSPI1_IRQHandler); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + soc_register_nvic(QSPI2_IRQn, (uint32_t)QSPI2_IRQHandler); +#endif + + app_err_code = qspi_gpio_config(p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(app_err_code); + + hal_nvic_clear_pending_irq(s_qspi_irq[id]); + hal_nvic_enable_irq(s_qspi_irq[id]); + + p_qspi_env[id]->p_pin_cfg = &p_params->pin_cfg; + p_qspi_env[id]->evt_handler = evt_handler; + + memcpy(&p_qspi_env[id]->handle.init, &p_params->init, sizeof(qspi_init_t)); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_qspi_env[id]->handle.p_instance = (ssi_regs_t *)s_qspi_instance[id]; +#else + p_qspi_env[id]->handle.p_instance = (qspi_regs_t *)s_qspi_instance[id]; +#endif + hal_err_code = hal_qspi_deinit(&p_qspi_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_qspi_init(&p_qspi_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + + p_qspi_env[id]->is_xfer_err = false; + p_qspi_env[id]->is_tx_done = false; + p_qspi_env[id]->is_rx_done = false; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + p_qspi_env[id]->is_mmap_inited = false; + p_qspi_env[id]->is_mmap_prefetch_en = false; +#endif + if(!s_sleep_cb_registered_flag)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_qspi_pwr_id = pwr_register_sleep_cb(&qspi_sleep_cb, APP_DRIVER_QSPI_WAPEUP_PRIORITY); + if (s_qspi_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_qspi_env[id]->qspi_state = APP_QSPI_ACTIVITY; + p_qspi_env[id]->start_flag = false; + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_deinit(app_qspi_id_t id) +{ + uint8_t i; + app_drv_err_t app_err_code; + hal_status_t hal_err_code; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_qspi_env[id]->p_pin_cfg->cs.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->cs.type, p_qspi_env[id]->p_pin_cfg->cs.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + if (p_qspi_env[id]->p_pin_cfg->clk.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->clk.type, p_qspi_env[id]->p_pin_cfg->clk.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + if (p_qspi_env[id]->p_pin_cfg->io_0.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->io_0.type, p_qspi_env[id]->p_pin_cfg->io_0.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + if (p_qspi_env[id]->p_pin_cfg->io_1.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->io_1.type, p_qspi_env[id]->p_pin_cfg->io_1.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + if (p_qspi_env[id]->p_pin_cfg->io_2.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->io_2.type, p_qspi_env[id]->p_pin_cfg->io_2.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + if (p_qspi_env[id]->p_pin_cfg->io_3.enable == APP_QSPI_PIN_ENABLE) + { + app_err_code = app_io_deinit(p_qspi_env[id]->p_pin_cfg->io_3.type, p_qspi_env[id]->p_pin_cfg->io_3.pin); + APP_DRV_ERR_CODE_CHECK(app_err_code); + } + + hal_nvic_disable_irq(s_qspi_irq[id]); + p_qspi_env[id]->qspi_state = APP_QSPI_INVALID; + p_qspi_env[id]->start_flag = false; + p_qspi_env[id]->is_xfer_err = false; + p_qspi_env[id]->is_tx_done = false; + p_qspi_env[id]->is_rx_done = false; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + p_qspi_env[id]->is_mmap_inited = false; + p_qspi_env[id]->is_mmap_prefetch_en = false; +#endif + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_QSPI_ID_MAX; i++) + { + if (p_qspi_env[i] != NULL && (p_qspi_env[i]->qspi_state) != APP_QSPI_INVALID) + { + break; + } + } + if (APP_QSPI_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_qspi_pwr_id); + s_qspi_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_qspi_deinit(&p_qspi_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + if (p_qspi_env[id]->qspi_dma_state == APP_QSPI_DMA_INVALID) + { + p_qspi_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_abort(app_qspi_id_t id) +{ + uint16_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (!p_qspi_env[id]->start_flag) + { + return APP_DRV_SUCCESS; + } + + err_code = hal_qspi_abort_it(&p_qspi_env[id]->handle); + if (err_code != HAL_OK) + { + return err_code; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +bool app_qspi_active_memory_mappped(app_qspi_id_t id, bool is_active) { + hal_status_t status = HAL_OK; + APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + + if(p_qspi_env[id]->start_flag) { + if(APP_QSPI_EXCEPT_DEBUG_EN) printf("+++ ERR : CAN NOT change(%d), Busy... \r\n", id); + return false; + } + if(is_active) { + if((p_qspi_env[id]->mounted_mmap_device.dev_type == APP_QSPI_DEVICE_FLASH) && + (g_flash_typical_mmap_read_cmd[p_qspi_env[id]->mounted_mmap_device.rd.flash_rd].x_sioo_mode == QSPI_CONCURRENT_XIP_INST_SENT_ONLY_FIRST_ACCESS)) { + status = hal_qspi_memorymapped_active(&p_qspi_env[id]->handle, true); + } else { + status = hal_qspi_memorymapped_active(&p_qspi_env[id]->handle, false); + } + } else { + status = hal_qspi_memorymapped_deactive(&p_qspi_env[id]->handle); + } + + return (status == HAL_OK) ? true : false; +} + +bool app_qspi_config_memory_mappped(app_qspi_id_t id, app_qspi_mmap_device_t dev) { + bool rRet = false; + hal_status_t status ; + const qspi_memorymapped_t * mmap_rd_cmd = NULL; + const qspi_memorymapped_write_t * mmap_wr_cmd = NULL; + + if ((id >= APP_QSPI_ID_MAX) || (p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return false; + } + + switch(dev.dev_type) { + case APP_QSPI_DEVICE_FLASH: + { + if(dev.rd.flash_rd < FLASH_MMAP_CMD_READ_MAX) { + mmap_rd_cmd = &g_flash_typical_mmap_read_cmd[dev.rd.flash_rd]; + } + } + break; + + case APP_QSPI_DEVICE_PSRAM: + { + if(dev.rd.psram_rd < PSRAM_MMAP_CMD_READ_MAX) { + mmap_rd_cmd = &g_psram_typical_mmap_qread_cmd[dev.rd.psram_rd]; + } + + if(dev.psram_wr < PSRAM_MMAP_CMD_WRITE_MAX) { + mmap_wr_cmd = &g_psram_typical_mmap_qwrite_cmd[dev.psram_wr]; + } + } + break; + + case APP_QSPI_DEVICE_UNSET: + default: + {} + break; + } + + if((mmap_rd_cmd != NULL) || (mmap_wr_cmd != NULL)) { + status = hal_qspi_memorymapped(&p_qspi_env[id]->handle, (qspi_memorymapped_t *)mmap_rd_cmd, (qspi_memorymapped_write_t *)mmap_wr_cmd); + if(HAL_OK == status) { + if(dev.dev_type == APP_QSPI_DEVICE_PSRAM) { + ll_qspi_enable_xip_dynamic_le(p_qspi_env[id]->handle.p_instance); /* active dynamicle mode for psram */ + } + rRet = true; + } + } + + if(rRet) { + memcpy(&p_qspi_env[id]->mounted_mmap_device, &dev, sizeof(app_qspi_mmap_device_t)); + p_qspi_env[id]->is_mmap_inited = true; + p_qspi_env[id]->mmap_endian_mode = (app_qspi_mmap_endian_mode_e) mmap_rd_cmd->x_endian_mode; + } + + return rRet; +} +#endif + +uint16_t app_qspi_command_receive_sync(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_receive(&p_qspi_env[id]->handle, p_cmd, p_data, timeout); + QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_command_receive_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_receive_it(&p_qspi_env[id]->handle, p_cmd, p_data); + if (HAL_OK != err_code) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_command_transmit_sync(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_transmit(&p_qspi_env[id]->handle, p_cmd, p_data, timeout); + QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_command_transmit_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_transmit_it(&p_qspi_env[id]->handle, p_cmd, p_data); + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + + +uint16_t app_qspi_command_sync(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command(&p_qspi_env[id]->handle, p_cmd, timeout); + QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_command_async(app_qspi_id_t id, app_qspi_command_t *p_cmd) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_it(&p_qspi_env[id]->handle, p_cmd); + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_transmit_sync(app_qspi_id_t id, uint8_t *p_data, uint32_t length, uint32_t timeout) +{ + return app_qspi_transmit_sync_ex(id, 0, 0, p_data, length, timeout); +} +#endif + +uint16_t app_qspi_transmit_sync_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length, uint32_t timeout) +{ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode);//mode and data_width were fixed when init + UNUSED(data_width); +#endif + hal_status_t err_code; + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_transmit(&p_qspi_env[id]->handle, p_data, length, timeout); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + err_code = hal_qspi_transmit(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length, timeout); +#endif + + QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return err_code; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_transmit_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length) +{ + return app_qspi_transmit_async_ex(id, 0, 0, p_data, length); +} +#endif + +uint16_t app_qspi_transmit_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode);//mode and data_width were fixed when init + UNUSED(data_width); +#endif + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_transmit_it(&p_qspi_env[id]->handle, p_data, length); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + err_code = hal_qspi_transmit_it(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length); +#endif + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_receive_sync(app_qspi_id_t id, uint8_t *p_data, uint32_t length, uint32_t timeout) +{ + return app_qspi_receive_sync_ex( id, 0, 0, p_data, length, timeout); +} +#endif + +uint16_t app_qspi_receive_sync_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length, uint32_t timeout) +{ + hal_status_t err_code; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode); + UNUSED(data_width); +#endif + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_receive(&p_qspi_env[id]->handle, p_data, length, timeout); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + err_code = hal_qspi_receive(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length, timeout); +#endif + QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_receive_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length) +{ + return app_qspi_receive_async_ex(id, 0, 0, p_data, length); +} +#endif + +uint16_t app_qspi_receive_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode); + UNUSED(data_width); +#endif + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_receive_it(&p_qspi_env[id]->handle, p_data, length); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + err_code = hal_qspi_receive_it(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length); +#endif + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +bool app_qspi_mmap_set_endian_mode(app_qspi_id_t id, app_qspi_mmap_endian_mode_e mode) { + hal_status_t status = HAL_ERROR; + + APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + + if(p_qspi_env[id]->mmap_endian_mode == mode) { + return true; + } + + qspi_memorymapped_set_t mmap_set = { + .mmap_key = QSPI_MMAPED_IDX_EDIAN_MODE, + .mmap_val = (mode == APP_QSPI_MMAP_ENDIAN_MODE_0) ? QSPI_CONCURRENT_XIP_ENDIAN_MODE_0 : ((mode == APP_QSPI_MMAP_ENDIAN_MODE_1) ? QSPI_CONCURRENT_XIP_ENDIAN_MODE_1 : QSPI_CONCURRENT_XIP_ENDIAN_MODE_2), + }; + + status = hal_qspi_memorymapped_update(&p_qspi_env[id]->handle, &mmap_set, 1); + + if(HAL_OK == status) { + p_qspi_env[id]->mmap_endian_mode = mode; + return true; + } + + return false; +} + +bool app_qspi_mmap_set_prefetch(app_qspi_id_t id, bool prefetch_en) { + hal_status_t status = HAL_ERROR; + + APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + + if(p_qspi_env[id]->is_mmap_prefetch_en == prefetch_en) { + return true; + } + + qspi_memorymapped_set_t mmap_set = { + .mmap_key = QSPI_MMAPED_IDX_PREFETCH_EN, + .mmap_val = prefetch_en ? QSPI_CONCURRENT_XIP_PREFETCH_ENABLE : QSPI_CONCURRENT_XIP_PREFETCH_DISABLE, + }; + + status = hal_qspi_memorymapped_update(&p_qspi_env[id]->handle, &mmap_set, 1); + + if(HAL_OK == status) { + p_qspi_env[id]->is_mmap_prefetch_en = prefetch_en; + return true; + } + + return false; +} + +uint8_t app_qspi_mmap_read_u8(app_qspi_id_t id, uint32_t address) { + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + //APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + app_qspi_mmap_set_endian_mode(id, APP_QSPI_MMAP_ENDIAN_MODE_0); + return *((volatile uint8_t *)(ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]) + address)); +} + +uint16_t app_qspi_mmap_read_u16(app_qspi_id_t id, uint32_t address) { + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + //APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + APP_ASSERT_CHECK(!(address & 0x01)); /* U16 aligned */ + app_qspi_mmap_set_endian_mode(id, APP_QSPI_MMAP_ENDIAN_MODE_1); + return *((volatile uint16_t *)(ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]) + address)); +} + +uint32_t app_qspi_mmap_read_u32(app_qspi_id_t id, uint32_t address) { + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + //APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + APP_ASSERT_CHECK(!(address & 0x03)); /* U32 aligned */ + app_qspi_mmap_set_endian_mode(id, APP_QSPI_MMAP_ENDIAN_MODE_2); + return *((volatile uint32_t *)(ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]) + address)); +} + +bool app_qspi_mmap_read_block(app_qspi_id_t id, uint32_t address, uint8_t * buffer, uint32_t length) { + bool ret = true; + + if ((id >= APP_QSPI_ID_MAX) || (p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return false; + } + //APP_ASSERT_CHECK(p_qspi_env[id]->is_mmap_inited); + + app_qspi_mmap_set_endian_mode(id, APP_QSPI_MMAP_ENDIAN_MODE_2); + app_qspi_mmap_set_prefetch(id, false); + memcpy(buffer, (void *)(ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]) + address), length); + return ret; +} + +uint32_t app_qspi_get_xip_base_address(app_qspi_id_t id) { + return ll_qspi_get_xip_base_address((qspi_regs_t*)s_qspi_instance[id]); +} + +#endif +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint16_t qspi_gpio_config(app_qspi_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (pin_cfg.cs.enable == APP_QSPI_PIN_ENABLE) + { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + io_init.pull = pin_cfg.cs.pull; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = pin_cfg.cs.mux; + io_init.mode = pin_cfg.cs.mode; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + io_init.pull = pin_cfg.cs.pull; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = APP_IO_MUX_7; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + app_io_write_pin(pin_cfg.cs.type, pin_cfg.cs.pin, APP_IO_PIN_SET); +#endif + } + if (pin_cfg.clk.enable == APP_QSPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.clk.pull; + io_init.pin = pin_cfg.clk.pin; + io_init.mux = pin_cfg.clk.mux; + io_init.mode = pin_cfg.clk.mode; + err_code = app_io_init(pin_cfg.clk.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.io_0.enable == APP_QSPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.io_0.pull; + io_init.pin = pin_cfg.io_0.pin; + io_init.mux = pin_cfg.io_0.mux; + io_init.mode = pin_cfg.io_0.mode; + err_code = app_io_init(pin_cfg.io_0.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.io_1.enable == APP_QSPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.io_1.pull; + io_init.pin = pin_cfg.io_1.pin; + io_init.mux = pin_cfg.io_1.mux; + io_init.mode = pin_cfg.io_1.mode; + err_code = app_io_init(pin_cfg.io_1.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.io_2.enable == APP_QSPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.io_2.pull; + io_init.pin = pin_cfg.io_2.pin; + io_init.mux = pin_cfg.io_2.mux; + io_init.mode = pin_cfg.io_2.mode; + err_code = app_io_init(pin_cfg.io_2.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.io_3.enable == APP_QSPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.io_3.pull; + io_init.pin = pin_cfg.io_3.pin; + io_init.mux = pin_cfg.io_3.mux; + io_init.mode = pin_cfg.io_3.mode; + err_code = app_io_init(pin_cfg.io_3.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +void app_qspi_force_cs(app_qspi_id_t screen_id, bool low_level) { + + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + + io_init.pull = p_qspi_env[screen_id]->p_pin_cfg->cs.pull; + io_init.pin = p_qspi_env[screen_id]->p_pin_cfg->cs.pin; + + if(low_level) { +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5525X) + io_init.mux = APP_IO_MUX_7; +#else + io_init.mux = APP_IO_MUX_8; +#endif + io_init.mode = APP_IO_MODE_OUTPUT; + app_io_init(p_qspi_env[screen_id]->p_pin_cfg->cs.type, &io_init); + app_io_write_pin(p_qspi_env[screen_id]->p_pin_cfg->cs.type, io_init.pin, APP_IO_PIN_SET); + delay_us(1); + app_io_write_pin(p_qspi_env[screen_id]->p_pin_cfg->cs.type, io_init.pin, APP_IO_PIN_RESET); + } else { + /* first : release cs */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5525X) + io_init.mux = APP_IO_MUX_7; +#else + io_init.mux = APP_IO_MUX_8; +#endif + io_init.mode = APP_IO_MODE_OUTPUT; + app_io_init(p_qspi_env[screen_id]->p_pin_cfg->cs.type, &io_init); + app_io_write_pin(p_qspi_env[screen_id]->p_pin_cfg->cs.type, io_init.pin, APP_IO_PIN_SET); + + /* then : restore hard-cs */ + io_init.mux = p_qspi_env[screen_id]->p_pin_cfg->cs.mux; + io_init.mode = p_qspi_env[screen_id]->p_pin_cfg->cs.mode; + app_io_init(p_qspi_env[screen_id]->p_pin_cfg->cs.type, &io_init); + } + + return; +} +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) + extern bool app_graphics_qspi_draw_screen_continue(app_qspi_id_t id, app_qspi_evt_t qspi_evt); +#endif +#endif + +static void app_qspi_event_call(qspi_handle_t *p_qspi, app_qspi_evt_type_t evt_type) +{ + app_qspi_evt_t qspi_evt; + app_qspi_id_t id = APP_QSPI_ID_MAX; + + if (p_qspi->p_instance == QSPI0) + { + id = APP_QSPI_ID_0; + } + else if (p_qspi->p_instance == QSPI1) + { + id = APP_QSPI_ID_1; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (p_qspi->p_instance == QSPI2) + { + id = APP_QSPI_ID_2; + } +#endif + qspi_evt.type = evt_type; + if (evt_type == APP_QSPI_EVT_ERROR) + { + qspi_evt.data.error_code = p_qspi->error_code; + p_qspi_env[id]->is_xfer_err = 1; + p_qspi_env[id]->is_rx_done = 1; + p_qspi_env[id]->is_tx_done = 1; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (is_dma_access) + { + ((qspi_regs_t *)s_qspi_instance[id])->DMAC = 0; + ll_dma_disable_channel(p_qspi_env[id]->dma_cfg.dma_instance, p_qspi_env[id]->dma_cfg.dma_channel); + } +#endif + if(APP_QSPI_EXCEPT_DEBUG_EN) printf("+++ ERR: QSPI%d xfer Err ...\r\n", id); + } + else if (evt_type == APP_QSPI_EVT_TX_CPLT) + { + qspi_evt.data.size = p_qspi->tx_xfer_size - p_qspi->tx_xfer_count; + p_qspi_env[id]->is_xfer_err = 0; + p_qspi_env[id]->is_tx_done = 1; + } + else if (evt_type == APP_QSPI_EVT_RX_DATA) + { + qspi_evt.data.size = p_qspi->rx_xfer_size - p_qspi->rx_xfer_count; + p_qspi_env[id]->is_xfer_err = 0; + p_qspi_env[id]->is_rx_done = 1; + } + else if (evt_type == APP_QSPI_EVT_ABORT) + { + p_qspi_env[id]->is_xfer_err = 1; + p_qspi_env[id]->is_rx_done = 1; + p_qspi_env[id]->is_tx_done = 1; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +#if (QSPI_DMA_LLP_FEATUTE_SUPPORT > 0u) + bool ret = app_graphics_qspi_draw_screen_continue(id, qspi_evt); + if(ret)return; +#endif +#endif + + p_qspi_env[id]->start_flag = false; + QSPI_SMART_CS_HIGH(id); + if (p_qspi_env[id]->evt_handler != NULL) + { + p_qspi_env[id]->evt_handler(&qspi_evt); + } +} + +qspi_handle_t *app_qspi_get_handle(app_qspi_id_t id) +{ + if (id >= APP_QSPI_ID_MAX) + { + return NULL; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + return &p_qspi_env[id]->handle; +} + +void hal_qspi_error_callback(qspi_handle_t *p_qspi) +{ + app_qspi_event_call(p_qspi, APP_QSPI_EVT_ERROR); +} + +void hal_qspi_rx_cplt_callback(qspi_handle_t *p_qspi) +{ + app_qspi_event_call(p_qspi, APP_QSPI_EVT_RX_DATA); +} + +void hal_qspi_tx_cplt_callback(qspi_handle_t *p_qspi) +{ + app_qspi_event_call(p_qspi, APP_QSPI_EVT_TX_CPLT); +} + +void hal_qspi_abort_cplt_callback(qspi_handle_t *p_qspi) +{ + app_qspi_event_call(p_qspi, APP_QSPI_EVT_ABORT); +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi_dma.c new file mode 100644 index 0000000..3539f15 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_qspi_dma.c @@ -0,0 +1,598 @@ +/** + **************************************************************************************** + * @file app_qspi_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_assert.h" +#include "app_qspi.h" +#include "app_qspi_dma.h" +#include "app_io.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include +#include "platform_sdk.h" +#include "app_drv.h" +#include "gr_soc.h" + +#ifdef HAL_QSPI_MODULE_ENABLED +/* + * DEFINES + ***************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define QSPI_SMART_CS_LOW(id) \ + do { \ + if(p_qspi_env[id]->p_pin_cfg->cs.enable == APP_QSPI_PIN_ENABLE) \ + { \ + app_io_write_pin(p_qspi_env[id]->p_pin_cfg->cs.type, \ + p_qspi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_RESET); \ + } \ + } while(0) + +#define QSPI_SMART_CS_HIGH(id) \ + do { \ + if(p_qspi_env[id]->p_pin_cfg->cs.enable == APP_QSPI_PIN_ENABLE) \ + { \ + app_io_write_pin(p_qspi_env[id]->p_pin_cfg->cs.type, \ + p_qspi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_SET); \ + } \ + } while(0) +#else +#define QSPI_SMART_CS_LOW(id) +#define QSPI_SMART_CS_HIGH(id) +#endif + +#define APP_QSPI_EXCEPT_DEBUG_EN 1u +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +/******************************************************************** + * QUAD_WRITE_32b_PATCH : just exist in QUAD/DATASIZE_32BITS/DMA scene + * if enable, MUST Control the CS By Software. + */ +#define QSPI_QUAD_WRITE_32b_PATCH_EN 0u + +/******************************************************************** + * DATA Endian Mode Optional Value : + * 0 : data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) + * 1 : data[1] | (data[0] << 8) | (data[3] << 16) | (data[2] << 24) + * 2 : data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24) + * 3 : data[2] | (data[3] << 8) | (data[0] << 16) | (data[1] << 24) + */ +#define QSPI_QUAD_WRITE_DATA_ENDIAN_MODE 0u +#endif +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +extern void qspi_wake_up(app_qspi_id_t id); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +volatile bool is_dma_access = false; +static bool app_qspi_dma_match_check(app_qspi_params_t * p_params); +static bool app_qspi_switch_dma_mode(app_qspi_id_t id, bool is_m2m_mode); +#endif +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern qspi_env_t *p_qspi_env[APP_QSPI_ID_MAX]; + +static uint16_t app_qspi_config_dma(app_qspi_params_t *p_params) +{ + app_dma_params_t dma_params = { 0 }; + + dma_params.p_instance = p_params->dma_cfg.dma_instance; + dma_params.channel_number = p_params->dma_cfg.dma_channel; + dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + dma_params.init.mode = DMA_NORMAL; + dma_params.init.priority = DMA_PRIORITY_LOW; + + p_qspi_env[p_params->id]->dma_id = app_dma_init(&dma_params, NULL); + if (p_qspi_env[p_params->id]->dma_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + p_qspi_env[p_params->id]->handle.p_dma = app_dma_get_handle(p_qspi_env[p_params->id]->dma_id); + p_qspi_env[p_params->id]->handle.p_dma->p_parent = (void*)&p_qspi_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +static void app_qspi_config_dma_qwrite_32b_patch(app_qspi_id_t id, bool enable_patch, uint32_t endian_mode) { + extern void hal_qspi_config_dma_qwrite_32b_patch(qspi_handle_t *p_qspi, bool enable_patch, uint32_t endian_mode) ; + hal_qspi_config_dma_qwrite_32b_patch(&p_qspi_env[id]->handle, enable_patch, endian_mode); +} +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_qspi_dma_init(app_qspi_params_t *p_params) +{ + app_qspi_id_t id = p_params->id; + app_drv_err_t app_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + GLOBAL_EXCEPTION_DISABLE(); + p_qspi_env[p_params->id]->dma_id = -1; + app_err_code = app_qspi_config_dma(p_params); + GLOBAL_EXCEPTION_ENABLE(); + APP_DRV_ERR_CODE_CHECK(app_err_code); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + app_err_code = app_qspi_dma_match_check(p_params) ? APP_DRV_SUCCESS : APP_DRV_ERR_INVALID_PARAM; + APP_DRV_ERR_CODE_CHECK(app_err_code); + GLOBAL_EXCEPTION_DISABLE(); + p_qspi_env[p_params->id]->dma_id = -1; + app_err_code = app_qspi_config_dma(p_params); + GLOBAL_EXCEPTION_ENABLE(); + APP_DRV_ERR_CODE_CHECK(app_err_code); + p_qspi_env[id]->is_used_dma = true; + p_qspi_env[id]->is_dma_mode_m2m = false; +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + p_qspi_env[id]->dma_cfg.wait_timeout_ms = p_params->dma_cfg.wait_timeout_ms; + p_qspi_env[id]->dma_cfg.dma_instance = p_params->dma_cfg.dma_instance; + p_qspi_env[id]->dma_cfg.dma_channel = p_params->dma_cfg.dma_channel; + p_qspi_env[id]->qspi_dma_state = APP_QSPI_DMA_ACTIVITY; +#endif + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_dma_deinit(app_qspi_id_t id) +{ + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_dma_state != APP_QSPI_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_qspi_env[id]->dma_id); + + GLOBAL_EXCEPTION_DISABLE(); + p_qspi_env[id]->qspi_dma_state = APP_QSPI_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + if (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID) + { + p_qspi_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_dma_command_receive_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + is_dma_access = true; + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_switch_dma_mode(id, false); +#endif + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_command_receive_dma(&p_qspi_env[id]->handle, p_cmd, p_data); + if (HAL_OK != err_code) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_dma_command_transmit_async(app_qspi_id_t id, app_qspi_command_t *p_cmd, uint8_t *p_data) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL || p_data == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_switch_dma_mode(id, false); + err_code = hal_qspi_command_transmit_dma(&p_qspi_env[id]->handle, p_cmd, p_data); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + app_qspi_config_dma_qwrite_32b_patch(id, QSPI_QUAD_WRITE_32b_PATCH_EN, QSPI_QUAD_WRITE_DATA_ENDIAN_MODE); + err_code = hal_qspi_command_transmit_dma(&p_qspi_env[id]->handle, p_cmd, p_data); + app_qspi_config_dma_qwrite_32b_patch(id, 0, QSPI_QUAD_WRITE_DATA_ENDIAN_MODE); +#endif + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_qspi_dma_command_async(app_qspi_id_t id, app_qspi_command_t *p_cmd) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_switch_dma_mode(id, false); +#endif + err_code = hal_qspi_command_dma(&p_qspi_env[id]->handle, p_cmd); + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +extern hal_status_t hal_qspi_transmit_dma_in_qpi(qspi_handle_t *p_qspi, uint32_t data_size, uint8_t *p_data, uint32_t length); + +uint16_t app_qspi_dma_transmit_in_qpi_async(app_qspi_id_t id, uint32_t data_width, uint8_t *p_data, uint32_t length) +{ + hal_status_t err_code; + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + QSPI_SMART_CS_LOW(id); + err_code = hal_qspi_transmit_dma_in_qpi(&p_qspi_env[id]->handle, data_width, p_data, length); + //QSPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + return err_code; + } + + return APP_DRV_SUCCESS; +} +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_dma_transmit_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length) +{ + return app_qspi_dma_transmit_async_ex(id, QSPI_DATA_MODE_SPI, QSPI_DATASIZE_08_BITS, p_data, length); +} +#endif + +uint16_t app_qspi_dma_transmit_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode); + UNUSED(data_width); +#endif + + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_transmit_dma(&p_qspi_env[id]->handle, p_data, length); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_switch_dma_mode(id, false); + err_code = hal_qspi_transmit_dma(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length); +#endif + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_qspi_dma_receive_async(app_qspi_id_t id, uint8_t *p_data, uint32_t length) +{ + return app_qspi_dma_receive_async_ex(id, 0, 0, p_data, length); +} +#endif + +uint16_t app_qspi_dma_receive_async_ex(app_qspi_id_t id, uint32_t qspi_mode, uint32_t data_width, uint8_t *p_data, uint32_t length) +{ + hal_status_t err_code = HAL_ERROR; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + UNUSED(qspi_mode); + UNUSED(data_width); +#endif + if (id >= APP_QSPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_qspi_env[id] == NULL) || (p_qspi_env[id]->qspi_state == APP_QSPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || length == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + qspi_wake_up(id); +#endif + + if (p_qspi_env[id]->start_flag == false) + { + p_qspi_env[id]->start_flag = true; + QSPI_SMART_CS_LOW(id); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + err_code = hal_qspi_receive_dma(&p_qspi_env[id]->handle, p_data, length); +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + is_dma_access = true; + APP_ASSERT_CHECK(p_qspi_env[id]->is_used_dma); + app_qspi_switch_dma_mode(id, false); + err_code = hal_qspi_receive_dma(&p_qspi_env[id]->handle, qspi_mode, data_width, p_data, length); +#endif + if (err_code != HAL_OK) + { + QSPI_SMART_CS_HIGH(id); + p_qspi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ + +static bool app_qspi_dma_match_check(app_qspi_params_t * p_params) { + if(((p_params->id == APP_QSPI_ID_0) && (p_params->dma_cfg.dma_instance == DMA1)) || + ((p_params->id == APP_QSPI_ID_2) && (p_params->dma_cfg.dma_instance == DMA0)) + ) { + if(APP_QSPI_EXCEPT_DEBUG_EN) printf("+++ ERR: QSPI/DMA DOES NOT MATCH !\r\n"); + return false; + } + + if((p_params->dma_cfg.dma_channel != DMA_Channel0) && (p_params->dma_cfg.dma_channel != DMA_Channel1)) { + if(APP_QSPI_EXCEPT_DEBUG_EN) printf("+++ ERR: Please AGGIGN DMA CHANNEL0/1 TO QSPI !\r\n"); + return false; + } + + return true; +} + +static bool app_qspi_switch_dma_mode(app_qspi_id_t id, bool is_m2m_mode) { + app_dma_params_t dma_params = {0}; + + if(p_qspi_env[id]->is_dma_mode_m2m == is_m2m_mode) { + return true; + } else { + if(is_m2m_mode) { + dma_params.p_instance = p_qspi_env[id]->dma_cfg.dma_instance; + dma_params.channel_number = p_qspi_env[id]->dma_cfg.dma_channel; + dma_params.init.direction = DMA_MEMORY_TO_MEMORY; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_INCREMENT; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + dma_params.init.mode = DMA_NORMAL; + dma_params.init.priority = DMA_PRIORITY_LOW; + } else { + dma_params.p_instance = p_qspi_env[id]->dma_cfg.dma_instance; + dma_params.channel_number = p_qspi_env[id]->dma_cfg.dma_channel; + dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + dma_params.init.src_increment = DMA_SRC_INCREMENT; + dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + dma_params.init.mode = DMA_NORMAL; + dma_params.init.priority = DMA_PRIORITY_LOW; + } + + p_qspi_env[id]->dma_id = app_dma_init(&dma_params, NULL); + if (p_qspi_env[id]->dma_id < 0) + { + return false; + } + p_qspi_env[id]->handle.p_dma = app_dma_get_handle(p_qspi_env[id]->dma_id); + p_qspi_env[id]->handle.p_dma->p_parent = (void*)&p_qspi_env[id]->handle; + } + + p_qspi_env[id]->is_dma_mode_m2m = is_m2m_mode; + return true; +} + +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rng.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rng.c new file mode 100644 index 0000000..a6d288c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rng.c @@ -0,0 +1,294 @@ +/** + **************************************************************************************** + * @file app_rng.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_rng.h" +#include "app_pwr_mgmt.h" +#include "string.h" +#include "gr_soc.h" + +#ifdef HAL_RNG_MODULE_ENABLED + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool rng_prepare_for_sleep(void); +static void rng_wake_up_ind(void); +void RNG_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +rng_env_t *p_rng_env = NULL; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_rng_pwr_id; + +const static app_sleep_callbacks_t rng_sleep_cb = +{ + .app_prepare_for_sleep = rng_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = rng_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool rng_prepare_for_sleep(void) +{ + hal_rng_state_t state; + + if (p_rng_env->rng_state == APP_RNG_ACTIVITY) + { + state = hal_rng_get_state(&p_rng_env->handle); + if ((state != HAL_RNG_STATE_READY) && (state != HAL_RNG_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_rng_suspend_reg(&p_rng_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_rng_env->rng_state = APP_RNG_SLEEP; + #endif + } + + return true; +} + +SECTION_RAM_CODE static void rng_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + if (p_rng_env->rng_state == APP_RNG_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_rng_resume_reg(&p_rng_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + if (p_rng_env->use_type == APP_RNG_TYPE_INTERRUPT) + { + hal_nvic_clear_pending_irq(RNG_IRQn); + hal_nvic_enable_irq(RNG_IRQn); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +static void rng_wake_up(void) +{ + if (p_rng_env->rng_state == APP_RNG_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_rng_resume_reg(&p_rng_env->handle); + GLOBAL_EXCEPTION_ENABLE(); + if (p_rng_env->use_type == APP_RNG_TYPE_INTERRUPT) + { + hal_nvic_clear_pending_irq(RNG_IRQn); + hal_nvic_enable_irq(RNG_IRQn); + } + p_rng_env->rng_state = APP_RNG_ACTIVITY; + } +} +#endif + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_rng_init(app_rng_params_t *p_params, app_rng_evt_handler_t evt_handler) +{ + hal_status_t hal_err_code = HAL_OK; + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + p_rng_env = &p_params->rng_env; + if (p_params->use_type == APP_RNG_TYPE_INTERRUPT) + { + soc_register_nvic(RNG_IRQn, (uint32_t)RNG_IRQHandler); + hal_nvic_clear_pending_irq(RNG_IRQn); + hal_nvic_enable_irq(RNG_IRQn); + } + + p_rng_env->use_type = p_params->use_type; + p_rng_env->evt_handler = evt_handler; + + memcpy(&p_rng_env->handle.init, &p_params->init, sizeof(rng_init_t)); + p_rng_env->handle.p_instance = RNG; + hal_err_code = hal_rng_deinit(&p_rng_env->handle); + APP_DRV_ERR_CODE_CHECK(hal_err_code); + + hal_err_code = hal_rng_init(&p_rng_env->handle); + APP_DRV_ERR_CODE_CHECK(hal_err_code); + + if(s_sleep_cb_registered_flag == false) // register sleep callback + { + s_sleep_cb_registered_flag = true; + s_rng_pwr_id = pwr_register_sleep_cb(&rng_sleep_cb, APP_DRIVER_RNG_WAPEUP_PRIORITY); + if (s_rng_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_rng_env->rng_state = APP_RNG_ACTIVITY; + + return app_err_code; +} + +uint16_t app_rng_deinit(void) +{ + hal_status_t hal_err_code; + + if ((p_rng_env == NULL) || (p_rng_env->rng_state == APP_RNG_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + hal_nvic_disable_irq(RNG_IRQn); + p_rng_env->rng_state = APP_RNG_INVALID; + + GLOBAL_EXCEPTION_DISABLE(); + pwr_unregister_sleep_cb(s_rng_pwr_id); + s_rng_pwr_id = -1; + s_sleep_cb_registered_flag = false; + GLOBAL_EXCEPTION_ENABLE(); + + hal_err_code = hal_rng_deinit(&p_rng_env->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + p_rng_env = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_rng_gen_sync(uint16_t *p_seed, uint32_t *p_random32bit) +{ + hal_status_t err_code; + + if ((p_rng_env == NULL) || (p_rng_env->rng_state == APP_RNG_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_random32bit == NULL) || ((p_seed == NULL) && (p_rng_env->handle.init.seed_mode != RNG_SEED_FR0_S0))) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + rng_wake_up(); +#endif + + err_code = hal_rng_generate_random_number(&p_rng_env->handle, p_seed, p_random32bit); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_rng_gen_async(uint16_t *p_seed) +{ + hal_status_t err_code; + + if ((p_rng_env == NULL) || (p_rng_env->rng_state == APP_RNG_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_rng_env->use_type == APP_RNG_TYPE_POLLING) + { + return APP_DRV_ERR_INVALID_MODE; + } + + if ((p_seed == NULL) && (p_rng_env->handle.init.seed_mode != RNG_SEED_FR0_S0)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + rng_wake_up(); +#endif + + err_code = hal_rng_generate_random_number_it(&p_rng_env->handle, p_seed); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +rng_handle_t *app_rng_get_handle(void) +{ + if ((p_rng_env == NULL) || (p_rng_env->rng_state == APP_RNG_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + rng_wake_up(); +#endif + + return &p_rng_env->handle; +} + +void hal_rng_ready_data_callback(rng_handle_t *p_rng, uint32_t random32bit) +{ + app_rng_evt_t rng_evt; + rng_evt.type = APP_RNG_EVT_DONE; + rng_evt.random_data = random32bit; + + if (p_rng_env->evt_handler != NULL) + { + p_rng_env->evt_handler(&rng_evt); + } +} + +SECTION_RAM_CODE void RNG_IRQHandler(void) +{ + hal_rng_irq_handler(&p_rng_env->handle); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtc.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtc.c new file mode 100644 index 0000000..9fb3f62 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtc.c @@ -0,0 +1,560 @@ +/** + **************************************************************************************** + * @file app_rtc.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_rtc.h" +#include +#include "platform_sdk.h" +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#include "gr55xx_pwr.h" +#endif +#include "gr_soc.h" + +#ifdef HAL_CALENDAR_MODULE_ENABLED + +#if (CFG_LPCLK_INTERNAL_EN == 0) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ + +/**@brief App rtc state types. */ +typedef enum +{ + APP_RTC_INVALID = 0, + APP_RTC_ACTIVITY, +} app_rtc_state_t; + +struct rtc_env_t +{ + app_rtc_evt_handler_t evt_handler; + calendar_handle_t handle; + app_rtc_state_t rtc_state; +}; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ + +void CALENDAR_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ + +struct rtc_env_t s_rtc_env; + +/* +* NOTE: +* This defined value is only for SOC GR5332 +* 1.RTC is fully functional without FreeRTOS +* 2.In FreeRTOS, only init time and get time work. +*/ +#if defined(ENV_USE_FREERTOS) && defined(SOC_GR5332) + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_rtc_init(app_rtc_evt_handler_t evt_handler) +{ + s_rtc_env.evt_handler = evt_handler; + s_rtc_env.handle.clock_freq = SystemSlowClock; + + clock_calib_notify_register(app_rtc_time_sync); + + s_rtc_env.rtc_state = APP_RTC_ACTIVITY; + + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_deinit(void) +{ + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_INVALID_ID; + } + + clock_calib_notify_register(NULL); + + s_rtc_env.rtc_state = APP_RTC_INVALID; + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_init_time(app_rtc_time_t *p_time) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_time == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = hal_calendar_init_time(&s_rtc_env.handle, p_time); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_get_time(app_rtc_time_t *p_time) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_time == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = hal_calendar_get_time(&s_rtc_env.handle, p_time); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_alarm(app_rtc_alarm_t *p_alarm) +{ + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_alarm == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_tick(uint32_t interval) +{ + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (interval == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + return APP_DRV_SUCCESS; +} + +void app_rtc_time_sync(uint16_t SlowClockFreq) +{ + if (s_rtc_env.rtc_state == APP_RTC_INVALID || SlowClockFreq == 0) + { + return; + } + + hal_calendar_sync_time(&s_rtc_env.handle, SlowClockFreq); +} + +#else + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_rtc_event_call(calendar_handle_t *p_calendar, app_rtc_evt_type_t evt_type) +{ + app_rtc_evt_t rtc_evt; + + rtc_evt.type = evt_type; + if(s_rtc_env.evt_handler != NULL) + { + s_rtc_env.evt_handler(&rtc_evt); + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_rtc_init(app_rtc_evt_handler_t evt_handler) +{ + hal_status_t err_code; + + s_rtc_env.evt_handler = evt_handler; + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + s_rtc_env.handle.clock_freq = SystemSlowClock; +#endif + + soc_register_nvic(CALENDAR_IRQn, (uint32_t)CALENDAR_IRQHandler); + err_code = hal_calendar_deinit(&s_rtc_env.handle); + HAL_ERR_CODE_CHECK(err_code); + err_code = hal_calendar_init(&s_rtc_env.handle); + HAL_ERR_CODE_CHECK(err_code); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + clock_calib_notify_register(app_rtc_time_sync); +#endif + + s_rtc_env.rtc_state = APP_RTC_ACTIVITY; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + pwr_mgmt_wakeup_source_setup(PWR_WKUP_COND_CALENDAR); +#endif + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_deinit(void) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + hal_calendar_disable_event(&s_rtc_env.handle, CALENDAR_ALARM_DISABLE_ALL); + + err_code = hal_calendar_deinit(&s_rtc_env.handle); + HAL_ERR_CODE_CHECK(err_code); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + clock_calib_notify_register(NULL); +#endif + + s_rtc_env.rtc_state = APP_RTC_INVALID; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + pwr_mgmt_wakeup_source_clear(PWR_WKUP_COND_CALENDAR); +#endif + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_init_time(app_rtc_time_t *p_time) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_time == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = hal_calendar_init_time(&s_rtc_env.handle, p_time); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_get_time(app_rtc_time_t *p_time) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_time == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = hal_calendar_get_time(&s_rtc_env.handle, p_time); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_alarm(app_rtc_alarm_t *p_alarm) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_alarm == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = hal_calendar_set_alarm(&s_rtc_env.handle, p_alarm); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_tick(uint32_t interval) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (interval < 5) +#else + if (interval == 0) +#endif + { + return APP_DRV_ERR_INVALID_PARAM; + } + + err_code = hal_calendar_set_tick(&s_rtc_env.handle, interval); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_disable_event(uint32_t disable_mode) +{ + hal_status_t err_code; + + if (s_rtc_env.rtc_state == APP_RTC_INVALID) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_calendar_disable_event(&s_rtc_env.handle, disable_mode); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +void app_rtc_time_sync(uint16_t SlowClockFreq) +{ + if (s_rtc_env.rtc_state == APP_RTC_INVALID || SlowClockFreq == 0) + { + return; + } + + hal_calendar_sync_time(&s_rtc_env.handle, SlowClockFreq); +} +#endif + +void hal_calendar_alarm_callback(calendar_handle_t *p_calendar) +{ + app_rtc_event_call(p_calendar, APP_RTC_EVT_DATE_ALARM); +} + +void hal_calendar_tick_callback(calendar_handle_t *p_calendar) +{ + app_rtc_event_call(p_calendar, APP_RTC_EVT_TICK_ALARM); +} + +void hal_calendar_overflow_callback(calendar_handle_t *p_calendar) +{ + app_rtc_event_call(p_calendar, APP_RTC_EVT_OVERFLOW); +} + +SECTION_RAM_CODE void CALENDAR_IRQHandler(void) +{ + hal_calendar_irq_handler(&s_rtc_env.handle); +} + +#endif + +#else + +#include "ble_time.h" +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint64_t s_sys_sync_hus = 0; // Record the hus from 01.01.2000 00:00 to the time when time sync +static ble_time_t s_ble_sync_time = {0, 0}; // Record the ble time when time sync + +/* Caculate seconds from 01.01.2000 00:00 to the time */ +void calendar_time2seconds(calendar_time_t *p_time, uint32_t *p_seconds) +{ + uint16_t year; + uint32_t utc; + + // 10957 is the days between 1970/1/1 and 2000/1/1 + year = (p_time->year + 2000) % 100; + utc = 10957; + utc += (year * 365 + (year + 3) / 4); + utc += (367 * p_time->mon - 362) / 12 - (p_time->mon <= 2 ? 0 : ((year % 4 == 0) ? 1 : 2)); + utc += (p_time->date - 1); + utc *= 86400; + utc += (p_time->hour * 3600 + p_time->min * 60 + p_time->sec); + + *p_seconds = utc; +} + +/* Caculate time with seconds from 01.01.2000 00:00 to the p_time */ +void seconds2_calendar_time(calendar_time_t *p_time, uint32_t seconds) +{ + const uint16_t days0[] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; + const uint16_t days1[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; + + calendar_time_t time; + uint32_t days, secs; + uint16_t year; + const uint16_t * dayp; + + // 10957 is the days between 1970/1/1 and 2000/1/1 + if (seconds >= 10957 * 86400) + { + days = seconds / 86400 - 10957; + secs = seconds % 86400; + } + else + { + days = 0; + secs = 0; + } + + time.sec = secs % 60; secs /= 60; + time.min = secs % 60; secs /= 60; + time.hour = secs; + + year = 2000; + time.week = (days + 6) % 7; + + year += (days / 1461) * 4; days %= 1461; + if (days >= 366) + dayp = days1; + else + dayp = days0; + if (days >= 366) + { + year += (days - 1) / 365; + days = (days - 1) % 365; + } + + time.mon = days / 31 + 1; + if (days >= dayp[time.mon]) + time.mon += 1; + + time.date = days - dayp[time.mon - 1] + 1; + time.year = year - 2000; + + memcpy(p_time, &time, sizeof(calendar_time_t)); +} + +/* The calendar_time_sync shall be called every 23 hours to keep counting continously*/ +void calendar_time_sync(void) +{ + // protect the calendar time sync operation + GLOBAL_EXCEPTION_DISABLE(); + + // calculate the sync diff + ble_time_t current_time = ble_time_get(); + uint64_t diff_hus = (uint64_t)CLK_SUB(current_time.hs, s_ble_sync_time.hs)*HALF_SLOT_SIZE; + diff_hus = diff_hus + current_time.hus - s_ble_sync_time.hus; + + // sync the calendar time + s_sys_sync_hus = s_sys_sync_hus + diff_hus; + s_ble_sync_time = current_time; + + GLOBAL_EXCEPTION_ENABLE(); +} + +uint16_t app_rtc_init_time(app_rtc_time_t *p_time) +{ + // calculate the calendar time in seconds + uint32_t seconds = 0; + calendar_time2seconds(p_time, &seconds); + + // initialize the calendar time in hus + s_sys_sync_hus = ((uint64_t)(seconds) * SECOND_IN_HUS) + (TICK_MS_IN_HUS * p_time->ms); + s_ble_sync_time = ble_time_get(); + + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_get_time(app_rtc_time_t *p_time) +{ + // sync the calendar time + calendar_time_sync(); + + // calculate the calendar time in seconds + uint32_t seconds = s_sys_sync_hus / SECOND_IN_HUS; + seconds2_calendar_time(p_time, seconds); + + // calculate the calendar time in ms + uint32_t ms = (s_sys_sync_hus % SECOND_IN_HUS) / TICK_MS_IN_HUS; + p_time->ms = ms; + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_init(app_rtc_evt_handler_t evt_handler) +{ + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_deinit(void) +{ + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_alarm(app_rtc_alarm_t *p_alarm) +{ + return APP_DRV_SUCCESS; +} + +uint16_t app_rtc_setup_tick(uint32_t interval) +{ + return APP_DRV_SUCCESS; +} + +#endif + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtos_cfg.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtos_cfg.c new file mode 100644 index 0000000..862b8c6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_rtos_cfg.c @@ -0,0 +1,248 @@ +/** + **************************************************************************************** + * @file app_rtos_cfg.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_rtos_cfg.h" +#include "app_drv_error.h" +#include +#include + + +#ifdef ENV_USE_FREERTOS + +#include "FreeRTOS.h" +#include "semphr.h" + +uint16_t app_driver_sem_init(sem_t *sem) +{ + SemaphoreHandle_t *xSemaphore = (SemaphoreHandle_t *)sem; + + if (NULL == sem) + { + return APP_DRV_ERR_INVALID_PARAM; + } + *xSemaphore = xSemaphoreCreateBinary(); + if (NULL == *xSemaphore) + { + return APP_DRV_ERR_POINTER_NULL; + } + return APP_DRV_SUCCESS; +} + +void app_driver_sem_deinit(sem_t sem) +{ + vSemaphoreDelete(sem); +} + +uint16_t app_driver_sem_pend(sem_t sem, uint32_t time_out) +{ + BaseType_t ret = pdTRUE; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)sem; + TickType_t xTicks = portMAX_DELAY; + + if (NULL == sem) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (time_out != portMAX_DELAY) + { + xTicks = pdMS_TO_TICKS(time_out); + } + + if (__get_IPSR()) + { + ret = xSemaphoreTakeFromISR(xSemaphore, &xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken != pdFALSE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + ret = xSemaphoreTake(xSemaphore, xTicks); + } + if (ret != pdTRUE) + { + return APP_DRV_ERR_TIMEOUT; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_driver_sem_post(sem_t sem) +{ + BaseType_t ret = pdTRUE; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)sem; + + if (NULL == sem) + { + return APP_DRV_ERR_INVALID_PARAM; + } + if (__get_IPSR()) + { + ret = xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken != pdFALSE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + ret = xSemaphoreGive(xSemaphore); + } + if (ret != pdTRUE) + { + return APP_DRV_ERR_INVALID_PARAM; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_driver_sem_post_from_isr(sem_t sem) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + BaseType_t ret = pdTRUE; + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t)sem; + + if (NULL == sem) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + ret = xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken != pdFALSE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + if (ret != pdTRUE) + { + return APP_DRV_ERR_INVALID_PARAM; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_driver_mutex_init(mutex_t *mutex) +{ + SemaphoreHandle_t *xMutex = (SemaphoreHandle_t *)(mutex); + + if (NULL == mutex) + { + return APP_DRV_ERR_INVALID_PARAM; + } + *xMutex = xSemaphoreCreateMutex(); + if (NULL == *xMutex) + { + return APP_DRV_ERR_POINTER_NULL; + } + return APP_DRV_SUCCESS; +} + +void app_driver_mutex_deinit(mutex_t mutex) +{ + vSemaphoreDelete(mutex); +} + +uint16_t app_driver_mutex_pend(mutex_t mutex, uint32_t time_out) +{ + SemaphoreHandle_t xMutex = (SemaphoreHandle_t)mutex; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + BaseType_t ret = pdTRUE; + TickType_t xTicks = portMAX_DELAY; + + if (NULL == mutex) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (time_out != portMAX_DELAY) + { + xTicks = pdMS_TO_TICKS(time_out); + } + + if (__get_IPSR()) + { + ret = xSemaphoreTakeFromISR(xMutex, &xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken != pdFALSE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + ret = xSemaphoreTake(xMutex, xTicks); + } + + if (ret != pdTRUE) + { + return APP_DRV_ERR_TIMEOUT; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_driver_mutex_post(mutex_t mutex) +{ + BaseType_t ret = pdTRUE; + SemaphoreHandle_t xMutex = (SemaphoreHandle_t)mutex; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + if (NULL == mutex) + { + return APP_DRV_ERR_INVALID_PARAM; + } + if (__get_IPSR()) + { + ret = xSemaphoreGiveFromISR(xMutex, &xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken != pdFALSE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + ret = xSemaphoreGive(xMutex); + } + + if (ret != pdTRUE) + { + return APP_DRV_ERR_INVALID_PARAM; + } + return APP_DRV_SUCCESS; +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_soft_encoder.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_soft_encoder.c new file mode 100644 index 0000000..04d0341 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_soft_encoder.c @@ -0,0 +1,177 @@ +/** + **************************************************************************************** + * @file app_soft_encoder.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_soft_encoder.h" +#include "string.h" +#include "app_pwr_mgmt.h" +#include "gr55xx_delay.h" +#include "app_timer.h" +#include "app_gpiote.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define SOFT_ENCODER_STOP_STATUS 0x00 + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static app_soft_encoder_direction_t s_cur_direction; /* */ +static int s_cur_distance; /**/ + +static app_gpiote_param_t s_gpiote_info[APP_SOFT_ENCODER_SINGAL_NUMBER]; + +static uint8_t s_singal_a_level; /* */ +static uint8_t s_singal_b_level; /* */ + +static app_soft_encoder_callback s_ext_callback;/**< the soft encoder current singal irq type A\B*/ + + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static void app_soft_encoder_analy_dir(uint8_t singal_a,uint8_t singal_b) +{ + if (singal_a == 1 && singal_b == 0) + { + s_cur_direction = APP_SOFT_ENCODER_POSITIVE; + s_cur_distance++; + } + else if (singal_a == 0 && singal_b == 1) + { + s_cur_direction = APP_SOFT_ENCODER_REVERSE; + s_cur_distance--; + } + else + { + return; + } + + s_ext_callback(s_cur_direction,s_cur_distance); +} + +static void app_soft_encoder_io_a_callback_t(app_io_evt_t *p_evt) +{ + uint8_t a_io_level = 0; + + delay_us(500); + + a_io_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].pin); + + if (APP_IO_PIN_SET == a_io_level && APP_IO_MODE_IT_RISING == s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].mode) + { + s_singal_a_level = a_io_level; + s_singal_b_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].pin); + app_soft_encoder_analy_dir(s_singal_a_level,s_singal_b_level); + } + else if (APP_IO_PIN_RESET == a_io_level && APP_IO_MODE_IT_FALLING == s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].mode) + { + s_singal_a_level = a_io_level; + s_singal_b_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].pin); + app_soft_encoder_analy_dir(s_singal_a_level,s_singal_b_level); + } +} + +static void app_soft_encoder_io_b_callback_t(app_io_evt_t *p_evt) +{ + uint8_t b_io_level = 0; + + delay_us(500); + + b_io_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].pin); + + if (APP_IO_PIN_SET == b_io_level && APP_IO_MODE_IT_RISING == s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].mode) + { + s_singal_b_level = b_io_level; + s_singal_a_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].pin); + app_soft_encoder_analy_dir(s_singal_a_level, s_singal_b_level); + } + else if (APP_IO_PIN_RESET == b_io_level && APP_IO_MODE_IT_FALLING == s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].mode) + { + s_singal_b_level = b_io_level; + s_singal_a_level = app_io_read_pin(s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].type,s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].pin); + app_soft_encoder_analy_dir(s_singal_a_level, s_singal_b_level); + } + +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_soft_encoder_init(app_soft_encoder_io_param_t *p_a_params, app_soft_encoder_io_param_t *p_b_params, app_soft_encoder_callback evt_handler) +{ + uint16_t error_code; + + if (evt_handler == NULL || p_a_params == NULL || p_b_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + s_ext_callback = evt_handler; + + + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].type = p_a_params->type; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].pin = p_a_params->pin; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].mode = p_a_params->mode; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].pull = p_a_params->pull; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_A].io_evt_cb = app_soft_encoder_io_a_callback_t; + + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].type = p_b_params->type; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].pin = p_b_params->pin; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].mode = p_b_params->mode; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].pull = p_b_params->pull; + s_gpiote_info[APP_SOFT_ENCODER_SIGNAL_B].io_evt_cb = app_soft_encoder_io_b_callback_t; + + error_code = app_gpiote_init(s_gpiote_info, APP_SOFT_ENCODER_SINGAL_NUMBER); + APP_DRV_ERR_CODE_CHECK(error_code); + + s_cur_direction = APP_SOFT_ENCODER_STOP; + s_cur_distance = 0; + + + s_singal_a_level = 0; + s_singal_b_level = 0; + + return APP_DRV_SUCCESS; +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi.c new file mode 100644 index 0000000..420ca55 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi.c @@ -0,0 +1,1201 @@ +/** + **************************************************************************************** + * @file app_spi.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_spi.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" +#include + +#ifdef HAL_SPI_MODULE_ENABLED + +/* + * DEFINES + ***************************************************************************************** + */ +#define DEFAULT_POLLING_WAIT_TIMEOUT_MS 1000u +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define BLE_INT_DISABLE() \ +do { \ + volatile uint32_t __ble_l_irq_rest = __get_PRIMASK(); \ + volatile bool __ble_int_status = NVIC_GetEnableIRQ(BLE_IRQn) || NVIC_GetEnableIRQ(BLESLP_IRQn); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_DisableIRQ(BLE_IRQn); \ + NVIC_DisableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); + +/** @brief Restore BLE_IRQn and BLESLP_IRQn. + * @sa BLE_INT_RESTORE + */ +#define BLE_INT_RESTORE() \ + __ble_l_irq_rest = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_EnableIRQ(BLE_IRQn); \ + NVIC_EnableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); \ +} while(0) +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define SPI_SMART_CS_LOW(id) \ + do { \ + if((APP_SPI_ID_SLAVE != id) && \ + (p_spi_env[id]->p_pin_cfg->cs.enable == APP_SPI_PIN_ENABLE)) \ + { \ + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, \ + p_spi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_RESET); \ + }\ + } while(0) + +#define SPI_SMART_CS_HIGH(id) \ + do { \ + if((APP_SPI_ID_SLAVE != id) && \ + (p_spi_env[id]->p_pin_cfg->cs.enable == APP_SPI_PIN_ENABLE)) \ + { \ + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, \ + p_spi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_SET); \ + } \ + } while(0) +#else +#define SPI_SMART_CS_LOW(id) +#define SPI_SMART_CS_HIGH(id) +#endif + +#define APP_SPI_CALLBACK(id, evt) \ + do \ + { \ + p_spi_env[id]->start_flag = false; \ + SPI_SMART_CS_HIGH(id); \ + if (p_spi_env[id]->evt_handler != NULL) \ + { \ + p_spi_env[id]->evt_handler(&evt); \ + } \ + } while(0) + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool spi_prepare_for_sleep(void); +static void spi_wake_up_ind(void); +static uint16_t spi_gpio_config(app_spi_id_t id, app_spi_pin_cfg_t pin_cfg); +void SPI_S_IRQHandler(void); +void SPI_M_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const IRQn_Type s_spi_irq[APP_SPI_ID_MAX] = {SPI_S_IRQn, SPI_M_IRQn}; +static const uint32_t s_spi_instance[APP_SPI_ID_MAX] = {SPIS_BASE, SPIM_BASE}; + +spi_env_t *p_spi_env[APP_SPI_ID_MAX]; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_spi_pwr_id = -1; + +static const app_sleep_callbacks_t spi_sleep_cb = +{ + .app_prepare_for_sleep = spi_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = spi_wake_up_ind +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool spi_prepare_for_sleep(void) +{ + hal_spi_state_t state; + uint8_t i; + + for (i = 0; i < APP_SPI_ID_MAX; i++) + { + if (p_spi_env[i] == NULL) + { + continue; + } + + if (p_spi_env[i]->spi_state == APP_SPI_ACTIVITY) + { + state = hal_spi_get_state(&p_spi_env[i]->handle); + if ((state != HAL_SPI_STATE_READY) && (state != HAL_SPI_STATE_RESET)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_spi_suspend_reg(&p_spi_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + #ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_spi_env[i]->spi_state = APP_SPI_SLEEP; + #endif + } + } + + return true; +} + +SECTION_RAM_CODE static void spi_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_SPI_ID_MAX; i++) + { + if (p_spi_env[i] == NULL) + { + continue; + } + + if (p_spi_env[i]->spi_state == APP_SPI_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_spi_resume_reg(&p_spi_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_spi_irq[i]); + hal_nvic_enable_irq(s_spi_irq[i]); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void spi_wake_up(app_spi_id_t id) +{ + if (p_spi_env[id]->spi_state == APP_SPI_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_spi_resume_reg(&p_spi_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + if(p_spi_env[id]->use_mode.type == APP_SPI_TYPE_INTERRUPT || + p_spi_env[id]->use_mode.type == APP_SPI_TYPE_DMA) + { + hal_nvic_clear_pending_irq(s_spi_irq[id]); + hal_nvic_enable_irq(s_spi_irq[id]); + } + p_spi_env[id]->spi_state = APP_SPI_ACTIVITY; + } + + dma_wake_up(p_spi_env[id]->dma_id[0]); + dma_wake_up(p_spi_env[id]->dma_id[1]); +} +#endif + +static uint16_t spi_gpio_config(app_spi_id_t id, app_spi_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (pin_cfg.cs.enable == APP_SPI_PIN_ENABLE) + { + if (id == APP_SPI_ID_SLAVE) + { + io_init.pull = pin_cfg.cs.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = pin_cfg.cs.mux; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + else + { +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + io_init.pull = pin_cfg.cs.pull; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = APP_IO_MUX_7; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + app_io_write_pin(pin_cfg.cs.type, pin_cfg.cs.pin, APP_IO_PIN_SET); + APP_DRV_ERR_CODE_CHECK(err_code); +#else + if(p_spi_env[id]->is_soft_cs) { + io_init.pull = pin_cfg.cs.pull; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = APP_IO_MUX; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + app_io_write_pin(pin_cfg.cs.type, pin_cfg.cs.pin, APP_IO_PIN_SET); + APP_DRV_ERR_CODE_CHECK(err_code); + } else { + io_init.pull = pin_cfg.cs.pull; + io_init.mode = pin_cfg.cs.mode; + io_init.pin = pin_cfg.cs.pin; + io_init.mux = pin_cfg.cs.mux; + err_code = app_io_init(pin_cfg.cs.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } +#endif + } + } + if (pin_cfg.clk.enable == APP_SPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.clk.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.clk.pin; + io_init.mux = pin_cfg.clk.mux; + err_code = app_io_init(pin_cfg.clk.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.mosi.enable == APP_SPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.mosi.pull; + io_init.pin = pin_cfg.mosi.pin; + io_init.mux = pin_cfg.mosi.mux; + err_code = app_io_init(pin_cfg.mosi.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + if (pin_cfg.miso.enable == APP_SPI_PIN_ENABLE) + { + io_init.pull = pin_cfg.miso.pull; + io_init.pin = pin_cfg.miso.pin; + io_init.mux = pin_cfg.miso.mux; + err_code = app_io_init(pin_cfg.miso.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +static inline app_spi_id_t spi_get_id(spi_handle_t *p_spi) +{ + app_spi_id_t id = APP_SPI_ID_MAX; + + if (p_spi->p_instance == SPIS) + { + id = APP_SPI_ID_SLAVE; + } + else if (p_spi->p_instance == SPIM) + { + id = APP_SPI_ID_MASTER; + } + + return id; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_spi_init(app_spi_params_t *p_params, app_spi_evt_handler_t evt_handler) +{ + app_spi_id_t id = p_params->id; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + p_spi_env[id] = &(p_params->spi_env); + soc_register_nvic(SPI_S_IRQn, (uint32_t)SPI_S_IRQHandler); + soc_register_nvic(SPI_M_IRQn, (uint32_t)SPI_M_IRQHandler); + + p_spi_env[id]->is_soft_cs = p_params->is_soft_cs; + + err_code = spi_gpio_config(p_params->id, p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(err_code); + + hal_nvic_clear_pending_irq(s_spi_irq[id]); + hal_nvic_enable_irq(s_spi_irq[id]); + + p_spi_env[id]->p_pin_cfg = &p_params->pin_cfg; + p_spi_env[id]->evt_handler = evt_handler; + + memcpy(&p_spi_env[id]->handle.init, &p_params->init, sizeof(spi_init_t)); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_spi_env[id]->handle.p_instance = (ssi_regs_t *)s_spi_instance[id]; +#else + p_spi_env[id]->handle.p_instance = (spi_regs_t *)s_spi_instance[id]; +#endif + +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + if(p_params->is_soft_cs) { + p_spi_env[id]->handle.soft_cs_magic = SPI_SOFT_CS_MAGIC_NUMBER; + } else { + p_spi_env[id]->handle.soft_cs_magic = 0x00; + } +#endif + + hal_spi_deinit(&p_spi_env[id]->handle); + hal_spi_init(&p_spi_env[id]->handle); + + if (s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_spi_pwr_id = pwr_register_sleep_cb(&spi_sleep_cb, APP_DRIVER_SPI_WAPEUP_PRIORITY); + + if (s_spi_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_spi_env[id]->spi_state = APP_SPI_ACTIVITY; + p_spi_env[id]->start_flag = false; + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_deinit(app_spi_id_t id) +{ + uint8_t i; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_spi_env[id]->p_pin_cfg->cs.enable == APP_SPI_PIN_ENABLE) + { + app_io_deinit(p_spi_env[id]->p_pin_cfg->cs.type, p_spi_env[id]->p_pin_cfg->cs.pin); + } + if (p_spi_env[id]->p_pin_cfg->clk.enable == APP_SPI_PIN_ENABLE) + { + app_io_deinit(p_spi_env[id]->p_pin_cfg->clk.type, p_spi_env[id]->p_pin_cfg->clk.pin); + } + if (p_spi_env[id]->p_pin_cfg->mosi.enable == APP_SPI_PIN_ENABLE) + { + app_io_deinit(p_spi_env[id]->p_pin_cfg->mosi.type, p_spi_env[id]->p_pin_cfg->mosi.pin); + } + if (p_spi_env[id]->p_pin_cfg->miso.enable == APP_SPI_PIN_ENABLE) + { + app_io_deinit(p_spi_env[id]->p_pin_cfg->miso.type, p_spi_env[id]->p_pin_cfg->miso.pin); + } + + hal_nvic_disable_irq(s_spi_irq[id]); + + p_spi_env[id]->spi_state = APP_SPI_INVALID; + p_spi_env[id]->start_flag = false; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_SPI_ID_MAX; i++) + { + if (p_spi_env[i] != NULL && (p_spi_env[i]->spi_state) != APP_SPI_INVALID) + { + break; + } + } + if (APP_SPI_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_spi_pwr_id); + s_spi_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_spi_deinit(&p_spi_env[id]->handle); + if (p_spi_env[id]->spi_dma_state == APP_SPI_DMA_INVALID) + { + p_spi_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spim_transmit_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t * p_data, uint16_t data_length) { + hal_status_t err_code = HAL_OK; + + if (id != APP_SPI_ID_MASTER) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_data == NULL) || (data_length == 0)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_with_ia(&p_spi_env[id]->handle, instruction, address, p_data, data_length, DEFAULT_POLLING_WAIT_TIMEOUT_MS); + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_spim_receive_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t dummy_bytes, uint8_t * p_data, uint16_t data_length) { + uint8_t ia_data[8]; + uint8_t sent_len = 0; + hal_status_t err_code = HAL_OK; + + if (id != APP_SPI_ID_MASTER) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_data == NULL) ||(data_length == 0)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + memset(&ia_data[0], 0, 8); + + ia_data[0] = instruction; + ia_data[1] = (address >> 16) & 0xff; + ia_data[2] = (address >> 8) & 0xff; + ia_data[3] = (address >> 0) & 0xff; + + if(dummy_bytes > 4) { + return APP_DRV_ERR_INVALID_PARAM; + } + + sent_len = 4 + dummy_bytes; + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_read_eeprom(&p_spi_env[id]->handle, ia_data, p_data, sent_len, data_length, DEFAULT_POLLING_WAIT_TIMEOUT_MS); + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_receive_async(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_receive_it(&p_spi_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_receive_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_receive(&p_spi_env[id]->handle, p_data, size, timeout); + SPI_SMART_CS_HIGH(id); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_spi_receive_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + hal_status_t hal_err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + BLE_INT_DISABLE(); + p_spi_env[id]->rx_done = 0; + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + hal_err_code = hal_spi_receive_it(&p_spi_env[id]->handle, p_data, size); + if (hal_err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + app_err_code = (uint16_t)hal_err_code; + goto exit; + } + } + else + { + app_err_code = APP_DRV_ERR_BUSY; + goto exit; + } + + while(p_spi_env[id]->rx_done == 0); + +exit: + BLE_INT_RESTORE(); + + return app_err_code; +} + +uint16_t app_spi_transmit_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + hal_status_t hal_err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + BLE_INT_DISABLE(); + p_spi_env[id]->tx_done = 0; + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + hal_err_code = hal_spi_transmit_it(&p_spi_env[id]->handle, p_data, size); + if (hal_err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + app_err_code = (uint16_t)hal_err_code; + + goto exit; + } + } + else + { + app_err_code = APP_DRV_ERR_BUSY; + goto exit; + } + + while(p_spi_env[id]->tx_done == 0); + +exit: + BLE_INT_RESTORE(); + + return app_err_code; +} +#endif + +uint16_t app_spi_transmit_async(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_it(&p_spi_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_transmit_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit(&p_spi_env[id]->handle, p_data, size, timeout); + SPI_SMART_CS_HIGH(id); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_transmit_receive_sync(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_receive(&p_spi_env[id]->handle, p_tx_data, p_rx_data, size, timeout); + SPI_SMART_CS_HIGH(id); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_transmit_receive_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_receive_it(&p_spi_env[id]->handle, p_tx_data, p_rx_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_read_eeprom_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL || tx_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_read_eeprom_it(&p_spi_env[id]->handle, p_tx_data, p_rx_data, tx_size, rx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_read_eeprom_sync(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL || tx_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_read_eeprom(&p_spi_env[id]->handle, p_tx_data, p_rx_data, tx_size, rx_size, timeout); + SPI_SMART_CS_HIGH(id); + + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_spi_read_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_rx_data, uint32_t cmd_size, uint32_t rx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd_data == NULL || p_rx_data == NULL || cmd_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit(&p_spi_env[id]->handle, p_cmd_data, cmd_size, 1000); + if (err_code != HAL_OK) + { + SPI_SMART_CS_HIGH(id); + p_spi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + err_code = hal_spi_receive_it(&p_spi_env[id]->handle, p_rx_data, rx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_write_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_tx_data, uint32_t cmd_size, uint32_t tx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd_data == NULL || p_tx_data == NULL || cmd_size == 0 || tx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit(&p_spi_env[id]->handle, p_cmd_data, cmd_size, 1000); + if (err_code != HAL_OK) + { + SPI_SMART_CS_HIGH(id); + p_spi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + err_code = hal_spi_transmit_it(&p_spi_env[id]->handle, p_tx_data, tx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} +#endif + +spi_handle_t *app_spi_get_handle(app_spi_id_t id) +{ + if (id >= APP_SPI_ID_MAX) + { + return NULL; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + return &p_spi_env[id]->handle; +} + +uint16_t app_spi_abort(app_spi_id_t id) +{ + uint16_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + err_code = hal_spi_abort_it(&p_spi_env[id]->handle); + if (err_code != HAL_OK) + return err_code; + + return APP_DRV_SUCCESS; +} + +void hal_spi_soft_cs_assert(spi_handle_t *p_spi, uint32_t state) +{ + app_spi_id_t id = spi_get_id(p_spi); + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, p_spi_env[id]->p_pin_cfg->cs.pin, APP_IO_PIN_RESET); +} + +void hal_spi_soft_cs_deassert(spi_handle_t *p_spi, uint32_t state) +{ + app_spi_id_t id = spi_get_id(p_spi); + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, p_spi_env[id]->p_pin_cfg->cs.pin, APP_IO_PIN_SET); +} + +void hal_spi_tx_cplt_callback(spi_handle_t *p_spi) +{ + app_spi_evt_t spi_evt; + app_spi_id_t id = spi_get_id(p_spi); + + spi_evt.type = APP_SPI_EVT_TX_CPLT; + spi_evt.data.size = p_spi->tx_xfer_size - p_spi->tx_xfer_count; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_spi_env[id]->tx_done = 1; +#endif + APP_SPI_CALLBACK(id, spi_evt); +} + +void hal_spi_rx_cplt_callback(spi_handle_t *p_spi) +{ + app_spi_evt_t spi_evt; + app_spi_id_t id = spi_get_id(p_spi); + + spi_evt.type = APP_SPI_EVT_RX_CPLT; + spi_evt.data.size = p_spi->rx_xfer_size - p_spi->rx_xfer_count; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_spi_env[id]->rx_done = 1; +#endif + APP_SPI_CALLBACK(id, spi_evt); +} + +void hal_spi_tx_rx_cplt_callback(spi_handle_t *p_spi) +{ + app_spi_evt_t spi_evt; + app_spi_id_t id = spi_get_id(p_spi); + + spi_evt.type = APP_SPI_EVT_TX_RX_CPLT; + spi_evt.data.size = p_spi->rx_xfer_size - p_spi->rx_xfer_count; + APP_SPI_CALLBACK(id, spi_evt); +} + +void hal_spi_error_callback(spi_handle_t *p_spi) +{ + app_spi_evt_t spi_evt; + app_spi_id_t id = spi_get_id(p_spi); + + spi_evt.type = APP_SPI_EVT_ERROR; + spi_evt.data.error_code = p_spi->error_code; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + p_spi_env[id]->rx_done = 1; + p_spi_env[id]->tx_done = 1; +#endif + APP_SPI_CALLBACK(id, spi_evt); +} + +void hal_spi_abort_cplt_callback(spi_handle_t *p_spi) +{ + app_spi_evt_t spi_evt; + app_spi_id_t id = spi_get_id(p_spi); + spi_evt.type = APP_SPI_EVT_ABORT; + APP_SPI_CALLBACK(id, spi_evt); +} + +SECTION_RAM_CODE void SPI_S_IRQHandler(void) +{ + hal_spi_irq_handler(&p_spi_env[APP_SPI_ID_SLAVE]->handle); +} + +SECTION_RAM_CODE void SPI_M_IRQHandler(void) +{ + hal_spi_irq_handler(&p_spi_env[APP_SPI_ID_MASTER]->handle); +} + +#endif /* HAL_SPI_MODULE_ENABLED */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi_dma.c new file mode 100644 index 0000000..9acff78 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_spi_dma.c @@ -0,0 +1,820 @@ +/** + **************************************************************************************** + * @file app_spi_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_spi_dma.h" +#include "app_dma.h" +#include "app_drv_config.h" +#include "app_pwr_mgmt.h" +#include +#include "gr_soc.h" + +#ifdef HAL_SPI_MODULE_ENABLED +/* + * DEFINES + ***************************************************************************************** + */ +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define BLE_INT_DISABLE() \ +do { \ + volatile uint32_t __ble_l_irq_rest = __get_PRIMASK(); \ + volatile bool __ble_int_status = NVIC_GetEnableIRQ(BLE_IRQn) || NVIC_GetEnableIRQ(BLESLP_IRQn); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_DisableIRQ(BLE_IRQn); \ + NVIC_DisableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); + +/** @brief Restore BLE_IRQn and BLESLP_IRQn. + * @sa BLE_INT_RESTORE + */ +#define BLE_INT_RESTORE() \ + __ble_l_irq_rest = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + if (__ble_int_status) \ + { \ + NVIC_EnableIRQ(BLE_IRQn); \ + NVIC_EnableIRQ(BLESLP_IRQn); \ + } \ + __set_PRIMASK(__ble_l_irq_rest); \ +} while(0) +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +#define SPI_SMART_CS_LOW(id) \ + do { \ + if((APP_SPI_ID_SLAVE != id) && \ + (p_spi_env[id]->p_pin_cfg->cs.enable == APP_SPI_PIN_ENABLE)) \ + { \ + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, \ + p_spi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_RESET); \ + }\ + } while(0) + +#define SPI_SMART_CS_HIGH(id) \ + do { \ + if((APP_SPI_ID_SLAVE != id) && \ + (p_spi_env[id]->p_pin_cfg->cs.enable == APP_SPI_PIN_ENABLE)) \ + { \ + app_io_write_pin(p_spi_env[id]->p_pin_cfg->cs.type, \ + p_spi_env[id]->p_pin_cfg->cs.pin, \ + APP_IO_PIN_SET); \ + } \ + } while(0) +#else +#define SPI_SMART_CS_LOW(id) +#define SPI_SMART_CS_HIGH(id) +#endif + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +extern bool spi_prepare_for_sleep(void); +extern void spi_sleep_canceled(void); +extern void spi_wake_up_ind(void); +extern void spi_wake_up(app_spi_id_t id); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +extern spi_env_t *p_spi_env[APP_SPI_ID_MAX]; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static uint16_t app_spi_config_dma_tx(app_spi_params_t *p_params) +{ + app_dma_params_t tx_dma_params = { 0 }; + + tx_dma_params.p_instance = p_params->dma_cfg.tx_dma_instance; + tx_dma_params.channel_number = p_params->dma_cfg.tx_dma_channel; + tx_dma_params.init.src_request = DMA0_REQUEST_MEM; + tx_dma_params.init.dst_request = (p_params->id == APP_SPI_ID_SLAVE) ? DMA0_REQUEST_SPIS_TX : DMA0_REQUEST_SPIM_TX; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (tx_dma_params.p_instance == DMA1) + { + if (p_params->id == APP_SPI_ID_SLAVE) + { + return APP_DRV_ERR_INVALID_PARAM; + } + tx_dma_params.init.src_request = DMA1_REQUEST_MEM; + tx_dma_params.init.dst_request = DMA1_REQUEST_SPIM_TX; + } +#endif + tx_dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + tx_dma_params.init.src_increment = DMA_SRC_INCREMENT; + tx_dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + if (p_params->init.data_size <= SPI_DATASIZE_8BIT) + { + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + } + else if (p_params->init.data_size <= SPI_DATASIZE_16BIT) + { + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD; + } + else + { + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; + } +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + tx_dma_params.init.mode = DMA_NORMAL; +#endif + tx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_spi_env[p_params->id]->dma_id[0] = app_dma_init(&tx_dma_params, NULL); + + if (p_spi_env[p_params->id]->dma_id[0] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + p_spi_env[p_params->id]->handle.p_dmatx = app_dma_get_handle(p_spi_env[p_params->id]->dma_id[0]); + p_spi_env[p_params->id]->handle.p_dmatx->p_parent = (void*)&p_spi_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_spi_config_dma_rx(app_spi_params_t *p_params) +{ + app_dma_params_t rx_dma_params = { 0 }; + + rx_dma_params.p_instance = p_params->dma_cfg.rx_dma_instance; + rx_dma_params.channel_number = p_params->dma_cfg.rx_dma_channel; + rx_dma_params.init.dst_request = DMA0_REQUEST_MEM; + rx_dma_params.init.src_request = (p_params->id == APP_SPI_ID_SLAVE) ? DMA0_REQUEST_SPIS_RX : DMA0_REQUEST_SPIM_RX; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + if (rx_dma_params.p_instance == DMA1) + { + if (p_params->id == APP_SPI_ID_SLAVE) + { + return APP_DRV_ERR_INVALID_PARAM; + } + rx_dma_params.init.dst_request = DMA1_REQUEST_MEM; + rx_dma_params.init.src_request = DMA1_REQUEST_SPIM_RX; + } +#endif + rx_dma_params.init.direction = DMA_PERIPH_TO_MEMORY; + rx_dma_params.init.src_increment = DMA_SRC_NO_CHANGE; + rx_dma_params.init.dst_increment = DMA_DST_INCREMENT; + if (p_params->init.data_size <= SPI_DATASIZE_8BIT) + { + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; + } + else if (p_params->init.data_size <= SPI_DATASIZE_16BIT) + { + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD; + } + else + { + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD; + } +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + rx_dma_params.init.mode = DMA_NORMAL; +#endif + rx_dma_params.init.priority = DMA_PRIORITY_LOW; + + p_spi_env[p_params->id]->dma_id[1] = app_dma_init(&rx_dma_params, NULL); + + if (p_spi_env[p_params->id]->dma_id[1] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + p_spi_env[p_params->id]->handle.p_dmarx = app_dma_get_handle(p_spi_env[p_params->id]->dma_id[1]); + p_spi_env[p_params->id]->handle.p_dmarx->p_parent = (void*)&p_spi_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_spi_config_dma(app_spi_params_t *p_params) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + + p_spi_env[p_params->id]->dma_id[0] = -1; + p_spi_env[p_params->id]->dma_id[1] = -1; + + if (p_params->dma_cfg.tx_dma_instance == NULL && + p_params->dma_cfg.rx_dma_instance == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_params->dma_cfg.tx_dma_instance != NULL) + { + app_err_code = app_spi_config_dma_tx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + if (p_params->dma_cfg.rx_dma_instance != NULL) + { + app_err_code = app_spi_config_dma_rx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + + return APP_DRV_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_spi_dma_init(app_spi_params_t *p_params) +{ + app_spi_id_t id = p_params->id; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + GLOBAL_EXCEPTION_DISABLE(); + err_code = app_spi_config_dma(p_params); + if (err_code != APP_DRV_SUCCESS) + { + goto __exit; + } + p_spi_env[id]->spi_dma_state = APP_SPI_DMA_ACTIVITY; +__exit: + GLOBAL_EXCEPTION_ENABLE(); + + return err_code; +} + +uint16_t app_spi_dma_deinit(app_spi_id_t id) +{ + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_dma_state != APP_SPI_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_spi_env[id]->dma_id[0]); + app_dma_deinit(p_spi_env[id]->dma_id[1]); + + GLOBAL_EXCEPTION_DISABLE(); + p_spi_env[id]->spi_dma_state = APP_SPI_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + if (p_spi_env[id]->spi_state == APP_SPI_INVALID) + { + p_spi_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spim_dma_transmit_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t * p_data, uint16_t data_length) { + hal_status_t err_code = HAL_OK; + + if (id != APP_SPI_ID_MASTER) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_data == NULL) || (data_length == 0)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_dma_with_ia(&p_spi_env[id]->handle, instruction, address, p_data, data_length); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + return APP_DRV_SUCCESS; +} + +uint16_t app_spim_dma_receive_with_ia(app_spi_id_t id, uint8_t instruction, uint32_t address, uint8_t dummy_bytes, uint8_t * p_data, uint16_t data_length) { + uint8_t ia_data[8]; + uint8_t sent_len = 0; + hal_status_t err_code = HAL_OK; + + if (id != APP_SPI_ID_MASTER) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if ((p_data == NULL) || (data_length == 0)) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + memset(&ia_data[0], 0, 8); + + ia_data[0] = instruction; + ia_data[1] = (address >> 16) & 0xff; + ia_data[2] = (address >> 8) & 0xff; + ia_data[3] = (address >> 0) & 0xff; + + if(dummy_bytes > 4) { + return APP_DRV_ERR_INVALID_PARAM; + } + + sent_len = 4 + dummy_bytes; + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_read_eeprom_dma(&p_spi_env[id]->handle, ia_data, p_data, sent_len, data_length); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_dma_receive_async(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_receive_dma(&p_spi_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_spi_dma_receive_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + hal_status_t hal_err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + BLE_INT_DISABLE(); + p_spi_env[id]->rx_done = 0; + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + hal_err_code = hal_spi_receive_dma(&p_spi_env[id]->handle, p_data, size); + if (hal_err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + app_err_code = (uint16_t)hal_err_code; + goto exit; + } + } + else + { + app_err_code = APP_DRV_ERR_BUSY; + goto exit; + } + + while(p_spi_env[id]->rx_done == 0); + +exit: + BLE_INT_RESTORE(); + + return app_err_code; +} + +uint16_t app_spi_dma_transmit_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + hal_status_t hal_err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + BLE_INT_DISABLE(); + p_spi_env[id]->tx_done = 0; + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + hal_err_code = hal_spi_transmit_dma(&p_spi_env[id]->handle, p_data, size); + if (hal_err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + app_err_code = (uint16_t)hal_err_code; + + goto exit; + } + } + else + { + app_err_code = APP_DRV_ERR_BUSY; + goto exit; + } + + while(p_spi_env[id]->tx_done == 0); + +exit: + BLE_INT_RESTORE(); + + return app_err_code; +} +#endif + +uint16_t app_spi_dma_transmit_async(app_spi_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_dma(&p_spi_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_dma_transmit_receive_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL ||size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit_receive_dma(&p_spi_env[id]->handle, p_tx_data, p_rx_data, size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_dma_read_eeprom_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_tx_data == NULL || p_rx_data == NULL || tx_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + SPI_SMART_CS_LOW(id); + err_code = hal_spi_read_eeprom_dma(&p_spi_env[id]->handle, p_tx_data, p_rx_data, tx_size, rx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) +uint16_t app_spi_dma_read_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_rx_data, uint32_t cmd_size, uint32_t rx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd_data == NULL || p_rx_data == NULL || cmd_size == 0 || rx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit(&p_spi_env[id]->handle, p_cmd_data, cmd_size, 1000); + if (err_code != HAL_OK) + { + SPI_SMART_CS_HIGH(id); + p_spi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + err_code = hal_spi_receive_dma(&p_spi_env[id]->handle, p_rx_data, rx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_spi_dma_write_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, uint8_t *p_tx_data, uint32_t cmd_size, uint32_t tx_size) +{ + hal_status_t err_code = HAL_ERROR; + + if (id >= APP_SPI_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_spi_env[id] == NULL) || (p_spi_env[id]->spi_state == APP_SPI_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + if (p_cmd_data == NULL || p_tx_data == NULL || cmd_size == 0 || tx_size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + spi_wake_up(id); +#endif + + if (p_spi_env[id]->start_flag == false) + { + p_spi_env[id]->start_flag = true; + + SPI_SMART_CS_LOW(id); + err_code = hal_spi_transmit(&p_spi_env[id]->handle, p_cmd_data, cmd_size, 1000); + if (err_code != HAL_OK) + { + SPI_SMART_CS_HIGH(id); + p_spi_env[id]->start_flag = false; + return (uint16_t)err_code; + } + + err_code = hal_spi_transmit_dma(&p_spi_env[id]->handle, p_tx_data, tx_size); + if (err_code != HAL_OK) + { + p_spi_env[id]->start_flag = false; + SPI_SMART_CS_HIGH(id); + return (uint16_t)err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} +#endif + +#endif /* HAL_SPI_MODULE_ENABLED */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_tim.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_tim.c new file mode 100644 index 0000000..f204c9c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_tim.c @@ -0,0 +1,426 @@ +/** + **************************************************************************************** + * @file app_tim.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "app_tim.h" +#include "app_drv.h" +#include "string.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" + +#ifdef HAL_TIMER_MODULE_ENABLED + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool tim_prepare_for_sleep(void); +static void tim_wake_up_ind(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const IRQn_Type s_tim_irq[APP_TIM_ID_MAX] = { TIMER0_IRQn, TIMER1_IRQn }; +static const uint32_t s_tim_instance[APP_TIM_ID_MAX] = { TIMER0_BASE, TIMER1_BASE }; + +tim_env_t *p_tim_env[APP_TIM_ID_MAX]; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_tim_pwr_id; + +const static app_sleep_callbacks_t tim_sleep_cb = +{ + .app_prepare_for_sleep = tim_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = tim_wake_up_ind, +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool tim_prepare_for_sleep(void) +{ + return false; +} + +SECTION_RAM_CODE static void tim_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_TIM_ID_MAX; i++) + { + if (p_tim_env[i] == NULL) + { + continue; + } + + if (p_tim_env[i]->tim_state == APP_TIM_ACTIVITY) + { + hal_nvic_clear_pending_irq(s_tim_irq[i]); + hal_nvic_enable_irq(s_tim_irq[i]); + + #if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + hal_timer_deinit(&p_tim_env[i]->handle); + hal_timer_init(&p_tim_env[i]->handle); + #else + hal_timer_base_deinit(&p_tim_env[i]->handle); + hal_timer_base_init(&p_tim_env[i]->handle); + #endif + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +static void tim_wake_up(app_tim_id_t id) +{ + if (p_tim_env[id]->tim_state == APP_TIM_SLEEP) + { + hal_nvic_clear_pending_irq(s_tim_irq[id]); + hal_nvic_enable_irq(s_tim_irq[id]); + + hal_timer_base_deinit(&p_tim_env[id]->handle); + hal_timer_base_init(&p_tim_env[id]->handle); + p_tim_env[id]->tim_state = APP_TIM_ACTIVITY; + } +} +#endif + +static void app_tim_event_call(timer_handle_t *p_tim, app_tim_evt_t evt_type) +{ + app_tim_evt_t tim_evt = APP_TIM_EVT_ERROR; + app_tim_id_t id = APP_TIM_ID_0; + + if(p_tim->p_instance == TIMER0) + { + id = APP_TIM_ID_0; + } + else if(p_tim->p_instance == TIMER1) + { + id = APP_TIM_ID_1; + } + + if (evt_type == APP_TIM_EVT_DONE) + { + tim_evt = APP_TIM_EVT_DONE; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + else if(evt_type == APP_TIM_EVT_CHANNEL0) + { + tim_evt = APP_TIM_EVT_CHANNEL0; + } + else if(evt_type == APP_TIM_EVT_CHANNEL1) + { + tim_evt = APP_TIM_EVT_CHANNEL1; + } + else if(evt_type == APP_TIM_EVT_CHANNEL2) + { + tim_evt = APP_TIM_EVT_CHANNEL2; + } + else if(evt_type == APP_TIM_EVT_CHANNEL3) + { + tim_evt = APP_TIM_EVT_CHANNEL3; + } +#endif + + if (p_tim_env[id]->tim_state == APP_TIM_INVALID) + { + tim_evt = APP_TIM_EVT_ERROR; + } + + if (p_tim_env[id]->evt_handler != NULL) + { + p_tim_env[id]->evt_handler(&tim_evt); + } +} + +#define TIMER_HANDLER(index, val) \ +SECTION_RAM_CODE void TIMER##index##_IRQHandler(void)\ +{\ + hal_timer_irq_handler(&p_tim_env[val]->handle);\ +} + +TIMER_HANDLER(0, APP_TIM_ID_0) +TIMER_HANDLER(1, APP_TIM_ID_1) + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_tim_init(app_tim_params_t *p_params, app_tim_evt_handler_t evt_handler) +{ + app_tim_id_t id = p_params->id; + hal_status_t hal_err_code; + + if (NULL == p_params) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + p_tim_env[id] = &p_params->tim_env; + + soc_register_nvic(TIMER0_IRQn, (uint32_t)TIMER0_IRQHandler); + soc_register_nvic(TIMER1_IRQn, (uint32_t)TIMER1_IRQHandler); + hal_nvic_clear_pending_irq(s_tim_irq[id]); + hal_nvic_enable_irq(s_tim_irq[id]); + + p_tim_env[id]->evt_handler = evt_handler; + + memcpy(&p_tim_env[id]->handle.init, &p_params->init, sizeof(timer_init_t)); + p_tim_env[id]->handle.p_instance = (timer_regs_t *)s_tim_instance[id]; +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + hal_err_code = hal_timer_deinit(&p_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + hal_err_code = hal_timer_init(&p_tim_env[id]->handle); +#else + hal_err_code = hal_timer_base_deinit(&p_tim_env[id]->handle); + HAL_ERR_CODE_CHECK(hal_err_code); + hal_err_code = hal_timer_base_init(&p_tim_env[id]->handle); +#endif + HAL_ERR_CODE_CHECK(hal_err_code); + + if(s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_tim_pwr_id = pwr_register_sleep_cb(&tim_sleep_cb, APP_DRIVER_TIM_WAPEUP_PRIORITY); + + if (s_tim_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_tim_env[id]->tim_state = APP_TIM_ACTIVITY; + + return APP_DRV_SUCCESS; +} + +uint16_t app_tim_deinit(app_tim_id_t id) +{ + uint8_t i; + hal_status_t hal_err_code; + + if (id >= APP_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + + hal_nvic_disable_irq(s_tim_irq[id]); + p_tim_env[id]->tim_state = APP_TIM_INVALID; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_TIM_ID_MAX; i++) + { + if (p_tim_env[i] != NULL && (p_tim_env[i]->tim_state) != APP_TIM_INVALID) + { + break; + } + } + if (APP_TIM_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_tim_pwr_id); + s_tim_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + hal_err_code = hal_timer_deinit(&p_tim_env[id]->handle); +#else + hal_err_code = hal_timer_base_deinit(&p_tim_env[id]->handle); +#endif + HAL_ERR_CODE_CHECK(hal_err_code); + p_tim_env[id] = NULL; + + return APP_DRV_SUCCESS; +} + +uint16_t app_tim_start(app_tim_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + tim_wake_up(id); +#endif + + #if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + err_code = hal_timer_start_it(&p_tim_env[id]->handle); + #else + err_code = hal_timer_base_start_it(&p_tim_env[id]->handle); + #endif + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_tim_stop(app_tim_id_t id) +{ + hal_status_t err_code; + + if (id >= APP_TIM_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + tim_wake_up(id); +#endif + + #if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) + err_code = hal_timer_stop_it(&p_tim_env[id]->handle); + #else + err_code = hal_timer_base_stop_it(&p_tim_env[id]->handle); + #endif + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +timer_handle_t *app_tim_get_handle(app_tim_id_t id) +{ + if (id >= APP_TIM_ID_MAX) + { + return NULL; + } + + if ((p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + tim_wake_up(id); +#endif + + return &p_tim_env[id]->handle; +} + +void hal_timer_period_elapsed_callback(timer_handle_t *p_timer) +{ + app_tim_event_call(p_timer, APP_TIM_EVT_DONE); +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5332X) +void hal_timer_channel0_event_callback(timer_handle_t *p_timer) +{ + app_tim_event_call(p_timer, APP_TIM_EVT_CHANNEL0); +} + +void hal_timer_channel1_event_callback(timer_handle_t *p_timer) +{ + app_tim_event_call(p_timer, APP_TIM_EVT_CHANNEL1); +} + +void hal_timer_channel2_event_callback(timer_handle_t *p_timer) +{ + app_tim_event_call(p_timer, APP_TIM_EVT_CHANNEL2); +} + +void hal_timer_channel3_event_callback(timer_handle_t *p_timer) +{ + app_tim_event_call(p_timer, APP_TIM_EVT_CHANNEL3); +} + +uint32_t app_tim_get_channel0_val(app_tim_id_t id) +{ + if ((id >= APP_TIM_ID_MAX) || (p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return 0; + } + + return hal_timer_get_channel0_val(&p_tim_env[id]->handle); +} + +uint32_t app_tim_get_channel1_val(app_tim_id_t id) +{ + if ((id >= APP_TIM_ID_MAX) || (p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return 0; + } + + return hal_timer_get_channel1_val(&p_tim_env[id]->handle); +} + +uint32_t app_tim_get_channel2_val(app_tim_id_t id) +{ + if ((id >= APP_TIM_ID_MAX) || (p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return 0; + } + + return hal_timer_get_channel2_val(&p_tim_env[id]->handle); +} + +uint32_t app_tim_get_channel3_val(app_tim_id_t id) +{ + if ((id >= APP_TIM_ID_MAX) || (p_tim_env[id] == NULL) || (p_tim_env[id]->tim_state == APP_TIM_INVALID)) + { + return 0; + } + + return hal_timer_get_channel3_val(&p_tim_env[id]->handle); +} +#endif + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart.c new file mode 100644 index 0000000..dfa3c22 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart.c @@ -0,0 +1,869 @@ +/** + **************************************************************************************** + * @file app_uart.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "app_uart.h" +#include "app_uart_dma.h" +#include "app_drv.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" +#include "gr_soc.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define APP_UART_CALLBACK(id, evt) \ + do \ + { \ + if (p_uart_env[id]->evt_handler != NULL) \ + { \ + p_uart_env[id]->evt_handler(&evt); \ + } \ + } while(0) + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +typedef struct { + app_uart_id_t id; + IRQn_Type irq; + uart_regs_t *instance; +} uart_info_t; + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ +static bool uart_prepare_for_sleep(void); +static void uart_wake_up_ind(void); +void UART0_IRQHandler(void); +void UART1_IRQHandler(void); +void UART2_IRQHandler(void); +void UART3_IRQHandler(void); +void UART4_IRQHandler(void); +void UART5_IRQHandler(void); + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const uart_info_t s_uart_info[APP_UART_ID_MAX] = { + { + .id = APP_UART_ID_0, + .irq = UART0_IRQn, + .instance = UART0, + }, + { + .id = APP_UART_ID_1, + .irq = UART1_IRQn, + .instance = UART1, + }, +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) | (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) + { + .id = APP_UART_ID_2, + .irq = UART2_IRQn, + .instance = UART2, + }, + { + .id = APP_UART_ID_3, + .irq = UART3_IRQn, + .instance = UART3, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + { + .id = APP_UART_ID_4, + .irq = UART4_IRQn, + .instance = UART4, + }, + { + .id = APP_UART_ID_5, + .irq = UART5_IRQn, + .instance = UART5, + }, +#endif +}; + +uart_env_t *p_uart_env[APP_UART_ID_MAX]; +static bool s_sleep_cb_registered_flag = false; +static pwr_id_t s_uart_pwr_id; +static const app_sleep_callbacks_t uart_sleep_cb = +{ + .app_prepare_for_sleep = uart_prepare_for_sleep, + .app_sleep_canceled = NULL, + .app_wake_up_ind = uart_wake_up_ind, +}; + +/* + * LOCAL FUNCTION DEFINITIONS + ***************************************************************************************** + */ +static bool uart_prepare_for_sleep(void) +{ + hal_uart_state_t state; + + for (uint8_t i = 0; i < APP_UART_ID_MAX; i++) + { + if (p_uart_env[i] == NULL) + { + continue; + } + + if (p_uart_env[i]->uart_state == APP_UART_ACTIVITY) + { + state = hal_uart_get_state(&p_uart_env[i]->handle); + if ((state != HAL_UART_STATE_RESET) && (state != HAL_UART_STATE_READY)) + { + return false; + } + + GLOBAL_EXCEPTION_DISABLE(); + hal_uart_suspend_reg(&p_uart_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + p_uart_env[i]->uart_state = APP_UART_SLEEP; +#endif + } + } + return true; +} + +SECTION_RAM_CODE static void uart_wake_up_ind(void) +{ +#ifndef APP_DRIVER_WAKEUP_CALL_FUN + uint8_t i; + + for (i = 0; i < APP_UART_ID_MAX; i++) + { + if (p_uart_env[i] == NULL) + { + continue; + } + + if (p_uart_env[i]->uart_state == APP_UART_ACTIVITY) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_uart_resume_reg(&p_uart_env[i]->handle); + GLOBAL_EXCEPTION_ENABLE(); + hal_nvic_clear_pending_irq(s_uart_info[i].irq); + hal_nvic_enable_irq(s_uart_info[i].irq); + } + } +#endif +} + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +void uart_wake_up(app_uart_id_t id) +{ + if (p_uart_env[id]->uart_state == APP_UART_SLEEP) + { + GLOBAL_EXCEPTION_DISABLE(); + hal_uart_resume_reg(&p_uart_env[id]->handle); + GLOBAL_EXCEPTION_ENABLE(); + + hal_nvic_clear_pending_irq(s_uart_info[id].irq); + hal_nvic_enable_irq(s_uart_info[id].irq); + + p_uart_env[id]->uart_state = APP_UART_ACTIVITY; + } + + dma_wake_up(p_uart_env[id]->dma_id[0]); + dma_wake_up(p_uart_env[id]->dma_id[1]); +} +#endif + +__WEAK uint16_t app_uart_dma_start_transmit_async(app_uart_id_t id) +{ + return 0; +}; + +static app_uart_id_t uart_get_id(uart_handle_t *p_uart) +{ + int i = 0; + + for (i = 0; i < APP_UART_ID_MAX; i++) + { + if (p_uart->p_instance == s_uart_info[i].instance) + { + return s_uart_info[i].id; + } + } + + return APP_UART_ID_MAX; +} + +static uint16_t uart_gpio_config(uint32_t hw_flow_ctrl, app_uart_pin_cfg_t pin_cfg) +{ + app_io_init_t io_init = APP_IO_DEFAULT_CONFIG; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + io_init.pull = pin_cfg.tx.pull; + io_init.mode = APP_IO_MODE_MUX; + io_init.pin = pin_cfg.tx.pin; + io_init.mux = pin_cfg.tx.mux; + err_code = app_io_init(pin_cfg.tx.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.rx.pull; + io_init.pin = pin_cfg.rx.pin; + io_init.mux = pin_cfg.rx.mux; + err_code = app_io_init(pin_cfg.rx.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + if (UART_HWCONTROL_RTS_CTS == hw_flow_ctrl) + { + io_init.pull = pin_cfg.cts.pull; + io_init.pin = pin_cfg.cts.pin; + io_init.mux = pin_cfg.cts.mux; + err_code = app_io_init(pin_cfg.cts.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + + io_init.pull = pin_cfg.rts.pull; + io_init.pin = pin_cfg.rts.pin; + io_init.mux = pin_cfg.rts.mux; + err_code = app_io_init(pin_cfg.rts.type, &io_init); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + return err_code; +} + +static uint16_t app_uart_start_transmit_async(app_uart_id_t id) +{ + uint16_t items_count = ring_buffer_items_count_get(&p_uart_env[id]->tx_ring_buffer); + uint16_t send_size = items_count; + hal_status_t err_code; + + if ((items_count == 0) || (p_uart_env[id]->start_flush_flag == true)) + { + p_uart_env[id]->start_tx_flag = false; + return APP_DRV_SUCCESS; + } + + if (items_count >= TX_ONCE_MAX_SIZE) + { + ring_buffer_read(&p_uart_env[id]->tx_ring_buffer, p_uart_env[id]->tx_send_buf, TX_ONCE_MAX_SIZE); + send_size = TX_ONCE_MAX_SIZE; + } + else + { + ring_buffer_read(&p_uart_env[id]->tx_ring_buffer, p_uart_env[id]->tx_send_buf, items_count); + } + + p_uart_env[id]->is_dma_tx_mode = false; + err_code = hal_uart_transmit_it(&p_uart_env[id]->handle, p_uart_env[id]->tx_send_buf, send_size); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +uint16_t app_uart_init(app_uart_params_t *p_params, app_uart_evt_handler_t evt_handler, app_uart_tx_buf_t *tx_buffer) +{ + app_uart_id_t id = p_params->id; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if ((p_params == NULL) || (tx_buffer == NULL)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + p_uart_env[id] = &(p_params->uart_dev); + ring_buffer_init(&p_uart_env[id]->tx_ring_buffer, tx_buffer->tx_buf, tx_buffer->tx_buf_size); + + err_code = uart_gpio_config(p_params->init.hw_flow_ctrl, p_params->pin_cfg); + APP_DRV_ERR_CODE_CHECK(err_code); + + soc_register_nvic(UART0_IRQn, (uint32_t)UART0_IRQHandler); + soc_register_nvic(UART1_IRQn, (uint32_t)UART1_IRQHandler); +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + soc_register_nvic(UART2_IRQn, (uint32_t)UART2_IRQHandler); + soc_register_nvic(UART3_IRQn, (uint32_t)UART3_IRQHandler); +#endif + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + soc_register_nvic(UART4_IRQn, (uint32_t)UART4_IRQHandler); + soc_register_nvic(UART5_IRQn, (uint32_t)UART5_IRQHandler); +#endif + hal_nvic_clear_pending_irq(s_uart_info[id].irq); + hal_nvic_enable_irq(s_uart_info[id].irq); + + p_uart_env[id]->p_pin_cfg = &p_params->pin_cfg; + p_uart_env[id]->evt_handler = evt_handler; + + memcpy(&p_uart_env[id]->handle.init, &p_params->init, sizeof(uart_init_t)); + p_uart_env[id]->handle.p_instance = s_uart_info[id].instance; + + hal_uart_deinit(&p_uart_env[id]->handle); + hal_uart_init(&p_uart_env[id]->handle); + + if (s_sleep_cb_registered_flag == false)// register sleep callback + { + s_sleep_cb_registered_flag = true; + s_uart_pwr_id = pwr_register_sleep_cb(&uart_sleep_cb, APP_DRIVER_UART_WAPEUP_PRIORITY); + + if (s_uart_pwr_id < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + } + + p_uart_env[id]->uart_state = APP_UART_ACTIVITY; + p_uart_env[id]->start_tx_flag = false; + p_uart_env[id]->start_flush_flag = false; + p_uart_env[id]->tx_abort_flag = false; + p_uart_env[id]->rx_abort_flag = false; + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_deinit(app_uart_id_t id) +{ + uint8_t i; + app_drv_err_t err_code = APP_DRV_SUCCESS; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + err_code = app_io_deinit(p_uart_env[id]->p_pin_cfg->tx.type, p_uart_env[id]->p_pin_cfg->tx.pin); + APP_DRV_ERR_CODE_CHECK(err_code); + + err_code = app_io_deinit(p_uart_env[id]->p_pin_cfg->rx.type, p_uart_env[id]->p_pin_cfg->rx.pin); + APP_DRV_ERR_CODE_CHECK(err_code); + + if (UART_HWCONTROL_RTS_CTS == p_uart_env[id]->handle.init.hw_flow_ctrl) + { + err_code = app_io_deinit(p_uart_env[id]->p_pin_cfg->rts.type, p_uart_env[id]->p_pin_cfg->rts.pin); + APP_DRV_ERR_CODE_CHECK(err_code); + + err_code = app_io_deinit(p_uart_env[id]->p_pin_cfg->cts.type, p_uart_env[id]->p_pin_cfg->cts.pin); + APP_DRV_ERR_CODE_CHECK(err_code); + } + + hal_nvic_disable_irq(s_uart_info[id].irq); + + p_uart_env[id]->uart_state = APP_UART_INVALID; + p_uart_env[id]->start_tx_flag = false; + p_uart_env[id]->start_flush_flag = false; + p_uart_env[id]->tx_abort_flag = false; + p_uart_env[id]->rx_abort_flag = false; + + GLOBAL_EXCEPTION_DISABLE(); + for (i = 0; i < APP_UART_ID_MAX; i++) + { + if (p_uart_env[i] != NULL && (p_uart_env[i]->uart_state) != APP_UART_INVALID) + { + break; + } + } + if (APP_UART_ID_MAX == i) + { + pwr_unregister_sleep_cb(s_uart_pwr_id); + s_uart_pwr_id = -1; + s_sleep_cb_registered_flag = false; + } + GLOBAL_EXCEPTION_ENABLE(); + + hal_uart_deinit(&p_uart_env[id]->handle); + if (p_uart_env[id]->uart_dma_state == APP_UART_DMA_INVALID) + { + p_uart_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_receive_async(app_uart_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 ) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + if (p_uart_env[id]->rx_abort_flag == true) + { + p_uart_env[id]->rx_abort_flag = false; + /* Clear rx_fifo */ + ll_uart_flush_rx_fifo(p_uart_env[id]->handle.p_instance); + /* Clear TIMEOUT interrupt flag bit */ + ll_uart_receive_data8(p_uart_env[id]->handle.p_instance); + } + + err_code = hal_uart_receive_it(&p_uart_env[id]->handle, p_data, size); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_receive_sync(app_uart_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 ) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + if (p_uart_env[id]->rx_abort_flag == true) + { + p_uart_env[id]->rx_abort_flag = false; + /* Clear rx_fifo */ + ll_uart_flush_rx_fifo(p_uart_env[id]->handle.p_instance); + /* Clear TIMEOUT interrupt flag bit */ + ll_uart_receive_data8(p_uart_env[id]->handle.p_instance); + } + err_code = hal_uart_receive(&p_uart_env[id]->handle, p_data, size, timeout); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_transmit_async(app_uart_id_t id, uint8_t *p_data, uint16_t size) +{ + uint16_t err_code; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 ) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + p_uart_env[id]->tx_abort_flag = false; + ring_buffer_write(&p_uart_env[id]->tx_ring_buffer, p_data, size); + + if ((p_uart_env[id]->start_tx_flag == false) && (p_uart_env[id]->start_flush_flag == false) && + (p_uart_env[id]->uart_state == APP_UART_ACTIVITY)) + { + p_uart_env[id]->start_tx_flag = true; + + err_code = app_uart_start_transmit_async(id); + if (err_code != APP_DRV_SUCCESS) + { + p_uart_env[id]->start_tx_flag = false; + return err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_transmit_sync(app_uart_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout) +{ + hal_status_t err_code; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 ) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + p_uart_env[id]->tx_abort_flag = false; + err_code = hal_uart_transmit(&p_uart_env[id]->handle, p_data, size, timeout); + if (err_code != HAL_OK) + { + return err_code; + } + + return APP_DRV_SUCCESS; +} + +uart_handle_t *app_uart_get_handle(app_uart_id_t id) +{ + if (id >= APP_UART_ID_MAX) + { + return NULL; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + return &p_uart_env[id]->handle; +} + +void app_uart_flush(app_uart_id_t id) +{ + uint16_t items_count; + uart_handle_t *p_uart = &p_uart_env[id]->handle; + + if (APP_UART_ID_MAX <= id || p_uart_env[id]->uart_state == APP_UART_INVALID) + { + return; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + if (p_uart_env[id]->uart_state == APP_UART_ACTIVITY) + { + p_uart_env[id]->start_flush_flag = true; + + uint16_t tx_xfer_size = 0; + uint16_t tx_xfer_count = 0; + uint32_t tx_wait_count = 0; + uint32_t data_width = 1 + p_uart_env[id]->handle.init.data_bits + 5 + + p_uart_env[id]->handle.init.stop_bits + 1 + + (p_uart_env[id]->handle.init.parity & 1); + + while(!ll_uart_is_active_flag_tfe(p_uart_env[id]->handle.p_instance)); + + if (p_uart_env[id]->is_dma_tx_mode == false) + { + tx_xfer_size = p_uart_env[id]->handle.tx_xfer_size; + tx_xfer_count = p_uart_env[id]->handle.tx_xfer_count; + hal_uart_abort_transmit_it(&p_uart_env[id]->handle); + hal_uart_transmit(&p_uart_env[id]->handle, + p_uart_env[id]->tx_send_buf + tx_xfer_size - tx_xfer_count, + tx_xfer_count, + 5000); + } + else + { + do + { + tx_wait_count++; + } + while ((HAL_UART_STATE_READY != p_uart_env[id]->handle.tx_state) && + (tx_wait_count <= data_width * TX_ONCE_MAX_SIZE * (SystemCoreClock/p_uart_env[id]->handle.init.baud_rate))); + } + + do{ + items_count = ring_buffer_items_count_get(&p_uart_env[id]->tx_ring_buffer); + while(items_count) + { + uint8_t send_char; + + ring_buffer_read(&p_uart_env[id]->tx_ring_buffer, &send_char, 1); + + while(!ll_uart_is_active_flag_tfnf(p_uart_env[id]->handle.p_instance)); + + ll_uart_transmit_data8(p_uart_env[id]->handle.p_instance, send_char); + + items_count--; + } + } while(ring_buffer_items_count_get(&p_uart_env[id]->tx_ring_buffer)); + + while((HAL_IS_BIT_SET(p_uart->p_instance->LSR, LL_UART_LSR_TEMT) ? SET : RESET) == RESET); + + GLOBAL_EXCEPTION_DISABLE(); + if(ring_buffer_items_count_get(&p_uart_env[id]->tx_ring_buffer)) + { + /* Enable the UART Transmit Data Register Empty Interrupt */ + __HAL_UART_ENABLE_IT(p_uart, UART_IT_THRE); + } + + p_uart_env[id]->start_flush_flag = false; + GLOBAL_EXCEPTION_ENABLE(); + } +} + +uint16_t app_uart_abort(app_uart_id_t id) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + ring_buffer_clean(&p_uart_env[id]->tx_ring_buffer); + + err_code = hal_uart_abort_it(&p_uart_env[id]->handle); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + p_uart_env[id]->tx_abort_flag = true; + p_uart_env[id]->rx_abort_flag = true; + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_abort_transmit(app_uart_id_t id) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + ring_buffer_clean(&p_uart_env[id]->tx_ring_buffer); + + err_code = hal_uart_abort_transmit_it(&p_uart_env[id]->handle); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + p_uart_env[id]->tx_abort_flag = true; + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_abort_receive(app_uart_id_t id) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + err_code = hal_uart_abort_receive_it(&p_uart_env[id]->handle); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + p_uart_env[id]->rx_abort_flag = true; + + return APP_DRV_SUCCESS; +} + +void hal_uart_tx_cplt_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_TX_CPLT; + uart_evt.data.size = p_uart->tx_xfer_size - p_uart->tx_xfer_count; + + if (p_uart_env[id]->is_dma_tx_mode) + { + app_uart_dma_start_transmit_async(id); + } + else + { + app_uart_start_transmit_async(id); + } + + if (p_uart_env[id]->start_tx_flag == false) + { + APP_UART_CALLBACK(id, uart_evt); + } +} + +void hal_uart_rx_cplt_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_RX_DATA; + uart_evt.data.size = p_uart->rx_xfer_size - p_uart->rx_xfer_count; + APP_UART_CALLBACK(id, uart_evt); +} + +void hal_uart_error_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_ERROR; + uart_evt.data.error_code = p_uart->error_code; + p_uart_env[id]->start_tx_flag = false; + APP_UART_CALLBACK(id, uart_evt); +} + +void hal_uart_abort_cplt_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_ABORT_TXRX; + p_uart_env[id]->start_tx_flag = false; + APP_UART_CALLBACK(id, uart_evt); +} + +void hal_uart_abort_tx_cplt_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_ABORT_TX; + p_uart_env[id]->start_tx_flag = false; + APP_UART_CALLBACK(id, uart_evt); +} + +void hal_uart_abort_rx_cplt_callback(uart_handle_t *p_uart) +{ + app_uart_evt_t uart_evt; + app_uart_id_t id = uart_get_id(p_uart); + + uart_evt.type = APP_UART_EVT_ABORT_RX; + p_uart_env[id]->start_tx_flag = false; + APP_UART_CALLBACK(id, uart_evt); +} + +#define UART_HANDLER(index, val) \ +void UART##index##_IRQHandler(void)\ +{\ + hal_uart_irq_handler(&p_uart_env[val]->handle);\ +} + +UART_HANDLER(0, APP_UART_ID_0) +UART_HANDLER(1, APP_UART_ID_1) +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) | (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) +UART_HANDLER(2, APP_UART_ID_2) +UART_HANDLER(3, APP_UART_ID_3) +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) +UART_HANDLER(4, APP_UART_ID_4) +UART_HANDLER(5, APP_UART_ID_5) +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart_dma.c b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart_dma.c new file mode 100644 index 0000000..d90e34c --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/drivers/src/app_uart_dma.c @@ -0,0 +1,564 @@ +/** + **************************************************************************************** + * @file app_uart_dma.c + * @author BLE Driver Team + * @brief HAL APP module driver. + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + **************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include +#include "app_uart.h" +#include "app_uart_dma.h" +#include "app_dma.h" +#include "app_pwr_mgmt.h" + +/* + * DEFINES + ***************************************************************************************** + */ +#define DMA_REQUEST_NULL (0x00) + +/* + * STRUCT DEFINE + ***************************************************************************************** + */ +struct dma_request { + uint32_t tx; + uint32_t rx; +}; + +typedef struct { + struct dma_request dma0_request; + struct dma_request dma1_request; +} uart_dma_info_t; + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static const uart_dma_info_t s_dma_info[APP_UART_ID_MAX] = { + { /* UART0 */ + .dma0_request = { + .tx = DMA0_REQUEST_UART0_TX, + .rx = DMA0_REQUEST_UART0_RX, + }, +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + .dma1_request = { + .tx = DMA1_REQUEST_UART0_TX, + .rx = DMA1_REQUEST_UART0_RX, + }, +#endif + }, + { /* UART1 */ +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR551X) + .dma0_request = { + .tx = DMA0_REQUEST_UART1_TX, + .rx = DMA0_REQUEST_UART1_RX, + }, +#else + .dma0_request = { + .tx = 0, + .rx = 0, + }, +#endif + }, +#if ((APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X)) + { /* UART2 */ + .dma0_request = { + .tx = DMA0_REQUEST_UART2_TX, + .rx = DMA0_REQUEST_UART2_RX, + }, + }, + { /* UART3 */ + .dma0_request = { + .tx = DMA0_REQUEST_UART3_TX, + .rx = DMA0_REQUEST_UART3_RX, + }, + .dma1_request = { + .tx = DMA1_REQUEST_UART3_TX, + .rx = DMA1_REQUEST_UART3_RX, + }, + }, +#endif +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) + { /* UART4 */ + .dma0_request = { + .tx = DMA0_REQUEST_UART4_TX, + .rx = DMA0_REQUEST_UART4_RX, + }, + .dma1_request = { + .tx = DMA1_REQUEST_UART4_TX, + .rx = DMA1_REQUEST_UART4_RX, + }, + }, + { /* UART5 */ + .dma1_request = { + .tx = DMA1_REQUEST_UART5_TX, + .rx = DMA1_REQUEST_UART5_RX, + }, + }, +#endif +}; + +extern uart_env_t *p_uart_env[APP_UART_ID_MAX]; +#ifdef APP_DRIVER_WAKEUP_CALL_FUN +extern void uart_wake_up(app_uart_id_t id); +#endif + +/* + * LOCAL FUNCTION DECLARATION + ***************************************************************************************** + */ + +static uint16_t app_uart_config_dma_tx(app_uart_params_t *p_params) +{ + app_dma_params_t tx_dma_params = { 0 }; + + tx_dma_params.p_instance = p_params->dma_cfg.tx_dma_instance; + tx_dma_params.channel_number = p_params->dma_cfg.tx_dma_channel; + if (tx_dma_params.p_instance == DMA0) + { + tx_dma_params.init.src_request = DMA0_REQUEST_MEM; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (tx_dma_params.p_instance == DMA1) + { + tx_dma_params.init.src_request = DMA1_REQUEST_MEM; + } +#endif + + if (tx_dma_params.p_instance == DMA0) + { + tx_dma_params.init.dst_request = s_dma_info[p_params->id].dma0_request.tx; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (tx_dma_params.p_instance == DMA1) + { + tx_dma_params.init.dst_request = s_dma_info[p_params->id].dma1_request.tx; + } +#endif + + if (tx_dma_params.init.dst_request == DMA_REQUEST_NULL) + { + return APP_DRV_ERR_INVALID_MODE; + } + + tx_dma_params.init.direction = DMA_MEMORY_TO_PERIPH; + tx_dma_params.init.src_increment = DMA_SRC_INCREMENT; + tx_dma_params.init.dst_increment = DMA_DST_NO_CHANGE; + tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + tx_dma_params.init.mode = DMA_NORMAL; +#endif + tx_dma_params.init.priority = DMA_PRIORITY_LOW; + p_uart_env[p_params->id]->dma_id[0] = app_dma_init(&tx_dma_params, NULL); + + if (p_uart_env[p_params->id]->dma_id[0] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + /* Associate the initialized DMA handle to the UART handle */ + p_uart_env[p_params->id]->handle.p_dmatx = app_dma_get_handle(p_uart_env[p_params->id]->dma_id[0]); + p_uart_env[p_params->id]->handle.p_dmatx->p_parent = (void*)&p_uart_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_uart_config_dma_rx(app_uart_params_t *p_params) +{ + app_dma_params_t rx_dma_params = { 0 }; + + rx_dma_params.p_instance = p_params->dma_cfg.rx_dma_instance; + rx_dma_params.channel_number = p_params->dma_cfg.rx_dma_channel; + if (rx_dma_params.p_instance == DMA0) + { + rx_dma_params.init.src_request = s_dma_info[p_params->id].dma0_request.rx; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (rx_dma_params.p_instance == DMA1) + { + rx_dma_params.init.src_request = s_dma_info[p_params->id].dma1_request.rx; + } +#endif + + if (rx_dma_params.init.src_request == DMA_REQUEST_NULL) + { + return APP_DRV_ERR_INVALID_MODE; + } + + if (rx_dma_params.p_instance == DMA0) + { + rx_dma_params.init.dst_request = DMA0_REQUEST_MEM; + } +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) + else if (rx_dma_params.p_instance == DMA1) + { + rx_dma_params.init.dst_request = DMA1_REQUEST_MEM; + } +#endif + + rx_dma_params.init.direction = DMA_PERIPH_TO_MEMORY; + rx_dma_params.init.src_increment = DMA_SRC_NO_CHANGE; + rx_dma_params.init.dst_increment = DMA_DST_INCREMENT; + rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE; + rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE; +#if (APP_DRIVER_CHIP_TYPE != APP_DRIVER_GR5332X) + rx_dma_params.init.mode = DMA_NORMAL; +#endif + rx_dma_params.init.priority = DMA_PRIORITY_HIGH; + p_uart_env[p_params->id]->dma_id[1] = app_dma_init(&rx_dma_params, NULL); + + if (p_uart_env[p_params->id]->dma_id[1] < 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + /* Associate the initialized DMA handle to the the UART handle */ + p_uart_env[p_params->id]->handle.p_dmarx = app_dma_get_handle(p_uart_env[p_params->id]->dma_id[1]); + p_uart_env[p_params->id]->handle.p_dmarx->p_parent = (void*)&p_uart_env[p_params->id]->handle; + + return APP_DRV_SUCCESS; +} + +static uint16_t app_uart_config_dma(app_uart_params_t *p_params) +{ + app_drv_err_t app_err_code = APP_DRV_SUCCESS; + + p_uart_env[p_params->id]->dma_id[0] = -1; + p_uart_env[p_params->id]->dma_id[1] = -1; + + if (p_params->dma_cfg.tx_dma_instance == NULL && + p_params->dma_cfg.rx_dma_instance == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + + if (p_params->dma_cfg.tx_dma_instance != NULL) + { + app_err_code = app_uart_config_dma_tx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + if (p_params->dma_cfg.rx_dma_instance != NULL) + { + app_err_code = app_uart_config_dma_rx(p_params); + if (app_err_code != APP_DRV_SUCCESS) + { + return app_err_code; + } + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_dma_init(app_uart_params_t *p_params) +{ + app_uart_id_t id = p_params->id; + app_drv_err_t err_code; + + if (p_params == NULL) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_NOT_INIT; + } + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR551X) + if (id == APP_UART_ID_1) + { + return APP_DRV_ERR_INVALID_ID; + } +#endif + + if (p_uart_env[id]->uart_dma_state == APP_UART_DMA_ACTIVITY) + { + app_uart_dma_deinit(id); + } + + GLOBAL_EXCEPTION_DISABLE(); + err_code = app_uart_config_dma(p_params); + if (err_code != APP_DRV_SUCCESS) + { + goto __exit; + } + p_uart_env[id]->uart_dma_state = APP_UART_DMA_ACTIVITY; + +__exit: + GLOBAL_EXCEPTION_ENABLE(); + + return err_code; +} + +uint16_t app_uart_dma_deinit(app_uart_id_t id) +{ + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || + (p_uart_env[id]->uart_dma_state != APP_UART_DMA_ACTIVITY)) + { + return APP_DRV_ERR_NOT_INIT; + } + + app_dma_deinit(p_uart_env[id]->dma_id[0]); + app_dma_deinit(p_uart_env[id]->dma_id[1]); + + GLOBAL_EXCEPTION_DISABLE(); + p_uart_env[id]->uart_dma_state = APP_UART_DMA_INVALID; + GLOBAL_EXCEPTION_ENABLE(); + + if (p_uart_env[id]->uart_state == APP_UART_INVALID) + { + p_uart_env[id] = NULL; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_dma_receive_async(app_uart_id_t id, uint8_t *p_data, uint16_t size) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + if (p_uart_env[id]->rx_abort_flag == true) + { + p_uart_env[id]->rx_abort_flag = false; + /* Clear rx_fifo */ + ll_uart_flush_rx_fifo(p_uart_env[id]->handle.p_instance); + /* Clear TIMEOUT interrupt flag bit */ + ll_uart_receive_data8(p_uart_env[id]->handle.p_instance); + } + + err_code = hal_uart_receive_dma(&p_uart_env[id]->handle, p_data, size); + APP_DRV_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_dma_start_transmit_async(app_uart_id_t id) +{ + uint16_t items_count = ring_buffer_items_count_get(&p_uart_env[id]->tx_ring_buffer); + uint16_t send_size = items_count; + hal_status_t err_code; + + if ((items_count == 0) || (p_uart_env[id]->start_flush_flag == true)) + { + p_uart_env[id]->start_tx_flag = false; + return APP_DRV_SUCCESS; + } + + p_uart_env[id]->is_dma_tx_mode = true; + if (items_count >= TX_ONCE_MAX_SIZE) + { + ring_buffer_read(&p_uart_env[id]->tx_ring_buffer, p_uart_env[id]->tx_send_buf, TX_ONCE_MAX_SIZE); + send_size = TX_ONCE_MAX_SIZE; + } + else + { + ring_buffer_read(&p_uart_env[id]->tx_ring_buffer, p_uart_env[id]->tx_send_buf, items_count); + } + + err_code = hal_uart_transmit_dma(&p_uart_env[id]->handle, p_uart_env[id]->tx_send_buf, send_size); + HAL_ERR_CODE_CHECK(err_code); + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_dma_transmit_async(app_uart_id_t id, uint8_t *p_data, uint16_t size) +{ + uint16_t err_code; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + p_uart_env[id]->tx_abort_flag = false; + ring_buffer_write(&p_uart_env[id]->tx_ring_buffer, p_data, size); + + if ((p_uart_env[id]->start_tx_flag == false) && (p_uart_env[id]->start_flush_flag == false) && + (p_uart_env[id]->uart_state == APP_UART_ACTIVITY)) + { + p_uart_env[id]->start_tx_flag = true; + + err_code = app_uart_dma_start_transmit_async(id); + if (err_code != APP_DRV_SUCCESS) + { + p_uart_env[id]->start_tx_flag = false; + return err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +#if (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5526X) || (APP_DRIVER_CHIP_TYPE == APP_DRIVER_GR5525X) +uint16_t app_uart_transmit_dma_sg_llp(app_uart_id_t id, uint8_t *p_data, uint16_t size, dma_sg_llp_config_t *sg_llp_config) +{ + uint16_t err_code; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 || sg_llp_config == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + p_uart_env[id]->tx_abort_flag = false; + app_uart_flush(id); + + if ((p_uart_env[id]->start_tx_flag == false) && (p_uart_env[id]->start_flush_flag == false) && + (p_uart_env[id]->uart_state == APP_UART_ACTIVITY)) + { + p_uart_env[id]->start_tx_flag = true; + + err_code = hal_uart_transmit_dma_sg_llp(&p_uart_env[id]->handle, p_data, size, sg_llp_config); + if (err_code != APP_DRV_SUCCESS) + { + return err_code; + } + } + else + { + return APP_DRV_ERR_BUSY; + } + + return APP_DRV_SUCCESS; +} + +uint16_t app_uart_receive_dma_sg_llp(app_uart_id_t id, uint8_t *p_data, uint16_t size, dma_sg_llp_config_t *sg_llp_config) +{ + hal_status_t err_code = HAL_OK; + + if (id >= APP_UART_ID_MAX) + { + return APP_DRV_ERR_INVALID_ID; + } + + if ((p_uart_env[id] == NULL) || (p_uart_env[id]->uart_state == APP_UART_INVALID)) + { + return APP_DRV_ERR_POINTER_NULL; + } + + if (p_data == NULL || size == 0 || sg_llp_config == NULL) + { + return APP_DRV_ERR_INVALID_PARAM; + } + +#ifdef APP_DRIVER_WAKEUP_CALL_FUN + uart_wake_up(id); +#endif + + if (p_uart_env[id]->rx_abort_flag == true) + { + p_uart_env[id]->rx_abort_flag = false; + /* Clear rx_fifo */ + ll_uart_flush_rx_fifo(p_uart_env[id]->handle.p_instance); + /* Clear TIMEOUT interrupt flag bit */ + ll_uart_receive_data8(p_uart_env[id]->handle.p_instance); + } + + err_code = hal_uart_receive_dma_sg_llp(&p_uart_env[id]->handle, p_data, size, sg_llp_config); + if (err_code != HAL_OK) + { + return (uint16_t)err_code; + } + + return APP_DRV_SUCCESS; +} + +#endif + diff --git a/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/BUILD.gn new file mode 100644 index 0000000..a1a9a5e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ "." ] +} + +kernel_module("segger_rtt") { + sources = [ "SEGGER_RTT.c" ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.c b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.c new file mode 100644 index 0000000..493043b --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.c @@ -0,0 +1,1459 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* The Embedded Experts * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o 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. * +* * +* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.12a * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 4351 $ + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef MEMCPY + #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + +//SEGGER_RTT_CB _SEGGER_RTT __attribute__ ((at(0x2000a230))); + +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + NumBytesAtOnce = Rem; + memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + pRing->WrOff; + pRing->WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; //Alternatively: NumBytes = 0; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // + memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); + pRing->WrOff = WrOff + NumBytes; +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, Rem); + memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, depending on configuration, +* remaining characters may be dropped or RTT module waits until there is more space in the buffer. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFU; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = strlen(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.h b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.h new file mode 100644 index 0000000..31ac1a4 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT.h @@ -0,0 +1,248 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* The Embedded Experts * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o 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. * +* * +* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.12a * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 4351 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ diff --git a/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT_Conf.h b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..be11a5d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/external/segger_rtt/SEGGER_RTT_Conf.h @@ -0,0 +1,269 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* The Embedded Experts * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o 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. * +* * +* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.12a * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 4351 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 3) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 3) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } +#else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/BUILD.gn b/gr551x/sdk_liteos/gr551x_sdk/platform/BUILD.gn new file mode 100644 index 0000000..f47be32 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright (c) 2024 GOODIX. +# Licensed 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. + +import("//kernel/liteos_m/liteos.gni") + +config("public") { + include_dirs = [ + "arch/arm/cortex-m/cmsis/core/include", + "boards", + "include", + "soc/include", + ] +} + +kernel_module("platform") { + sources = [ + "arch/arm/cortex-m/gcc/startup_gr55xx.s", + "boards/board_SK.c", + "soc/common/gr_platform.c", + "soc/common/gr_system.c", + "soc/src/gr_soc.c", + ] +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_compiler.h b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_gcc.h b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_gcc.h new file mode 100644 index 0000000..67bda4e --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_gcc.h @@ -0,0 +1,2211 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.1 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_version.h b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_version.h new file mode 100644 index 0000000..8b4765f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/core_cm4.h b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/core_cm4.h new file mode 100644 index 0000000..e21cd14 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/mpu_armv7.h b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/mpu_armv7.h new file mode 100644 index 0000000..d9eedf8 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/cmsis/core/include/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/gcc/startup_gr55xx.s b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/gcc/startup_gr55xx.s new file mode 100644 index 0000000..2eec798 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/arch/arm/cortex-m/gcc/startup_gr55xx.s @@ -0,0 +1,218 @@ +/**************************************************************************//** + * @file startup_ARMCM4.s + * @brief CMSIS Core Device Startup File for + * ARMCM4 Device Series + * @version V5.00 + * @date 02. March 2016 + ******************************************************************************/ +/* + * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + + .syntax unified + .arch armv7-m + + .section .stack + .align 3 +//#ifdef __STACK_SIZE +// .equ Stack_Size, __STACK_SIZE +//#else + .equ Stack_Size, 0x00008000 +//#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0x00000100 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .vectors + .align 2 + .globl __Vectors +__Vectors: + .long _estack /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External interrupts */ + .long WDT_IRQHandler /* 0: Watchdog Timer */ + .long BLE_SDK_Handler /* 1: Reserved */ + .long BLE_IRQHandler /* 2: BLE */ + .long DMA0_IRQHandler /* 3: DMA0 */ + .long SPI_M_IRQHandler /* 4: SPI_M */ + .long SPI_S_IRQHandler /* 5: SPI_S */ + .long EXT0_IRQHandler /* 6: GPIO0 */ + .long EXT1_IRQHandler /* 7: GPIO1 */ + .long TIMER0_IRQHandler /* 8: TIMER0 */ + .long TIMER1_IRQHandler /* 9: TIMER1 */ + .long DUAL_TIMER_IRQHandler /* 10: DUAL_TIMER0/DUAL_TIMER1 */ + .long QSPI0_IRQHandler /* 11: QSPI0 */ + .long UART0_IRQHandler /* 12: UART0 */ + .long UART1_IRQHandler /* 13: UART1 */ + .long I2C0_IRQHandler /* 14: I2C0 */ + .long I2C1_IRQHandler /* 15: I2C1 */ + .long AES_IRQHandler /* 16: AES */ + .long HMAC_IRQHandler /* 17: HMAC */ + .long EXT2_IRQHandler /* 18: GPIO2 */ + .long RNG_IRQHandler /* 19: TRNG Interrupt */ + .long PMU_IRQHandler /* 20: PMU */ + .long PKC_IRQHandler /* 21: PKC */ + .long XQSPI_IRQHandler /* 22: XQSPI */ + .long QSPI1_IRQHandler /* 23: QSPI1 */ + .long PWR_CMD_IRQHandler /* 24: PWR_CMD */ + .long BLESLP_IRQHandler /* 25: BLE Sleep */ + .long SLPTIMER_IRQHandler /* 26: Sleep Timer */ + .long EXTWKUP_IRQHandler /* 27: EXT Wakeup */ + .long AON_WDT_IRQHandler /* 28: AON_WDT */ + .long I2S_M_IRQHandler /* 29: I2S_M */ + .long I2S_S_IRQHandler /* 30: I2S_S */ + .long ISO7816_IRQHandler /* 31: ISO7816 */ + .long PRESENT_IRQHandler /* 32: PRESENT */ + .long CALENDAR_IRQHandler /* 33: CALENDAR */ + .long COMM_CORE_IRQHandler /* 34: COMM_CORE */ + .long DMA1_IRQHandler /* 35: DMA1 */ + .long DMA2_IRQHandler /* 36: DMA2 */ + .long DSPI_IRQHandler /* 37: DSPI */ + .long AON_IRQHandler /* 38: AON */ + .long PDM_IRQHandler /* 39: PDM */ + .long VTTBL_IRQHandler /* 40: VTTBL */ + .long CTE_FULL_IRQHandler /* 41: CTE_FULL */ + .long USB_IRQHandler /* 42: USB */ + .long GPADC_IRQHandler /* 43: GPADC */ + .long AON_PMU_BOD_FEDGE_IRQHandler /* 44: AON_PMU_BOD_FEDGE */ + .long AON_PMU_MSIO_COMP_IRQHandler /* 45: AON_PMU_MSIO_COMP */ + .long AON_PMU_USB_WKUP_IRQHandler /* 46: AON_PMU_USB_WKUP */ + + .size __Vectors, . - __Vectors + + .text + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + bl SystemInit + + bl main_init + + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler MemManage_Handler + def_irq_handler BusFault_Handler + def_irq_handler UsageFault_Handler + def_irq_handler SVC_Handler + def_irq_handler DebugMon_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler WDT_IRQHandler + def_irq_handler DMA0_IRQHandler + def_irq_handler SPI_M_IRQHandler + def_irq_handler SPI_S_IRQHandler + def_irq_handler EXT0_IRQHandler + def_irq_handler EXT1_IRQHandler + def_irq_handler TIMER0_IRQHandler + def_irq_handler TIMER1_IRQHandler + def_irq_handler DUAL_TIMER_IRQHandler + def_irq_handler QSPI0_IRQHandler + def_irq_handler UART0_IRQHandler + def_irq_handler UART1_IRQHandler + def_irq_handler I2C0_IRQHandler + def_irq_handler I2C1_IRQHandler + def_irq_handler AES_IRQHandler + def_irq_handler HMAC_IRQHandler + def_irq_handler EXT2_IRQHandler + def_irq_handler RNG_IRQHandler + def_irq_handler PMU_IRQHandler + def_irq_handler PKC_IRQHandler + def_irq_handler XQSPI_IRQHandler + def_irq_handler QSPI1_IRQHandler + def_irq_handler PWR_CMD_IRQHandler + def_irq_handler SLPTIMER_IRQHandler + def_irq_handler EXTWKUP_IRQHandler + def_irq_handler AON_WDT_IRQHandler + def_irq_handler I2S_M_IRQHandler + def_irq_handler I2S_S_IRQHandler + def_irq_handler ISO7816_IRQHandler + def_irq_handler PRESENT_IRQHandler + def_irq_handler CALENDAR_IRQHandler + def_irq_handler COMM_CORE_IRQHandler + def_irq_handler DMA1_IRQHandler + def_irq_handler DMA2_IRQHandler + def_irq_handler DSPI_IRQHandler + def_irq_handler AON_IRQHandler + def_irq_handler PDM_IRQHandler + def_irq_handler VTTBL_IRQHandler + def_irq_handler CTE_FULL_IRQHandler + def_irq_handler USB_IRQHandler + def_irq_handler GPADC_IRQHandler + def_irq_handler AON_PMU_BOD_FEDGE_IRQHandler + def_irq_handler AON_PMU_MSIO_COMP_IRQHandler + def_irq_handler AON_PMU_USB_WKUP_IRQHandler + .end diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.c b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.c new file mode 100644 index 0000000..a585ac3 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.c @@ -0,0 +1,253 @@ + +/** + ***************************************************************************************** + * + * @file board.c + * + * @brief Board Support Package Implementation. + * + ***************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "grx_sys.h" +#include "app_log.h" +#include "app_assert.h" +#include "app_io.h" +#include "board_SK.h" +#if (APP_LOG_PORT == 1) +#include "SEGGER_RTT.h" +#endif + +#define UART_TX_BUFF_SIZE 0x400 /**< Size of app uart tx buffer. */ + +/* + * LOCAL VARIABLE DEFINITIONS + ***************************************************************************************** + */ +static uint8_t s_uart_tx_buffer[UART_TX_BUFF_SIZE]; +static app_uart_params_t uart_param; + +void bsp_uart_send(uint8_t *p_data, uint16_t length) +{ + app_uart_transmit_sync(APP_UART_ID, p_data, length, 1000); +} + +void bsp_uart_flush(void) +{ + app_uart_flush(APP_UART_ID); +} + +__WEAK void app_uart_evt_handler(app_uart_evt_t *p_evt) +{ + UNUSED(p_evt); +} + +void bsp_uart_init(void) +{ + app_uart_tx_buf_t uart_buffer; + + uart_buffer.tx_buf = s_uart_tx_buffer; + uart_buffer.tx_buf_size = UART_TX_BUFF_SIZE; + + uart_param.id = APP_UART_ID; + uart_param.init.baud_rate = APP_UART_BAUDRATE; + uart_param.init.data_bits = UART_DATABITS_8; + uart_param.init.stop_bits = UART_STOPBITS_1; + uart_param.init.parity = UART_PARITY_NONE; + uart_param.init.hw_flow_ctrl = UART_HWCONTROL_NONE; + uart_param.init.rx_timeout_mode = UART_RECEIVER_TIMEOUT_ENABLE; + uart_param.pin_cfg.rx.type = APP_UART_RX_IO_TYPE; + uart_param.pin_cfg.rx.pin = APP_UART_RX_PIN; + uart_param.pin_cfg.rx.mux = APP_UART_RX_PINMUX; + uart_param.pin_cfg.rx.pull = APP_UART_RX_PULL; + uart_param.pin_cfg.tx.type = APP_UART_TX_IO_TYPE; + uart_param.pin_cfg.tx.pin = APP_UART_TX_PIN; + uart_param.pin_cfg.tx.mux = APP_UART_TX_PINMUX; + uart_param.pin_cfg.tx.pull = APP_UART_TX_PULL; + + app_uart_init(&uart_param, app_uart_evt_handler, &uart_buffer); +} + +#if (APP_LOG_PORT == 1) +void bsp_segger_rtt_send(uint8_t *p_data, uint16_t length) +{ + SEGGER_RTT_Write(0, (void*)p_data, length); +} +#endif + +#if (APP_LOG_PORT == 2) +void bsp_itm_send(uint8_t *p_data, uint16_t length) +{ + for(uint16_t i = 0; i < length; i++) + { + ITM_SendChar(p_data[i]); + } +} +#endif + +void bsp_log_init(void) +{ +#if (APP_LOG_ENABLE == 1) + +#if (APP_LOG_PORT == 0) + bsp_uart_init(); +#elif (APP_LOG_PORT == 1) + SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); +#endif + +#if (APP_LOG_PORT <= 2) + app_log_init_t log_init; + + log_init.filter.level = APP_LOG_LVL_DEBUG; + log_init.fmt_set[APP_LOG_LVL_ERROR] = APP_LOG_FMT_ALL & (~APP_LOG_FMT_TAG); + log_init.fmt_set[APP_LOG_LVL_WARNING] = APP_LOG_FMT_LVL; + log_init.fmt_set[APP_LOG_LVL_INFO] = APP_LOG_FMT_LVL; + log_init.fmt_set[APP_LOG_LVL_DEBUG] = APP_LOG_FMT_LVL; + +#if (APP_LOG_PORT == 0) + app_log_init(&log_init, bsp_uart_send, bsp_uart_flush); +#elif (APP_LOG_PORT == 1) + app_log_init(&log_init, bsp_segger_rtt_send, NULL); +#elif (APP_LOG_PORT == 2) + app_log_init(&log_init, bsp_itm_send, NULL); +#endif + + app_assert_init(); + +#endif + +#endif +} + +__WEAK void app_key_evt_handler(uint8_t key_id, app_key_click_type_t key_click_type) +{ + UNUSED(key_id); + UNUSED(key_click_type); +} + +void bsp_key_init(void) +{ + app_key_gpio_t app_key_inst[5]; + + app_key_inst[0].gpio_type = APP_IO_TYPE_NORMAL; + app_key_inst[0].gpio_pin = APP_KEY_UP_PIN; + app_key_inst[0].trigger_mode = APP_KEY_TRIGGER_MODE; + app_key_inst[0].pull = APP_KEY_PULL_MODE; + app_key_inst[0].key_id = BSP_KEY_UP_ID; + + app_key_inst[1].gpio_type = APP_IO_TYPE_NORMAL; + app_key_inst[1].gpio_pin = APP_KEY_DOWN_PIN; + app_key_inst[1].trigger_mode = APP_KEY_TRIGGER_MODE; + app_key_inst[1].pull = APP_KEY_PULL_MODE; + app_key_inst[1].key_id = BSP_KEY_DOWN_ID; + + app_key_inst[2].gpio_type = APP_IO_TYPE_NORMAL; + app_key_inst[2].gpio_pin = APP_KEY_RIGHT_PIN; + app_key_inst[2].trigger_mode = APP_KEY_TRIGGER_MODE; + app_key_inst[2].pull = APP_KEY_PULL_MODE; + app_key_inst[2].key_id = BSP_KEY_RIGHT_ID; + + app_key_inst[3].gpio_type = APP_IO_TYPE_NORMAL; + app_key_inst[3].gpio_pin = APP_KEY_LEFT_PIN; + app_key_inst[3].trigger_mode = APP_KEY_TRIGGER_MODE; + app_key_inst[3].pull = APP_KEY_PULL_MODE; + app_key_inst[3].key_id = BSP_KEY_LEFT_ID; + + app_key_inst[4].gpio_type = APP_IO_TYPE_AON; + app_key_inst[4].gpio_pin = APP_KEY_OK_PIN; + app_key_inst[4].trigger_mode = APP_KEY_TRIGGER_MODE; + app_key_inst[4].pull = APP_KEY_PULL_MODE; + app_key_inst[4].key_id = BSP_KEY_OK_ID; + + app_key_init(app_key_inst, 5, app_key_evt_handler); +} + +void bsp_led_init(void) +{ + app_io_init_t io_init; + + io_init.pin = APP_LED_NUM_0_IO; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pull = APP_IO_PULLDOWN; + io_init.mux = APP_IO_MUX; + app_io_init(APP_IO_TYPE_NORMAL, &io_init); + + io_init.pin = APP_LED_NUM_1_IO; + io_init.mode = APP_IO_MODE_OUTPUT; + io_init.pull = APP_IO_PULLDOWN; + io_init.mux = APP_IO_MUX; + app_io_init(APP_IO_TYPE_MSIO, &io_init); +} + + +void bsp_led_open(bsp_led_num_t led_num) +{ + switch (led_num) + { + case BSP_LED_NUM_0: + app_io_write_pin(APP_IO_TYPE_NORMAL, APP_LED_NUM_0_IO, APP_IO_PIN_RESET); + break; + + case BSP_LED_NUM_1: + app_io_write_pin(APP_IO_TYPE_MSIO, APP_LED_NUM_1_IO, APP_IO_PIN_RESET); + break; + + default: + break; + } +} + +void bsp_led_close(bsp_led_num_t led_num) +{ + switch (led_num) + { + case BSP_LED_NUM_0: + app_io_write_pin(APP_IO_TYPE_NORMAL, APP_LED_NUM_0_IO, APP_IO_PIN_SET); + break; + + case BSP_LED_NUM_1: + app_io_write_pin(APP_IO_TYPE_MSIO, APP_LED_NUM_1_IO, APP_IO_PIN_SET); + break; + + default: + break; + } +} + +void board_init(void) +{ + bsp_log_init(); + bsp_led_init(); + bsp_key_init(); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.h b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.h new file mode 100644 index 0000000..821af2f --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/board_SK.h @@ -0,0 +1,342 @@ +/** + **************************************************************************************** + * + * @file board_SK.h + * + * @brief Board Start Kit Macro. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef __BOARD_SK_H__ +#define __BOARD_SK_H__ + +#include "app_key.h" +#include "app_uart.h" + +/*******HCI UART IO CONFIG***********************/ +#define APP_HCI_UART_ID APP_UART_ID_0 +#define APP_HCI_UART_FLOW_ON 0 +#define APP_HCI_UART_BAUDRATE 115200 +#define APP_HCI_UART_TRN_PORT APP_IO_TYPE_NORMAL +#define APP_HCI_UART_FLOW_PORT APP_IO_TYPE_NORMAL +#define APP_HCI_UART_TX_PIN APP_IO_PIN_10 +#define APP_HCI_UART_RX_PIN APP_IO_PIN_11 +#define APP_HCI_UART_CTS_PIN APP_IO_PIN_2 +#define APP_HCI_UART_RTS_PIN APP_IO_PIN_5 +#define APP_HCI_UART_TX_PINMUX APP_IO_MUX_2 +#define APP_HCI_UART_RX_PINMUX APP_IO_MUX_2 +#define APP_HCI_UART_CTS_PINMUX APP_IO_MUX_0 +#define APP_HCI_UART_RTS_PINMUX APP_IO_MUX_0 + +/*******UART DRIVER IO CONFIG*******************/ +#define APP_UART_ID APP_UART_ID_0 +#define APP_UART_BAUDRATE 115200 +#define APP_UART_TX_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_UART_RX_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_UART_TX_PIN APP_IO_PIN_10 +#define APP_UART_RX_PIN APP_IO_PIN_11 +#define APP_UART_TX_PINMUX APP_IO_MUX_2 +#define APP_UART_RX_PINMUX APP_IO_MUX_2 +#define APP_UART_TX_PULL APP_IO_PULLUP +#define APP_UART_RX_PULL APP_IO_PULLUP + +#define APP_UART1_ID APP_UART_ID_1 +#define APP_UART1_BAUDRATE 115200 +#define APP_UART1_TX_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_UART1_RX_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_UART1_TX_PIN APP_IO_PIN_30 +#define APP_UART1_RX_PIN APP_IO_PIN_26 +#define APP_UART1_TX_PINMUX APP_IO_MUX_1 +#define APP_UART1_RX_PINMUX APP_IO_MUX_1 + +/*******KEY DRIVER IO CONFIG********************/ +#define APP_KEY_OK_IO_TYPE APP_IO_TYPE_AON +#define APP_KEY_UP_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_KEY_DOWN_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_KEY_LEFT_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_KEY_RIGHT_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_KEY_OK_PIN APP_IO_PIN_1 +#define APP_KEY_UP_PIN APP_IO_PIN_12 +#define APP_KEY_DOWN_PIN APP_IO_PIN_13 +#define APP_KEY_LEFT_PIN APP_IO_PIN_14 +#define APP_KEY_RIGHT_PIN APP_IO_PIN_15 +#define APP_KEY_OK_MUX APP_IO_MUX_7 +#define APP_KEY_UP_MUX APP_IO_MUX_7 +#define APP_KEY_DOWN_MUX APP_IO_MUX_7 +#define APP_KEY_LEFT_MUX APP_IO_MUX_7 +#define APP_KEY_RIGHT_MUX APP_IO_MUX_7 + +/*******KEY TRIGGER & PULL MODE CONFIG*******************/ +#define APP_KEY_TRIGGER_MODE APP_IO_MODE_IT_FALLING +#define APP_KEY_PULL_MODE APP_IO_PULLUP + +/*******LED IO CONFIG FOR SK*********************/ +#define APP_LED_NUM_0_IO APP_IO_PIN_4 +#define APP_LED_NUM_1_IO MSIO_PIN_4 + +/*******ADC IO CONFIG***************************/ +#define APP_ADC_P_INPUT_PIN MSIO_PIN_0 +#define APP_ADC_P_INPUT_PIN_MUX APP_IO_MUX_7 +#define APP_ADC_N_INPUT_PIN MSIO_PIN_1 +#define APP_ADC_N_INPUT_PIN_MUX APP_IO_MUX_7 + +/*******COMP IO CONFIG***************************/ +#define APP_COMP_INPUT_PIN APP_IO_PIN_0 +#define APP_COMP_INPUT_PIN_MUX APP_IO_MUX_7 +#define APP_COMP_VREF_PIN APP_IO_PIN_1 +#define APP_COMP_VREF_PIN_MUX APP_IO_MUX_7 + +/*******I2C IO CONFIG***************************/ +#define APP_I2C_MASTER_ID APP_I2C_ID_1 +#define APP_I2C_MASTER_SCL_PIN APP_IO_PIN_30 +#define APP_I2C_MASTER_SDA_PIN APP_IO_PIN_26 +#define APP_I2C_MASTER_SCL_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2C_MASTER_SDA_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2C_MASTER_SCL_PINMUX APP_IO_MUX_0 +#define APP_I2C_MASTER_SDA_PINMUX APP_IO_MUX_0 + +#define APP_I2C_SLAVE_ID APP_I2C_ID_1 +#define APP_I2C_SLAVE_SCL_PIN APP_IO_PIN_30 +#define APP_I2C_SLAVE_SDA_PIN APP_IO_PIN_26 +#define APP_I2C_SLAVE_SCL_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2C_SLAVE_SDA_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2C_SLAVE_SCL_PINMUX APP_IO_MUX_0 +#define APP_I2C_SLAVE_SDA_PINMUX APP_IO_MUX_0 + +/*******SPI IO CONFIG***************************/ +#define APP_SPIM_CS_PIN APP_IO_PIN_17 +#define APP_SPIM_CLK_PIN APP_IO_PIN_24 +#define APP_SPIM_MOSI_PIN APP_IO_PIN_25 +#define APP_SPIM_MISO_PIN APP_IO_PIN_16 +#define APP_SPIM_CS_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_SPIM_CLK_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_SPIM_MOSI_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_SPIM_MISO_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_SPIM_CS_PINMUX APP_IO_MUX_0 +#define APP_SPIM_CLK_PINMUX APP_IO_MUX_0 +#define APP_SPIM_MOSI_PINMUX APP_IO_MUX_0 +#define APP_SPIM_MISO_PINMUX APP_IO_MUX_0 + +/*******QSPI IO CONFIG***************************/ +#define APP_QSPI1_CS_PIN APP_IO_PIN_15 +#define APP_QSPI1_CLK_PIN APP_IO_PIN_9 +#define APP_QSPI1_IO0_PIN APP_IO_PIN_8 +#define APP_QSPI1_IO1_PIN APP_IO_PIN_14 +#define APP_QSPI1_IO2_PIN APP_IO_PIN_13 +#define APP_QSPI1_IO3_PIN APP_IO_PIN_12 +#define APP_QSPI1_CS_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_CLK_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_IO0_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_IO1_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_IO2_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_IO3_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_QSPI1_GPIO_MUX APP_IO_MUX_2 + +#define APP_FLASH_GPIO_MUX APP_QSPI1_GPIO_MUX +#define APP_FLASH_CS_IO_TYPE APP_QSPI1_CS_IO_TYPE +#define APP_FLASH_CLK_IO_TYPE APP_QSPI1_CLK_IO_TYPE +#define APP_FLASH_IO0_IO_TYPE APP_QSPI1_IO0_IO_TYPE +#define APP_FLASH_IO1_IO_TYPE APP_QSPI1_IO1_IO_TYPE +#define APP_FLASH_IO2_IO_TYPE APP_QSPI1_IO2_IO_TYPE +#define APP_FLASH_IO3_IO_TYPE APP_QSPI1_IO3_IO_TYPE +#define APP_FLASH_CS_PIN APP_QSPI1_CS_PIN +#define APP_FLASH_CLK_PIN APP_QSPI1_CLK_PIN +#define APP_FLASH_IO0_PIN APP_QSPI1_IO0_PIN +#define APP_FLASH_IO1_PIN APP_QSPI1_IO1_PIN +#define APP_FLASH_IO2_PIN APP_QSPI1_IO2_PIN +#define APP_FLASH_IO3_PIN APP_QSPI1_IO3_PIN +#define APP_FLASH_QSPI_ID APP_QSPI_ID_1 + +/*******I2S IO CONFIG***************************/ +#define APP_I2S_MASTER_WS_PIN APP_IO_PIN_24 +#define APP_I2S_MASTER_SDO_PIN APP_IO_PIN_25 +#define APP_I2S_MASTER_SDI_PIN APP_IO_PIN_16 +#define APP_I2S_MASTER_SCLK_PIN APP_IO_PIN_17 +#define APP_I2S_MASTER_WS_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2S_MASTER_SDO_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2S_MASTER_SDI_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2S_MASTER_SCLK_IO_TYPE APP_IO_TYPE_NORMAL +#define APP_I2S_MASTER_WS_PINMUX APP_IO_MUX_3 +#define APP_I2S_MASTER_SDO_PINMUX APP_IO_MUX_3 +#define APP_I2S_MASTER_SDI_PINMUX APP_IO_MUX_3 +#define APP_I2S_MASTER_SCLK_PINMUX APP_IO_MUX_3 + +#define APP_I2S_SLAVE_WS_PIN APP_IO_PIN_2 +#define APP_I2S_SLAVE_SDO_PIN APP_IO_PIN_3 +#define APP_I2S_SLAVE_SDI_PIN APP_IO_PIN_4 +#define APP_I2S_SLAVE_SCLK_PIN APP_IO_PIN_5 +#define APP_I2S_SLAVE_WS_IO_TYPE APP_IO_TYPE_AON +#define APP_I2S_SLAVE_SDO_IO_TYPE APP_IO_TYPE_AON +#define APP_I2S_SLAVE_SDI_IO_TYPE APP_IO_TYPE_AON +#define APP_I2S_SLAVE_SCLK_IO_TYPE APP_IO_TYPE_AON +#define APP_I2S_SLAVE_WS_PINMUX APP_IO_MUX_3 +#define APP_I2S_SLAVE_SDO_PINMUX APP_IO_MUX_3 +#define APP_I2S_SLAVE_SDI_PINMUX APP_IO_MUX_3 +#define APP_I2S_SLAVE_SCLK_PINMUX APP_IO_MUX_3 + +/*******UC1701 DRIVER IO CONFIG*****************/ +#define DISPLAY_DRIVER_TYPE_HW_SPI +#define DISPLAY_SPIM_CS0_PIN APP_IO_PIN_3 +#define DISPLAY_CMD_AND_DATA_PIN APP_IO_PIN_5 +#define DISPLAY_SPIM_CLK_PIN APP_IO_PIN_7 +#define DISPLAY_SPIM_MOSI_PIN APP_IO_PIN_6 +#define DISPLAY_BACK_LIGHT_PIN APP_IO_PIN_2 +#define DISPLAY_SPIM_GPIO_TYPE APP_IO_TYPE_NORMAL + +/*******PWM IO CONFIG***************************/ +#define APP_PWM0_MODULE APP_PWM_ID_0 +#define APP_PWM0_GPIO_MUX APP_IO_MUX_5 +#define APP_PWM0_CHANNEL_A APP_IO_PIN_2 +#define APP_PWM0_CHANNEL_B APP_IO_PIN_3 +#define APP_PWM0_CHANNEL_C APP_IO_PIN_4 +#define APP_PWM0_GPIO_TYPE APP_IO_TYPE_NORMAL + +#define APP_PWM1_MODULE APP_PWM_ID_1 +#define APP_PWM1_GPIO_MUX APP_IO_MUX_0 +#define APP_PWM1_CHANNEL_A APP_IO_PIN_3 +#define APP_PWM1_CHANNEL_B APP_IO_PIN_4 +#define APP_PWM1_GPIO_TYPE APP_IO_TYPE_MSIO + + + +/** + * @defgroup BSP_MAROC Defines + * @{ + */ +#if APP_DRIVER_USE_ENABLE + #define BSP_KEY_UP_ID 0x00 /**< ID for UP KEY. */ + #define BSP_KEY_DOWN_ID 0x01 /**< ID for DOWN KEY. */ + #define BSP_KEY_LEFT_ID 0x02 /**< ID for LEFT KEY. */ + #define BSP_KEY_RIGHT_ID 0x03 /**< ID for RIGHT KEY. */ + #define BSP_KEY_OK_ID 0x04 /**< ID for OK KEY. */ + + #define UART_TX_BUFF_SIZE 0x400 /**< Size of app uart tx buffer. */ +#endif +/** @} */ + +/** + * @defgroup BSP_ENUM Enumerations + * @{ + */ +typedef enum +{ + BSP_LED_NUM_0, + BSP_LED_NUM_1, +} bsp_led_num_t; +/** @} */ + +/** + * @defgroup BSP_FUNCTION Functions + * @{ + */ +/** + ***************************************************************************************** + * @brief Initialize boards key. + ***************************************************************************************** + */ +void bsp_key_init(void); + +/** + ***************************************************************************************** + * @brief App key event handler + ***************************************************************************************** + */ +void app_key_evt_handler(uint8_t key_id, app_key_click_type_t key_click_type); + +/** + ***************************************************************************************** + * @brief Initialize app uart. + ***************************************************************************************** + */ +void bsp_uart_init(void); + +/** + ***************************************************************************************** + * @brief Uart data send. + ***************************************************************************************** + */ +void bsp_uart_send(uint8_t *p_data, uint16_t length); + +/** + ***************************************************************************************** + * @brief Uart data flush. + ***************************************************************************************** + */ +void bsp_uart_flush(void); + +/** + ***************************************************************************************** + * @brief App uart event handler. + ***************************************************************************************** + */ +void app_uart_evt_handler(app_uart_evt_t *p_evt); + +/** + ***************************************************************************************** + * @brief Initialize boards led. + ***************************************************************************************** + */ +void bsp_led_init(void); + +/** + ***************************************************************************************** + * @brief Open boards led. + * + * @param[in] led_num: Number of led needed open. + ***************************************************************************************** + */ +void bsp_led_open(bsp_led_num_t led_num); + +/** + ***************************************************************************************** + * @brief Close boards led. + * + * @param[in] led_num: Number of led needed close. + ***************************************************************************************** + */ +void bsp_led_close(bsp_led_num_t led_num); + +/** + ***************************************************************************************** + * @brief BSP log init. + ***************************************************************************************** + */ +void bsp_log_init(void); + +/** + ***************************************************************************************** + * @brief Board init. + ***************************************************************************************** + */ +void board_init(void); + + +#endif /* __BOARD_SK_H__ */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/boards/unity_test_config.h b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/unity_test_config.h new file mode 100644 index 0000000..8f187ed --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/boards/unity_test_config.h @@ -0,0 +1,40 @@ +/** + **************************************************************************************** + * + * @file board_SK.h + * + * @brief Start Kit Board Macro. + * + **************************************************************************************** + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ +#ifndef UNITY_TEST_CONFIG_H +#define UNITY_TEST_CONFIG_H + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_plat.h b/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_plat.h new file mode 100644 index 0000000..62cdc00 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_plat.h @@ -0,0 +1,33 @@ +#ifndef GR_PLAT_H +#define GR_PLAT_H + +#include + +#define MAX_COMMENTS_CNT 12 +#define MAX_RESERVED_1_CNT 6 +typedef struct __attribute((packed)) +{ + uint32_t app_pattern; + uint32_t app_info_version; + uint32_t chip_ver; + uint32_t load_addr; + uint32_t run_addr; + uint32_t app_info_sum; + uint8_t check_img; + uint8_t boot_delay; + uint8_t sec_cfg; + uint8_t reserved0; + uint8_t comments[MAX_COMMENTS_CNT]; + uint32_t reserved1[MAX_RESERVED_1_CNT]; +} APP_INFO_t; + +#define APP_INFO_ADDR (APP_CODE_RUN_ADDR+0x200) +#define APP_INFO_PATTERN_VALUE 0x47525858 +#define APP_INFO_VERSION 0x1 +#define CHECK_SUM (APP_INFO_PATTERN_VALUE+APP_INFO_VERSION+CHIP_VER+APP_CODE_LOAD_ADDR+APP_CODE_RUN_ADDR) + +extern void __main(void); + +extern void sdk_init(void); + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_soc.h b/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_soc.h new file mode 100644 index 0000000..8875959 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/include/gr_soc.h @@ -0,0 +1,53 @@ +#ifndef GR_SOC_H +#define GR_SOC_H + +#include "grx_sys.h" + +extern void Reset_Handler(void); +extern void NMI_Handler(void); +extern void HardFault_Handler(void); +extern void MemManage_Handler(void); +extern void BusFault_Handler(void); +extern void UsageFault_Handler(void); +extern void SVC_Handler(void); +extern void DebugMon_Handler(void); +extern void PendSV_Handler(void); +extern void SysTick_Handler(void); + +extern void vector_table_init(void); +extern void soc_init(void); +extern void warm_boot_process(void); +extern void platform_init(void); +extern void soc_register_nvic(IRQn_Type indx, uint32_t func); +extern uint32_t get_wakeup_flag(void); + +extern hal_status_t hal_exflash_read_rom(exflash_handle_t *p_exflash, uint32_t addr, uint8_t *p_data, uint32_t size); +extern uint8_t nvds_put_patch(NvdsTag_t tag, uint16_t len, const uint8_t *p_buf); +extern uint8_t nvds_put_rom(NvdsTag_t tag, uint16_t len, const uint8_t *p_buf); +extern void dfu_cmd_handler_replace_for_encrypt(void); +extern void register_rwip_reset(void (*callback)(void)); +extern void rwip_reset_patch(void); +extern void register_rwip_init(void (*callback)(uint32_t)); +extern void rwip_init_patch(uint32_t error); +extern void ble_sup_mul_link_with_same_dev(void); + +#if defined (__CC_ARM) +extern void tiny_rw_section_init(void); +#endif + +typedef void (*FuncVector_t)(void); +typedef void (*FUNC_t)(void); + +#define SYS_RESET_REASON_NONE (0U) +#define SYS_RESET_REASON_AONWDT (1U << 2U) +/** + * @brief Get chip reset reason. + * + * @retval Returned value can be one of the following values: + * @arg @ref SYS_RESET_REASON_NONE + * @arg @ref SYS_RESET_REASON_AONWDT + */ +uint8_t sys_device_reset_reason(void); + + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/include/scatter_common.h b/gr551x/sdk_liteos/gr551x_sdk/platform/include/scatter_common.h new file mode 100644 index 0000000..c08c921 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/include/scatter_common.h @@ -0,0 +1,18 @@ +/** + **************************************************************************************** + * + * @file scatter_common.h + * + * @brief decalare the symbols in scatter_common.sct. + * + * + **************************************************************************************** + */ + +#ifndef __SCATTER_COMMON_H__ +#define __SCATTER_COMMON_H__ + +#include +#include "ble_cfg.h" + +#endif // __SCATTER_COMMON_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_interrupt.c b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_interrupt.c new file mode 100644 index 0000000..90ba62a --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_interrupt.c @@ -0,0 +1,223 @@ +/** + ***************************************************************************************** + * + * @file gr_interrupt.c + * + * @brief Interrupt Service Routines. + * + ***************************************************************************************** + + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + ***************************************************************************************** + */ +#include "custom_config.h" +#include "grx_sys.h" + +/******************************************************************************/ +/* Cortex-M4F Processor Interruption and Exception Handlers */ +/* Add here the Interrupt Handler for the BLE peripheral(s) */ +/******************************************************************************/ + +/** + **************************************************************************************** + * @brief hardfault Interrupt Handler + * @retval void + **************************************************************************************** + */ +#if SYS_FAULT_TRACE_ENABLE + +__WEAK void app_log_flush(void) +{ +} + +#if defined ( __CC_ARM ) +uint32_t R4_R11_REG[8]; +SECTION_RAM_CODE __WEAK void hardfault_trace_handler(uint32_t sp) +{ + printf("HARDFAULT CALLSTACK INFO:\r\n"); + printf("================================\r\n"); + printf(" r0: %08x r1: %08x\r\n", ((uint32_t *)sp)[0], ((uint32_t *)sp)[1]); + printf(" r2: %08x r3: %08x\r\n", ((uint32_t *)sp)[2], ((uint32_t *)sp)[3]); + printf(" r4: %08x r5: %08x\r\n", R4_R11_REG[0], R4_R11_REG[1] ); + printf(" r6: %08x r7: %08x\r\n", R4_R11_REG[2], R4_R11_REG[3] ); + printf(" r8: %08x r9: %08x\r\n", R4_R11_REG[4], R4_R11_REG[5] ); + printf(" r10:%08x r11:%08x\r\n", R4_R11_REG[6], R4_R11_REG[7] ); + printf(" r12:%08x lr: %08x\r\n", ((uint32_t *)sp)[4], ((uint32_t *)sp)[5]); + printf(" pc: %08x xpsr: %08x\r\n", ((uint32_t *)sp)[6], ((uint32_t *)sp)[7]); + printf("================================\r\n"); + app_log_flush(); + while (1); +} + +SECTION_RAM_CODE __WEAK void cortex_backtrace_fault_handler(uint32_t fault_handler_lr, uint32_t fault_handler_sp) +{ +} + +SECTION_RAM_CODE __asm void HardFault_Handler (void) +{ +#if (ENABLE_BACKTRACE_FEA == 0)//use fault trace module + PRESERVE8 + IMPORT hardfault_trace_handler + IMPORT R4_R11_REG + LDR R0,=R4_R11_REG + STMIA R0!,{R4-R11} + MOV R0,SP + BL hardfault_trace_handler +#elif (ENABLE_BACKTRACE_FEA == 1)//use cortex_backtrace module + PRESERVE8 + IMPORT cortex_backtrace_fault_handler + MOV r0, lr + MOV r1, sp + BL cortex_backtrace_fault_handler +#endif + +Fault_Loop + BL Fault_Loop + ALIGN +} + +#elif defined ( __GNUC__ ) + +__WEAK void hardfault_trace_handler(unsigned int *hardfault_args) +{ + unsigned int stacked_r0; + unsigned int stacked_r1; + unsigned int stacked_r2; + unsigned int stacked_r3; + unsigned int stacked_r12; + unsigned int stacked_lr; + unsigned int stacked_pc; + unsigned int stacked_psr; + + stacked_r0 = ((unsigned long) hardfault_args[0]); + stacked_r1 = ((unsigned long) hardfault_args[1]); + stacked_r2 = ((unsigned long) hardfault_args[2]); + stacked_r3 = ((unsigned long) hardfault_args[3]); + + stacked_r12 = ((unsigned long) hardfault_args[4]); + stacked_lr = ((unsigned long) hardfault_args[5]); + stacked_pc = ((unsigned long) hardfault_args[6]); + stacked_psr = ((unsigned long) hardfault_args[7]); + printf("HARDFAULT CALLSTACK INFO:\r\n"); + printf("================================\r\n"); + printf("R0 = %x\r\n", stacked_r0); + printf("R1 = %x\r\n", stacked_r1); + printf("R2 = %x\r\n", stacked_r2); + printf("R3 = %x\r\n", stacked_r3); + printf("R12 = %x\r\n", stacked_r12); + printf("LR [R14] = %x subroutine call return address\r\n", stacked_lr); + printf("PC [R15] = %x program counter\r\n", stacked_pc); + printf("PSR = %x\r\n", stacked_psr); + printf("BFAR = %x\r\n", (*((volatile unsigned long *)(0xE000ED38)))); + printf("CFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED28)))); + printf("HFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED2C)))); + printf("DFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED30)))); + printf("AFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED3C)))); + printf("SCB_SHCSR = %x\r\n", SCB->SHCSR); + printf("================================\r\n"); + app_log_flush(); + + while (1); +} + +SECTION_RAM_CODE __WEAK void cortex_backtrace_fault_handler(uint32_t fault_handler_lr, uint32_t fault_handler_sp) +{ +} + +SECTION_RAM_CODE void HardFault_Handler (void) +{ +#if (ENABLE_BACKTRACE_FEA == 0)//use fault trace module + __asm("TST LR,#4\n"); + __asm("ITE EQ\n"); + __asm("MRSEQ R0,MSP\n"); + __asm("MRSNE R0,PSP\n"); + __asm("BL hardfault_trace_handler\n"); +#elif (ENABLE_BACKTRACE_FEA == 1)//use cortex_backtrace module + __asm("MOV r0, lr"); + __asm("MOV r1, sp"); + __asm("BL cortex_backtrace_fault_handler"); +#endif + + while (1); +} + +#else + +void HardFault_Handler (void) +{ + while (1); +} + +#endif + +#else /*SYS_FAULT_TRACE_ENABLE*/ + +SECTION_RAM_CODE void HardFault_Handler (void) +{ + while (1); +} + +#endif /*SYS_FAULT_TRACE_ENABLE*/ + +/** + **************************************************************************************** + * @brief MemManage fault Interrupt Handler + * @retval void + **************************************************************************************** + */ +void MemManage_Handler(void) +{ + while (1); +} + +/** + **************************************************************************************** + * @brief Bus Fault Interrupt Handler + * @retval void + **************************************************************************************** + */ +void BusFault_Handler(void) +{ + while (1); +} + +/** + **************************************************************************************** + * @brief UsageFault Interrupt Handler + * @retval void + **************************************************************************************** + */ +void UsageFault_Handler(void) +{ + while (1); +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_platform.c b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_platform.c new file mode 100644 index 0000000..f9db0e6 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_platform.c @@ -0,0 +1,138 @@ +/** + ******************************************************************************* + * + * @file gr_platform.c + * + * @brief Platform Initialization Routines. + * + ******************************************************************************* + + * @attention + #####Copyright (c) 2019 GOODIX + 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 GOODIX nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +/* + * INCLUDE FILES + ******************************************************************************* + */ +#include "grx_sys.h" +#include "gr_soc.h" +#include "gr_plat.h" + +#if defined (__CC_ARM ) +const APP_INFO_t BUILD_IN_APP_INFO __attribute__((at(APP_INFO_ADDR))) = +#elif defined (__ICCARM__) +__root const APP_INFO_t BUILD_IN_APP_INFO @ (APP_INFO_ADDR) = +#else +const APP_INFO_t BUILD_IN_APP_INFO __attribute__((section(".app_info"))) = +#endif +{ + .app_pattern = APP_INFO_PATTERN_VALUE, + .app_info_version = APP_INFO_VERSION, + .chip_ver = CHIP_VER, + .load_addr = APP_CODE_LOAD_ADDR, + .run_addr = APP_CODE_RUN_ADDR, + .app_info_sum = CHECK_SUM, + .check_img = BOOT_CHECK_IMAGE, + .boot_delay = BOOT_LONG_TIME, + .sec_cfg = SECURITY_CFG_VAL, +#ifdef APP_INFO_COMMENTS + .comments = APP_INFO_COMMENTS, +#endif +}; + +void C_CONSTRUCTOR system_platform_init(void) +{ + vector_table_init(); + sdk_init(); + soc_init(); + return; +} + +#if defined ( __ICCARM__ ) +extern void __iar_program_start(void); +void __main(void) +{ + __iar_program_start(); +} + +extern void __iar_data_init3(void); +int __low_level_init(void) +{ + __iar_data_init3(); + system_platform_init(); + return 0; +} +#elif defined ( __GNUC__ ) && !defined ( __CC_ARM ) +extern int main(void); +void __main(void) +{ + __asm("ldr r1, =__etext\n"); + __asm("ldr r2, =__data_start__\n"); + __asm("ldr r3, =__data_end__\n"); + __asm(".L_loop1:\n"); + __asm("cmp r2, r3\n"); + __asm("ittt lt\n"); + __asm("ldrlt r0, [r1], #4\n"); + __asm("strlt r0, [r2], #4\n"); + __asm("blt .L_loop1\n"); + __asm("ldr r1, =__bss_start__\n"); + __asm("ldr r2, =__bss_end__\n"); + __asm("movs r0, 0\n"); + __asm(".L_loop3:\n"); + __asm("cmp r1, r2\n"); + __asm("itt lt\n"); + __asm("strlt r0, [r1], #4\n"); + __asm("blt .L_loop3\n"); + system_platform_init(); + main(); +} +#endif + +void main_init(void) +{ +#if defined ( SOC_GR5332 ) + uint32_t boot_flag = pwr_mgmt_get_wakeup_flag(); +#else + uint32_t boot_flag = get_wakeup_flag(); + #endif + if(COLD_BOOT == boot_flag) + { + extern void __main(void); + __main(); + } + else + { + __DMB(); + SCB->VTOR = (uint32_t)(uintptr_t)ArchGetHwiFrom(); + __DSB(); + pwr_mgmt_warm_boot(); + while (1); + } +} + diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_system.c b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_system.c new file mode 100644 index 0000000..11b0da0 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/common/gr_system.c @@ -0,0 +1,46 @@ +/**************************************************************************//** + * @file gr_system.c + * @brief CMSIS Device System Source File for + * Device GR55xx + * @version V1.00 + * @date 12. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "grx_sys.h" + +/*---------------------------------------------------------------------------- + Global Functions + *----------------------------------------------------------------------------*/ + + +void SystemInit(void) +{ + #if (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ + (3UL << 11*2) ); /* set CP11 Full Access */ + #endif + + #ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; + #endif + + return; +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/ble_cfg.h b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/ble_cfg.h new file mode 100644 index 0000000..5ebf074 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/ble_cfg.h @@ -0,0 +1,212 @@ +/** + **************************************************************************************** + * + * @file scatter_common.h + * + * @brief decalare the symbols in scatter_common.sct. + * + * + **************************************************************************************** + */ + +#ifndef __BLE_CFG_H__ +#define __BLE_CFG_H__ + +#include +#include "custom_config.h" + +/* ************************************************************************ + * developer must define CFG_MAX_CONNECTIONS in custom_config.h . + * Max value for GR551X: 10 which must be same with CFG_CON + * in ROM's configs.opt + */ +#ifndef CFG_MAX_CONNECTIONS + #error "CFG_MAX_CONNECTIONS is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_CONNECTIONS <= 10) + #define USER_MAX_CONNECTIONS CFG_MAX_CONNECTIONS +#else + #define USER_MAX_CONNECTIONS (1) +#endif + +#ifndef CFG_MAX_ADVS + #error "CFG_MAX_ADVS is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_ADVS <= 5) + #define USER_MAX_ADVS CFG_MAX_ADVS +#else + #define USER_MAX_ADVS (1) +#endif + +#ifndef CFG_MAX_PER_ADVS + #error "CFG_MAX_PER_ADVS is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_PER_ADVS <= 5) + #define USER_MAX_PER_ADVS CFG_MAX_PER_ADVS +#else + #define USER_MAX_PER_ADVS (0) +#endif + +#if ((USER_MAX_ADVS+USER_MAX_PER_ADVS) > 5) + #error "The number of BLE Legacy/Extended/Periodic Advertising exceeds the limit." +#endif + +#ifndef CFG_MAX_SCAN + #error "CFG_MAX_SCAN is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_SCAN <= 1) + #define USER_MAX_SCAN CFG_MAX_SCAN +#else + #define USER_MAX_SCAN (1) +#endif + +#ifndef CFG_SCAN_DUP_FILT_LIST_NUM + #define USER_SCAN_DUP_FILT_NUM 0 +#else + #define USER_SCAN_DUP_FILT_NUM CFG_SCAN_DUP_FILT_LIST_NUM +#endif + +#ifndef CFG_MAX_SYNCS + #error "CFG_MAX_SYNCS is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_SYNCS <= 5) + #define USER_MAX_SYNCS CFG_MAX_SYNCS +#else + #define USER_MAX_SYNCS (0) +#endif + +#if ((USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) > 12) + #error "The number of BLE Activities exceeds the limit." +#endif + +#ifndef CFG_MAX_BOND_DEVS + #error "CFG_MAX_BOND_DEVS is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_BOND_DEVS <= 10) + #define USER_MAX_BOND_DEVS CFG_MAX_BOND_DEVS +#else + #define USER_MAX_BOND_DEVS (1) +#endif + +#ifndef CFG_MAX_PRFS + #error "CFG_MAX_PRFS is not defined in app's custom_config.h ." +#endif + +#ifndef CFG_MESH_SUPPORT + #error "CFG_MESH_SUPPORT is not defined in app's custom_config.h ." +#endif + +#if (CFG_MAX_PRFS <= 64) + #define USER_MAX_PRFS CFG_MAX_PRFS +#else + #define USER_MAX_PRFS (1) +#endif + +/* The macro is used to compute size of the heap block in bytes. */ +#define MEM_HEAP_HEADER (12 / sizeof(uint32_t)) +#define MEM_CALC_HEAP_LEN(len) ((((len) + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) + MEM_HEAP_HEADER) +#define MEM_CALC_HEAP_LEN_IN_BYTES(len) (MEM_CALC_HEAP_LEN(len) * sizeof(uint32_t)) + +#define ENV_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(292 * USER_MAX_CONNECTIONS \ + + 426 * (USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) \ + + 600) +/* The size of heap for ATT database depends on the number of attributes in + * profiles. The value can be tuned based on supported profiles. */ +#if (CFG_MESH_SUPPORT == 1) +#include "mesh_stack_config.h" +#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1000 + MESH_HEAP_SIZE_ADD) +#else +#define ATT_DB_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1024) +#endif + +#define KE_MSG_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(1650 * (USER_MAX_SCAN+USER_MAX_SYNCS) \ + + 112 *(USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS) \ + + 408 *(USER_MAX_CONNECTIONS+USER_MAX_ADVS+2*USER_MAX_PER_ADVS+USER_MAX_SCAN+USER_MAX_SYNCS) \ + + 3072) +/* The size of non-retention heap is customized. This heap will used by BLE + * stack only when other three heaps are full. */ +#define NON_RET_HEAP_SIZE MEM_CALC_HEAP_LEN_IN_BYTES(328 * 2) + +#define PRF_BUF_SIZE (92*USER_MAX_PRFS + 4) +#define BOND_BUF_SIZE (8*USER_MAX_BOND_DEVS + 4) +#define CONN_BUF_SIZE (372*USER_MAX_CONNECTIONS + 4) +#define SCAN_DUP_FILT_BUF_SIZE (2 * USER_SCAN_DUP_FILT_NUM + 4) + +#if (CFG_MAX_CONNECTIONS < 3) && (CFG_MAX_ADVS < 2) && (CFG_MESH_SUPPORT < 1) +#define EM_BASE_ADDR (0xB0008000) +#define EM_BLE_ADVDATATXBUF_OFFSET (0x13A0) +#define EM_BLE_ADVDATATXBUF_END (0x4F28) +#define EM_NVDS_OFFSET (0x6690) + +// (EM_BASE_ADDR + EM_BLE_ADVDATATXBUF_OFFSET + 4 * 1270 + 16(reserved)) +#define ENV_HEAP_ADDR (0xB000A788) + +// (ENV_HEAP_ADDR + ENV_HEAP_SIZE:2900 bytes) +#define KE_MSG_HEAP_ADDR (0xB000B2DC) + +// (KE_MSG_HEAP_ADDR + MSG_HEAP_SIZE:6700 bytes) +#define KE_MSG_HEAP_END_ADDR (0xB000CD08) + +// (EM_BASE_ADDR + EM_NVDS_OFFSET + 4096 + 16(reserved)) +#define ATT_DB_HEAP_ADDR (0xB000F6A0) + +// (ATT_DB_HEAP_ADDR + ATT_DB_HEAP_SIZE:1024) +#define NON_RET_HEAP_ADDR (0xB000FAA0) + +// (NON_RET_HEAP_ADDR + ATT_DB_HEAP_SIZE:1024) +#define NON_RET_HEAP_END_ADDR (0xB000FEA0) + +#define STACK_HEAP_INIT(heaps_table) uint8_t prf_buf[PRF_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t bond_buf[BOND_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t conn_buf[CONN_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t scan_dup_filt_buf[SCAN_DUP_FILT_BUF_SIZE] __attribute__((aligned (32))) = {0};\ +stack_heaps_table_t heaps_table = { (uint32_t *)(ENV_HEAP_ADDR),\ + (uint32_t *)(ATT_DB_HEAP_ADDR),\ + (uint32_t *)(KE_MSG_HEAP_ADDR),\ + (uint32_t *)(NON_RET_HEAP_ADDR),\ + 2900,\ + 1024,\ + 6700,\ + 1024,\ + (uint8_t *)prf_buf,\ + PRF_BUF_SIZE,\ + (uint8_t *)bond_buf,\ + BOND_BUF_SIZE,\ + (uint8_t *)conn_buf,\ + CONN_BUF_SIZE,\ + scan_dup_filt_buf,\ + SCAN_DUP_FILT_BUF_SIZE} +#else +#define STACK_HEAP_INIT(heaps_table) uint8_t prf_buf[PRF_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t bond_buf[BOND_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t conn_buf[CONN_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t scan_dup_filt_buf[SCAN_DUP_FILT_BUF_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t env_heap_buf[ENV_HEAP_SIZE] __attribute__((aligned (32)))= {0};\ + uint8_t att_db_heap_buf[ATT_DB_HEAP_SIZE] __attribute__((aligned (32)))= {0};\ + uint8_t ke_msg_heap_buf[KE_MSG_HEAP_SIZE] __attribute__((aligned (32))) = {0};\ + uint8_t non_ret_heap_buf[NON_RET_HEAP_SIZE]__attribute__((aligned (32))) = {0};\ +stack_heaps_table_t heaps_table = { (uint32_t *)env_heap_buf,\ + (uint32_t *)att_db_heap_buf,\ + (uint32_t *)ke_msg_heap_buf,\ + (uint32_t *)non_ret_heap_buf,\ + ENV_HEAP_SIZE,\ + ATT_DB_HEAP_SIZE,\ + KE_MSG_HEAP_SIZE,\ + NON_RET_HEAP_SIZE,\ + (uint8_t *)prf_buf,\ + PRF_BUF_SIZE,\ + (uint8_t *)bond_buf,\ + BOND_BUF_SIZE,\ + (uint8_t *)conn_buf,\ + CONN_BUF_SIZE,\ + scan_dup_filt_buf,\ + SCAN_DUP_FILT_BUF_SIZE} +#endif + +#endif // __SCATTER_COMMON_H__ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr551xx.h b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr551xx.h new file mode 100644 index 0000000..ef5ec21 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr551xx.h @@ -0,0 +1,6550 @@ +/**************************************************************************//** + * @file gr551xx.h + * @brief CMSIS Cortex-M# Core Peripheral Access Layer Header File for + * Device gr551xx + * @version V1.00 + * @date 12. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2016-2018, Shenzhen Huiding Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +/** @addtogroup Device_Included + * @{ + */ + +/** @addtogroup GR551xx + * @{ + */ + +#ifndef __GR551xx_H__ +#define __GR551xx_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + +/** + * @brief GR55xx Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ + +/* ================================================================================================================= */ +/* ================ Interrupt Number Definition ================ */ +/* ================================================================================================================= */ +typedef enum IRQn +{ +/* ================================== ARM Cortex-M# Specific Interrupt Numbers =================================== */ + + NonMaskableInt_IRQn = -14, /**< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /**< -13 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /**< -12 Memory Management, MPU mismatch, including Access Violation + and No Match */ + BusFault_IRQn = -11, /**< -11 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory + related Fault */ + UsageFault_IRQn = -10, /**< -10 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /**< -5 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /**< -4 Debug Monitor */ + PendSV_IRQn = -2, /**< -2 Pendable request for system service */ + SysTick_IRQn = -1, /**< -1 System Tick Timer */ + +/* ====================================== Specific Interrupt Numbers ==================================== */ + WDT_IRQn = 0, /**< Watchdog Timer Interrupt */ + BLE_SDK_IRQn = 1, /**< BLE_SDK_SCHEDULE Interrupt */ + BLE_IRQn = 2, /**< BLE Interrupt */ + DMA_IRQn = 3, /**< DMA Interrupt */ + SPI_M_IRQn = 4, /**< SPI_M Interrupt */ + SPI_S_IRQn = 5, /**< SPI_S Interrupt */ + EXT0_IRQn = 6, /**< EXT0 Interrupt */ + EXT1_IRQn = 7, /**< EXT1 Interrupt */ + TIMER0_IRQn = 8, /**< Timer0 Interrupt */ + TIMER1_IRQn = 9, /**< Timer1 Interrupt */ + DUAL_TIMER_IRQn = 10, /**< Dual_Timer Interrupt */ + QSPI0_IRQn = 11, /**< QSPI0 Interrupt */ + UART0_IRQn = 12, /**< UART0 Interrupt */ + UART1_IRQn = 13, /**< UART1 Interrupt */ + I2C0_IRQn = 14, /**< I2C0 Interrupt */ + I2C1_IRQn = 15, /**< I2C1 Interrupt */ + AES_IRQn = 16, /**< AES Interrupt */ + HMAC_IRQn = 17, /**< HMAC Interrupt */ + EXT2_IRQn = 18, /**< EXT2 Interrupt */ + RNG_IRQn = 19, /**< RNG Interrupt */ + BOD_ASSERT_IRQn = 20, /**< BOD Interrupt */ + PKC_IRQn = 21, /**< PKC Interrupt */ + XQSPI_IRQn = 22, /**< XQSPI Interrupt */ + QSPI1_IRQn = 23, /**< QSPI1 Interrupt */ + PWR_CMD_IRQn = 24, /**< POWER CMD ACK Interrupt */ + BLESLP_IRQn = 25, /**< BLE Sleep Interrupt */ + SLPTIMER_IRQn = 26, /**< Sleep Timer Interrupt */ + COMP_EXT_IRQn = 27, /**< Comparator and External Wakeup Interrupt */ + AON_WDT_IRQn = 28, /**< Always on Watchdog Interrupt */ + I2S_M_IRQn = 29, /**< I2S_M Interrupt */ + I2S_S_IRQn = 30, /**< I2S_S Interrupt */ + ISO7816_IRQn = 31, /**< ISO7816 Interrupt */ + PRESENT_IRQn = 32, /**< Presnet Done Interrupt */ + CALENDAR_IRQn = 33, /**< AON Calendar Timer Interrupt */ + MAX_NUMS_IRQn = 34, /**< Last Interrupt */ +} IRQn_Type; + +#define AON_EXT_IRQn EXT2_IRQn + +/** @} */ /* End of group Peripheral _interrupt_number_definition */ + +/* ================================================================================================================= */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================================================= */ + +/* =================================== Start of section using anonymous unions =================================== */ + +/* ====================== Configuration of the ARM Cortex-M4 Processor and Core Peripherals ====================== */ +#define __CM4_REV 0x0001U /* Core revision r0p1 */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __VTOR_PRESENT 1 /* VTOR present */ +#define __NVIC_PRIO_BITS 8 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /* FPU present */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "system_gr55xx.h" /* System Header */ +#include + +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* ================================================================================================================= */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================================================= */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief AES + */ +typedef struct _aes_regs +{ + __IOM uint32_t CTRL; /**< AES_REG_CTRL, Address offset: 0x00 */ + __IOM uint32_t CONFIG; /**< AES_REG_CONFIG, Address offset: 0x04 */ + __IM uint32_t STATUS; /**< AES_REG_STATUS, Address offset: 0x08 */ + __IOM uint32_t INTERRUPT; /**< AES_REG_INTERRUPT, Address offset: 0x0C */ + __IOM uint32_t TRAN_SIZE; /**< AES_REG_TRAN_SIZE, Address offset: 0x10 */ + __IOM uint32_t RSTART_ADDR; /**< AES_REG_RSTART_ADDR, Address offset: 0x14 */ + __IOM uint32_t WSTART_ADDR; /**< AES_REG_WSTART_ADDR, Address offset: 0x18 */ + __IOM uint32_t KEY_ADDR; /**< AES_REG_KEY_ADDR, Address offset: 0x1C */ + __IM uint32_t DATA_OUT[4]; /**< AES_REG_DATA_OUT, Address offset: 0x20 */ + __OM uint32_t KEY[8]; /**< AES_REG_KEY, Address offset: 0x30 */ + __IOM uint32_t SEED_IN; /**< AES_REG_SEED_IN, Address offset: 0x50 */ + __IOM uint32_t SEED_OUT; /**< AES_REG_SEED_OUT, Address offset: 0x54 */ + __IOM uint32_t SEED_IMASK; /**< AES_REG_SEED_IMASK, Address offset: 0x58 */ + __IOM uint32_t SEED_OSBOX; /**< AES_REG_SEED_OSBOX, Address offset: 0x5C */ + __OM uint32_t VECTOR_INIT[4]; /**< AES_REG_VECTOR_INIT, Address offset: 0x60 */ + __OM uint32_t DATA_IN[4]; /**< AES_REG_DATA_IN, Address offset: 0x70 */ + __OM uint32_t KPORT_MASK; /**< AES_REG_KPORT_MASK, Address offset: 0x80 */ +} aes_regs_t; + +/** + * @brief AON + */ +typedef struct _aon_regs +{ + __IOM uint32_t SOFTWARE_0; /**< AON_REG_SOFTWARE_0, Address offset: 0x00 */ + __IOM uint32_t PWR_RET01; /**< AON_REG_PWR_RET01, Address offset: 0x04 */ + __IOM uint32_t SNSADC_CFG; /**< AON_REG_SNSADC_CFG, Address offset: 0x08 */ + __IOM uint32_t RF_REG_0; /**< AON_REG_RF_REG_0, Address offset: 0x0C */ + __IOM uint32_t RF_REG_1; /**< AON_REG_RF_REG_1, Address offset: 0x10 */ + __IOM uint32_t RF_REG_2; /**< AON_REG_RF_REG_2, Address offset: 0x14 */ + __IOM uint32_t CALENDAR_TIMER_CTL; /**< AON_REG_CALENDAR_TIMER_CTL, Address offset: 0x18 */ + __IOM uint32_t MEM_STD_OVR; /**< AON_REG_MEM_STD_OVR, Address offset: 0x1C */ + __IOM uint32_t RF_REG_3; /**< AON_REG_RF_REG_3, Address offset: 0x20 */ + __IOM uint32_t RF_REG_4; /**< AON_REG_RF_REG_4, Address offset: 0x24 */ + __IOM uint32_t RF_REG_5; /**< AON_REG_RF_REG_5, Address offset: 0x28 */ + __IOM uint32_t RF_REG_6; /**< AON_REG_RF_REG_6, Address offset: 0x2C */ + __IOM uint32_t RF_REG_7; /**< AON_REG_RF_REG_7, Address offset: 0x30 */ + __IOM uint32_t RF_REG_8; /**< AON_REG_RF_REG_8, Address offset: 0x34 */ + __IOM uint32_t RF_REG_9; /**< AON_REG_RF_REG_9, Address offset: 0x38 */ + __IOM uint32_t MSIO_PAD_CFG_0; /**< AON_REG_MSIO_PAD_CFG_0, Address offset: 0x3C */ + __IOM uint32_t MSIO_PAD_CFG_1; /**< AON_REG_MSIO_PAD_CFG_1, Address offset: 0x40 */ + __IOM uint32_t SLP_EVENT; /**< AON_REG_SLP_EVENT, Address offset: 0x44 */ + __IOM uint32_t WARM_BOOT_TIME; /**< AON_REG_WARM_BOOT_TIME, Address offset: 0x48 */ + __IOM uint32_t RF_REG_10; /**< AON_REG_RF_REG_10, Address offset: 0x4C */ + __IOM uint32_t AON_PAD_CTL0; /**< AON_REG_AON_PAD_CTL0, Address offset: 0x50 */ + __IOM uint32_t MEM_N_SLP_CTL; /**< AON_REG_MEM_N_SLP_CTL, Address offset: 0x54 */ + __IOM uint32_t EXT_WKUP_CTL; /**< AON_REG_EXT_WKUP_CTL, Address offset: 0x58 */ + __IOM uint32_t AON_PAD_CTL1; /**< AON_REG_AON_PAD_CTL1, Address offset: 0x5C */ + __IOM uint32_t SOFTWARE_1; /**< AON_REG_SOFTWARE_1, Address offset: 0x60 */ + __IOM uint32_t MEM_PWR_SLP; /**< AON_REG_MEM_PWR_SLP, Address offset: 0x64 */ + __IOM uint32_t MEM_PWR_WKUP; /**< AON_REG_MEM_PWR_WKUP, Address offset: 0x68 */ + __IOM uint32_t PWR_RET27; /**< AON_REG_PWR_RET27, Address offset: 0x6C */ + __IOM uint32_t PWR_RET28; /**< AON_REG_PWR_RET28, Address offset: 0x70 */ + __IOM uint32_t PWR_RET29; /**< AON_REG_PWR_RET29, Address offset: 0x74 */ + __IOM uint32_t SOFTWARE_2; /**< AON_REG_SOFTWARE_2, Address offset: 0x78 */ + __IOM uint32_t PWR_RET31; /**< AON_REG_PWR_RET31, Address offset: 0x7C */ + __IOM uint32_t PSC_CMD; /**< AON_REG_PSC_CMD, Address offset: 0x80 */ + __IOM uint32_t PSC_CMD_OPC; /**< AON_REG_PSC_CMD_OPC, Address offset: 0x84 */ + __IM uint32_t MCU_RELEASE; /**< AON_REG_MCU_RELEASE, Address offset: 0x88 */ + __IM uint32_t RESERVED0; /**< Reserved, Address offset: 0x8C */ + __IOM uint32_t TIMER_VALUE; /**< AON_REG_TIMER_VALUE, Address offset: 0x90 */ + __IM uint32_t TIMER_VAL; /**< AON_REG_TIMER_VAL, Address offset: 0x94 */ + __IM uint32_t RESERVED1[13]; /**< Reserved, Address offset: 0x98 */ + __IOM uint32_t FPGA_CTRL; /**< AON_REG_FPGA_CTRL, Address offset: 0xCC */ + __IM uint32_t RESERVED2[5]; /**< Reserved, Address offset: 0xD0 */ + __IOM uint32_t ST_CALIB; /**< AON_REG_ST_CALIB_REG, Address offset: 0xE4 */ +} aon_regs_t; + +/** + * @brief DMA + */ +#define DMA_REG(name) __IOM uint32_t name; __IOM uint32_t __pad_##name +/* DMA/Channel_x_Registers Registers */ +typedef struct +{ + DMA_REG(SAR); /**< Source Address, Address offset: 0x00 */ + DMA_REG(DAR); /**< Destination Address, Address offset: 0x08 */ + DMA_REG(LLP); /**< Linked List Pointer, Address offset: 0x10 */ + __IOM uint32_t CTL_LO; /**< Control Register Low, Address offset: 0x18 */ + __IOM uint32_t CTL_HI; /**< Control Register High, Address offset: 0x1C */ + DMA_REG(SSTAT); /**< Source Status, Address offset: 0x20 */ + DMA_REG(DSTAT); /**< Destination Status, Address offset: 0x28 */ + DMA_REG(SSTATAR); /**< Source Status Address, Address offset: 0x30 */ + DMA_REG(DSTATAR); /**< Destination Status Address, Address offset: 0x38 */ + __IOM uint32_t CFG_LO; /**< Configuration Register Low, Address offset: 0x40 */ + __IOM uint32_t CFG_HI; /**< Configuration Register High, Address offset: 0x44 */ + DMA_REG(SGR); /**< Source Gather, Address offset: 0x48 */ + DMA_REG(DSR); /**< Destination Scatter, Address offset: 0x50 */ +} DMA_CH_REGS; + +/* DMA/Interrupt_Registers Registers */ +typedef struct +{ + __IO uint32_t RAW_CH_EVT[10]; /**< Raw channel event, Address offset: 0x00 */ + __I uint32_t STATUS_CH_EVT[10]; /**< Status channel event, Address offset: 0x28 */ + __IO uint32_t MASK_CH_EVT[10]; /**< Mask channel event, Address offset: 0x50 */ + __O uint32_t CLEAR_CH_EVT[10]; /**< Clear channel event, Address offset: 0x78 */ + DMA_REG(STATUS_EVT); /**< Status event, Address offset: 0xA0 */ +} DMA_INT_REGS; + +/* DMA/Software_Handshake_Registers Registers */ +typedef struct +{ + DMA_REG(REQ_SRC); /**< Source Transaction Request, Address offset: 0x00 */ + DMA_REG(REQ_DST); /**< Destination Transaction Request, Address offset: 0x08 */ + DMA_REG(SGL_RQ_SRC); /**< Source Single Transaction Request, Address offset: 0x20 */ + DMA_REG(SGL_RQ_DST); /**< Destination Single Transaction Request,Address offset: 0x28 */ + DMA_REG(LST_SRC); /**< Source Last Transaction Request, Address offset: 0x30 */ + DMA_REG(LST_DST); /**< Destination Last Transaction Request, Address offset: 0x38 */ +} DMA_HS_REGS; + +/* DMA/Miscellaneous_Registers Registers */ +typedef struct +{ + DMA_REG(CFG); /**< DMA Configuration, Address offset: 0x00 */ + DMA_REG(CH_EN); /**< DMA Channel Enable, Address offset: 0x08 */ + DMA_REG(ID); /**< DMA ID, Address offset: 0x20 */ + DMA_REG(TEST); /**< DMA Test, Address offset: 0x28 */ + DMA_REG(LP_TIMEOUT); /**< DMA Low Power Timeout, Address offset: 0x30 */ + DMA_REG(RESERVED); /**< Reserved, Address offset: 0x38 */ + DMA_REG(COMP_PARAMS_6); /**< DMA Component Parameters 6, Address offset: 0x40 */ + DMA_REG(COMP_PARAMS_5); /**< DMA Component Parameters 5, Address offset: 0x48 */ + DMA_REG(COMP_PARAMS_4); /**< DMA Component Parameters 4, Address offset: 0x50 */ + DMA_REG(COMP_PARAMS_3); /**< DMA Component Parameters 3, Address offset: 0x58 */ + DMA_REG(COMP_PARAMS_2); /**< DMA Component Parameters 2, Address offset: 0x60 */ + DMA_REG(COMP_PARAMS_1); /**< DMA Component Parameters 1, Address offset: 0x68 */ + DMA_REG(COMPS_ID); /**< DMA Component ID, Address offset: 0x70 */ +} DMA_MISC_REGS; + +typedef struct _dma_regs +{ + DMA_CH_REGS CHANNEL[8]; /**< DMA_REG_CH register, Address offset: 0x000 */ + DMA_INT_REGS EVENT; /**< DMA_REG_INT register, Address offset: 0x2C0 */ + DMA_HS_REGS HANDSHAKE; /**< DMA_REG_HS register, Address offset: 0x368 */ + DMA_MISC_REGS MISCELLANEOU; /**< DMA_REG_MISC register, Address offset: 0x3A8 */ +} dma_regs_t; + +/** + * @brief DUAL_TIM + */ +typedef struct _dual_timer_regs +{ + __IOM uint32_t RELOAD; /**< DUAL_TIMER auto-reload register, Address offset: 0x00 */ + __IM uint32_t VALUE; /**< DUAL_TIMER counter value register, Address offset: 0x04 */ + __IOM uint32_t CTRL; /**< DUAL_TIMER control register, Address offset: 0x08 */ + __OM uint32_t INTCLR; /**< DUAL_TIMER interrupt status clear register, Address offset: 0x0C */ + __IM uint32_t RAW_INTSTAT; /**< DUAL_TIMER raw interrupt status register, Address offset: 0x10 */ + __IM uint32_t INTSTAT; /**< DUAL_TIMER interrupt status register, Address offset: 0x14 */ + __IOM uint32_t BG_LOAD; /**< DUAL_TIMER background-reload register, Address offset: 0x18 */ +} dual_timer_regs_t; + +/** + * @brief GPIO + */ +typedef struct _gpio_regs +{ + __IOM uint32_t DATA; /**< GPIO_REG_DATA register, Address offset: 0x000 */ + __IOM uint32_t DATAOUT; /**< GPIO_REG_DATAOUT register, Address offset: 0x004 */ + __IM uint32_t RESERVED0[2]; /**< GPIO_REG_RESERVED register, Address offset: 0x008 */ + __IOM uint32_t OUTENSET; /**< GPIO_REG_OUTENSET register, Address offset: 0x010 */ + __IOM uint32_t OUTENCLR; /**< GPIO_REG_OUTENCLR register, Address offset: 0x014 */ + __IOM uint32_t ALTFUNCSET; /**< GPIO_REG_ALTFUNCSET register, Address offset: 0x018 */ + __IOM uint32_t ALTFUNCCLR; /**< GPIO_REG_ALTFUNCCLR register, Address offset: 0x01C */ + __IOM uint32_t INTENSET; /**< GPIO_REG_INTENSET register, Address offset: 0x020 */ + __IOM uint32_t INTENCLR; /**< GPIO_REG_INTENCLR register, Address offset: 0x024 */ + __IOM uint32_t INTTYPESET; /**< GPIO_REG_INTTYPESET register, Address offset: 0x028 */ + __IOM uint32_t INTTYPECLR; /**< GPIO_REG_INTTYPECLR register, Address offset: 0x02C */ + __IOM uint32_t INTPOLSET; /**< GPIO_REG_INTPOLSET register, Address offset: 0x030 */ + __IOM uint32_t INTPOLCLR; /**< GPIO_REG_INTPOLCLR register, Address offset: 0x034 */ + __IOM uint32_t INTSTAT; /**< GPIO_REG_INTSTAT register, Address offset: 0x038 */ + __IM uint32_t RESERVED1[241]; /**< GPIO_REG_RESERVED register, Address offset: 0x03C */ + __IOM uint32_t MASKLOWBYTE[256]; /**< GPIO_REG_MASKLOWBYTE register, Address offset: 0x400 */ + __IOM uint32_t MASKHIGHBYTE[256]; /**< GPIO_REG_MASKHIGHBYTE register, Address offset: 0x500 */ +} gpio_regs_t; + +/** + * @brief HMAC + */ +typedef struct _hmac_regs +{ + __IOM uint32_t CTRL; /**< HMAC_REG_CTRL register, Adderss offset: 0x00 */ + __IOM uint32_t CONFIG; /**< HMAC_REG_CONFIG register, Adderss offset: 0x04 */ + __IM uint32_t STATUS; /**< HMAC_REG_STATUS register, Adderss offset: 0x08 */ + __IOM uint32_t TRAN_SIZE; /**< HMAC_REG_TRAN_SIZE register, Adderss offset: 0x0C */ + __IOM uint32_t INTERRUPT; /**< HMAC_REG_INTERRUPT register, Adderss offset: 0x10 */ + __IOM uint32_t RSTART_ADDR; /**< HMAC_REG_RSTART_ADDR register, Adderss offset: 0x14 */ + __IOM uint32_t WSTART_ADDR; /**< HMAC_REG_WSTART_ADDR register, Adderss offset: 0x18 */ + __IM uint32_t REVERSED0; /**< HMAC_REG_REVERSED register, Adderss offset: 0x1C */ + __IOM uint32_t USER_HASH[8]; /**< HMAC_REG_USER_HASH register, Adderss offset: 0x20 */ + __IM uint32_t FIFO_OUT; /**< HMAC_REG_FIFO_OUT register, Adderss offset: 0x40 */ + __OM uint32_t MESSAGE_FIFO; /**< HMAC_REG_MESSAGE_FIFO register, Adderss offset: 0x44 */ + __OM uint32_t KEY[8]; /**< HMAC_REG_KEY register, Adderss offset: 0x48 */ + __IOM uint32_t KEY_ADDR; /**< HMAC_REG_KEY_ADDR register, Adderss offset: 0x68 */ + __OM uint32_t KPORT_MASK; /**< HMAC_REG_KPORT_MASK register, Adderss offset: 0x6C */ +} hmac_regs_t; + +/** + * @brief I2C + */ +typedef struct _i2c_regs +{ + __IOM uint32_t CON; /**< I2C control, Address offset: 0x00 */ + __IOM uint32_t TAR; /**< I2C target address, Address offset: 0x04 */ + __IOM uint32_t SAR; /**< I2C slave address, Address offset: 0x08 */ + __IOM uint32_t HS_MADDR; /**< I2C HS Master Mode Code address, Address offset: 0x0C */ + __IOM uint32_t DATA_CMD; /**< I2C Rx/Tx Data Buffer and Command, Address offset: 0x10 */ + __IOM uint32_t SS_SCL_HCNT; /**< Standard Speed I2C clock SCL High Count, Address offset: 0x14 */ + __IOM uint32_t SS_SCL_LCNT; /**< Standard Speed I2C clock SCL Low Count, Address offset: 0x18 */ + __IOM uint32_t FS_SCL_HCNT; /**< Fast Speed I2C clock SCL Low Count, Address offset: 0x1C */ + __IOM uint32_t FS_SCL_LCNT; /**< Fast Speed I2C clock SCL Low Count, Address offset: 0x20 */ + __IOM uint32_t HS_SCL_HCNT; /**< High Speed I2C clock SCL Low Count, Address offset: 0x24 */ + __IOM uint32_t HS_SCL_LCNT; /**< High Speed I2C clock SCL Low Count, Address offset: 0x28 */ + __IM uint32_t INTR_STAT; /**< I2C Interrupt Status, Address offset: 0x2C */ + __IOM uint32_t INTR_MASK; /**< I2C Interrupt Mask, Address offset: 0x30 */ + __IM uint32_t RAW_INTR_STAT; /**< I2C Raw Interrupt Status, Address offset: 0x34 */ + __IOM uint32_t RX_TL; /**< I2C Receive FIFO Threshold, Address offset: 0x38 */ + __IOM uint32_t TX_TL; /**< I2C Transmit FIFO Threshold, Address offset: 0x3C */ + __IM uint32_t CLR_INTR; /**< Clear combined and Individual Interrupts, Address offset: 0x40 */ + __IM uint32_t CLR_RX_UNDER; /**< Clear RX_UNDER Interrupt, Address offset: 0x44 */ + __IM uint32_t CLR_RX_OVER; /**< Clear RX_OVER Interrupt, Address offset: 0x48 */ + __IM uint32_t CLR_TX_OVER; /**< Clear TX_OVER Interrupt, Address offset: 0x4C */ + __IM uint32_t CLR_RD_REQ; /**< Clear RQ_REQ Interrupt, Address offset: 0x50 */ + __IM uint32_t CLR_TX_ABRT; /**< Clear TX_ABRT Interrupt, Address offset: 0x54 */ + __IM uint32_t CLR_RX_DONE; /**< Clear RX_DONE Interrupt, Address offset: 0x58 */ + __IM uint32_t CLR_ACTIVITY; /**< Clear ACTIVITY Interrupt, Address offset: 0x5C */ + __IM uint32_t CLR_STOP_DET; /**< Clear STOP_DET Interrupt, Address offset: 0x60 */ + __IM uint32_t CLR_START_DET; /**< Clear START_DET Interrupt, Address offset: 0x64 */ + __IM uint32_t CLR_GEN_CALL; /**< Clear GEN_CALL Interrupt, Address offset: 0x68 */ + __IOM uint32_t ENABLE; /**< I2C Enable, Address offset: 0x6C */ + __IM uint32_t STATUS; /**< I2C Status, Address offset: 0x70 */ + __IM uint32_t TXFLR; /**< Transmit FIFO Level Register, Address offset: 0x74 */ + __IM uint32_t RXFLR; /**< Receive FIFO Level Register, Address offset: 0x78 */ + __IOM uint32_t SDA_HOLD; /**< SDA Hold Time Length Reg, Address offset: 0x7C */ + __IM uint32_t TX_ABRT_SOURCE; /**< I2C Transmit Abort Status Reg, Address offset: 0x80 */ + __IOM uint32_t SLV_DATA_NACK_ONLY; /**< Generate SLV_DATA_NACK Register, Address offset: 0x84 */ + __IOM uint32_t DMA_CR; /**< DMA Control Register, Address offset: 0x88 */ + __IOM uint32_t DMA_TDLR; /**< DMA Transmit Data Level, Address offset: 0x8C */ + __IOM uint32_t DMA_RDLR; /**< DMA Receive Data Level, Address offset: 0x90 */ + __IOM uint32_t SDA_SETUP; /**< SDA Setup Register, Address offset: 0x94 */ + __IOM uint32_t ACK_GENERAL_CALL; /**< ACK General Call Register, Address offset: 0x98 */ + __IM uint32_t ENABLE_STATUS; /**< Enable Status Register, Address offset: 0x9C */ + __IOM uint32_t FS_SPKLEN; /**< ISS and FS spike suppression limit, Address offset: 0xA0 */ + __IOM uint32_t HS_SPKLEN; /**< HS spike suppression limit, Address offset: 0xA4 */ + __IM uint32_t CLR_RESTART_DET; /**< Clear RESTART_DET Interrupt Register, Address offset: 0xA8 */ + __IOM uint32_t SCL_STUCK_AT_LOW_TIMEOUT; /**< I2C SCL Stuck at Low Timeout, Address offset: 0xAC */ + __IOM uint32_t SDA_STUCK_AT_LOW_TIMEOUT; /**< I2C SDA Stuck at Low Timeout, Address offset: 0xB0 */ + __IM uint32_t CLR_SCL_STUCK_DET; /**< Clear SCL Stuck at Low Detect Interrupt Register, Address offset: 0xB4 */ + __IM uint32_t DEVICE_ID; /**< I2C Device-ID Register, Address offset: 0xB8 */ + __IOM uint32_t SMBUS_CLK_LOW_SEXT; /**< SMBus Slave Clock Extend Timeout Register, Address offset: 0xBC */ + __IOM uint32_t SMBUS_CLK_LOW_MEXT; /**< SMBus Master Clock Extend Timeout Register, Address offset: 0xC0 */ + __IOM uint32_t SMBUS_THIGH_MAX_IDLE_COUNT; /**< SMBus Master THigh MAX Bus-idle count Register, Address offset: 0xC4 */ + __IM uint32_t SMBUS_INTSTAT; /**< SMBUS Interrupt Status Register, Address offset: 0xC8 */ + __IOM uint32_t SMBUS_INTMASK; /**< SMBus Interrupt Mask Register, Address offset: 0xCC */ + __IM uint32_t SMBUS_RAW_INTSTAT; /**< SMBus Raw Interrupt Status Register, Address offset: 0xD0 */ + __OM uint32_t SMBUS_INTCLR; /**< SMBus Clear Interrupt Register, Address offset: 0xD4 */ + __IOM uint32_t OPTIONAL_SAR; /**< I2C Optional Slave Address Register, Address offset: 0xD8 */ + __IOM uint32_t SMBUS_UDID_LSB; /**< SMBUS ARP UDID LSB Register, Address offset: 0xDC */ + __IM uint32_t RESERVED[5]; /**< I2C RESERVED register, Address offset: 0xE0 */ + __IM uint32_t COMP_PARAM_1; /**< Component Parameter Register 1, Address offset: 0xF4 */ + __IM uint32_t COMP_VERSION; /**< Component Version Register, Address offset: 0xF8 */ + __IM uint32_t COMP_TYPE; /**< Component Type Register, Address offset: 0xFC */ +} i2c_regs_t; + +/** + * @brief I2S + */ +typedef struct +{ + __IOM uint32_t DATA_L; /**< Left TX/RX buffer register, Address offset: 0x000 */ + __IOM uint32_t DATA_R; /**< Right TX/RX buffer register, Address offset: 0x004 */ + __IOM uint32_t RXEN; /**< RX enable, Address offset: 0x008 */ + __IOM uint32_t TXEN; /**< TX enable, Address offset: 0x00C */ + __IOM uint32_t RXSIZE; /**< RX data size, Address offset: 0x010 */ + __IOM uint32_t TXSIZE; /**< TX data size, Address offset: 0x014 */ + __IM uint32_t INTSTAT; /**< Interrupt status, Address offset: 0x018 */ + __IOM uint32_t INTMASK; /**< Interrupt mask, Address offset: 0x01C */ + __IM uint32_t RXOVR; /**< RX FIFO overflow flag, read to clear, Address offset: 0x020 */ + __IM uint32_t TXOVR; /**< TX FIFO overflow flag, read to clear, Address offset: 0x024 */ + __IOM uint32_t RXFIFO_TL; /**< RX FIFO threshold level, Address offset: 0x028 */ + __IOM uint32_t TXFIFO_TL; /**< TX FIFO threshold level, Address offset: 0x02C */ + __OM uint32_t RXFIFO_FLUSH; /**< RX FIFO flush, Address offset: 0x030 */ + __OM uint32_t TXFIFO_FLUSH; /**< TX FIFO flush, Address offset: 0x034 */ + __IM uint32_t RESERVED[2]; /**< Reversed, Address offset: 0x038 */ +}I2S_CHANNEL_REGS; + +typedef struct _i2s_regs +{ + __IOM uint32_t ENABLE; /**< I2S enable, Address offset: 0x000 */ + __IOM uint32_t RBEN; /**< I2S receiver block enable, Address offset: 0x004 */ + __IOM uint32_t TBEN; /**< I2S transmitter block enable, Address offset: 0x008 */ + __IOM uint32_t CLKEN; /**< Clock enable, Address offset: 0x00C */ + __IOM uint32_t CLKCONFIG; /**< Clock configuration, Address offset: 0x010 */ + __OM uint32_t RXFIFO_RST; /**< Receiver block FIFO reset, Address offset: 0x014 */ + __OM uint32_t TXFIFO_RST; /**< Transmitter block FIFO reset, Address offset: 0x018 */ + __IM uint32_t RESERVED0; /**< Reversed, Address offset: 0x01C */ + I2S_CHANNEL_REGS I2S_CHANNEL[4]; /**< I2S channels registers, Address offset: 0x020 */ + __IM uint32_t RESERVED1[40]; /**< Reversed, Address offset: 0x120 */ + __IM uint32_t RXDMA; /**< Receiver block DMA register, Address offset: 0x1C0 */ + __OM uint32_t RXDMA_RST; /**< Receiver block DMA reset, Address offset: 0x1C4 */ + __OM uint32_t TXDMA; /**< Transmitter block DMA register, Address offset: 0x1C8 */ + __OM uint32_t TXDMA_RST; /**< Transmitter block DMA reset, Address offset: 0x1CC */ + __IM uint32_t RESERVED2[8]; /**< Reversed, Address offset: 0x1D0 */ + __IM uint32_t I2S_PARAM2; /**< I2S component parameter register 2, Address offset: 0x1F0 */ + __IM uint32_t I2S_PARAM1; /**< I2S component parameter register 1, Address offset: 0x1F4 */ + __IM uint32_t I2S_VERSION; /**< I2S component version, Address offset: 0x1F8 */ + __IM uint32_t I2S_TYPE; /**< I2S component type, Address offset: 0x1FC */ +} i2s_regs_t; + +/** + * @brief ISO7816 + */ +typedef struct _iso7816_regs +{ + __OM uint32_t CTRL; /**< Control Register, Address offset: 0x0000 */ + __IM uint32_t STAT; /**< Status Register, Address offset: 0x0004 */ + __IOM uint32_t CLK_CFG; /**< Clock Configuration Register , Address offset: 0x0008 */ + __IOM uint32_t RESERVED0[1]; /**< RESERVED, Address offset: 0x000C */ + __IOM uint32_t TIMES_CFG; /**< Times Configuration Register , Address offset: 0x0010 */ + __IOM uint32_t DATA_CFG; /**< Data Configuration Register , Address offset: 0x0014 */ + __IM uint32_t ADDR; /**< Address Register , Address offset: 0x0018 */ + __IOM uint32_t START_ADDR; /**< Start Address Register , Address offset: 0x001C */ + __IOM uint32_t RX_END_ADDR; /**< RX End Address Register , Address offset: 0x0020 */ + __IOM uint32_t TX_END_ADDR; /**< TX End Address Register , Address offset: 0x0024 */ +} iso7816_regs_t; + +/** + * @brief MCU_SUB + */ +typedef struct _mcu_sub_regs +{ + __IM uint32_t SENSE_ADC_FIFO; /**< MCU_SUB_REG_SENSE_ADC_FIFO, Address offset: 0x000 */ + __IM uint32_t RESERVED0[63]; /**< RESERVED, Address offset: 0x004 */ + __IOM uint32_t SENSE_FF_THRESH; /**< MCU_SUB_REG_SENSE_FF_THRESH, Address offset: 0x100 */ + __IM uint32_t SENSE_ADC_STAT; /**< MCU_SUB_REG_SENSE_ADC_STAT, Address offset: 0x104 */ + __IM uint32_t RESERVED1[62]; /**< RESERVED, Address offset: 0x108 */ + __IOM uint32_t COMM_TMR_DEEPSLPSTAT; /**< MCU_SUB_REG_COMM_TMR_DEEPSLPSTAT, Address offset: 0x200 */ + __IM uint32_t RESERVED2; /**< RESERVED, Address offset: 0x204 */ + __IOM uint32_t DPAD_RE_N_BUS; /**< MCU_SUB_REG_DPAD_RE_N_BUS, Address offset: 0x208 */ + __IM uint32_t RESERVED3; /**< RESERVED, Address offset: 0x20C */ + __IOM uint32_t DPAD_RTYP_BUS; /**< MCU_SUB_REG_DPAD_RTYP_BUS, Address offset: 0x210 */ + __IM uint32_t RESERVED4; /**< RESERVED, Address offset: 0x214 */ + __IOM uint32_t DPAD_IE_N_BUS; /**< MCU_SUB_REG_DPAD_IE_N_BUS, Address offset: 0x218 */ + __IM uint32_t RESERVED5; /**< RESERVED, Address offset: 0x21C */ + __IOM uint32_t MSIO_REG0; /**< MCU_SUB_REG_MSIO_REG, Address offset: 0x220 */ + __IOM uint32_t BLE_FERP_CTL; /**< MCU_SUB_REG_BLE_FERP_CTL, Address offset: 0x224 */ + __IOM uint32_t DMA_ACC_SEL; /**< MCU_SUB_REG_DMA_ACC_SEL, Address offset: 0x228 */ + __IOM uint32_t SECURITY_RESET; /**< MCU_SUB_REG_SECURITY_RESET, Address offset: 0x22C */ + __IOM uint32_t PMU_ID; /**< MCU_SUB_REG_PMU_ID, Address offset: 0x230 */ + __IOM uint32_t PWR_AVG_CTL; /**< MCU_SUB_REG_PWR_AVG_CTL_REG, Address offset: 0x234 */ + __IOM uint32_t CLK_CAL_CTL[2]; /**< MCU_SUB_REG_CLK_CAL_CTL_REG0~1, Address offset: 0x238 */ + __IOM uint32_t DPAD_MUX_CTL0_7; /**< MCU_SUB_REG_DPAD_MUX_CTL_00_07, Address offset: 0x240 */ + __IOM uint32_t DPAD_MUX_CTL8_15; /**< MCU_SUB_REG_DPAD_MUX_CTL_08_15, Address offset: 0x244 */ + __IOM uint32_t DPAD_MUX_CTL16_23; /**< MCU_SUB_REG_DPAD_MUX_CTL_16_23, Address offset: 0x248 */ + __IOM uint32_t DPAD_MUX_CTL24_31; /**< MCU_SUB_REG_DPAD_MUX_CTL_24_31, Address offset: 0x24C */ + __IM uint32_t RESERVED6; /**< RESERVED, Address offset: 0x250 */ + __IOM uint32_t EFUSE_PWR_DELTA[2]; /**< MCU_SUB_REG_EFUSE_PWR_DELTA0~1, Address offset: 0x254 */ + __IM uint32_t RESERVED7; /**< RESERVED, Address offset: 0x250 */ + __IOM uint32_t EFUSE_PWR_CTRL[2]; /**< MCU_SUB_REG_EFUSE_PWR_CTRL0~1, Address offset: 0x260 */ + __IOM uint32_t I2S_CLK_CFG; /**< MCU_SUB_REG_I2S_CLK_CFG, Address offset: 0x268 */ + __IM uint32_t RESERVED8[5]; /**< RESERVED, Address offset: 0x26C */ + __IOM uint32_t MCU_SUB_REG; /**< MCU_SUB_REG_MCU_SUB_REG, Address offset: 0x280 */ + __IM uint32_t RESERVED9[3]; /**< RESERVED, Address offset: 0x284 */ + __IOM uint32_t AON_PAD_MUX_CTL; /**< MCU_SUB_REG_AON_PAD_MUX_CTL, Address offset: 0x290 */ + __IOM uint32_t MSIO_PAD_MUX_CTL; /**< MCU_SUB_REG_MSIO_PAD_MUX_CTL, Address offset: 0x294 */ + __IM uint32_t RESERVED10[2]; /**< RESERVED, Address offset: 0x298 */ + __IOM uint32_t MCU_SUBSYS_CG_CTRL[3]; /**< MCU_SUB_REG_MCU_SUBSYS_CG_CTRL0~2, Address offset: 0x2A0 */ + __IOM uint32_t MCU_PERIPH_CG; /**< MCU_SUB_REG_MCU_PERIPH_CG, Address offset: 0x2AC */ + __IOM uint32_t MCU_SUBSYS_CLK_CTRL; /**< MCU_SUB_REG_MCU_SUBSYS_CLK_CTRL, Address offset: 0x2B0 */ + __IM uint32_t RESERVED11[3]; /**< RESERVED, Address offset: 0x2B4 */ + __IOM uint32_t BLE_DSLEEP_CORR_EN; /**< MCU_SUB_REG_BLE_DSLEEP_CORR_EN, Address offset: 0x2C0 */ + __IOM uint32_t BLE_DSLEEP_HW_TIM_CORR; /**< MCU_SUB_REG_BLE_DSLEEP_HW_TIM_CORR,Address offset: 0x2C4 */ +} mcu_sub_regs_t; + +/** + * @brief PKC + */ +typedef struct _pkc_regs +{ + __IOM uint32_t CTRL; /**< PKC_REG_CTRL, Address offset: 0x00 */ + __IOM uint32_t CONFIG0; /**< PKC_REG_CONFIG0, Address offset: 0x04 */ + __IOM uint32_t CONFIG1; /**< PKC_REG_CONFIG1, Address offset: 0x08 */ + __IOM uint32_t CONFIG2; /**< PKC_REG_CONFIG2, Address offset: 0x0C */ + __IOM uint32_t CONFIG3; /**< PKC_REG_CONFIG3, Address offset: 0x10 */ + __IOM uint32_t CONFIG4; /**< PKC_REG_CONFIG4, Address offset: 0x14 */ + __IOM uint32_t CONFIG5; /**< PKC_REG_CONFIG5, Address offset: 0x18 */ + __IOM uint32_t CONFIG6; /**< PKC_REG_CONFIG6, Address offset: 0x1C */ + __IOM uint32_t CONFIG7; /**< PKC_REG_CONFIG7, Address offset: 0x20 */ + __IOM uint32_t CONFIG8; /**< PKC_REG_CONFIG8, Address offset: 0x24 */ + __IOM uint32_t CONFIG9; /**< PKC_REG_CONFIG9, Address offset: 0x28 */ + __IOM uint32_t CONFIG10; /**< PKC_REG_CONFIG10, Address offset: 0x2C */ + __IOM uint32_t CONFIG11; /**< PKC_REG_CONFIG11, Address offset: 0x30 */ + __IOM uint32_t CONFIG12; /**< PKC_REG_CONFIG12, Address offset: 0x34 */ + __IOM uint32_t CONFIG13; /**< PKC_REG_CONFIG13, Address offset: 0x38 */ + __IM uint32_t REVERSED0; /**< PKC_REG_REVERSED, Address offset: 0x3C */ + __IOM uint32_t SW_CTRL; /**< PKC_REG_SW_CTRL, Address offset: 0x40 */ + __IOM uint32_t SW_CONFIG0; /**< PKC_REG_SW_CONFIG, Address offset: 0x44 */ + __IOM uint32_t SW_CONFIG1; /**< PKC_REG_SW_CONFIG, Address offset: 0x48 */ + __IOM uint32_t SW_CONFIG2; /**< PKC_REG_SW_CONFIG, Address offset: 0x4C */ + __IOM uint32_t SW_CONFIG3; /**< PKC_REG_SW_CONFIG, Address offset: 0x50 */ + __IOM uint32_t SW_CONFIG4; /**< PKC_REG_SW_CONFIG, Address offset: 0x54 */ + __IOM uint32_t SW_CONFIG5; /**< PKC_REG_SW_CONFIG, Address offset: 0x58 */ + __IOM uint32_t SW_CONFIG6; /**< PKC_REG_SW_CONFIG, Address offset: 0x5C */ + __IOM uint32_t SW_CONFIG7; /**< PKC_REG_SW_CONFIG, Address offset: 0x60 */ + __IM uint32_t SW_CONFIG8; /**< PKC_REG_SW_CONFIG, Address offset: 0x64 */ + __IOM uint32_t SW_CONFIG9; /**< PKC_REG_SW_CONFIG, Address offset: 0x68 */ + __IOM uint32_t SW_CONFIG10; /**< PKC_REG_SW_CONFIG, Address offset: 0x6C */ + __IOM uint32_t SW_CONFIG11; /**< PKC_REG_SW_CONFIG, Address offset: 0x70 */ + __IOM uint32_t SW_CONFIG12; /**< PKC_REG_SW_CONFIG, Address offset: 0x74 */ + __IOM uint32_t SW_CONFIG13; /**< PKC_REG_SW_CONFIG, Address offset: 0x78 */ + __IM uint32_t REVERSED1; /**< PKC_REG_REVERSED, Address offset: 0x7C */ + __IOM uint32_t INTSTAT; /**< PKC_REG_INT_STATUS, Address offset: 0x80 */ + __IOM uint32_t INTEN; /**< PKC_REG_INT_ENABLE, Address offset: 0x84 */ + __IM uint32_t WORKSTAT; /**< PKC_REG_WORK_STATUS, Address offset: 0x88 */ + __IM uint32_t REVERSED2; /**< PKC_REG_REVERSED, Address offset: 0x8C */ + __IOM uint32_t DUMMY0; /**< PKC_REG_DUMMY0, Address offset: 0x90 */ + __IOM uint32_t DUMMY1; /**< PKC_REG_DUMMY1, Address offset: 0x94 */ + __IOM uint32_t DUMMY2; /**< PKC_REG_DUMMY2, Address offset: 0x98 */ +} pkc_regs_t; + +/** + * @brief PWM + */ +typedef struct _pwm_regs +{ + __IOM uint32_t MODE; /**< PWM_REG_MODE, Address, offset: 0x00 */ + __IOM uint32_t UPDATE; /**< PWM_REG_UPDATE, Address, offset: 0x04 */ + __IOM uint32_t PRD; /**< PWM_REG_PRD, Address, offset: 0x08 */ + __IOM uint32_t CMPA0; /**< PWM_REG_CMPA0, Address, offset: 0x0C */ + __IOM uint32_t CMPA1; /**< PWM_REG_CMPA1, Address, offset: 0x10 */ + __IOM uint32_t CMPB0; /**< PWM_REG_CMPB0, Address, offset: 0x14 */ + __IOM uint32_t CMPB1; /**< PWM_REG_CMPB1, Address, offset: 0x18 */ + __IOM uint32_t CMPC0; /**< PWM_REG_CMPC0, Address, offset: 0x1C */ + __IOM uint32_t CMPC1; /**< PWM_REG_CMPC1, Address, offset: 0x20 */ + __IOM uint32_t AQCTRL; /**< PWM_REG_AQCTRL, Address, offset: 0x24 */ + __IOM uint32_t BRPRD; /**< PWM_REG_BRPRD, Address, offset: 0x28 */ + __IOM uint32_t HOLD; /**< PWM_REG_HOLD, Address, offset: 0x2C */ +} pwm_regs_t; + +/** + * @brief SSI + */ +typedef struct _ssi_regs +{ + __IOM uint32_t CTRL0; /**< SSI_REG_CTRL0, Address offset: 0x00 */ + __IOM uint32_t CTRL1; /**< SSI_REG_CTRL1, Address offset: 0x04 */ + __IOM uint32_t SSI_EN; /**< SSI_REG_SSI_EN, Address offset: 0x08 */ + __IOM uint32_t MWC; /**< SSI_REG_MWC, Address offset: 0x0C */ + __IOM uint32_t SE; /**< SSI_REG_SE, Address offset: 0x10 */ + __IOM uint32_t BAUD; /**< SSI_REG_BAUD, Address offset: 0x14 */ + __IOM uint32_t TX_FTL; /**< SSI_REG_TX_FTL, Address offset: 0x18 */ + __IOM uint32_t RX_FTL; /**< SSI_REG_RX_FTL, Address offset: 0x1C */ + __IM uint32_t TX_FL; /**< SSI_REG_TX_FL, Address offset: 0x20 */ + __IM uint32_t RX_FL; /**< SSI_REG_RX_FL, Address offset: 0x24 */ + __IM uint32_t STAT; /**< SSI_REG_STAT, Address offset: 0x28 */ + __IOM uint32_t INTMASK; /**< SSI_REG_INT_MASK, Address offset: 0x2C */ + __IM uint32_t INTSTAT; /**< SSI_REG_INT_STAT, Address offset: 0x30 */ + __IM uint32_t RAW_INTSTAT; /**< SSI_REG_RAW_INT_STAT, Address offset: 0x34 */ + __IM uint32_t TXOIC; /**< SSI_REG_TXOIC, Address offset: 0x38 */ + __IM uint32_t RXOIC; /**< SSI_REG_RXOIC, Address offset: 0x3C */ + __IM uint32_t RXUIC; /**< SSI_REG_RXUIC, Address offset: 0x40 */ + __IM uint32_t MSTIC; /**< SSI_REG_MSTIC, Address offset: 0x44 */ + __IM uint32_t INTCLR; /**< SSI_REG_INT_CLR, Address offset: 0x48 */ + __IOM uint32_t DMAC; /**< SSI_REG_DMAC, Address offset: 0x4C */ + __IOM uint32_t DMA_TDL; /**< SSI_REG_DMA_TDL, Address offset: 0x50 */ + __IOM uint32_t DMA_RDL; /**< SSI_REG_DMA_RDL, Address offset: 0x54 */ + __IM uint32_t ID; /**< SSI_REG_ID, Address offset: 0x58 */ + __IM uint32_t VERSION_ID; /**< SSI_REG_VERSION_ID, Address offset: 0x5C */ + __IOM uint32_t DATA; /**< SSI_REG_DATA, Address offset: 0x60 */ + __IM uint32_t REVERSED[35]; /**< SSI_REG_REVERSED, Address offset: 0x64 */ + __IOM uint32_t RX_SAMPLE_DLY; /**< SSI_REG_RX_SAMPLE_DLY, Address offset: 0xF0 */ + __IOM uint32_t SPI_CTRL0; /**< SSI_REG_SPI_CTRL0, Address offset: 0xF4 */ +} ssi_regs_t; + +/** + * @brief TIM + */ +typedef struct _timer_regs +{ + __IOM uint32_t CTRL; /**< TIMER control register, Address offset: 0x00 */ + __IOM uint32_t VALUE; /**< TIMER counter value register, Address offset: 0x04 */ + __IOM uint32_t RELOAD; /**< TIMER auto-reload register, Address offset: 0x08 */ + __IOM uint32_t INTSTAT; /**< TIMER interrupt status register, Address offset: 0x0C */ +} timer_regs_t; + +/** + * @brief UART + */ +typedef struct _uart_regs +{ + union + { + __IOM uint32_t RBR; + __IOM uint32_t DLL; + __IOM uint32_t THR; + } RBR_DLL_THR; /**< UART_REG_RBR_DLL_THR, Address offset: 0x00 */ + union + { + __IOM uint32_t DLH; + __IOM uint32_t IER; + } DLH_IER; /**< UART_REG_DLH_IER, Address offset: 0x04 */ + union + { + __IOM uint32_t FCR; + __IOM uint32_t IIR; + } FCR_IIR; /**< UART_REG_FCR_IIR, Address offset: 0x08 */ + __IOM uint32_t LCR; /**< UART_REG_LCR, Address offset: 0x0C */ + __IOM uint32_t MCR; /**< UART_REG_MCR, Address offset: 0x10 */ + __IOM uint32_t LSR; /**< UART_REG_LSR, Address offset: 0x14 */ + __IOM uint32_t MSR; /**< UART_REG_MSR, Address offset: 0x18 */ + __IOM uint32_t SCRATCHPAD; /**< UART_REG_SCRATCHPAD, Address offset: 0x1C */ + __IOM uint32_t LPDLL; /**< UART_REG_LPDLL, Address offset: 0x20 */ + __IOM uint32_t LPDLH; /**< UART_REG_LPDLH, Address offset: 0x24 */ + __IOM uint32_t REVERSED0[2]; /**< REVERSED, Address offset: 0x28 */ + union + { + __IOM uint32_t SRBR[16]; + __IOM uint32_t STHR[16]; + } SRBR_STHR; /**< UART_REG_SRBR_STHR, Address offset: 0x30 */ + __IOM uint32_t FAR; /**< UART_REG_FAR, Address offset: 0x70 */ + __IOM uint32_t TFR; /**< UART_REG_TFR, Address offset: 0x74 */ + __IOM uint32_t TFW; /**< UART_REG_TFW, Address offset: 0x78 */ + __IOM uint32_t USR; /**< UART_REG_USR, Address offset: 0x7C */ + __IOM uint32_t TFL; /**< UART_REG_TFL, Address offset: 0x80 */ + __IOM uint32_t RFL; /**< UART_REG_RFL, Address offset: 0x84 */ + __IOM uint32_t SRR; /**< UART_REG_SRR, Address offset: 0x88 */ + __IOM uint32_t SRTS; /**< UART_REG_SRTS, Address offset: 0x8C */ + __IOM uint32_t SBCR; /**< UART_REG_SBCR, Address offset: 0x90 */ + __IOM uint32_t SDMAM; /**< UART_REG_SDMAM, Address offset: 0x94 */ + __IOM uint32_t SFE; /**< UART_REG_SFE, Address offset: 0x98 */ + __IOM uint32_t SRT; /**< UART_REG_SRT, Address offset: 0x9C */ + __IOM uint32_t STET; /**< UART_REG_STET, Address offset: 0xA0 */ + __IOM uint32_t HTX; /**< UART_REG_HTX, Address offset: 0xA4 */ + __IOM uint32_t DMASA; /**< UART_REG_DMASA, Address offset: 0xA8 */ + __IOM uint32_t TCR; /**< UART_REG_TCR, Address offset: 0xAC */ + __IOM uint32_t DE_EN; /**< UART_REG_DE_EN, Address offset: 0xB0 */ + __IOM uint32_t RE_EN; /**< UART_REG_RE_EN, Address offset: 0xB4 */ + __IOM uint32_t DET; /**< UART_REG_DET, Address offset: 0xB8 */ + __IOM uint32_t TAT; /**< UART_REG_TAT, Address offset: 0xBC */ + __IOM uint32_t DLF; /**< UART_REG_DLF, Address offset: 0xC0 */ + __IOM uint32_t RAR; /**< UART_REG_RAR, Address offset: 0xC4 */ + __IOM uint32_t TAR; /**< UART_REG_TAR, Address offset: 0xC8 */ + __IOM uint32_t LCR_EXT; /**< UART_REG_LCR_EXT, Address offset: 0xCC */ + __IOM uint32_t REVERSED1[9]; /**< REVERSED, Address offset: 0xD0 */ + __IOM uint32_t CPR; /**< UART_REG_CPR, Address offset: 0xF4 */ + __IOM uint32_t UCV; /**< UART_REG_UCV, Address offset: 0xF8 */ + __IOM uint32_t CTR; /**< UART_REG_CTR, Address offset: 0xFC */ +} uart_regs_t; + +/** + * @brief WDT + */ +typedef struct _wdt_regs +{ + __IOM uint32_t LOAD; /**< WDT_REG_LOAD, Address offset: 0x000 */ + __IOM uint32_t VALUE; /**< WDT_REG_VALUE, Address offset: 0x004 */ + __IOM uint32_t CTRL; /**< WDT_REG_CONTROL, Address offset: 0x008 */ + __IOM uint32_t INTCLR; /**< WDT_REG_INTCLR, Address offset: 0x00C */ + __IOM uint32_t RIS; /**< WDT_REG_RIS, Address offset: 0x010 */ + __IOM uint32_t MIS; /**< WDT_REG_MIS, Address offset: 0x014 */ + __IOM uint32_t REVERSED[762]; /**< REVERSED, Address offset: 0x018 */ + __IOM uint32_t LOCK; /**< WDT_REG_LOCK, Address offset: 0xC00 */ +} wdt_regs_t; + +/** + * @brief XQSPI + */ +/* XQSPI/Cache Registers */ +typedef struct +{ + __IOM uint32_t CTRL0; /**< Cache Control 0 Register, Address offset: 0x00 */ + __IOM uint32_t CTRL1; /**< Cache Control 1 Register, Address offset: 0x04 */ + __IM uint32_t HIT_COUNT; /**< Cache hits count, Address offset: 0x08 */ + __IM uint32_t MISS_COUNT; /**< Cache miss count, Address offset: 0x0C */ + __IM uint32_t STAT; /**< Status Register, Address offset: 0x10 */ + __IOM uint32_t BUF_FIRST_ADDR; /**< Preload start address, Address offset: 0x14 */ + __IOM uint32_t BUF_LAST_ADDR; /**< Preload last address, Address offset: 0x18 */ +} CACHE_REGS; + +/* XQSPI/QSPI Registers */ +typedef struct +{ + __OM uint32_t TX_DATA; /**< Serial Data Transmit, Address offset: 0x00 */ + __IM uint32_t RX_DATA; /**< Serial Data Receive, Address offset: 0x04 */ + __IM uint32_t RESERVED0; /**< RESERVED, Address offset: 0x08 */ + __IOM uint32_t CTRL; /**< Control, Address offset: 0x0C */ + __IOM uint32_t AUX_CTRL; /**< Auxiliary Control, Address offset: 0x10 */ + __IM uint32_t STAT; /**< Status Control, Address offset: 0x14 */ + __IOM uint32_t SLAVE_SEL; /**< Slave Select, Address offset: 0x18 */ + __IOM uint32_t SLAVE_SEL_POL; /**< Slave Select Polarity, Address offset: 0x1C */ + __IOM uint32_t INTEN; /**< Interrupt Enable, Address offset: 0x20 */ + __IM uint32_t INTSTAT; /**< Interrupt Status, Address offset: 0x24 */ + __OM uint32_t INTCLR; /**< Interrupt Clear, Address offset: 0x28 */ + __IM uint32_t TX_FIFO_LVL; /**< TX FIFO Level, Address offset: 0x2C */ + __IM uint32_t RX_FIFO_LVL; /**< RX FIFO Level, Address offset: 0x30 */ + __IM uint32_t RESERVED1; /**< RESERVED, Address offset: 0x34 */ + __IOM uint32_t MSTR_IT_DELAY; /**< Master Inter-transfer Delay, Address offset: 0x38 */ + __IOM uint32_t SPIEN; /**< SPI Enable, Address offset: 0x3C */ + __IOM uint32_t SPI_GP_SET; /**< GPO Set / GPO State, Address offset: 0x40 */ + __IOM uint32_t SPI_GP_CLEAR; /**< GPO Clear / GPI State, Address offset: 0x44 */ + __IM uint32_t RX_DATA0_31; /**< 32-bit LSB word(0~31), Address offset: 0x48 */ + __IM uint32_t RX_DATA32_63; /**< 32-bit LSB word(32~63), Address offset: 0x4C */ + __IM uint32_t RX_DATA64_95; /**< 32-bit LSB word(64~95), Address offset: 0x50 */ + __IM uint32_t RX_DATA96_127; /**< 32-bit MSB word(96~127), Address offset: 0x54 */ + __OM uint32_t P_IV; /**< 32-BIT IV Key, Address offset: 0x58 */ + __IOM uint32_t FLASH_WRITE; /**< use for flash write, Address offset: 0x5C */ + __IOM uint32_t P_KEY_VALID_KPORT; /**< Status bit, Address offset: 0x60 */ + __IOM uint32_t P_RD_KEY_EN_KPORT; /**< Enable read key on keyport, Address offset: 0x64 */ + __IOM uint32_t P_KEY_ADDR; /**< Present key address, Address offset: 0x68 */ + __IOM uint32_t P_KEYPORT_MASK; /**< Present key mask, Address offset: 0x6C */ + __IOM uint32_t BYPASS; /**< Enable Bypass, Address offset: 0x70 */ +} QSPI_REGS; + +/* XQSPI/XIP Registers */ +typedef struct +{ + __IOM uint32_t CTRL0; /**< XIP Control 0 Register, Address offset: 0x00 */ + __IOM uint32_t CTRL1; /**< XIP Control 1 Register, Address offset: 0x04 */ + __IOM uint32_t CTRL2; /**< XIP Control 2 Register, Address offset: 0x08 */ + __IOM uint32_t CTRL3; /**< XIP Enable Request, Address offset: 0x0C */ + __IOM uint32_t STAT; /**< XIP Enable Output (Stat0), Address offset: 0x10 */ + __IM uint32_t INTEN; /**< Interrupt Enable (Intr0), Address offset: 0x14 */ + __IM uint32_t INTSTAT; /**< Interrupt Status (Intr1), Address offset: 0x18 */ + __IM uint32_t INTREQ; /**< Interrupt Status (Intr2), Address offset: 0x1C */ + __OM uint32_t INTSET; /**< Interrupt Set (Intr3), Address offset: 0x20 */ + __OM uint32_t INTCLR; /**< Interrupt Clear (Intr4), Address offset: 0x24 */ +} XIP_REGS; + +typedef struct _xqspi_regs +{ + CACHE_REGS CACHE; /**< CACHE Registers, Address offset: 0x000 */ + __IM uint32_t RESERVED0[249]; + QSPI_REGS QSPI; /**< QSPI Registers, Address offset: 0x400 */ + __IM uint32_t RESERVED1[483]; + XIP_REGS XIP; /**< XIP Registers, Address offset: 0xC00 */ +} xqspi_regs_t; + +/** + * @brief EFUSE + */ +typedef struct _efuse_regs +{ + __IOM uint32_t TPGM; /**< EFUSE_TPGM, Address offset: 0x000 */ + __IOM uint32_t PGENB; /**< EFUSE_PGENB, Address offset: 0x004 */ + __IM uint32_t TEST_MODE; /**< EFUSE_TEST_MODE, Address offset: 0x008 */ + __OM uint32_t OPERATION; /**< EFUSE_OPERATION, Address offset: 0x00C */ + __IM uint32_t STAT; /**< EFUSE_STATUS, Address offset: 0x010 */ + __IOM uint32_t KEY_MASK; /**< EFUSE_KEY_MASK, Address offset: 0x014 */ + __IOM uint32_t CRC_ADDR; /**< EFUSE_CRC_START_ADDR, Address offset: 0x018 */ + __IM uint32_t CRC_OUTPUT; /**< EFUSE_CRC_OUTPUT, Address offset: 0x01C */ + __IOM uint32_t TRIM_ADDR; /**< EFUSE_TRIM_ADDR, Address offset: 0x020 */ + __IOM uint32_t TRIM_LEN; /**< EFUSE_TRIM_LEN, Address offset: 0x024 */ + __IM uint32_t TRIM[14]; /**< EFUSE_TRIM, Address offset: 0x028 */ +} efuse_regs_t; + +/** + * @brief RNG + */ +typedef struct _rng_regs +{ + __IOM uint32_t CTRL; /**< RNG_CTRL, Address offset: 0x000 */ + __IOM uint32_t STATUS; /**< RNG_STATUS, Address offset: 0x004 */ + __IM uint32_t DATA; /**< RNG_DATA, Address offset: 0x008 */ + __IOM uint32_t RESERVED; /**< RESERVED, Address offset: 0x00C */ + __IM uint32_t LR_STATUS; /**< RNG_LR_STATUS, Address offset: 0x010 */ + __IOM uint32_t CONFIG; /**< RNG_CONFIG, Address offset: 0x014 */ + __IOM uint32_t TSCON; /**< RNG_TSCON, Address offset: 0x018 */ + __IOM uint32_t FROCFG; /**< RNG_FROCFG, Address offset: 0x01C */ + __OM uint32_t USER_SEED; /**< RNG_USER_SEED, Address offset: 0x020 */ + __IOM uint32_t LRCON; /**< RNG_LRCON, Address offset: 0x024 */ +} rng_regs_t; + +/** @} */ /* End of group Peripheral_registers_structures */ + + +/* ==================================== End of section using anonymous unions ==================================== */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* ================================================================================================================= */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* ================================================================================================================= */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define ROM_BASE ((uint32_t)0x00000000UL) +#define FLASH_BASE ((uint32_t)0x01000000UL) +#define SRAM_BASE ((uint32_t)0x30000000UL) +#define PERIPH_BASE ((uint32_t)0xA0000000UL) + +#define TIMER0_BASE (PERIPH_BASE + 0x00000000UL) +#define TIMER1_BASE (PERIPH_BASE + 0x00001000UL) +#define DUAL_TIMER0_BASE (PERIPH_BASE + 0x00002000UL) +#define DUAL_TIMER1_BASE (PERIPH_BASE + 0x00002020UL) +#define WDT_BASE (PERIPH_BASE + 0x00008000UL) +#define SPIM_BASE (PERIPH_BASE + 0x0000C000UL) +#define SPIS_BASE (PERIPH_BASE + 0x0000C100UL) +#define QSPI0_BASE (PERIPH_BASE + 0x0000C200UL) +#define I2C0_BASE (PERIPH_BASE + 0x0000C300UL) +#define I2C1_BASE (PERIPH_BASE + 0x0000C400UL) +#define AON_BASE (PERIPH_BASE + 0x0000C500UL) +#define UART0_BASE (PERIPH_BASE + 0x0000C600UL) +#define UART1_BASE (PERIPH_BASE + 0x0000C700UL) +#define QSPI1_BASE (PERIPH_BASE + 0x0000C800UL) +#define PWM0_BASE (PERIPH_BASE + 0x0000C900UL) +#define I2S_M_BASE (PERIPH_BASE + 0x0000CA00UL) +#define PWM1_BASE (PERIPH_BASE + 0x0000CC00UL) +#define XQSPI_BASE (PERIPH_BASE + 0x0000D000UL) +#define MCU_SUB_BASE (PERIPH_BASE + 0x0000E000UL) +#define I2S_S_BASE (PERIPH_BASE + 0x0000F000UL) +#define ISO7816_BASE (PERIPH_BASE + 0x0000F200UL) +#define GPIO0_BASE (PERIPH_BASE + 0x00010000UL) +#define GPIO1_BASE (PERIPH_BASE + 0x00011000UL) +#define GPIO2_BASE (PERIPH_BASE + 0x00012000UL) +#define DMA_BASE (PERIPH_BASE + 0x00013000UL) +#define PKC_BASE (PERIPH_BASE + 0x00014000UL) +#define AES_BASE (PERIPH_BASE + 0x00015400UL) +#define HMAC_BASE (PERIPH_BASE + 0x00015800UL) +#define EFUSE_BASE (PERIPH_BASE + 0x00016400UL) +#define RNG_BASE (PERIPH_BASE + 0x00017800UL) + +#define PKC_SPRAM_BASE (PKC_BASE + 0x00000800UL) +#define KRAM_BASE (PERIPH_BASE + 0x00017000UL) +#define EFUSE_STORAGE_BASE (PERIPH_BASE + 0x00016000UL) + +/** @} */ /* End of group Peripheral_memory_map */ + + +/* ================================================================================================================= */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================================================= */ + +/** @addtogroup Peripheral_declaration + * @{ + */ + +#define TIMER0 ((timer_regs_t *)TIMER0_BASE) +#define TIMER1 ((timer_regs_t *)TIMER1_BASE) +#define DUAL_TIMER0 ((dual_timer_regs_t *)DUAL_TIMER0_BASE) +#define DUAL_TIMER1 ((dual_timer_regs_t *)DUAL_TIMER1_BASE) +#define WDT ((wdt_regs_t *)WDT_BASE) +#define SPIM ((ssi_regs_t *)SPIM_BASE) +#define SPIS ((ssi_regs_t *)SPIS_BASE) +#define QSPI0 ((ssi_regs_t *)QSPI0_BASE) +#define QSPI1 ((ssi_regs_t *)QSPI1_BASE) +#define I2C0 ((i2c_regs_t *)I2C0_BASE) +#define I2C1 ((i2c_regs_t *)I2C1_BASE) +#define AON ((aon_regs_t *)AON_BASE) +#define UART0 ((uart_regs_t *)UART0_BASE) +#define UART1 ((uart_regs_t *)UART1_BASE) +#define PWM0 ((pwm_regs_t *)PWM0_BASE) +#define PWM1 ((pwm_regs_t *)PWM1_BASE) +#define I2S_M ((i2s_regs_t *)I2S_M_BASE) +#define I2S_S ((i2s_regs_t *)I2S_S_BASE) +#define ISO7816 ((iso7816_regs_t *)ISO7816_BASE) +#define XQSPI ((xqspi_regs_t *)XQSPI_BASE) +#define MCU_SUB ((mcu_sub_regs_t *)MCU_SUB_BASE) +#define GPIO0 ((gpio_regs_t *)GPIO0_BASE) +#define GPIO1 ((gpio_regs_t *)GPIO1_BASE) +#define GPIO2 ((gpio_regs_t *)GPIO2_BASE) +#define DMA ((dma_regs_t *)DMA_BASE) +#define PKC ((pkc_regs_t *)PKC_BASE) +#define AES ((aes_regs_t *)AES_BASE) +#define HMAC ((hmac_regs_t *)HMAC_BASE) +#define EFUSE ((efuse_regs_t *)EFUSE_BASE) +#define RNG ((rng_regs_t *)RNG_BASE) +#define DMA0 DMA + +/** @} */ /* End of group Peripheral_declaration */ + +/** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/* ================================================================================================================= */ +/* ================ AES ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for AES_CTRL register *******************/ +#define AES_CTRL_ENABLE_Pos (0U) +#define AES_CTRL_ENABLE_Len (1U) +#define AES_CTRL_ENABLE_Msk (1U << AES_CTRL_ENABLE_Pos) +#define AES_CTRL_ENABLE AES_CTRL_ENABLE_Msk + +#define AES_CTRL_START_NORMAL_Pos (1U) +#define AES_CTRL_START_NORMAL_Len (1U) +#define AES_CTRL_START_NORMAL_Msk (1U << AES_CTRL_START_NORMAL_Pos) +#define AES_CTRL_START_NORMAL AES_CTRL_START_NORMAL_Msk + +#define AES_CTRL_START_DMA_Pos (2U) +#define AES_CTRL_START_DMA_Len (1U) +#define AES_CTRL_START_DMA_Msk (1U << AES_CTRL_START_DMA_Pos) +#define AES_CTRL_START_DMA AES_CTRL_START_DMA_Msk + +#define AES_CTRL_ENABLE_RKEY_Pos (3U) +#define AES_CTRL_ENABLE_RKEY_Len (1U) +#define AES_CTRL_ENABLE_RKEY_Msk (1U << AES_CTRL_ENABLE_RKEY_Pos) +#define AES_CTRL_ENABLE_RKEY AES_CTRL_ENABLE_RKEY_Msk + +/******************* Bit definition for AES_CONFIG register *******************/ +#define AES_CONFIG_KEYMODE_Pos (0U) +#define AES_CONFIG_KEYMODE_Len (2U) +#define AES_CONFIG_KEYMODE_Msk (3U << AES_CONFIG_KEYMODE_Pos) +#define AES_CONFIG_KEYMODE AES_CONFIG_KEYMODE_Msk + +#define AES_CONFIG_ENABLE_FULLMASK_Pos (3U) +#define AES_CONFIG_ENABLE_FULLMASK_Len (1U) +#define AES_CONFIG_ENABLE_FULLMASK_Msk (1U << AES_CONFIG_ENABLE_FULLMASK_Pos) +#define AES_CONFIG_ENABLE_FULLMASK AES_CONFIG_ENABLE_FULLMASK_Msk + +#define AES_CONFIG_ENABLE_ENCRYPTION_Pos (4U) +#define AES_CONFIG_ENABLE_ENCRYPTION_Len (1U) +#define AES_CONFIG_ENABLE_ENCRYPTION_Msk (1U << AES_CONFIG_ENABLE_ENCRYPTION_Pos) +#define AES_CONFIG_ENABLE_ENCRYPTION AES_CONFIG_ENABLE_ENCRYPTION_Msk + +#define AES_CONFIG_LOADSEED_Pos (5U) +#define AES_CONFIG_LOADSEED_Len (1U) +#define AES_CONFIG_LOADSEED_Msk (1U << AES_CONFIG_LOADSEED_Pos) +#define AES_CONFIG_LOADSEED AES_CONFIG_LOADSEED_Msk + +#define AES_CONFIG_FIRSTBLOCK_Pos (6U) +#define AES_CONFIG_FIRSTBLOCK_Len (1U) +#define AES_CONFIG_FIRSTBLOCK_Msk (1U << AES_CONFIG_FIRSTBLOCK_Pos) +#define AES_CONFIG_FIRSTBLOCK AES_CONFIG_FIRSTBLOCK_Msk + +#define AES_CONFIG_ENDIAN_Pos (7U) +#define AES_CONFIG_ENDIAN_Len (1U) +#define AES_CONFIG_ENDIAN_Msk (1U << AES_CONFIG_ENDIAN_Pos) +#define AES_CONFIG_ENDIAN AES_CONFIG_ENDIAN_Msk + +#define AES_CONFIG_OPMODE_Pos (8U) +#define AES_CONFIG_OPMODE_Len (3U) +#define AES_CONFIG_OPMODE_Msk (7U << AES_CONFIG_OPMODE_Pos) +#define AES_CONFIG_OPMODE AES_CONFIG_OPMODE_Msk + +#define AES_CONFIG_KEYTYPE_Pos (11U) +#define AES_CONFIG_KEYTYPE_Len (2U) +#define AES_CONFIG_KEYTYPE_Msk (3U << AES_CONFIG_KEYTYPE_Pos) +#define AES_CONFIG_KEYTYPE AES_CONFIG_KEYTYPE_Msk + +/******************* Bit definition for AES_STATUS register *******************/ +#define AES_STATUS_READY_Pos (0U) +#define AES_STATUS_READY_Len (1U) +#define AES_STATUS_READY_Msk (1U << AES_STATUS_READY_Pos) +#define AES_STATUS_READY AES_STATUS_READY_Msk + +#define AES_STATUS_TRANSDONE_Pos (1U) +#define AES_STATUS_TRANSDONE_Len (1U) +#define AES_STATUS_TRANSDONE_Msk (1U << AES_STATUS_TRANSDONE_Pos) +#define AES_STATUS_TRANSDONE AES_STATUS_TRANSDONE_Msk + +#define AES_STATUS_TRANSERR_Pos (2U) +#define AES_STATUS_TRANSERR_Len (1U) +#define AES_STATUS_TRANSERR_Msk (1U << AES_STATUS_TRANSERR_Pos) +#define AES_STATUS_TRANSERR AES_STATUS_TRANSERR_Msk + +#define AES_STATUS_KEYVALID_Pos (3U) +#define AES_STATUS_KEYVALID_Len (1U) +#define AES_STATUS_KEYVALID_Msk (1U << AES_STATUS_KEYVALID_Pos) +#define AES_STATUS_KEYVALID AES_STATUS_KEYVALID_Msk + +/******************* Bit definition for AES_INTERRUPT register *******************/ +#define AES_INTERRUPT_DONE_Pos (0U) +#define AES_INTERRUPT_DONE_Len (1U) +#define AES_INTERRUPT_DONE_Msk (1U << AES_INTERRUPT_DONE_Pos) +#define AES_INTERRUPT_DONE AES_INTERRUPT_DONE_Msk + +#define AES_INTERRUPT_ENABLE_Pos (1U) +#define AES_INTERRUPT_ENABLE_Len (1U) +#define AES_INTERRUPT_ENABLE_Msk (1U << AES_INTERRUPT_ENABLE_Pos) +#define AES_INTERRUPT_ENABLE AES_INTERRUPT_ENABLE_Msk + +/******************* Bit definition for AES_TRAN_SIZE register *******************/ +#define AES_TRAN_SIZE_Pos (0U) +#define AES_TRAN_SIZE_Len (15U) +#define AES_TRAN_SIZE_Msk (0x00007FFFU) +#define AES_TRAN_SIZE AES_TRAN_SIZE_Msk + +/******************* Bit definition for AES_RSTART_ADDR register *******************/ +#define AES_RSTART_ADDR_Pos (0U) +#define AES_RSTART_ADDR_Len (32U) +#define AES_RSTART_ADDR_Msk (0xFFFFFFFFU) +#define AES_RSTART_ADDR AES_RSTART_ADDR_Msk + +/******************* Bit definition for AES_WSTART_ADDR register *******************/ +#define AES_WSTART_ADDR_Pos (0U) +#define AES_WSTART_ADDR_Len (32U) +#define AES_WSTART_ADDR_Msk (0xFFFFFFFFU) +#define AES_WSTART_ADDR AES_WSTART_ADDR_Msk + +/******************* Bit definition for AES_KEY_ADDR register *******************/ +#define AES_KEY_ADDR_Pos (0U) +#define AES_KEY_ADDR_Len (32U) +#define AES_KEY_ADDR_Msk (0xFFFFFFFFU) +#define AES_KEY_ADDR AES_KEY_ADDR_Msk + +/******************* Bit definition for AES_DATA_OUT register *******************/ +#define AES_DATA_OUT_Pos (0U) +#define AES_DATA_OUT_Len (32U) +#define AES_DATA_OUT_Msk (0xFFFFFFFFU) +#define AES_DATA_OUT AES_DATA_OUT_Msk + +/******************* Bit definition for AES_KEY register *******************/ +#define AES_KEY_Pos (0U) +#define AES_KEY_Len (32U) +#define AES_KEY_Msk (0xFFFFFFFFU) +#define AES_KEY AES_KEY_Msk + +/******************* Bit definition for AES_SEED_IN register *******************/ +#define AES_SEED_IN_Pos (0U) +#define AES_SEED_IN_Len (32U) +#define AES_SEED_IN_Msk (0xFFFFFFFFU) +#define AES_SEED_IN AES_SEED_IN_Msk + +/******************* Bit definition for AES_SEED_OUT register *******************/ +#define AES_SEED_OUT_Pos (0U) +#define AES_SEED_OUT_Len (32U) +#define AES_SEED_OUT_Msk (0xFFFFFFFFU) +#define AES_SEED_OUT AES_SEED_OUT_Msk + +/******************* Bit definition for AES_SEED_IMASK register *******************/ +#define AES_SEED_IMASK_Pos (0U) +#define AES_SEED_IMASK_Len (32U) +#define AES_SEED_IMASK_Msk (0xFFFFFFFFU) +#define AES_SEED_IMASK AES_SEED_IMASK_Msk + +/******************* Bit definition for AES_SEED_OSBOX register *******************/ +#define AES_SEED_OSBOX_Pos (0U) +#define AES_SEED_OSBOX_Len (32U) +#define AES_SEED_OSBOX_Msk (0xFFFFFFFFU) +#define AES_SEED_OSBOX AES_SEED_OSBOX_Msk + +/******************* Bit definition for AES_VECTOR_INIT register *******************/ +#define AES_VECTOR_INIT_Pos (0U) +#define AES_VECTOR_INIT_Len (32U) +#define AES_VECTOR_INIT_Msk (0xFFFFFFFFU) +#define AES_VECTOR_INIT AES_VECTOR_INIT_Msk + +/******************* Bit definition for AES_DATA_IN register *******************/ +#define AES_DATA_IN_Pos (0U) +#define AES_DATA_IN_Len (32U) +#define AES_DATA_IN_Msk (0xFFFFFFFFU) +#define AES_DATA_IN AES_DATA_IN_Msk + + +/* ================================================================================================================= */ +/* ================ AON ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for AON_REG_PWR_RET01 register **********/ +#define AON_PWR_REG01_WAKE_UP_SEL_Pos (24U) +#define AON_PWR_REG01_WAKE_UP_SEL_Len (6U) +#define AON_PWR_REG01_WAKE_UP_SEL_Msk (0x3FU << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL AON_PWR_REG01_WAKE_UP_SEL_Msk +#define AON_PWR_REG01_WAKE_UP_SEL_TIMER (0x1U << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL_EXTWKUP (0x2U << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL_BLE (0x4U << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL_CALENDAR (0x8U << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL_PMU_BOD_FEDGE (0x10U << AON_PWR_REG01_WAKE_UP_SEL_Pos) +#define AON_PWR_REG01_WAKE_UP_SEL_MSIO_COMP (0x20U << AON_PWR_REG01_WAKE_UP_SEL_Pos) + +#define AON_PWR_REG01_SMC_WAKEUP_REQ_Pos (22U) +#define AON_PWR_REG01_SMC_WAKEUP_REQ_Len (1U) +#define AON_PWR_REG01_SMC_WAKEUP_REQ_Msk (0x1U << AON_PWR_REG01_SMC_WAKEUP_REQ_Pos) +#define AON_PWR_REG01_SMC_WAKEUP_REQ AON_PWR_REG01_SMC_WAKEUP_REQ_Msk + +#define AON_PWR_REG01_XF_TAG_RET_Pos (21U) +#define AON_PWR_REG01_XF_TAG_RET_Len (1U) +#define AON_PWR_REG01_XF_TAG_RET_Msk (0x1U << AON_PWR_REG01_XF_TAG_RET_Pos) +#define AON_PWR_REG01_XF_TAG_RET AON_PWR_REG01_XF_TAG_RET_Msk + +#define AON_PWR_REG01_XF_SCK_CLK_SEL_Pos (18U) +#define AON_PWR_REG01_XF_SCK_CLK_SEL_Len (3U) +#define AON_PWR_REG01_XF_SCK_CLK_SEL_Msk (0x7U << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos) +#define AON_PWR_REG01_XF_SCK_CLK_SEL AON_PWR_REG01_XF_SCK_CLK_SEL_Msk + +#define AON_PWR_REG01_SWD_ENABLE_Pos (17U) +#define AON_PWR_REG01_SWD_ENABLE_Len (1U) +#define AON_PWR_REG01_SWD_ENABLE_Msk (0x7U << AON_PWR_REG01_SWD_ENABLE_Pos) +#define AON_PWR_REG01_SWD_ENABLE AON_PWR_REG01_SWD_ENABLE_Msk + +#define AON_PWR_REG01_BM_REMAP_Pos (13U) +#define AON_PWR_REG01_BM_REMAP_Len (4U) +#define AON_PWR_REG01_BM_REMAP_Msk (0xFU << AON_PWR_REG01_BM_REMAP_Pos) +#define AON_PWR_REG01_BM_REMAP AON_PWR_REG01_BM_REMAP_Msk + +#define AON_PWR_REG01_COMM_CORE_RST_N_Pos (12U) +#define AON_PWR_REG01_COMM_CORE_RST_N_Len (1U) +#define AON_PWR_REG01_COMM_CORE_RST_N_Msk (0x1U << AON_PWR_REG01_COMM_CORE_RST_N_Pos) +#define AON_PWR_REG01_COMM_CORE_RST_N AON_PWR_REG01_COMM_CORE_RST_N_Msk + +#define AON_PWR_REG01_COMM_TIMER_RST_N_Pos (11U) +#define AON_PWR_REG01_COMM_TIMER_RST_N_Len (1U) +#define AON_PWR_REG01_COMM_TIMER_RST_N_Msk (0x1U << AON_PWR_REG01_COMM_TIMER_RST_N_Pos) +#define AON_PWR_REG01_COMM_TIMER_RST_N AON_PWR_REG01_COMM_TIMER_RST_N_Msk + +#define AON_PWR_REG01_ISO_EN_PD_COMM_TIMER_Pos (9U) +#define AON_PWR_REG01_ISO_EN_PD_COMM_TIMER_Len (1U) +#define AON_PWR_REG01_ISO_EN_PD_COMM_TIMER_Msk (0x1U << AON_PWR_REG01_ISO_EN_PD_COMM_TIMER_Pos) +#define AON_PWR_REG01_ISO_EN_PD_COMM_TIMER AON_PWR_REG01_ISO_EN_PD_COMM_TIMER_Msk + +#define AON_PWR_REG01_ISO_EN_PD_COMM_CORE_Pos (8U) +#define AON_PWR_REG01_ISO_EN_PD_COMM_CORE_Len (1U) +#define AON_PWR_REG01_ISO_EN_PD_COMM_CORE_Msk (0x1U << AON_PWR_REG01_ISO_EN_PD_COMM_CORE_Pos) +#define AON_PWR_REG01_ISO_EN_PD_COMM_CORE AON_PWR_REG01_ISO_EN_PD_COMM_CORE_Msk + +#define AON_PWR_REG01_PWR_EN_PD_COMM_TIMER_Pos (7U) +#define AON_PWR_REG01_PWR_EN_PD_COMM_TIMER_Len (1U) +#define AON_PWR_REG01_PWR_EN_PD_COMM_TIMER_Msk (0x1U << AON_PWR_REG01_PWR_EN_PD_COMM_TIMER_Pos) +#define AON_PWR_REG01_PWR_EN_PD_COMM_TIMER AON_PWR_REG01_PWR_EN_PD_COMM_TIMER_Msk + +#define AON_PWR_REG01_PWR_EN_PD_COMM_CORE_Pos (6U) +#define AON_PWR_REG01_PWR_EN_PD_COMM_CORE_Len (1U) +#define AON_PWR_REG01_PWR_EN_PD_COMM_CORE_Msk (0x1U << AON_PWR_REG01_PWR_EN_PD_COMM_CORE_Pos) +#define AON_PWR_REG01_PWR_EN_PD_COMM_CORE AON_PWR_REG01_PWR_EN_PD_COMM_CORE_Msk + +#define AON_PWR_REG01_EFLASH_PAD_EN_Pos (5U) +#define AON_PWR_REG01_EFLASH_PAD_EN_Len (1U) +#define AON_PWR_REG01_EFLASH_PAD_EN_Msk (0x1U << AON_PWR_REG01_EFLASH_PAD_EN_Pos) +#define AON_PWR_REG01_EFLASH_PAD_EN AON_PWR_REG01_EFLASH_PAD_EN_Msk + +#define AON_PWR_REG01_XO_2MHZ_ENA_Pos (4U) +#define AON_PWR_REG01_XO_2MHZ_ENA_Len (1U) +#define AON_PWR_REG01_XO_2MHZ_ENA_Msk (0x1U << AON_PWR_REG01_XO_2MHZ_ENA_Pos) +#define AON_PWR_REG01_XO_2MHZ_ENA AON_PWR_REG01_XO_2MHZ_ENA_Msk + +#define AON_PWR_REG01_XF_XO_DIV1_Pos (3U) +#define AON_PWR_REG01_XF_XO_DIV1_Len (1U) +#define AON_PWR_REG01_XF_XO_DIV1_Msk (0x1U << AON_PWR_REG01_XF_XO_DIV1_Pos) +#define AON_PWR_REG01_XF_XO_DIV1 AON_PWR_REG01_XF_XO_DIV1_Msk + +#define AON_PWR_REG01_SYS_CLK_SEL_Pos (0U) +#define AON_PWR_REG01_SYS_CLK_SEL_Len (3U) +#define AON_PWR_REG01_SYS_CLK_SEL_Msk (0x7U << AON_PWR_REG01_SYS_CLK_SEL_Pos) +#define AON_PWR_REG01_SYS_CLK_SEL AON_PWR_REG01_SYS_CLK_SEL_Msk + +/******************* Bit definition for AON_REG_SNSADC_CFG register **********/ +#define AON_SNSADC_CFG_SNSADC_REG4_Pos (24U) +#define AON_SNSADC_CFG_SNSADC_REG4_Len (8U) +#define AON_SNSADC_CFG_SNSADC_REG4_Msk (0xFFU << AON_SNSADC_CFG_SNSADC_REG4_Pos) +#define AON_SNSADC_CFG_SNSADC_REG4 AON_SNSADC_CFG_SNSADC_REG4_Msk +#define AON_SNSADC_CFG_MAS_RST_Pos (31U) +#define AON_SNSADC_CFG_MAS_RST_Msk (0x1U << AON_SNSADC_CFG_MAS_RST_Pos) +#define AON_SNSADC_CFG_EN_Pos (30U) +#define AON_SNSADC_CFG_EN_Msk (0x1U << AON_SNSADC_CFG_EN_Pos) +#define AON_SNSADC_CFG_REF_SEL_Pos (27U) +#define AON_SNSADC_CFG_REF_SEL_Msk (0x7U << AON_SNSADC_CFG_REF_SEL_Pos) +#define AON_SNSADC_CFG_REF_HP_Pos (24U) +#define AON_SNSADC_CFG_REF_HP_Msk (0x7U << AON_SNSADC_CFG_REF_HP_Pos) + +#define AON_SNSADC_CFG_SNSADC_REG3_Pos (16U) +#define AON_SNSADC_CFG_SNSADC_REG3_Len (8U) +#define AON_SNSADC_CFG_SNSADC_REG3_Msk (0xFFU << AON_SNSADC_CFG_SNSADC_REG3_Pos) +#define AON_SNSADC_CFG_SNSADC_REG3 AON_SNSADC_CFG_SNSADC_REG3_Msk +#define AON_SNSADC_CFG_CHN_P_Pos (19U) +#define AON_SNSADC_CFG_CHN_P_Msk (0x7U << AON_SNSADC_CFG_CHN_P_Pos) +#define AON_SNSADC_CFG_CHN_N_Pos (16U) +#define AON_SNSADC_CFG_CHN_N_Msk (0x7U << AON_SNSADC_CFG_CHN_N_Pos) + +#define AON_SNSADC_CFG_SNSADC_REG2_Pos (8U) +#define AON_SNSADC_CFG_SNSADC_REG2_Len (8U) +#define AON_SNSADC_CFG_SNSADC_REG2_Msk (0xFFU << AON_SNSADC_CFG_SNSADC_REG2_Pos) +#define AON_SNSADC_CFG_SNSADC_REG2 AON_SNSADC_CFG_SNSADC_REG2_Msk +#define AON_SNSADC_CFG_TEMP_EN_Pos (15U) +#define AON_SNSADC_CFG_TEMP_EN_Msk (0x1U << AON_SNSADC_CFG_TEMP_EN_Pos) +#define AON_SNSADC_CFG_VBAT_EN_Pos (14U) +#define AON_SNSADC_CFG_VBAT_EN_Msk (0x1U << AON_SNSADC_CFG_VBAT_EN_Pos) +#define AON_SNSADC_CFG_SINGLE_EN_Pos (13U) +#define AON_SNSADC_CFG_SINGLE_EN_Msk (0x1U << AON_SNSADC_CFG_SINGLE_EN_Pos) +#define AON_SNSADC_CFG_OFS_CAL_EN_Pos (12U) +#define AON_SNSADC_CFG_OFS_CAL_EN_Msk (0x1U << AON_SNSADC_CFG_OFS_CAL_EN_Pos) +#define AON_SNSADC_CFG_DYMAMIC_Pos (8U) +#define AON_SNSADC_CFG_DYMAMIC_Msk (0x7U << AON_SNSADC_CFG_DYMAMIC_Pos) + +#define AON_SNSADC_CFG_SNSADC_REG1_Pos (0U) +#define AON_SNSADC_CFG_SNSADC_REG1_Len (8U) +#define AON_SNSADC_CFG_SNSADC_REG1_Msk (0xFFU << AON_SNSADC_CFG_SNSADC_REG1_Pos) +#define AON_SNSADC_CFG_SNSADC_REG1 AON_SNSADC_CFG_SNSADC_REG1_Msk +#define AON_SNSADC_CFG_REF_VALUE_Pos (0U) +#define AON_SNSADC_CFG_REF_VALUE_Msk (0xFU << AON_SNSADC_CFG_REF_VALUE_Pos) + +/******************* Bit definition for AON_REG_RF_REG_0 register **********/ +#define AON_RF_REG_0_IO_LDO_REG1_Pos (24U) +#define AON_RF_REG_0_IO_LDO_REG1_Len (8U) +#define AON_RF_REG_0_IO_LDO_REG1_Msk (0xFFU << AON_RF_REG_0_IO_LDO_REG1_Pos) +#define AON_RF_REG_0_IO_LDO_REG1 AON_RF_REG_0_IO_LDO_REG1_Msk + +#define AON_RF_REG_0_LPD_REG2_Pos (16U) +#define AON_RF_REG_0_LPD_REG2_Len (8U) +#define AON_RF_REG_0_LPD_REG2_Msk (0xFFU << AON_RF_REG_0_LPD_REG2_Pos) +#define AON_RF_REG_0_LPD_REG2 AON_RF_REG_0_LPD_REG2_Msk + +#define AON_RF_REG_0_LPD_REG1_Pos (8U) +#define AON_RF_REG_0_LPD_REG1_Len (8U) +#define AON_RF_REG_0_LPD_REG1_Msk (0xFFU << AON_RF_REG_0_LPD_REG1_Pos) +#define AON_RF_REG_0_LPD_REG1 AON_RF_REG_0_LPD_REG1_Msk + +#define AON_RF_REG_0_RTC_REG1_Pos (0U) +#define AON_RF_REG_0_RTC_REG1_Len (8U) +#define AON_RF_REG_0_RTC_REG1_Msk (0xFFU << AON_RF_REG_0_RTC_REG1_Pos) +#define AON_RF_REG_0_RTC_REG1 AON_RF_REG_0_RTC_REG1_Msk + +#define AON_RF_REG_0_DYN_CLK_CTRL_Pos (16U) +#define AON_RF_REG_0_DYN_CLK_CTRL_Len (3U) +#define AON_RF_REG_0_DYN_CLK_CTRL_Msk (0x7U << AON_RF_REG_0_DYN_CLK_CTRL_Pos) +#define AON_RF_REG_0_DYN_CLK_CTRL AON_RF_REG_0_DYN_CLK_CTRL_Msk + +#define AON_RF_REG_0_BGAP_STATIC_EN_LV_Pos (19U) +#define AON_RF_REG_0_BGAP_STATIC_EN_LV_Len (1U) +#define AON_RF_REG_0_BGAP_STATIC_EN_LV_Msk (0x1U << AON_RF_REG_0_BGAP_STATIC_EN_LV_Pos) +#define AON_RF_REG_0_BGAP_STATIC_EN_LV_EN (0x1U << AON_RF_REG_0_BGAP_STATIC_EN_LV_Pos) +#define AON_RF_REG_0_BGAP_STATIC_EN_LV_DIS (0x0U << AON_RF_REG_0_BGAP_STATIC_EN_LV_Pos) + +#define AON_RF_REG_0_RCOSC_BIAS_CNTRL_Pos (22) +#define AON_RF_REG_0_RCOSC_BIAS_CNTRL_Len (2U) +#define AON_RF_REG_0_RCOSC_BIAS_CNTRL_Msk (0x03 << AON_RF_REG_0_RCOSC_BIAS_CNTRL_Pos) + + +#define AON_RF_REG_0_CTRL_TEMPCO_Pos (13U) +#define AON_RF_REG_0_CTRL_TEMPCO_Len (3U) +#define AON_RF_REG_0_CTRL_TEMPCO_Msk (0x7U << AON_RF_REG_0_CTRL_TEMPCO_Pos) +#define AON_RF_REG_0_CTRL_TEMPCO AON_RF_REG_0_CTRL_TEMPCO_Msk + +#define AON_RF_REG_0_CTRL_RET_Pos (11U) +#define AON_RF_REG_0_CTRL_RET_Len (2U) +#define AON_RF_REG_0_CTRL_RET_Msk (0x3U << AON_RF_REG_0_CTRL_RET_Pos) +#define AON_RF_REG_0_CTRL_RET AON_RF_REG_0_CTRL_RET_Msk + +#define AON_RF_REG_0_CTRL_BGAP_Pos (9U) +#define AON_RF_REG_0_CTRL_BGAP_Len (2U) +#define AON_RF_REG_0_CTRL_BGAP_Msk (0x3U << AON_RF_REG_0_CTRL_BGAP_Pos) +#define AON_RF_REG_0_CTRL_BGAP AON_RF_REG_0_CTRL_BGAP_Msk + +#define AON_RF_REG_0_BGAP_VOLTAGE_EN_Pos (8U) +#define AON_RF_REG_0_BGAP_VOLTAGE_EN_Len (1U) +#define AON_RF_REG_0_BGAP_VOLTAGE_ON (0x1U << AON_RF_REG_0_BGAP_VOLTAGE_EN_Pos) +#define AON_RF_REG_0_BGAP_VOLTAGE_OFF (0x0U << AON_RF_REG_0_BGAP_VOLTAGE_EN_Pos) + +#define AON_RF_REG_0_LPD_REG1_Pos (8U) +#define AON_RF_REG_0_LPD_REG1_Len (8U) +#define AON_RF_REG_0_LPD_REG1_Msk (0xFFU << AON_RF_REG_0_LPD_REG1_Pos) +#define AON_RF_REG_0_LPD_REG1 AON_RF_REG_0_LPD_REG1_Msk + +#define AON_RF_REG_0_RTC_REG1_Pos (0U) +#define AON_RF_REG_0_RTC_REG1_Len (8U) +#define AON_RF_REG_0_RTC_REG1_Msk (0xFFU << AON_RF_REG_0_RTC_REG1_Pos) +#define AON_RF_REG_0_RTC_REG1 AON_RF_REG_0_RTC_REG1_Msk + +/******************* Bit definition for AON_REG_RF_REG_1 register **********/ +#define AON_RF_REG_1_DCDC_REG4_Pos (24U) +#define AON_RF_REG_1_DCDC_REG4_Len (8U) +#define AON_RF_REG_1_DCDC_REG4_Msk (0xFFU << AON_RF_REG_1_DCDC_REG4_Pos) +#define AON_RF_REG_1_DCDC_REG4 AON_RF_REG_1_DCDC_REG4_Msk + +#define AON_RF_REG_1_DCDC_REG3_Pos (16U) +#define AON_RF_REG_1_DCDC_REG3_Len (8U) +#define AON_RF_REG_1_DCDC_REG3_Msk (0xFFU << AON_RF_REG_1_DCDC_REG3_Pos) +#define AON_RF_REG_1_DCDC_REG3 AON_RF_REG_1_DCDC_REG3_Msk + +#define AON_RF_REG_1_EN_INJ_Pos (14U) +#define AON_RF_REG_1_EN_INJ_Msk (0x1 << AON_RF_REG_1_EN_INJ_Pos) +#define AON_RF_REG_1_EN_INJ_ON (0x1 << AON_RF_REG_1_EN_INJ_Pos) +#define AON_RF_REG_1_EN_INJ_OFF (0x0 << AON_RF_REG_1_EN_INJ_Pos) + +#define AON_RF_REG_1_TON_Pos (11U) +#define AON_RF_REG_1_TON_Len (3U) +#define AON_RF_REG_1_TON_Msk (0x7U << AON_RF_REG_1_TON_Pos) +#define AON_RF_REG_1_TON AON_RF_REG_1_TON_Msk + +#define AON_RF_REG_1_DCDC_REG2_Pos (8U) +#define AON_RF_REG_1_DCDC_REG2_Len (8U) +#define AON_RF_REG_1_DCDC_REG2_Msk (0xFFU << AON_RF_REG_1_DCDC_REG2_Pos) +#define AON_RF_REG_1_DCDC_REG2 AON_RF_REG_1_DCDC_REG2_Msk + +#define AON_RF_REG_1_DCDC_REG1_Pos (0U) +#define AON_RF_REG_1_DCDC_REG1_Len (8U) +#define AON_RF_REG_1_DCDC_REG1_Msk (0xFFU << AON_RF_REG_1_DCDC_REG1_Pos) +#define AON_RF_REG_1_DCDC_REG1 AON_RF_REG_1_DCDC_REG1_Msk + +/******************* Bit definition for AON_REG_RF_REG_2 register **********/ +#define AON_RF_REG_2_TON_EN_Pos (17U) +#define AON_RF_REG_2_TON_EN_Msk (0x1U << AON_RF_REG_2_TON_EN_Pos) +#define AON_RF_REG_2_TON_EN_ON (0x1 << AON_RF_REG_2_TON_EN_Pos) +#define AON_RF_REG_2_TON_EN_OFF (0x0 << AON_RF_REG_2_TON_EN_Pos) + +#define AON_RF_REG_2_GP_REG2_Pos (16U) +#define AON_RF_REG_2_GP_REG2_Len (8U) +#define AON_RF_REG_2_GP_REG2_Msk (0xFFU << AON_RF_REG_2_GP_REG2_Pos) +#define AON_RF_REG_2_GP_REG2 AON_RF_REG_2_GP_REG2_Msk + +#define AON_RF_REG_2_GP_REG1_Pos (8U) +#define AON_RF_REG_2_GP_REG1_Len (8U) +#define AON_RF_REG_2_GP_REG1_Msk (0xFFU << AON_RF_REG_2_GP_REG1_Pos) +#define AON_RF_REG_2_GP_REG1 AON_RF_REG_2_GP_REG1_Msk +#define AON_RF_REG_2_EFUSE_VDD_EN (0x4U << AON_RF_REG_2_GP_REG1_Pos) + +#define AON_RF_REG_2_MUX1_REG1_Pos (0U) +#define AON_RF_REG_2_MUX1_REG1_Len (8U) +#define AON_RF_REG_2_MUX1_REG1_Msk (0xFFU << AON_RF_REG_2_MUX1_REG1_Pos) +#define AON_RF_REG_2_MUX1_REG1 AON_RF_REG_2_MUX1_REG1_Msk + +/******************* Bit definition for AON_REG_CALENDAR_TIMER_CTL register **********/ +#define AON_CALENDAR_TIMER_CTL_WRAP_INT_EN_Pos (13U) +#define AON_CALENDAR_TIMER_CTL_WRAP_INT_EN_Len (1U) +#define AON_CALENDAR_TIMER_CTL_WRAP_INT_EN_Msk (0x1U << AON_CALENDAR_TIMER_CTL_WRAP_INT_EN_Pos) +#define AON_CALENDAR_TIMER_CTL_WRAP_INT_EN AON_CALENDAR_TIMER_CTL_WRAP_INT_EN_Msk + +#define AON_CALENDAR_TIMER_CTL_ALARM_INT_EN_Pos (12U) +#define AON_CALENDAR_TIMER_CTL_ALARM_INT_EN_Len (1U) +#define AON_CALENDAR_TIMER_CTL_ALARM_INT_EN_Msk (0x1U << AON_CALENDAR_TIMER_CTL_ALARM_INT_EN_Pos) +#define AON_CALENDAR_TIMER_CTL_ALARM_INT_EN AON_CALENDAR_TIMER_CTL_ALARM_INT_EN_Msk + +#define AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos (8U) +#define AON_CALENDAR_TIMER_CTL_CLK_SEL_Len (3U) +#define AON_CALENDAR_TIMER_CTL_CLK_SEL_Msk (0x7U << AON_CALENDAR_TIMER_CTL_CLK_SEL_Pos) +#define AON_CALENDAR_TIMER_CTL_CLK_SEL AON_CALENDAR_TIMER_CTL_CLK_SEL_Msk + +#define AON_CALENDAR_TIMER_CTL_WRAP_CNT_Pos (4U) +#define AON_CALENDAR_TIMER_CTL_WRAP_CNT_Len (4U) +#define AON_CALENDAR_TIMER_CTL_WRAP_CNT_Msk (0xFU << AON_CALENDAR_TIMER_CTL_WRAP_CNT_Pos) +#define AON_CALENDAR_TIMER_CTL_WRAP_CNT AON_CALENDAR_TIMER_CTL_WRAP_CNT_Msk + +#define AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD_Pos (2U) +#define AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD_Len (1U) +#define AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD_Msk (0x1U << AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD_Pos) +#define AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD AON_CALENDAR_TIMER_CTL_ALARM_VAL_LOAD_Msk + +#define AON_CALENDAR_TIMER_CTL_VAL_LOAD_Pos (1U) +#define AON_CALENDAR_TIMER_CTL_VAL_LOAD_Len (1U) +#define AON_CALENDAR_TIMER_CTL_VAL_LOAD_Msk (0x1U << AON_CALENDAR_TIMER_CTL_VAL_LOAD_Pos) +#define AON_CALENDAR_TIMER_CTL_VAL_LOAD AON_CALENDAR_TIMER_CTL_VAL_LOAD_Msk + +#define AON_CALENDAR_TIMER_CTL_EN_Pos (0U) +#define AON_CALENDAR_TIMER_CTL_EN_Len (1U) +#define AON_CALENDAR_TIMER_CTL_EN_Msk (0x1U << AON_CALENDAR_TIMER_CTL_EN_Pos) +#define AON_CALENDAR_TIMER_CTL_EN AON_CALENDAR_TIMER_CTL_EN_Msk + +/******************* Bit definition for AON_REG_MEM_STD_OVR register **********/ +#define AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N_Pos (30U) +#define AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N_Len (1U) +#define AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N_Msk (0x1U << AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N_Pos) +#define AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N AON_MEM_STD_OVR_MCU_KEYRAM_STDBY_N_Msk + +#define AON_MEM_STD_OVR_PMEM_STDBY_N_Pos (29U) +#define AON_MEM_STD_OVR_PMEM_STDBY_N_Len (1U) +#define AON_MEM_STD_OVR_PMEM_STDBY_N_Msk (0x1U << AON_MEM_STD_OVR_PMEM_STDBY_N_Pos) +#define AON_MEM_STD_OVR_PMEM_STDBY_N AON_MEM_STD_OVR_PMEM_STDBY_N_Msk + +#define AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N_Pos (28U) +#define AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N_Len (1U) +#define AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N_Msk (1U << AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N_Pos) +#define AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N AON_MEM_STD_OVR_MCU_ICACHE_STDBY_N_Msk + +#define AON_MEM_STD_OVR_MCU_HTM_STDBY_N_Pos (27U) +#define AON_MEM_STD_OVR_MCU_HTM_STDBY_N_Len (1U) +#define AON_MEM_STD_OVR_MCU_HTM_STDBY_N_Msk (1U << AON_MEM_STD_OVR_MCU_HTM_STDBY_N_Pos) +#define AON_MEM_STD_OVR_MCU_HTM_STDBY_N AON_MEM_STD_OVR_MCU_HTM_STDBY_N_Msk + +#define AON_MEM_STD_OVR_MCU_MEM_STDBY_N_Pos (16U) +#define AON_MEM_STD_OVR_MCU_MEM_STDBY_N_Len (11U) +#define AON_MEM_STD_OVR_MCU_MEM_STDBY_N_Msk (0x7FFU << AON_MEM_STD_OVR_MCU_MEM_STDBY_N_Pos) +#define AON_MEM_STD_OVR_MCU_MEM_STDBY_N AON_MEM_STD_OVR_MCU_MEM_STDBY_N_Msk + +#define AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N_Pos (14U) +#define AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N_Len (1U) +#define AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N_Msk (0x1U << AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N_Pos) +#define AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N AON_MEM_STD_OVR_KEYRAM_ISO_VDD_N_Msk + +#define AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N_Pos (13U) +#define AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N_Len (1U) +#define AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N_Msk (0x1U << AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N_Pos) +#define AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N AON_MEM_STD_OVR_EF_CACHE_ISO_VDD_N_Msk + +#define AON_MEM_STD_OVR_HTABLE_ISO_VDD_N_Pos (12U) +#define AON_MEM_STD_OVR_HTABLE_ISO_VDD_N_Len (1U) +#define AON_MEM_STD_OVR_HTABLE_ISO_VDD_N_Msk (0x1U << AON_MEM_STD_OVR_HTABLE_ISO_VDD_N_Pos) +#define AON_MEM_STD_OVR_HTABLE_ISO_VDD_N AON_MEM_STD_OVR_HTABLE_ISO_VDD_N_Msk + +#define AON_MEM_STD_OVR_PMEM_ISO_VDD_N_Pos (11U) +#define AON_MEM_STD_OVR_PMEM_ISO_VDD_N_Len (1U) +#define AON_MEM_STD_OVR_PMEM_ISO_VDD_N_Msk (0x1U << AON_MEM_STD_OVR_PMEM_ISO_VDD_N_Pos) +#define AON_MEM_STD_OVR_PMEM_ISO_VDD_N AON_MEM_STD_OVR_PMEM_ISO_VDD_N_Msk + +#define AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N_Pos (0U) +#define AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N_Len (11U) +#define AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N_Msk (0x7FF << AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N_Pos) +#define AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N AON_MEM_STD_OVR_MCU_MEM_ISO_VDD_N_Msk + +/******************* Bit definition for AON_REG_RF_REG_3 register **********/ +#define AON_RF_REG_3_IO_LDO_REG2_Pos (24U) +#define AON_RF_REG_3_IO_LDO_REG2_Len (8U) +#define AON_RF_REG_3_IO_LDO_REG2_Msk (0xFFU << AON_RF_REG_3_IO_LDO_REG2_Pos) +#define AON_RF_REG_3_IO_LDO_REG2 AON_RF_REG_3_IO_LDO_REG2_Msk + +#define AON_RF_REG_3_LDO_5V_REG1_Pos (8U) +#define AON_RF_REG_3_LDO_5V_REG1_Len (8U) +#define AON_RF_REG_3_LDO_5V_REG1_Msk (0xFFU << AON_RF_REG_3_LDO_5V_REG1_Pos) +#define AON_RF_REG_3_LDO_5V_REG1 AON_RF_REG_3_LDO_5V_REG1_Msk + +#define AON_RF_REG_3_RTC_EN_Pos (7U) +#define AON_RF_REG_3_RTC_EN_Len (1U) +#define AON_RF_REG_3_RTC_EN_Msk (0x1U << AON_RF_REG_3_RTC_EN_Pos) +#define AON_RF_REG_3_RTC_EN AON_RF_REG_3_RTC_EN_Msk +#define AON_RF_REG_3_RTC_DIS (0x0U << AON_RF_REG_3_RTC_EN_Pos) + +#define AON_RF_REG_3_BOD_STATIC_LV_Pos (5U) +#define AON_RF_REG_3_BOD_STATIC_LV_Len (1U) +#define AON_RF_REG_3_BOD_STATIC_LV_Msk (0x1U << AON_RF_REG_3_BOD_STATIC_LV_Pos) +#define AON_RF_REG_3_BOD_STATIC_LV_EN (0x1U << AON_RF_REG_3_BOD_STATIC_LV_Pos) +#define AON_RF_REG_3_BOD_STATIC_LV_DIS (0x0U << AON_RF_REG_3_BOD_STATIC_LV_Pos) +#define AON_RF_REG_3_BOD_LVL_CTRL_LV_Pos (2U) +#define AON_RF_REG_3_BOD_LVL_CTRL_LV_Len (3U) +#define AON_RF_REG_3_BOD_LVL_CTRL_LV_Msk (0x7U << AON_RF_REG_3_BOD_LVL_CTRL_LV_Pos) +#define AON_RF_REG_3_BOD_LVL_CTRL_LV AON_RF_REG_3_BOD_LVL_CTRL_LV_Msk +#define AON_RF_REG_3_BOD2_EN_Pos (1U) +#define AON_RF_REG_3_BOD2_EN_Len (1U) +#define AON_RF_REG_3_BOD2_EN_Msk (0x1U << AON_RF_REG_3_BOD2_EN_Pos) +#define AON_RF_REG_3_BOD2_EN (0x1U << AON_RF_REG_3_BOD2_EN_Pos) +#define AON_RF_REG_3_BOD2_DIS (0x0U << AON_RF_REG_3_BOD2_EN_Pos) + +#define AON_RF_REG_3_BOD_EN_Pos (0U) +#define AON_RF_REG_3_BOD_EN_Len (1U) +#define AON_RF_REG_3_BOD_EN_Msk (0x1U << AON_RF_REG_3_BOD_EN_Pos) +#define AON_RF_REG_3_BOD_EN (0x1U << AON_RF_REG_3_BOD_EN_Pos) +#define AON_RF_REG_3_BOD_DIS (0x0U << AON_RF_REG_3_BOD_EN_Pos) + +#define AON_RF_REG_3_BOD_REG1_Pos (0U) +#define AON_RF_REG_3_BOD_REG1_Len (8U) +#define AON_RF_REG_3_BOD_REG1_Msk (0xFFU << AON_RF_REG_3_BOD_REG1_Pos) +#define AON_RF_REG_3_BOD_REG1 AON_RF_REG_3_BOD_REG1_Msk + +/******************* Bit definition for AON_REG_RF_REG_4 register **********/ +#define AON_RF_REG_4_DIG_LDO_REG1_Pos (16U) +#define AON_RF_REG_4_DIG_LDO_REG1_Len (8U) +#define AON_RF_REG_4_DIG_LDO_REG1_Msk (0xFFU << AON_RF_REG_4_DIG_LDO_REG1_Pos) +#define AON_RF_REG_4_DIG_LDO_REG1 AON_RF_REG_4_DIG_LDO_REG1_Msk + +#define AON_RF_REG_4_CLK_PERIOD_Pos (12U) +#define AON_RF_REG_4_CLK_PERIOD_Len (4U) +#define AON_RF_REG_4_CLK_PERIOD_Msk (0xF << AON_RF_REG_4_CLK_PERIOD_Pos) +#define AON_RF_REG_4_CLK_PERIOD AON_RF_REG_4_CLK_PERIOD_Msk + +#define AON_RF_REG_4_DCDC_REG6_Pos (8U) +#define AON_RF_REG_4_DCDC_REG6_Len (8U) +#define AON_RF_REG_4_DCDC_REG6_Msk (0xFFU << AON_RF_REG_4_DCDC_REG6_Pos) +#define AON_RF_REG_4_DCDC_REG6 AON_RF_REG_4_DCDC_REG6_Msk + +#define AON_RF_REG_4_DCDC_REG5_Pos (0U) +#define AON_RF_REG_4_DCDC_REG5_Len (8U) +#define AON_RF_REG_4_DCDC_REG5_Msk (0xFFU << AON_RF_REG_4_DCDC_REG5_Pos) +#define AON_RF_REG_4_DCDC_REG5 AON_RF_REG_4_DCDC_REG5_Msk + +/******************* Bit definition for AON_REG_RF_REG_5 register **********/ +#define AON_RF_REG_5_MUX_REG2_Pos (24U) +#define AON_RF_REG_5_MUX_REG2_Len (8U) +#define AON_RF_REG_5_MUX_REG2_Msk (0xFFU << AON_RF_REG_5_MUX_REG2_Pos) +#define AON_RF_REG_5_MUX_REG2 AON_RF_REG_5_MUX_REG2_Msk + +#define AON_RF_REG_5_MUX_REG1_Pos (16U) +#define AON_RF_REG_5_MUX_REG1_Len (8U) +#define AON_RF_REG_5_MUX_REG1_Msk (0xFFU << AON_RF_REG_5_MUX_REG1_Pos) +#define AON_RF_REG_5_MUX_REG1 AON_RF_REG_5_MUX_REG1_Msk + +#define AON_RF_REG_5_LPD_REG3_Pos (0U) +#define AON_RF_REG_5_LPD_REG3_Len (8U) +#define AON_RF_REG_5_LPD_REG3_Msk (0xFFU << AON_RF_REG_5_LPD_REG3_Pos) +#define AON_RF_REG_5_LPD_REG3 AON_RF_REG_5_LPD_REG3_Msk + +#define AON_RF_REG_5_RCOSC_EN_Pos (7) +#define AON_RF_REG_5_RCOSC_EN_Len (1U) +#define AON_RF_REG_5_RCOSC_EN_Msk (0x01 << AON_RF_REG_5_RCOSC_EN_Pos) +#define AON_RF_REG_5_RCOSC_EN (AON_RF_REG_5_RCOSC_EN_Msk) + +#define AON_RF_REG_5_RCOSC_DELAY_EN_Pos (6) +#define AON_RF_REG_5_RCOSC_DELAY_EN_Len (1U) +#define AON_RF_REG_5_RCOSC_DELAY_EN_Msk (0x01 << AON_RF_REG_5_RCOSC_DELAY_EN_Pos) +#define AON_RF_REG_5_RCOSC_DELAY_EN (0x01 << AON_RF_REG_5_RCOSC_DELAY_EN_Pos) + +#define AON_RF_REG_5_RCOSC_RDIV_DELAY_Pos (3) +#define AON_RF_REG_5_RCOSC_RDIV_DELAY_Len (3U) +#define AON_RF_REG_5_RCOSC_RDIV_DELAY_Msk (0x07 << AON_RF_REG_5_RCOSC_RDIV_DELAY_Pos) +#define AON_RF_REG_5_RCOSC_RDIV_DELAY (AON_RF_REG_5_RCOSC_RDIV_DELAY_Msk) + +#define AON_RF_REG_5_RCOSC_RESN_CNTRL_Pos (0) +#define AON_RF_REG_5_RCOSC_RESN_CNTRL_Len (3U) +#define AON_RF_REG_5_RCOSC_RESN_CNTRL_Msk (0x07 << AON_RF_REG_5_RCOSC_RESN_CNTRL_Pos) +#define AON_RF_REG_5_RCOSC_RESN_CNTRL (AON_RF_REG_5_RCOSC_RESN_CNTRL_Msk) + +/******************* Bit definition for AON_REG_RF_REG_6 register **********/ +#define AON_RF_REG_6_CPLL_REG1_Pos (0U) +#define AON_RF_REG_6_CPLL_REG1_Len (32U) +#define AON_RF_REG_6_CPLL_REG1_Msk (0xFFFFFFFFU) +#define AON_RF_REG_6_CPLL_REG1 AON_RF_REG_6_CPLL_REG1_Msk + +/******************* Bit definition for AON_REG_RF_REG_7 register **********/ +#define AON_RF_REG_7_CPLL_REG2_Pos (0U) +#define AON_RF_REG_7_CPLL_REG2_Len (32U) +#define AON_RF_REG_7_CPLL_REG2_Msk (0xFFFFFFFFU) +#define AON_RF_REG_7_CPLL_REG2 AON_RF_REG_7_CPLL_REG2_Msk + +/******************* Bit definition for AON_REG_RF_REG_8 register **********/ +#define AON_RF_REG_8_XO_REG1_Pos (0U) +#define AON_RF_REG_8_XO_REG1_Len (32U) +#define AON_RF_REG_8_XO_REG1_Msk (0xFFFFFFFFU) +#define AON_RF_REG_8_XO_REG1 AON_RF_REG_8_XO_REG1_Msk + +/******************* Bit definition for AON_REG_RF_REG_9 register **********/ +#define AON_RF_REG_9_XO_REG2_Pos (0U) +#define AON_RF_REG_9_XO_REG2_Len (32U) +#define AON_RF_REG_9_XO_REG2_Msk (0xFFFFFFFFU) +#define AON_RF_REG_9_XO_REG2 AON_RF_REG_9_XO_REG2_Msk + +/******************* Bit definition for AON_REG_MSIO_PAD_CFG_0 register **********/ +#define AON_MSIO_PAD_CFG_0_OE_N_Pos (24U) +#define AON_MSIO_PAD_CFG_0_OE_N_Len (5U) +#define AON_MSIO_PAD_CFG_0_OE_N_Msk (0x1FU << AON_MSIO_PAD_CFG_0_OE_N_Pos) +#define AON_MSIO_PAD_CFG_0_OE_N AON_MSIO_PAD_CFG_0_OE_N_Msk + +#define AON_MSIO_PAD_CFG_0_IE_N_Pos (16U) +#define AON_MSIO_PAD_CFG_0_IE_N_Len (5U) +#define AON_MSIO_PAD_CFG_0_IE_N_Msk (0x1FU << AON_MSIO_PAD_CFG_0_IE_N_Pos) +#define AON_MSIO_PAD_CFG_0_IE_N AON_MSIO_PAD_CFG_0_IE_N_Msk + +#define AON_MSIO_PAD_CFG_0_IN_Pos (8U) +#define AON_MSIO_PAD_CFG_0_IN_Len (5U) +#define AON_MSIO_PAD_CFG_0_IN_Msk (0x1FU << AON_MSIO_PAD_CFG_0_IN_Pos) +#define AON_MSIO_PAD_CFG_0_IN AON_MSIO_PAD_CFG_0_IN_Msk + +#define AON_MSIO_PAD_CFG_0_RE_N_Pos (0U) +#define AON_MSIO_PAD_CFG_0_RE_N_Len (5U) +#define AON_MSIO_PAD_CFG_0_RE_N_Msk (0x1FU << AON_MSIO_PAD_CFG_0_RE_N_Pos) +#define AON_MSIO_PAD_CFG_0_RE_N AON_MSIO_PAD_CFG_0_RE_N_Msk + +/******************* Bit definition for AON_REG_MSIO_PAD_CFG_1 register **********/ +#define AON_MSIO_PAD_CFG_1_ADC_CLK_EN_Pos (31U) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_EN_Len (1U) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_EN_Msk (0x1U << AON_MSIO_PAD_CFG_1_ADC_CLK_EN_Pos) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_EN AON_MSIO_PAD_CFG_1_ADC_CLK_EN_Msk + +#define AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos (28U) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Len (3U) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Msk (0x7U << AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Pos) +#define AON_MSIO_PAD_CFG_1_ADC_CLK_SEL AON_MSIO_PAD_CFG_1_ADC_CLK_SEL_Msk + +#define AON_MSIO_PAD_CFG_1_MCU_OVR_Pos (22U) +#define AON_MSIO_PAD_CFG_1_MCU_OVR_Len (5U) +#define AON_MSIO_PAD_CFG_1_MCU_OVR_Msk (0x1FU << AON_MSIO_PAD_CFG_1_MCU_OVR_Pos) +#define AON_MSIO_PAD_CFG_1_MCU_OVR AON_MSIO_PAD_CFG_1_MCU_OVR_Msk + +#define AON_COMM_DEEPSLCNTL_EXTWKUPDSB_Pos (21U) +#define AON_COMM_DEEPSLCNTL_EXTWKUPDSB_Len (1U) +#define AON_COMM_DEEPSLCNTL_EXTWKUPDSB_Msk (0x1U << AON_COMM_DEEPSLCNTL_EXTWKUPDSB_Pos) +#define AON_COMM_DEEPSLCNTL_EXTWKUPDSB AON_COMM_DEEPSLCNTL_EXTWKUPDSB_Msk + +#define AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ_Pos (20U) +#define AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ_Len (1U) +#define AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ_Msk (0x1U << AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ_Pos) +#define AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ AON_COMM_DEEPSLCNTL_SOFT_WAKEUP_REQ_Msk + +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON_Pos (18U) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON_Len (1U) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON_Msk (0x1U << AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON_Pos) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON AON_COMM_DEEPSLCNTL_DEEP_SLEEP_ON_Msk + +#define AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN_Pos (17U) +#define AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN_Len (1U) +#define AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN_Msk (0x1U << AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN_Pos) +#define AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN AON_COMM_DEEPSLCNTL_RADIO_SLEEP_EN_Msk + +#define AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN_Pos (16U) +#define AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN_Len (1U) +#define AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN_Msk (0x1U << AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN_Pos) +#define AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN AON_COMM_DEEPSLCNTL_OSC_SLEEP_EN_Msk + +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT_Pos (15U) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT_Len (1U) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT_Msk (0x1U << AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT_Pos) +#define AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT AON_COMM_DEEPSLCNTL_DEEP_SLEEP_STAT_Msk + +#define AON_MSIO_PAD_CFG_1_RTYPE_Pos (8U) +#define AON_MSIO_PAD_CFG_1_RTYPE_Len (5U) +#define AON_MSIO_PAD_CFG_1_RTYPE_Msk (0x1FU << AON_MSIO_PAD_CFG_1_RTYPE_Pos) +#define AON_MSIO_PAD_CFG_1_RTYPE AON_MSIO_PAD_CFG_1_RTYPE_Msk + +#define AON_MSIO_PAD_CFG_1_AE_N_Pos (0U) +#define AON_MSIO_PAD_CFG_1_AE_N_Len (5U) +#define AON_MSIO_PAD_CFG_1_AE_N_Msk (0x1FU << AON_MSIO_PAD_CFG_1_AE_N_Pos) +#define AON_MSIO_PAD_CFG_1_AE_N AON_MSIO_PAD_CFG_1_AE_N_Msk + +/******************* Bit definition for AON_REG_SLP_EVENT register **********/ +#define AON_SLP_EVENT_SLP_TIMER_MODE_Pos (30U) +#define AON_SLP_EVENT_SLP_TIMER_MODE_Len (2U) +#define AON_SLP_EVENT_SLP_TIMER_MODE_Msk (0x3U << AON_SLP_EVENT_SLP_TIMER_MODE_Pos) +#define AON_SLP_EVENT_SLP_TIMER_MODE AON_SLP_EVENT_SLP_TIMER_MODE_Msk +#define AON_SLP_EVENT_SLP_TIMER_MODE_NORMAL (0x0U << AON_SLP_EVENT_SLP_TIMER_MODE_Pos) +#define AON_SLP_EVENT_SLP_TIMER_MODE_SINGLE (0x1U << AON_SLP_EVENT_SLP_TIMER_MODE_Pos) +#define AON_SLP_EVENT_SLP_TIMER_MODE_RELOAD (0x2U << AON_SLP_EVENT_SLP_TIMER_MODE_Pos) +#define AON_SLP_EVENT_SLP_TIMER_MODE_DISABLE (0x3U << AON_SLP_EVENT_SLP_TIMER_MODE_Pos) + +#define AON_SLP_EVENT_EXT_WKUP_STATUS_Pos (16U) +#define AON_SLP_EVENT_EXT_WKUP_STATUS_Len (8U) +#define AON_SLP_EVENT_EXT_WKUP_STATUS_Msk (0xFFU << AON_SLP_EVENT_EXT_WKUP_STATUS_Pos) +#define AON_SLP_EVENT_EXT_WKUP_STATUS AON_SLP_EVENT_EXT_WKUP_STATUS_Msk + +#define AON_SLP_EVENT_CALENDAR_TIMER_WRAP_Pos (9U) +#define AON_SLP_EVENT_CALENDAR_TIMER_WRAP_Len (1U) +#define AON_SLP_EVENT_CALENDAR_TIMER_WRAP_Msk (0x1U << AON_SLP_EVENT_CALENDAR_TIMER_WRAP_Pos) +#define AON_SLP_EVENT_CALENDAR_TIMER_WRAP AON_SLP_EVENT_CALENDAR_TIMER_WRAP_Msk + +#define AON_SLP_EVENT_CALENDAR_TIMER_ALARM_Pos (8U) +#define AON_SLP_EVENT_CALENDAR_TIMER_ALARM_Len (1U) +#define AON_SLP_EVENT_CALENDAR_TIMER_ALARM_Msk (0x1U << AON_SLP_EVENT_CALENDAR_TIMER_ALARM_Pos) +#define AON_SLP_EVENT_CALENDAR_TIMER_ALARM AON_SLP_EVENT_CALENDAR_TIMER_ALARM_Msk + +#define AON_SLP_EVENT_WDT_REBOOT_Pos (6U) +#define AON_SLP_EVENT_WDT_REBOOT_Len (1U) +#define AON_SLP_EVENT_WDT_REBOOT_Msk (0x1U << AON_SLP_EVENT_WDT_REBOOT_Pos) +#define AON_SLP_EVENT_WDT_REBOOT AON_SLP_EVENT_WDT_REBOOT_Msk + +#define AON_SLP_EVENT_PMU_MSIO_COMP_Pos (4U) +#define AON_SLP_EVENT_PMU_MSIO_COMP_Len (1U) +#define AON_SLP_EVENT_PMU_MSIO_COMP_Msk (0x1U << AON_SLP_EVENT_PMU_MSIO_COMP_Pos) +#define AON_SLP_EVENT_PMU_MSIO_COMP AON_SLP_EVENT_PMU_MSIO_COMP_Msk + +#define AON_SLP_EVENT_PMU_BOD_FEDGE_Pos (3U) +#define AON_SLP_EVENT_PMU_BOD_FEDGE_Len (1U) +#define AON_SLP_EVENT_PMU_BOD_FEDGE_Msk (0x1U << AON_SLP_EVENT_PMU_BOD_FEDGE_Pos) +#define AON_SLP_EVENT_PMU_BOD_FEDGE AON_SLP_EVENT_PMU_BOD_FEDGE_Msk + +#define AON_SLP_EVENT_EXTWKUP_Pos (2U) +#define AON_SLP_EVENT_EXTWKUP_Len (1U) +#define AON_SLP_EVENT_EXTWKUP_Msk (0x1U << AON_SLP_EVENT_EXTWKUP_Pos) +#define AON_SLP_EVENT_EXTWKUP AON_SLP_EVENT_EXTWKUP_Msk + +#define AON_SLP_EVENT_TIMER_Pos (1U) +#define AON_SLP_EVENT_TIMER_Len (1U) +#define AON_SLP_EVENT_TIMER_Msk (0x1U << AON_SLP_EVENT_TIMER_Pos) +#define AON_SLP_EVENT_TIMER AON_SLP_EVENT_TIMER_Msk + +#define AON_SLP_EVENT_SMCOSCEN_Pos (0U) +#define AON_SLP_EVENT_SMCOSCEN_Len (1U) +#define AON_SLP_EVENT_SMCOSCEN_Msk (0x1U << AON_SLP_EVENT_SMCOSCEN_Pos) +#define AON_SLP_EVENT_SMCOSCEN AON_SLP_EVENT_SMCOSCEN_Msk + +/******************* Bit definition for AON_REG_WARM_BOOT_TIME register **********/ +#define AON_WARM_BOOT_TIME_TUNE_C_Pos (24U) +#define AON_WARM_BOOT_TIME_TUNE_C_Len (7U) +#define AON_WARM_BOOT_TIME_TUNE_C_Msk (0x7FU << AON_WARM_BOOT_TIME_TUNE_C_Pos) +#define AON_WARM_BOOT_TIME_TUNE_C AON_WARM_BOOT_TIME_TUNE_C_Msk + +#define AON_WARM_BOOT_TIME_DIG_LDO_D_Pos (16U) +#define AON_WARM_BOOT_TIME_DIG_LDO_D_Len (7U) +#define AON_WARM_BOOT_TIME_DIG_LDO_D_Msk (0x7FU << AON_WARM_BOOT_TIME_DIG_LDO_D_Pos) +#define AON_WARM_BOOT_TIME_DIG_LDO_D AON_WARM_BOOT_TIME_DIG_LDO_D_Msk + +#define AON_WARM_BOOT_TIME_COUNTER_B_Pos (8U) +#define AON_WARM_BOOT_TIME_COUNTER_B_Len (7U) +#define AON_WARM_BOOT_TIME_COUNTER_B_Msk (0x7FU << AON_WARM_BOOT_TIME_COUNTER_B_Pos) +#define AON_WARM_BOOT_TIME_COUNTER_B AON_WARM_BOOT_TIME_COUNTER_B_Msk + +#define AON_WARM_BOOT_TIME_COUNTER_A_Pos (0U) +#define AON_WARM_BOOT_TIME_COUNTER_A_Len (7U) +#define AON_WARM_BOOT_TIME_COUNTER_A_Msk (0x7FU << AON_WARM_BOOT_TIME_COUNTER_A_Pos) +#define AON_WARM_BOOT_TIME_COUNTER_A AON_WARM_BOOT_TIME_COUNTER_A_Msk + +/******************* Bit definition for AON_REG_RF_REG_10 register **********/ +#define AON_RF_REG_10_MSIO_0 (0U) +#define AON_RF_REG_10_MSIO_1 (1U) +#define AON_RF_REG_10_MSIO_2 (2U) +#define AON_RF_REG_10_MSIO_3 (3U) +#define AON_RF_REG_10_MSIO_4 (4U) +#define AON_RF_REG_10_VTEMP (5U) +#define AON_RF_REG_10_VBATT (6U) +#define AON_RF_REG_10_VREF (7U) + +#define AON_RF_REG_10_XO_BYP_Pos (24U) +#define AON_RF_REG_10_XO_BYP_Len (1U) +#define AON_RF_REG_10_XO_BYP_Msk (0x1U << AON_RF_REG_10_XO_BYP_Pos) +#define AON_RF_REG_10_XO_BYP AON_RF_REG_10_XO_BYP_Msk + +#define AON_RF_REG_10_COMP_REF_CTRL_LV_Pos (16U) +#define AON_RF_REG_10_COMP_REF_CTRL_LV_Len (6U) +#define AON_RF_REG_10_COMP_REF_CTRL_LV_Msk (0x3FU << AON_RF_REG_10_COMP_REF_CTRL_LV_Pos) +#define AON_RF_REG_10_COMP_REF_CTRL_LV AON_RF_REG_10_COMP_REF_CTRL_LV_Msk + +#define AON_RF_REG_10_LPD_REG6_Pos (16U) +#define AON_RF_REG_10_LPD_REG6_Len (8U) +#define AON_RF_REG_10_LPD_REG6_Msk (0xFFU << AON_RF_REG_10_LPD_REG6_Pos) +#define AON_RF_REG_10_LPD_REG6 AON_RF_REG_10_LPD_REG6_Msk + +#define AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Pos (12U) +#define AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Len (3U) +#define AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Msk (0x7U << AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Pos) +#define AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV AON_RF_REG_10_COMP_BATT_LVL_CTRL_LV_Msk + +#define AON_RF_REG_10_ICOMP_CTRL_LV_Pos (8U) +#define AON_RF_REG_10_ICOMP_CTRL_LV_Len (4U) +#define AON_RF_REG_10_ICOMP_CTRL_LV_Msk (0xFU << AON_RF_REG_10_ICOMP_CTRL_LV_Pos) +#define AON_RF_REG_10_ICOMP_CTRL_LV AON_RF_REG_10_ICOMP_CTRL_LV_Msk + +#define AON_RF_REG_10_LPD_REG5_Pos (8U) +#define AON_RF_REG_10_LPD_REG5_Len (8U) +#define AON_RF_REG_10_LPD_REG5_Msk (0xFFU << AON_RF_REG_10_LPD_REG5_Pos) +#define AON_RF_REG_10_LPD_REG5 AON_RF_REG_10_LPD_REG5_Msk + +#define AON_RF_REG_10_WAKE_COMP_EN_Pos (6U) +#define AON_RF_REG_10_WAKE_COMP_EN_Len (1U) +#define AON_RF_REG_10_WAKE_COMP_EN_Msk (0x1U << AON_RF_REG_10_WAKE_COMP_EN_Pos) +#define AON_RF_REG_10_WAKE_COMP_EN AON_RF_REG_10_WAKE_COMP_EN_Msk + +#define AON_RF_REG_10_CHANNEL_SEL_N_Pos (3U) +#define AON_RF_REG_10_CHANNEL_SEL_N_Len (3U) +#define AON_RF_REG_10_CHANNEL_SEL_N_Msk (0x7U << AON_RF_REG_10_CHANNEL_SEL_N_Pos) +#define AON_RF_REG_10_CHANNEL_SEL_N AON_RF_REG_10_CHANNEL_SEL_N_Msk + +#define AON_RF_REG_10_CHANNEL_SEL_P_Pos (0U) +#define AON_RF_REG_10_CHANNEL_SEL_P_Len (3U) +#define AON_RF_REG_10_CHANNEL_SEL_P_Msk (0x7U << AON_RF_REG_10_CHANNEL_SEL_P_Pos) +#define AON_RF_REG_10_CHANNEL_SEL_P AON_RF_REG_10_CHANNEL_SEL_P_Msk + +#define AON_RF_REG_10_LPD_REG4_Pos (0U) +#define AON_RF_REG_10_LPD_REG4_Len (8U) +#define AON_RF_REG_10_LPD_REG4_Msk (0xFFU << AON_RF_REG_10_LPD_REG4_Pos) +#define AON_RF_REG_10_LPD_REG4 AON_RF_REG_10_LPD_REG4_Msk + +/******************* Bit definition for AON_REG_AON_PAD_CTL0 register **************/ +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Pos (28U) +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Len (2U) +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Msk (0x3U << AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Pos) +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Msk +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_RNG (0x00 << AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Pos) +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_RTC (0x01 << AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Pos) +#define AON_PAD_CTL0_COMM_TIMER_CLK_SEL_RNG2 (0x03 << AON_PAD_CTL0_COMM_TIMER_CLK_SEL_Pos) + +#define AON_PAD_CTL0_MCU_OVR_Pos (16U) +#define AON_PAD_CTL0_MCU_OVR_Len (8U) +#define AON_PAD_CTL0_MCU_OVR_Msk (0xFFU << AON_PAD_CTL0_MCU_OVR_Pos) +#define AON_PAD_CTL0_MCU_OVR AON_PAD_CTL0_MCU_OVR_Msk + +#define AON_PAD_CTL0_GPO_RTYPE_Pos (8U) +#define AON_PAD_CTL0_GPO_RTYPE_Len (8U) +#define AON_PAD_CTL0_GPO_RTYPE_Msk (0xFFU << AON_PAD_CTL0_GPO_RTYPE_Pos) +#define AON_PAD_CTL0_GPO_RTYPE AON_PAD_CTL0_GPO_RTYPE_Msk + +#define AON_PAD_CTL0_GPO_RE_N_Pos (0U) +#define AON_PAD_CTL0_GPO_RE_N_Len (8U) +#define AON_PAD_CTL0_GPO_RE_N_Msk (0xFFU << AON_PAD_CTL0_GPO_RE_N_Pos) +#define AON_PAD_CTL0_GPO_RE_N AON_PAD_CTL0_GPO_RE_N_Msk + +/******************* Bit definition for AON_REG_MEM_N_SLP_CTL register ****************/ +#define AON_MEM_CTL_DPAD_LE_WKUP_VAL_Pos (25U) +#define AON_MEM_CTL_DPAD_LE_WKUP_VAL_Len (1U) +#define AON_MEM_CTL_DPAD_LE_WKUP_VAL_Msk (0x1U << AON_MEM_CTL_DPAD_LE_WKUP_VAL_Pos) +#define AON_MEM_CTL_DPAD_LE_WKUP_VAL AON_MEM_CTL_DPAD_LE_WKUP_VAL_Msk + +#define AON_MEM_CTL_DPAD_LE_SLP_VAL_Pos (24U) +#define AON_MEM_CTL_DPAD_LE_SLP_VAL_Len (1U) +#define AON_MEM_CTL_DPAD_LE_SLP_VAL_Msk (0x1U << AON_MEM_CTL_DPAD_LE_SLP_VAL_Pos) +#define AON_MEM_CTL_DPAD_LE_SLP_VAL AON_MEM_CTL_DPAD_LE_SLP_VAL_Msk + +#define AON_MEM_CTL_SLP_Pos (16U) +#define AON_MEM_CTL_SLP_Len (7U) +#define AON_MEM_CTL_SLP_Msk (0x7FU << AON_MEM_CTL_SLP_Pos) +#define AON_MEM_CTL_SLP_EN AON_MEM_CTL_SLP_Msk +#define AON_MEM_CTL_SLP_ALL (AON_MEM_CTL_SLP_TRN_OFF_DCDC | AON_MEM_CTL_SLP_TRN_OFF_XO |\ + AON_MEM_CTL_SLP_TRN_OFF_PLL_EN | AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE |\ + AON_MEM_CTL_SLP_TRN_OFF_LDO_EN | AON_MEM_CTL_SLP_TRN_OFF_PLL_RST |\ + AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN ) + +#define AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN_Pos (22U) +#define AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN AON_MEM_CTL_SLP_TRN_OFF_IO_LDO_EN_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_RST_Pos (21U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_RST_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_RST_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_PLL_RST_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_RST AON_MEM_CTL_SLP_TRN_OFF_PLL_RST_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_LDO_EN_Pos (20U) +#define AON_MEM_CTL_SLP_TRN_OFF_LDO_EN_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_LDO_EN_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_LDO_EN_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_LDO_EN AON_MEM_CTL_SLP_TRN_OFF_LDO_EN_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE_Pos (19U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE AON_MEM_CTL_SLP_TRN_OFF_PLL_TUNE_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_EN_Pos (18U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_EN_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_EN_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_PLL_EN_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_PLL_EN AON_MEM_CTL_SLP_TRN_OFF_PLL_EN_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_XO_Pos (17U) +#define AON_MEM_CTL_SLP_TRN_OFF_XO_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_XO_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_XO_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_XO AON_MEM_CTL_SLP_TRN_OFF_XO_Msk + +#define AON_MEM_CTL_SLP_TRN_OFF_DCDC_Pos (16U) +#define AON_MEM_CTL_SLP_TRN_OFF_DCDC_Len (1U) +#define AON_MEM_CTL_SLP_TRN_OFF_DCDC_Msk (0x1U << AON_MEM_CTL_SLP_TRN_OFF_DCDC_Pos) +#define AON_MEM_CTL_SLP_TRN_OFF_DCDC AON_MEM_CTL_SLP_TRN_OFF_DCDC_Msk + +#define AON_MEM_CTL_MEM_BTRM_Pos (8U) +#define AON_MEM_CTL_MEM_BTRM_Len (4U) +#define AON_MEM_CTL_MEM_BTRM_Msk (0xFU << AON_MEM_CTL_MEM_BTRM_Pos) +#define AON_MEM_CTL_MEM_BTRM AON_MEM_CTL_MEM_BTRM_Msk + +#define AON_MEM_CTL_NON_CRITICAL_MEM_RWM_Pos (6U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RWM_Len (2U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RWM_Msk (0x3U << AON_MEM_CTL_NON_CRITICAL_MEM_RWM_Pos) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RWM AON_MEM_CTL_NON_CRITICAL_MEM_RWM_Msk + +#define AON_MEM_CTL_NON_CRITICAL_MEM_WM_Pos (5U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_WM_Len (1U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_WM_Msk (0x1U << AON_MEM_CTL_NON_CRITICAL_MEM_WM_Pos) +#define AON_MEM_CTL_NON_CRITICAL_MEM_WM AON_MEM_CTL_NON_CRITICAL_MEM_WM_Msk + +#define AON_MEM_CTL_NON_CRITICAL_MEM_RM_Pos (4U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RM_Len (1U) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RM_Msk (0x1U << AON_MEM_CTL_NON_CRITICAL_MEM_RM_Pos) +#define AON_MEM_CTL_NON_CRITICAL_MEM_RM AON_MEM_CTL_NON_CRITICAL_MEM_RM_Msk + +#define AON_MEM_CTL_CRITICAL_MEM_RWM_Pos (2U) +#define AON_MEM_CTL_CRITICAL_MEM_RWM_Len (2U) +#define AON_MEM_CTL_CRITICAL_MEM_RWM_Msk (0x3U << AON_MEM_CTL_CRITICAL_MEM_RWM_Pos) +#define AON_MEM_CTL_CRITICAL_MEM_RWM AON_MEM_CTL_CRITICAL_MEM_RWM_Msk + +#define AON_MEM_CTL_CRITICAL_MEM_WM_Pos (1U) +#define AON_MEM_CTL_CRITICAL_MEM_WM_Len (1U) +#define AON_MEM_CTL_CRITICAL_MEM_WM_Msk (0x1U << AON_MEM_CTL_CRITICAL_MEM_WM_Pos) +#define AON_MEM_CTL_CRITICAL_MEM_WM AON_MEM_CTL_CRITICAL_MEM_WM_Msk + +#define AON_MEM_CTL_CRITICAL_MEM_RM_Pos (0U) +#define AON_MEM_CTL_CRITICAL_MEM_RM_Len (1U) +#define AON_MEM_CTL_CRITICAL_MEM_RM_Msk (0x1U << AON_MEM_CTL_CRITICAL_MEM_RM_Pos) +#define AON_MEM_CTL_CRITICAL_MEM_RM AON_MEM_CTL_CRITICAL_MEM_RM_Msk + +/********************* Bit definition for AON_REG_EXT_WKUP_CTL register ************************************/ +#define AON_EXT_WKUP_CTL_WDT_ALARM_Pos (27U) +#define AON_EXT_WKUP_CTL_WDT_ALARM_Len (5U) +#define AON_EXT_WKUP_CTL_WDT_ALARM_Msk (0x1FU << AON_EXT_WKUP_CTL_WDT_ALARM_Pos) +#define AON_EXT_WKUP_CTL_WDT_ALARM AON_EXT_WKUP_CTL_WDT_ALARM_Msk + +#define AON_EXT_WKUP_CTL_WDT_RUNNING_Pos (26U) +#define AON_EXT_WKUP_CTL_WDT_RUNNING_Len (1U) +#define AON_EXT_WKUP_CTL_WDT_RUNNING_Msk (0x1U << AON_EXT_WKUP_CTL_WDT_RUNNING_Pos) +#define AON_EXT_WKUP_CTL_WDT_RUNNING AON_EXT_WKUP_CTL_WDT_RUNNING_Msk + +#define AON_EXT_WKUP_CTL_WDT_RELOAD_Pos (25U) +#define AON_EXT_WKUP_CTL_WDT_RELOAD_Len (1U) +#define AON_EXT_WKUP_CTL_WDT_RELOAD_Msk (0x1U << AON_EXT_WKUP_CTL_WDT_RELOAD_Pos) +#define AON_EXT_WKUP_CTL_WDT_RELOAD AON_EXT_WKUP_CTL_WDT_RELOAD_Msk + +#define AON_EXT_WKUP_CTL_WDT_EN_Pos (24U) +#define AON_EXT_WKUP_CTL_WDT_EN_Len (1U) +#define AON_EXT_WKUP_CTL_WDT_EN_Msk (0x1U << AON_EXT_WKUP_CTL_WDT_EN_Pos) +#define AON_EXT_WKUP_CTL_WDT_EN AON_EXT_WKUP_CTL_WDT_EN_Msk + +#define AON_EXT_WKUP_CTL_TYPE_Pos (16U) +#define AON_EXT_WKUP_CTL_TYPE_Len (8U) +#define AON_EXT_WKUP_CTL_TYPE_Msk (0xFFU << AON_EXT_WKUP_CTL_TYPE_Pos) +#define AON_EXT_WKUP_CTL_TYPE AON_EXT_WKUP_CTL_TYPE_Msk + +#define AON_EXT_WKUP_CTL_INVERT_Pos (8U) +#define AON_EXT_WKUP_CTL_INVERT_Len (8U) +#define AON_EXT_WKUP_CTL_INVERT_Msk (0xFFU << AON_EXT_WKUP_CTL_INVERT_Pos) +#define AON_EXT_WKUP_CTL_INVERT AON_EXT_WKUP_CTL_INVERT_Msk + +#define AON_EXT_WKUP_CTL_SRC_EN_Pos (0U) +#define AON_EXT_WKUP_CTL_SRC_EN_Len (8U) +#define AON_EXT_WKUP_CTL_SRC_EN_Msk (0xFFU << AON_EXT_WKUP_CTL_SRC_EN_Pos) +#define AON_EXT_WKUP_CTL_SRC_EN AON_EXT_WKUP_CTL_SRC_EN_Msk + +/********************* Bit definition for AON_REG_AON_PAD_CTL1 register ***************************************/ +#define AON_PAD_CTL1_TIMER_READ_SEL_Pos (30U) +#define AON_PAD_CTL1_TIMER_READ_SEL_Len (2U) +#define AON_PAD_CTL1_TIMER_READ_SEL_Msk (0x3U << AON_PAD_CTL1_TIMER_READ_SEL_Pos) +#define AON_PAD_CTL1_TIMER_READ_SEL AON_PAD_CTL1_TIMER_READ_SEL_Msk +#define AON_PAD_CTL1_TIMER_READ_SEL_CAL_TIMER (0x0U << AON_PAD_CTL1_TIMER_READ_SEL_Pos) +#define AON_PAD_CTL1_TIMER_READ_SEL_AON_WDT (0x1U << AON_PAD_CTL1_TIMER_READ_SEL_Pos) +#define AON_PAD_CTL1_TIMER_READ_SEL_SLP_TIMER (0x2U << AON_PAD_CTL1_TIMER_READ_SEL_Pos) +#define AON_PAD_CTL1_TIMER_READ_SEL_CAL_ALARM (0x3U << AON_PAD_CTL1_TIMER_READ_SEL_Pos) + +#define AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN_Pos (25U) +#define AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN_Len (1U) +#define AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN_Msk (0x1U << AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN_Pos) +#define AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN AON_PAD_CTL1_MEM_STDBY_VDDISO_OVR_EN_Msk + +#define AON_PAD_CTL1_O_AON_GPI_Pos (16U) +#define AON_PAD_CTL1_O_AON_GPI_Len (6U) +#define AON_PAD_CTL1_O_AON_GPI_Msk (0x3FU << AON_PAD_CTL1_O_AON_GPI_Pos) +#define AON_PAD_CTL1_O_AON_GPI AON_PAD_CTL1_O_AON_GPI_Msk + +#define AON_PAD_CTL1_AON_GPO_Pos (8U) +#define AON_PAD_CTL1_AON_GPO_Len (8U) +#define AON_PAD_CTL1_AON_GPO_Msk (0xFFU << AON_PAD_CTL1_AON_GPO_Pos) +#define AON_PAD_CTL1_AON_GPO AON_PAD_CTL1_AON_GPO_Msk + +#define AON_PAD_CTL1_AON_GPO_OE_N_Pos (0U) +#define AON_PAD_CTL1_AON_GPO_OE_N_Len (8U) +#define AON_PAD_CTL1_AON_GPO_OE_N_Msk (0xFFU << AON_PAD_CTL1_AON_GPO_OE_N_Pos) +#define AON_PAD_CTL1_AON_GPO_OE_N AON_PAD_CTL1_AON_GPO_OE_N_Msk + +/********************* Bit definition for AON_REG_MEM_PWR_SLP register **************************************/ +#define AON_MEM_PWR_SLP_PD_MCU_KEYRAM_Pos (28U) +#define AON_MEM_PWR_SLP_PD_MCU_KEYRAM_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_KEYRAM_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_KEYRAM_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_KEYRAM AON_MEM_PWR_SLP_PD_MCU_KEYRAM_Msk + +#define AON_MEM_PWR_SLP_PD_PACKET_MEM_Pos (26U) +#define AON_MEM_PWR_SLP_PD_PACKET_MEM_Len (2U) +#define AON_MEM_PWR_SLP_PD_PACKET_MEM_Msk (0x3U << AON_MEM_PWR_SLP_PD_PACKET_MEM_Pos) +#define AON_MEM_PWR_SLP_PD_PACKET_MEM AON_MEM_PWR_SLP_PD_PACKET_MEM_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_ICACHE_Pos (24U) +#define AON_MEM_PWR_SLP_PD_MCU_ICACHE_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_ICACHE_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_ICACHE_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_ICACHE AON_MEM_PWR_SLP_PD_MCU_ICACHE_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_HTM_Pos (22U) +#define AON_MEM_PWR_SLP_PD_MCU_HTM_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_HTM_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_HTM_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_HTM AON_MEM_PWR_SLP_PD_MCU_HTM_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_10_Pos (20U) +#define AON_MEM_PWR_SLP_PD_MCU_10_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_10_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_10_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_10 AON_MEM_PWR_SLP_PD_MCU_10_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_09_Pos (18U) +#define AON_MEM_PWR_SLP_PD_MCU_09_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_09_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_09_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_09 AON_MEM_PWR_SLP_PD_MCU_09_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_08_Pos (16U) +#define AON_MEM_PWR_SLP_PD_MCU_08_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_08_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_08_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_08 AON_MEM_PWR_SLP_PD_MCU_08_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_07_Pos (14U) +#define AON_MEM_PWR_SLP_PD_MCU_07_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_07_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_07_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_07 AON_MEM_PWR_SLP_PD_MCU_07_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_06_Pos (12U) +#define AON_MEM_PWR_SLP_PD_MCU_06_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_06_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_06_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_06 AON_MEM_PWR_SLP_PD_MCU_06_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_05_Pos (10U) +#define AON_MEM_PWR_SLP_PD_MCU_05_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_05_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_05_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_05 AON_MEM_PWR_SLP_PD_MCU_05_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_04_Pos (8U) +#define AON_MEM_PWR_SLP_PD_MCU_04_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_04_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_04_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_04 AON_MEM_PWR_SLP_PD_MCU_04_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_03_Pos (6U) +#define AON_MEM_PWR_SLP_PD_MCU_03_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_03_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_03_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_03 AON_MEM_PWR_SLP_PD_MCU_03_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_02_Pos (4U) +#define AON_MEM_PWR_SLP_PD_MCU_02_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_02_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_02_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_02 AON_MEM_PWR_SLP_PD_MCU_02_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_01_Pos (2U) +#define AON_MEM_PWR_SLP_PD_MCU_01_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_01_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_01_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_01 AON_MEM_PWR_SLP_PD_MCU_01_Msk + +#define AON_MEM_PWR_SLP_PD_MCU_00_Pos (0U) +#define AON_MEM_PWR_SLP_PD_MCU_00_Len (2U) +#define AON_MEM_PWR_SLP_PD_MCU_00_Msk (0x3U << AON_MEM_PWR_SLP_PD_MCU_00_Pos) +#define AON_MEM_PWR_SLP_PD_MCU_00 AON_MEM_PWR_SLP_PD_MCU_00_Msk + +/**************************** Bit definition for AON_REG_MEM_PWR_WKUP register *****************************/ +#define AON_MEM_PWR_WKUP_PD_MCU_KEYRAM_Pos (28U) +#define AON_MEM_PWR_WKUP_PD_MCU_KEYRAM_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_KEYRAM_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_KEYRAM_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_KEYRAM AON_MEM_PWR_WKUP_PD_MCU_KEYRAM_Msk + +#define AON_MEM_PWR_WKUP_PD_PACKET_MEM_Pos (26U) +#define AON_MEM_PWR_WKUP_PD_PACKET_MEM_Len (2U) +#define AON_MEM_PWR_WKUP_PD_PACKET_MEM_Msk (0x3U << AON_MEM_PWR_WKUP_PD_PACKET_MEM_Pos) +#define AON_MEM_PWR_WKUP_PD_PACKET_MEM AON_MEM_PWR_WKUP_PD_PACKET_MEM_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_ICACHE_Pos (24U) +#define AON_MEM_PWR_WKUP_PD_MCU_ICACHE_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_ICACHE_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_ICACHE_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_ICACHE AON_MEM_PWR_WKUP_PD_MCU_ICACHE_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_HTM_Pos (22U) +#define AON_MEM_PWR_WKUP_PD_MCU_HTM_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_HTM_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_HTM_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_HTM AON_MEM_PWR_WKUP_PD_MCU_HTM_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_10_Pos (20U) +#define AON_MEM_PWR_WKUP_PD_MCU_10_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_10_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_10_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_10 AON_MEM_PWR_WKUP_PD_MCU_10_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_09_Pos (18U) +#define AON_MEM_PWR_WKUP_PD_MCU_09_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_09_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_09_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_09 AON_MEM_PWR_WKUP_PD_MCU_09_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_08_Pos (16U) +#define AON_MEM_PWR_WKUP_PD_MCU_08_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_08_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_08_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_08 AON_MEM_PWR_WKUP_PD_MCU_08_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_07_Pos (14U) +#define AON_MEM_PWR_WKUP_PD_MCU_07_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_07_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_07_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_07 AON_MEM_PWR_WKUP_PD_MCU_07_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_06_Pos (12U) +#define AON_MEM_PWR_WKUP_PD_MCU_06_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_06_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_06_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_06 AON_MEM_PWR_WKUP_PD_MCU_06_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_05_Pos (10U) +#define AON_MEM_PWR_WKUP_PD_MCU_05_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_05_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_05_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_05 AON_MEM_PWR_WKUP_PD_MCU_05_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_04_Pos (8U) +#define AON_MEM_PWR_WKUP_PD_MCU_04_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_04_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_04_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_04 AON_MEM_PWR_WKUP_PD_MCU_04_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_03_Pos (6U) +#define AON_MEM_PWR_WKUP_PD_MCU_03_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_03_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_03_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_03 AON_MEM_PWR_WKUP_PD_MCU_03_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_02_Pos (4U) +#define AON_MEM_PWR_WKUP_PD_MCU_02_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_02_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_02_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_02 AON_MEM_PWR_WKUP_PD_MCU_02_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_01_Pos (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_01_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_01_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_01_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_01 AON_MEM_PWR_WKUP_PD_MCU_01_Msk + +#define AON_MEM_PWR_WKUP_PD_MCU_00_Pos (0U) +#define AON_MEM_PWR_WKUP_PD_MCU_00_Len (2U) +#define AON_MEM_PWR_WKUP_PD_MCU_00_Msk (0x3U << AON_MEM_PWR_WKUP_PD_MCU_00_Pos) +#define AON_MEM_PWR_WKUP_PD_MCU_00 AON_MEM_PWR_WKUP_PD_MCU_00_Msk + +/*********************** Bit definition for AON_REG_PWR_RET28 register ***************************/ +#define AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME_Pos (0U) +#define AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME_Len (32U) +#define AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME_Msk (0xFFFFFFFFU) +#define AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME AON_COMM_TMR_DEEPSLWKUP_DEEPSLTIME_Msk + +/*********************** Bit definition for AON_REG_PWR_RET29 register ************************/ +#define AON_COMM_TMR_ENBPRESET_TWEXT_Pos (21U) +#define AON_COMM_TMR_ENBPRESET_TWEXT_Len (11U) +#define AON_COMM_TMR_ENBPRESET_TWEXT_Msk (0x07FFU << AON_COMM_TMR_ENBPRESET_TWEXT_Pos) +#define AON_COMM_TMR_ENBPRESET_TWEXT AON_COMM_TMR_ENBPRESET_TWEXT_Msk + +#define AON_COMM_TMR_ENBPRESET_TWOSC_Pos (10U) +#define AON_COMM_TMR_ENBPRESET_TWOSC_Len (11U) +#define AON_COMM_TMR_ENBPRESET_TWOSC_Msk (0x07FFU << AON_COMM_TMR_ENBPRESET_TWOSC_Pos) +#define AON_COMM_TMR_ENBPRESET_TWOSC AON_COMM_TMR_ENBPRESET_TWOSC_Msk + +#define AON_COMM_TMR_ENBPRESET_TWRM_Pos (0U) +#define AON_COMM_TMR_ENBPRESET_TWRM_Len (10U) +#define AON_COMM_TMR_ENBPRESET_TWRM_Msk (0x03FFU << AON_COMM_TMR_ENBPRESET_TWRM_Pos) +#define AON_COMM_TMR_ENBPRESET_TWRM AON_COMM_TMR_ENBPRESET_TWRM_Msk + +/*********************** Bit definition for AON_REG_PWR_RET31 register *********************************/ +#define AON_PWR_REG31_FPGA_DBG_MUX_SEL_Pos (0U) +#define AON_PWR_REG31_FPGA_DBG_MUX_SEL_Len (2U) +#define AON_PWR_REG31_FPGA_DBG_MUX_SEL_Msk (0x3U << AON_PWR_REG31_FPGA_DBG_MUX_SEL_Pos) +#define AON_PWR_REG31_FPGA_DBG_MUX_SEL AON_PWR_REG31_FPGA_DBG_MUX_SEL_Msk + +/*********************** Bit definition for AON_REG_PSC_CMD register ***************************************/ +#define AON_PSC_CMD_MCU_PWR_BUSY_Pos (1U) +#define AON_PSC_CMD_MCU_PWR_BUSY_Len (1U) +#define AON_PSC_CMD_MCU_PWR_BUSY_Msk (0x1U << AON_PSC_CMD_MCU_PWR_BUSY_Pos) +#define AON_PSC_CMD_MCU_PWR_BUSY AON_PSC_CMD_MCU_PWR_BUSY_Msk + +#define AON_PSC_CMD_MCU_PWR_REQ_Pos (0U) +#define AON_PSC_CMD_MCU_PWR_REQ_Len (1U) +#define AON_PSC_CMD_MCU_PWR_REQ_Msk (0x1U << AON_PSC_CMD_MCU_PWR_REQ_Pos) +#define AON_PSC_CMD_MCU_PWR_REQ AON_PSC_CMD_MCU_PWR_REQ_Msk + +/********************** Bit definition for AON_REG_PSC_CMD_OPC register ************************************/ +#define AON_PSC_CMD_OPC_OPCODE_Pos (0U) +#define AON_PSC_CMD_OPC_OPCODE_Len (8U) +#define AON_PSC_CMD_OPC_OPCODE_Msk (0xFFU << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE AON_PSC_CMD_OPC_OPCODE_Msk +#define AON_PSC_CMD_OPC_OPCODE_LOOPBACK (0x0U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_EF_DIR_ON (0x1U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_32_TIMER_LD (0x2U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_DEEP_SLEEP (0x3U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_EF_DIR_OFF (0x4U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_EXT_CLK (0x5U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_RNG_CLK (0x6U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_RTC_CLK (0x7U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_RNG2_CLK (0x8U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_LD_MEM_SLP_CFG (0x9U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_LD_MEM_WKUP_CFG (0xAU << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_DPAD_LE_HI (0xBU << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_DPAD_LE_LO (0xCU << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_0 (0x10U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_1 (0x11U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_2 (0x12U << AON_PSC_CMD_OPC_OPCODE_Pos) +#define AON_PSC_CMD_OPC_OPCODE_SLP_TIMER_MODE_3 (0x13U << AON_PSC_CMD_OPC_OPCODE_Pos) + +/******************* Bit definition for AON_REG_TIMER_VALUE register **********/ +#define AON_TIMER_VALUE_PWR_CTL_TIMER_32B_Pos (0U) +#define AON_TIMER_VALUE_PWR_CTL_TIMER_32B_Len (32U) +#define AON_TIMER_VALUE_PWR_CTL_TIMER_32B_Msk (0xFFFFFFFFU) +#define AON_TIMER_VALUE_PWR_CTL_TIMER_32B AON_TIMER_VALUE_PWR_CTL_TIMER_32B_Msk + +/********************* Bit definition for AON_REG_TIMER_VAL register **************************************/ +#define AON_TIMER_VAL_READ_Pos (0U) +#define AON_TIMER_VAL_READ_Len (32U) +#define AON_TIMER_VAL_READ_Msk (0xFFFFFFFFU) +#define AON_TIMER_VAL_READ AON_TIMER_VAL_READ_Msk + +/*********************** Bit definition for AON_REG_FPGA_CTRL register *********************************/ +#define AON_REG_FPGA_CTRL_MUX_SEL_Pos (0U) +#define AON_REG_FPGA_CTRL_MUX_SEL_Len (2U) +#define AON_REG_FPGA_CTRL_MUX_SEL_Msk (0x3U << AON_REG_FPGA_CTRL_MUX_SEL_Pos) +#define AON_REG_FPGA_CTRL_MUX_SEL AON_REG_FPGA_CTRL_MUX_SEL_Msk + +#define AON_REG_FPGA_CTRL_EXIST_Pos (4U) +#define AON_REG_FPGA_CTRL_EXIST_Len (1U) +#define AON_REG_FPGA_CTRL_EXIST_Msk (0x1U << AON_REG_FPGA_CTRL_EXIST_Pos) +#define AON_REG_FPGA_CTRL_EXIST AON_REG_FPGA_CTRL_EXIST_Msk + +/********************** Bit definition for AON_REG_ST_CALIB_REG register ***********************************/ +#define AON_ST_CALIB_REG_STCALIB_Pos (0U) +#define AON_ST_CALIB_REG_STCALIB_Len (27U) +#define AON_ST_CALIB_REG_STCALIB_Msk (0x7FFFFFFU << AON_ST_CALIB_REG_STCALIB_Pos) +#define AON_ST_CALIB_REG_STCALIB AON_ST_CALIB_REG_STCALIB_Msk + + +/* ================================================================================================================= */ +/* ================ DMA ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for DMA_SAR register ********************/ +#define DMA_SAR_CSA_Pos (0U) +#define DMA_SAR_CSA_Len (32U) +#define DMA_SAR_CSA_Msk (0xFFFFFFFFU) +#define DMA_SAR_CSA DMA_SAR_CSA_Msk + +/******************* Bit definition for DMA_DAR register ********************/ +#define DMA_DAR_CDA_Pos (0U) +#define DMA_DAR_CDA_Len (32U) +#define DMA_DAR_CDA_Msk (0xFFFFFFFFU) +#define DMA_DAR_CDA DMA_DAR_CDA_Msk + +/******************* Bit definition for DMA_CTLL register *******************/ +#define DMA_CTLL_TT_FC_Pos (20U) +#define DMA_CTLL_TT_FC_Len (2U) +#define DMA_CTLL_TT_FC_Msk (0x3U << DMA_CTLL_TT_FC_Pos) +#define DMA_CTLL_TT_FC DMA_CTLL_TT_FC_Msk +#define DMA_CTLL_TT_FC_M2M (0x0U << DMA_CTLL_TT_FC_Pos) +#define DMA_CTLL_TT_FC_M2P (0x1U << DMA_CTLL_TT_FC_Pos) +#define DMA_CTLL_TT_FC_P2M (0x2U << DMA_CTLL_TT_FC_Pos) +#define DMA_CTLL_TT_FC_P2P (0x3U << DMA_CTLL_TT_FC_Pos) + +#define DMA_CTLL_SRC_MSIZE_Pos (14U) +#define DMA_CTLL_SRC_MSIZE_Len (3U) +#define DMA_CTLL_SRC_MSIZE_Msk (0x7U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE DMA_CTLL_SRC_MSIZE_Msk +#define DMA_CTLL_SRC_MSIZE_1 (0x0U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_4 (0x1U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_8 (0x2U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_16 (0x3U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_32 (0x4U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_64 (0x5U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_128 (0x6U << DMA_CTLL_SRC_MSIZE_Pos) +#define DMA_CTLL_SRC_MSIZE_256 (0x7U << DMA_CTLL_SRC_MSIZE_Pos) + +#define DMA_CTLL_DST_MSIZE_Pos (11U) +#define DMA_CTLL_DST_MSIZE_Len (3U) +#define DMA_CTLL_DST_MSIZE_Msk (0x7U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE DMA_CTLL_DST_MSIZE_Msk +#define DMA_CTLL_DST_MSIZE_1 (0x0U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_4 (0x1U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_8 (0x2U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_16 (0x3U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_32 (0x4U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_64 (0x5U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_128 (0x6U << DMA_CTLL_DST_MSIZE_Pos) +#define DMA_CTLL_DST_MSIZE_256 (0x7U << DMA_CTLL_DST_MSIZE_Pos) + +#define DMA_CTLL_SINC_Pos (9U) +#define DMA_CTLL_SINC_Len (2U) +#define DMA_CTLL_SINC_Msk (0x3U << DMA_CTLL_SINC_Pos) +#define DMA_CTLL_SINC DMA_CTLL_SINC_Msk +#define DMA_CTLL_SINC_INC (0x0U << DMA_CTLL_SINC_Pos) +#define DMA_CTLL_SINC_DEC (0x1U << DMA_CTLL_SINC_Pos) +#define DMA_CTLL_SINC_NO (0x2U << DMA_CTLL_SINC_Pos) + +#define DMA_CTLL_DINC_Pos (7U) +#define DMA_CTLL_DINC_Len (2U) +#define DMA_CTLL_DINC_Msk (0x3U << DMA_CTLL_DINC_Pos) +#define DMA_CTLL_DINC DMA_CTLL_DINC_Msk +#define DMA_CTLL_DINC_INC (0x0U << DMA_CTLL_DINC_Pos) +#define DMA_CTLL_DINC_DEC (0x1U << DMA_CTLL_DINC_Pos) +#define DMA_CTLL_DINC_NO (0x2U << DMA_CTLL_DINC_Pos) + +#define DMA_CTLL_SRC_TR_WIDTH_Pos (4U) +#define DMA_CTLL_SRC_TR_WIDTH_Len (2U) +#define DMA_CTLL_SRC_TR_WIDTH_Msk (0x3U << DMA_CTLL_SRC_TR_WIDTH_Pos) +#define DMA_CTLL_SRC_TR_WIDTH DMA_CTLL_SRC_TR_WIDTH_Msk +#define DMA_CTLL_SRC_TR_WIDTH_8 (0x0U << DMA_CTLL_SRC_TR_WIDTH_Pos) +#define DMA_CTLL_SRC_TR_WIDTH_16 (0x1U << DMA_CTLL_SRC_TR_WIDTH_Pos) +#define DMA_CTLL_SRC_TR_WIDTH_32 (0x2U << DMA_CTLL_SRC_TR_WIDTH_Pos) + +#define DMA_CTLL_DST_TR_WIDTH_Pos (1U) +#define DMA_CTLL_DST_TR_WIDTH_Len (2U) +#define DMA_CTLL_DST_TR_WIDTH_Msk (0x3U << DMA_CTLL_DST_TR_WIDTH_Pos) +#define DMA_CTLL_DST_TR_WIDTH DMA_CTLL_DST_TR_WIDTH_Msk +#define DMA_CTLL_DST_TR_WIDTH_8 (0x0U << DMA_CTLL_DST_TR_WIDTH_Pos) +#define DMA_CTLL_DST_TR_WIDTH_16 (0x1U << DMA_CTLL_DST_TR_WIDTH_Pos) +#define DMA_CTLL_DST_TR_WIDTH_32 (0x2U << DMA_CTLL_DST_TR_WIDTH_Pos) + +#define DMA_CTLL_INT_EN_Pos (0U) +#define DMA_CTLL_INT_EN_Len (1U) +#define DMA_CTLL_INT_EN_Msk (0x1U << DMA_CTLL_INT_EN_Pos) +#define DMA_CTLL_INI_EN DMA_CTLL_INT_EN_Msk + +/******************* Bit definition for DMA_CTLH register *******************/ +#define DMA_CTLH_BLOCK_TS_Pos (0U) +#define DMA_CTLH_BLOCK_TS_Len (12U) +#define DMA_CTLH_BLOCK_TS_Msk (0xFFFU << DMA_CTLH_BLOCK_TS_Pos) +#define DMA_CTLH_BLOCK_TS DMA_CTLH_BLOCK_TS_Msk + +/******************* Bit definition for DMA_CFGL register *******************/ +#define DMA_CFGL_RELOAD_DST_Pos (31U) +#define DMA_CFGL_RELOAD_DST_Len (1U) +#define DMA_CFGL_RELOAD_DST_Msk (0x1U << DMA_CFGL_RELOAD_DST_Pos) +#define DMA_CFGL_RELOAD_DST DMA_CFGL_RELOAD_DST_Msk + +#define DMA_CFGL_RELOAD_SRC_Pos (30U) +#define DMA_CFGL_RELOAD_SRC_Len (1U) +#define DMA_CFGL_RELOAD_SRC_Msk (0x1U << DMA_CFGL_RELOAD_SRC_Pos) +#define DMA_CFGL_RELOAD_SRC DMA_CFGL_RELOAD_SRC_Msk + +#define DMA_CFGL_HS_SEL_SRC_Pos (11U) +#define DMA_CFGL_HS_SEL_SRC_Len (1U) +#define DMA_CFGL_HS_SEL_SRC_Msk (0x1U << DMA_CFGL_HS_SEL_SRC_Pos) +#define DMA_CFGL_HS_SEL_SRC DMA_CFGL_HS_SEL_SRC_Msk + +#define DMA_CFGL_HS_SEL_DST_Pos (10U) +#define DMA_CFGL_HS_SEL_DST_Len (1U) +#define DMA_CFGL_HS_SEL_DST_Msk (0x1U << DMA_CFGL_HS_SEL_DST_Pos) +#define DMA_CFGL_HS_SEL_DST DMA_CFGL_HS_SEL_DST_Msk + +#define DMA_CFGL_FIFO_EMPTY_Pos (9U) +#define DMA_CFGL_FIFO_EMPTY_Len (1U) +#define DMA_CFGL_FIFO_EMPTY_Msk (0x1U << DMA_CFGL_FIFO_EMPTY_Pos) +#define DMA_CFGL_FIFO_EMPTY DMA_CFGL_FIFO_EMPTY_Msk + +#define DMA_CFGL_CH_SUSP_Pos (8U) +#define DMA_CFGL_CH_SUSP_Len (1U) +#define DMA_CFGL_CH_SUSP_Msk (0x1U << DMA_CFGL_CH_SUSP_Pos) +#define DMA_CFGL_CH_SUSP DMA_CFGL_CH_SUSP_Msk + +#define DMA_CFGL_CH_PRIOR_Pos (5U) +#define DMA_CFGL_CH_PRIOR_Len (3U) +#define DMA_CFGL_CH_PRIOR_Msk (0x7U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR DMA_CFGL_CH_PRIOR_Msk +#define DMA_CFGL_CH_PRIOR_0 (0x0U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_1 (0x1U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_2 (0x2U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_3 (0x3U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_4 (0x4U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_5 (0x5U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_6 (0x6U << DMA_CFGL_CH_PRIOR_Pos) +#define DMA_CFGL_CH_PRIOR_7 (0x7U << DMA_CFGL_CH_PRIOR_Pos) + +/******************* Bit definition for DMA_CFGH register ********************/ +#define DMA_CFGH_DST_PER_Pos (11U) +#define DMA_CFGH_DST_PER_Len (4U) +#define DMA_CFGH_DST_PER_Msk (0xFU << DMA_CFGH_DST_PER_Pos) +#define DMA_CFGH_DST_PER DMA_CFGH_DST_PER_Msk + +#define DMA_CFGH_SRC_PER_Pos (7U) +#define DMA_CFGH_SRC_PER_Len (4U) +#define DMA_CFGH_SRC_PER_Msk (0xFU << DMA_CFGH_SRC_PER_Pos) +#define DMA_CFGH_SRC_PER DMA_CFGH_SRC_PER_Msk + +#define DMA_CFGH_PROTCTL_Pos (2U) +#define DMA_CFGH_PROTCTL_Len (3U) +#define DMA_CFGH_PROTCTL_Msk (0x7U << DMA_CFGH_PROTCTL_Pos) +#define DMA_CFGH_PROTCTL DMA_CFGH_PROTCTL_Msk + +#define DMA_CFGH_FIFO_MODE_Pos (2U) +#define DMA_CFGH_FIFO_MODE_Len (1U) +#define DMA_CFGH_FIFO_MODE_Msk (0x1U << DMA_CFGH_FIFO_MODE_Pos) +#define DMA_CFGH_FIFO_MODE DMA_CFGH_FIFO_MODE_Msk + +/******************* Bit definition for DMA_RAW_TFR register *****************/ +#define DMA_RAW_TFR_Pos (0U) +#define DMA_RAW_TFR_Len (8U) +#define DMA_RAW_TFR_Msk (0xFFU << DMA_RAW_TFR_Pos) +#define DMA_RAW_TFR DMA_RAW_TFR_Msk + +/******************* Bit definition for DMA_RAW_BLK register *****************/ +#define DMA_RAW_BLK_Pos (0U) +#define DMA_RAW_BLK_Len (8U) +#define DMA_RAW_BLK_Msk (0xFFU << DMA_RAW_BLK_Pos) +#define DMA_RAW_BLK DMA_RAW_BLK_Msk + +/******************* Bit definition for DMA_RAW_SRC_TRN register *************/ +#define DMA_RAW_SRC_TRN_Pos (0U) +#define DMA_RAW_SRC_TRN_Len (8U) +#define DMA_RAW_SRC_TRN_Msk (0xFFU << DMA_RAW_SRC_TRN_Pos) +#define DMA_RAW_SRC_TRN DMA_RAW_SRC_TRN_Msk + +/******************* Bit definition for DMA_RAW_DST_TRN register *************/ +#define DMA_RAW_DST_TRN_Pos (0U) +#define DMA_RAW_DST_TRN_Len (8U) +#define DMA_RAW_DST_TRN_Msk (0xFFU << DMA_RAW_DST_TRN_Pos) +#define DMA_RAW_DST_TRN DMA_RAW_DST_TRN_Msk + +/******************* Bit definition for DMA_RAW_ERR register *****************/ +#define DMA_RAW_ERR_Pos (0U) +#define DMA_RAW_ERR_Len (8U) +#define DMA_RAW_ERR_Msk (0xFFU << DMA_RAW_ERR_Pos) +#define DMA_RAW_ERR DMA_RAW_ERR_Msk + +/******************* Bit definition for DMA_STAT_TFR register ****************/ +#define DMA_STAT_TFR_Pos (0U) +#define DMA_STAT_TFR_Len (8U) +#define DMA_STAT_TFR_Msk (0xFFUL << DMA_STAT_TFR_Pos) +#define DMA_STAT_TFR DMA_STAT_TFR_Msk + +/******************* Bit definition for DMA_STAT_BLK register ****************/ +#define DMA_STAT_BLK_Pos (0U) +#define DMA_STAT_BLK_Len (8U) +#define DMA_STAT_BLK_Msk (0xFFU << DMA_STAT_BLK_Pos) +#define DMA_STAT_BLK DMA_STAT_BLK_Msk + +/******************* Bit definition for DMA_STAT_SRC_TRN register ************/ +#define DMA_STAT_SRC_TRN_Pos (0U) +#define DMA_STAT_SRC_TRN_Len (8U) +#define DMA_STAT_SRC_TRN_Msk (0xFFU << DMA_STAT_SRC_TRN_Pos) +#define DMA_STAT_SRC_TRN DMA_STAT_SRC_TRN_Msk + +/******************* Bit definition for DMA_STAT_DST_TRN register ************/ +#define DMA_STAT_DST_TRN_Pos (0U) +#define DMA_STAT_DST_TRN_Len (8U) +#define DMA_STAT_DST_TRN_Msk (0xFFU << DMA_STAT_DST_TRN_Pos) +#define DMA_STAT_DST_TRN DMA_STAT_DST_TRN_Msk + +/******************* Bit definition for DMA_STAT_ERR register ****************/ +#define DMA_STAT_ERR_Pos (0U) +#define DMA_STAT_ERR_Len (8U) +#define DMA_STAT_ERR_Msk (0xFFU << DMA_STAT_ERR_Pos) +#define DMA_STAT_ERR DMA_STAT_ERR_Msk + +/******************* Bit definition for DMA_MASK_TFR register ****************/ +#define DMA_MASK_TFR_WE_Pos (8U) +#define DMA_MASK_TFR_WE_Len (8U) +#define DMA_MASK_TFR_WE_Msk (0xFFU << DMA_MASK_TFR_WE_Pos) +#define DMA_MASK_TFR_WE DMA_MASK_TFR_WE_Msk + +#define DMA_MASK_TFR_Pos (0U) +#define DMA_MASK_TFR_Len (8U) +#define DMA_MASK_TFR_Msk (0xFFU << DMA_MASK_TFR_Pos) +#define DMA_MASK_TFR DMA_MASK_TFR_Msk + +/******************* Bit definition for DMA_MASK_BLK register ****************/ +#define DMA_MASK_BLK_WE_Pos (8U) +#define DMA_MASK_BLK_WE_Len (8U) +#define DMA_MASK_BLK_WE_Msk (0xFFU << DMA_MASK_BLK_WE_Pos) +#define DMA_MASK_BLK_WE DMA_MASK_BLK_WE_Msk + +#define DMA_MASK_BLK_Pos (0U) +#define DMA_MASK_BLK_Len (8U) +#define DMA_MASK_BLK_Msk (0xFFU << DMA_MASK_BLK_Pos) +#define DMA_MASK_BLK DMA_MASK_BLK_Msk + +/******************* Bit definition for DMA_MASK_SRC_TRN register ************/ +#define DMA_MASK_SRC_TRN_WE_Pos (8U) +#define DMA_MASK_SRC_TRN_WE_Len (8U) +#define DMA_MASK_SRC_TRN_WE_Msk (0x1U << DMA_MASK_SRC_TRN_WE_Pos) +#define DMA_MASK_SRC_TRN_WE DMA_MASK_SRC_TRN_WE_Msk + +#define DMA_MASK_SRC_TRN_Pos (0U) +#define DMA_MASK_SRC_TRN_Len (8U) +#define DMA_MASK_SRC_TRN_Msk (0xFFU << DMA_MASK_SRC_TRN_Pos) +#define DMA_MASK_SRC_TRN DMA_MASK_SRC_TRN_Msk + +/******************* Bit definition for DMA_MASK_DST_TRN register ************/ +#define DMA_MASK_DST_TRN_WE_Pos (8U) +#define DMA_MASK_DST_TRN_WE_Len (8U) +#define DMA_MASK_DST_TRN_WE_Msk (0xFFU << DMA_MASK_DST_TRN_WE_Pos) +#define DMA_MASK_DST_TRN_WE DMA_MASK_DST_TRN_WE_Msk + +#define DMA_MASK_DST_TRN_Pos (0U) +#define DMA_MASK_DST_TRN_Len (8U) +#define DMA_MASK_DST_TRN_Msk (0xFFU << DMA_MASK_DST_TRN_Pos) +#define DMA_MASK_DST_TRN DMA_MASK_DST_TRN_Msk + +/******************* Bit definition for DMA_MASK_ERR register ****************/ +#define DMA_MASK_ERR_WE_Pos (8U) +#define DMA_MASK_ERR_WE_Len (8U) +#define DMA_MASK_ERR_WE_Msk (0xFFU << DMA_MASK_ERR_WE_Pos) +#define DMA_MASK_ERR_WE DMA_MASK_ERR_WE_Msk + +#define DMA_MASK_ERR_Pos (0U) +#define DMA_MASK_ERR_Len (8U) +#define DMA_MASK_ERR_Msk (0xFFU << DMA_MASK_ERR_Pos) +#define DMA_MASK_ERR DMA_MASK_ERR_Msk + +/******************* Bit definition for DMA_CLR_TFR register *****************/ +#define DMA_CLR_TFR_Pos (0U) +#define DMA_CLR_TFR_Len (8U) +#define DMA_CLR_TFR_Msk (0xFFU << DMA_CLR_TFR_Pos) +#define DMA_CLR_TFR DMA_CLR_TFR_Msk + +/******************* Bit definition for DMA_CLR_BLK register *****************/ +#define DMA_CLR_BLK_Pos (0U) +#define DMA_CLR_BLK_Len (8U) +#define DMA_CLR_BLK_Msk (0xFFU << DMA_CLR_BLK_Pos) +#define DMA_CLR_BLK DMA_CLR_BLK_Msk + +/******************* Bit definition for DMA_CLR_SRC_TRN register *************/ +#define DMA_CLR_SRC_TRN_Pos (0U) +#define DMA_CLR_SRC_TRN_Len (8U) +#define DMA_CLR_SRC_TRN_Msk (0xFFU << DMA_CLR_SRC_TRN_Pos) +#define DMA_CLR_SRC_TRN DMA_CLR_SRC_TRN_Msk + +/******************* Bit definition for DMA_CLR_DST_TRN register *************/ +#define DMA_CLR_DST_TRN_Pos (0U) +#define DMA_CLR_DST_TRN_Len (8U) +#define DMA_CLR_DST_TRN_Msk (0xFFU << DMA_CLR_DST_TRN_Pos) +#define DMA_CLR_DST_TRN DMA_CLR_DST_TRN_Msk + +/******************* Bit definition for DMA_CLR_ERR register *****************/ +#define DMA_CLR_ERR_Pos (0U) +#define DMA_CLR_ERR_Len (8U) +#define DMA_CLR_ERR_Msk (0xFFU << DMA_CLR_ERR_Pos) +#define DMA_CLR_ERR DMA_CLR_ERR_Msk + +/******************* Bit definition for DMA_STATUS_INT register **************/ +#define DMA_STAT_INT_ERR_Pos (4U) +#define DMA_STAT_INT_ERR_Len (1U) +#define DMA_STAT_INT_ERR_Msk (0x1U << DMA_STAT_INT_ERR_Pos) +#define DMA_STAT_INT_ERR DMA_STAT_INT_ERR_Msk + +#define DMA_STAT_INT_DST_Pos (3U) +#define DMA_STAT_INT_DST_Len (1U) +#define DMA_STAT_INT_DST_Msk (0x1U << DMA_STAT_INT_DST_Pos) +#define DMA_STAT_INT_DST DMA_STAT_INT_DST_Msk + +#define DMA_STAT_INT_SRC_Pos (2U) +#define DMA_STAT_INT_SRC_Len (1U) +#define DMA_STAT_INT_SRC_Msk (0x1U << DMA_STAT_INT_SRC_Pos) +#define DMA_STAT_INT_SRC DMA_STAT_INT_SRC_Msk + +#define DMA_STAT_INT_BLK_Pos (1U) +#define DMA_STAT_INT_BLK_Len (1U) +#define DMA_STAT_INT_BLK_Msk (0x1U << DMA_STAT_INT_BLK_Pos) +#define DMA_STAT_INT_BLK DMA_STAT_INT_BLK_Msk + +#define DMA_STAT_INT_TFR_Pos (0U) +#define DMA_STAT_INT_TFR_Len (1U) +#define DMA_STAT_INT_TFR_Msk (0x1U << DMA_STAT_INT_TFR_Pos) +#define DMA_STAT_INT_TFR DMA_STAT_INT_TFR_Msk + +/******************* Bit definition for DMA_REQ_SRC_REG register *************/ +#define DMA_REQ_SRC_WE_Pos (8U) +#define DMA_REQ_SRC_WE_Len (8U) +#define DMA_REQ_SRC_WE_Msk (0xFFU << DMA_REQ_SRC_WE_Pos) +#define DMA_REQ_SRC_WE DMA_REQ_SRC_WE_Msk + +#define DMA_REQ_SRC_Pos (0U) +#define DMA_REQ_SRC_Len (8U) +#define DMA_REQ_SRC_Msk (0xFFU << DMA_REQ_SRC_Pos) +#define DMA_REQ_SRC DMA_REQ_SRC_Msk + +/******************* Bit definition for DMA_REQ_DST_REG register *************/ +#define DMA_REQ_DST_WE_Pos (8U) +#define DMA_REQ_DST_WE_Len (8U) +#define DMA_REQ_DST_WE_Msk (0xFFU << DMA_REQ_DST_WE_Pos) +#define DMA_REQ_DST_WE DMA_REQ_DST_WE_Msk + +#define DMA_REQ_DST_Pos (0U) +#define DMA_REQ_DST_Len (8U) +#define DMA_REQ_DST_Msk (0xFFU << DMA_REQ_DST_Pos) +#define DMA_REQ_DST DMA_REQ_DST_Msk + +/******************* Bit definition for DMA_SGL_REQ_SRC_REG register *********/ +#define DMA_SGL_REQ_SRC_WE_Pos (8U) +#define DMA_SGL_REQ_SRC_WE_Len (8U) +#define DMA_SGL_REQ_SRC_WE_Msk (0xFFU << DMA_SGL_REQ_SRC_WE_Pos) +#define DMA_SGL_REQ_SRC_WE DMA_SGL_REQ_SRC_WE_Msk + +#define DMA_SGL_REQ_SRC_Pos (0U) +#define DMA_SGL_REQ_SRC_Len (8U) +#define DMA_SGL_REQ_SRC_Msk (0xFFU << DMA_SGL_REQ_SRC_Pos) +#define DMA_SGL_REQ_SRC DMA_SGL_REQ_SRC_Msk + +/******************* Bit definition for DMA_SGL_REQ_DST_REG register *********/ +#define DMA_SGL_REQ_DST_WE_Pos (8U) +#define DMA_SGL_REQ_DST_WE_Len (8U) +#define DMA_SGL_REQ_DST_WE_Msk (0xFFU << DMA_SGL_REQ_DST_WE_Pos) +#define DMA_SGL_REQ_DST_WE DMA_SGL_REQ_DST_WE_Msk + +#define DMA_SGL_REQ_DST_Pos (0U) +#define DMA_SGL_REQ_DST_Len (8U) +#define DMA_SGL_REQ_DST_Msk (0xFFU << DMA_SGL_REQ_DST_Pos) +#define DMA_SGL_REQ_DST DMA_SGL_REQ_DST_Msk + +/******************* Bit definition for DMA_LST_SRC_REG register *********/ +#define DMA_LST_SRC_WE_Pos (8U) +#define DMA_LST_SRC_WE_Len (8U) +#define DMA_LST_SRC_WE_Msk (0xFFU << DMA_LST_SRC_WE_Pos) +#define DMA_LST_SRC_WE DMA_LST_SRC_WE_Msk + +#define DMA_LST_SRC_Pos (0U) +#define DMA_LST_SRC_Len (8U) +#define DMA_LST_SRC_Msk (0xFFU << DMA_LST_SRC_Pos) +#define DMA_LST_SRC DMA_LST_SRC_Msk + +/******************* Bit definition for DMA_LST_DST_REG register *********/ +#define DMA_LST_DST_WE_Pos (8U) +#define DMA_LST_DST_WE_Len (8U) +#define DMA_LST_DST_WE_Msk (0xFFU << DMA_LST_DST_WE_Pos) +#define DMA_LST_DST_WE DMA_LST_DST_WE_Msk + +#define DMA_LST_DST_Pos (0U) +#define DMA_LST_DST_Len (8U) +#define DMA_LST_DST_Msk (0xFFU << DMA_LST_DST_Pos) +#define DMA_LST_DST DMA_LST_DST_Msk + +/******************* Bit definition for DMA_CFG_REG register ****************/ +#define DMA_MODULE_CFG_EN_Pos (0U) +#define DMA_MODULE_CFG_EN_Len (1U) +#define DMA_MODULE_CFG_EN_Msk (0x1U << DMA_MODULE_CFG_EN_Pos) +#define DMA_MODULE_CFG_EN DMA_MODULE_CFG_EN_Msk + +/******************* Bit definition for DMA_CH_EN_REG register **************/ +#define DMA_CH_WE_EN_Pos (8U) +#define DMA_CH_WE_EN_Len (8U) +#define DMA_CH_WE_EN_Msk (0xFFU << DMA_CH_WE_EN_Pos) +#define DMA_CH_WE_EN DMA_CH_WE_EN_Msk + +#define DMA_CH_EN_Pos (0U) +#define DMA_CH_EN_Len (8U) +#define DMA_CH_EN_Msk (0xFFU << DMA_CH_EN_Pos) +#define DMA_CH_EN DMA_CH_EN_Msk + + +/* ================================================================================================================= */ +/* ================ DUAL_TIMER ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for DUAL_TIMER_RELOAD register ************/ +#define DUAL_TIMER_RELOAD_RELOAD_Pos (0U) +#define DUAL_TIMER_RELOAD_RELOAD_Len (32U) +#define DUAL_TIMER_RELOAD_RELOAD_Msk (0xFFFFFFFFU) +#define DUAL_TIMER_RELOAD_RELOAD DUAL_TIMER_RELOAD_RELOAD_Msk + +/******************* Bit definition for DUAL_TIMER_VALUE register *************/ +#define DUAL_TIMER_VALUE_VALUE_Pos (0U) +#define DUAL_TIMER_VALUE_VALUE_Len (32U) +#define DUAL_TIMER_VALUE_VALUE_Msk (0xFFFFFFFFU) +#define DUAL_TIMER_VALUE_VALUE DUAL_TIMER_VALUE_VALUE_Msk + +/******************* Bit definition for DUAL_TIMER_CTRL register **************/ +#define DUAL_TIMER_CTRL_EN_Pos (7U) +#define DUAL_TIMER_CTRL_EN_Len (1U) +#define DUAL_TIMER_CTRL_EN_Msk (0x1U << DUAL_TIMER_CTRL_EN_Pos) +#define DUAL_TIMER_CTRL_EN DUAL_TIMER_CTRL_EN_Msk + +#define DUAL_TIMER_CTRL_MODE_Pos (6U) +#define DUAL_TIMER_CTRL_MODE_Len (1U) +#define DUAL_TIMER_CTRL_MODE_Msk (0x1U << DUAL_TIMER_CTRL_MODE_Pos) +#define DUAL_TIMER_CTRL_MODE DUAL_TIMER_CTRL_MODE_Msk + +#define DUAL_TIMER_CTRL_INTEN_Pos (5U) +#define DUAL_TIMER_CTRL_INTEN_Len (1U) +#define DUAL_TIMER_CTRL_INTEN_Msk (0x1U << DUAL_TIMER_CTRL_INTEN_Pos) +#define DUAL_TIMER_CTRL_INTEN DUAL_TIMER_CTRL_INTEN_Msk + +#define DUAL_TIMER_CTRL_PRE_Pos (2U) +#define DUAL_TIMER_CTRL_PRE_Len (2U) +#define DUAL_TIMER_CTRL_PRE_Msk (0x3U << DUAL_TIMER_CTRL_PRE_Pos) +#define DUAL_TIMER_CTRL_PRE DUAL_TIMER_CTRL_PRE_Msk + +#define DUAL_TIMER_CTRL_SIZE_Pos (1U) +#define DUAL_TIMER_CTRL_SIZE_Len (1U) +#define DUAL_TIMER_CTRL_SIZE_Msk (0x1U << DUAL_TIMER_CTRL_SIZE_Pos) +#define DUAL_TIMER_CTRL_SIZE DUAL_TIMER_CTRL_SIZE_Msk + +#define DUAL_TIMER_CTRL_ONESHOT_Pos (0U) +#define DUAL_TIMER_CTRL_ONESHOT_Len (1U) +#define DUAL_TIMER_CTRL_ONESHOT_Msk (0x1U << DUAL_TIMER_CTRL_ONESHOT_Pos) +#define DUAL_TIMER_CTRL_ONESHOT DUAL_TIMER_CTRL_ONESHOT_Msk + +/******************* Bit definition for DUAL_TIMER_INT_CLR register ***********/ +#define DUAL_TIMER_INT_CLR_Pos (0U) +#define DUAL_TIMER_INT_CLR_Len (32U) +#define DUAL_TIMER_INT_CLR_Msk (0xFFFFFFFFU) +#define DUAL_TIMER_INT_CLR DUAL_TIMER_INT_CLR_Msk + +/******************* Bit definition for DUAL_TIMER_RAW_INT_STAT register ******/ +#define DUAL_TIMER_RIS_RTI_Pos (0U) +#define DUAL_TIMER_RIS_RTI_Len (1U) +#define DUAL_TIMER_RIS_RTI_Msk (0x1U << DUAL_TIMER_RIS_RTI_Pos) +#define DUAL_TIMER_RIS_RTI DUAL_TIMER_RIS_RTI_Msk + +/******************* Bit definition for DUAL_TIMER_INT_STAT register **********/ +#define DUAL_TIMER_ISR_TI_Pos (0U) +#define DUAL_TIMER_ISR_TI_Len (1U) +#define DUAL_TIMER_ISR_TI_Msk (0x1U << DUAL_TIMER_ISR_TI_Pos) +#define DUAL_TIMER_ISR_TI DUAL_TIMER_ISR_TI_Msk + +/******************* Bit definition for DUAL_TIMER_BGLOAD register ************/ +#define DUAL_TIMER_BLR_BL_Pos (0U) +#define DUAL_TIMER_BLR_BL_Len (32U) +#define DUAL_TIMER_BLR_BL_Msk (0xFFFFFFFFU) +#define DUAL_TIMER_BLR_BL DUAL_TIMER_BLR_BL_Msk + + +/* ================================================================================================================= */ +/* ================ GPIO ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for GPIO_DATA register ******************/ +#define GPIO_DATA_Pos (0U) +#define GPIO_DATA_Len (16U) +#define GPIO_DATA_Msk (0xFFFFU << GPIO_DATA_Pos) +#define GPIO_DATA GPIO_DATA_Msk /**< Data */ + +/******************* Bit definition for GPIO_DATAOUT register ***************/ +#define GPIO_DATAOUT_Pos (0U) +#define GPIO_DATAOUT_Len (16U) +#define GPIO_DATAOUT_Msk (0xFFFFU << GPIO_DATAOUT_Pos) +#define GPIO_DATAOUT GPIO_DATAOUT_Msk /**< Data Output */ + +/******************* Bit definition for GPIO_OUTENSET register ***************/ +#define GPIO_OUTENSET_Pos (0U) +#define GPIO_OUTENSET_Len (16U) +#define GPIO_OUTENSET_Msk (0xFFFFU << GPIO_OUTENSET_Pos) +#define GPIO_OUTENSET GPIO_OUTENSET_Msk /**< Data Output Enable Set*/ + +/******************* Bit definition for GPIO_OUTENCLR register ***************/ +#define GPIO_OUTENCLR_Pos (0U) +#define GPIO_OUTENCLR_Len (16U) +#define GPIO_OUTENCLR_Msk (0xFFFFU << GPIO_OUTENCLR_Pos) +#define GPIO_OUTENCLR GPIO_OUTENCLR_Msk /**< Data Output Enable Clear */ + +/******************* Bit definition for GPIO_INTENSET register ***************/ +#define GPIO_INTENSET_Pos (0U) +#define GPIO_INTENSET_Len (16U) +#define GPIO_INTENSET_Msk (0xFFFFU << GPIO_INTENSET_Pos) +#define GPIO_INTENSET GPIO_INTENSET_Msk /**< Interrupt Enable Set */ + +/******************* Bit definition for GPIO_INTENCLR register ***************/ +#define GPIO_INTENCLR_Pos (0U) +#define GPIO_INTENCLR_Len (16U) +#define GPIO_INTENCLR_Msk (0xFFFFU << GPIO_INTENCLR_Pos) +#define GPIO_INTENCLR GPIO_INTENCLR_Msk /**< Interrupt Enable clear */ + +/******************* Bit definition for GPIO_INTTYPESET register ***************/ +#define GPIO_INTTYPESET_Pos (0U) +#define GPIO_INTTYPESET_Len (16U) +#define GPIO_INTTYPESET_Msk (0xFFFFU << GPIO_INTTYPESET_Pos) +#define GPIO_INTTYPESET GPIO_INTTYPESET_Msk /**< Interrupt Type Set */ + +/******************* Bit definition for GPIO_INTTYPECLR register ***************/ +#define GPIO_INTTYPECLR_Pos (0U) +#define GPIO_INTTYPECLR_Len (16U) +#define GPIO_INTTYPECLR_Msk (0xFFFFU << GPIO_INTTYPECLR_Pos) +#define GPIO_INTTYPECLR GPIO_INTTYPECLR_Msk /**< Interrupt Type Clear */ + +/******************* Bit definition for GPIO_INTPOLSET register ***************/ +#define GPIO_INTPOLSET_Pos (0U) +#define GPIO_INTPOLSET_Len (16U) +#define GPIO_INTPOLSET_Msk (0xFFFFU << GPIO_INTPOLSET_Pos) +#define GPIO_INTPOLSET GPIO_INTPOLSET_Msk /**< Interrupt Polarity-level Set */ + +/******************* Bit definition for GPIO_INTPOLCLR register ***************/ +#define GPIO_INTPOLCLR_Pos (0U) +#define GPIO_INTPOLCLR_Len (16U) +#define GPIO_INTPOLCLR_Msk (0xFFFFU << GPIO_INTPOLCLR_Pos) +#define GPIO_INTPOLCLR GPIO_INTPOLCLR_Msk /**< Interrupt Polarity-level Clear */ + +/******************* Bit definition for GPIO_INTSTAT register ***************/ +#define GPIO_INTSTAT_Pos (0U) +#define GPIO_INTSTAT_Len (16U) +#define GPIO_INTSTAT_Msk (0xFFFFU << GPIO_INTSTAT_Pos) +#define GPIO_INTSTAT GPIO_INTSTAT_Msk /**< Interrupt Status */ + +/******************* Bit definition for GPIO_MASKLOWBYTE register ***********/ +#define GPIO_MASKLOWBYTE_DATA_Pos (0U) +#define GPIO_MASKLOWBYTE_DATA_Len (8U) +#define GPIO_MASKLOWBYTE_DATA_Msk (0xFFU << GPIO_MASKLOWBYTE_DATA_Pos) +#define GPIO_MASKLOWBYTE_DATA GPIO_MASKLOWBYTE_DATA_Msk /**< Lower eight bits masked access */ + +/******************* Bit definition for GPIO_MASKLOWBYTE register ***********/ +#define GPIO_MASKHIGHBYTE_DATA_Pos (8U) +#define GPIO_MASKHIGHBYTE_DATA_Len (8U) +#define GPIO_MASKHIGHBYTE_DATA_Msk (0xFFU << GPIO_MASKHIGHBYTE_DATA_Pos) +#define GPIO_MASKHIGHBYTE_DATA GPIO_MASKHIGHBYTE_DATA /**< Higher eight bits masked access */ + + +/* ================================================================================================================= */ +/* ================ HMAC ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for HMAC_CTRL register ******************/ +#define HMAC_CTRL_ENABLE_Pos (0U) +#define HMAC_CTRL_ENABLE_Len (1U) +#define HMAC_CTRL_ENABLE_Msk (1U << HMAC_CTRL_ENABLE_Pos) +#define HMAC_CTRL_ENABLE HMAC_CTRL_ENABLE_Msk + +#define HMAC_CTRL_START_DMA_Pos (1U) +#define HMAC_CTRL_START_DMA_Len (1U) +#define HMAC_CTRL_START_DMA_Msk (1U << HMAC_CTRL_START_DMA_Pos) +#define HMAC_CTRL_START_DMA HMAC_CTRL_START_DMA_Msk + +#define HMAC_CTRL_ENABLE_RKEY_Pos (2U) +#define HMAC_CTRL_ENABLE_RKEY_Len (1U) +#define HMAC_CTRL_ENABLE_RKEY_Msk (1U << HMAC_CTRL_ENABLE_RKEY_Pos) +#define HMAC_CTRL_ENABLE_RKEY HMAC_CTRL_ENABLE_RKEY_Msk + +#define HMAC_CTRL_LASTTRANSFER_Pos (3U) +#define HMAC_CTRL_LASTTRANSFER_Len (1U) +#define HMAC_CTRL_LASTTRANSFER_Msk (1U << HMAC_CTRL_LASTTRANSFER_Pos) +#define HMAC_CTRL_LASTTRANSFER HMAC_CTRL_LASTTRANSFER_Msk + +/******************* Bit definition for HMAC_CONFIG register ****************/ +#define HMAC_CONFIG_ENABLE_USERHASH_Pos (0U) +#define HMAC_CONFIG_ENABLE_USERHASH_Len (1U) +#define HMAC_CONFIG_ENABLE_USERHASH_Msk (1U << HMAC_CONFIG_ENABLE_USERHASH_Pos) +#define HMAC_CONFIG_ENABLE_USERHASH HMAC_CONFIG_ENABLE_USERHASH_Msk + +#define HMAC_CONFIG_ENDIAN_Pos (1U) +#define HMAC_CONFIG_ENDIAN_Len (1U) +#define HMAC_CONFIG_ENDIAN_Msk (1U << HMAC_CONFIG_ENDIAN_Pos) +#define HMAC_CONFIG_ENDIAN HMAC_CONFIG_ENDIAN_Msk + +#define HMAC_CONFIG_KEYTYPE_Pos (2U) +#define HMAC_CONFIG_KEYTYPE_Len (2U) +#define HMAC_CONFIG_KEYTYPE_Msk (3U << HMAC_CONFIG_KEYTYPE_Pos) +#define HMAC_CONFIG_KEYTYPE HMAC_CONFIG_KEYTYPE_Msk + +#define HMAC_CONFIG_CALCTYPE_Pos (4U) +#define HMAC_CONFIG_CALCTYPE_Len (1U) +#define HMAC_CONFIG_CALCTYPE_Msk (1U << HMAC_CONFIG_CALCTYPE_Pos) +#define HMAC_CONFIG_CALCTYPE HMAC_CONFIG_CALCTYPE_Msk + +#define HMAC_CONFIG_PRIVATE_Pos (5U) +#define HMAC_CONFIG_PRIVATE_Len (1U) +#define HMAC_CONFIG_PRIVATE_Msk (1U << HMAC_CONFIG_PRIVATE_Pos) +#define HMAC_CONFIG_PRIVATE HMAC_CONFIG_PRIVATE_Msk + +/******************* Bit definition for HMAC_STATUS register ****************/ +#define HMAC_STATUS_DATAREADY_SHA_Pos (0U) +#define HMAC_STATUS_DATAREADY_SHA_Len (1U) +#define HMAC_STATUS_DATAREADY_SHA_Msk (1U << HMAC_STATUS_DATAREADY_SHA_Pos) +#define HMAC_STATUS_DATAREADY_SHA HMAC_STATUS_DATAREADY_SHA_Msk + +#define HMAC_STATUS_MESSAGEDONE_DMA_Pos (1U) +#define HMAC_STATUS_MESSAGEDONE_DMA_Len (1U) +#define HMAC_STATUS_MESSAGEDONE_DMA_Msk (1U << HMAC_STATUS_MESSAGEDONE_DMA_Pos) +#define HMAC_STATUS_MESSAGEDONE_DMA HMAC_STATUS_MESSAGEDONE_DMA_Msk + +#define HMAC_STATUS_TRANSERR_DMA_Pos (2U) +#define HMAC_STATUS_TRANSERR_DMA_Len (1U) +#define HMAC_STATUS_TRANSERR_DMA_Msk (1U << HMAC_STATUS_TRANSERR_DMA_Pos) +#define HMAC_STATUS_TRANSERR_DMA HMAC_STATUS_TRANSERR_DMA_Msk + +#define HMAC_STATUS_KEYVALID_Pos (3U) +#define HMAC_STATUS_KEYVALID_Len (1U) +#define HMAC_STATUS_KEYVALID_Msk (1U << HMAC_STATUS_KEYVALID_Pos) +#define HMAC_STATUS_KEYVALID HMAC_STATUS_KEYVALID_Msk + +#define HMAC_STATUS_DATAREADY_HMAC_Pos (4U) +#define HMAC_STATUS_DATAREADY_HMAC_Len (1U) +#define HMAC_STATUS_DATAREADY_HMAC_Msk (1U << HMAC_STATUS_DATAREADY_HMAC_Pos) +#define HMAC_STATUS_DATAREADY_HMAC HMAC_STATUS_DATAREADY_HMAC_Msk + +#define HMAC_STATUS_TRANSDONE_DMA_Pos (5U) +#define HMAC_STATUS_TRANSDONE_DMA_Len (1U) +#define HMAC_STATUS_TRANSDONE_DMA_Msk (1U << HMAC_STATUS_TRANSDONE_DMA_Pos) +#define HMAC_STATUS_TRANSDONE_DMA HMAC_STATUS_TRANSDONE_DMA_Msk + +/******************* Bit definition for HMAC_TRAN_SIZE register *************/ +#define HMAC_TRANSIZE_Pos (0U) +#define HMAC_TRANSIZE_Len (15U) +#define HMAC_TRANSIZE_Msk (0x7FFFU << HMAC_TRANSIZE_Pos) +#define HMAC_TRANSIZE HMAC_TRANSIZE_Msk + +/******************* Bit definition for HMAC_INTERRUPT register *************/ +#define HMAC_INTERRUPT_DONE_Pos (0U) +#define HMAC_INTERRUPT_DONE_Len (1U) +#define HMAC_INTERRUPT_DONE_Msk (1U << HMAC_INTERRUPT_DONE_Pos) +#define HMAC_INTERRUPT_DONE HMAC_INTERRUPT_DONE_Msk + +#define HMAC_INTERRUPT_ENABLE_Pos (1U) +#define HMAC_INTERRUPT_ENABLE_Len (1U) +#define HMAC_INTERRUPT_ENABLE_Msk (1U << HMAC_INTERRUPT_ENABLE_Pos) +#define HMAC_INTERRUPT_ENABLE HMAC_INTERRUPT_ENABLE_Msk + +/******************* Bit definition for HMAC_RSTART_ADDR register ***********/ +#define HMAC_RSTART_ADDR_Pos (0U) +#define HMAC_RSTART_ADDR_Len (32U) +#define HMAC_RSTART_ADDR_Msk (0xFFFFFFFFU << HMAC_RSTART_ADDR_Pos) +#define HMAC_RSTART_ADDR HMAC_RSTART_ADDR_Msk + +/******************* Bit definition for HMAC_WSTART_ADDR register ***********/ +#define HMAC_WSTART_ADDR_Pos (0U) +#define HMAC_WSTART_ADDR_Len (32U) +#define HMAC_WSTART_ADDR_Msk (0xFFFFFFFFU << HMAC_WSTART_ADDR_Pos) +#define HMAC_WSTART_ADDR HMAC_WSTART_ADDR_Msk + +/******************* Bit definition for HMAC_USER_HASH register *************/ +#define HMAC_USERHASH_Pos (0U) +#define HMAC_USERHASH_Len (32U) +#define HMAC_USERHASH_Msk (0xFFFFFFFFU << HMAC_USERHASH_Pos) +#define HMAC_USERHASH HMAC_USERHASH_Msk + +/******************* Bit definition for HMAC_FIFO_OUT register **************/ +#define HMAC_FIFO_OUT_Pos (0U) +#define HMAC_FIFO_OUT_Len (32U) +#define HMAC_FIFO_OUT_Msk (0xFFFFFFFFU << HMAC_FIFO_OUT_Pos) +#define HMAC_FIFO_OUT HMAC_FIFO_OUT_Msk + +/******************* Bit definition for HMAC_MESSAGE_FIFO register **********/ +#define HMAC_FIFO_MESSAGE_Pos (0U) +#define HMAC_FIFO_MESSAGE_Len (32U) +#define HMAC_FIFO_MESSAGE_Msk (0xFFFFFFFFU << HMAC_FIFO_MESSAGE_Pos) +#define HMAC_FIFO_MESSAGE HMAC_FIFO_MESSAGE_Msk + +/******************* Bit definition for HMAC_KEY register *******************/ +#define HMAC_KEY_Pos (0U) +#define HMAC_KEY_Len (32U) +#define HMAC_KEY_Msk (0xFFFFFFFFU << HMAC_KEY_Pos) +#define HMAC_KEY HMAC_KEY_Msk + +/******************* Bit definition for HMAC_KEY_ADDR register **************/ +#define HMAC_KEY_ADDR_Pos (0U) +#define HMAC_KEY_ADDR_Len (32U) +#define HMAC_KEY_ADDR_Msk (0xFFFFFFFFU << HMAC_KEY_ADDR_Pos) +#define HMAC_KEY_ADDR HMAC_KEY_ADDR_Msk + +/******************* Bit definition for HMAC_KPORT_MASK register ************/ +#define HMAC_KPORT_MASK_Pos (0U) +#define HMAC_KPORT_MASK_Len (32U) +#define HMAC_KPORT_MASK_Msk (0xFFFFFFFFU << HMAC_KPORT_MASK_Pos) +#define HMAC_KPORT_MASK HMAC_KPORT_MASK_Msk + + +/* ================================================================================================================= */ +/* ================ I2C ================ */ +/* ================================================================================================================= */ +#define I2C_TXFIFO_SIZE (8U) +#define I2C_RXFIFO_SIZE (8U) + +/******************* Bit definition for IC_CON register *********************/ +#define I2C_CON_BUS_CLR_FEATURE_CTRL_Pos (11U) +#define I2C_CON_BUS_CLR_FEATURE_CTRL_Len (1U) +#define I2C_CON_BUS_CLR_FEATURE_CTRL_Msk (0x1U << I2C_CON_BUS_CLR_FEATURE_CTRL_Pos) +#define I2C_CON_BUS_CLR_FEATURE_CTRL I2C_CON_BUS_CLR_FEATURE_CTRL_Msk + +#define I2C_CON_STOP_DET_IF_MASTER_ACTIVE_Pos (10U) +#define I2C_CON_STOP_DET_IF_MASTER_ACTIVE_Len (1U) +#define I2C_CON_STOP_DET_IF_MASTER_ACTIVE_Msk (0x1U << I2C_CON_STOP_DET_IF_MASTER_ACTIVE_Pos) +#define I2C_CON_STOP_DET_IF_MASTER_ACTIVE I2C_CON_STOP_DET_IF_MASTER_ACTIVE_Msk + +#define I2C_CON_RX_FIFO_FULL_HLD_CTRL_Pos (9U) +#define I2C_CON_RX_FIFO_FULL_HLD_CTRL_Len (1U) +#define I2C_CON_RX_FIFO_FULL_HLD_CTRL_Msk (0x1U << I2C_CON_RX_FIFO_FULL_HLD_CTRL_Pos) +#define I2C_CON_RX_FIFO_FULL_HLD_CTRL I2C_CON_RX_FIFO_FULL_HLD_CTRL_Msk + +#define I2C_CON_TX_EMPTY_CTRL_Pos (8U) +#define I2C_CON_TX_EMPTY_CTRL_Len (1U) +#define I2C_CON_TX_EMPTY_CTRL_Msk (0x1U << I2C_CON_TX_EMPTY_CTRL_Pos) +#define I2C_CON_TX_EMPTY_CTRL I2C_CON_TX_EMPTY_CTRL_Msk + +#define I2C_CON_STOP_DET_IF_ADDRESSED_Pos (7U) +#define I2C_CON_STOP_DET_IF_ADDRESSED_Len (1U) +#define I2C_CON_STOP_DET_IF_ADDRESSED_Msk (0x1U << I2C_CON_STOP_DET_IF_ADDRESSED_Pos) +#define I2C_CON_STOP_DET_IF_ADDRESSED I2C_CON_STOP_DET_IF_ADDRESSED_Msk + +#define I2C_CON_SLV_DIS_Pos (6U) +#define I2C_CON_SLV_DIS_Len (1U) +#define I2C_CON_SLV_DIS_Msk (0x1U << I2C_CON_SLV_DIS_Pos) +#define I2C_CON_SLV_DIS I2C_CON_SLV_DIS_Msk + +#define I2C_CON_RESTART_EN_Pos (5U) +#define I2C_CON_RESTART_EN_Len (1U) +#define I2C_CON_RESTART_EN_Msk (0x1U << I2C_CON_RESTART_EN_Pos) +#define I2C_CON_RESTART_EN I2C_CON_RESTART_EN_Msk + +#define I2C_CON_10BITADDR_MST_Pos (4U) +#define I2C_CON_10BITADDR_MST_Len (1U) +#define I2C_CON_10BITADDR_MST_Msk (0x1U << I2C_CON_10BITADDR_MST_Pos) +#define I2C_CON_10BITADDR_MST I2C_CON_10BITADDR_MST_Msk + +#define I2C_CON_10BITADDR_SLV_Pos (3U) +#define I2C_CON_10BITADDR_SLV_Len (1U) +#define I2C_CON_10BITADDR_SLV_Msk (0x1U << I2C_CON_10BITADDR_SLV_Pos) +#define I2C_CON_10BITADDR_SLV I2C_CON_10BITADDR_SLV_Msk + +#define I2C_CON_SPEED_Pos (1U) +#define I2C_CON_SPEED_Len (2U) +#define I2C_CON_SPEED_Msk (0x3U << I2C_CON_SPEED_Pos) +#define I2C_CON_SPEED I2C_CON_SPEED_Msk +#define I2C_CON_SPEED_STANDARD (0x1U << I2C_CON_SPEED_Pos) +#define I2C_CON_SPEED_FAST (0x2U << I2C_CON_SPEED_Pos) +#define I2C_CON_SPEED_HIGH (0x3U << I2C_CON_SPEED_Pos) + +#define I2C_CON_MST_MODE_Pos (0U) +#define I2C_CON_MST_MODE_Len (1U) +#define I2C_CON_MST_MODE_Msk (0x1U << I2C_CON_MST_MODE_Pos) +#define I2C_CON_MST_MODE I2C_CON_MST_MODE_Msk + +/******************* Bit definition for IC_TAR register *********************/ +#define I2C_TAR_SPECIAL_Pos (11U) +#define I2C_TAR_SPECIAL_Len (1U) +#define I2C_TAR_SPECIAL_Msk (0x1U << I2C_TAR_SPECIAL_Pos) +#define I2C_TAR_SPECIAL I2C_TAR_SPECIAL_Msk + +#define I2C_TAR_GC_OR_START_Pos (10U) +#define I2C_TAR_GC_OR_START_Len (1U) +#define I2C_TAR_GC_OR_START_Msk (0x0U << I2C_TAR_GC_OR_START_Pos) +#define I2C_TAR_GC_OR_START I2C_TAR_GC_OR_START_Msk + +#define I2C_TAR_ADDR_Pos (0U) +#define I2C_TAR_ADDR_Len (10U) +#define I2C_TAR_ADDR_Msk (0x3FFU << I2C_TAR_ADDR_Pos) +#define I2C_TAR_ADDR I2C_TAR_ADDR_Msk +#define I2C_TAR_ADDR_7BIT (0x07FU << I2C_TAR_ADDR_Pos) +#define I2C_TAR_ADDR_10BIT (0x3FFU << I2C_TAR_ADDR_Pos) + +/******************* Bit definition for IC_SAR register *********************/ +#define I2C_SAR_ADDR_Pos (0U) +#define I2C_SAR_ADDR_Len (10U) +#define I2C_SAR_ADDR_Msk (0x3FFU << I2C_SAR_ADDR_Pos) +#define I2C_SAR_ADDR_7BIT (0x07FU << I2C_SAR_ADDR_Pos) +#define I2C_SAR_ADDR_10BIT (0x3FFU << I2C_SAR_ADDR_Pos) + +/******************* Bit definition for IC_HS_MADDR register ****************/ +#define I2C_HS_MADDR_HS_MAR_Pos (0U) +#define I2C_HS_MADDR_HS_MAR_Len (3U) +#define I2C_HS_MADDR_HS_MAR_Msk (0x7U << I2C_HS_MADDR_HS_MAR_Pos) +#define I2C_HS_MADDR_HS_MAR I2C_HS_MADDR_HS_MAR_Msk + +/******************* Bit definition for IC_DATA_CMD register ****************/ +#define I2C_DATA_CMD_RESTART_Pos (10U) +#define I2C_DATA_CMD_RESTART_Len (1U) +#define I2C_DATA_CMD_RESTART_Msk (0x1U << I2C_DATA_CMD_RESTART_Pos) +#define I2C_DATA_CMD_RESTART I2C_DATA_CMD_RESTART_Msk + +#define I2C_DATA_CMD_STOP_Pos (9U) +#define I2C_DATA_CMD_STOP_Len (1U) +#define I2C_DATA_CMD_STOP_Msk (0x1U << I2C_DATA_CMD_STOP_Pos) +#define I2C_DATA_CMD_STOP I2C_DATA_CMD_STOP_Msk + +#define I2C_DATA_CMD_CMD_Pos (8U) +#define I2C_DATA_CMD_CMD_Len (1U) +#define I2C_DATA_CMD_CMD_Msk (0x1U << I2C_DATA_CMD_CMD_Pos) +#define I2C_DATA_CMD_CMD I2C_DATA_CMD_CMD_Msk + +#define I2C_DATA_CMD_DAT_Pos (0U) +#define I2C_DATA_CMD_DAT_Len (8U) +#define I2C_DATA_CMD_DAT_Msk (0xFFU << I2C_DATA_CMD_DAT_Pos) +#define I2C_DATA_CMD_DAT I2C_DATA_CMD_DAT_Msk + +/******************* Bit definition for IC_SS_SCL_HCNT register *************/ +#define I2C_SS_SCL_HCNT_Pos (0U) +#define I2C_SS_SCL_HCNT_Len (16U) +#define I2C_SS_SCL_HCNT_Msk (0xFFFFU << I2C_SS_SCL_HCNT_Pos) +#define I2C_SS_SCL_HCNT I2C_SS_SCL_HCNT_Msk + +/******************* Bit definition for IC_SS_SCL_LCNT register *************/ +#define I2C_SS_SCL_LCNT_Pos (0U) +#define I2C_SS_SCL_LCNT_Len (16U) +#define I2C_SS_SCL_LCNT_Msk (0xFFFFU << I2C_SS_SCL_LCNT_Pos) +#define I2C_SS_SCL_LCNT I2C_SS_SCL_LCNT_Msk + +/******************* Bit definition for IC_FS_SCL_HCNT register *************/ +#define I2C_FS_SCL_HCNT_Pos (0U) +#define I2C_FS_SCL_HCNT_Len (16U) +#define I2C_FS_SCL_HCNT_Msk (0xFFFFU << I2C_FS_SCL_HCNT_Pos) +#define I2C_FS_SCL_HCNT I2C_FS_SCL_HCNT_Msk + +/******************* Bit definition for IC_FS_SCL_LCNT register *************/ +#define I2C_FS_SCL_LCNT_Pos (0U) +#define I2C_FS_SCL_LCNT_Len (16U) +#define I2C_FS_SCL_LCNT_Msk (0xFFFFU << I2C_FS_SCL_LCNT_Pos) +#define I2C_FS_SCL_LCNT I2C_FS_SCL_LCNT_Msk + +/******************* Bit definition for IC_HS_SCL_HCNT register *************/ +#define I2C_HS_SCL_HCNT_Pos (0U) +#define I2C_HS_SCL_HCNT_Len (16U) +#define I2C_HS_SCL_HCNT_Msk (0xFFFFU << I2C_HS_SCL_HCNT_Pos) +#define I2C_HS_SCL_HCNT I2C_HS_SCL_HCNT_Msk + +/******************* Bit definition for IC_HS_SCL_LCNT register *************/ +#define I2C_HS_SCL_LCNT_Pos (0U) +#define I2C_HS_SCL_LCNT_Len (16U) +#define I2C_HS_SCL_LCNT_Msk (0xFFFFU << I2C_HS_SCL_LCNT_Pos) +#define I2C_HS_SCL_LCNT I2C_HS_SCL_LCNT_Msk + +/** Bit definition for IC_INTR_STAT/IC_INTR_MASK/IC_RAW_INTR_STAT register **/ +#define I2C_INTR_ALL (0x3FFFU) + +#define I2C_INTR_MST_ON_HOLD_Pos (13U) +#define I2C_INTR_MST_ON_HOLD_Len (1U) +#define I2C_INTR_MST_ON_HOLD_Msk (0x1U << I2C_INTR_MST_ON_HOLD_Pos) +#define I2C_INTR_MST_ON_HOLD I2C_INTR_MST_ON_HOLD_Msk + +#define I2C_INTR_RESTART_DET_Pos (12U) +#define I2C_INTR_RESTART_DET_Len (1U) +#define I2C_INTR_RESTART_DET_Msk (0x1U << I2C_INTR_RESTART_DET_Pos) +#define I2C_INTR_RESTART_DET I2C_INTR_RESTART_DET_Msk + +#define I2C_INTR_GEN_CALL_Pos (11U) +#define I2C_INTR_GEN_CALL_Len (1U) +#define I2C_INTR_GEN_CALL_Msk (0x1U << I2C_INTR_GEN_CALL_Pos) +#define I2C_INTR_GEN_CALL I2C_INTR_GEN_CALL_Msk + +#define I2C_INTR_START_DET_Pos (10U) +#define I2C_INTR_START_DET_Len (1U) +#define I2C_INTR_START_DET_Msk (0x1U << I2C_INTR_START_DET_Pos) +#define I2C_INTR_START_DET I2C_INTR_START_DET_Msk + +#define I2C_INTR_STOP_DET_Pos (9U) +#define I2C_INTR_STOP_DET_Len (1U) +#define I2C_INTR_STOP_DET_Msk (0x1U << I2C_INTR_STOP_DET_Pos) +#define I2C_INTR_STOP_DET I2C_INTR_STOP_DET_Msk + +#define I2C_INTR_ACTIVITY_Pos (8U) +#define I2C_INTR_ACTIVITY_Len (1U) +#define I2C_INTR_ACTIVITY_Msk (0x1U << I2C_INTR_ACTIVITY_Pos) +#define I2C_INTR_ACTIVITY I2C_INTR_ACTIVITY_Msk + +#define I2C_INTR_RX_DONE_Pos (7U) +#define I2C_INTR_RX_DONE_Len (1U) +#define I2C_INTR_RX_DONE_Msk (0x1U << I2C_INTR_RX_DONE_Pos) +#define I2C_INTR_RX_DONE I2C_INTR_RX_DONE_Msk + +#define I2C_INTR_TX_ABRT_Pos (6U) +#define I2C_INTR_TX_ABRT_Len (1U) +#define I2C_INTR_TX_ABRT_Msk (0x1U << I2C_INTR_TX_ABRT_Pos) +#define I2C_INTR_TX_ABRT I2C_INTR_TX_ABRT_Msk + +#define I2C_INTR_RD_REQ_Pos (5U) +#define I2C_INTR_RD_REQ_Len (1U) +#define I2C_INTR_RD_REQ_Msk (0x1U << I2C_INTR_RD_REQ_Pos) +#define I2C_INTR_RD_REQ I2C_INTR_RD_REQ_Msk + +#define I2C_INTR_TX_EMPTY_Pos (4U) +#define I2C_INTR_TX_EMPTY_Len (1U) +#define I2C_INTR_TX_EMPTY_Msk (0x1U << I2C_INTR_TX_EMPTY_Pos) +#define I2C_INTR_TX_EMPTY I2C_INTR_TX_EMPTY_Msk + +#define I2C_INTR_TX_OVER_Pos (3U) +#define I2C_INTR_TX_OVER_Len (1U) +#define I2C_INTR_TX_OVER_Msk (0x1U << I2C_INTR_TX_OVER_Pos) +#define I2C_INTR_TX_OVER I2C_INTR_TX_OVER_Msk + +#define I2C_INTR_RX_FULL_Pos (2U) +#define I2C_INTR_RX_FULL_Len (1U) +#define I2C_INTR_RX_FULL_Msk (0x1U << I2C_INTR_RX_FULL_Pos) +#define I2C_INTR_RX_FULL I2C_INTR_RX_FULL_Msk + +#define I2C_INTR_RX_OVER_Pos (1U) +#define I2C_INTR_RX_OVER_Len (1U) +#define I2C_INTR_RX_OVER_Msk (0x1U << I2C_INTR_RX_OVER_Pos) +#define I2C_INTR_RX_OVER I2C_INTR_RX_OVER_Msk + +#define I2C_INTR_RX_UNDER_Pos (0U) +#define I2C_INTR_RX_UNDER_Len (1U) +#define I2C_INTR_RX_UNDER_Msk (0x1U << I2C_INTR_RX_UNDER_Pos) +#define I2C_INTR_RX_UNDER I2C_INTR_RX_UNDER_Msk + +/******************* Bit definition for IC_RX_TL register *******************/ +#define I2C_RX_TL_RXTL_Pos (0U) +#define I2C_RX_TL_RXTL_Len (8U) +#define I2C_RX_TL_RXTL_Msk (0xFFU << I2C_RX_TL_RXTL_Pos) +#define I2C_RX_TL_RXTL I2C_RX_TL_RXTL_Msk + +/******************* Bit definition for IC_TX_TL register *******************/ +#define I2C_TX_TL_TXTL_Pos (0U) +#define I2C_TX_TL_TXTL_Len (8U) +#define I2C_TX_TL_TXTL_Msk (0xFFU << I2C_TX_TL_TXTL_Pos) +#define I2C_TX_TL_TXTL I2C_TX_TL_TXTL_Msk + +/******************* Bit definition for IC_ENABLE register ******************/ +// #define I2C_ENABLE_TX_CMD_BLOCK_Pos (2U) +// #define I2C_ENABLE_TX_CMD_BLOCK_Len (1U) +// #define I2C_ENABLE_TX_CMD_BLOCK_Msk (0x1U << I2C_ENABLE_TX_CMD_BLOCK_Pos) +// #define I2C_ENABLE_TX_CMD_BLOCK I2C_ENABLE_TX_CMD_BLOCK_Msk +#define I2C_ENABLE_ABORT_Pos (1U) +#define I2C_ENABLE_ABORT_Len (1U) +#define I2C_ENABLE_ABORT_Msk (0x1U << I2C_ENABLE_ABORT_Pos) +#define I2C_ENABLE_ABORT I2C_ENABLE_ABORT_Msk + +#define I2C_ENABLE_ENABLE_Pos (0U) +#define I2C_ENABLE_ENABLE_Len (1U) +#define I2C_ENABLE_ENABLE_Msk (0x1U << I2C_ENABLE_ENABLE_Pos) +#define I2C_ENABLE_ENABLE I2C_ENABLE_ENABLE_Msk + +/******************* Bit definition for IC_STATUS register ******************/ +#define I2C_STATUS_SLV_ACTIVITY_Pos (6U) +#define I2C_STATUS_SLV_ACTIVITY_Len (1U) +#define I2C_STATUS_SLV_ACTIVITY_Msk (0x1U << I2C_STATUS_SLV_ACTIVITY_Pos) +#define I2C_STATUS_SLV_ACTIVITY I2C_STATUS_SLV_ACTIVITY_Msk + +#define I2C_STATUS_MST_ACTIVITY_Pos (5U) +#define I2C_STATUS_MST_ACTIVITY_Len (1U) +#define I2C_STATUS_MST_ACTIVITY_Msk (0x1U << I2C_STATUS_MST_ACTIVITY_Pos) +#define I2C_STATUS_MST_ACTIVITY I2C_STATUS_MST_ACTIVITY_Msk + +#define I2C_STATUS_RFF_Pos (4U) +#define I2C_STATUS_RFF_Len (1U) +#define I2C_STATUS_RFF_Msk (0x1U << I2C_STATUS_RFF_Pos) +#define I2C_STATUS_RFF I2C_STATUS_RFF_Msk + +#define I2C_STATUS_RFNE_Pos (3U) +#define I2C_STATUS_RFNE_Len (1U) +#define I2C_STATUS_RFNE_Msk (0x1U << I2C_STATUS_RFNE_Pos) +#define I2C_STATUS_RFNE I2C_STATUS_RFNE_Msk + +#define I2C_STATUS_TFE_Pos (2U) +#define I2C_STATUS_TFE_Len (1U) +#define I2C_STATUS_TFE_Msk (0x1U << I2C_STATUS_TFE_Pos) +#define I2C_STATUS_TFE I2C_STATUS_TFE_Msk + +#define I2C_STATUS_TFNF_Pos (1U) +#define I2C_STATUS_TFNF_Len (1U) +#define I2C_STATUS_TFNF_Msk (0x1U << I2C_STATUS_TFNF_Pos) +#define I2C_STATUS_TFNF I2C_STATUS_TFNF_Msk + +#define I2C_STATUS_ACTIVITY_Pos (0U) +#define I2C_STATUS_ACTIVITY_Len (1U) +#define I2C_STATUS_ACTIVITY_Msk (0x1U << I2C_STATUS_ACTIVITY_Pos) +#define I2C_STATUS_ACTIVITY I2C_STATUS_ACTIVITY_Msk + +/******************* Bit definition for IC_RXFLR register *******************/ +#define I2C_RXFLR_RXFLR_Pos (0U) +#define I2C_RXFLR_RXFLR_Len (8U) +#define I2C_RXFLR_RXFLR_Msk (0xFFU << I2C_RXFLR_RXFLR_Pos) +#define I2C_RXFLR_RXFLR I2C_RXFLR_RXFLR_Msk + +/******************* Bit definition for IC_TXFLR register *******************/ +#define I2C_TXFLR_TXFLR_Pos (0U) +#define I2C_TXFLR_TXFLR_Len (8U) +#define I2C_TXFLR_TXFLR_Msk (0xFFU << I2C_TXFLR_TXFLR_Pos) +#define I2C_TXFLR_TXFLR I2C_TXFLR_TXFLR_Msk + +/******************* Bit definition for IC_SDA_HOLD register *******************/ +#define I2C_SDA_HOLD_RX_HOLD_Pos (16U) +#define I2C_SDA_HOLD_RX_HOLD_Len (16U) +#define I2C_SDA_HOLD_RX_HOLD_Msk (0xFFFFU << I2C_SDA_HOLD_RX_HOLD_Pos) +#define I2C_SDA_HOLD_RX_HOLD I2C_SDA_HOLD_RX_HOLD_Msk + +#define I2C_SDA_HOLD_TX_HOLD_Pos (0U) +#define I2C_SDA_HOLD_TX_HOLD_Len (16U) +#define I2C_SDA_HOLD_TX_HOLD_Msk (0xFFFFU << I2C_SDA_HOLD_TX_HOLD_Pos) +#define I2C_SDA_HOLD_TX_HOLD I2C_SDA_HOLD_TX_HOLD_Msk + +/******************* Bit definition for IC_TX_ABRT_SOURCE register **********/ +#define I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Pos (23U) +#define I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Len (9U) +#define I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Msk (0x1FFU << I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Pos) +#define I2C_TX_ABRT_SRC_TX_FLUSH_CNT I2C_TX_ABRT_SRC_TX_FLUSH_CNT_Msk + +#define I2C_TX_ABRT_SRC_USER_ABRT_Pos (16U) +#define I2C_TX_ABRT_SRC_USER_ABRT_Len (1U) +#define I2C_TX_ABRT_SRC_USER_ABRT_Msk (0x1U << I2C_TX_ABRT_SRC_USER_ABRT_Pos) +#define I2C_TX_ABRT_SRC_USER_ABRT I2C_TX_ABRT_SRC_USER_ABRT_Msk + +#define I2C_TX_ABRT_SRC_SLVRD_INTX_Pos (15U) +#define I2C_TX_ABRT_SRC_SLVRD_INTX_Len (1U) +#define I2C_TX_ABRT_SRC_SLVRD_INTX_Msk (0x1U << I2C_TX_ABRT_SRC_SLVRD_INTX_Pos) +#define I2C_TX_ABRT_SRC_SLVRD_INTX I2C_TX_ABRT_SRC_SLVRD_INTX_Msk + +#define I2C_TX_ABRT_SRC_SLV_ARBLOST_Pos (14U) +#define I2C_TX_ABRT_SRC_SLV_ARBLOST_Len (1U) +#define I2C_TX_ABRT_SRC_SLV_ARBLOST_Msk (0x1U << I2C_TX_ABRT_SRC_SLV_ARBLOST_Pos) +#define I2C_TX_ABRT_SRC_SLV_ARBLOST I2C_TX_ABRT_SRC_SLV_ARBLOST_Msk + +#define I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO_Pos (13U) +#define I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO_Len (1U) +#define I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO_Msk (0x1U << I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO_Pos) +#define I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO I2C_TX_ABRT_SRC_SLVFLUSH_TXFIFO_Msk + +#define I2C_TX_ABRT_SRC_ARB_LOST_Pos (12U) +#define I2C_TX_ABRT_SRC_ARB_LOST_Len (1U) +#define I2C_TX_ABRT_SRC_ARB_LOST_Msk (0x1U << I2C_TX_ABRT_SRC_ARB_LOST_Pos) +#define I2C_TX_ABRT_SRC_ARB_LOST I2C_TX_ABRT_SRC_ARB_LOST_Msk + +#define I2C_TX_ABRT_SRC_MST_DIS_Pos (11U) +#define I2C_TX_ABRT_SRC_MST_DIS_Len (1U) +#define I2C_TX_ABRT_SRC_MST_DIS_Msk (0x1U << I2C_TX_ABRT_SRC_MST_DIS_Pos) +#define I2C_TX_ABRT_SRC_MST_DIS I2C_TX_ABRT_SRC_MST_DIS_Msk + +#define I2C_TX_ABRT_SRC_10B_RD_NORSTRT_Pos (10U) +#define I2C_TX_ABRT_SRC_10B_RD_NORSTRT_Len (1U) +#define I2C_TX_ABRT_SRC_10B_RD_NORSTRT_Msk (0x1U << I2C_TX_ABRT_SRC_10B_RD_NORSTRT_Pos) +#define I2C_TX_ABRT_SRC_10B_RD_NORSTRT I2C_TX_ABRT_SRC_10B_RD_NORSTRT_Msk + +#define I2C_TX_ABRT_SRC_SBYTE_NORSTRT_Pos (9U) +#define I2C_TX_ABRT_SRC_SBYTE_NORSTRT_Len (1U) +#define I2C_TX_ABRT_SRC_SBYTE_NORSTRT_Msk (0x1U << I2C_TX_ABRT_SRC_SBYTE_NORSTRT_Pos) +#define I2C_TX_ABRT_SRC_SBYTE_NORSTRT I2C_TX_ABRT_SRC_SBYTE_NORSTRT_Msk + +#define I2C_TX_ABRT_SRC_HS_NORSTRT_Pos (8U) +#define I2C_TX_ABRT_SRC_HS_NORSTRT_Len (1U) +#define I2C_TX_ABRT_SRC_HS_NORSTRT_Msk (0x1U << I2C_TX_ABRT_SRC_HS_NORSTRT_Pos) +#define I2C_TX_ABRT_SRC_HS_NORSTRT I2C_TX_ABRT_SRC_HS_NORSTRT_Msk + +#define I2C_TX_ABRT_SRC_SBYTE_ACKDET_Pos (7U) +#define I2C_TX_ABRT_SRC_SBYTE_ACKDET_Len (1U) +#define I2C_TX_ABRT_SRC_SBYTE_ACKDET_Msk (0x1U << I2C_TX_ABRT_SRC_SBYTE_ACKDET_Pos) +#define I2C_TX_ABRT_SRC_SBYTE_ACKDET I2C_TX_ABRT_SRC_SBYTE_ACKDET_Msk + +#define I2C_TX_ABRT_SRC_HS_ACKDET_Pos (6U) +#define I2C_TX_ABRT_SRC_HS_ACKDET_Len (1U) +#define I2C_TX_ABRT_SRC_HS_ACKDET_Msk (0x1U << I2C_TX_ABRT_SRC_HS_ACKDET_Pos) +#define I2C_TX_ABRT_SRC_HS_ACKDET I2C_TX_ABRT_SRC_HS_ACKDET_Msk + +#define I2C_TX_ABRT_SRC_GCALL_READ_Pos (5U) +#define I2C_TX_ABRT_SRC_GCALL_READ_Len (1U) +#define I2C_TX_ABRT_SRC_GCALL_READ_Msk (0x1U << I2C_TX_ABRT_SRC_GCALL_READ_Pos) +#define I2C_TX_ABRT_SRC_GCALL_READ I2C_TX_ABRT_SRC_GCALL_READ_Msk + +#define I2C_TX_ABRT_SRC_GCALL_NOACK_Pos (4U) +#define I2C_TX_ABRT_SRC_GCALL_NOACK_Len (1U) +#define I2C_TX_ABRT_SRC_GCALL_NOACK_Msk (0x1U << I2C_TX_ABRT_SRC_GCALL_NOACK_Pos) +#define I2C_TX_ABRT_SRC_GCALL_NOACK I2C_TX_ABRT_SRC_GCALL_NOACK_Msk + +#define I2C_TX_ABRT_SRC_TXDATA_NOACK_Pos (3U) +#define I2C_TX_ABRT_SRC_TXDATA_NOACK_Len (1U) +#define I2C_TX_ABRT_SRC_TXDATA_NOACK_Msk (0x1U << I2C_TX_ABRT_SRC_TXDATA_NOACK_Pos) +#define I2C_TX_ABRT_SRC_TXDATA_NOACK I2C_TX_ABRT_SRC_TXDATA_NOACK_Msk + +#define I2C_TX_ABRT_SRC_10ADDR2_NOACK_Pos (2U) +#define I2C_TX_ABRT_SRC_10ADDR2_NOACK_Len (1U) +#define I2C_TX_ABRT_SRC_10ADDR2_NOACK_Msk (0x1U << I2C_TX_ABRT_SRC_10ADDR2_NOACK_Pos) +#define I2C_TX_ABRT_SRC_10ADDR2_NOACK I2C_TX_ABRT_SRC_10ADDR2_NOACK_Msk + +#define I2C_TX_ABRT_SRC_10ADDR1_NOACK_Pos (1U) +#define I2C_TX_ABRT_SRC_10ADDR1_NOACK_Len (1U) +#define I2C_TX_ABRT_SRC_10ADDR1_NOACK_Msk (0x1U << I2C_TX_ABRT_SRC_10ADDR1_NOACK_Pos) +#define I2C_TX_ABRT_SRC_10ADDR1_NOACK I2C_TX_ABRT_SRC_10ADDR1_NOACK_Msk + +#define I2C_TX_ABRT_SRC_7B_ADDR_NOACK_Pos (0U) +#define I2C_TX_ABRT_SRC_7B_ADDR_NOACK_Len (1U) +#define I2C_TX_ABRT_SRC_7B_ADDR_NOACK_Msk (0x1U << I2C_TX_ABRT_SRC_7B_ADDR_NOACK_Pos) +#define I2C_TX_ABRT_SRC_7B_ADDR_NOACK I2C_TX_ABRT_SRC_7B_ADDR_NOACK_Msk + +/******************* Bit definition for IC_DMA_CR register *******************/ +#define I2C_DMA_CR_TDMAE_Pos (1U) +#define I2C_DMA_CR_TDMAE_Len (1U) +#define I2C_DMA_CR_TDMAE_Msk (0x1U << I2C_DMA_CR_TDMAE_Pos) +#define I2C_DMA_CR_TDMAE I2C_DMA_CR_TDMAE_Msk + +#define I2C_DMA_CR_RDMAE_Pos (0U) +#define I2C_DMA_CR_RDMAE_Len (1U) +#define I2C_DMA_CR_RDMAE_Msk (0x1U << I2C_DMA_CR_RDMAE_Pos) +#define I2C_DMA_CR_RDMAE I2C_DMA_CR_RDMAE_Msk + +/******************* Bit definition for IC_DMA_TDLR register ****************/ +#define I2C_DMA_TDLR_DMATDL_Pos (0U) +#define I2C_DMA_TDLR_DMATDL_Len (8U) +#define I2C_DMA_TDLR_DMATDL_Msk (0xFFU << I2C_DMA_TDLR_DMATDL_Pos) +#define I2C_DMA_TDLR_DMATDL I2C_DMA_TDLR_DMATDL_Msk + +/******************* Bit definition for IC_DMA_RDLR register ****************/ +#define I2C_DMA_RDLR_DMARDL_Pos (0U) +#define I2C_DMA_RDLR_DMARDL_Len (8U) +#define I2C_DMA_RDLR_DMARDL_Msk (0xFFU << I2C_DMA_RDLR_DMARDL_Pos) +#define I2C_DMA_RDLR_DMARDL I2C_DMA_RDLR_DMARDL_Msk + +/******************* Bit definition for IC_SDA_SETUP register ***************/ +#define I2C_SDA_SETUP_SDA_SETUP_Pos (0U) +#define I2C_SDA_SETUP_SDA_SETUP_Len (8U) +#define I2C_SDA_SETUP_SDA_SETUP_Msk (0xFFU << I2C_SDA_SETUP_SDA_SETUP_Pos) +#define I2C_SDA_SETUP_SDA_SETUP I2C_SDA_SETUP_SDA_SETUP_Msk + +/******************* Bit definition for IC_ACK_GENERAL_CALL register ********/ +#define I2C_ACK_GENERAL_CALL_ACK_GC_Pos (0U) +#define I2C_ACK_GENERAL_CALL_ACK_GC_Len (1U) +#define I2C_ACK_GENERAL_CALL_ACK_GC_Msk (0x1U << I2C_ACK_GENERAL_CALL_ACK_GC_Pos) +#define I2C_ACK_GENERAL_CALL_ACK_GC I2C_ACK_GENERAL_CALL_ACK_GC_Msk + +/******************* Bit definition for IC_ENABLE_STATUS register ***********/ +#define I2C_ENABLE_STATUS_SLV_RX_LOST_Pos (2U) +#define I2C_ENABLE_STATUS_SLV_RX_LOST_Len (1U) +#define I2C_ENABLE_STATUS_SLV_RX_LOST_Msk (0x1U << I2C_ENABLE_STATUS_SLV_RX_LOST_Pos) +#define I2C_ENABLE_STATUS_SLV_RX_LOST I2C_ENABLE_STATUS_SLV_RX_LOST_Msk + +#define I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY_Pos (1U) +#define I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY_Len (1U) +#define I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY_Msk (0x1U << I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY_Pos) +#define I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY I2C_ENABLE_STATUS_SLV_DIS_WHL_BUSY_Msk + +#define I2C_ENABLE_STATUS_IC_EN_Pos (0U) +#define I2C_ENABLE_STATUS_IC_EN_Len (1U) +#define I2C_ENABLE_STATUS_IC_EN_Msk (0x1U << I2C_ENABLE_STATUS_IC_EN_Pos) +#define I2C_ENABLE_STATUS_IC_EN I2C_ENABLE_STATUS_IC_EN_Msk + +/******************* Bit definition for IC_FS_SPKLEN register ***************/ +#define I2C_FS_SPKLEN_FS_SPKLEN_Pos (0U) +#define I2C_FS_SPKLEN_FS_SPKLEN_Len (8U) +#define I2C_FS_SPKLEN_FS_SPKLEN_Msk (0xFFU << I2C_FS_SPKLEN_FS_SPKLEN_Pos) +#define I2C_FS_SPKLEN_FS_SPKLEN I2C_FS_SPKLEN_FS_SPKLEN_Msk + +/******************* Bit definition for IC_HS_SPKLEN register ***************/ +#define I2C_HS_SPKLEN_HS_SPKLEN_Pos (0U) +#define I2C_HS_SPKLEN_HS_SPKLEN_Len (8U) +#define I2C_HS_SPKLEN_HS_SPKLEN_Msk (0xFFU << I2C_HS_SPKLEN_HS_SPKLEN_Pos) +#define I2C_HS_SPKLEN_HS_SPKLEN I2C_HS_SPKLEN_HS_SPKLEN_Msk + + +/* ================================================================================================================= */ +/* ================ I2S ================ */ +/* ================================================================================================================= */ +#define I2S_TXFIFO_SIZE (16U) +#define I2S_RXFIFO_SIZE (16U) + +/******************* Bit definition for ENABLE register *********************/ +#define I2S_ENABLE_EN_Pos (0U) +#define I2S_ENABLE_EN_Len (1U) +#define I2S_ENABLE_EN_Msk (0x1U << I2S_ENABLE_EN_Pos) +#define I2S_ENABLE_EN I2S_ENABLE_EN_Msk + +/******************* Bit definition for RBEN register ***********************/ +#define I2S_RBEN_EN_Pos (0U) +#define I2S_RBEN_EN_Len (1U) +#define I2S_RBEN_EN_Msk (0x1U << I2S_RBEN_EN_Pos) +#define I2S_RBEN_EN I2S_RBEN_EN_Msk + +/******************* Bit definition for TBEN register ***********************/ +#define I2S_TBEN_EN_Pos (0U) +#define I2S_TBEN_EN_Len (1U) +#define I2S_TBEN_EN_Msk (0x1U << I2S_TBEN_EN_Pos) +#define I2S_TBEN_EN I2S_TBEN_EN_Msk + +/******************* Bit definition for CLKEN register **********************/ +#define I2S_CLKEN_EN_Pos (0U) +#define I2S_CLKEN_EN_Len (1U) +#define I2S_CLKEN_EN_Msk (0x1U << I2S_CLKEN_EN_Pos) +#define I2S_CLKEN_EN I2S_CLKEN_EN_Msk + +/***************** Bit definition for CLKCONFIG register ********************/ +#define I2S_CLKCONFIG_WSS_Pos (3U) +#define I2S_CLKCONFIG_WSS_Len (2U) +#define I2S_CLKCONFIG_WSS_Msk (0x3U << I2S_CLKCONFIG_WSS_Pos) +#define I2S_CLKCONFIG_WSS I2S_CLKCONFIG_WSS_Msk + +#define I2S_CLKCONFIG_SCLKG_Pos (0U) +#define I2S_CLKCONFIG_SCLKG_Len (3U) +#define I2S_CLKCONFIG_SCLKG_Msk (0x7U << I2S_CLKCONFIG_SCLKG_Pos) +#define I2S_CLKCONFIG_SCLKG I2S_CLKCONFIG_SCLKG_Msk + +/***************** Bit definition for RXFIFO_RST register *******************/ +#define I2S_RXFIFO_RST_Pos (0U) +#define I2S_RXFIFO_RST_Len (1U) +#define I2S_RXFIFO_RST_Msk (0x1U << I2S_RXFIFO_RST_Pos) +#define I2S_RXFIFO_RST I2S_RXFIFO_RST_Msk + +/***************** Bit definition for TXFIFO_RST register *******************/ +#define I2S_TXFIFO_RST_Pos (0U) +#define I2S_TXFIFO_RST_Len (1U) +#define I2S_TXFIFO_RST_Msk (0x1U << I2S_TXFIFO_RST_Pos) +#define I2S_TXFIFO_RST I2S_TXFIFO_RST_Msk + +/******************* Bit definition for DATA_L register *********************/ +#define I2S_DATA_L_Pos (0U) +#define I2S_DATA_L_Len (32U) +#define I2S_DATA_L_Msk (0xFFFFFFFFU) +#define I2S_DATA_L I2S_DATA_L_Msk + +/******************* Bit definition for DATA_R register *********************/ +#define I2S_DATA_R_Pos (0U) +#define I2S_DATA_R_Len (32U) +#define I2S_DATA_R_Msk (0xFFFFFFFFU) +#define I2S_DATA_R I2S_DATA_R_Msk + +/******************** Bit definition for RXEN register **********************/ +#define I2S_RXEN_EN_Pos (0U) +#define I2S_RXEN_EN_Len (1U) +#define I2S_RXEN_EN_Msk (0x1U << I2S_RXEN_EN_Pos) +#define I2S_RXEN_EN I2S_RXEN_EN_Msk + +/******************** Bit definition for TXEN register **********************/ +#define I2S_TXEN_EN_Pos (0U) +#define I2S_TXEN_EN_Len (1U) +#define I2S_TXEN_EN_Msk (0x1U << I2S_TXEN_EN_Pos) +#define I2S_TXEN_EN I2S_TXEN_EN_Msk + +/******************* Bit definition for RXSIZE register *********************/ +#define I2S_RXSIZE_WLEN_Pos (0U) +#define I2S_RXSIZE_WLEN_Len (3U) +#define I2S_RXSIZE_WLEN_Msk (0x7U << I2S_RXSIZE_WLEN_Pos) +#define I2S_RXSIZE_WLEN I2S_RXSIZE_WLEN_Msk + +/******************* Bit definition for TXSIZE register *********************/ +#define I2S_TXSIZE_WLEN_Pos (0U) +#define I2S_TXSIZE_WLEN_Len (3U) +#define I2S_TXSIZE_WLEN_Msk (0x7U << I2S_TXSIZE_WLEN_Pos) +#define I2S_TXSIZE_WLEN I2S_TXSIZE_WLEN_Msk + +/******************* Bit definition for INTSTAT register ********************/ +#define I2S_INTSTAT_TXFO_Pos (5U) +#define I2S_INTSTAT_TXFO_Len (1U) +#define I2S_INTSTAT_TXFO_Msk (0x1U << I2S_INTSTAT_TXFO_Pos) +#define I2S_INTSTAT_TXFO I2S_INTSTAT_TXFO_Msk + +#define I2S_INTSTAT_TXFE_Pos (4U) +#define I2S_INTSTAT_TXFE_Len (1U) +#define I2S_INTSTAT_TXFE_Msk (0x1U << I2S_INTSTAT_TXFE_Pos) +#define I2S_INTSTAT_TXFE I2S_INTSTAT_TXFE_Msk + +#define I2S_INTSTAT_RXFO_Pos (1U) +#define I2S_INTSTAT_RXFO_Len (1U) +#define I2S_INTSTAT_RXFO_Msk (0x1U << I2S_INTSTAT_RXFO_Pos) +#define I2S_INTSTAT_RXFO I2S_INTSTAT_RXFO_Msk + +#define I2S_INTSTAT_RXDA_Pos (0U) +#define I2S_INTSTAT_RXDA_Len (1U) +#define I2S_INTSTAT_RXDA_Msk (0x1U << I2S_INTSTAT_RXDA_Pos) +#define I2S_INTSTAT_RXDA I2S_INTSTAT_RXDA_Msk + +/******************* Bit definition for INTMASK register ********************/ +#define I2S_INTMASK_TXFO_Pos (5U) +#define I2S_INTMASK_TXFO_Len (1U) +#define I2S_INTMASK_TXFO_Msk (0x1U << I2S_INTSTAT_TXFO_Pos) +#define I2S_INTMASK_TXFO I2S_INTSTAT_TXFO_Msk + +#define I2S_INTMASK_TXFE_Pos (4U) +#define I2S_INTMASK_TXFE_Len (1U) +#define I2S_INTMASK_TXFE_Msk (0x1U << I2S_INTSTAT_TXFE_Pos) +#define I2S_INTMASK_TXFE I2S_INTSTAT_TXFE_Msk + +#define I2S_INTMASK_RXFO_Pos (1U) +#define I2S_INTMASK_RXFO_Len (1U) +#define I2S_INTMASK_RXFO_Msk (0x1U << I2S_INTSTAT_RXFO_Pos) +#define I2S_INTMASK_RXFO I2S_INTSTAT_RXFO_Msk + +#define I2S_INTMASK_RXDA_Pos (0U) +#define I2S_INTMASK_RXDA_Len (1U) +#define I2S_INTMASK_RXDA_Msk (0x1U << I2S_INTSTAT_RXDA_Pos) +#define I2S_INTMASK_RXDA I2S_INTSTAT_RXDA_Msk + +/******************** Bit definition for RXOVR register *********************/ +#define I2S_RXOVR_RXCHO_Pos (0U) +#define I2S_RXOVR_RXCHO_Len (1U) +#define I2S_RXOVR_RXCHO_Msk (0x1U << I2S_RXOVR_RXCHO_Pos) +#define I2S_RXOVR_RXCHO I2S_RXOVR_RXCHO_Msk + +/******************** Bit definition for TXOVR register *********************/ +#define I2S_TXOVR_TXCHO_Pos (0U) +#define I2S_TXOVR_TXCHO_Len (1U) +#define I2S_TXOVR_TXCHO_Msk (0x1U << I2S_TXOVR_TXCHO_Pos) +#define I2S_TXOVR_TXCHO I2S_TXOVR_TXCHO_Msk + +/****************** Bit definition for RXFIFO_TL register *******************/ +#define I2S_RXFIFO_TL_Pos (0U) +#define I2S_RXFIFO_TL_Len (4U) +#define I2S_RXFIFO_TL_Msk (0xFU << I2S_RXFIFO_TL_Pos) +#define I2S_RXFIFO_TL I2S_RXFIFO_TL_Msk + +/****************** Bit definition for TXFIFO_TL register *******************/ +#define I2S_TXFIFO_TL_Pos (0U) +#define I2S_TXFIFO_TL_Len (4U) +#define I2S_TXFIFO_TL_Msk (0xFU << I2S_TXFIFO_TL_Pos) +#define I2S_TXFIFO_TL I2S_TXFIFO_TL_Msk + +/**************** Bit definition for RXFIFO_FLUSH register ******************/ +#define I2S_RXFIFO_FLUSH_Pos (0U) +#define I2S_RXFIFO_FLUSH_Len (1U) +#define I2S_RXFIFO_FLUSH_Msk (0x1U << I2S_RXFIFO_FLUSH_Pos) +#define I2S_RXFIFO_FLUSH I2S_RXFIFO_FLUSH_Msk + +/**************** Bit definition for TXFIFO_FLUSH register ******************/ +#define I2S_TXFIFO_FLUSH_Pos (0U) +#define I2S_TXFIFO_FLUSH_Len (1U) +#define I2S_TXFIFO_FLUSH_Msk (0x1U << I2S_TXFIFO_FLUSH_Pos) +#define I2S_TXFIFO_FLUSH I2S_TXFIFO_FLUSH_Msk + +/******************** Bit definition for RXDMA register *********************/ +#define I2S_RXDMA_Pos (0U) +#define I2S_RXDMA_Len (32U) +#define I2S_RXDMA_Msk (0xFFFFFFFFU) +#define I2S_RXDMA I2S_RXDMA_Msk + +/****************** Bit definition for RXDMA_RST register *******************/ +#define I2S_RXDMA_RST_Pos (0U) +#define I2S_RXDMA_RST_Len (1U) +#define I2S_RXDMA_RST_Msk (0x1U << I2S_RXDMA_RST_Pos) +#define I2S_RXDMA_RST I2S_RXDMA_RST_Msk + +/******************** Bit definition for TXDMA register *********************/ +#define I2S_TXDMA_Pos (0U) +#define I2S_TXDMA_Len (32U) +#define I2S_TXDMA_Msk (0xFFFFFFFFU) +#define I2S_TXDMA I2S_TXDMA_Msk + +/****************** Bit definition for TXDMA_RST register *******************/ +#define I2S_TXDMA_RST_Pos (0U) +#define I2S_TXDMA_RST_Len (1U) +#define I2S_TXDMA_RST_Msk (0x1U << I2S_TXDMA_RST_Pos) +#define I2S_TXDMA_RST I2S_TXDMA_RST_Msk + +/****************** Bit definition for I2S_PARAM2 register ******************/ +#define I2S_PARAM2_RXSIZE_3_Pos (10U) +#define I2S_PARAM2_RXSIZE_3_Len (3U) +#define I2S_PARAM2_RXSIZE_3_Msk (0x7U << I2S_PARAM2_RXSIZE_3_Pos) +#define I2S_PARAM2_RXSIZE_3 I2S_PARAM2_RXSIZE_3_Msk + +#define I2S_PARAM2_RXSIZE_2_Pos (7U) +#define I2S_PARAM2_RXSIZE_2_Len (3U) +#define I2S_PARAM2_RXSIZE_2_Msk (0x7U << I2S_PARAM2_RXSIZE_2_Pos) +#define I2S_PARAM2_RXSIZE_2 I2S_PARAM2_RXSIZE_2_Msk + +#define I2S_PARAM2_RXSIZE_1_Pos (3U) +#define I2S_PARAM2_RXSIZE_1_Len (3U) +#define I2S_PARAM2_RXSIZE_1_Msk (0x7U << I2S_PARAM2_RXSIZE_1_Pos) +#define I2S_PARAM2_RXSIZE_1 I2S_PARAM2_RXSIZE_1_Msk + +#define I2S_PARAM2_RXSIZE_0_Pos (0U) +#define I2S_PARAM2_RXSIZE_0_Len (3U) +#define I2S_PARAM2_RXSIZE_0_Msk (0x7U << I2S_PARAM2_RXSIZE_0_Pos) +#define I2S_PARAM2_RXSIZE_0 I2S_PARAM2_RXSIZE_0_Msk + +/****************** Bit definition for I2S_PARAM1 register ******************/ +#define I2S_PARAM1_TXSIZE_3_Pos (25U) +#define I2S_PARAM1_TXSIZE_3_Len (3U) +#define I2S_PARAM1_TXSIZE_3_Msk (0x7U << I2S_PARAM1_TXSIZE_3_Pos) +#define I2S_PARAM1_TXSIZE_3 I2S_PARAM1_TXSIZE_3_Msk + +#define I2S_PARAM1_TXSIZE_2_Pos (22U) +#define I2S_PARAM1_TXSIZE_2_Len (3U) +#define I2S_PARAM1_TXSIZE_2_Msk (0x7U << I2S_PARAM1_TXSIZE_2_Pos) +#define I2S_PARAM1_TXSIZE_2 I2S_PARAM1_TXSIZE_2_Msk + +#define I2S_PARAM1_TXSIZE_1_Pos (19U) +#define I2S_PARAM1_TXSIZE_1_Len (3U) +#define I2S_PARAM1_TXSIZE_1_Msk (0x7U << I2S_PARAM1_TXSIZE_1_Pos) +#define I2S_PARAM1_TXSIZE_1 I2S_PARAM1_TXSIZE_1_Msk + +#define I2S_PARAM1_TXSIZE_0_Pos (16U) +#define I2S_PARAM1_TXSIZE_0_Len (3U) +#define I2S_PARAM1_TXSIZE_0_Msk (0x7U << I2S_PARAM1_TXSIZE_0_Pos) +#define I2S_PARAM1_TXSIZE_0 I2S_PARAM1_TXSIZE_0_Msk + +#define I2S_PARAM1_TXCHN_Pos (9U) +#define I2S_PARAM1_TXCHN_Len (2U) +#define I2S_PARAM1_TXCHN_Msk (0x3U << I2S_PARAM1_TXCHN_Pos) +#define I2S_PARAM1_TXCHN I2S_PARAM1_TXCHN_Msk + +#define I2S_PARAM1_RXCHN_Pos (7U) +#define I2S_PARAM1_RXCHN_Len (2U) +#define I2S_PARAM1_RXCHN_Msk (0x3U << I2S_PARAM1_RXCHN_Pos) +#define I2S_PARAM1_RXCHN I2S_PARAM1_RXCHN_Msk + +#define I2S_PARAM1_RXBLOCK_Pos (6U) +#define I2S_PARAM1_RXBLOCK_Len (1U) +#define I2S_PARAM1_RXBLOCK_Msk (0x1U << I2S_PARAM1_RXBLOCK_Pos) +#define I2S_PARAM1_RXBLOCK I2S_PARAM1_RXBLOCK_Msk + +#define I2S_PARAM1_TXBLOCK_Pos (5U) +#define I2S_PARAM1_TXBLOCK_Len (1U) +#define I2S_PARAM1_TXBLOCK_Msk (0x1U << I2S_PARAM1_TXBLOCK_Pos) +#define I2S_PARAM1_TXBLOCK I2S_PARAM1_TXBLOCK_Msk + +#define I2S_PARAM1_MODE_Pos (4U) +#define I2S_PARAM1_MODE_Len (1U) +#define I2S_PARAM1_MODE_Msk (0x1U << I2S_PARAM1_MODE_Pos) +#define I2S_PARAM1_MODE I2S_PARAM1_MODE_Msk + +#define I2S_PARAM1_FIFO_DEPTH_Pos (2U) +#define I2S_PARAM1_FIFO_DEPTH_Len (2U) +#define I2S_PARAM1_FIFO_DEPTH_Msk (0x3U << I2S_PARAM1_FIFO_DEPTH_Pos) +#define I2S_PARAM1_FIFO_DEPTH I2S_PARAM1_FIFO_DEPTH_Msk + +#define I2S_PARAM1_APB_DATA_WIDTH_Pos (0U) +#define I2S_PARAM1_APB_DATA_WIDTH_Len (2U) +#define I2S_PARAM1_APB_DATA_WIDTH_Msk (0x3U << I2S_PARAM1_APB_DATA_WIDTH_Pos) +#define I2S_PARAM1_APB_DATA_WIDTH I2S_PARAM1_APB_DATA_WIDTH_Msk + +/****************** Bit definition for I2S_VERSION register *****************/ +#define I2S_COMP_VERSION_Pos (0U) +#define I2S_COMP_VERSION_Len (32U) +#define I2S_COMP_VERSION_Msk (0xFFFFFFFFU) +#define I2S_COMP_VERSION I2S_COMP_VERSION_Msk + +/******************* Bit definition for I2S_TYPE register *******************/ +#define I2S_COMP_TYPE_Pos (0U) +#define I2S_COMP_TYPE_Len (32U) +#define I2S_COMP_TYPE_Msk (0xFFFFFFFFU) +#define I2S_COMP_TYPE I2S_COMP_TYPE_Msk + + +/* ================================================================================================================= */ +/* ================ ISO7816 ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for ISO7816_CTRL register *******************/ +#define ISO7816_CTRL_ACTION_POS (0U) +#define ISO7816_CTRL_ACTION_Len (3U) +#define ISO7816_CTRL_ACTION_Msk (0x7UL << ISO7816_CTRL_ACTION_POS) +#define ISO7816_CTRL_ACTION ISO7816_CTRL_ACTION_Msk + +#define ISO7816_CTRL_RX_RETYR_MC_POS (8U) +#define ISO7816_CTRL_RX_RETYR_MC_Len (1U) +#define ISO7816_CTRL_RX_RETYR_MC_Msk (0x1UL << ISO7816_CTRL_RX_RETYR_MC_POS) +#define ISO7816_CTRL_RX_RETYR_MC ISO7816_CTRL_RX_RETYR_MC_Msk + +#define ISO7816_CTRL_TX_RETYR_MC_POS (12U) +#define ISO7816_CTRL_TX_RETYR_MC_Len (1U) +#define ISO7816_CTRL_TX_RETYR_MC_Msk (0x1UL << ISO7816_CTRL_TX_RETYR_MC_POS) +#define ISO7816_CTRL_TX_RETYR_MC ISO7816_CTRL_TX_RETYR_MC_Msk + +#define ISO7816_CTRL_IRQ_DONE_CLR_POS (20U) +#define ISO7816_CTRL_IRQ_DONE_CLR_Len (1U) +#define ISO7816_CTRL_IRQ_DONE_CLR_Msk (0x1UL << ISO7816_CTRL_IRQ_DONE_CLR_POS) +#define ISO7816_CTRL_IRQ_DONE_CLR ISO7816_CTRL_IRQ_DONE_CLR_Msk + +#define ISO7816_CTRL_IRQ_RX_EC_POS (21U) +#define ISO7816_CTRL_IRQ_RX_EC_Len (1U) +#define ISO7816_CTRL_IRQ_RX_EC_Msk (0x1UL << ISO7816_CTRL_IRQ_RX_EC_POS) +#define ISO7816_CTRL_IRQ_RX_EC ISO7816_CTRL_IRQ_RX_EC_Msk + +#define ISO7816_CTRL_IRQ_RETYR_EC_POS (22U) +#define ISO7816_CTRL_IRQ_RETYR_EC_Len (1U) +#define ISO7816_CTRL_IRQ_RETYR_EC_Msk (0x1UL << ISO7816_CTRL_IRQ_RETYR_EC_POS) +#define ISO7816_CTRL_IRQ_RETYR_EC ISO7816_CTRL_IRQ_RETYR_EC_Msk + +#define ISO7816_CTRL_IRQ_DMA_EC_POS (23U) +#define ISO7816_CTRL_IRQ_DMA_EC_Len (1U) +#define ISO7816_CTRL_IRQ_DMA_EC_Msk (0x1UL << ISO7816_CTRL_IRQ_DMA_EC_POS) +#define ISO7816_CTRL_IRQ_DMA_EC ISO7816_CTRL_IRQ_DMA_EC_Msk + +#define ISO7816_CTRL_IRQ_STAT_EC_POS (24U) +#define ISO7816_CTRL_IRQ_STAT_EC_Len (1U) +#define ISO7816_CTRL_IRQ_STAT_EC_Msk (0x1UL << ISO7816_CTRL_IRQ_STAT_EC_POS) +#define ISO7816_CTRL_IRQ_STAT_EC ISO7816_CTRL_IRQ_STAT_EC_Msk + +#define ISO7816_CTRL_IRQ_PRESENCE_CLR_POS (25U) +#define ISO7816_CTRL_IRQ_PRESENCE_CLR_Len (1U) +#define ISO7816_CTRL_IRQ_PRESENCE_CLR_Msk (0x1UL << ISO7816_CTRL_IRQ_PRESENCE_CLR_POS) +#define ISO7816_CTRL_IRQ_PRESENCE_CLR ISO7816_CTRL_IRQ_PRESENCE_CLR_Msk + +#define ISO7816_CTRL_IRQ_TEST_CLR_POS (30U) +#define ISO7816_CTRL_IRQ_TEST_CLR_Len (1U) +#define ISO7816_CTRL_IRQ_TEST_CLR_Msk (0x1UL << ISO7816_CTRL_IRQ_TEST_CLR_POS) +#define ISO7816_CTRL_IRQ_TEST_CLR ISO7816_CTRL_IRQ_TEST_CLR_Msk + +#define ISO7816_CTRL_IRQ_TEST_SET_POS (31U) +#define ISO7816_CTRL_IRQ_TEST_SET_Len (1U) +#define ISO7816_CTRL_IRQ_TEST_SET_Msk (0x1UL << ISO7816_CTRL_IRQ_TEST_SET_POS) +#define ISO7816_CTRL_IRQ_TEST_SET ISO7816_CTRL_IRQ_TEST_SET_Msk + +/******************* Bit definition for ISO7816_STAT register *******************/ +#define ISO7816_INTR_ALL (0x43F00000) + +#define ISO7816_STAT_PWR_STAT_POS (0U) +#define ISO7816_STAT_PWR_STAT_Len (4U) +#define ISO7816_STAT_PWR_STAT_Msk (0xFUL << ISO7816_STAT_PWR_STAT_POS) +#define ISO7816_STAT_PWR_STAT ISO7816_STAT_PWR_STAT_Msk + +#define ISO7816_STAT_IO_STAT_POS (4U) +#define ISO7816_STAT_IO_STAT_Len (3U) +#define ISO7816_STAT_IO_STAT_Msk (0x7UL << ISO7816_STAT_IO_STAT_POS) +#define ISO7816_STAT_IO_STAT ISO7816_STAT_IO_STAT_Msk + +#define ISO7816_STAT_RX_RETRY_MAX_POS (8U) +#define ISO7816_STAT_RX_RETRY_MAX_Len (3U) +#define ISO7816_STAT_RX_RETRY_MAX_Msk (0x7UL << ISO7816_STAT_RX_RETRY_MAX_POS) +#define ISO7816_STAT_RX_RETRY_MAX ISO7816_STAT_RX_RETRY_MAX_Msk + +#define ISO7816_STAT_TX_RETRY_MAX_POS (12U) +#define ISO7816_STAT_TX_RETRY_MAX_Len (3U) +#define ISO7816_STAT_TX_RETRY_MAX_Msk (0x7UL << ISO7816_STAT_TX_RETRY_MAX_POS) +#define ISO7816_STAT_TX_RETRY_MAX ISO7816_STAT_TX_RETRY_MAX_Msk + +#define ISO7816_STAT_BUSY_POS (16U) +#define ISO7816_STAT_BUSY_Len (1U) +#define ISO7816_STAT_BUSY_Msk (0x1UL << ISO7816_STAT_BUSY_POS) +#define ISO7816_STAT_BUSY ISO7816_STAT_BUSY_Msk + +#define ISO7816_STAT_PRESENCE_STAT_POS (17U) +#define ISO7816_STAT_PRESENCE_STAT_Len (1U) +#define ISO7816_STAT_PRESENCE_STAT_Msk (0x1UL << ISO7816_STAT_PRESENCE_STAT_POS) +#define ISO7816_STAT_PRESENCE_STAT ISO7816_STAT_PRESENCE_STAT_Msk + +#define ISO7816_STAT_IRQ_DONE_POS (20U) +#define ISO7816_STAT_IRQ_DONE_Len (1U) +#define ISO7816_STAT_IRQ_DONE_Msk (0x1UL << ISO7816_STAT_IRQ_DONE_POS) +#define ISO7816_STAT_IRQ_DONE ISO7816_STAT_IRQ_DONE_Msk + +#define ISO7816_STAT_IRQ_RX_ERR_POS (21U) +#define ISO7816_STAT_IRQ_RX_ERR_Len (1U) +#define ISO7816_STAT_IRQ_RX_ERR_Msk (0x1UL << ISO7816_STAT_IRQ_RX_ERR_POS) +#define ISO7816_STAT_IRQ_RX_ERR ISO7816_STAT_IRQ_RX_ERR_Msk + +#define ISO7816_STAT_IRQ_RETRY_ERR_POS (22U) +#define ISO7816_STAT_IRQ_RETRY_ERR_Len (1U) +#define ISO7816_STAT_IRQ_RETRY_ERR_Msk (0x1UL << ISO7816_STAT_IRQ_RETRY_ERR_POS) +#define ISO7816_STAT_IRQ_RETRY_ERR ISO7816_STAT_IRQ_RETRY_ERR_Msk + +#define ISO7816_STAT_IRQ_DMA_ERR_POS (23U) +#define ISO7816_STAT_IRQ_DMA_ERR_Len (1U) +#define ISO7816_STAT_IRQ_DMA_ERR_Msk (0x1UL << ISO7816_STAT_IRQ_DMA_ERR_POS) +#define ISO7816_STAT_IRQ_DMA_ERR ISO7816_STAT_IRQ_DMA_ERR_Msk + +#define ISO7816_STAT_IRQ_STAT_ERR_POS (24U) +#define ISO7816_STAT_IRQ_STAT_ERR_Len (1U) +#define ISO7816_STAT_IRQ_STAT_ERR_Msk (0x1UL << ISO7816_STAT_IRQ_STAT_ERR_POS) +#define ISO7816_STAT_IRQ_STAT_ERR ISO7816_STAT_IRQ_STAT_ERR_Msk + +#define ISO7816_STAT_IRQ_PRESENCE_POS (25U) +#define ISO7816_STAT_IRQ_PRESENCE_Len (1U) +#define ISO7816_STAT_IRQ_PRESENCE_Msk (0x1UL << ISO7816_STAT_IRQ_PRESENCE_POS) +#define ISO7816_STAT_IRQ_PRESENCE ISO7816_STAT_IRQ_PRESENCE_Msk + +#define ISO7816_STAT_IRQ_TEST_POS (30U) +#define ISO7816_STAT_IRQ_TEST_Len (1U) +#define ISO7816_STAT_IRQ_TEST_Msk (0x1UL << ISO7816_STAT_IRQ_TEST_POS) +#define ISO7816_STAT_IRQ_TEST ISO7816_STAT_IRQ_TEST_Msk + +/******************* Bit definition for ISO7816_CLK_CFG register *******************/ +#define ISO7816_CLK_CFG_ETU_DIV_POS (0U) +#define ISO7816_CLK_CFG_ETU_DIV_Len (10U) +#define ISO7816_CLK_CFG_ETU_DIV_Msk (0x3FFUL << ISO7816_CLK_CFG_ETU_DIV_POS) +#define ISO7816_CLK_CFG_ETU_DIV ISO7816_CLK_CFG_ETU_DIV_Msk + +#define ISO7816_CLK_CFG_CLK_DIV_POS (16U) +#define ISO7816_CLK_CFG_CLK_DIV_Len (8U) +#define ISO7816_CLK_CFG_CLK_DIV_Msk (0xFFUL << ISO7816_CLK_CFG_CLK_DIV_POS) +#define ISO7816_CLK_CFG_CLK_DIV ISO7816_CLK_CFG_CLK_DIV_Msk + +#define ISO7816_CLK_CFG_CLK_STOP_SEL_POS (31U) +#define ISO7816_CLK_CFG_CLK_STOP_SEL_Len (1U) +#define ISO7816_CLK_CFG_CLK_STOP_SEL_Msk (0x1UL << ISO7816_CLK_CFG_CLK_STOP_SEL_POS) +#define ISO7816_CLK_CFG_CLK_STOP_SEL ISO7816_CLK_CFG_CLK_STOP_SEL_Msk + +/******************* Bit definition for ISO7816_TIMES_CFG register *******************/ +#define ISO7816_TIMES_CFG_GUARD_TIME_POS (0U) +#define ISO7816_TIMES_CFG_GUARD_TIME_Len (10U) +#define ISO7816_TIMES_CFG_GUARD_TIME_Msk (0x3FFUL << ISO7816_TIMES_CFG_GUARD_TIME_POS) +#define ISO7816_TIMES_CFG_GUARD_TIME ISO7816_TIMES_CFG_GUARD_TIME_Msk + +#define ISO7816_TIMES_CFG_WAIT_TIME_POS (12U) +#define ISO7816_TIMES_CFG_WAIT_TIME_Len (18U) +#define ISO7816_TIMES_CFG_WAIT_TIME_Msk (0x3FFFFUL << ISO7816_TIMES_CFG_WAIT_TIME_POS) +#define ISO7816_TIMES_CFG_WAIT_TIME ISO7816_TIMES_CFG_WAIT_TIME_Msk + +/******************* Bit definition for ISO7816_DATA_CFG register *******************/ +#define ISO7816_DATA_CFG_CODING_POS (0U) +#define ISO7816_DATA_CFG_CODING_Len (1U) +#define ISO7816_DATA_CFG_CODING_Msk (0x1UL << ISO7816_DATA_CFG_CODING_POS) +#define ISO7816_DATA_CFG_CODING ISO7816_DATA_CFG_CODING_Msk + +#define ISO7816_DATA_CFG_DETECT_CODING_POS (1U) +#define ISO7816_DATA_CFG_DETECT_CODING_Len (1U) +#define ISO7816_DATA_CFG_DETECT_CODING_Msk (0x1UL << ISO7816_DATA_CFG_DETECT_CODING_POS) +#define ISO7816_DATA_CFG_DETECT_CODING ISO7816_DATA_CFG_DETECT_CODING_Msk + +#define ISO7816_DATA_CFG_RETRY_LIMIT_POS (4U) +#define ISO7816_DATA_CFG_RETRY_LIMIT_Len (3U) +#define ISO7816_DATA_CFG_RETRY_LIMIT_Msk (0x7UL << ISO7816_DATA_CFG_RETRY_LIMIT_POS) +#define ISO7816_DATA_CFG_RETRY_LIMIT ISO7816_DATA_CFG_RETRY_LIMIT_Msk + +/******************* Bit definition for ISO7816_ADDR register *******************/ +#define ISO7816_ADDR_ADDR_FRAC_POS (0U) +#define ISO7816_ADDR_ADDR_FRAC_Len (2U) +#define ISO7816_ADDR_ADDR_FRAC_Msk (0x3UL << ISO7816_ADDR_ADDR_FRAC_POS) +#define ISO7816_ADDR_ADDR_FRAC ISO7816_ADDR_ADDR_FRAC_Msk + +#define ISO7816_ADDR_ADDR_POS (2U) +#define ISO7816_ADDR_ADDR_Len (18U) +#define ISO7816_ADDR_ADDR_Msk (0x3FFFFUL << ISO7816_ADDR_ADDR_POS) +#define ISO7816_ADDR_ADDR ISO7816_ADDR_ADDR_Msk + +/******************* Bit definition for ISO7816_START_ADDR register *******************/ +#define ISO7816_START_ADDR_START_ADDR_POS (2U) +#define ISO7816_START_ADDR_START_ADDR_Len (18U) +#define ISO7816_START_ADDR_START_ADDR_Msk (0x3FFFFUL << ISO7816_START_ADDR_START_ADDR_POS) +#define ISO7816_START_ADDR_START_ADDR ISO7816_START_ADDR_START_ADDR_Msk + +#define ISO7816_START_ADDR_BASE_ADDR_POS (20U) +#define ISO7816_START_ADDR_BASE_ADDR_Len (12U) +#define ISO7816_START_ADDR_BASE_ADDR_Msk (0xFFFUL << ISO7816_START_ADDR_BASE_ADDR_POS) +#define ISO7816_START_ADDR_BASE_ADDR ISO7816_START_ADDR_BASE_ADDR_Msk + +/******************* Bit definition for ISO7816_RX_END_ADDR register *******************/ +#define ISO7816_RX_END_ADDR_RX_END_AF_POS (0U) +#define ISO7816_RX_END_ADDR_RX_END_AF_Len (2U) +#define ISO7816_RX_END_ADDR_RX_END_AF_Msk (0x3UL << ISO7816_RX_END_ADDR_RX_END_AF_POS) +#define ISO7816_RX_END_ADDR_RX_END_AF ISO7816_RX_END_ADDR_RX_END_AF_Msk + +#define ISO7816_RX_END_ADDR_RX_END_ADDR_POS (2U) +#define ISO7816_RX_END_ADDR_RX_END_ADDR_Len (18U) +#define ISO7816_RX_END_ADDR_RX_END_ADDR_Msk (0x3FFFFUL << ISO7816_RX_END_ADDR_RX_END_ADDR_POS) +#define ISO7816_RX_END_ADDR_RX_END_ADDR ISO7816_RX_END_ADDR_RX_END_ADDR_Msk + +/******************* Bit definition for ISO7816_TX_END_ADDR register *******************/ +#define ISO7816_TX_END_ADDR_TX_END_AF_POS (0U) +#define ISO7816_TX_END_ADDR_TX_END_AF_Len (2U) +#define ISO7816_TX_END_ADDR_TX_END_AF_Msk (0x3UL << ISO7816_TX_END_ADDR_TX_END_AF_POS) +#define ISO7816_TX_END_ADDR_TX_END_AF ISO7816_TX_END_ADDR_TX_END_AF_Msk + +#define ISO7816_TX_END_ADDR_TX_END_ADDR_POS (2U) +#define ISO7816_TX_END_ADDR_TX_END_ADDR_Len (18U) +#define ISO7816_TX_END_ADDR_TX_END_ADDR_Msk (0x3FFFFUL << ISO7816_TX_END_ADDR_TX_END_ADDR_POS) +#define ISO7816_TX_END_ADDR_TX_END_ADDR ISO7816_TX_END_ADDR_TX_END_ADDR_Msk + +/* ================================================================================================================= */ +/* ================ MCU_SUB ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for MCU_SUB_REG_SENSE_ADC_FIFO register ****************/ +#define MCU_SUB_SNSADC_FF_DATA_Pos (0U) +#define MCU_SUB_SNSADC_FF_DATA_Len (32U) +#define MCU_SUB_SNSADC_FF_DATA_Msk (0xFFFFFFFFU) +#define MCU_SUB_SNSADC_FF_DATA MCU_SUB_SNSADC_FF_DATA_Msk + +/******************* Bit definition for MCU_SUB_REG_SENSE_FF_THRESH register ****/ +#define MCU_SUB_SNSADC_FF_THRESH_Pos (0U) +#define MCU_SUB_SNSADC_FF_THRESH_Len (6U) +#define MCU_SUB_SNSADC_FF_THRESH_Msk (0x3FU << MCU_SUB_SNSADC_FF_THRESH_Pos) +#define MCU_SUB_SNSADC_FF_THRESH MCU_SUB_SNSADC_FF_THRESH_Msk + +/******************* Bit definition for MCU_SUB_REG_SENSE_ADC_STAT register *****/ +#define MCU_SUB_SNSADC_STAT_VAL_Pos (8U) +#define MCU_SUB_SNSADC_STAT_VAL_Len (1U) +#define MCU_SUB_SNSADC_STAT_VAL_Msk (0x1U << MCU_SUB_SNSADC_STAT_VAL_Pos) +#define MCU_SUB_SNSADC_STAT_VAL MCU_SUB_SNSADC_STAT_VAL_Msk + +#define MCU_SUB_SNSADC_STAT_FF_COUNT_Pos (0U) +#define MCU_SUB_SNSADC_STAT_FF_COUNT_Len (7U) +#define MCU_SUB_SNSADC_STAT_FF_COUNT_Msk (0x7FU << MCU_SUB_SNSADC_STAT_FF_COUNT_Pos) +#define MCU_SUB_SNSADC_STAT_FF_COUNT MCU_SUB_SNSADC_STAT_FF_COUNT_Msk + + +/******************* Bit definition for MCU_SUB_REG_COMM_TMR_DEEPSLPSTAT register ***********/ +#define MCU_SUB_COMM_TMR_DEEPSLPSTAT_DEEPSLDUR_Pos (0U) +#define MCU_SUB_COMM_TMR_DEEPSLPSTAT_DEEPSLDUR_Len (32U) +#define MCU_SUB_COMM_TMR_DEEPSLPSTAT_DEEPSLDUR_Msk (0xFFFFFFFFU) +#define MCU_SUB_COMM_TMR_DEEPSLPSTAT_DEEPSLDUR MCU_SUB_COMM_TMR_DEEPSLPSTAT_DEEPSLDUR_Msk + +/*************** Bit definition for MCU_SUB_REG_DPAD_RE_N_BUS register ********/ +#define MCU_SUB_DPAD_RE_N_BUS_Pos (0U) +#define MCU_SUB_DPAD_RE_N_BUS_Len (32U) +#define MCU_SUB_DPAD_RE_N_BUS_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_RE_N_BUS MCU_SUB_DPAD_RE_N_BUS_Msk + +/************* Bit definition for MCU_SUB_REG_DPAD_RTYP_BUS register **********/ +#define MCU_SUB_DPAD_RTYP_BUS_Pos (0U) +#define MCU_SUB_DPAD_RTYP_BUS_Len (32U) +#define MCU_SUB_DPAD_RTYP_BUS_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_RTYP_BUS MCU_SUB_DPAD_RTYP_BUS_Msk + +/********** Bit definition for MCU_SUB_REG_DPAD_IE_N_BUS register *************/ +#define MCU_SUB_DPAD_IE_N_BUS_Pos (0U) +#define MCU_SUB_DPAD_IE_N_BUS_Len (32U) +#define MCU_SUB_DPAD_IE_N_BUS_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_IE_N_BUS MCU_SUB_DPAD_IE_N_BUS_Msk + +/********** Bit definition for MCU_SUB_REG_MSIO_REG register ******************/ +#define MCU_SUB_MSIO_REG0_PFAST_CS_CTRL_Pos (8U) +#define MCU_SUB_MSIO_REG0_PFAST_CS_CTRL_Len (4U) +#define MCU_SUB_MSIO_REG0_PFAST_CS_CTRL_Msk (0xFU << MCU_SUB_MSIO_REG0_PFAST_CS_CTRL_Pos) +#define MCU_SUB_MSIO_REG0_PFAST_CS_CTRL MCU_SUB_MSIO_REG0_PFAST_CS_CTRL_Msk + +#define MCU_SUB_MSIO_REG0_MSIO_C_Pos (0U) +#define MCU_SUB_MSIO_REG0_MSIO_C_Len (5U) +#define MCU_SUB_MSIO_REG0_MSIO_C_Msk (0x1FU << MCU_SUB_MSIO_REG0_MSIO_C_Pos) +#define MCU_SUB_MSIO_REG0_MSIO_C MCU_SUB_MSIO_REG0_MSIO_C_Msk + +/********** Bit definition for MCU_SUB_REG_BLE_FERP_CTL register ****************/ +#define MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL_Pos (4U) +#define MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL_Len (3U) +#define MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL_Msk (0x7U << MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL_Pos) +#define MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL MUC_SUB_BLE_FERP_CTL_TESTBUS_SEL_Msk + +#define MCU_SUB_BLE_FERP_CTL_FERP_EN_Pos (0U) +#define MCU_SUB_BLE_FERP_CTL_FERP_EN_Len (1U) +#define MCU_SUB_BLE_FERP_CTL_FERP_EN_Msk (0x1U << MCU_SUB_BLE_FERP_CTL_FERP_EN_Pos) +#define MCU_SUB_BLE_FERP_CTL_FERP_EN MCU_SUB_BLE_FERP_CTL_FERP_EN_Msk + +/********** Bit definition for MCU_SUB_REG_DMA_ACC_SEL register ****************/ +#define MCU_SUB_DMA_ACC_SEL_I2C1_I2SS_Pos (1U) +#define MCU_SUB_DMA_ACC_SEL_I2C1_I2SS_Len (1U) +#define MCU_SUB_DMA_ACC_SEL_I2C1_I2SS_Msk (0x1U << MCU_SUB_DMA_ACC_SEL_I2C1_I2SS_Pos) +#define MCU_SUB_DMA_ACC_SEL_I2C1_I2SS MCU_SUB_DMA_ACC_SEL_I2C1_I2SS_Msk + +#define MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM_Pos (0U) +#define MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM_Len (1U) +#define MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM_Msk (0x1U << MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM_Pos) +#define MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM MCU_SUB_DMA_ACC_SEL_QSPI1_I2SM_Msk + +/********** Bit definition for MCU_SUB_REG_SECURITY_RESET register ****************/ +#define MCU_SUB_SECURITY_RESET_PRESENT_Pos (6U) +#define MCU_SUB_SECURITY_RESET_PRESENT_Len (1U) +#define MCU_SUB_SECURITY_RESET_PRESENT_Msk (0x1U << MCU_SUB_SECURITY_RESET_PRESENT_Pos) +#define MCU_SUB_SECURITY_RESET_PRESENT MCU_SUB_SECURITY_RESET_PRESENT_Msk + +#define MCU_SUB_SECURITY_RESET_TRNG_Pos (5U) +#define MCU_SUB_SECURITY_RESET_TRNG_Len (1U) +#define MCU_SUB_SECURITY_RESET_TRNG_Msk (0x1U << MCU_SUB_SECURITY_RESET_TRNG_Pos) +#define MCU_SUB_SECURITY_RESET_TRNG MCU_SUB_SECURITY_RESET_TRNG_Msk + +#define MCU_SUB_SECURITY_RESET_RAMKEY_Pos (4U) +#define MCU_SUB_SECURITY_RESET_RAMKEY_Len (1U) +#define MCU_SUB_SECURITY_RESET_RAMKEY_Msk (0x1U << MCU_SUB_SECURITY_RESET_RAMKEY_Pos) +#define MCU_SUB_SECURITY_RESET_RAMKEY MCU_SUB_SECURITY_RESET_RAMKEY_Msk + +#define MCU_SUB_SECURITY_RESET_EFUSE_Pos (3U) +#define MCU_SUB_SECURITY_RESET_EFUSE_Len (1U) +#define MCU_SUB_SECURITY_RESET_EFUSE_Msk (0x1U << MCU_SUB_SECURITY_RESET_EFUSE_Pos) +#define MCU_SUB_SECURITY_RESET_EFUSE MCU_SUB_SECURITY_RESET_EFUSE_Msk + +#define MCU_SUB_SECURITY_RESET_PKC_Pos (2U) +#define MCU_SUB_SECURITY_RESET_PKC_Len (1U) +#define MCU_SUB_SECURITY_RESET_PKC_Msk (0x1U << MCU_SUB_SECURITY_RESET_PKC_Pos) +#define MCU_SUB_SECURITY_RESET_PKC MCU_SUB_SECURITY_RESET_PKC_Msk + +#define MCU_SUB_SECURITY_RESET_HMAC_Pos (1U) +#define MCU_SUB_SECURITY_RESET_HMAC_Len (1U) +#define MCU_SUB_SECURITY_RESET_HMAC_Msk (0x1U << MCU_SUB_SECURITY_RESET_HMAC_Pos) +#define MCU_SUB_SECURITY_RESET_HMAC MCU_SUB_SECURITY_RESET_HMAC_Msk + +#define MCU_SUB_SECURITY_RESET_AES_Pos (0U) +#define MCU_SUB_SECURITY_RESET_AES_Len (1U) +#define MCU_SUB_SECURITY_RESET_AES_Msk (0x1U << MCU_SUB_SECURITY_RESET_AES_Pos) +#define MCU_SUB_SECURITY_RESET_AES MCU_SUB_SECURITY_RESET_AES_Msk + +/********** Bit definition for MCU_SUB_REG_PMU_ID_REG register *****************/ +#define MCU_SUB_PMU_ID_Pos (0U) +#define MCU_SUB_PMU_ID_Len (8U) +#define MCU_SUB_PMU_ID_Msk (0xFFU << MCU_SUB_PMU_ID_Pos) +#define MCU_SUB_PMU_ID MCU_SUB_PMU_ID_Msk + +/********** Bit definition for MCU_SUB_REG_PWR_AVG_CTL_REG register ************/ +#define MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT_Pos (24U) +#define MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT_Len (8U) +#define MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT_Msk (0xFFU << MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT_Pos) +#define MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT MCU_SUB_PWR_AVG_CTL0_TPA_ADC_OUT_Msk + +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR_Pos (18U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR_Len (1U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR_Msk (0x1U << MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR_Pos) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR MCU_SUB_PWR_AVG_CTL0_AVG_PWR_ERR_Msk + +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY_Pos (16U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY_Len (1U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY_Msk (0x1U << MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY_Pos) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY MCU_SUB_PWR_AVG_CTL0_AVG_PWR_RDY_Msk + +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_Pos (8U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_Len (8U) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR_Msk (0xFFU << MCU_SUB_PWR_AVG_CTL0_AVG_PWR_Pos) +#define MCU_SUB_PWR_AVG_CTL0_AVG_PWR MCU_SUB_PWR_AVG_CTL0_AVG_PWR_Msk + +#define MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR_Pos (4U) +#define MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR_Len (4U) +#define MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR_Msk (0xFU << MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR_Pos) +#define MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR MCU_SUB_PWR_AVG_CTL0_SAMPL_PWR_Msk + +#define MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN_Pos (3U) +#define MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN_Len (1U) +#define MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN_Msk (0x1 << MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN_Pos) +#define MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN MCU_SUB_PWR_AVG_CTL0_BLE_F_TX_EN_Msk + +#define MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN_Pos (2U) +#define MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN_Len (1U) +#define MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN_Msk (0x1 << MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN_Pos) +#define MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN MCU_SUB_PWR_AVG_CTL0_ONESHOT_EN_Msk + +#define MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN_Pos (0U) +#define MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN_Len (1U) +#define MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN_Msk (0x1 << MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN_Pos) +#define MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN MCU_SUB_PWR_AVG_CTL0_PWR_AVG_EN_Msk + +/********** Bit definition for MCU_SUB_REG_CLK_CAL_CTL_REG0 register ************/ +#define MCU_SUB_CLK_CAL_CTL0_EN_Pos (0U) +#define MCU_SUB_CLK_CAL_CTL0_EN_Len (1U) +#define MCU_SUB_CLK_CAL_CTL0_EN_Msk (0x1U << MCU_SUB_CLK_CAL_CTL0_EN_Pos) +#define MCU_SUB_CLK_CAL_CTL0_EN MCU_SUB_CLK_CAL_CTL0_EN_Msk + +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN_Pos (1U) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN_Len (1U) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN_Msk (0x1U << MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN_Pos) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_EN_Msk + +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL_Pos (4U) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL_Len (12U) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL_Msk (0xFFFU << MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL_Pos) +#define MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL MCU_SUB_CLK_CAL_CTL0_CNT_LOAD_VAL_Msk + +#define MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY_Pos (16U) +#define MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY_Len (1U) +#define MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY_Msk (0x1U << MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY_Pos) +#define MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY MCU_SUB_CLK_CAL_CTL0_STS_CNT_RDY_Msk + +/********** Bit definition for MCU_SUB_REG_CLK_CAL_CTL_REG1 register ************/ +#define MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL_Pos (0U) +#define MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL_Len (24U) +#define MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL_Msk (0xFFFFFFU << MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL_Pos) +#define MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL MCU_SUB_CLK_CAL_CTL1_STS_CNT_VAL_Msk + +/********** Bit definition for MCU_SUB_REG_DPAD_MUX_CTL_00_07 register **********/ +#define MCU_SUB_DPAD_MUX_CTL_00_07_Pos (0U) +#define MCU_SUB_DPAD_MUX_CTL_00_07_Len (32U) +#define MCU_SUB_DPAD_MUX_CTL_00_07_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_MUX_CTL_00_07 MCU_SUB_DPAD_MUX_CTL_00_07_Msk + +#define MCU_SUB_DPAD_MUX_CTL_SEL_Msk (0xFU) +#define MCU_SUB_DPAD_MUX_CTL_SEL_00 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 0) +#define MCU_SUB_DPAD_MUX_CTL_SEL_01 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_DPAD_MUX_CTL_SEL_02 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_DPAD_MUX_CTL_SEL_03 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_DPAD_MUX_CTL_SEL_04 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 16) +#define MCU_SUB_DPAD_MUX_CTL_SEL_05 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 20) +#define MCU_SUB_DPAD_MUX_CTL_SEL_06 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 24) +#define MCU_SUB_DPAD_MUX_CTL_SEL_07 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 28) + +/********** Bit definition for MCU_SUB_REG_DPAD_MUX_CTL_08_15 register **********/ +#define MCU_SUB_DPAD_MUX_CTL_08_15_Pos (0U) +#define MCU_SUB_DPAD_MUX_CTL_08_15_Len (32U) +#define MCU_SUB_DPAD_MUX_CTL_08_15_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_MUX_CTL_08_15 MCU_SUB_DPAD_MUX_CTL_08_15_Msk + +#define MCU_SUB_DPAD_MUX_CTL_SEL_08 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 0) +#define MCU_SUB_DPAD_MUX_CTL_SEL_09 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_DPAD_MUX_CTL_SEL_10 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_DPAD_MUX_CTL_SEL_11 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_DPAD_MUX_CTL_SEL_12 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 16) +#define MCU_SUB_DPAD_MUX_CTL_SEL_13 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 20) +#define MCU_SUB_DPAD_MUX_CTL_SEL_14 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 24) +#define MCU_SUB_DPAD_MUX_CTL_SEL_15 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 28) + +/********** Bit definition for MCU_SUB_REG_DPAD_MUX_CTL_16_23 register **********/ +#define MCU_SUB_DPAD_MUX_CTL_16_23_Pos (0U) +#define MCU_SUB_DPAD_MUX_CTL_16_23_Len (32U) +#define MCU_SUB_DPAD_MUX_CTL_16_23_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_MUX_CTL_16_23 MCU_SUB_DPAD_MUX_CTL_16_23_Msk + +#define MCU_SUB_DPAD_MUX_CTL_SEL_16 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 0) +#define MCU_SUB_DPAD_MUX_CTL_SEL_17 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_DPAD_MUX_CTL_SEL_18 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_DPAD_MUX_CTL_SEL_19 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_DPAD_MUX_CTL_SEL_20 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 16) +#define MCU_SUB_DPAD_MUX_CTL_SEL_21 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 20) +#define MCU_SUB_DPAD_MUX_CTL_SEL_22 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 24) +#define MCU_SUB_DPAD_MUX_CTL_SEL_23 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 28) + +/********** Bit definition for MCU_SUB_REG_DPAD_MUX_CTL_24_31 register ***********/ +#define MCU_SUB_DPAD_MUX_CTL_24_31_Pos (0U) +#define MCU_SUB_DPAD_MUX_CTL_24_31_Len (32U) +#define MCU_SUB_DPAD_MUX_CTL_24_31_Msk (0xFFFFFFFFU) +#define MCU_SUB_DPAD_MUX_CTL_24_31 MCU_SUB_DPAD_MUX_CTL_24_31_Msk + +#define MCU_SUB_DPAD_MUX_CTL_SEL_24 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 0) +#define MCU_SUB_DPAD_MUX_CTL_SEL_25 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_DPAD_MUX_CTL_SEL_26 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_DPAD_MUX_CTL_SEL_27 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_DPAD_MUX_CTL_SEL_28 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 16) +#define MCU_SUB_DPAD_MUX_CTL_SEL_29 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 20) +#define MCU_SUB_DPAD_MUX_CTL_SEL_30 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 24) +#define MCU_SUB_DPAD_MUX_CTL_SEL_31 (MCU_SUB_DPAD_MUX_CTL_SEL_Msk << 28) + +/********** Bit definition for MCU_SUB_REG_EFUSE_PWR_DELTA0 register ***********/ +#define MCU_SUB_EFUSE_PWR_DELTA0_Pos (0U) +#define MCU_SUB_EFUSE_PWR_DELTA0_Len (16U) +#define MCU_SUB_EFUSE_PWR_DELTA0_Msk (0xFFFFU << MCU_SUB_EFUSE_PWR_DELTA0_Pos) +#define MCU_SUB_EFUSE_PWR_DELTA0 MCU_SUB_EFUSE_PWR_DELTA0_Msk + +#define MCU_SUB_EFUSE_PWR_DELTA1_Pos (16U) +#define MCU_SUB_EFUSE_PWR_DELTA1_Len (16U) +#define MCU_SUB_EFUSE_PWR_DELTA1_Msk (0xFFFFU << MCU_SUB_EFUSE_PWR_DELTA1_Pos) +#define MCU_SUB_EFUSE_PWR_DELTA1 MCU_SUB_EFUSE_PWR_DELTA1_Msk + +/********** Bit definition for MCU_SUB_REG_EFUSE_PWR_DELTA0 register ***********/ +#define MCU_SUB_EFUSE_PWR_DELTA2_Pos (0U) +#define MCU_SUB_EFUSE_PWR_DELTA2_Len (16U) +#define MCU_SUB_EFUSE_PWR_DELTA2_Msk (0xFFFFU << MCU_SUB_EFUSE_PWR_DELTA2_Pos) +#define MCU_SUB_EFUSE_PWR_DELTA2 MCU_SUB_EFUSE_PWR_DELTA2_Msk + +/********** Bit definition for MCU_SUB_REG_EFUSE_PWR_CTRL0 register ***********/ +#define MCU_SUB_EFUSE_PWR_CTL0_EN_Pos (0U) +#define MCU_SUB_EFUSE_PWR_CTL0_EN_Len (1U) +#define MCU_SUB_EFUSE_PWR_CTL0_EN_Msk (0x1U << MCU_SUB_EFUSE_PWR_CTL0_EN_Pos) +#define MCU_SUB_EFUSE_PWR_CTL0_EN MCU_SUB_EFUSE_PWR_CTL0_EN_Msk + +#define MCU_SUB_EFUSE_PWR_CTL0_BGN_Pos (2U) +#define MCU_SUB_EFUSE_PWR_CTL0_BGN_Len (1U) +#define MCU_SUB_EFUSE_PWR_CTL0_BGN_Msk (0x1U << MCU_SUB_EFUSE_PWR_CTL0_BGN_Pos) +#define MCU_SUB_EFUSE_PWR_CTL0_BGN MCU_SUB_EFUSE_PWR_CTL0_BGN_Msk + +#define MCU_SUB_EFUSE_PWR_CTL0_STP_Pos (4U) +#define MCU_SUB_EFUSE_PWR_CTL0_STP_Len (1U) +#define MCU_SUB_EFUSE_PWR_CTL0_STP_Msk (0x1U << MCU_SUB_EFUSE_PWR_CTL0_STP_Pos) +#define MCU_SUB_EFUSE_PWR_CTL0_STP MCU_SUB_EFUSE_PWR_CTL0_STP_Msk + +/********** Bit definition for MCU_SUB_REG_EFUSE_PWR_CTRL1 register ***********/ +#define MCU_SUB_EFUSE_PWR_CTL0_EN_DONE_Pos (0U) +#define MCU_SUB_EFUSE_PWR_CTL0_EN_DONE_Len (1U) +#define MCU_SUB_EFUSE_PWR_CTL0_EN_DONE_Msk (0x1U << MCU_SUB_EFUSE_PWR_CTL0_EN_DONE_Pos) +#define MCU_SUB_EFUSE_PWR_CTL0_EN_DONE MCU_SUB_EFUSE_PWR_CTL0_EN_DONE_Msk + +#define MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE_Pos (4U) +#define MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE_Len (1U) +#define MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE_Msk (0x1U << MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE_Pos) +#define MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE MCU_SUB_EFUSE_PWR_CTL0_DIS_DONE_Msk + +/********** Bit definition for MCU_SUB_REG_I2S_CLK_CFG register ***********/ +#define MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL_Pos (18U) +#define MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL_Len (1U) +#define MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL_Msk (0x1U << MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL_Pos) +#define MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL MCU_SUB_I2S_CLK_CFG_SRC_CLK_SEL_Msk + +#define MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN_Pos (16U) +#define MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN_Len (1U) +#define MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN_Msk (0x1U << MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN_Pos) +#define MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN MCU_SUB_I2S_CLK_CFG_CLK_DIV_EN_Msk + +#define MCU_SUB_I2S_CLK_CFG_DIV_CNT_Pos (0U) +#define MCU_SUB_I2S_CLK_CFG_DIV_CNT_Len (12U) +#define MCU_SUB_I2S_CLK_CFG_DIV_CNT_Msk (0xFFFU << MCU_SUB_I2S_CLK_CFG_DIV_CNT_Pos) +#define MCU_SUB_I2S_CLK_CFG_DIV_CNT MCU_SUB_I2S_CLK_CFG_DIV_CNT_Msk + +/********** Bit definition for MCU_SUB_REG_AON_PAD_MUX_CTL register ***********/ +#define MCU_SUB_AON_MUX_CTL_00_07_Pos (0U) +#define MCU_SUB_AON_MUX_CTL_00_07_Len (32U) +#define MCU_SUB_AON_MUX_CTL_00_07_Msk (0x00777770U) +#define MCU_SUB_AON_MUX_CTL_00_07 MCU_SUB_AON_MUX_CTL_00_07_Msk + +#define MCU_SUB_AON_MUX_CTL_SEL_Msk (0x7U) +#define MCU_SUB_AON_MUX_CTL_SEL_01 (MCU_SUB_AON_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_AON_MUX_CTL_SEL_02 (MCU_SUB_AON_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_AON_MUX_CTL_SEL_03 (MCU_SUB_AON_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_AON_MUX_CTL_SEL_04 (MCU_SUB_AON_MUX_CTL_SEL_Msk << 16) +#define MCU_SUB_AON_MUX_CTL_SEL_05 (MCU_SUB_AON_MUX_CTL_SEL_Msk << 20) + +/********** Bit definition for MCU_SUB_REG_MSIO_PAD_MUX_CTL register ***********/ +#define MCU_SUB_MSIO_MUX_CTL_00_04_Pos (0U) +#define MCU_SUB_MSIO_MUX_CTL_00_04_Len (32U) +#define MCU_SUB_MSIO_MUX_CTL_00_04_Msk (0x77777U) +#define MCU_SUB_MSIO_MUX_CTL_00_04 MCU_SUB_MSIO_MUX_CTL_00_04_Msk + +#define MCU_SUB_MSIO_MUX_CTL_SEL_Msk (0x7U) +#define MCU_SUB_MSIO_MUX_CTL_SEL_00 (MCU_SUB_MSIO_MUX_CTL_SEL_Msk << 0) +#define MCU_SUB_MSIO_MUX_CTL_SEL_01 (MCU_SUB_MSIO_MUX_CTL_SEL_Msk << 4) +#define MCU_SUB_MSIO_MUX_CTL_SEL_02 (MCU_SUB_MSIO_MUX_CTL_SEL_Msk << 8) +#define MCU_SUB_MSIO_MUX_CTL_SEL_03 (MCU_SUB_MSIO_MUX_CTL_SEL_Msk << 12) +#define MCU_SUB_MSIO_MUX_CTL_SEL_04 (MCU_SUB_MSIO_MUX_CTL_SEL_Msk << 16) + +/********** Bit definition for MCU_SUB_REG_MCU_SUBSYS_CG_CTRL_0 register ***********/ +#define MCU_SUB_WFI_MSK_HCLK_0 (0xFFFU) + +#define MCU_SUB_WFI_I2S_S_HCLK_Pos (11U) +#define MCU_SUB_WFI_I2S_S_HCLK_Len (1U) +#define MCU_SUB_WFI_I2S_S_HCLK_Msk (0x01 << MCU_SUB_WFI_I2S_S_HCLK_Pos) +#define MCU_SUB_WFI_I2S_S_HCLK MCU_SUB_WFI_I2S_S_HCLK_Msk + +#define MCU_SUB_WFI_SERIAL_HCLK_Pos (10U) +#define MCU_SUB_WFI_SERIAL_HCLK_Len (1U) +#define MCU_SUB_WFI_SERIAL_HCLK_Msk (0x01 << MCU_SUB_WFI_SERIAL_HCLK_Pos) +#define MCU_SUB_WFI_SERIAL_HCLK MCU_SUB_WFI_SERIAL_HCLK_Msk + +#define MCU_SUB_WFI_APB_SUB_HCLK_Pos (9U) +#define MCU_SUB_WFI_APB_SUB_HCLK_Len (1U) +#define MCU_SUB_WFI_APB_SUB_HCLK_Msk (0x01 << MCU_SUB_WFI_APB_SUB_HCLK_Pos) +#define MCU_SUB_WFI_APB_SUB_HCLK MCU_SUB_WFI_APB_SUB_HCLK_Msk + +#define MCU_SUB_WFI_BLE_BRG_HCLK_Pos (8U) +#define MCU_SUB_WFI_BLE_BRG_HCLK_Len (1U) +#define MCU_SUB_WFI_BLE_BRG_HCLK_Msk (0x01 << MCU_SUB_WFI_BLE_BRG_HCLK_Pos) +#define MCU_SUB_WFI_BLE_BRG_HCLK MCU_SUB_WFI_BLE_BRG_HCLK_Msk + +#define MCU_SUB_WFI_DMA_HCLK_Pos (7U) +#define MCU_SUB_WFI_DMA_HCLK_Len (1U) +#define MCU_SUB_WFI_DMA_HCLK_Msk (0x01 << MCU_SUB_WFI_DMA_HCLK_Pos) +#define MCU_SUB_WFI_DMA_HCLK MCU_SUB_WFI_DMA_HCLK_Msk + +#define MCU_SUB_WFI_GPIO_HCLK_Pos (6U) +#define MCU_SUB_WFI_GPIO_HCLK_Len (1U) +#define MCU_SUB_WFI_GPIO_HCLK_Msk (0x01 << MCU_SUB_WFI_GPIO_HCLK_Pos) +#define MCU_SUB_WFI_GPIO_HCLK MCU_SUB_WFI_GPIO_HCLK_Msk + +#define MCU_SUB_WFI_SNSADC_HCLK_Pos (5U) +#define MCU_SUB_WFI_SNSADC_HCLK_Len (1U) +#define MCU_SUB_WFI_SNSADC_HCLK_Msk (0x01 << MCU_SUB_WFI_SNSADC_HCLK_Pos) +#define MCU_SUB_WFI_SNSADC_HCLK MCU_SUB_WFI_SNSADC_HCLK_Msk + +#define MCU_SUB_WFI_ROM_HCLK_Pos (4U) +#define MCU_SUB_WFI_ROM_HCLK_Len (1U) +#define MCU_SUB_WFI_ROM_HCLK_Msk (0x01 << MCU_SUB_WFI_ROM_HCLK_Pos) +#define MCU_SUB_WFI_ROM_HCLK MCU_SUB_WFI_ROM_HCLK_Msk + +#define MCU_SUB_WFI_PWM_HCLK_Pos (3U) +#define MCU_SUB_WFI_PWM_HCLK_Len (1U) +#define MCU_SUB_WFI_PWM_HCLK_Msk (0x01 << MCU_SUB_WFI_PWM_HCLK_Pos) +#define MCU_SUB_WFI_PWM_HCLK MCU_SUB_WFI_PWM_HCLK_Msk + +#define MCU_SUB_WFI_HTB_HCLK_Pos (2U) +#define MCU_SUB_WFI_HTB_HCLK_Len (1U) +#define MCU_SUB_WFI_HTB_HCLK_Msk (0x01 << MCU_SUB_WFI_HTB_HCLK_Pos) +#define MCU_SUB_WFI_HTB_HCLK MCU_SUB_WFI_HTB_HCLK_Msk + +#define MCU_SUB_WFI_SIM_HCLK_Pos (1U) +#define MCU_SUB_WFI_SIM_HCLK_Len (1U) +#define MCU_SUB_WFI_SIM_HCLK_Msk (0x01 << MCU_SUB_WFI_SIM_HCLK_Pos) +#define MCU_SUB_WFI_SIM_HCLK MCU_SUB_WFI_SIM_HCLK_Msk + +#define MCU_SUB_WFI_SECU_HCLK_Pos (0U) +#define MCU_SUB_WFI_SECU_HCLK_Len (1U) +#define MCU_SUB_WFI_SECU_HCLK_Msk (0x01 << MCU_SUB_WFI_SECU_HCLK_Pos) +#define MCU_SUB_WFI_SECU_HCLK MCU_SUB_WFI_SECU_HCLK_Msk + +/********** Bit definition for MCU_SUB_REG_MCU_SUBSYS_CG_CTRL_1 register ***********/ +#define MCU_SUB_FORCE_MSK_HCLK_0 (0xFFFU) + +#define MCU_SUB_FORCE_I2S_S_HCLK_Pos (11U) +#define MCU_SUB_FORCE_I2S_S_HCLK_Len (1U) +#define MCU_SUB_FORCE_I2S_S_HCLK_Msk (0x01 << MCU_SUB_FORCE_I2S_S_HCLK_Pos) +#define MCU_SUB_FORCE_I2S_S_HCLK MCU_SUB_FORCE_I2S_S_HCLK_Msk + +#define MCU_SUB_FORCE_SERIAL_HCLK_Pos (10U) +#define MCU_SUB_FORCE_SERIAL_HCLK_Len (1U) +#define MCU_SUB_FORCE_SERIAL_HCLK_Msk (0x01 << MCU_SUB_FORCE_SERIAL_HCLK_Pos) +#define MCU_SUB_FORCE_SERIAL_HCLK MCU_SUB_FORCE_SERIAL_HCLK_Msk + +#define MCU_SUB_FORCE_APB_SUB_HCLK_Pos (9U) +#define MCU_SUB_FORCE_APB_SUB_HCLK_Len (1U) +#define MCU_SUB_FORCE_APB_SUB_HCLK_Msk (0x01 << MCU_SUB_FORCE_APB_SUB_HCLK_Pos) +#define MCU_SUB_FORCE_APB_SUB_HCLK MCU_SUB_FORCE_APB_SUB_HCLK_Msk + +#define MCU_SUB_FORCE_BLE_BRG_HCLK_Pos (8U) +#define MCU_SUB_FORCE_BLE_BRG_HCLK_Len (1U) +#define MCU_SUB_FORCE_BLE_BRG_HCLK_Msk (0x01 << MCU_SUB_FORCE_BLE_BRG_HCLK_Pos) +#define MCU_SUB_FORCE_BLE_BRG_HCLK MCU_SUB_FORCE_BLE_BRG_HCLK_Msk + +#define MCU_SUB_FORCE_DMA_HCLK_Pos (7U) +#define MCU_SUB_FORCE_DMA_HCLK_Len (1U) +#define MCU_SUB_FORCE_DMA_HCLK_Msk (0x01 << MCU_SUB_FORCE_DMA_HCLK_Pos) +#define MCU_SUB_FORCE_DMA_HCLK MCU_SUB_FORCE_DMA_HCLK_Msk + +#define MCU_SUB_FORCE_GPIO_HCLK_Pos (6U) +#define MCU_SUB_FORCE_GPIO_HCLK_Len (1U) +#define MCU_SUB_FORCE_GPIO_HCLK_Msk (0x01 << MCU_SUB_FORCE_GPIO_HCLK_Pos) +#define MCU_SUB_FORCE_GPIO_HCLK MCU_SUB_FORCE_GPIO_HCLK_Msk + +#define MCU_SUB_FORCE_SNSADC_HCLK_Pos (5U) +#define MCU_SUB_FORCE_SNSADC_HCLK_Len (1U) +#define MCU_SUB_FORCE_SNSADC_HCLK_Msk (0x01 << MCU_SUB_FORCE_SNSADC_HCLK_Pos) +#define MCU_SUB_FORCE_SNSADC_HCLK MCU_SUB_FORCE_SNSADC_HCLK_Msk + +#define MCU_SUB_FORCE_ROM_HCLK_Pos (4U) +#define MCU_SUB_FORCE_ROM_HCLK_Len (1U) +#define MCU_SUB_FORCE_ROM_HCLK_Msk (0x01 << MCU_SUB_FORCE_ROM_HCLK_Pos) +#define MCU_SUB_FORCE_ROM_HCLK MCU_SUB_FORCE_ROM_HCLK_Msk + +#define MCU_SUB_FORCE_PWM_HCLK_Pos (3U) +#define MCU_SUB_FORCE_PWM_HCLK_Len (1U) +#define MCU_SUB_FORCE_PWM_HCLK_Msk (0x01 << MCU_SUB_FORCE_PWM_HCLK_Pos) +#define MCU_SUB_FORCE_PWM_HCLK MCU_SUB_FORCE_PWM_HCLK_Msk + +#define MCU_SUB_FORCE_HTB_HCLK_Pos (2U) +#define MCU_SUB_FORCE_HTB_HCLK_Len (1U) +#define MCU_SUB_FORCE_HTB_HCLK_Msk (0x01 << MCU_SUB_FORCE_HTB_HCLK_Pos) +#define MCU_SUB_FORCE_HTB_HCLK MCU_SUB_FORCE_HTB_HCLK_Msk + +#define MCU_SUB_FORCE_SIM_HCLK_Pos (1U) +#define MCU_SUB_FORCE_SIM_HCLK_Len (1U) +#define MCU_SUB_FORCE_SIM_HCLK_Msk (0x01 << MCU_SUB_FORCE_SIM_HCLK_Pos) +#define MCU_SUB_FORCE_SIM_HCLK MCU_SUB_FORCE_SIM_HCLK_Msk + +#define MCU_SUB_FORCE_SECU_HCLK_Pos (0U) +#define MCU_SUB_FORCE_SECU_HCLK_Len (1U) +#define MCU_SUB_FORCE_SECU_HCLK_Msk (0x01 << MCU_SUB_FORCE_SECU_HCLK_Pos) +#define MCU_SUB_FORCE_SECU_HCLK MCU_SUB_FORCE_SECU_HCLK_Msk + +/********** Bit definition for MCU_SUB_REG_MCU_SUBSYS_CG_CTRL_2 register ***********/ +#define MCU_SUB_FORCE_MSK_HCLK_1 (0x00070000U) + +#define MCU_SUB_FORCE_SRAM_HCLK_Pos (18U) +#define MCU_SUB_FORCE_SRAM_HCLK_Len (1U) +#define MCU_SUB_FORCE_SRAM_HCLK_Msk (0x1UL << MCU_SUB_FORCE_SRAM_HCLK_Pos) +#define MCU_SUB_FORCE_SRAM_HCLK MCU_SUB_FORCE_SRAM_HCLK_Msk + +#define MCU_SUB_FORCE_XF_XQSPI_HCLK_Pos (17U) +#define MCU_SUB_FORCE_XF_XQSPI_HCLK_Len (1U) +#define MCU_SUB_FORCE_XF_XQSPI_HCLK_Msk (0x1UL << MCU_SUB_FORCE_XF_XQSPI_HCLK_Pos) +#define MCU_SUB_FORCE_XF_XQSPI_HCLK MCU_SUB_FORCE_XF_XQSPI_HCLK_Msk + +#define MCU_SUB_FORCE_AON_MCUSUB_HCLK_Pos (16U) +#define MCU_SUB_FORCE_AON_MCUSUB_HCLK_Len (1U) +#define MCU_SUB_FORCE_AON_MCUSUB_HCLK_Msk (0x1UL << MCU_SUB_FORCE_AON_MCUSUB_HCLK_Pos) +#define MCU_SUB_FORCE_AON_MCUSUB_HCLK MCU_SUB_FORCE_AON_MCUSUB_HCLK_Msk + +#define MCU_SUB_WFI_MSK_HCLK_1 (0x00000007U) + +#define MCU_SUB_WFI_SRAM_HCLK_Pos (2U) +#define MCU_SUB_WFI_SRAM_HCLK_Len (1U) +#define MCU_SUB_WFI_SRAM_HCLK_Msk (0x1UL << MCU_SUB_WFI_SRAM_HCLK_Pos) +#define MCU_SUB_WFI_SRAM_HCLK MCU_SUB_WFI_SRAM_HCLK_Msk + +#define MCU_SUB_WFI_XF_XQSPI_HCLK_Pos (1U) +#define MCU_SUB_WFI_XF_XQSPI_HCLK_Len (1U) +#define MCU_SUB_WFI_XF_XQSPI_HCLK_Msk (0x1UL << MCU_SUB_WFI_XF_XQSPI_HCLK_Pos) +#define MCU_SUB_WFI_XF_XQSPI_HCLK MCU_SUB_WFI_XF_XQSPI_HCLK_Msk + +#define MCU_SUB_WFI_AON_MCUSUB_HCLK_Pos (0U) +#define MCU_SUB_WFI_AON_MCUSUB_HCLK_Len (1U) +#define MCU_SUB_WFI_AON_MCUSUB_HCLK_Msk (0x1UL << MCU_SUB_WFI_AON_MCUSUB_HCLK_Pos) +#define MCU_SUB_WFI_AON_MCUSUB_HCLK MCU_SUB_WFI_AON_MCUSUB_HCLK_Msk + +/********** Bit definition for MCU_SUB_REG_MCU_PERIPH_GC register ***********/ +#define MCU_SUB_FORCE_MSK_HCLK_2 (0x0A01FF00U) +#define MCU_SUB_WFI_MSK_HCLK_2 (0x05000000U) +#define MCU_SUB_FORCE_XQSPI_DIV4_PCLK_Pos (27U) +#define MCU_SUB_FORCE_XQSPI_DIV4_PCLK_Len (1U) +#define MCU_SUB_FORCE_XQSPI_DIV4_PCLK_Msk (0x1UL << MCU_SUB_FORCE_XQSPI_DIV4_PCLK_Pos) +#define MCU_SUB_FORCE_XQSPI_DIV4_PCLK MCU_SUB_FORCE_XQSPI_DIV4_PCLK_Msk + +#define MCU_SUB_WFI_XQSPI_DIV4_PCLK_Pos (26U) +#define MCU_SUB_WFI_XQSPI_DIV4_PCLK_Len (1U) +#define MCU_SUB_WFI_XQSPI_DIV4_PCLK_Msk (0x1UL << MCU_SUB_WFI_XQSPI_DIV4_PCLK_Pos) +#define MCU_SUB_WFI_XQSPI_DIV4_PCLK MCU_SUB_WFI_XQSPI_DIV4_PCLK_Msk + +#define MCU_SUB_FORCE_SECU_DIV4_PCLK_Pos (25U) +#define MCU_SUB_FORCE_SECU_DIV4_PCLK_Len (1U) +#define MCU_SUB_FORCE_SECU_DIV4_PCLK_Msk (0x1UL << MCU_SUB_FORCE_SECU_DIV4_PCLK_Pos) +#define MCU_SUB_FORCE_SECU_DIV4_PCLK MCU_SUB_FORCE_SECU_DIV4_PCLK_Msk + +#define MCU_SUB_WFI_SECU_DIV4_PCLK_Pos (24U) +#define MCU_SUB_WFI_SECU_DIV4_PCLK_Len (1U) +#define MCU_SUB_WFI_SECU_DIV4_PCLK_Msk (0x1UL << MCU_SUB_WFI_SECU_DIV4_PCLK_Pos) +#define MCU_SUB_WFI_SECU_DIV4_PCLK MCU_SUB_WFI_SECU_DIV4_PCLK_Msk + +#define MCU_SUB_FORCE_I2S_HCLK_Pos (16U) +#define MCU_SUB_FORCE_I2S_HCLK_Len (1U) +#define MCU_SUB_FORCE_I2S_HCLK_Msk (0x1UL << MCU_SUB_FORCE_I2S_HCLK_Pos) +#define MCU_SUB_FORCE_I2S_HCLK MCU_SUB_FORCE_I2S_HCLK_Msk + +#define MCU_SUB_FORCE_QSPI1_HCLK_Pos (15U) +#define MCU_SUB_FORCE_QSPI1_HCLK_Len (1U) +#define MCU_SUB_FORCE_QSPI1_HCLK_Msk (0x1UL << MCU_SUB_FORCE_QSPI1_HCLK_Pos) +#define MCU_SUB_FORCE_QSPI1_HCLK MCU_SUB_FORCE_QSPI1_HCLK_Msk + +#define MCU_SUB_FORCE_QSPI0_HCLK_Pos (14U) +#define MCU_SUB_FORCE_QSPI0_HCLK_Len (1U) +#define MCU_SUB_FORCE_QSPI0_HCLK_Msk (0x1UL << MCU_SUB_FORCE_QSPI0_HCLK_Pos) +#define MCU_SUB_FORCE_QSPI0_HCLK MCU_SUB_FORCE_QSPI0_HCLK_Msk + +#define MCU_SUB_FORCE_SPIS_HCLK_Pos (13U) +#define MCU_SUB_FORCE_SPIS_HCLK_Len (1U) +#define MCU_SUB_FORCE_SPIS_HCLK_Msk (0x1UL << MCU_SUB_FORCE_SPIS_HCLK_Pos) +#define MCU_SUB_FORCE_SPIS_HCLK MCU_SUB_FORCE_SPIS_HCLK_Msk + +#define MCU_SUB_FORCE_SPIM_HCLK_Pos (12U) +#define MCU_SUB_FORCE_SPIM_HCLK_Len (1U) +#define MCU_SUB_FORCE_SPIM_HCLK_Msk (0x1UL << MCU_SUB_FORCE_SPIM_HCLK_Pos) +#define MCU_SUB_FORCE_SPIM_HCLK MCU_SUB_FORCE_SPIM_HCLK_Msk + +#define MCU_SUB_FORCE_I2C1_HCLK_Pos (11U) +#define MCU_SUB_FORCE_I2C1_HCLK_Len (1U) +#define MCU_SUB_FORCE_I2C1_HCLK_Msk (0x1UL << MCU_SUB_FORCE_I2C1_HCLK_Pos) +#define MCU_SUB_FORCE_I2C1_HCLK MCU_SUB_FORCE_I2C1_HCLK_Msk + +#define MCU_SUB_FORCE_I2C0_HCLK_Pos (10U) +#define MCU_SUB_FORCE_I2C0_HCLK_Len (1U) +#define MCU_SUB_FORCE_I2C0_HCLK_Msk (0x1UL << MCU_SUB_FORCE_I2C0_HCLK_Pos) +#define MCU_SUB_FORCE_I2C0_HCLK MCU_SUB_FORCE_I2C0_HCLK_Msk + +#define MCU_SUB_FORCE_UART1_HCLK_Pos (9U) +#define MCU_SUB_FORCE_UART1_HCLK_Len (1U) +#define MCU_SUB_FORCE_UART1_HCLK_Msk (0x1UL << MCU_SUB_FORCE_UART1_HCLK_Pos) +#define MCU_SUB_FORCE_UART1_HCLK MCU_SUB_FORCE_UART1_HCLK_Msk + +#define MCU_SUB_FORCE_UART0_HCLK_Pos (8U) +#define MCU_SUB_FORCE_UART0_HCLK_Len (1U) +#define MCU_SUB_FORCE_UART0_HCLK_Msk (0x1UL << MCU_SUB_FORCE_UART0_HCLK_Pos) +#define MCU_SUB_FORCE_UART0_HCLK MCU_SUB_FORCE_UART0_HCLK_Msk + +#define MCU_SUB_I2S_LP_EN_Pos (2U) +#define MCU_SUB_I2S_LP_EN_Len (1U) +#define MCU_SUB_I2S_LP_EN_Msk (0x1UL << MCU_SUB_I2S_LP_EN_Pos) +#define MCU_SUB_I2S_LP_EN MCU_SUB_I2S_LP_EN_Msk + +#define MCU_SUB_UART_LP_PCLK_EN_Pos (1U) +#define MCU_SUB_UART_LP_PCLK_EN_Len (1U) +#define MCU_SUB_UART_LP_PCLK_EN_Msk (0x1UL << MCU_SUB_UART_LP_PCLK_EN_Pos) +#define MCU_SUB_UART_LP_PCLK_EN MCU_SUB_UART_LP_PCLK_EN_Msk + +#define MCU_SUB_UART_LP_SCLK_EN_Pos (0U) +#define MCU_SUB_UART_LP_SCLK_EN_Len (1U) +#define MCU_SUB_UART_LP_SCLK_EN_Msk (0x1UL << MCU_SUB_UART_LP_SCLK_EN_Pos) +#define MCU_SUB_UART_LP_SCLK_EN MCU_SUB_UART_LP_SCLK_EN_Msk + +/********** Bit definition for MCU_SUB_REG_BLE_DSLEEP_CORR_EN register ***********/ +#define MCU_SUB_BLE_DSLEEP_CORR_EN_Pos (0U) +#define MCU_SUB_BLE_DSLEEP_CORR_EN_Len (2U) +#define MCU_SUB_BLE_DSLEEP_CORR_EN_Msk (0x3U << MCU_SUB_BLE_DSLEEP_CORR_EN_Pos) +#define MCU_SUB_BLE_DSLEEP_CORR_HW_EN (0x02 << MCU_SUB_BLE_DSLEEP_CORR_EN_Pos) +#define MCU_SUB_BLE_DSLEEP_CORR_SW_EN (0x01 << MCU_SUB_BLE_DSLEEP_CORR_EN_Pos) + +/********** Bit definition for MCU_SUB_REG_BLE_DSLEEP_HW_TIM_CORR register ***********/ +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD_Pos (12U) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD_Len (18U) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD_Msk (0x3FFFFU << MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD_Pos) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_CLK_PERIOD_Msk + +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY_Pos (0U) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY_Len (9U) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY_Msk (0x1FFU << MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY_Pos) +#define MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY MCU_SUB_BLE_DSLEEP_HW_TIM_CORR_DELAY_Msk + + + +/* ================================================================================================================= */ +/* ================ PKC ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for PKC_CTRL register *******************/ +#define PKC_CTRL_EN_Pos (0U) +#define PKC_CTRL_EN_Len (1U) +#define PKC_CTRL_EN_Msk (0x1U << PKC_CTRL_EN_Pos) +#define PKC_CTRL_EN PKC_CTRL_EN_Msk + +#define PKC_CTRL_START_Pos (1U) +#define PKC_CTRL_START_Len (1U) +#define PKC_CTRL_START_Msk (0x1U << PKC_CTRL_START_Pos) +#define PKC_CTRL_START PKC_CTRL_START_Msk + +#define PKC_CTRL_SWCTRL_Pos (4U) +#define PKC_CTRL_SWCTRL_Len (1U) +#define PKC_CTRL_SWCTRL_Msk (0x1U << PKC_CTRL_SWCTRL_Pos) +#define PKC_CTRL_SWCTRL PKC_CTRL_SWCTRL_Msk + +#define PKC_CTRL_SWRST_Pos (8U) +#define PKC_CTRL_SWRST_Len (1U) +#define PKC_CTRL_SWRST_Msk (0x1U << PKC_CTRL_SWRST_Pos) +#define PKC_CTRL_SWRST PKC_CTRL_SWRST_Msk + +/******************* Bit definition for PKC_CONFIG0 register ****************/ +#define PKC_CONFIG0_KPTR_Pos (0U) +#define PKC_CONFIG0_KPTR_Len (9U) +#define PKC_CONFIG0_KPTR_Msk (0x000001FFU) +#define PKC_CONFIG0_KPTR PKC_CONFIG0_KPTR_Msk + +#define PKC_CONFIG0_RPTR_Pos (16U) +#define PKC_CONFIG0_RPTR_Len (9U) +#define PKC_CONFIG0_RPTR_Msk (0x01FF0000U) +#define PKC_CONFIG0_RPTR PKC_CONFIG0_RPTR_Msk + +/******************* Bit definition for PKC_CONFIG1 register ****************/ +#define PKC_CONFIG1_PPTR_Pos (0U) +#define PKC_CONFIG1_PPTR_Len (9U) +#define PKC_CONFIG1_PPTR_Msk (0x000001FFU) +#define PKC_CONFIG1_PPTR PKC_CONFIG1_PPTR_Msk + +#define PKC_CONFIG1_RSQPTR_Pos (16U) +#define PKC_CONFIG1_RSQPTR_Len (9U) +#define PKC_CONFIG1_RSQPTR_Msk (0x01FF0000U) +#define PKC_CONFIG1_RSQPTR PKC_CONFIG1_RSQPTR_Msk + +/******************* Bit definition for PKC_CONFIG2 register ****************/ +#define PKC_CONFIG2_GXPTR_Pos (0U) +#define PKC_CONFIG2_GXPTR_Len (9U) +#define PKC_CONFIG2_GXPTR_Msk (0x000001FFU) +#define PKC_CONFIG2_GXPTR PKC_CONFIG2_GXPTR_Msk + +#define PKC_CONFIG2_GYPTR_Pos (16U) +#define PKC_CONFIG2_GYPTR_Len (9U) +#define PKC_CONFIG2_GYPTR_Msk (0x01FF0000U) +#define PKC_CONFIG2_GYPTR PKC_CONFIG2_GYPTR_Msk + +/******************* Bit definition for PKC_CONFIG3 register ****************/ +#define PKC_CONFIG3_GZPTR_Pos (0U) +#define PKC_CONFIG3_GZPTR_Len (9U) +#define PKC_CONFIG3_GZPTR_Msk (0x000001FFU) +#define PKC_CONFIG3_GZPTR PKC_CONFIG3_GZPTR_Msk + +#define PKC_CONFIG3_R0XPTR_Pos (16U) +#define PKC_CONFIG3_R0XPTR_Len (9U) +#define PKC_CONFIG3_R0XPTR_Msk (0x01FF0000U) +#define PKC_CONFIG3_R0XPTR PKC_CONFIG3_R0XPTR_Msk + +/******************* Bit definition for PKC_CONFIG4 register ****************/ +#define PKC_CONFIG4_R0YPTR_Pos (0U) +#define PKC_CONFIG4_R0YPTR_Len (9U) +#define PKC_CONFIG4_R0YPTR_Msk (0x000001FFU) +#define PKC_CONFIG4_R0YPTR PKC_CONFIG4_R0YPTR_Msk + +#define PKC_CONFIG4_R0ZPTR_Pos (16U) +#define PKC_CONFIG4_R0ZPTR_Len (9U) +#define PKC_CONFIG4_R0ZPTR_Msk (0x01FF0000U) +#define PKC_CONFIG4_R0ZPTR PKC_CONFIG4_R0ZPTR_Msk + +/******************* Bit definition for PKC_CONFIG5 register ****************/ +#define PKC_CONFIG5_R1XPTR_Pos (0U) +#define PKC_CONFIG5_R1XPTR_Len (9U) +#define PKC_CONFIG5_R1XPTR_Msk (0x000001FFU) +#define PKC_CONFIG5_R1XPTR PKC_CONFIG5_R1XPTR_Msk + +#define PKC_CONFIG5_R1YPTR_Pos (16U) +#define PKC_CONFIG5_R1YPTR_Len (9U) +#define PKC_CONFIG5_R1YPTR_Msk (0x01FF0000U) +#define PKC_CONFIG5_R1YPTR PKC_CONFIG5_R1YPTR_Msk + +/******************* Bit definition for PKC_CONFIG6 register ****************/ +#define PKC_CONFIG6_R1ZPTR_Pos (0U) +#define PKC_CONFIG6_R1ZPTR_Len (9U) +#define PKC_CONFIG6_R1ZPTR_Msk (0x000001FFU) +#define PKC_CONFIG6_R1ZPTR PKC_CONFIG6_R1ZPTR_Msk + +#define PKC_CONFIG6_TMP1PTR_Pos (16U) +#define PKC_CONFIG6_TMP1PTR_Len (9U) +#define PKC_CONFIG6_TMP1PTR_Msk (0x01FF0000U) +#define PKC_CONFIG6_TMP1PTR PKC_CONFIG6_TMP1PTR_Msk + +/******************* Bit definition for PKC_CONFIG7 register ****************/ +#define PKC_CONFIG7_TMP2PTR_Pos (0U) +#define PKC_CONFIG7_TMP2PTR_Len (9U) +#define PKC_CONFIG7_TMP2PTR_Msk (0x000001FFU) +#define PKC_CONFIG7_TMP2PTR PKC_CONFIG7_TMP2PTR_Msk + +#define PKC_CONFIG7_TMP3PTR_Pos (16U) +#define PKC_CONFIG7_TMP3PTR_Len (9U) +#define PKC_CONFIG7_TMP3PTR_Msk (0x01FF0000U) +#define PKC_CONFIG7_TMP3PTR PKC_CONFIG7_TMP3PTR_Msk + +/******************* Bit definition for PKC_CONFIG8 register ****************/ +#define PKC_CONFIG8_TMP4PTR_Pos (0U) +#define PKC_CONFIG8_TMP4PTR_Len (9U) +#define PKC_CONFIG8_TMP4PTR_Msk (0x000001FFU) +#define PKC_CONFIG8_TMP4PTR PKC_CONFIG8_TMP4PTR_Msk + +#define PKC_CONFIG8_TMP5PTR_Pos (16U) +#define PKC_CONFIG8_TMP5PTR_Len (9U) +#define PKC_CONFIG8_TMP5PTR_Msk (0x01FF0000U) +#define PKC_CONFIG8_TMP5PTR PKC_CONFIG8_TMP5PTR_Msk + +/******************* Bit definition for PKC_CONFIG9 register ****************/ +#define PKC_CONFIG9_TMP6PTR_Pos (0U) +#define PKC_CONFIG9_TMP6PTR_Len (9U) +#define PKC_CONFIG9_TMP6PTR_Msk (0x000001FFU) +#define PKC_CONFIG9_TMP6PTR PKC_CONFIG9_TMP6PTR_Msk + +#define PKC_CONFIG9_CONST1PTR_Pos (16U) +#define PKC_CONFIG9_CONST1PTR_Len (9U) +#define PKC_CONFIG9_CONST1PTR_Msk (0x01FF0000U) +#define PKC_CONFIG9_CONST1PTR PKC_CONFIG9_CONST1PTR_Msk + +/******************* Bit definition for PKC_CONFIG10 register ****************/ +#define PKC_CONFIG10_X1PTR_Pos (0U) +#define PKC_CONFIG10_X1PTR_Len (9U) +#define PKC_CONFIG10_X1PTR_Msk (0x000001FFU) +#define PKC_CONFIG10_X1PTR PKC_CONFIG10_X1PTR_Msk + +#define PKC_CONFIG10_X2PTR_Pos (16U) +#define PKC_CONFIG10_X2PTR_Len (9U) +#define PKC_CONFIG10_X2PTR_Msk (0x01FF0000U) +#define PKC_CONFIG10_X2PTR PKC_CONFIG10_X2PTR_Msk + +/******************* Bit definition for PKC_CONFIG11 register ****************/ +#define PKC_CONFIG11_MITMPPTR_Pos (0U) +#define PKC_CONFIG11_MITMPPTR_Len (9U) +#define PKC_CONFIG11_MITMPPTR_Msk (0x000001FFU) +#define PKC_CONFIG11_MITMPPTR PKC_CONFIG11_MITMPPTR_Msk + +#define PKC_CONFIG11_TMPKPTR_Pos (16U) +#define PKC_CONFIG11_TMPKPTR_Len (9U) +#define PKC_CONFIG11_TMPKPTR_Msk (0x01FF0000U) +#define PKC_CONFIG11_TMPKPTR PKC_CONFIG11_TMPKPTR_Msk + +/******************* Bit definition for PKC_CONFIG12 register ****************/ +#define PKC_CONFIG12_APTR_Pos (0U) +#define PKC_CONFIG12_APTR_Len (9U) +#define PKC_CONFIG12_APTR_Msk (0x000001FFU) +#define PKC_CONFIG12_APTR PKC_CONFIG12_APTR_Msk + +#define PKC_CONFIG12_BPTR_Pos (16U) +#define PKC_CONFIG12_BPTR_Len (9U) +#define PKC_CONFIG12_BPTR_Msk (0x01FF0000U) +#define PKC_CONFIG12_BPTR PKC_CONFIG12_BPTR_Msk + +/******************* Bit definition for PKC_CONFIG13 register ****************/ +#define PKC_CONFIG13_CONSTQ_Pos (0U) +#define PKC_CONFIG13_CONSTQ_Len (32U) +#define PKC_CONFIG13_CONSTQ_Msk (0xFFFFFFFFU) +#define PKC_CONFIG13_CONSTQ PKC_CONFIG13_CONSTQ_Msk + +/******************* Bit definition for PKC_SW_CTRL register *****************/ +#define PKC_SW_CTRL_OPSTART_Pos (0U) +#define PKC_SW_CTRL_OPSTART_Len (1U) +#define PKC_SW_CTRL_OPSTART_Msk (0x1U << PKC_SW_CTRL_OPSTART_Pos) +#define PKC_SW_CTRL_OPSTART PKC_SW_CTRL_OPSTART_Msk + +#define PKC_SW_CTRL_OPMODE_Pos (4U) +#define PKC_SW_CTRL_OPMODE_Len (3U) +#define PKC_SW_CTRL_OPMODE_Msk (0x7U << PKC_SW_CTRL_OPMODE_Pos) +#define PKC_SW_CTRL_OPMODE PKC_SW_CTRL_OPMODE_Msk + +#define PKC_SW_CTRL_STARTDM_Pos (8U) +#define PKC_SW_CTRL_STARTDM_Len (1U) +#define PKC_SW_CTRL_STARTDM_Msk (0x1U << PKC_SW_CTRL_STARTDM_Pos) +#define PKC_SW_CTRL_STARTDM PKC_SW_CTRL_STARTDM_Msk + +#define PKC_SW_CTRL_RANDEN_Pos (9U) +#define PKC_SW_CTRL_RANDEN_Len (1U) +#define PKC_SW_CTRL_RANDEN_Msk (0x1U << PKC_SW_CTRL_RANDEN_Pos) +#define PKC_SW_CTRL_RANDEN PKC_SW_CTRL_RANDEN_Msk + +/******************* Bit definition for PKC_SW_CONFIG0 register ************/ +#define PKC_SW_CONFIG0_MMAPTR_Pos (0U) +#define PKC_SW_CONFIG0_MMAPTR_Len (9U) +#define PKC_SW_CONFIG0_MMAPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG0_MMAPTR PKC_SW_CONFIG0_MMAPTR_Msk + +#define PKC_SW_CONFIG0_MMBPTR_Pos (16U) +#define PKC_SW_CONFIG0_MMBPTR_Len (9U) +#define PKC_SW_CONFIG0_MMBPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG0_MMBPTR PKC_SW_CONFIG0_MMBPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG1 register ************/ +#define PKC_SW_CONFIG1_MMPPTR_Pos (0U) +#define PKC_SW_CONFIG1_MMPPTR_Len (9U) +#define PKC_SW_CONFIG1_MMPPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG1_MMPPTR PKC_SW_CONFIG1_MMPPTR_Msk + +#define PKC_SW_CONFIG1_MMCPTR_Pos (16U) +#define PKC_SW_CONFIG1_MMCPTR_Len (9U) +#define PKC_SW_CONFIG1_MMCPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG1_MMCPTR PKC_SW_CONFIG1_MMCPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG2 register ************/ +#define PKC_SW_CONFIG2_MASAPTR_Pos (0U) +#define PKC_SW_CONFIG2_MASAPTR_Len (9U) +#define PKC_SW_CONFIG2_MASAPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG2_MASAPTR PKC_SW_CONFIG2_MASAPTR_Msk + +#define PKC_SW_CONFIG2_MASBPTR_Pos (16U) +#define PKC_SW_CONFIG2_MASBPTR_Len (9U) +#define PKC_SW_CONFIG2_MASBPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG2_MASBPTR PKC_SW_CONFIG2_MASBPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG3 register ************/ +#define PKC_SW_CONFIG3_MASPPTR_Pos (0U) +#define PKC_SW_CONFIG3_MASPPTR_Len (9U) +#define PKC_SW_CONFIG3_MASPPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG3_MASPPTR PKC_SW_CONFIG3_MASPPTR_Msk + +#define PKC_SW_CONFIG3_MASCPTR_Pos (16U) +#define PKC_SW_CONFIG3_MASCPTR_Len (9U) +#define PKC_SW_CONFIG3_MASCPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG3_MASCPTR PKC_SW_CONFIG3_MASCPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG4 register ************/ +#define PKC_SW_CONFIG4_MIUPTR_Pos (0U) +#define PKC_SW_CONFIG4_MIUPTR_Len (9U) +#define PKC_SW_CONFIG4_MIUPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG4_MIUPTR PKC_SW_CONFIG4_MIUPTR_Msk + +#define PKC_SW_CONFIG4_MIVPTR_Pos (16U) +#define PKC_SW_CONFIG4_MIVPTR_Len (9U) +#define PKC_SW_CONFIG4_MIVPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG4_MIVPTR PKC_SW_CONFIG4_MIVPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG5 register ************/ +#define PKC_SW_CONFIG5_MIX1PTR_Pos (0U) +#define PKC_SW_CONFIG5_MIX1PTR_Len (9U) +#define PKC_SW_CONFIG5_MIX1PTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG5_MIX1PTR PKC_SW_CONFIG5_MIX1PTR_Msk + +#define PKC_SW_CONFIG5_MIX2PTR_Pos (16U) +#define PKC_SW_CONFIG5_MIX2PTR_Len (9U) +#define PKC_SW_CONFIG5_MIX2PTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG5_MIX2PTR PKC_SW_CONFIG5_MIX2PTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG6 register ************/ +#define PKC_SW_CONFIG6_MITMPPTR_Pos (0U) +#define PKC_SW_CONFIG6_MITMPPTR_Len (9U) +#define PKC_SW_CONFIG6_MITMPPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG6_MITMPPTR PKC_SW_CONFIG6_MITMPPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG7 register ************/ +#define PKC_SW_CONFIG7_WORDLEN_Pos (0U) +#define PKC_SW_CONFIG7_WORDLEN_Len (6U) +#define PKC_SW_CONFIG7_WORDLEN_Msk (0x0000003FU) +#define PKC_SW_CONFIG7_WORDLEN PKC_SW_CONFIG7_WORDLEN_Msk + +/******************* Bit definition for PKC_SW_CONFIG8 register ************/ +#define PKC_SW_CONFIG8_MIKOUT_Pos (0U) +#define PKC_SW_CONFIG8_MIKOUT_Len (13U) +#define PKC_SW_CONFIG8_MIKOUT_Msk (0x00001FFFU) +#define PKC_SW_CONFIG8_MIKOUT PKC_SW_CONFIG8_MIKOUT_Msk + +/******************* Bit definition for PKC_SW_CONFIG9 register ************/ +#define PKC_SW_CONFIG9_DMRNGSEED_Pos (0U) +#define PKC_SW_CONFIG9_DMRNGSEED_Len (32U) +#define PKC_SW_CONFIG9_DMRNGSEED_Msk (0xFFFFFFFFU) +#define PKC_SW_CONFIG9_DMRNGSEED PKC_SW_CONFIG9_DMRNGSEED_Msk + +/******************* Bit definition for PKC_SW_CONFIG10 register ************/ +#define PKC_SW_CONFIG10_BMAPTR_Pos (0U) +#define PKC_SW_CONFIG10_BMAPTR_Len (9U) +#define PKC_SW_CONFIG10_BMAPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG10_BMAPTR PKC_SW_CONFIG10_BMAPTR_Msk + +#define PKC_SW_CONFIG10_BMBPTR_Pos (16U) +#define PKC_SW_CONFIG10_BMBPTR_Len (9U) +#define PKC_SW_CONFIG10_BMBPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG10_BMBPTR PKC_SW_CONFIG10_BMBPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG11 register ************/ +#define PKC_SW_CONFIG11_BMCPTR_Pos (0U) +#define PKC_SW_CONFIG11_BMCPTR_Len (9U) +#define PKC_SW_CONFIG11_BMCPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG11_BMCPTR PKC_SW_CONFIG11_BMCPTR_Msk + +#define PKC_SW_CONFIG11_BAAPTR_Pos (16U) +#define PKC_SW_CONFIG11_BAAPTR_Len (9U) +#define PKC_SW_CONFIG11_BAAPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG11_BAAPTR PKC_SW_CONFIG11_BAAPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG12 register ************/ +#define PKC_SW_CONFIG12_BABPTR_Pos (0U) +#define PKC_SW_CONFIG12_BABPTR_Len (9U) +#define PKC_SW_CONFIG12_BABPTR_Msk (0x000001FFU) +#define PKC_SW_CONFIG12_BABPTR PKC_SW_CONFIG12_BABPTR_Msk + +#define PKC_SW_CONFIG12_BACPTR_Pos (16U) +#define PKC_SW_CONFIG12_BACPTR_Len (9U) +#define PKC_SW_CONFIG12_BACPTR_Msk (0x01FF0000U) +#define PKC_SW_CONFIG12_BACPTR PKC_SW_CONFIG12_BACPTR_Msk + +/******************* Bit definition for PKC_SW_CONFIG13 register ************/ +#define PKC_SW_CONFIG13_RANDSEED_Pos (0U) +#define PKC_SW_CONFIG13_RANDSEED_Len (32U) +#define PKC_SW_CONFIG13_RANDSEED_Msk (0xFFFFFFFFU) +#define PKC_SW_CONFIG13_RANDSEED PKC_SW_CONFIG13_RANDSEED_Msk + +/******************* Bit definition for PKC_INT_STATUS register ************/ +#define PKC_INTSTAT_DONE_Pos (0U) +#define PKC_INTSTAT_DONE_Len (1U) +#define PKC_INTSTAT_DONE_Msk (0x1U << PKC_INTSTAT_DONE_Pos) +#define PKC_INTSTAT_DONE PKC_INTSTAT_DONE_Msk + +#define PKC_INTSTAT_ERR_Pos (1U) +#define PKC_INTSTAT_ERR_Len (1U) +#define PKC_INTSTAT_ERR_Msk (0x1U << PKC_INTSTAT_ERR_Pos) +#define PKC_INTSTAT_ERR PKC_INTSTAT_ERR_Msk + +#define PKC_INTSTAT_BAOVF_Pos (2U) +#define PKC_INTSTAT_BAOVF_Len (1U) +#define PKC_INTSTAT_BAOVF_Msk (0x1U << PKC_INTSTAT_BAOVF_Pos) +#define PKC_INTSTAT_BAOVF PKC_INTSTAT_BAOVF_Msk + +/******************* Bit definition for PKC_INT_ENABLE register ************/ +#define PKC_INTEN_DONE_Pos (0U) +#define PKC_INTEN_DONE_Len (1U) +#define PKC_INTEN_DONE_Msk (0x1U << PKC_INTEN_DONE_Pos) +#define PKC_INTEN_DONE PKC_INTEN_DONE_Msk + +#define PKC_INTEN_ERR_Pos (1U) +#define PKC_INTEN_ERR_Len (1U) +#define PKC_INTEN_ERR_Msk (0x1U << PKC_INTEN_ERR_Pos) +#define PKC_INTEN_ERR PKC_INTEN_ERR_Msk + +#define PKC_INTEN_BAOVF_Pos (2U) +#define PKC_INTEN_BAOVF_Len (1U) +#define PKC_INTEN_BAOVF_Msk (0x1U << PKC_INTEN_BAOVF_Pos) +#define PKC_INTEN_BAOVF PKC_INTEN_BAOVF_Msk + +/******************* Bit definition for PKC_WORK_STATUS register ***********/ +#define PKC_WORKSTAT_BUSY_Pos (0U) +#define PKC_WORKSTAT_BUSY_Len (1U) +#define PKC_WORKSTAT_BUSY_Msk (0x1U << PKC_WORKSTAT_BUSY_Pos) +#define PKC_WORKSTAT_BUSY PKC_WORKSTAT_BUSY_Msk + +/******************* Bit definition for PKC_DUMMY0 register ****************/ +#define PKC_DUMMY0_DUMMY0_Pos (0U) +#define PKC_DUMMY0_DUMMY0_Len (32U) +#define PKC_DUMMY0_DUMMY0_Msk (0xFFFFFFFFU) +#define PKC_DUMMY0_DUMMY0 PKC_DUMMY0_DUMMY0_Msk + +/******************* Bit definition for PKC_DUMMY1 register ****************/ +#define PKC_DUMMY1_DUMMY1_Pos (0U) +#define PKC_DUMMY1_DUMMY1_Len (32U) +#define PKC_DUMMY1_DUMMY1_Msk (0xFFFFFFFFU) +#define PKC_DUMMY1_DUMMY1 PKC_DUMMY1_DUMMY1_Msk + +/******************* Bit definition for PKC_DUMMY2 register ****************/ +#define PKC_DUMMY2_DUMMY2_Pos (0U) +#define PKC_DUMMY2_DUMMY2_Len (32U) +#define PKC_DUMMY2_DUMMY2_Msk (0xFFFFFFFFU) +#define PKC_DUMMY2_DUMMY2 PKC_DUMMY2_DUMMY2_Msk + + +/* ================================================================================================================= */ +/* ================ PWM ================ */ +/* ================================================================================================================= */ + +/******************* Bit definition for PWM_MODE register *******************/ +#define PWM_MODE_EN_Pos (0U) +#define PWM_MODE_EN_Len (1U) +#define PWM_MODE_EN_Msk (0x1U << PWM_MODE_EN_Pos) +#define PWM_MODE_EN PWM_MODE_EN_Msk + +#define PWM_MODE_PAUSE_Pos (1U) +#define PWM_MODE_PAUSE_Len (1U) +#define PWM_MODE_PAUSE_Msk (0x1U << PWM_MODE_PAUSE_Pos) +#define PWM_MODE_PAUSE PWM_MODE_PAUSE_Msk + +#define PWM_MODE_BREATHEN_Pos (2U) +#define PWM_MODE_BREATHEN_Len (1U) +#define PWM_MODE_BREATHEN_Msk (0x1U << PWM_MODE_BREATHEN_Pos) +#define PWM_MODE_BREATHEN PWM_MODE_BREATHEN_Msk + +#define PWM_MODE_DPENA_Pos (3U) +#define PWM_MODE_DPENA_Len (1U) +#define PWM_MODE_DPENA_Msk (0x1U << PWM_MODE_DPENA_Pos) +#define PWM_MODE_DPENA PWM_MODE_DPENA_Msk + +#define PWM_MODE_DPENB_Pos (4U) +#define PWM_MODE_DPENB_Len (1U) +#define PWM_MODE_DPENB_Msk (0x1U << PWM_MODE_DPENB_Pos) +#define PWM_MODE_DPENB PWM_MODE_DPENB_Msk + +#define PWM_MODE_DPENC_Pos (5U) +#define PWM_MODE_DPENC_Len (1U) +#define PWM_MODE_DPENC_Msk (0x1U << PWM_MODE_DPENC_Pos) +#define PWM_MODE_DPENC PWM_MODE_DPENC_Msk + +/******************* Bit definition for PWM_UPDATE register *****************/ +#define PWM_UPDATE_SAG_Pos (0U) +#define PWM_UPDATE_SAG_Len (1U) +#define PWM_UPDATE_SAG_Msk (0x1U << PWM_UPDATE_SAG_Pos) +#define PWM_UPDATE_SAG PWM_UPDATE_SAG_Msk + +#define PWM_UPDATE_SA_Pos (1U) +#define PWM_UPDATE_SA_Len (1U) +#define PWM_UPDATE_SA_Msk (0x1U << PWM_UPDATE_SA_Pos) +#define PWM_UPDATE_SA PWM_UPDATE_SA_Msk + +#define PWM_UPDATE_SSPRD_Pos (8U) +#define PWM_UPDATE_SSPRD_Len (1U) +#define PWM_UPDATE_SSPRD_Msk (0x1U << PWM_UPDATE_SSPRD_Pos) +#define PWM_UPDATE_SSPRD PWM_UPDATE_SSPRD_Msk + +#define PWM_UPDATE_SSCMPA0_Pos (9U) +#define PWM_UPDATE_SSCMPA0_Len (1U) +#define PWM_UPDATE_SSCMPA0_Msk (0x1U << PWM_UPDATE_SSCMPA0_Pos) +#define PWM_UPDATE_SSCMPA0 PWM_UPDATE_SSCMPA0_Msk + +#define PWM_UPDATE_SSCMPA1_Pos (10U) +#define PWM_UPDATE_SSCMPA1_Len (1U) +#define PWM_UPDATE_SSCMPA1_Msk (0x1U << PWM_UPDATE_SSCMPA1_Pos) +#define PWM_UPDATE_SSCMPA1 PWM_UPDATE_SSCMPA1_Msk + +#define PWM_UPDATE_SSCMPB0_Pos (11U) +#define PWM_UPDATE_SSCMPB0_Len (1U) +#define PWM_UPDATE_SSCMPB0_Msk (0x1U << PWM_UPDATE_SSCMPB0_Pos) +#define PWM_UPDATE_SSCMPB0 PWM_UPDATE_SSCMPB0_Msk + +#define PWM_UPDATE_SSCMPB1_Pos (12U) +#define PWM_UPDATE_SSCMPB1_Len (1U) +#define PWM_UPDATE_SSCMPB1_Msk (0x1U << PWM_UPDATE_SSCMPB1_Pos) +#define PWM_UPDATE_SSCMPB1 PWM_UPDATE_SSCMPB1_Msk + +#define PWM_UPDATE_SSCMPC0_Pos (13U) +#define PWM_UPDATE_SSCMPC0_Len (1U) +#define PWM_UPDATE_SSCMPC0_Msk (0x1U << PWM_UPDATE_SSCMPC0_Pos) +#define PWM_UPDATE_SSCMPC0 PWM_UPDATE_SSCMPC0_Msk + +#define PWM_UPDATE_SSCMPC1_Pos (14U) +#define PWM_UPDATE_SSCMPC1_Len (1U) +#define PWM_UPDATE_SSCMPC1_Msk (0x1U << PWM_UPDATE_SSCMPC1_Pos) +#define PWM_UPDATE_SSCMPC1 PWM_UPDATE_SSCMPC1_Msk + +#define PWM_UPDATE_SSPAUSE_Pos (15U) +#define PWM_UPDATE_SSPAUSE_Len (1U) +#define PWM_UPDATE_SSPAUSE_Msk (0x1U << PWM_UPDATE_SSPAUSE_Pos) +#define PWM_UPDATE_SSPAUSE PWM_UPDATE_SSPAUSE_Msk + +#define PWM_UPDATE_SSBRPRD_Pos (16U) +#define PWM_UPDATE_SSBRPRD_Len (1U) +#define PWM_UPDATE_SSBRPRD_Msk (0x1U << PWM_UPDATE_SSBRPRD_Pos) +#define PWM_UPDATE_SSBRPRD PWM_UPDATE_SSBRPRD_Msk + +#define PWM_UPDATE_SSHOLD_Pos (17U) +#define PWM_UPDATE_SSHOLD_Len (1U) +#define PWM_UPDATE_SSHOLD_Msk (0x1U << PWM_UPDATE_SSHOLD_Pos) +#define PWM_UPDATE_SSHOLD PWM_UPDATE_SSHOLD_Msk + +#define PWM_UPDATE_SSAQCTRL_Pos (18U) +#define PWM_UPDATE_SSAQCTRL_Len (1U) +#define PWM_UPDATE_SSAQCTRL_Msk (0x1U << PWM_UPDATE_SSAQCTRL_Pos) +#define PWM_UPDATE_SSAQCTRL PWM_UPDATE_SSAQCTRL_Msk + +/******************* Bit definition for PWM_PRD register ********************/ +#define PWM_PRD_PRD_Pos (0U) +#define PWM_PRD_PRD_Len (32U) +#define PWM_PRD_PRD_Msk (0xFFFFFFFFU) +#define PWM_PRD_PRD PWM_PRD_PRD_Msk + +/******************* Bit definition for PWM_CMPA0 register ******************/ +#define PWM_CMPA0_CMPA0_Pos (0U) +#define PWM_CMPA0_CMPA0_Len (32U) +#define PWM_CMPA0_CMPA0_Msk (0xFFFFFFFFU) +#define PWM_CMPA0_CMPA0 PWM_CMPA0_CMPA0_Msk + +/******************* Bit definition for PWM_CMPA1 register ******************/ +#define PWM_CMPA1_CMPA1_Pos (0U) +#define PWM_CMPA1_CMPA1_Len (32U) +#define PWM_CMPA1_CMPA1_Msk (0xFFFFFFFFU) +#define PWM_CMPA1_CMPA1 PWM_CMPA1_CMPA1_Msk + +/******************* Bit definition for PWM_CMPB0 register ******************/ +#define PWM_CMPB0_CMPB0_Pos (0U) +#define PWM_CMPB0_CMPB0_Len (32U) +#define PWM_CMPB0_CMPB0_Msk (0xFFFFFFFFU) +#define PWM_CMPB0_CMPB0 PWM_CMPB0_CMPB0_Msk + +/******************* Bit definition for PWM_CMPB1 register ******************/ +#define PWM_CMPB1_CMPB1_Pos (0U) +#define PWM_CMPB1_CMPB1_Len (32U) +#define PWM_CMPB1_CMPB1_Msk (0xFFFFFFFFU) +#define PWM_CMPB1_CMPB1 PWM_CMPB1_CMPB1_Msk + +/******************* Bit definition for PWM_CMPC0 register ******************/ +#define PWM_CMPC0_CMPC0_Pos (0U) +#define PWM_CMPC0_CMPC0_Len (32U) +#define PWM_CMPC0_CMPC0_Msk (0xFFFFFFFFU) +#define PWM_CMPC0_CMPC0 PWM_CMPC0_CMPC0_Msk + +/******************* Bit definition for PWM_CMPC1 register ******************/ +#define PWM_CMPC1_CMPC1_Pos (0U) +#define PWM_CMPC1_CMPC1_Len (32U) +#define PWM_CMPC1_CMPC1_Msk (0xFFFFFFFFU) +#define PWM_CMPC1_CMPC1 PWM_CMPC1_CMPC1_Msk + +/******************* Bit definition for PWM_AQCTRL register *****************/ +#define PWM_AQCTRL_A0_Pos (0U) +#define PWM_AQCTRL_A0_Len (2U) +#define PWM_AQCTRL_A0_Msk (0x3U << PWM_AQCTRL_A0_Pos) +#define PWM_AQCTRL_A0 PWM_AQCTRL_A0_Msk + +#define PWM_AQCTRL_A1_Pos (2U) +#define PWM_AQCTRL_A1_Len (2U) +#define PWM_AQCTRL_A1_Msk (0x3U << PWM_AQCTRL_A1_Pos) +#define PWM_AQCTRL_A1 PWM_AQCTRL_A1_Msk + +#define PWM_AQCTRL_B0_Pos (4U) +#define PWM_AQCTRL_B0_Len (2U) +#define PWM_AQCTRL_B0_Msk (0x3U << PWM_AQCTRL_B0_Pos) +#define PWM_AQCTRL_B0 PWM_AQCTRL_B0_Msk + +#define PWM_AQCTRL_B1_Pos (6U) +#define PWM_AQCTRL_B1_Len (2U) +#define PWM_AQCTRL_B1_Msk (0x3U << PWM_AQCTRL_B1_Pos) +#define PWM_AQCTRL_B1 PWM_AQCTRL_B1_Msk + +#define PWM_AQCTRL_C0_Pos (8U) +#define PWM_AQCTRL_C0_Len (2U) +#define PWM_AQCTRL_C0_Msk (0x3U << PWM_AQCTRL_C0_Pos) +#define PWM_AQCTRL_C0 PWM_AQCTRL_C0_Msk + +#define PWM_AQCTRL_C1_Pos (10U) +#define PWM_AQCTRL_C1_Len (2U) +#define PWM_AQCTRL_C1_Msk (0x3U << PWM_AQCTRL_C1_Pos) +#define PWM_AQCTRL_C1 PWM_AQCTRL_C1_Msk + +/******************* Bit definition for PWM_BRPRD register ******************/ +#define PWM_BRPRD_BRPRD_Pos (0U) +#define PWM_BRPRD_BRPRD_Len (32U) +#define PWM_BRPRD_BRPRD_Msk (0xFFFFFFFFU) +#define PWM_BRPRD_BRPRD PWM_BRPRD_BRPRD_Msk + +/******************* Bit definition for PWM_HOLD register *******************/ +#define PWM_HOLD_HOLD_Pos (0U) +#define PWM_HOLD_HOLD_Len (24U) +#define PWM_HOLD_HOLD_Msk (0x00FFFFFFU) +#define PWM_HOLD_HOLD PWM_HOLD_HOLD_Msk + + +/* ================================================================================================================= */ +/* ================ SSI ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for SSI_CTRL0 register ******************/ +#define SSI_CTRL0_SSTEN_Pos (24U) +#define SSI_CTRL0_SSTEN_Len (1U) +#define SSI_CTRL0_SSTEN_Msk (0x1U << SSI_CTRL0_SSTEN_Pos) +#define SSI_CTRL0_SSTEN SSI_CTRL0_SSTEN_Msk + +#define SSI_CTRL0_SPIFRF_Pos (21U) +#define SSI_CTRL0_SPIFRF_Len (2U) +#define SSI_CTRL0_SPIFRF_Msk (0x3U << SSI_CTRL0_SPIFRF_Pos) +#define SSI_CTRL0_SPIFRF SSI_CTRL0_SPIFRF_Msk + +#define SSI_CTRL0_DFS32_Pos (16U) +#define SSI_CTRL0_DFS32_Len (5U) +#define SSI_CTRL0_DFS32_Msk (0x1FU << SSI_CTRL0_DFS32_Pos) +#define SSI_CTRL0_DFS32 SSI_CTRL0_DFS32_Msk + +#define SSI_CTRL0_CFS_Pos (12U) +#define SSI_CTRL0_CFS_Len (4U) +#define SSI_CTRL0_CFS_Msk (0xFU << SSI_CTRL0_CFS_Pos) +#define SSI_CTRL0_CFS SSI_CTRL0_CFS_Msk + +#define SSI_CTRL0_SRL_Pos (11U) +#define SSI_CTRL0_SRL_Len (1U) +#define SSI_CTRL0_SRL_Msk (0x1U << SSI_CTRL0_SRL_Pos) +#define SSI_CTRL0_SRL SSI_CTRL0_SRL_Msk + +#define SSI_CTRL0_SLVOE_Pos (10U) +#define SSI_CTRL0_SLVOE_Len (1U) +#define SSI_CTRL0_SLVOE_Msk (0x1U << SSI_CTRL0_SLVOE_Pos) +#define SSI_CTRL0_SLVOE SSI_CTRL0_SLVOE_Msk + +#define SSI_CTRL0_TMOD_Pos (8U) +#define SSI_CTRL0_TMOD_Len (2U) +#define SSI_CTRL0_TMOD_Msk (0x3U << SSI_CTRL0_TMOD_Pos) +#define SSI_CTRL0_TMOD SSI_CTRL0_TMOD_Msk + +#define SSI_CTRL0_SCPOL_Pos (7U) +#define SSI_CTRL0_SCPOL_Len (1U) +#define SSI_CTRL0_SCPOL_Msk (0x1U << SSI_CTRL0_SCPOL_Pos) +#define SSI_CTRL0_SCPOL SSI_CTRL0_SCPOL_Msk + +#define SSI_CTRL0_SCPHA_Pos (6U) +#define SSI_CTRL0_SCPHA_Len (1U) +#define SSI_CTRL0_SCPHA_Msk (0x1U << SSI_CTRL0_SCPHA_Pos) +#define SSI_CTRL0_SCPHA SSI_CTRL0_SCPHA_Msk + +#define SSI_CTRL0_FRF_Pos (4U) +#define SSI_CTRL0_FRF_Len (2U) +#define SSI_CTRL0_FRF_Msk (0x3U << SSI_CTRL0_FRF_Pos) +#define SSI_CTRL0_FRF SSI_CTRL0_FRF_Msk + +#define SSI_CTRL1_NDF_Pos (0U) +#define SSI_CTRL1_NDF_Len (16U) +#define SSI_CTRL1_NDF_Msk (0xFFFFU << SSI_CTRL1_NDF_Pos) +#define SSI_CTRL1_NDF SSI_CTRL1_NDF_Msk + +/******************* Bit definition for SSI_SSIEN register ******************/ +#define SSI_SSIEN_EN_Pos (0U) +#define SSI_SSIEN_EN_Len (1U) +#define SSI_SSIEN_EN_Msk (0x1U << SSI_SSIEN_EN_Pos) +#define SSI_SSIEN_EN SSI_SSIEN_EN_Msk + +/******************* Bit definition for SSI_MWC register ********************/ +#define SSI_MWC_MHS_Pos (2U) +#define SSI_MWC_MHS_Len (1U) +#define SSI_MWC_MHS_Msk (0x1U << SSI_MWC_MHS_Pos) +#define SSI_MWC_MHS SSI_MWC_MHS_Msk + +#define SSI_MWC_MDD_Pos (1U) +#define SSI_MWC_MDD_Len (1U) +#define SSI_MWC_MDD_Msk (0x1U << SSI_MWC_MDD_Pos) +#define SSI_MWC_MDD SSI_MWC_MDD_Msk + +#define SSI_MWC_MWMOD_Pos (0U) +#define SSI_MWC_MWMOD_Len (1U) +#define SSI_MWC_MWMOD_Msk (0x1U << SSI_MWC_MWMOD_Pos) +#define SSI_MWC_MWMOD SSI_MWC_MWMOD_Msk + +/******************* Bit definition for SSI_SE register *********************/ +#define SSI_SE_SLAVE1_Pos (1U) +#define SSI_SE_SLAVE1_Len (1U) +#define SSI_SE_SLAVE1_Msk (0x1U << SSI_SE_SLAVE1_Pos) +#define SSI_SE_SLAVE1 SSI_SE_SLAVE1_Msk + +#define SSI_SE_SLAVE0_Pos (0U) +#define SSI_SE_SLAVE0_Len (1U) +#define SSI_SE_SLAVE0_Msk (0x1U << SSI_SE_SLAVE0_Pos) +#define SSI_SE_SLAVE0 SSI_SE_SLAVE0_Msk + +/******************* Bit definition for SSI_BAUD register *******************/ +#define SSI_BAUD_SCKDIV_Pos (0U) +#define SSI_BAUD_SCKDIV_Len (16U) +#define SSI_BAUD_SCKDIV_Msk (0xFFFFUL << SSI_BAUD_SCKDIV_Pos) +#define SSI_BAUD_SCKDIV SSI_BAUD_SCKDIV_Msk + +/******************* Bit definition for SSI_TXFTL register ******************/ +#define SSI_TXFTL_TFT_Pos (0U) +#define SSI_TXFTL_TFT_Len (3U) +#define SSI_TXFTL_TFT_Msk (0x7U << SSI_TXFTL_TFT_Pos) +#define SSI_TXFTL_TFT SSI_TXFTL_TFT_Msk + +/******************* Bit definition for SSI_RXFTL register ******************/ +#define SSI_RXFTL_RFT_Pos (0U) +#define SSI_RXFTL_RFT_Len (3U) +#define SSI_RXFTL_RFT_Msk (0x7U << SSI_RXFTL_RFT_Pos) +#define SSI_RXFTL_RFT SSI_RXFTL_RFT_Msk + +/******************* Bit definition for SSI_TXFL register *******************/ +#define SSI_TXFL_TXTFL_Pos (0U) +#define SSI_TXFL_TXTFL_Len (4U) +#define SSI_TXFL_TXTFL_Msk (0xFU << SSI_TXFL_TXTFL_Pos) +#define SSI_TXFL_TXTFL SSI_TXFL_TXTFL_Msk + +/******************* Bit definition for SSI_RXFL register *******************/ +#define SSI_RXFL_RXTFL_Pos (0U) +#define SSI_RXFL_RXTFL_Len (4U) +#define SSI_RXFL_RXTFL_Msk (0xFU << SSI_RXFL_RXTFL_Pos) +#define SSI_RXFL_RXTFL SSI_RXFL_RXTFL_Msk + +/******************* Bit definition for SSI_STAT register *******************/ +#define SSI_STAT_DCOL_Pos (6U) +#define SSI_STAT_DCOL_Len (1U) +#define SSI_STAT_DCOL_Msk (0x1U << SSI_STAT_DCOL_Pos) +#define SSI_STAT_DCOL SSI_STAT_DCOL_Msk + +#define SSI_STAT_TXE_Pos (5U) +#define SSI_STAT_TXE_Len (1U) +#define SSI_STAT_TXE_Msk (0x1U << SSI_STAT_TXE_Pos) +#define SSI_STAT_TXE SSI_STAT_TXE_Msk + +#define SSI_STAT_RFF_Pos (4U) +#define SSI_STAT_RFF_Len (1U) +#define SSI_STAT_RFF_Msk (0x1U << SSI_STAT_RFF_Pos) +#define SSI_STAT_RFF SSI_STAT_RFF_Msk + +#define SSI_STAT_RFNE_Pos (3U) +#define SSI_STAT_RFNE_Len (1U) +#define SSI_STAT_RFNE_Msk (0x1U << SSI_STAT_RFNE_Pos) +#define SSI_STAT_RFNE SSI_STAT_RFNE_Msk + +#define SSI_STAT_TFE_Pos (2U) +#define SSI_STAT_TFE_Len (1U) +#define SSI_STAT_TFE_Msk (0x1U << SSI_STAT_TFE_Pos) +#define SSI_STAT_TFE SSI_STAT_TFE_Msk + +#define SSI_STAT_TFNF_Pos (1U) +#define SSI_STAT_TFNF_Len (1U) +#define SSI_STAT_TFNF_Msk (0x1U << SSI_STAT_TFNF_Pos) +#define SSI_STAT_TFNF SSI_STAT_TFNF_Msk + +#define SSI_STAT_BUSY_Pos (0U) +#define SSI_STAT_BUSY_Len (1U) +#define SSI_STAT_BUSY_Msk (0x1U << SSI_STAT_BUSY_Pos) +#define SSI_STAT_BUSY SSI_STAT_BUSY_Msk + +/******************* Bit definition for SSI_INTMASK register ****************/ +#define SSI_INTMASK_MSTIM_Pos (5U) +#define SSI_INTMASK_MSTIM_Len (1U) +#define SSI_INTMASK_MSTIM_Msk (0x1U << SSI_INTMASK_MSTIM_Pos) +#define SSI_INTMASK_MSTIM SSI_INTMASK_MSTIM_Msk + +#define SSI_INTMASK_RXFIM_Pos (4U) +#define SSI_INTMASK_RXFIM_Len (1U) +#define SSI_INTMASK_RXFIM_Msk (0x1U << SSI_INTMASK_RXFIM_Pos) +#define SSI_INTMASK_RXFIM SSI_INTMASK_RXFIM_Msk + +#define SSI_INTMASK_RXOIM_Pos (3U) +#define SSI_INTMASK_RXOIM_Len (1U) +#define SSI_INTMASK_RXOIM_Msk (0x1U << SSI_INTMASK_RXOIM_Pos) +#define SSI_INTMASK_RXOIM SSI_INTMASK_RXOIM_Msk + +#define SSI_INTMASK_RXUIM_Pos (2U) +#define SSI_INTMASK_RXUIM_Len (1U) +#define SSI_INTMASK_RXUIM_Msk (0x1U << SSI_INTMASK_RXUIM_Pos) +#define SSI_INTMASK_RXUIM SSI_INTMASK_RXUIM_Msk + +#define SSI_INTMASK_TXOIM_Pos (1U) +#define SSI_INTMASK_TXOIM_Len (1U) +#define SSI_INTMASK_TXOIM_Msk (0x1U << SSI_INTMASK_TXOIM_Pos) +#define SSI_INTMASK_TXOIM SSI_INTMASK_TXOIM_Msk + +#define SSI_INTMASK_TXEIM_Pos (0U) +#define SSI_INTMASK_TXEIM_Len (1U) +#define SSI_INTMASK_TXEIM_Msk (0x1U << SSI_INTMASK_TXEIM_Pos) +#define SSI_INTMASK_TXEIM SSI_INTMASK_TXEIM_Msk + +/******************* Bit definition for SSI_INTSTAT register ****************/ +#define SSI_INTSTAT_MSTIS_Pos (5U) +#define SSI_INTSTAT_MSTIS_Len (1U) +#define SSI_INTSTAT_MSTIS_Msk (0x1U << SSI_INTSTAT_MSTIS_Pos) +#define SSI_INTSTAT_MSTIS SSI_INTSTAT_MSTIS_Msk + +#define SSI_INTSTAT_RXFIS_Pos (4U) +#define SSI_INTSTAT_RXFIS_Len (1U) +#define SSI_INTSTAT_RXFIS_Msk (0x1U << SSI_INTSTAT_RXFIS_Pos) +#define SSI_INTSTAT_RXFIS SSI_INTSTAT_RXFIS_Msk + +#define SSI_INTSTAT_RXOIS_Pos (3U) +#define SSI_INTSTAT_RXOIS_Len (1U) +#define SSI_INTSTAT_RXOIS_Msk (0x1U << SSI_INTSTAT_RXOIS_Pos) +#define SSI_INTSTAT_RXOIS SSI_INTSTAT_RXOIS_Msk + +#define SSI_INTSTAT_RXUIS_Pos (2U) +#define SSI_INTSTAT_RXUIS_Len (1U) +#define SSI_INTSTAT_RXUIS_Msk (0x1U << SSI_INTSTAT_RXUIS_Pos) +#define SSI_INTSTAT_RXUIS SSI_INTSTAT_RXUIS_Msk + +#define SSI_INTSTAT_TXOIS_Pos (1U) +#define SSI_INTSTAT_TXOIS_Len (1U) +#define SSI_INTSTAT_TXOIS_Msk (0x1U << SSI_INTSTAT_TXOIS_Pos) +#define SSI_INTSTAT_TXOIS SSI_INTSTAT_TXOIS_Msk + +#define SSI_INTSTAT_TXEIS_Pos (0U) +#define SSI_INTSTAT_TXEIS_Len (1U) +#define SSI_INTSTAT_TXEIS_Msk (0x1U << SSI_INTSTAT_TXEIS_Pos) +#define SSI_INTSTAT_TXEIS SSI_INTSTAT_TXEIS_Msk + +/******************* Bit definition for SSI_RAW_INTSTAT register ************/ +#define SSI_RAW_INTSTAT_MSTIR_Pos (5U) +#define SSI_RAW_INTSTAT_MSTIR_Len (1U) +#define SSI_RAW_INTSTAT_MSTIR_Msk (0x1U << SSI_RAW_INTSTAT_MSTIR_Pos) +#define SSI_RAW_INTSTAT_MSTIR SSI_RAW_INTSTAT_MSTIR_Msk + +#define SSI_RAW_INTSTAT_RXFIR_Pos (4U) +#define SSI_RAW_INTSTAT_RXFIR_Len (1U) +#define SSI_RAW_INTSTAT_RXFIR_Msk (0x1U << SSI_RAW_INTSTAT_RXFIR_Pos) +#define SSI_RAW_INTSTAT_RXFIR SSI_RAW_INTSTAT_RXFIR_Msk + +#define SSI_RAW_INTSTAT_RXOIR_Pos (3U) +#define SSI_RAW_INTSTAT_RXOIR_Len (1U) +#define SSI_RAW_INTSTAT_RXOIR_Msk (0x1U << SSI_RAW_INTSTAT_RXOIR_Pos) +#define SSI_RAW_INTSTAT_RXOIR SSI_RAW_INTSTAT_RXOIR_Msk + +#define SSI_RAW_INTSTAT_RXUIR_Pos (2U) +#define SSI_RAW_INTSTAT_RXUIR_Len (1U) +#define SSI_RAW_INTSTAT_RXUIR_Msk (0x1U << SSI_RAW_INTSTAT_RXUIR_Pos) +#define SSI_RAW_INTSTAT_RXUIR SSI_RAW_INTSTAT_RXUIR_Msk + +#define SSI_RAW_INTSTAT_TXOIR_Pos (1U) +#define SSI_RAW_INTSTAT_TXOIR_Len (1U) +#define SSI_RAW_INTSTAT_TXOIR_Msk (0x1U << SSI_RAW_INTSTAT_TXOIR_Pos) +#define SSI_RAW_INTSTAT_TXOIR SSI_RAW_INTSTAT_TXOIR_Msk + +#define SSI_RAW_INTSTAT_TXEIR_Pos (0U) +#define SSI_RAW_INTSTAT_TXEIR_Len (1U) +#define SSI_RAW_INTSTAT_TXEIR_Msk (0x1U << SSI_RAW_INTSTAT_TXEIR_Pos) +#define SSI_RAW_INTSTAT_TXEIR SSI_RAW_INTSTAT_TXEIR_Msk + +/******************* Bit definition for SSI_TXOIC register ******************/ +#define SSI_TXOIC_TXOIC_Pos (0U) +#define SSI_TXOIC_TXOIC_Len (1U) +#define SSI_TXOIC_TXOIC_Msk (0x1U << SSI_TXOIC_TXOIC_Pos) +#define SSI_TXOIC_TXOIC SSI_TXOIC_TXOIC_Msk + +/******************* Bit definition for SSI_RXOIC register ******************/ +#define SSI_RXOIC_RXOIC_Pos (0U) +#define SSI_RXOIC_RXOIC_Len (1U) +#define SSI_RXOIC_RXOIC_Msk (0x1U << SSI_RXOIC_RXOIC_Pos) +#define SSI_RXOIC_RXOIC SSI_RXOIC_RXOIC_Msk + +#define SSI_RXUIC_RXUIC_Pos (0U) +#define SSI_RXUIC_RXUIC_Len (1U) +#define SSI_RXUIC_RXUIC_Msk (0x1U << SSI_RXUIC_RXUIC_Pos) +#define SSI_RXUIC_RXUIC SSI_RXUIC_RXUIC_Msk + +/******************* Bit definition for SSI_MSTIC register ******************/ +#define SSI_MSTIC_MSTIC_Pos (0U) +#define SSI_MSTIC_MSTIC_Len (1U) +#define SSI_MSTIC_MSTIC_Msk (0x1U << SSI_MSTIC_MSTIC_Pos) +#define SSI_MSTIC_MSTIC SSI_MSTIC_MSTIC_Msk + +/******************* Bit definition for SSI_INTCLR register ******************/ +#define SSI_INTCLR_INTCLR_Pos (0U) +#define SSI_INTCLR_INTCLR_Len (1U) +#define SSI_INTCLR_INTCLR_Msk (0x1U << SSI_INTCLR_INTCLR_Pos) +#define SSI_INTCLR_INTCLR SSI_INTCLR_INTCLR_Msk + +/******************* Bit definition for SSI_DMAC register *******************/ +#define SSI_DMAC_TDMAE_Pos (1U) +#define SSI_DMAC_TDMAE_Len (1U) +#define SSI_DMAC_TDMAE_Msk (0x1U << SSI_DMAC_TDMAE_Pos) +#define SSI_DMAC_TDMAE SSI_DMAC_TDMAE_Msk + +#define SSI_DMAC_RDMAE_Pos (0U) +#define SSI_DMAC_RDMAE_Len (1U) +#define SSI_DMAC_RDMAE_Msk (0x1U << SSI_DMAC_RDMAE_Pos) +#define SSI_DMAC_RDMAE SSI_DMAC_RDMAE_Msk + +/******************* Bit definition for SSI_DMATDL register *****************/ +#define SSI_DMATDL_DMATDL_Pos (0U) +#define SSI_DMATDL_DMATDL_Len (4U) +#define SSI_DMATDL_DMATDL_Msk (0xFU << SSI_DMATDL_DMATDL_Pos) +#define SSI_DMATDL_DMATDL SSI_DMATDL_DMATDL_Msk + +#define SSI_DMARDL_DMARDL_Pos (0U) +#define SSI_DMARDL_DMARDL_Len (4U) +#define SSI_DMARDL_DMARDL_Msk (0xFU << SSI_DMARDL_DMARDL_Pos) +#define SSI_DMARDL_DMARDL SSI_DMARDL_DMARDL_Msk + +/******************* Bit definition for SSI_IDCODE register *****************/ +#define SSI_IDCODE_ID_Pos (0U) +#define SSI_IDCODE_ID_Len (32U) +#define SSI_IDCODE_ID_Msk (0xFFFFFFFFU) +#define SSI_IDCODE_ID SSI_IDCODE_ID_Msk + +/******************* Bit definition for SSI_COMP register *******************/ +#define SSI_COMP_VERSION_Pos (0U) +#define SSI_COMP_VERSION_Len (32U) +#define SSI_COMP_VERSION_Msk (0xFFFFFFFFU) +#define SSI_COMP_VERSION SSI_COMP_VERSION_Msk + +/******************* Bit definition for SSI_DATA register *******************/ +#define SSI_DATA_REG_Pos (0U) +#define SSI_DATA_REG_Len (32U) +#define SSI_DATA_REG_Msk (0xFFFFFFFFU) +#define SSI_DATA_REG SSI_DATA_REG_Msk + +/******************* Bit definition for SSI_RX register *********************/ +#define SSI_RX_SAMPLEDLY_Pos (0U) +#define SSI_RX_SAMPLEDLY_Len (8U) +#define SSI_RX_SAMPLEDLY_Msk (0xFFU << SSI_RX_SAMPLEDLY_Pos) +#define SSI_RX_SAMPLEDLY SSI_RX_SAMPLEDLY_Msk + +/******************* Bit definition for SSI_SCTRL0 register *****************/ +#define SSI_SCTRL0_WAITCYCLES_Pos (11U) +#define SSI_SCTRL0_WAITCYCLES_Len (5U) +#define SSI_SCTRL0_WAITCYCLES_Msk (0x1FU << SSI_SCTRL0_WAITCYCLES_Pos) +#define SSI_SCTRL0_WAITCYCLES SSI_SCTRL0_WAITCYCLES_Msk + +#define SSI_SCTRL0_INSTL_Pos (8U) +#define SSI_SCTRL0_INSTL_Len (2U) +#define SSI_SCTRL0_INSTL_Msk (0x03U << SSI_SCTRL0_INSTL_Pos) +#define SSI_SCTRL0_INSTL SSI_SCTRL0_INSTL_Msk + +#define SSI_SCTRL0_ADDRL_Pos (2U) +#define SSI_SCTRL0_ADDRL_Len (4U) +#define SSI_SCTRL0_ADDRL_Msk (0x0FU << SSI_SCTRL0_ADDRL_Pos) +#define SSI_SCTRL0_ADDRL SSI_SCTRL0_ADDRL_Msk + +#define SSI_SCTRL0_TRANSTYPE_Pos (0U) +#define SSI_SCTRL0_TRANSTYPE_Len (2U) +#define SSI_SCTRL0_TRANSTYPE_Msk (0x03U << SSI_SCTRL0_TRANSTYPE_Pos) +#define SSI_SCTRL0_TRANSTYPE SSI_SCTRL0_TRANSTYPE_Msk + + +/* ================================================================================================================= */ +/* ================ TIMER ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for TIMER_CTRL register *******************/ +#define TIMER_CTRL_INTEN_Pos (3U) +#define TIMER_CTRL_INTEN_Len (1U) +#define TIMER_CTRL_INTEN_Msk (0x1U << TIMER_CTRL_INTEN_Pos) +#define TIMER_CTRL_INTEN TIMER_CTRL_INTEN_Msk + +#define TIMER_CTRL_EN_Pos (0U) +#define TIMER_CTRL_EN_Len (1U) +#define TIMER_CTRL_EN_Msk (0x1U << TIMER_CTRL_EN_Pos) +#define TIMER_CTRL_EN TIMER_CTRL_EN_Msk + +/******************* Bit definition for TIMER_VALUE register ******************/ +#define TIMER_VALUE_VALUE_Pos (0U) +#define TIMER_VALUE_VALUE_Len (32U) +#define TIMER_VALUE_VALUE_Msk (0xFFFFFFFFU) +#define TIMER_VALUE_VALUE TIMER_VALUE_VALUE_Msk + +/******************* Bit definition for TIMER_RELOAD register *****************/ +#define TIMER_RELOAD_RELOAD_Pos (0U) +#define TIMER_RELOAD_RELOAD_Len (32U) +#define TIMER_RELOAD_RELOAD_Msk (0xFFFFFFFFU) +#define TIMER_RELOAD_RELOAD TIMER_RELOAD_RELOAD_Msk + +/******************* Bit definition for TIMER_RELOAD register *****************/ +#define TIMER_INT_STAT_Pos (0U) +#define TIMER_INT_STAT_Len (1U) +#define TIMER_INT_STAT_Msk (0x1U << TIMER_INT_STAT_Pos) +#define TIMER_INT_STAT TIMER_INT_STAT_Msk + + +/* ================================================================================================================= */ +/* ================ UART ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for UART_RBR register *******************/ +#define UART_RBR_RBR_Pos (0U) +#define UART_RBR_RBR_Len (8U) +#define UART_RBR_RBR_Msk (0xFFU << UART_RBR_RBR_Pos) +#define UART_RBR_RBR UART_RBR_RBR_Msk /**< Receive Buffer Register */ + +/******************* Bit definition for UART_DLL register *******************/ +#define UART_DLL_DLL_Pos (0U) +#define UART_DLL_DLL_Len (8U) +#define UART_DLL_DLL_Msk (0xFFU << UART_DLL_DLL_Pos) +#define UART_DLL_DLL UART_DLL_DLL_Msk /**< Divisor Latch (Low) */ + +/******************* Bit definition for UART_THR register *******************/ +#define UART_THR_THR_Pos (0U) +#define UART_THR_THR_Len (8U) +#define UART_THR_THR_Msk (0xFFU << UART_THR_THR_Pos) +#define UART_THR_THR UART_THR_THR_Msk /**< Transmit Holding Register */ + +/******************* Bit definition for UART_DLH register *******************/ +#define UART_DLH_DLH_Pos (0U) +#define UART_DLH_DLH_Len (8U) +#define UART_DLH_DLH_Msk (0xFFU << UART_DLH_DLH_Pos) +#define UART_DLH_DLH UART_DLH_DLH_Msk /**< Divisor Latch (High) */ + +/******************* Bit definition for UART_IER register *******************/ +#define UART_IER_PTIME_Pos (7U) +#define UART_IER_PTIME_Len (1U) +#define UART_IER_PTIME_Msk (0x1U << UART_IER_PTIME_Pos) +#define UART_IER_PTIME UART_IER_PTIME_Msk /**< Programmable THRE Interrupt Mode Enable */ + +#define UART_IER_ELCOLR_Pos (4U) +#define UART_IER_ELCOLR_Len (1U) +#define UART_IER_ELCOLR_Msk (0x1U << UART_IER_ELCOLR_Pos) +#define UART_IER_ELCOLR UART_IER_ELCOLR_Msk /**< Enable Auto Clear LSR Register by read RBR/LSR, read only */ + +#define UART_IER_EDSSI_Pos (3U) +#define UART_IER_EDSSI_Len (1U) +#define UART_IER_EDSSI_Msk (0x1U << UART_IER_EDSSI_Pos) +#define UART_IER_EDSSI UART_IER_EDSSI_Msk /**< Enable Modem Status Interrupt */ + +#define UART_IER_ERLS_Pos (2U) +#define UART_IER_ERLS_Len (1U) +#define UART_IER_ERLS_Msk (0x1U << UART_IER_ERLS_Pos) +#define UART_IER_ERLS UART_IER_ERLS_Msk /**< Enable Receiver Line Status Interrupt */ + +#define UART_IER_ETBEI_Pos (1U) +#define UART_IER_ETBEI_Len (1U) +#define UART_IER_ETBEI_Msk (0x1U << UART_IER_ETBEI_Pos) +#define UART_IER_ETBEI UART_IER_ETBEI_Msk /**< Enable Transmit Holding Register Empty Interrupt */ + +#define UART_IER_ERBFI_Pos (0U) +#define UART_IER_ERBFI_Len (1U) +#define UART_IER_ERBFI_Msk (0x1U << UART_IER_ERBFI_Pos) +#define UART_IER_ERBFI UART_IER_ERBFI_Msk /**< Enable Received Data Available Interrupt */ + +/******************* Bit definition for UART_FCR register *******************/ +#define UART_TXFIFO_SIZE 128 +#define UART_RXFIFO_SIZE 128 + +#define UART_FCR_RT_Pos (6U) +#define UART_FCR_RT_Len (2U) +#define UART_FCR_RT_Msk (0x3U << UART_FCR_RT_Pos) +#define UART_FCR_RT UART_FCR_RT_Msk /**< RCVR Trigger */ +#define UART_FCR_RT_CHAR_1 (0x0U << UART_FCR_RT_Pos) /**< RX FIFO 1 Char */ +#define UART_FCR_RT_QUARTER_FULL (0x1U << UART_FCR_RT_Pos) /**< RX FIFO Quater Full*/ +#define UART_FCR_RT_HALF_FULL (0x2U << UART_FCR_RT_Pos) /**< RX FIFO Half Full */ +#define UART_FCR_RT_FULL_2 (0x3U << UART_FCR_RT_Pos) /**< RX FIFO 2 less than Full */ + +#define UART_FCR_TET_Pos (4U) +#define UART_FCR_TET_Len (2U) +#define UART_FCR_TET_Msk (0x3U << UART_FCR_TET_Pos) +#define UART_FCR_TET UART_FCR_TET_Msk /**< TX Empty Trigger */ +#define UART_FCR_TET_EMPTY (0x0U << UART_FCR_TET_Pos) /**< TX FIFO Empty */ +#define UART_FCR_TET_CHAR_2 (0x1U << UART_FCR_TET_Pos) /**< TX FIFO 2 chars */ +#define UART_FCR_TET_QUARTER_FULL (0x2U << UART_FCR_TET_Pos) /**< TX FIFO Quater Full */ +#define UART_FCR_TET_HALF_FULL (0x3U << UART_FCR_TET_Pos) /**< TX FIFO Half Full */ + +#define UART_FCR_XFIFOR_Pos (2U) +#define UART_FCR_XFIFOR_Len (1U) +#define UART_FCR_XFIFOR_Msk (0x1U << UART_FCR_XFIFOR_Pos) +#define UART_FCR_XFIFOR UART_FCR_XFIFOR_Msk /**< XMIT FIFO Reset */ + +#define UART_FCR_RFIFOR_Pos (1U) +#define UART_FCR_RFIFOR_Len (1U) +#define UART_FCR_RFIFOR_Msk (0x1U << UART_FCR_RFIFOR_Pos) +#define UART_FCR_RFIFOR UART_FCR_RFIFOR_Msk /**< RCVR FIFO Reset */ + +#define UART_FCR_FIFOE_Pos (0U) +#define UART_FCR_FIFOE_Len (1U) +#define UART_FCR_FIFOE_Msk (0x1U << UART_FCR_FIFOE_Pos) +#define UART_FCR_FIFOE UART_FCR_FIFOE_Msk /**< FIFO Enable */ + +/******************* Bit definition for UART_IIR register *******************/ +#define UART_IIR_IID_Pos (0U) +#define UART_IIR_IID_Len (4U) +#define UART_IIR_IID_Msk (0xFU << UART_IIR_IID_Pos) +#define UART_IIR_IID UART_IIR_IID_Msk /**< Interrupt ID */ +#define UART_IIR_IID_MS (0x0U << UART_IIR_IID_Pos) /**< Modem Status */ +#define UART_IIR_IID_NIP (0x1U << UART_IIR_IID_Pos) /**< No Interrupt Pending */ +#define UART_IIR_IID_THRE (0x2U << UART_IIR_IID_Pos) /**< THR Empty */ +#define UART_IIR_IID_RDA (0x4U << UART_IIR_IID_Pos) /**< Received Data Available */ +#define UART_IIR_IID_RLS (0x6U << UART_IIR_IID_Pos) /**< Receiver Line Status */ +#define UART_IIR_IID_CTO (0xCU << UART_IIR_IID_Pos) /**< Character Timeout */ + +/******************* Bit definition for UART_LCR register *******************/ +#define UART_LCR_DLAB_Pos (7U) +#define UART_LCR_DLAB_Len (1U) +#define UART_LCR_DLAB_Msk (0x1U << UART_LCR_DLAB_Pos) +#define UART_LCR_DLAB UART_LCR_DLAB_Msk /**< Divisor Latch Access */ + +#define UART_LCR_BC_Pos (6U) +#define UART_LCR_BC_Len (1U) +#define UART_LCR_BC_Msk (0x1U << UART_LCR_BC_Pos) +#define UART_LCR_BC UART_LCR_BC_Msk /**< Break Control */ + +#define UART_LCR_PARITY_Pos (3U) +#define UART_LCR_PARITY_Len (3U) +#define UART_LCR_PARITY_Msk (0x7U << UART_LCR_PARITY_Pos) +#define UART_LCR_PARITY UART_LCR_PARITY_Msk /**< Parity, SP,EPS,PEN bits */ +#define UART_LCR_PARITY_NONE (0x0U << UART_LCR_PARITY_Pos) /**< Parity none */ +#define UART_LCR_PARITY_ODD (0x1U << UART_LCR_PARITY_Pos) /**< Parity odd */ +#define UART_LCR_PARITY_EVEN (0x3U << UART_LCR_PARITY_Pos) /**< Parity even */ +#define UART_LCR_PARITY_SP0 (0x5U << UART_LCR_PARITY_Pos) /**< Parity stick 0 */ +#define UART_LCR_PARITY_SP1 (0x7U << UART_LCR_PARITY_Pos) /**< Parity stick 1 */ + +#define UART_LCR_STOP_Pos (2U) +#define UART_LCR_STOP_Msk (0x1U << UART_LCR_STOP_Pos) +#define UART_LCR_STOP UART_LCR_STOP_Msk /**< Stop bit */ +#define UART_LCR_STOP_1 (0x0U << UART_LCR_STOP_Pos) /**< Stop bit 1 */ +#define UART_LCR_STOP_1_5 (0x1U << UART_LCR_STOP_Pos) /**< Stop bit 1.5 (DLS = 0) */ +#define UART_LCR_STOP_2 (0x1U << UART_LCR_STOP_Pos) /**< Stop bit 2 (DLS != 0) */ + +#define UART_LCR_DLS_Pos (0U) +#define UART_LCR_DLS_Msk (0x3U << UART_LCR_DLS_Pos) +#define UART_LCR_DLS UART_LCR_DLS_Msk /**< Data Length Select */ +#define UART_LCR_DLS_5 (0x0U << UART_LCR_DLS_Pos) /**< Data bits 5 */ +#define UART_LCR_DLS_6 (0x1U << UART_LCR_DLS_Pos) /**< Data bits 6 */ +#define UART_LCR_DLS_7 (0x2U << UART_LCR_DLS_Pos) /**< Data bits 7 */ +#define UART_LCR_DLS_8 (0x3U << UART_LCR_DLS_Pos) /**< Data bits 8 */ + +/******************* Bit definition for UART_MCR register *******************/ +#define UART_MCR_AFCE_Pos (5U) +#define UART_MCR_AFCE_Len (1U) +#define UART_MCR_AFCE_Msk (0x1U << UART_MCR_AFCE_Pos) +#define UART_MCR_AFCE UART_MCR_AFCE_Msk /**< Auto flow contrl enable */ + +#define UART_MCR_LOOPBACK_Pos (4U) +#define UART_MCR_LOOPBACK_Len (1U) +#define UART_MCR_LOOPBACK_Msk (0x1U << UART_MCR_LOOPBACK_Pos) +#define UART_MCR_LOOPBACK UART_MCR_LOOPBACK_Msk /**< LoopBack */ + +#define UART_MCR_RTS_Pos (1U) +#define UART_MCR_RTS_Len (1U) +#define UART_MCR_RTS_Msk (0x1U << UART_MCR_RTS_Pos) +#define UART_MCR_RTS UART_MCR_RTS_Msk /**< Request To Send */ + +/******************* Bit definition for UART_LSR register *******************/ +#define UART_LSR_RFE_Pos (7U) +#define UART_LSR_RFE_Len (1U) +#define UART_LSR_RFE_Msk (0x1U << UART_LSR_RFE_Pos) +#define UART_LSR_RFE UART_LSR_RFE_Msk /**< Receiver FIFO Error */ + +#define UART_LSR_TEMT_Pos (6U) +#define UART_LSR_TEMT_Len (1U) +#define UART_LSR_TEMT_Msk (0x1U << UART_LSR_TEMT_Pos) +#define UART_LSR_TEMT UART_LSR_TEMT_Msk /**< Transmitter Empty */ + +#define UART_LSR_THRE_Pos (5U) +#define UART_LSR_THRE_Len (1U) +#define UART_LSR_THRE_Msk (0x1U << UART_LSR_THRE_Pos) +#define UART_LSR_THRE UART_LSR_THRE_Msk /**< Transmit Holding Register Empty */ + +#define UART_LSR_BI_Pos (4U) +#define UART_LSR_BI_Len (1U) +#define UART_LSR_BI_Msk (0x1U << UART_LSR_BI_Pos) +#define UART_LSR_BI UART_LSR_BI_Msk /**< Break Interrupt */ + +#define UART_LSR_FE_Pos (3U) +#define UART_LSR_FE_Len (1U) +#define UART_LSR_FE_Msk (0x1U << UART_LSR_FE_Pos) +#define UART_LSR_FE UART_LSR_FE_Msk /**< Framing Error */ + +#define UART_LSR_PE_Pos (2U) +#define UART_LSR_PE_Len (1U) +#define UART_LSR_PE_Msk (0x1U << UART_LSR_PE_Pos) +#define UART_LSR_PE UART_LSR_PE_Msk /**< Parity Error */ + +#define UART_LSR_OE_Pos (1U) +#define UART_LSR_OE_Len (1U) +#define UART_LSR_OE_Msk (0x1U << UART_LSR_OE_Pos) +#define UART_LSR_OE UART_LSR_OE_Msk /**< Overrun error */ + +#define UART_LSR_DR_Pos (0U) +#define UART_LSR_DR_Msk (0x1U << UART_LSR_DR_Pos) +#define UART_LSR_DR UART_LSR_DR_Msk /**< Data Ready */ + +/******************* Bit definition for UART_MSR register *******************/ +#define UART_MSR_CTS_Pos (4U) +#define UART_MSR_CTS_Len (1U) +#define UART_MSR_CTS_Msk (0x1U << UART_MSR_CTS_Pos) +#define UART_MSR_CTS UART_MSR_CTS_Msk /**< Clear To Send */ + +#define UART_MSR_DCTS_Pos (0U) +#define UART_MSR_DCTS_Len (1U) +#define UART_MSR_DCTS_Msk (0x1U << UART_MSR_DCTS_Pos) +#define UART_MSR_DCTS UART_MSR_DCTS_Msk /**< Delta Clear To Send */ + +/******************* Bit definition for UART_USR register *******************/ +#define UART_USR_RFF_Pos (4U) +#define UART_USR_RFF_Len (1U) +#define UART_USR_RFF_Msk (0x1U << UART_USR_RFF_Pos) +#define UART_USR_RFF UART_USR_RFF_Msk /**< Receive FIFO Full */ + +#define UART_USR_RFNE_Pos (3U) +#define UART_USR_RFNE_Len (1U) +#define UART_USR_RFNE_Msk (0x1U << UART_USR_RFNE_Pos) +#define UART_USR_RFNE UART_USR_RFNE_Msk /**< Receive FIFO Not Empty */ + +#define UART_USR_TFE_Pos (2U) +#define UART_USR_TFE_Len (1U) +#define UART_USR_TFE_Msk (0x1U << UART_USR_TFE_Pos) +#define UART_USR_TFE UART_USR_TFE_Msk /**< Transmit FIFO Empty */ + +#define UART_USR_TFNF_Pos (1U) +#define UART_USR_TFNF_Len (1U) +#define UART_USR_TFNF_Msk (0x1U << UART_USR_TFNF_Pos) +#define UART_USR_TFNF UART_USR_TFNF_Msk /**< Transmit FIFO Not Full */ + +/******************* Bit definition for UART_TFL register *******************/ +/* Transmit FIFO Level bits */ +#define UART_TFL_TFL_Pos (0U) +#define UART_TFL_TFL_Len (7U) +#define UART_TFL_TFL_Msk (0x7FU << UART_TFL_TFL_Pos) +#define UART_TFL_TFL UART_TFL_TFL_Msk /**< Transmit FIFO Level */ + +/******************* Bit definition for UART_RFL register *******************/ +/* Receive FIFO Level bits */ +#define UART_RFL_RFL_Pos (0U) +#define UART_RFL_RFL_Len (7U) +#define UART_RFL_RFL_Msk (0x7FU << UART_RFL_RFL_Pos) +#define UART_RFL_RFL UART_RFL_RFL_Msk /**< Receive FIFO Level */ + +/******************* Bit definition for UART_SRR register *******************/ +/* XMIT FIFO Reset bit */ +#define UART_SRR_XFR_Pos (2U) +#define UART_SRR_XFR_Len (1U) +#define UART_SRR_XFR_Msk (0x1U << UART_SRR_XFR_Pos) +#define UART_SRR_XFR UART_SRR_XFR_Msk /**< XMIT FIFO Reset */ + +/* RCVR FIFO Reset bit */ +#define UART_SRR_RFR_Pos (1U) +#define UART_SRR_RFR_Len (1U) +#define UART_SRR_RFR_Msk (0x1U << UART_SRR_RFR_Pos) +#define UART_SRR_RFR UART_SRR_RFR_Msk /**< RCVR FIFO Reset */ + +/* UART Reset Enable bit */ +#define UART_SRR_UR_Pos (0U) +#define UART_SRR_UR_Len (1U) +#define UART_SRR_UR_Msk (0x1U << UART_SRR_UR_Pos) +#define UART_SRR_UR UART_SRR_UR_Msk /**< UART Reset */ + +/******************* Bit definition for UART_SRTS register *******************/ +#define UART_SRTS_SRTS_Pos (0U) +#define UART_SRTS_SRTS_Len (1U) +#define UART_SRTS_SRTS_Msk (0x1U << UART_SRTS_SRTS_Pos) +#define UART_SRTS_SRTS UART_SRTS_SRTS_Msk /**< Shadow Request to Send */ + +/******************* Bit definition for UART_SBCR register *******************/ +#define UART_SBCR_SBCR_Pos (0U) +#define UART_SBCR_SBCR_Len (1U) +#define UART_SBCR_SBCR_Msk (0x1U << UART_SBCR_SBCR_Pos) +#define UART_SBCR_SBCR UART_SBCR_SBCR_Msk /**< Shadow Break Control */ + +/******************* Bit definition for UART_SFE register *******************/ +#define UART_SFE_SFE_Pos (0U) +#define UART_SFE_SFE_Len (1U) +#define UART_SFE_SFE_Msk (0x1U << UART_SFE_SFE_Pos) +#define UART_SFE_SFE UART_SFE_SFE_Msk /**< Shadow FIFO Enable */ + +/******************* Bit definition for UART_SRT register *******************/ +#define UART_SRT_SRT_Pos (0U) +#define UART_SRT_SRT_Len (2U) +#define UART_SRT_SRT_Msk (0x3U << UART_SRT_SRT_Pos) +#define UART_SRT_SRT UART_SRT_SRT_Msk +#define UART_SRT_SRT_CHAR_1 (0x0U << UART_SRT_SRT_Pos) /**< RX FIFO 1 Char */ +#define UART_SRT_SRT_QUARTER_FULL (0x1U << UART_SRT_SRT_Pos) /**< RX FIFO Quater Full*/ +#define UART_SRT_SRT_HALF_FULL (0x2U << UART_SRT_SRT_Pos) /**< RX FIFO Half Full */ +#define UART_SRT_SRT_FULL_2 (0x3U << UART_SRT_SRT_Pos) /**< RX FIFO 2 less than Full */ + +/******************* Bit definition for UART_STET register *******************/ +#define UART_STET_STET_Pos (0U) +#define UART_STET_STET_Len (2U) +#define UART_STET_STET_Msk (0x3U << UART_STET_STET_Pos) +#define UART_STET_STET UART_STET_STET_Msk +#define UART_STET_STET_EMPTY (0x0U << UART_STET_STET_Pos) /**< TX FIFO Empty */ +#define UART_STET_STET_CHAR_2 (0x1U << UART_STET_STET_Pos) /**< TX FIFO 2 chars */ +#define UART_STET_STET_QUARTER_FULL (0x2U << UART_STET_STET_Pos) /**< TX FIFO Quater Full */ +#define UART_STET_STET_HALF_FULL (0x3U << UART_STET_STET_Pos) /**< TX FIFO Half Full */ + +/******************* Bit definition for UART_HTX register *******************/ +#define UART_HTX_HTX_Pos (0U) +#define UART_HTX_HTX_Len (1U) +#define UART_HTX_HTX_Msk (0x1U << UART_HTX_HTX_Pos) +#define UART_HTX_HTX UART_HTX_HTX_Msk /**< Halt TX */ + +/******************* Bit definition for UART_DLF register *******************/ +#define UART_DLF_DLF_Pos (0U) +#define UART_DLF_DLF_Len (1U) +#define UART_DLF_DLF_Msk (0x1U << UART_DLF_DLF_Pos) +#define UART_DLF_DLF UART_DLF_DLF_Msk /**< Fractional part of divisor */ + + +/* ================================================================================================================= */ +/* ================ WDT ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for WDT_CTRL register ********************/ +#define WDT_CTRL_INTEN_Pos (0U) +#define WDT_CTRL_INTEN_Len (1U) +#define WDT_CTRL_INTEN_Msk (0x1U << WDT_CTRL_INTEN_Pos) +#define WDT_CTRL_INTEN WDT_CTRL_INTEN_Msk /**< Interrupt Enable */ + +#define WDT_CTRL_RSTEN_Pos (1U) +#define WDT_CTRL_RSTEN_Len (1U) +#define WDT_CTRL_RSTEN_Msk (0x1U << WDT_CTRL_RSTEN_Pos) +#define WDT_CTRL_RSTEN WDT_CTRL_RSTEN_Msk /**< Reset Enable */ + +/******************* Bit definition for WDT_INTCLR register ********************/ +#define WDT_INTCLR_Pos (0U) +#define WDT_INTCLR_Len (1U) +#define WDT_INTCLR_Msk (0x1U << WDT_INTCLR_Pos) +#define WDT_INTCLR WDT_INTCLR_Msk /**< Interrupt status clear */ + +/******************* Bit definition for WDT_MIS register ********************/ +#define WDT_MIS_INTSTAT_Pos (0U) +#define WDT_MIS_INTSTAT_Len (1U) +#define WDT_MIS_INTSTAT_Msk (0x1U << WDT_MIS_INTSTAT_Pos) +#define WDT_MIS_INTSTAT WDT_MIS_INTSTAT_Msk /**< Interrupt status */ + + +/* ================================================================================================================= */ +/* ================ XQSPI ================ */ +/* ================================================================================================================= */ +/******************* Bit definition for XQSPI_CACHE_CTRL0 register **********/ +#define XQSPI_CACHE_CTRL0_CLK_FORCE_EN_Pos (7U) +#define XQSPI_CACHE_CTRL0_CLK_FORCE_EN_Len (4U) +#define XQSPI_CACHE_CTRL0_CLK_FORCE_EN_Msk (0xFU << XQSPI_CACHE_CTRL0_CLK_FORCE_EN_Pos) +#define XQSPI_CACHE_CTRL0_CLK_FORCE_EN XQSPI_CACHE_CTRL0_CLK_FORCE_EN_Msk + +#define XQSPI_CACHE_CTRL0_BUF_DIS_Pos (6U) +#define XQSPI_CACHE_CTRL0_BUF_DIS_Len (1U) +#define XQSPI_CACHE_CTRL0_BUF_DIS_Msk (0x1U << XQSPI_CACHE_CTRL0_BUF_DIS_Pos) +#define XQSPI_CACHE_CTRL0_BUF_DIS XQSPI_CACHE_CTRL0_BUF_DIS_Msk + +#define XQSPI_CACHE_CTRL0_DIS_SEQ_Pos (5U) +#define XQSPI_CACHE_CTRL0_DIS_SEQ_Len (1U) +#define XQSPI_CACHE_CTRL0_DIS_SEQ_Msk (0x1U << XQSPI_CACHE_CTRL0_DIS_SEQ_Pos) +#define XQSPI_CACHE_CTRL0_DIS_SEQ XQSPI_CACHE_CTRL0_DIS_SEQ_Msk + +#define XQSPI_CACHE_CTRL0_HITMISS_Pos (4U) +#define XQSPI_CACHE_CTRL0_HITMISS_Len (1U) +#define XQSPI_CACHE_CTRL0_HITMISS_Msk (0x1U << XQSPI_CACHE_CTRL0_HITMISS_Pos) +#define XQSPI_CACHE_CTRL0_HITMISS XQSPI_CACHE_CTRL0_HITMISS_Msk + +#define XQSPI_CACHE_CTRL0_FIFO_Pos (3U) +#define XQSPI_CACHE_CTRL0_FIFO_Len (1U) +#define XQSPI_CACHE_CTRL0_FIFO_Msk (0x1U << XQSPI_CACHE_CTRL0_FIFO_Pos) +#define XQSPI_CACHE_CTRL0_FIFO XQSPI_CACHE_CTRL0_FIFO_Msk + +#define XQSPI_CACHE_CTRL0_FLUSH_Pos (1U) +#define XQSPI_CACHE_CTRL0_FLUSH_Len (1U) +#define XQSPI_CACHE_CTRL0_FLUSH_Msk (0x1U << XQSPI_CACHE_CTRL0_FLUSH_Pos) +#define XQSPI_CACHE_CTRL0_FLUSH XQSPI_CACHE_CTRL0_FLUSH_Msk + +#define XQSPI_CACHE_CTRL0_DIS_Pos (0U) +#define XQSPI_CACHE_CTRL0_DIS_Len (1U) +#define XQSPI_CACHE_CTRL0_DIS_Msk (0x1U << XQSPI_CACHE_CTRL0_DIS_Pos) +#define XQSPI_CACHE_CTRL0_DIS XQSPI_CACHE_CTRL0_DIS_Msk + +/******************* Bit definition for XQSPI_CACHE_CTRL1 register **********/ +#define XQSPI_CACHE_CTRL1_DBGMUX_EN_Pos (4U) +#define XQSPI_CACHE_CTRL1_DBGMUX_EN_Len (1U) +#define XQSPI_CACHE_CTRL1_DBGMUX_EN_Msk (0x1U << XQSPI_CACHE_CTRL1_DBGMUX_EN_Pos) +#define XQSPI_CACHE_CTRL1_DBGMUX_EN XQSPI_CACHE_CTRL1_DBGMUX_EN_Msk + +#define XQSPI_CACHE_CTRL1_DBGBUS_SEL_Pos (0U) +#define XQSPI_CACHE_CTRL1_DBGBUS_SEL_Len (4U) +#define XQSPI_CACHE_CTRL1_DBGBUS_SEL_Msk (0xFU << XQSPI_CACHE_CTRL1_DBGBUS_SEL_Pos) +#define XQSPI_CACHE_CTRL1_DBGBUS_SEL XQSPI_CACHE_CTRL1_DBGBUS_SEL_Msk + +/******************* Bit definition for XQSPI_CACHE_HITCOUNT register *******/ +#define XQSPI_CACHE_HITCOUNT_Pos (0U) +#define XQSPI_CACHE_HITCOUNT_Len (32U) +#define XQSPI_CACHE_HITCOUNT_Msk (0xFFFFFFFFU) +#define XQSPI_CACHE_HITCOUNT XQSPI_CACHE_HITCOUNT_Msk + +/******************* Bit definition for XQSPI_CACHE_MISSCOUNT register ******/ +#define XQSPI_CACHE_MISSCOUNT_Pos (0U) +#define XQSPI_CACHE_MISSCOUNT_Len (32U) +#define XQSPI_CACHE_MISSCOUNT_Msk (0xFFFFFFFFU) +#define XQSPI_CACHE_MISSCOUNT XQSPI_CACHE_MISSCOUNT_Msk + +/******************* Bit definition for XQSPI_CACHE_STAT register ***********/ +#define XQSPI_CACHE_BUF_BUSY_Pos (2U) +#define XQSPI_CACHE_BUF_BUSY_Len (1U) +#define XQSPI_CACHE_BUF_BUSY_Msk (0x1U << XQSPI_CACHE_BUF_BUSY_Pos) +#define XQSPI_CACHE_BUF_BUSY XQSPI_CACHE_BUF_BUSY_Msk + +#define XQSPI_CACHE_BUF_ADDR_REACHED_Pos (1U) +#define XQSPI_CACHE_BUF_ADDR_REACHED_Len (1U) +#define XQSPI_CACHE_BUF_ADDR_REACHED_Msk (0x1U << XQSPI_CACHE_BUF_ADDR_REACHED_Pos) +#define XQSPI_CACHE_BUF_ADDR_REACHED XQSPI_CACHE_BUF_ADDR_REACHED_Msk + +#define XQSPI_CACHE_STAT_Pos (0U) +#define XQSPI_CACHE_STAT_Len (1U) +#define XQSPI_CACHE_STAT_Msk (0x1U << XQSPI_CACHE_STAT_Pos) +#define XQSPI_CACHE_STAT XQSPI_CACHE_STAT_Msk + +/******************* Bit definition for XQSPI_CACHE_BUF_FIRST_ADDR register ***********/ +#define XQSPI_CACHE_BUF_FISRT_ADDR_Pos (0U) +#define XQSPI_CACHE_BUF_FISRT_ADDR_Len (32U) +#define XQSPI_CACHE_BUF_FISRT_ADDR_Msk (0xFFFFFFFFU) +#define XQSPI_CACHE_BUF_FISRT_ADDR XQSPI_CACHE_BUF_FISRT_ADDR_Msk + +/******************* Bit definition for XQSPI_CACHE_BUF_LAST_ADDR register ***********/ +#define XQSPI_CACHE_BUF_LAST_ADDR_Pos (0U) +#define XQSPI_CACHE_BUF_LAST_ADDR_Len (32U) +#define XQSPI_CACHE_BUF_LAST_ADDR_Msk (0xFFFFFFFFU) +#define XQSPI_CACHE_BUF_LAST_ADDR XQSPI_CACHE_BUF_LAST_ADDR_Msk + +/******************* Bit definition for XQSPI_XIP_CFG register **************/ +#define XQSPI_XIP_CFG_CMD_Pos (0U) +#define XQSPI_XIP_CFG_CMD_Len (8U) +#define XQSPI_XIP_CFG_CMD_Msk (0xFFU << XQSPI_XIP_CFG_CMD_Pos) +#define XQSPI_XIP_CFG_CMD XQSPI_XIP_CFG_CMD_Msk + +#define XQSPI_XIP_CFG_LE32_Pos (8U) +#define XQSPI_XIP_CFG_LE32_Len (1U) +#define XQSPI_XIP_CFG_LE32_Msk (0x1U << XQSPI_XIP_CFG_LE32_Pos) +#define XQSPI_XIP_CFG_LE32 XQSPI_XIP_CFG_LE32_Msk + +#define XQSPI_XIP_CFG_ADDR4_Pos (7U) +#define XQSPI_XIP_CFG_ADDR4_Len (1U) +#define XQSPI_XIP_CFG_ADDR4_Msk (0x1U << XQSPI_XIP_CFG_ADDR4_Pos) +#define XQSPI_XIP_CFG_ADDR4 XQSPI_XIP_CFG_ADDR4_Msk + +#define XQSPI_XIP_CFG_CPOL_Pos (6U) +#define XQSPI_XIP_CFG_CPOL_Len (1U) +#define XQSPI_XIP_CFG_CPOL_Msk (0x1U << XQSPI_XIP_CFG_CPOL_Pos) +#define XQSPI_XIP_CFG_CPOL XQSPI_XIP_CFG_CPOL_Msk + +#define XQSPI_XIP_CFG_CPHA_Pos (5U) +#define XQSPI_XIP_CFG_CPHA_Len (1U) +#define XQSPI_XIP_CFG_CPHA_Msk (0x1U << XQSPI_XIP_CFG_CPHA_Pos) +#define XQSPI_XIP_CFG_CPHA XQSPI_XIP_CFG_CPHA_Msk + +#define XQSPI_XIP_CFG_SS_Pos (1U) +#define XQSPI_XIP_CFG_SS_Len (4U) +#define XQSPI_XIP_CFG_SS_Msk (0xFU << XQSPI_XIP_CFG_SS_Pos) +#define XQSPI_XIP_CFG_SS XQSPI_XIP_CFG_SS_Msk + +#define XQSPI_XIP_CFG_HPEN_Pos (0U) +#define XQSPI_XIP_CFG_HPEN_Len (1U) +#define XQSPI_XIP_CFG_HPEN_Msk (0x1U << XQSPI_XIP_CFG_HPEN_Pos) +#define XQSPI_XIP_CFG_HPEN XQSPI_XIP_CFG_HPEN_Msk + +#define XQSPI_XIP_CFG_ENDDUMMY_Pos (12U) +#define XQSPI_XIP_CFG_ENDDUMMY_Len (2U) +#define XQSPI_XIP_CFG_ENDDUMMY_Msk (0x3U << XQSPI_XIP_CFG_ENDDUMMY_Pos) +#define XQSPI_XIP_CFG_ENDDUMMY XQSPI_XIP_CFG_ENDDUMMY_Msk + +#define XQSPI_XIP_CFG_DUMMYCYCLES_Pos (8U) +#define XQSPI_XIP_CFG_DUMMYCYCLES_Len (4U) +#define XQSPI_XIP_CFG_DUMMYCYCLES_Msk (0xFU << XQSPI_XIP_CFG_DUMMYCYCLES_Pos) +#define XQSPI_XIP_CFG_DUMMYCYCLES XQSPI_XIP_CFG_DUMMYCYCLES_Msk + +#define XQSPI_XIP_CFG_HPMODE_Pos (0U) +#define XQSPI_XIP_CFG_HPMODE_Len (8U) +#define XQSPI_XIP_CFG_HPMODE_Msk (0xFFUL << XQSPI_XIP_CFG_HPMODE_Pos) +#define XQSPI_XIP_CFG_HPMODE XQSPI_XIP_CFG_HPMODE_Msk + +/******************* Bit definition for XQSPI_XIP_EN register ***************/ +#define XQSPI_XIP_EN_REQ_Pos (0U) +#define XQSPI_XIP_EN_REQ_Len (1U) +#define XQSPI_XIP_EN_REQ_Msk (0x1U << XQSPI_XIP_EN_REQ_Pos) +#define XQSPI_XIP_EN_REQ XQSPI_XIP_EN_REQ_Msk + +#define XQSPI_XIP_EN_OUT_Pos (0U) +#define XQSPI_XIP_EN_OUT_Len (1U) +#define XQSPI_XIP_EN_OUT_Msk (0x1U << XQSPI_XIP_EN_OUT_Pos) +#define XQSPI_XIP_EN_OUT XQSPI_XIP_EN_OUT_Msk + +/******************* Bit definition for XQSPI_XIP_INT0 register *************/ +#define XQSPI_XIP_INT_EN_Pos (0U) +#define XQSPI_XIP_INT_EN_Len (1U) +#define XQSPI_XIP_INT_EN_Msk (0x1U << XQSPI_XIP_INT_EN_Pos) +#define XQSPI_XIP_INT_EN XQSPI_XIP_INT_EN_Msk + +/******************* Bit definition for XQSPI_XIP_INT1 register *************/ +#define XQSPI_XIP_INT_STAT_Pos (0U) +#define XQSPI_XIP_INT_STAT_Len (1U) +#define XQSPI_XIP_INT_STAT_Msk (0x1U << XQSPI_XIP_INT_STAT_Pos) +#define XQSPI_XIP_INT_STAT XQSPI_XIP_INT_STAT_Msk + +/******************* Bit definition for XQSPI_XIP_INT2 register *************/ +#define XQSPI_XIP_INT_REQ_Pos (0U) +#define XQSPI_XIP_INT_REQ_Len (1U) +#define XQSPI_XIP_INT_REQ_Msk (0x1U << XQSPI_XIP_INT_REQ_Pos) +#define XQSPI_XIP_INT_REQ XQSPI_XIP_INT_REQ_Msk + +/******************* Bit definition for XQSPI_XIP_INT3 register *************/ +#define XQSPI_XIP_INT_SET_Pos (0U) +#define XQSPI_XIP_INT_SET_Len (1U) +#define XQSPI_XIP_INT_SET_Msk (0x1U << XQSPI_XIP_INT_SET_Pos) +#define XQSPI_XIP_INT_SET XQSPI_XIP_INT_SET_Msk + +/******************* Bit definition for XQSPI_XIP_INT4 register *************/ +#define XQSPI_XIP_INT_CLR_Pos (0U) +#define XQSPI_XIP_INT_CLR_Len (1U) +#define XQSPI_XIP_INT_CLR_Msk (0x1U << XQSPI_XIP_INT_CLR_Pos) +#define XQSPI_XIP_INT_CLR XQSPI_XIP_INT_CLR_Msk + +/******************* Bit definition for XQSPI_QSPI_STAT register ************/ +#define XQSPI_QSPI_STAT_RXFULL_Pos (7U) +#define XQSPI_QSPI_STAT_RXFULL_Len (1U) +#define XQSPI_QSPI_STAT_RXFULL_Msk (0x1U << XQSPI_QSPI_STAT_RXFULL_Pos) +#define XQSPI_QSPI_STAT_RXFULL XQSPI_QSPI_STAT_RXFULL_Msk + +#define XQSPI_QSPI_STAT_RXWMARK_Pos (6U) +#define XQSPI_QSPI_STAT_RXWMARK_Len (1U) +#define XQSPI_QSPI_STAT_RXWMARK_Msk (0x1U << XQSPI_QSPI_STAT_RXWMARK_Pos) +#define XQSPI_QSPI_STAT_RXWMARK XQSPI_QSPI_STAT_RXWMARK_Msk + +#define XQSPI_QSPI_STAT_RXEMPTY_Pos (5U) +#define XQSPI_QSPI_STAT_RXEMPTY_Len (1U) +#define XQSPI_QSPI_STAT_RXEMPTY_Msk (0x1U << XQSPI_QSPI_STAT_RXEMPTY_Pos) +#define XQSPI_QSPI_STAT_RXEMPTY XQSPI_QSPI_STAT_RXEMPTY_Msk + +#define XQSPI_QSPI_STAT_TXFULL_Pos (4U) +#define XQSPI_QSPI_STAT_TXFULL_Len (1U) +#define XQSPI_QSPI_STAT_TXFULL_Msk (0x1U << XQSPI_QSPI_STAT_TXFULL_Pos) +#define XQSPI_QSPI_STAT_TXFULL XQSPI_QSPI_STAT_TXFULL_Msk + +#define XQSPI_QSPI_STAT_TXWMARK_Pos (3U) +#define XQSPI_QSPI_STAT_TXWMARK_Len (1U) +#define XQSPI_QSPI_STAT_TXWMARK_Msk (0x1U << XQSPI_QSPI_STAT_TXWMARK_Pos) +#define XQSPI_QSPI_STAT_TXWMARK XQSPI_QSPI_STAT_TXWMARK_Msk + +#define XQSPI_QSPI_STAT_TXEMPTY_Pos (2U) +#define XQSPI_QSPI_STAT_TXEMPTY_Len (1U) +#define XQSPI_QSPI_STAT_TXEMPTY_Msk (0x1U << XQSPI_QSPI_STAT_TXEMPTY_Pos) +#define XQSPI_QSPI_STAT_TXEMPTY XQSPI_QSPI_STAT_TXEMPTY_Msk + +#define XQSPI_QSPI_STAT_XFERIP_Pos (0U) +#define XQSPI_QSPI_STAT_XFERIP_Len (1U) +#define XQSPI_QSPI_STAT_XFERIP_Msk (0x1U << XQSPI_QSPI_STAT_XFERIP_Pos) +#define XQSPI_QSPI_STAT_XFERIP XQSPI_QSPI_STAT_XFERIP_Msk + +/******************* Bit definition for XQSPI_QSPI_FIFO register ************/ +#define XQSPI_QSPI_FIFO_TX_Pos (0U) +#define XQSPI_QSPI_FIFO_TX_Len (32U) +#define XQSPI_QSPI_FIFO_TX_Msk (0xFFFFFFFFU) +#define XQSPI_QSPI_FIFO_TX XQSPI_QSPI_FIFO_TX_Msk + +#define XQSPI_QSPI_FIFO_RX_Pos (0U) +#define XQSPI_QSPI_FIFO_RX_Len (32U) +#define XQSPI_QSPI_FIFO_RX_Msk (0xFFFFFFFFU) +#define XQSPI_QSPI_FIFO_RX XQSPI_QSPI_FIFO_RX_Msk + +/******************* Bit definition for XQSPI_QSPI_CTRL register ************/ +#define XQSPI_QSPI_CTRL_TXWMARK_Pos (14U) +#define XQSPI_QSPI_CTRL_TXWMARK_Len (2U) +#define XQSPI_QSPI_CTRL_TXWMARK_Msk (0x3U << XQSPI_QSPI_CTRL_TXWMARK_Pos) +#define XQSPI_QSPI_CTRL_TXWMARK XQSPI_QSPI_CTRL_TXWMARK_Msk + +#define XQSPI_QSPI_CTRL_RXWMARK_Pos (12U) +#define XQSPI_QSPI_CTRL_RXWMARK_Len (2U) +#define XQSPI_QSPI_CTRL_RXWMARK_Msk (0x3U << XQSPI_QSPI_CTRL_RXWMARK_Pos) +#define XQSPI_QSPI_CTRL_RXWMARK XQSPI_QSPI_CTRL_RXWMARK_Msk + +#define XQSPI_QSPI_CTRL_MWAITEN_Pos (11U) +#define XQSPI_QSPI_CTRL_MWAITEN_Len (1U) +#define XQSPI_QSPI_CTRL_MWAITEN_Msk (0x1U << XQSPI_QSPI_CTRL_MWAITEN_Pos) +#define XQSPI_QSPI_CTRL_MWAITEN XQSPI_QSPI_CTRL_MWAITEN_Msk + +#define XQSPI_QSPI_CTRL_DMA_Pos (10U) +#define XQSPI_QSPI_CTRL_DMA_Len (1U) +#define XQSPI_QSPI_CTRL_DMA_Msk (0x1U << XQSPI_QSPI_CTRL_DMA_Pos) +#define XQSPI_QSPI_CTRL_DMA XQSPI_QSPI_CTRL_DMA_Msk + +#define XQSPI_QSPI_CTRL_MASTER_Pos (5U) +#define XQSPI_QSPI_CTRL_MASTER_Len (1U) +#define XQSPI_QSPI_CTRL_MASTER_Msk (0x1U << XQSPI_QSPI_CTRL_MASTER_Pos) +#define XQSPI_QSPI_CTRL_MASTER XQSPI_QSPI_CTRL_MASTER_Msk + +#define XQSPI_QSPI_CTRL_CPOL_Pos (4U) +#define XQSPI_QSPI_CTRL_CPOL_Len (1U) +#define XQSPI_QSPI_CTRL_CPOL_Msk (0x1U << XQSPI_QSPI_CTRL_CPOL_Pos) +#define XQSPI_QSPI_CTRL_CPOL XQSPI_QSPI_CTRL_CPOL_Msk + +#define XQSPI_QSPI_CTRL_CPHA_Pos (3U) +#define XQSPI_QSPI_CTRL_CPHA_Len (1U) +#define XQSPI_QSPI_CTRL_CPHA_Msk (0x1U << XQSPI_QSPI_CTRL_CPHA_Pos) +#define XQSPI_QSPI_CTRL_CPHA XQSPI_QSPI_CTRL_CPHA_Msk + +#define XQSPI_QSPI_CTRL_MSB1ST_Pos (2U) +#define XQSPI_QSPI_CTRL_MSB1ST_Len (1U) +#define XQSPI_QSPI_CTRL_MSB1ST_Msk (0x1U << XQSPI_QSPI_CTRL_MSB1ST_Pos) +#define XQSPI_QSPI_CTRL_MSB1ST XQSPI_QSPI_CTRL_MSB1ST_Msk + +#define XQSPI_QSPI_CTRL_CONTXFER_Pos (0U) +#define XQSPI_QSPI_CTRL_CONTXFER_Len (1U) +#define XQSPI_QSPI_CTRL_CONTXFER_Msk (0x1U << XQSPI_QSPI_CTRL_CONTXFER_Pos) +#define XQSPI_QSPI_CTRL_CONTXFER XQSPI_QSPI_CTRL_CONTXFER_Msk + +/******************* Bit definition for XQSPI_QSPI_AUXCTRL register *********/ +#define XQSPI_QSPI_AUXCTRL_CONTXFERX_Pos (7U) +#define XQSPI_QSPI_AUXCTRL_CONTXFERX_Len (1U) +#define XQSPI_QSPI_AUXCTRL_CONTXFERX_Msk (0x1U << XQSPI_QSPI_AUXCTRL_CONTXFERX_Pos) +#define XQSPI_QSPI_AUXCTRL_CONTXFERX XQSPI_QSPI_AUXCTRL_CONTXFERX_Msk + +#define XQSPI_QSPI_AUXCTRL_BITSIZE_Pos (4U) +#define XQSPI_QSPI_AUXCTRL_BITSIZE_Len (3U) +#define XQSPI_QSPI_AUXCTRL_BITSIZE_Msk (0x7U << XQSPI_QSPI_AUXCTRL_BITSIZE_Pos) +#define XQSPI_QSPI_AUXCTRL_BITSIZE XQSPI_QSPI_AUXCTRL_BITSIZE_Msk + +#define XQSPI_QSPI_AUXCTRL_INHIBITDIN_Pos (3U) +#define XQSPI_QSPI_AUXCTRL_INHIBITDIN_Len (1U) +#define XQSPI_QSPI_AUXCTRL_INHIBITDIN_Msk (0x1U << XQSPI_QSPI_AUXCTRL_INHIBITDIN_Pos) +#define XQSPI_QSPI_AUXCTRL_INHIBITDIN XQSPI_QSPI_AUXCTRL_INHIBITDIN_Msk + +#define XQSPI_QSPI_AUXCTRL_INHIBITDOUT_Pos (2U) +#define XQSPI_QSPI_AUXCTRL_INHIBITDOUT_Len (1U) +#define XQSPI_QSPI_AUXCTRL_INHIBITDOUT_Msk (0x1U << XQSPI_QSPI_AUXCTRL_INHIBITDOUT_Pos) +#define XQSPI_QSPI_AUXCTRL_INHIBITDOUT XQSPI_QSPI_AUXCTRL_INHIBITDOUT_Msk + +#define XQSPI_QSPI_AUXCTRL_QMODE_Pos (0U) +#define XQSPI_QSPI_AUXCTRL_QMODE_Len (2U) +#define XQSPI_QSPI_AUXCTRL_QMODE_Msk (0x3U << XQSPI_QSPI_AUXCTRL_QMODE_Pos) +#define XQSPI_QSPI_AUXCTRL_QMODE XQSPI_QSPI_AUXCTRL_QMODE_Msk + +/******************* Bit definition for XQSPI_QSPI_SS register **************/ +#define XQSPI_QSPI_SS_OUT3_Pos (3U) +#define XQSPI_QSPI_SS_OUT3_Len (1U) +#define XQSPI_QSPI_SS_OUT3_Msk (0x1U << XQSPI_QSPI_SS_OUT3_Pos) +#define XQSPI_QSPI_SS_OUT3 XQSPI_QSPI_SS_OUT3_Msk + +#define XQSPI_QSPI_SS_OUT2_Pos (2U) +#define XQSPI_QSPI_SS_OUT2_Len (1U) +#define XQSPI_QSPI_SS_OUT2_Msk (0x1U << XQSPI_QSPI_SS_OUT2_Pos) +#define XQSPI_QSPI_SS_OUT2 XQSPI_QSPI_SS_OUT2_Msk + +#define XQSPI_QSPI_SS_OUT1_Pos (1U) +#define XQSPI_QSPI_SS_OUT1_Len (1U) +#define XQSPI_QSPI_SS_OUT1_Msk (0x1U << XQSPI_QSPI_SS_OUT1_Pos) +#define XQSPI_QSPI_SS_OUT1 XQSPI_QSPI_SS_OUT1_Msk + +#define XQSPI_QSPI_SS_OUT0_Pos (0U) +#define XQSPI_QSPI_SS_OUT0_Len (1U) +#define XQSPI_QSPI_SS_OUT0_Msk (0x1U << XQSPI_QSPI_SS_OUT0_Pos) +#define XQSPI_QSPI_SS_OUT0 XQSPI_QSPI_SS_OUT0_Msk + +/******************* Bit definition for XQSPI_QSPI_SS_POL register **********/ +#define XQSPI_QSPI_SS_POL3_Pos (3U) +#define XQSPI_QSPI_SS_POL3_Len (1U) +#define XQSPI_QSPI_SS_POL3_Msk (0x1U << XQSPI_QSPI_SS_POL3_Pos) +#define XQSPI_QSPI_SS_POL3 XQSPI_QSPI_SS_POL3_Msk + +#define XQSPI_QSPI_SS_POL2_Pos (2U) +#define XQSPI_QSPI_SS_POL2_Len (1U) +#define XQSPI_QSPI_SS_POL2_Msk (0x1U << XQSPI_QSPI_SS_POL2_Pos) +#define XQSPI_QSPI_SS_POL2 XQSPI_QSPI_SS_POL2_Msk + +#define XQSPI_QSPI_SS_POL1_Pos (1U) +#define XQSPI_QSPI_SS_POL1_Len (1U) +#define XQSPI_QSPI_SS_POL1_Msk (0x1U << XQSPI_QSPI_SS_POL1_Pos) +#define XQSPI_QSPI_SS_POL1 XQSPI_QSPI_SS_POL1_Msk + +#define XQSPI_QSPI_SS_POL0_Pos (0U) +#define XQSPI_QSPI_SS_POL0_Len (1U) +#define XQSPI_QSPI_SS_POL0_Msk (0x1U << XQSPI_QSPI_SS_POL0_Pos) +#define XQSPI_QSPI_SS_POL0 XQSPI_QSPI_SS_POL0_Msk + +/******************* Bit definition for XQSPI_QSPI_INT_EN register **********/ +#define XQSPI_QSPI_INT_EN_Pos (0U) +#define XQSPI_QSPI_INT_EN_Len (7U) +#define XQSPI_QSPI_INT_EN_Msk (0x7FUL << XQSPI_QSPI_INT_EN_Pos) +#define XQSPI_QSPI_INT_EN XQSPI_QSPI_INT_EN_Msk + +/******************* Bit definition for XQSPI_QSPI_INT_STAT register ********/ +#define XQSPI_QSPI_INT_STAT_Pos (0U) +#define XQSPI_QSPI_INT_STAT_Len (7U) +#define XQSPI_QSPI_INT_STAT_Msk (0x7FUL << XQSPI_QSPI_INT_STAT_Pos) +#define XQSPI_QSPI_INT_STAT XQSPI_QSPI_INT_STAT_Msk + +/******************* Bit definition for XQSPI_QSPI_INT_CLR register *********/ +#define XQSPI_QSPI_INT_CLR_Pos (0U) +#define XQSPI_QSPI_INT_CLR_Len (7U) +#define XQSPI_QSPI_INT_CLR_Msk (0x7FUL << XQSPI_QSPI_INT_CLR_Pos) +#define XQSPI_QSPI_INT_CLR XQSPI_QSPI_INT_CLR_Msk + +/******************* Bit definition for XQSPI Interrupt Bit Mapping *********/ +#define XQSPI_QSPI_GPI_HI_PULSE1_Pos (6U) +#define XQSPI_QSPI_GPI_HI_PULSE1_Len (1U) +#define XQSPI_QSPI_GPI_HI_PULSE1_Msk (0x1U << XQSPI_QSPI_GPI_HI_PULSE1_Pos) +#define XQSPI_QSPI_GPI_HI_PULSE0_Pos (5U) +#define XQSPI_QSPI_GPI_HI_PULSE0_Len (1U) +#define XQSPI_QSPI_GPI_HI_PULSE0_Msk (0x1U << XQSPI_QSPI_GPI_HI_PULSE0_Pos) +#define XQSPI_QSPI_XFER_DPULSE_Pos (4U) +#define XQSPI_QSPI_XFER_DPULSE_Len (1U) +#define XQSPI_QSPI_XFER_DPULSE_Msk (0x1U << XQSPI_QSPI_XFER_DPULSE_Pos) +#define XQSPI_QSPI_RX_FPULSE_Pos (3U) +#define XQSPI_QSPI_RX_FPULSE_Len (1U) +#define XQSPI_QSPI_RX_FPULSE_Msk (0x1U << XQSPI_QSPI_RX_FPULSE_Pos) +#define XQSPI_QSPI_RX_WPULSE_Pos (2U) +#define XQSPI_QSPI_RX_WPULSE_Len (1U) +#define XQSPI_QSPI_RX_WPULSE_Msk (0x1U << XQSPI_QSPI_RX_WPULSE_Pos) +#define XQSPI_QSPI_TX_WPULSE_Pos (1U) +#define XQSPI_QSPI_TX_WPULSE_Len (1U) +#define XQSPI_QSPI_TX_WPULSE_Msk (0x1U << XQSPI_QSPI_TX_WPULSE_Pos) +#define XQSPI_QSPI_TX_EPULSE_Pos (0U) +#define XQSPI_QSPI_TX_EPULSE_Len (1U) +#define XQSPI_QSPI_TX_EPULSE_Msk (0x1U << XQSPI_QSPI_TX_EPULSE_Pos) + +/******************* Bit definition for XQSPI_QSPI_TXFIFOLVL register *******/ +#define XQSPI_QSPI_TXFIFOLVL_Pos (0U) +#define XQSPI_QSPI_TXFIFOLVL_Len (7U) +#define XQSPI_QSPI_TXFIFOLVL_Msk (0x7FUL << XQSPI_QSPI_TXFIFOLVL_Pos) +#define XQSPI_QSPI_TXFIFOLVL XQSPI_QSPI_TXFIFOLVL_Msk + +/******************* Bit definition for XQSPI_QSPI_RXFIFOLVL register *******/ +#define XQSPI_QSPI_RXFIFOLVL_Pos (0U) +#define XQSPI_QSPI_RXFIFOLVL_Len (7U) +#define XQSPI_QSPI_RXFIFOLVL_Msk (0x7FUL << XQSPI_QSPI_RXFIFOLVL_Pos) +#define XQSPI_QSPI_RXFIFOLVL XQSPI_QSPI_RXFIFOLVL_Msk + +/******************* Bit definition for XQSPI_QSPI_MWAIT register ***********/ +#define XQSPI_QSPI_MWAIT_MWAIT_Pos (0U) +#define XQSPI_QSPI_MWAIT_MWAIT_Len (8U) +#define XQSPI_QSPI_MWAIT_MWAIT_Msk (0xFFUL << XQSPI_QSPI_MWAIT_MWAIT_Pos) +#define XQSPI_QSPI_MWAIT_MWAIT XQSPI_QSPI_MWAIT_MWAIT_Msk + +/******************* Bit definition for XQSPI_QSPI_EN register **************/ +#define XQSPI_QSPI_EN_EN_Pos (0U) +#define XQSPI_QSPI_EN_EN_Len (1U) +#define XQSPI_QSPI_EN_EN_Msk (0x1U << XQSPI_QSPI_EN_EN_Pos) +#define XQSPI_QSPI_EN_EN XQSPI_QSPI_EN_EN_Msk + +/******************* Bit definition for XQSPI_QSPI_GPOSET_GPOSET register ***/ +#define XQSPI_QSPI_GPOSET_GPOSET_Pos (0U) +#define XQSPI_QSPI_GPOSET_GPOSET_Len (8U) +#define XQSPI_QSPI_GPOSET_GPOSET_Msk (0xFFUL << XQSPI_QSPI_GPOSET_GPOSET_Pos) +#define XQSPI_QSPI_GPOSET_GPOSET XQSPI_QSPI_GPOSET_GPOSET_Msk + +/******************* Bit definition for XQSPI_QSPI_GPOCLR_GPOCLR register ***/ +#define XQSPI_QSPI_GPOCLR_GPOCLR_Pos (0U) +#define XQSPI_QSPI_GPOCLR_GPOCLR_Len (8U) +#define XQSPI_QSPI_GPOCLR_GPOCLR_Msk (0xFFUL << XQSPI_QSPI_GPOCLR_GPOCLR_Pos) +#define XQSPI_QSPI_GPOCLR_GPOCLR XQSPI_QSPI_GPOCLR_GPOCLR_Msk + +/******************* Bit definition for XQSPI_QSPI_FLASH_WRITE register ***/ +#define XQSPI_QSPI_FLASH_WRITE_Pos (0U) +#define XQSPI_QSPI_FLASH_WRITE_Len (1U) +#define XQSPI_QSPI_FLASH_WRITE_Msk (0xFFUL << XQSPI_QSPI_FLASH_WRITE_Pos) +#define XQSPI_QSPI_FLASH_WRITE XQSPI_QSPI_FLASH_WRITE_Msk + +/******************* Bit definition for XQSPI_QSPI_PRESENT_BYPASS register ***/ +#define XQSPI_QSPI_PRESENT_BYPASS_Pos (0U) +#define XQSPI_QSPI_PRESENT_BYPASS_Len (1U) +#define XQSPI_QSPI_PRESENT_BYPASS_Msk (0xFFUL << XQSPI_QSPI_PRESENT_BYPASS_Pos) +#define XQSPI_QSPI_PRESENT_BYPASS XQSPI_QSPI_PRESENT_BYPASS_Msk + +/* =============================================================================================================== */ +/* ================ EFUSE ================ */ +/* =============================================================================================================== */ +/******************* Bit definition for EFUSE_TPGM register **********/ +#define EFUSE_TPGM_TIME_Pos (0U) +#define EFUSE_TPGM_TIME_Len (12U) +#define EFUSE_TPGM_TIME_Msk (0xFFFUL << EFUSE_TPGM_TIME_Pos) +#define EFUSE_TPGM_TIME EFUSE_TPGM_TIME_Msk + +#define EFUSE_TPGM_MAIN_OR_BACKUP_Pos (12U) +#define EFUSE_TPGM_MAIN_OR_BACKUP_Len (1U) +#define EFUSE_TPGM_MAIN_OR_BACKUP_Msk (0x1UL << EFUSE_TPGM_MAIN_OR_BACKUP_Pos) +#define EFUSE_TPGM_MAIN_OR_BACKUP EFUSE_TPGM_MAIN_OR_BACKUP_Msk + +#define EFUSE_TPGM_CRC_CHECK_LEN_Pos (16U) +#define EFUSE_TPGM_CRC_CHECK_LEN_Len (6U) +#define EFUSE_TPGM_CRC_CHECK_LEN_Msk (0x3FUL << EFUSE_TPGM_CRC_CHECK_LEN_Pos) +#define EFUSE_TPGM_CRC_CHECK_LEN EFUSE_TPGM_CRC_CHECK_LEN_Msk + +#define EFUSE_TPGM_WRITE_INTERVAL_Pos (24U) +#define EFUSE_TPGM_WRITE_INTERVAL_Len (8U) +#define EFUSE_TPGM_WRITE_INTERVAL_Msk (0xFFUL << EFUSE_TPGM_WRITE_INTERVAL_Pos) +#define EFUSE_TPGM_WRITE_INTERVAL EFUSE_TPGM_WRITE_INTERVAL_Msk + +/******************* Bit definition for EFUSE_PGENB register **********/ +#define EFUSE_PGENB_SIG_Pos (0U) +#define EFUSE_PGENB_SIG_Len (1U) +#define EFUSE_PGENB_SIG_Msk (0x1UL << EFUSE_PGENB_SIG_Pos) +#define EFUSE_PGENB_SIG EFUSE_PGENB_SIG_Msk + +/******************* Bit definition for EFUSE_TEST_MODE register **********/ +#define EFUSE_TEST_MODE_Pos (0U) +#define EFUSE_TEST_MODE_Len (16U) +#define EFUSE_TEST_MODE_Msk (0xFFFFUL << EFUSE_TEST_MODE_Pos) +#define EFUSE_TEST_MODE EFUSE_TEST_MODE_Msk + +/******************* Bit definition for EFUSE_OPERATION register **********/ +#define EFUSE_OPER_WRITE_KEYRAM_Pos (0U) +#define EFUSE_OPER_WRITE_KEYRAM_Len (1U) +#define EFUSE_OPER_WRITE_KEYRAM_Msk (0x1UL << EFUSE_OPER_WRITE_KEYRAM_Pos) +#define EFUSE_OPER_WRITE_KEYRAM EFUSE_OPER_WRITE_KEYRAM_Msk + +#define EFUSE_OPER_INIT_CHECK_Pos (1U) +#define EFUSE_OPER_INIT_CHECK_Len (1U) +#define EFUSE_OPER_INIT_CHECK_Msk (0x1UL << EFUSE_OPER_INIT_CHECK_Pos) +#define EFUSE_OPER_INIT_CHECK EFUSE_OPER_INIT_CHECK_Msk + +#define EFUSE_OPER_CRC_CHECK_Pos (2U) +#define EFUSE_OPER_CRC_CHECK_Len (1U) +#define EFUSE_OPER_CRC_CHECK_Msk (0x1UL << EFUSE_OPER_CRC_CHECK_Pos) +#define EFUSE_OPER_CRC_CHECK EFUSE_OPER_CRC_CHECK_Msk + +#define EFUSE_OPER_READ_TRIM_Pos (3U) +#define EFUSE_OPER_READ_TRIM_Len (1U) +#define EFUSE_OPER_READ_TRIM_Msk (0x1UL << EFUSE_OPER_READ_TRIM_Pos) +#define EFUSE_OPER_READ_TRIM EFUSE_OPER_READ_TRIM_Msk + +#define EFUSE_OPER_RD_TEST_MODE_Pos (4U) +#define EFUSE_OPER_RD_TEST_MODE_Len (1U) +#define EFUSE_OPER_RD_TEST_MODE_Msk (0x1UL << EFUSE_OPER_RD_TEST_MODE_Pos) +#define EFUSE_OPER_RD_TEST_MODE EFUSE_OPER_RD_TEST_MODE_Msk + +/******************* Bit definition for EFUSE_STATUS register **********/ +#define EFUSE_STATUS_WRITE_KEYRAM_BUSY_Pos (0U) +#define EFUSE_STATUS_WRITE_KEYRAM_BUSY_Len (1U) +#define EFUSE_STATUS_WRITE_KEYRAM_BUSY_Msk (0x1UL << EFUSE_STATUS_WRITE_KEYRAM_BUSY_Pos) +#define EFUSE_STATUS_WRITE_KEYRAM_BUSY EFUSE_STATUS_WRITE_KEYRAM_BUSY_Msk + +#define EFUSE_STATUS_READ_TRIM_DONE_Pos (1U) +#define EFUSE_STATUS_READ_TRIM_DONE_Len (1U) +#define EFUSE_STATUS_READ_TRIM_DONE_Msk (0x1UL << EFUSE_STATUS_READ_TRIM_DONE_Pos) +#define EFUSE_STATUS_READ_TRIM_DONE EFUSE_STATUS_READ_TRIM_DONE_Msk + +#define EFUSE_STATUS_TRIM_CRC_SUCCESS_Pos (2U) +#define EFUSE_STATUS_TRIM_CRC_SUCCESS_Len (1U) +#define EFUSE_STATUS_TRIM_CRC_SUCCESS_Msk (0x1UL << EFUSE_STATUS_TRIM_CRC_SUCCESS_Pos) +#define EFUSE_STATUS_TRIM_CRC_SUCCESS EFUSE_STATUS_TRIM_CRC_SUCCESS_Msk + +#define EFUSE_STATUS_INIT_DONE_Pos (3U) +#define EFUSE_STATUS_INIT_DONE_Len (1U) +#define EFUSE_STATUS_INIT_DONE_Msk (0x1UL << EFUSE_STATUS_INIT_DONE_Pos) +#define EFUSE_STATUS_INIT_DONE EFUSE_STATUS_INIT_DONE_Msk + +#define EFUSE_STATUS_INIT_SUCCESS_Pos (4U) +#define EFUSE_STATUS_INIT_SUCCESS_Len (1U) +#define EFUSE_STATUS_INIT_SUCCESS_Msk (0x1UL << EFUSE_STATUS_INIT_SUCCESS_Pos) +#define EFUSE_STATUS_INIT_SUCCESS EFUSE_STATUS_INIT_SUCCESS_Msk + +#define EFUSE_STATUS_CRC_CHECK_DONE_Pos (5U) +#define EFUSE_STATUS_CRC_CHECK_DONE_Len (1U) +#define EFUSE_STATUS_CRC_CHECK_DONE_Msk (0x1UL << EFUSE_STATUS_CRC_CHECK_DONE_Pos) +#define EFUSE_STATUS_CRC_CHECK_DONE EFUSE_STATUS_CRC_CHECK_DONE_Msk + +#define EFUSE_STATUS_WRITE_DONE_Pos (6U) +#define EFUSE_STATUS_WRITE_DONE_Len (1U) +#define EFUSE_STATUS_WRITE_DONE_Msk (0x1UL << EFUSE_STATUS_WRITE_DONE_Pos) +#define EFUSE_STATUS_WRITE_DONE EFUSE_STATUS_WRITE_DONE_Msk + +#define EFUSE_STATUS_TEST_MODE_DONE_Pos (7U) +#define EFUSE_STATUS_TEST_MODE_DONE_Len (1U) +#define EFUSE_STATUS_TEST_MODE_DONE_Msk (0x1UL << EFUSE_STATUS_TEST_MODE_DONE_Pos) +#define EFUSE_STATUS_TEST_MODE_DONE EFUSE_STATUS_TEST_MODE_DONE_Msk + +/******************* Bit definition for EFUSE_KEY_MASK register **********/ +#define EFUSE_KEY_MASK_Pos (0U) +#define EFUSE_KEY_MASK_Len (32U) +#define EFUSE_KEY_MASK_Msk (0x1UL << EFUSE_KEY_MASK_Pos) +#define EFUSE_KEY_MASK EFUSE_KEY_MASK_Msk + +/******************* Bit definition for EFUSE_CRC_START_ADDR register **********/ +#define EFUSE_CRC_START_CHECK_ADDR_Pos (0U) +#define EFUSE_CRC_START_CHECK_ADDR_Len (32U) +#define EFUSE_CRC_START_CHECK_ADDR_Msk (0xFFFFFFFFU) +#define EFUSE_CRC_START_CHECK_ADDR EFUSE_CRC_START_CHECK_ADDR_Msk + +/******************* Bit definition for EFUSE_CRC_OUTPUT register **********/ +#define EFUSE_CRC_OUTPUT_VALUE_Pos (0U) +#define EFUSE_CRC_OUTPUT_VALUE_Len (32U) +#define EFUSE_CRC_OUTPUT_VALUE_Msk (0xFFFFFFFFU) +#define EFUSE_CRC_OUTPUT_VALUE EFUSE_CRC_OUTPUT_VALUE_Msk + +/******************* Bit definition for EFUSE_TRIM_ADDR register **********/ +#define EFUSE_TRIM_START_ADDR_Pos (0U) +#define EFUSE_TRIM_START_ADDR_Len (32U) +#define EFUSE_TRIM_START_ADDR_Msk (0xFFFFFFFFU) +#define EFUSE_TRIM_START_ADDR EFUSE_TRIM_START_ADDR_Msk + +/******************* Bit definition for EFUSE_TRIM_LEN register **********/ +#define EFUSE_TRIM_LENGTH_Pos (0U) +#define EFUSE_TRIM_LENGTH_Len (5U) +#define EFUSE_TRIM_LENGTH_Msk (0x1FU << EFUSE_TRIM_LENGTH_Pos) +#define EFUSE_TRIM_LENGTH EFUSE_TRIM_LENGTH_Msk + +/******************* Bit definition for EFUSE_TRIM register **************/ +#define EFUSE_TRIM_Pos (0U) +#define EFUSE_TRIM_Len (32U) +#define EFUSE_TRIM_Msk (0xFFFFFFFFU) +#define EFUSE_TRIM EFUSE_TRIM_Msk + +/* =============================================================================================================== */ +/* ================ RNG ================ */ +/* =============================================================================================================== */ +/******************* Bit definition for RNG_CTRL register **********/ +#define RNG_CTRL_RUN_EN_Pos (0U) +#define RNG_CTRL_RUN_EN_Len (1U) +#define RNG_CTRL_RUN_EN_Msk (0x1UL << RNG_CTRL_RUN_EN_Pos) +#define RNG_CTRL_RUN_EN RNG_CTRL_RUN_EN_Msk + +/******************* Bit definition for RNG_STATUS register **********/ +#define RNG_STATUS_READY_Pos (0U) +#define RNG_STATUS_READY_Len (1U) +#define RNG_STATUS_READY_Msk (0x1UL << RNG_STATUS_READY_Pos) +#define RNG_STATUS_READY RNG_STATUS_READY_Msk + +/******************* Bit definition for RNG_DATA register **********/ +#define RNG_DATA_VALUE_Pos (0U) +#define RNG_DATA_VALUE_Len (32U) +#define RNG_DATA_VALUE_Msk (0xFFFFFFFF) +#define RNG_DATA_VALUE RNG_DATA_VALUE_Msk + +/******************* Bit definition for RNG_LR_STATUS register *********/ +#define RNG_LR_STATUS_FLAG_Pos (0U) +#define RNG_LR_STATUS_FLAG_Len (1U) +#define RNG_LR_STATUS_FLAG_Msk (0x1UL << RNG_LR_STATUS_FLAG_Pos) +#define RNG_LR_STATUS_FLAG RNG_LR_STATUS_FLAG_Msk +#define RNG_LR_STATUS_CNT_Pos (1U) +#define RNG_LR_STATUS_CNT_Len (8U) +#define RNG_LR_STATUS_CNT_Msk (0xFFUL << RNG_LR_STATUS_CNT_Pos) +#define RNG_LR_STATUS_CNT RNG_LR_STATUS_CNT_Msk + +/******************* Bit definition for RNG_CONFIG register ************/ +#define RNG_CONFIG_OUT_MODE_Pos (0U) +#define RNG_CONFIG_OUT_MODE_Len (4U) +#define RNG_CONFIG_OUT_MODE_Msk (0xFUL << RNG_CONFIG_OUT_MODE_Pos) +#define RNG_CONFIG_OUT_MODE RNG_CONFIG_OUT_MODE_Msk +#define RNG_CONFIG_LFSR_XOR_SEL_Pos (4U) +#define RNG_CONFIG_LFSR_XOR_SEL_Len (3U) +#define RNG_CONFIG_LFSR_XOR_SEL_Msk (0x7UL << RNG_CONFIG_LFSR_XOR_SEL_Pos) +#define RNG_CONFIG_LFSR_XOR_SEL RNG_CONFIG_LFSR_XOR_SEL_Msk +#define RNG_CONFIG_POST_MODE_Pos (7U) +#define RNG_CONFIG_POST_MODE_Len (2U) +#define RNG_CONFIG_POST_MODE_Msk (0x3UL << RNG_CONFIG_POST_MODE_Pos) +#define RNG_CONFIG_POST_MODE RNG_CONFIG_POST_MODE_Msk +#define RNG_CONFIG_LFSR_MODE_Pos (9U) +#define RNG_CONFIG_LFSR_MODE_Len (1U) +#define RNG_CONFIG_LFSR_MODE_Msk (0x1UL << RNG_CONFIG_LFSR_MODE_Pos) +#define RNG_CONFIG_LFSR_MODE RNG_CONFIG_LFSR_MODE_Msk +#define RNG_CONFIG_LFSR_SEED_SEL_Pos (10U) +#define RNG_CONFIG_LFSR_SEED_SEL_Len (3U) +#define RNG_CONFIG_LFSR_SEED_SEL_Msk (0x7UL << RNG_CONFIG_LFSR_SEED_SEL_Pos) +#define RNG_CONFIG_LFSR_SEED_SEL RNG_CONFIG_LFSR_SEED_SEL_Msk +#define RNG_CONFIG_IRQ_EN_Pos (13U) +#define RNG_CONFIG_IRQ_EN_Len (1U) +#define RNG_CONFIG_IRQ_EN_Msk (0x1UL << RNG_CONFIG_IRQ_EN_Pos) +#define RNG_CONFIG_IRQ_EN RNG_CONFIG_IRQ_EN_Msk +#define RNG_CONFIG_FRO_EN_Pos (15U) +#define RNG_CONFIG_FRO_EN_Len (1U) +#define RNG_CONFIG_FRO_EN_Msk (0x1UL << RNG_CONFIG_FRO_EN_Pos) +#define RNG_CONFIG_FRO_EN RNG_CONFIG_FRO_EN_Msk + +/******************* Bit definition for RNG_TSCON register *************/ +#define RNG_TSCON_TRDY_TIME_Pos (0U) +#define RNG_TSCON_TRDY_TIME_Len (8U) +#define RNG_TSCON_TRDY_TIME_Msk (0xFUL << RNG_TSCON_TRDY_TIME_Pos) +#define RNG_TSCON_TRDY_TIME RNG_TSCON_TRDY_TIME_Msk +#define RNG_TSCON_FRO_CHAIN_Pos (11U) +#define RNG_TSCON_FRO_CHAIN_Len (4U) +#define RNG_TSCON_FRO_CHAIN_Msk (0xFUL << RNG_TSCON_FRO_CHAIN_Pos) +#define RNG_TSCON_FRO_CHAIN RNG_TSCON_FRO_CHAIN_Msk + +/******************* Bit definition for RNG_FROCFG register *************/ +#define RNG_FROCFG_CHAINE_EN_Pos (0U) +#define RNG_FROCFG_CHAINE_EN_Len (8U) +#define RNG_FROCFG_CHAINE_EN_Msk (0xFFUL << RNG_FROCFG_CHAINE_EN_Pos) +#define RNG_FROCFG_CHAINE_EN RNG_FROCFG_CHAINE_EN_Msk +#define RNG_FROCFG_TEST_IN_Pos (8U) +#define RNG_FROCFG_TEST_IN_Len (8U) +#define RNG_FROCFG_TEST_IN_Msk (0xFFUL << RNG_FROCFG_TEST_IN_Pos) +#define RNG_FROCFG_TEST_IN RNG_FROCFG_TEST_IN_Msk + +/******************* Bit definition for RNG_USER_SEED register *************/ +#define RNG_USER_SEED_Pos (0U) +#define RNG_USER_SEED_Len (16U) +#define RNG_USER_SEED_Msk (0xFFUL << RNG_USER_SEED_Pos) +#define RNG_USER_SEED RNG_USER_SEED_Msk + +/******************* Bit definition for RNG_LRCON register *****************/ +#define RNG_LRCON_TEST_EN_Pos (0U) +#define RNG_LRCON_TEST_EN_Len (1U) +#define RNG_LRCON_TEST_EN_Msk (0x1UL << RNG_LRCON_TEST_EN_Pos) +#define RNG_LRCON_TEST_EN RNG_LRCON_TEST_EN_Msk +#define RNG_LRCON_TEST_LIMIT_Pos (1U) +#define RNG_LRCON_TEST_LIMIT_Len (5U) +#define RNG_LRCON_TEST_LIMIT_Msk (0x1FUL << RNG_LRCON_TEST_LIMIT_Pos) +#define RNG_LRCON_TEST_LIMIT RNG_LRCON_TEST_LIMIT_Msk + +/** @} */ /* End of group Peripheral_Registers_Bits_Definition */ + +/** @addtogroup Exported_macros + * @{ + */ +/****************************** GPIO instances ********************************/ +#define IS_GPIO_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == GPIO0) || \ + ((__INSTANCE__) == GPIO1)) + +/****************************** I2C instances *********************************/ +#define IS_I2C_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == I2C0) || \ + ((__INSTANCE__) == I2C1)) + +/****************************** I2S instances *********************************/ +#define IS_I2S_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == I2S_M) || \ + ((__INSTANCE__) == I2S_S)) + +/****************************** UART instances ********************************/ +#define IS_UART_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == UART0) || \ + ((__INSTANCE__) == UART1)) + +/******************** UART instances : Support of DMA *************************/ +#define IS_UART_DMA_INSTANCE(__INSTANCE__) (((__INSTANCE__) == UART0)) + +/****************************** TIM instances *********************************/ +#define IS_TIMER_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == TIMER0) || \ + ((__INSTANCE__) == TIMER1)) + +/****************************** DUAL TIM instances ****************************/ +#define IS_DUAL_TIM_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == DUAL_TIMER0) || \ + ((__INSTANCE__) == DUAL_TIMER1)) + +/****************************** PWM instances *********************************/ +#define IS_PWM_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == PWM0) || \ + ((__INSTANCE__) == PWM1)) + +/****************************** WDT instances *********************************/ +#define IS_WDT_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == WDT)) + +/****************************** SPI instances *********************************/ +#define IS_SPI_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == SPIM) || \ + ((__INSTANCE__) == SPIS)) + +/****************************** QSPI instances ********************************/ +#define IS_QSPI_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == QSPI0) || \ + ((__INSTANCE__) == QSPI1)) + +/****************************** PKC instances *********************************/ +#define IS_PKC_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == PKC)) + +/****************************** AES Instances *********************************/ +#define IS_AES_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == AES)) + +/****************************** HMAC Instances ********************************/ +#define IS_HMAC_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == HMAC)) + +/****************************** XQSPI Instances *******************************/ +#define IS_XQSPI_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == XQSPI)) + +/****************************** EFUSE Instances *******************************/ +#define IS_EFUSE_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == EFUSE)) + +/****************************** RNG Instances *******************************/ +#define IS_RNG_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == RNG)) + + +/** @} */ /* End of group Exported_macros */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __GR551xx_H__ */ + +/** @} */ /* End of group GR551xx */ + +/** @} */ /* End of group CMSIS_Device */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr55xx.h b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr55xx.h new file mode 100644 index 0000000..c35bde9 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/gr55xx.h @@ -0,0 +1,207 @@ +/**************************************************************************//** + * @file gr55xx.h + * @brief CMSIS Cortex-M# Core Peripheral Access Layer Header File for + * Device GR55xx + * @version V1.00 + * @date 12. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2016-2018, Shenzhen Huiding Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +/** @addtogroup CMSIS_Device + * @{ + */ + +/** @addtogroup GR55xx + * @{ + */ + +#ifndef __GR55xx_H__ +#define __GR55xx_H__ +#ifndef CFG_LAYER_TAG_SDK +#ifndef CFG_LAYER_TAG_ROM +#include "custom_config.h" +#endif +#endif + +#if defined (__GNUC__) +#define __ramfunc __attribute__((noinline)) \ + __attribute__((long_call, section(".ramfunc"))) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief GR55 Family + */ +#if !defined (GR55) +#define GR55 +#endif /* GR55 */ + +/* Uncomment the line below according to the target GR55 device used in your + application + */ +#if !defined (GR551xx) + #define GR551xx +#endif + +/** @} */ + +/** @addtogroup Device_Included + * @{ + */ +#if defined(GR551xx) + #include "gr551xx.h" + + #define GR55XX_RAM_ADDRESS 0x30000000 + #define GR55XX_FLASH_ADDRESS 0x01000000 + #define GR55XX_ALIAS_ADDRESS 0x00800000 +#else + #error "Please select first the target GR55xx device used in your application (in gr551xx.h file)" +#endif + +/** @} */ + +/** @addtogroup Exported_types + * @{ + */ + +typedef enum +{ + RESET = 0, + SET = !RESET +} flag_status_t, it_status_t; + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} functional_state_t; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum +{ + ERROR = 0, + SUCCESS = !ERROR +} error_status_t; + +/** @} */ + +/** @addtogroup Exported_macros + * @{ + */ +#ifndef SET_BITS +#define SET_BITS(REG, BIT) ((REG) |= (BIT)) +#endif + +#ifndef CLEAR_BITS +#define CLEAR_BITS(REG, BIT) ((REG) &= ~(BIT)) +#endif + +#ifndef READ_BITS +#define READ_BITS(REG, BIT) ((REG) & (BIT)) +#endif + +#ifndef CLEAR_REG +#define CLEAR_REG(REG) ((REG) = (0x0)) +#endif + +#ifndef WRITE_REG +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) +#endif + +#ifndef READ_REG +#define READ_REG(REG) ((REG)) +#endif + +#ifndef MODIFY_REG +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) +#endif + +#ifndef POSITION_VAL +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) +#endif + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +#ifndef SECTION_RAM_CODE +#if defined(CFG_LAYER_TAG_ROM) + #define SECTION_RAM_CODE +#else +#if defined ( __ICCARM__ ) || defined (__GNUC__) + #define SECTION_RAM_CODE __ramfunc +#else + #define SECTION_RAM_CODE __attribute__((section("RAM_CODE"))) /**< To prevent doxygen from misidentifying the function name */ +#endif +#endif +#endif + +#ifndef C_CONSTRUCTOR +#if defined ( __ICCARM__ ) +#define C_CONSTRUCTOR +#else +#define C_CONSTRUCTOR __attribute__((constructor)) +#endif +#endif + +#ifndef TINY_RAM_SECTION + #define TINY_RAM_SECTION SECTION_RAM_CODE +#endif + +#ifndef RESERVE_RAM_SECTION +#if defined ( __CC_ARM ) +#define RESERVE_RAM_SECTION __attribute__((section("RAM_RESERVE"),zero_init)) /**< To prevent doxygen from misidentifying the function name */ +#endif +#endif + +/** @brief Disable interrupts globally in the system(apart from the NMI). + * This macro must be used in conjunction with the @ref GLOBAL_EXCEPTION_ENABLE macro + * since this last one will close the brace that the current macro opens. This means + * that both macros must be located at the same scope level. + */ +#define GLOBAL_EXCEPTION_DISABLE() \ +do { \ + uint32_t __l_irq_rest = __get_PRIMASK(); \ + __set_PRIMASK(1) + + +/** @brief Restore interrupts from the previous global disable(apart from the NMI). + * @sa GLOBAL_EXCEPTION_ENABLE + */ +#define GLOBAL_EXCEPTION_ENABLE() \ + __set_PRIMASK(__l_irq_rest); \ +} while(0) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GR55xx_H__ */ + +/** @} */ + +/** @} */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/grx_soc_reg.h b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/grx_soc_reg.h new file mode 100644 index 0000000..ba8e3d5 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/grx_soc_reg.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file grx_soc_reg.h + * @brief The SOC chip register header file contains. + * + * @version V1.00 + * @date 12. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2016-2018, Shenzhen Huiding Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 __GRX_SOC_REG_H__ +#define __GRX_SOC_REG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gr55xx.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_GR55xx_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/system_gr55xx.h b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/system_gr55xx.h new file mode 100644 index 0000000..e84ebbe --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/include/system_gr55xx.h @@ -0,0 +1,92 @@ +/**************************************************************************//** + * @file system_gr55xx.h + * @brief CMSIS Cortex-M# Device Peripheral Access Layer Header File for + * Device GR55xx + * @version V1.00 + * @date 12. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2016-2018, Shenzhen Huiding Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 __SYSTEM_GR55xx_H__ +#define __SYSTEM_GR55xx_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define CLK_64M 64000000 +#define CLK_48M 48000000 +#define CLK_32M 32000000 +#define CLK_24M 24000000 +#define CLK_16M 16000000 + +typedef enum +{ + XO_S16M_CLK = 2, + CPLL_S16M_CLK = 4, + CPLL_T24M_CLK = 3, + CPLL_T32M_CLK = 5, + CPLL_F48M_CLK = 1, + CPLL_S64M_CLK = 0, + CLK_TYPE_NUM = 6, +} mcu_clock_type_t; + +typedef enum +{ + QSPI_64M_CLK = 0, + QSPI_48M_CLK = 1, + QSPI_32M_CLK = 2, + QSPI_24M_CLK = 3, + QSPI_16M_CLK = 4, + QSPI_CLK_TYPE_NUM = 5, +} qspi_clock_type_t; + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** @brief Setup the microcontroller system. + + Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit(void); + +/** \brief Update SystemCoreClock variable. + + Updates the SystemCoreClock with current core Clock + retrieved from cpu registers. + */ +extern void SystemCoreSetClock(mcu_clock_type_t clock); + +/** \brief Get SystemCoreClock variable. + + Get the SystemCoreClock with current core Clock + retrieved from cpu registers. + */ +extern void SystemCoreGetClock(mcu_clock_type_t *clock); + + +extern void SystemCoreUpdateClock(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_GR55xx_H__ */ diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5513.lds b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5513.lds new file mode 100644 index 0000000..d981917 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5513.lds @@ -0,0 +1,116 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01002000, LENGTH = (0x00800000 -0x00002000) + RAM (rwx) : ORIGIN = 0x30000000 +0x4000, LENGTH = (0x00020000 -0x4000) +} + +GROUP(libgcc.a libc.a libm.a libnosys.a) +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + . = ALIGN(0x200); + KEEP(*(.app_info)) + *( .text*) + KEEP(*(.init)) + KEEP(*(.fini)) + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + *(.rodata*) + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + *(.ramfunc) + *(RAM_CODE) + *(TINY_RAM_SPACE) + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; + } > RAM + + .my_section : + { + . = ALIGN(32); + *(FPB*) + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + __sstack = __StackLimit; + __estack = __StackTop; + + PROVIDE(__stack = __StackTop); + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5515.lds b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5515.lds new file mode 100644 index 0000000..60a2a07 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/gcc_linker_gr5515.lds @@ -0,0 +1,116 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x01002000, LENGTH = (0x00800000 -0x00002000) + RAM (rwx) : ORIGIN = 0x30000000 +0x4000, LENGTH = (0x00040000 -0x4000) +} + +GROUP(libgcc.a libc.a libm.a libnosys.a) +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + . = ALIGN(0x200); + KEEP(*(.app_info)) + *( .text*) + KEEP(*(.init)) + KEEP(*(.fini)) + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + *(.rodata*) + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + *(.ramfunc) + *(RAM_CODE) + *(TINY_RAM_SPACE) + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; + } > RAM + + .my_section : + { + . = ALIGN(32); + *(FPB*) + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + __sstack = __StackLimit; + __estack = __StackTop; + + PROVIDE(__stack = __StackTop); + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/hardfloat_lib/libble_sdk.a b/gr551x/sdk_liteos/gr551x_sdk/platform/soc/linker/gcc/hardfloat_lib/libble_sdk.a new file mode 100644 index 0000000000000000000000000000000000000000..4f2eca1e4971dead876794c4d1f32f89e58d014c GIT binary patch literal 4943310 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�#TSsS@_eGmz2L{-e_RTpyy--s^PLj_=5xm} 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

    #y+<_9Q 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

    e=RMRaB+(bd@$8h=`eiY&%QT`J84 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%0AV{>ZsAzBCM1WkqIdgN9in&{JG^2 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μ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

    !z~f|>J;Ls1>;#r@ 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�+(|eqvog=-YDOwx8&893Z`UTGJ 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%0AE$jp5ZbVr2>O;`Lj-|^ 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Ν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

      M^eb-U)k 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 z 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°I{3x%2Yi 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

      T7u7_O7^I0kqk5glAv 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%0Axd~u~S!kDZMBW3c` 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ńwO+l@ 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 z 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 z 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೬IJZ;`((X`I?3EBv0v8nRP~U=fmtUo@WT?L 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 Zg+ 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 $+ewb^qKeNpWno`!k12Kg5T&FGtr@%c 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

    {_7^2kF50#{`4W7)B@ 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 M_D265uSx#@0A6;SU;qFB literal 0 HcmV?d00001 diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_common_tables.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_common_tables.h new file mode 100644 index 0000000..721b18d --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_common_tables.h @@ -0,0 +1,517 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + /* Double Precision Float CFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024) + extern const uint16_t armBitRevTable[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_16) + extern const uint64_t twiddleCoefF64_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_32) + extern const uint64_t twiddleCoefF64_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_64) + extern const uint64_t twiddleCoefF64_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_128) + extern const uint64_t twiddleCoefF64_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_256) + extern const uint64_t twiddleCoefF64_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_512) + extern const uint64_t twiddleCoefF64_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_1024) + extern const uint64_t twiddleCoefF64_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_2048) + extern const uint64_t twiddleCoefF64_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_4096) + extern const uint64_t twiddleCoefF64_4096[8192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) + extern const float32_t twiddleCoef_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + extern const float32_t twiddleCoef_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) + extern const float32_t twiddleCoef_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + extern const float32_t twiddleCoef_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) + extern const float32_t twiddleCoef_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + extern const float32_t twiddleCoef_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) + extern const float32_t twiddleCoef_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + extern const float32_t twiddleCoef_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) + extern const float32_t twiddleCoef_4096[8192]; + #define twiddleCoef twiddleCoef_4096 + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) + extern const q31_t twiddleCoef_16_q31[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + extern const q31_t twiddleCoef_32_q31[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) + extern const q31_t twiddleCoef_64_q31[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + extern const q31_t twiddleCoef_128_q31[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) + extern const q31_t twiddleCoef_256_q31[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + extern const q31_t twiddleCoef_512_q31[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) + extern const q31_t twiddleCoef_1024_q31[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + extern const q31_t twiddleCoef_2048_q31[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) + extern const q31_t twiddleCoef_4096_q31[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) + extern const q15_t twiddleCoef_16_q15[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + extern const q15_t twiddleCoef_32_q15[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) + extern const q15_t twiddleCoef_64_q15[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + extern const q15_t twiddleCoef_128_q15[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) + extern const q15_t twiddleCoef_256_q15[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + extern const q15_t twiddleCoef_512_q15[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) + extern const q15_t twiddleCoef_1024_q15[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + extern const q15_t twiddleCoef_2048_q15[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) + extern const q15_t twiddleCoef_4096_q15[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + /* Double Precision Float RFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_32) + extern const uint64_t twiddleCoefF64_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_64) + extern const uint64_t twiddleCoefF64_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_128) + extern const uint64_t twiddleCoefF64_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_256) + extern const uint64_t twiddleCoefF64_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_512) + extern const uint64_t twiddleCoefF64_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_1024) + extern const uint64_t twiddleCoefF64_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_2048) + extern const uint64_t twiddleCoefF64_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_4096) + extern const uint64_t twiddleCoefF64_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32) + extern const float32_t twiddleCoef_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64) + extern const float32_t twiddleCoef_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128) + extern const float32_t twiddleCoef_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256) + extern const float32_t twiddleCoef_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512) + extern const float32_t twiddleCoef_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024) + extern const float32_t twiddleCoef_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048) + extern const float32_t twiddleCoef_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096) + extern const float32_t twiddleCoef_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* Double precision floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_16) + #define ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTableF64_16[ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_32) + #define ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTableF64_32[ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_64) + #define ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTableF64_64[ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_128) + #define ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTableF64_128[ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_256) + #define ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTableF64_256[ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_512) + #define ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTableF64_512[ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_1024) + #define ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTableF64_1024[ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_2048) + #define ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTableF64_2048[ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_4096) + #define ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTableF64_4096[ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + /* floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16) + #define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) + extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32) + #define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) + extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64) + #define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128) + #define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) + extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256) + #define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) + extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512) + #define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) + extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024) + #define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) + extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048) + #define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) + extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096) + #define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* fixed-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16) + #define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32) + #define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64) + #define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128) + #define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256) + #define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512) + #define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024) + #define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048) + #define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096) + #define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32) + extern const float32_t realCoefA[8192]; + extern const float32_t realCoefB[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31) + extern const q31_t realCoefAQ31[8192]; + extern const q31_t realCoefBQ31[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15) + extern const q15_t realCoefAQ15[8192]; + extern const q15_t realCoefBQ15[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128) + extern const float32_t Weights_128[256]; + extern const float32_t cos_factors_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512) + extern const float32_t Weights_512[1024]; + extern const float32_t cos_factors_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048) + extern const float32_t Weights_2048[4096]; + extern const float32_t cos_factors_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192) + extern const float32_t Weights_8192[16384]; + extern const float32_t cos_factors_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128) + extern const q15_t WeightsQ15_128[256]; + extern const q15_t cos_factorsQ15_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512) + extern const q15_t WeightsQ15_512[1024]; + extern const q15_t cos_factorsQ15_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048) + extern const q15_t WeightsQ15_2048[4096]; + extern const q15_t cos_factorsQ15_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192) + extern const q15_t WeightsQ15_8192[16384]; + extern const q15_t cos_factorsQ15_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128) + extern const q31_t WeightsQ31_128[256]; + extern const q31_t cos_factorsQ31_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512) + extern const q31_t WeightsQ31_512[1024]; + extern const q31_t cos_factorsQ31_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048) + extern const q31_t WeightsQ31_2048[4096]; + extern const q31_t cos_factorsQ31_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192) + extern const q31_t WeightsQ31_8192[16384]; + extern const q31_t cos_factorsQ31_8192[8192]; + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */ + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES) + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15) + extern const q15_t armRecipTableQ15[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31) + extern const q31_t armRecipTableQ31[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + /* Tables for Fast Math Sine and Cosine */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32) + extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31) + extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15) + extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE) + extern const q31_t sqrtTable_Q31[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE) + extern const q15_t sqrtTable_Q15[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */ + +#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) + extern const float32_t exp_tab[8]; + extern const float32_t __logf_lut_f32[8]; +#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) */ + +#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) +extern const unsigned char hwLUT[256]; +#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */ + +#endif /* ARM_COMMON_TABLES_H */ + diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_const_structs.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_const_structs.h new file mode 100644 index 0000000..83984c4 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_const_structs.h @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.h + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() function. + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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 _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len16; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len32; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len64; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len128; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len256; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len512; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len1024; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len2048; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len4096; + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_math.h b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_math.h new file mode 100644 index 0000000..48bee62 --- /dev/null +++ b/gr551x/sdk_liteos/gr551x_sdk/components/libraries/CMSIS/cmsis_dsp/include/arm_math.h @@ -0,0 +1,8970 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.7.0 + * @date 18. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M and Cortex-A processor + * based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filtering functions + * - Matrix functions + * - Transform functions + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * - Support Vector Machine functions (SVM) + * - Bayes classifier functions + * - Distance functions + * + * The library has generally separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * + * Here is the list of pre-built libraries : + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library is now tested on Fast Models building with cmake. + * Core M0, M7, A5 are tested. + * + * + * + * Building the Library + * ------------ + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP\\Projects\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * There is also a work in progress cmake build. The README file is giving more details. + * + * Preprocessor Macros + * ------------ + * + * Each library project have different preprocessor macros. + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_LOOPUNROLL: + * + * Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions + * + * - ARM_MATH_NEON: + * + * Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions. + * It is not enabled by default when Neon is available because performances are + * dependent on the compiler and target architecture. + * + * - ARM_MATH_NEON_EXPERIMENTAL: + * + * Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of + * of some DSP functions. Experimental Neon versions currently do not have better + * performances than the scalar versions. + * + * - ARM_MATH_HELIUM: + * + * It implies the flags ARM_MATH_MVEF and ARM_MATH_MVEI and ARM_MATH_FLOAT16. + * + * - ARM_MATH_MVEF: + * + * Select Helium versions of the f32 algorithms. + * It implies ARM_MATH_FLOAT16 and ARM_MATH_MVEI. + * + * - ARM_MATH_MVEI: + * + * Select Helium versions of the int and fixed point algorithms. + * + * - ARM_MATH_FLOAT16: + * + * Float16 implementations of some algorithms (Requires MVE extension). + * + *

zpY*z!TG%>f8t01HrwePC=h6zymVMG;7MwU|mSn8Wl*B2_9K%;J4@Qg3-1D`VcDp%d zie63Tr>&W0IJgEgiE+lvELxp8>wdy4^oklY8h6yJZ)gd#8gE9qhJfRR^>%>1qmft>Rj%%~HCV75fp zjN>u@%9&bb1{wX}sgz}Alh3|@j3a;HMr(UPwdh&6c-LpJc;`5L%cX7*?>7t&8U6s? z@*IHQc6<-6$M?XuoqY>NSigr;pLK%gpdIkEb#K6j>)PNNVXwg!jVAbq;&!lM{xSUb z#0#)^v>G1m-UcT2-GdwPT0onwn{bn^=itldSK;ySXJFXFOK`0tjbLZl1^BO;2GFTU z1vl5K2bozCc;SvZ@F9-}k1u)z_NIbx*2F{b=h3t9@1zIdK-4LCwzwL6w&OTl@wpOI zc^`&#Pb63#0r0-qL{!6W}%0@GE- zaJK(N5W&%h&tA$0E0Wj3@6F_b*h8z}4>w-`b3&KH*X5rBfA}rJ?oMWdmL9)h1&l1v z-~Qjpo~r~SVLxHvlX7tHx^FOhZyD&l>?sG zNrp9piQtog1Q@0FI0);EgRLMQ1OI98V20U8z=FFGu#;19;NwfXVWwLTgRRo-u#Gnl zf(_~Zu$`-7!Qvy{ux|%qz@%^rtgdk%i1u@X4Vg!SZwOAX-9RL`&l&^U)VCM>Vt|4n z{#77*Yg)k07KDMh(@+?ENhsLeZvb1jHw4spy$j5O4+^yyd25Kk#4yPG~wBfCGQS z*rpnl4xqbEhUp;_EO=x-#ngyx4+;hoO%2BEK;`Rr)5u_3kXL)abnX!fJX9KK`oYQ? zbXJ9$YRRm?@r)g&-~s|v#RZu9?6UwZcWpM^^U@3~qEbyCxxhhfdw0{rMW$esk+bPO zT@$cK18Z8EVhp|>N0|}_jlhv^3)4-3o4|=C6H{8P0r>Tfq3Hu_eeg-{deii*4WN*t zZ7NaM1E~p`rX$DJf#1TGnkswNfF~FWCOkh~Z~{AR(psYp?lK-T39()c-qieVg3DP6 zj*j=4gs#v6jk>!{+D~eNj*VR=l5fjF*Rpn#++cMOb*|ZDrb!K42{xFVcU}s+2?V|IGsgy(=bxM}GrFfAdZ1`(}ap!5owH?K1$e zU2ejCHU%845}Nc7CIRLpwn^r#aX`q=Fga%S3&==3ZE_=P6o?2*GQq9>383jmOjc$L z1K;gpO;9u60kM9RNzS1m0KO#5BWU-uq(u-4Q>oBtL# z{oBxFoq88w`DMLHRO%bx@iT3crL(UATA8NF@X=R5W!6#?`0z_WKWzbeW#0=RdjB-^ zL~kpQ>o*3K?`{F=9lt~WbUg>UjQXK>0-ph0YM-FxFB*aR?_E%JpQk`>dpoqCsUC=` zXohmAPXPVA254>FW1teOg?e~A0_cY-p*jyA0(D#OK#_z80Mhw7R9aOHoP}P2(wwV+ zI`sl5y`lp6^&b2(sLlkGI?Y2DNy%iQJe|G`6uWbXRg`Ed7 zCoG`Uz8t{ytqD{TlMVFN7($UhRX}3FdZoQKS zWdZ8(?Z$V!m_YT`W@GzT01%FAFkT4B1jY<%jn@yP195*Uj87d&13vWJHnyHm1svCAmL+*@%L{>0c35W@%f}9Kx;v~@wsL3Ksa!~ctCm>__Qz5IMwtJ;KK+t zj=B{KT(RC^taLvBjI9nZ)_buZK#X}C_k`^Od|pwE=YB>3;dkAP!_Gzm;YugtHM$Xi z-${(IZowYFdKb!gHzpjIcC|2`dJ+oUgqRqA*tQ$k_Md^V_P1TY_nvjeg5;gR;kwnv zyH*DSpDt+_AJ5+oxPeQI-(j}_ynXW!L1Q5Bls*L!glq-IEJq>lNBsc}tszJPumxEC z;|nCjzzxAe~HUoDBFCpFU7{Kwk=a89rFTi9=JtTZN9jLZ@2w8W5 z3Q%+_AbJiIpk}NL64~qtz}ib8e43hWK5y0t9>_ zB+%UwxO@-~Df(yuT=%wzP?F7oOIFqpw7wa@(lm!0D2D;N28|)3L8gGwQ+-I?1Qci~ zTnqUkH3kl5{sZ4&Ai&(-YbXjEMVI{?F5u$3ykK;h8avVK9rCv1O}>N~Kbkyjmn{)`ZAT*6h1E_gX5V zeG!%Ry(q2BxkZvTeJjzTl2qDPDJ{SI&yNqE*S+_gbI*C-=Q+#!-g{3G@8D_OXUg27 zLnSA4|2xVlnjUdTm+z%iROhfqxB5G~NJoFWZrV15qO@Up7d~JWHFmGnRqbaKeK}pG zd%f%*Dcw-4+co(wIbnIB?v$?I6a?u{|ONJUP9uG)ZJdFHK+ z?nnLyl6iHS?yC#$NSnPDy5pnXk`ZW}u3X~{nYYAPx8}lYvS_BB?$xMQWR9jpcedaq zx%88UE=T@?oOXk&tGld^{CPk@H(&gmJXZ8a$GrI&>ACcW&e-IqWS`AvokYDSWR&Es z4(r-u^8V)+I{jIX$Qd`E=!i`ok}D2&>#V=mO|})?(OFW|MGl7C&`GzvPiop+(dq8J zM;ePS>Xfa!OB#MUud{0Q9a8Q3DV@&Gx5m#o8%~~ zY8}-x*U7W|O*#)^u90)zR_c7$ZYP^sSL%e^Xd_K(NgYku6;hU)uOqc=C9nEs>csZ9 zkjzQTb(E@_Ni%Mo&S$qvA>-uaxD+p)-3CqMKNnXW zjm`_?l`)Pw*UHY5`G4(o?l_zyM|aQEG5v9dJYR3AbM4q^63Qp&T!?HSPe+>Q{Lno` z>e?IX5O?dz6se9*KzSW`=95ULaPA56UAvmjr{QCyU=K&9uHh(Yn$OgcCmtau_zi1I zO%IdC7T>k0X9r0R=cD$iZ3oE5PhV>f`tB!ppL?!dqOp(kU-wu${MsJ!_p*w6oX3yS5N_DSkU;Vw4toYiZ{pj2d^6PcEwoS%%(s}P$?N?K3$Tj)(+PxpPk*&T* zw9SrIk#8sL)5goTk}SoY+O?)zNN&$o?T-FUC%eEBv_dwy6YS=f@Oy}_u0&&W^v*4UL~<&cN=j#s7R)s6+)jfYCeulwg{nPBg^m<43w3aNHkYaXc=BG3*i%OxA9scIK5 z%pqM>6}1O7v&rkdf3+GOW|DU2hO{o$W{^87zi8>iq?4Z_-)UW(m_|;ueW`W&TM8K? zc&7EEaXDH3>VZ~iQ8HO8zpEAQnndo~a8s*7lt@-DYtv#sjweaDq}9GRjtmqxYCTR| zMjF3u(6XBmOFp`ITx)<4LzZklsP*Dn6ls{STWjK`Nb<<+8m;D~5#%`OX083^;pC=w zYqYw)hmv0}tueArYmdhJvX16z-4LOD03t&dxoX6gXfWE_1~rJ$#Y3T$w#SJ zVGj9b@qje#z5{uBLZ4LsFp$d`JyNYgdvesh`_d5aS!C0J+tRNlcBEV0HEHLt4SCb! zvXuRwH3`O8O6;FW?)iRJ>Xtu)9J*RBjr6u6?Q4!muZ^2dW+v~G7XF(`?wqqzD!Xq< zUJzGFZylRLUU|J<8doxzyxh22>Ki9 zUoQir4G+^ z$*(I$Noy$`@@arn>b_l@l#drko$|EEia#pSwEX5`{ zP(<3#`yx5tDJ0v(?EeDe6YrxN8%4U$*(K!O*klS_i`N-oV%BX>@? zDG_S($h&{8Na}y7kUwu-lXSx zgp#?5By`~i;_^=eiKX>>BBNbf;x+mmp;aZ4V70fzu~;=p&d>lcZ6-%T^t~pIbC{Cu zTdxS+u3zH(3onVB{olk%`}>LO86U*Q*1sUs9bb!WWqpLB=5w(m;W?4m_ecx@y~N6s zo#Hd|pAnmh4sqVJr^FV|c5#LA6JnJ?i}(Y-he-a=B(C}Qh;Wjh5pVtQkPxn}6ZiH! zAUXmMi*s&v6Ed^C;t+WkVKlT|y#CmI;_Q_zV$qIH!hX{_ac|{4;(SE8_^<3PVPaV# zUY2r)C}qgRMiKuJ4{l|PP5o{Y2HR7`c}^XKe|&;?l+7)Iw2l_@Cf+1!IiX?~!y80> zXMng#04Ff ziPM=DVzbs3B6!|7@#w~8Vn|>tj<3H&ls?rJGY?)Ql#YqT{W~ZkH&;U}-HeG|C$4x) zg`BVvD~KaYnurz8e{0GL8i}?OgPH>w7l@zvpEPTe&JzYMZ#4JCoFisRUuX`6o+TV# z^k`NEo+0MdcWJKlJxy2@{-=4_qk+(Ky{@^?`4sU@+Nx1&G_7NNBCux4u-Af!7#%c!Z z?jf3AEs)?vslQmmMZzEV-b4?qQDq{V;(VBn8Z6zeNqcqhgY#}P+rJ9M8 zHWNRs1e!WiHxY|js+!^%8;Qd=*_t7?8;H+a|BAlBdcr(%Nc3RdI%4spFCw1HS|aDy zTT#WrHAH1=zi5eHC9!4gQ&DzM1+gLMfv7KRHBn@8S5y;QPQ-k^A=;B%MnKaQ(NN|p zLS@B8(YC^s#5J!AqVm!eM1fv|=vrkdG3M1Vk^hzwf~r3tvaBs8-1B#df({iCx93-j z{yRw$^97qko0|xt{!yjq&=o{z>|ZHT`ArKbR5^|nt*u>7KWt$j zGOSA`8oISaf2ky5@@}EX{B|Ny8_yH%eU?BdPFE5oe2yoA|Naw_ta##Z+fU(3Q5^AZ z?N?#d*ky!K;Co@!j99{T^ef?O=NKaH-7{hFl4v6T^h05CauiWicu#ncj3i`Ew}g{6 zM-a*Ut3vkSaKh)oC7~$}BgXG;6mGo}O8ksFEnNI+DRE)y31QUl5Muf7gThOK5JIa&;d z<`ORgpLZ3?Gd&48;V2wlyO22P48qbQ9z?akS{Qo8oyd7$DO}m>M!4>pApG~+l@Kj6 z5w>W#5*?Ebh4-hq5NJqSXyxThm|PSI`x6%smsY3=pO-lio(nlbi-YrtP6<=k*6K)j zJozO!-Zzhs@B1cr!JJ1JCVmja8qOuMr@a=~z#O7=xK|JuGMnJEJQB1QI1u(_or2Qs zK*V`<2-eE&iE^!W!9dR}V)xT#!MeY8#IgNNf>HxoCY}*obFd|LPpcCIh1(Dn!-oX6 z#nwbZ^BzIm{+Yz=RoewGug)M;Jhuqy-&zsvl68W1bt|Hvr%W)}ayntUw^;DfZyM1W zS11_BnMwpq$rjk|uq2-UND{dSJ zmsX4-I3NYp0wj62J3sMaF- z-`DYPwM&Unrw;S2h9rb*_Fn!w6A6(tYX|?cpO{#|+RC3-qDgFSTgUHj5E0d@%lY?S z2#HNzC48Y+NR&!s{2h)0BH>XsKRc68ET~Q8*B;OybfOaY(g*59uURzzv5Gpe^TSg9 zCp$I5`&0nmJDErP&hp{2cB>NAcJ6#erwTEd>BM(eRv{W&9r&+pxx}n88~%UE%0z?5 zG(LAPhcFUZ@Yi%J5yf4m{0KEAqNm!3UphyTm>8QlfvR(^JEfZrvKJxS-~J?{`{_?Lj6N?EHJqpZK;uo1XxJqUqKj|#Y7`#&j@*v#&`|IHhHj;7)p%$44b7jvUPC+h zD{2@j*VtI~1!*^xXawK?j51_0jSSIe)HWwaB_IsxflzL70$2F8uM`)ughMd;P*xvTW|CuqdHxU&FcN=ajID3 zx#tU1IbB1eU_&3W8dBDXzW*F`USMhL(0-2M3x2DQ3GPKdU{HOi_8H1!eNxx$e~P|e z9#CIx_7p|0=u>w~dV+2__oxS+>Om8DUFv6t9wYMBZS`>b$LQADYwAJ8kC4FUvihED z50R@Ft6K{mqWrG2>iUZxpuJV~>Rvm$QA^Mf^}8>-Q1_^P>U%7@Q2)~%>X$O_qk&yp z)h(z_)EBW{eSp)6I>)Y7|LS=U;a4T=&9nbQ zoR10WP0hDaOI@`3cD36mD>YR8#^MfSG%ZlwdG9UM{M|=g{OKkNI_s`J$?hh4o9(2& zb>$6|YBO7XVdr)9Y1l^H&-glumQPbZlza`{DYQ^`leZ%)hjHq&RNK)yrm=c{z*Y33 zSyx@mY17OTG+yn>P)HPnUkub=};T=nuzt*EPwrS8*z8U0=PTP<$-Wu)gasMb-^ zf-F@(sgd`ak;9DvwPMp|G_Rsh?OygJ~&e~p9rI4Lab&QBS)Ec&#G;|(1d1etXB(DZ$ck^kEo@GH=>>5eQKR&E};4M zcc_)9UO@eux2hF|o=189>(y?bK8LtktJM-z&!IKlC2EVp&LUowOs(?l8AJx;sEO6j zpby$BcF!}YU)i5=)|^YHA2*Y6oNw4=ER>u3v~n4yjo78^^bhiPUxOQH>=&% zmZaAs#u6tr|C@DayxwfJT_$zN5b zIqu$z0s^k_BA9zopVnpG?a)0as$0%0zqlJc+j5q-$#6IF_OIu?N4t<*a)h_Bw-y=R z-^*JyrxxXH+QGZIXD90L-O3A9+=+BF*Yjq_>_8!R%Xum7+tIf5CA^R0x1$a(8Lz3b z1`YFbcwL{Xk>TxB-fX{WWWOeX_v_p?%_Y#-h!rIb>QvH+l<63Yg1fnzzEezZju)t4dKm!*1VR2ga;cUCpEY!y;`Ri_&EVR_a z6{9a*g{u9_iqWS{*{WL~6rq(=A&v;h>&)ho2uxO3_UHLuWB1EL)+&#sMg;rM1Bk#)l8>Cq==`guDVcwPUKBg zeK)ZHd0U&R*6hkh9|jFoYsC4es6j{d&8j>kNYzwb@i!N3ousasmX?dO-*Z%tz0N`F z4>MJ*LUNE|?63+=T$D2QyUJ9TY}EDqgUZ2+S;(sPwMxQ_EL0KvT&3`MCVHy#Smo*1 zOk~#GsZzN;10``Z zJ|1nXS*+4ABOdt$c&mIp9f$Z5H1rzN)1y$% zWRA-AvytfaJBG?d>qz8%=oib&%vm8<{|F)tYEbD+ivdZze~`8x*G1~k|n4vVKdiAZ3#LxZY}rL#voMp zViotQUJyD^Tf`Oa3q(~*3b=(3qs4u$KKb{+9?Tg}fjpe#s@j*(#23*3&2i0h4bCr6%(S&(6bY=~Y zJN(-V*|;ikS`|3g@`}R`VZt+6& z{KPZmlGh%{A^xHAs2mSeWpYoMt>S^+_1;vru69Q@+uM}o6WkHG_>%Hk?1oxJjmjrI z-4LszL3wnaD~-$J%Fi=gQKI8P__6<%;za26vzryJ+vO`-PFLL~i z?T{+t0!Mnu7G+;J#W4xBMZM|AIK}^LkmIBSoGCkP(7u6M&P1?5^!Fz@Sx>FeqL7Uo zKC(s!v?@76hSuoYofVu(%`=f*1;IHTF%u!DJkBb`nFup8I7bi6KtCIkI0h~=kVR%J z=h-_ev~+Sf=i?eHwE9gD$78A$YS`!<2Q0i@#(rc43=-jH`ilvW6qhE6d71P#^Ml*kZ zR6OB08l|2dP_!8~Mu(F66gBIOQIBblqFszJ;`QEFJT=M~&D?fdk$(RLh51}lTvKj@ zN_m$Rzs@m22U_Kd`+pgt*21%j2TmHIr!(pmhvE#;;HSfiTSglq?%}7ecEk?F zmQ4o8L~pC&!i5HCQs+8FbFKlJR#~p-+oF%GoJtgL7U-kt44LAlnfhq*`E11_Uq_*F zsi}&B6Qhvc_yon)xKT*$MU>)IlTm26W~ri1pB{SY7ogaQw&}BVS#Yby&(E3h8 z#W@Rg(2`0W#UXVaG}=j1@y{)7^y;6QqURcIbnqNU@#{iu6qUkMe8Ja7hUUZUv3Imk z_w#S;h7DS1b@d1KdOs~>@B5lfNwv^B-gCC?Ln+$Q`iQNxU5XqEJK2VzQq*tN!CpC9 zidKHS%651qL8b?r+4GM`(B;r3c1^Mb1#6#SJ4}>Xc4$d;4BKF}yar>Hpg-y#tjmmSI8>n1|mCWo-A#3H0J;Lq-PB1Bocyx7SHg{U{c zmF<-(M9xA-HfbkB$FJG5nH(YF7tLhf{!f6G+gh^U*9g$fujAPPu>v&i=vcPqGyy`9 z25bX{0CnnVv$JpT(YQ__+n|b%aw>RiNi-j|IV!Q2Oywit-+v098GICU=BL8FTN-G0 z(pLq}b`A8>o;txu>w_pgNLXys2;^ zTOGM)w<)MNt0Oe|l0t*FIy(9Kg2J&kYUo*QgTnVlHKZ1BT%o)|4b2c7R7hE>hCom>*Om0j^!bn zI~fXRf2ty{vSfvbTdF8(&N7AIJ*p`CSGdA~Y*n=K23%SBbqY=xhCT(mm(FU#_WGAghf zVqN%886~{=%vyU?83pWq%Q~|{8O;mqXPHMRBMaeE)_Z$pB)QhjV(2QP-^3kO*bffs zwZ6d;+~c5@&#f$eJqPVQM6p6DIjA`7JZm_fgTk~=v0gcI(5(NCvW&-ZkaX34)=?!6 z`s7f{D(P23Z9`S8qnDLXP2C38=)Fp4d29vib&(R9Yq)~-CqfB{x)CdMo)UV#CYL1| ztAy&D(pj2HN+|zdA}jKhB62z#!(z89B7Slh>&sz9)MXOHnpB~Pc0BQAH6|;f@Xa2q z&EAU0#A5;L;&esyT5%4`T3Znvl-sfxf7mD{V>(OP%SK}-PGS|bveEMw<5-r5*=T!> zF>Cr7HuCq?W35bQBMqK}WfsV$=TRCg9S1hb&*QQJOxS43R0Y;69vi)Q^PAcFRRL|; zJ;?n0PysCn{KQOXRzN=lZSO#I`Zi@Gu=%A z`5nB*Y@e=x{w}@DOf;a=OEEK)tAN})&N6p>WudR7^-RkrEVRY`2vgY3Lbii@nGOvs z)N^bH6YpdpS=3f$Svdcc$l7&K6moVEsS?Kp%8S~C87OEP~W}1y> zq3NemnH^dzbUQAAd0B~t;*6u2%HNqt;o(wdbsrPetP5Zk++m_=&OXfJmzd}p!<}hS z&qSf;<}?4)GSOhN151HMeusc6LX zoX@2F7CKC)nRLE%O=hJz6O~L*XO14lM4B%+Ol3Y3?XG4rZ55bkvd=I>KFC0FmG6wo zHw@(5{DE=e2?KTJyk_X%WuVY0&l!)~80hWmM~s0c2Fj@IWH_E=pnv`yj86v`Xr)Fw zPRwGUfUqpa(HRW% zSSy9`V+vib+i{F_6Bwv(MIbH20kh>QvgBw%nD$ zgcgZhqh1D+hZo3?6w4ree4aefLk5b6Hp>^Q%K)7@Ay2$q2v+i|^19`PVA0eoA0sM+ zw3EN&H;xoQX$Kb{wJCri2MKPc^5M)8V?53_A9nL6;hRVEpd-l^W6eBhZgs+}v|M0{ zeew3T91txD#ao3rAlsIJhkUZ(Mn^VoEzg3B1tjKN$b=1*EAf>l8DPAv60817hbgri zagS;`l-6#;PMT@ZzpWN~i&8!0C(!;z3N^(79p zi-5-KZ}HaFFnAOA85_+Hh3n4-u_6uu)8OBjjtjwyR}4yLV-U=$QJ~_!1OVx(MENXO z4AtM2ss2riAby)FHRX{nJhWD)oV9%5=3PED%iRmiV?~rf?m~DlD5h9D-Ql84iyCTl zg)1ywO8B2M{3jblMLltX>w^ZA!V5>JiZP}b&*#F}J7cKj-Lqkll_?d|1|Z&OM*TcK z3tZlgr)<~Q!V_ByYEG;*G?q-JM%&DQ_N$iESN3$E|0w!@pwChCHK5Z_bXuVEP;_3P z%b@78fG(4w%Le)$6n!tC?@7`32D%OuT^FG1MA3Bvx{efGSD@=m(RBy94HVrLpxZ>z zZ3DWE6x~*!+f31I2U-UdtqY)aLeaVbT1OPEE1-2o(Yga#hZL<#pmj>oy0xcuOwqcw zr*%%zy0@ooK+(3ar)@&fwy~#eMA5dgr)@^jwzH>gNYS>mr)^5nwza2iOwqQsr)^Hr zwzsD-K+#yRr!hg%*s!NDLeW^Ur!hm(*s-TEMA2BXr!hs**s`ZFM$uTar!hy-*t4fG zNYPldr!h&<*tDlHO3_%gr!h;>*tMrIOwm}jr!h^@*tVxJPSIGmr!h~_*te%SK+#;V zr#V5<+_0xPLeX5Yr#VB>+_9%QMA2Nbr#VH@+?qvmjH00fb8i;SL5k+$ESi%P z&COXfM=6@CvuMszGXp}oe#qd2=;=B967W$;e0 zy=mx+4D44;PjmA~f5&<& zgA?8zP3Hz=uzy=;Q^ac-Y<&KxN%0kZAM@u;+xzKuq`qz%|AOupFMMb^@mvN&%r-Wv{K-ujOtdhRKff-6>t3VfkK1JsnPDQo(MFfE z)l7b}RR(0!1o@g48E~FWl80TAL5adtxj7|+-zHY_fhHLwxLC_~T%hflXeW0*CxaR5 zK>p^m4AwQwk&~xn@S@9cq<`OVTn1_SZgRDwv>s+JlouS5!ShIOdEb5+sIT;s!(JIo zIkH&3ZWnE*TS4-NJ7lo*bBJ84hSslUxZJ%;25~c@U$UxkZB5y8}!9ahyym5sLPAO-Pj4SI18I1QRlqVL_^*)E>4tX-b&ZJy9TLvnR zisWtSGVo3)k>{n*cKK5(H%XGgoywK+wmAB_VVQhsj127R%jNGP=z7elkSB-I?Yvtl zA6O!ThRC(@fB+fX{=QC5`N`l_=?1y3w+wztH;s&EXI$uVY_`h3&8Ow{D!JKQdYoHQ zE%yaF-MbojhAo}1V26D53>kE&*UGm|rN_ygyX4y^$zb*5J@PH%We|30uY83mjdSn) z^2E_JKAsoA@8Jvb?QaU9#imLAv%e4~ zT$jt;dJCZ~x5TnI1UUX#@7? z_Ub}7KdV!|a&sZy!(n6R~@JK$Ipzo*FBd^b+%c*%H zpPpF=1rwf)%o~j23*o+NpL}IhA!I&!A@5&W2)y{0@|l5!uCC+$WzA`!o`el^2D)) zFw7p5hZxX$+W130Uz^t7=$|9=l^?u9STXyzyjiIb*5CdkCmDsXap^z#%wGlIn8m>T zUkjkgo{3k!F8~WA7B+fS0M$2Hxc*rIur?`RtA_;;wSvMUtB6-$ zDS)JtO86~B=g;9_hw}xXI9nN)oh*O_%3S>ad6L4u0-!dl;K@4*;A^ld_T5qdMq_z6 zX>9?xyyM}*RRxfEN)4Bg1yG)=j>)_N*gIPTr>7UdS!F&BNi2ZN9eg}1x&Ur$7GTlR z0=N|{#83PS;My1wuJtT{OK(Luz_|cUp47ygIR!v(hCVVsbDCNJ5gaM*9$x^nZb@X|y^5ILl37)bhAH2Lx@%PevIIJ}e*A?c&?0b%7+_M#$%h{d|(fa$CrKc!3s~n^W5?wtau`BoSP3NE*2y6 z(Q?atIDdZ*|MV!#prvKLfk}mk00sXJXr{c~CdX8XHo1kkDt1 zf1l0+qeC_$^WaT;@*s1X9roFl2jX9Ln6oYqj#0Dl$rX8EUt*7a3iF`N1@N2nJaFba z;OzK3xZLT0e~0D4jOy7qb8#N*37vyqdE^1dWG?n_%!A0cbMX<|JUCxB5C5G)pU-r} z3&!PvyX}0uQa=yM8BQbf@3$&>@VRUOR%hmcmZviw_ahf(ie2!G_qnj}p$neXmkUdG zx?-CLxeycSh9`E=(##!8T5}=vgFF6yAs0MPdEo1HbiV9`c+37=(4OUq18Q>NGn3wW zeSI!my5fZ|t;mH{<=!~DAQzlHeMaW}8)I{!{(&#n3(1AWJN$69Pc96FFT#B1Tv%i3 zkMr$wVbnW++%q*7_SP-NR%W?ioDqPF^>bm1bs%mR<$~hhK+NXmLR@nYw)&d`S4x-Q zkgqwQ;~I?fU*|xSMhITllLH6uhTxhzIq-bT(vkJXrluUQGYrE;^*ONQMHr6Vp9AR! z!|~ke94JbNz?y4wVAbSE{J1y=O20+oZ8*?{Kz_IP>HT*NFsI_&W0mK zNqE!8Y?#`ggzxud!^wlmSiL(N#w9Grwl}h2wvjD%r3otN^e1lLdxj3Nin47WBR> z#4BH9!PY}E{G%%ijI9t}ay<*uw;+5L)9bb>fPKsk`WUi-4ZrIEmEw`RdgJ#u7S z_qi|&zC9taD3#9dP=v=vWdZ&A6}DNN1$(8o-8sImf!pJ&4D_!ao_y-c`tV+D?H z%YA4E;U6%KmjUaoD@WF`&9^h)*sn@_syPEJgVx}hh735_xCZC#&wvSfYq96n4A_;w z7VDK|0KaD~ev+2~IkVQ`Er}V>vwaC4M(%~K2j5~Lw1EY5{W^70Y_1RmnadA3GcWuEo8R?+S+=`u}(?Jrp6)*Hp2enIE zvFn0#_-j~&?XA;c099dA^K`iNtO|2<)8UxIwvl!F;ooTxz^KMa@6*6Ev>K0lk_I2B zYW(0<8k{hw!332Cak3h0P?rXVPit^PZ5njgZ^y7M4YGG^$CrpS(EYm|Tc@VMx!@i6 zV0aoVl<&amK56h&ZzqnQOXttuiSbmr+($bxXG|I-+SZQv3kun3;Qy-@AN`gJ%>ldc z?H8#q?))zN_FgKi(AtfEUrvQ*S-Ua&bSg~k+Km3ay*=;1|WIp!j_c zZc9%E@ZF1RBU2&u)Ly*YHx+gY_u(1y=yWOj@VBX{(0_X$J~%p+Ugzu|@l$+brGmkS z{do146d3D%0P8%b<hO(ra-^xA?&{<1umB! z!p93!V0-@|Je-&U$@30l2u=apJ%@3wTM95)NAOYG6re(n;CtpNkVPHAU$s-fO#kSJ ze?)U=Ib=UNilwiXgV^R67TjMBN4Fls%+}>#_v08IIJF$E_#MYrb}t9#hU2(;-EwFZ zp1{#)IoPC}z~hpa!@-UdxHot?@Ga`_I=AJJvbqk>uw4$<-_+rIX3Ig}xgN)8Er<96 z_4td@a;Q^0IpUXj+m{Tc%_ni-on%;ScnVV&lYuNeg>_FP!@kF-aMJc` z{jCjnC?^^E2OIF@*kpL;dm4uzypjZ;chO&xYe<5V|IXn_yOSUx_&gq3lLY#W=keKs zB)Fz^0Vl>MK~m-gtP_v~s`oBnJUgb|B21o6;axF_ zki4G4w|o;}-$x36nVkroZWl3cQX>30bP z;KYv`*sh57-}&6c8p(0+6&$hj;&nr{>bv|Ne*9 zMJ)qv;2r$Za~T{veFt0GErSJuyExr+89Yk3i;oMJLCn>=`01Zmcr*GQ<_yF_r0gCx zxfcsv5ATim8J!Qu!rpbA*lklR{CU@jolq<+TyP&-$Hzj|p8I(8qF8wN_dZsb9Sfqs zF8pwOEX+OKg%3(%A)eoj6PdA49^Z}4-o?P4E8V!~ehi#6dVp74ih=X_53t$M7&zPY z0AJc11IH{MVlN^Fsw*Cj_&5C)#X#`fNBEjU3{2Va2wRPhfj>i!aFsX)F8MshU;jlz z{_)4y@l7;XaC>mYy=dr;=)pH|H00nOtZ*nAgxXK=@kuWf}ALn&N!gX0c{%|o8_CDwz@#i*fhy=TemsqnP5{6&C#8J_a zQ19>xA6*y;!P{Qpw=*Mw`Rx@pGLD2A_t)4%H4-ciyvAwYBH%1z09W=zz>L5Fyz5E? z96vRHkDQ1AJ+(LZ=++1zqTk?sL7U%gyKyK>W5kK;zu@Uff%sc#B zEdq=R-_h%-aB%8+hx49>L&RkIqnTI3A#>Gx+*KD2^uud7yDA(A+YgvehC|NA54bii z9Ae&oz$QN7;5Ppw-fJ5U<92?;I%C3N_{T?F$_s~9&rkTxw=gI<^a(rmgn=FF^N9bt z_gENIp8AZ9H-~{4?+Xqp41>nVFSsl^4Ccze;ChcRXcm9Px2?ipX3|&OuO9|`uY9HZ z@i5>Re8YnuLLn^c8~$=X6zV&^;eH$nL#E$x$No^5j=tl%%20^y{*G5=hQfx)gE%lG z6i%%i9Pyh!n-~h+Gk@UC;!t?J_6MH#XDM{O{(%QxEQPBML%8(DQmETHgtZ%%Lgl9+ zysvsGgfIAsO^cSo#M+;DSKLzg@Z%>IdM|~23xDA}>!sjx;1_;mxDE&$hX9-R2bZUXKvcvZygx7m8ZZ38=Vyli zNB9@Fj0*vmWq)z2MhFyL{EP8mFr1YB!zX%z>G9?t-f}q@zPA3unMZw`hb zhC%7(1Vc#_gX&!x4FA?Ls2%fzA-#z~{Xb6dPZSIbMNDeXuO)EWo=MsFE&*vAllrf1 z38ZaeQbEU;z_p7^s%PU8(0j+E7UeC0Wl|Q^7PbWH=dh?r3zopQL>5(Pu>>ruSkz0+ zB@lm^MNJzHf}I~(RBmq&+|p5?&b0->kfQ?i{#X!LbzPuS-Mfq$C<6&M->iC+|` zr1?QmIEqc>ObCKi3)obiFbLM9v8jxqKv=hfO~pJ3go<`H<#{;}ioda`DTf0g!$6VZ zt__567e(qpMj*IkC{ndSfiR&~ky<)CkoK!7QWDcZc>Z0Hy37lN(}qeTaS={;0Jvr< zQ8n@aP~W9Qne7RHo7a`7V=DuobdWwy3IH1;4prk50Iyv+l(KaItk2|7aryyZwTnZw zDg;31bq*yNSPaR794hqIVo)$rrgoiL4C`H$sfSw^gI=aGrCPWccGW6VQzI6G;dSMa zcud^H#lSb@QaQrKAamhT=!ZWHq;o0RV}J12$)z$b`NQ#cE)}ugAGqJR)Piz<2+>!e zOqTn@u>~sBu&+N1rK(VE*8VVSy9%{h-yaIvRHy|C{&4m)ef`xUc&DpM9k{Uw^yaHl zF7=CG{&LlkI8b)(A}GJCO0kwMf_)!Usp7ed;DQ#9`fIuf+UM}7<-A33H-Sez_~Zv& zn|YK?CoM1Xs14`+;Px9H)wkUbS~b1a$MmHqtB{Sw(-93=$SfYzR(vc zRWvA#slH%4O@n$b@rCEX8dS?KA1Gd-L9Kn_14i{4lwY$CoO`H23HSSeGn-Gft@44+ ziF_(O(FcP3`IMHI4?ISE>hv@p@ITBSiF2cEE$r%4$#c|yo^O-f;>CoB%pqpD#;$H^0n9%xdw=AOW2 ziK#)JCpO*&Y0xwW;fG++bshHnsnT8{DkYrgDzE z0i#))a$M^M7H_mEctI(5pwCndkzY%A=^q z>Ml?`c@#DL(HSfjj~a=m8q+V9B_9|?nQd?er4CxAJHwX2QIwINGZ^dZQvxezIN+#H z{gOC?NuoaW@W%q!xlx}w)x7|OP5M;H`2|qer%!ooTLAqk1{6PU0XSM3P}hR!bO8ob zzTE=&iVP^zQ43)9LHhh3Cs@^CFcQc8iJd@6-;gTa=>)cphLkdLg17`jS`SXJVS^#{ z%fSiGTri|!jGW+3uOW4V=>!AHMwI#U`S5d+5rvxPgMz;ib!+#0P%1Q{#6|Ogz0Zj9 zjhGL^*Nv$1x%1)O7bB{1^nB>jHm3R%=0l@{@ksnw@3JGLR2owg_d3$^N@Hq9u_LHI zHm0m29pNr(G&OaeBdj+Y{Xe3vIzX!GZG(hJcS%WiH#_G6Bt($z4k=-~V`k{??(RmK zo%_BZAu56>DT;(hD1wB53Vx6LzH{fV%#Cx;c~Z-kZjRRNOKGn3&G9O(ls>!F z44api(sRd}q22LPx_)gl{C>ZbMvZNTiMdK^y+O@TxPEDU*0dQm^ewGhOEyF0@ujur zTg|X-YiXCaUUl?+EP7E|>#u$v>5G@qQ={I;h~{OqL;v^j)rd0sE#61zIc2m>@%Isb zu#C#& z^V4$rTka-kT)4d6`J*w)HZHHN)d$p`?!ow+m38O{4-VC-taDp=aHnTw zJy_0z9HT1h#S9))TVGj!yA^^~Usl$?kA|Sn!^)a&RS5aNDw@t0g75}a^q*cF`&QB4 z8-!r!*eZIZKnQwls-l5sjnM4tD!S;qMyT+(iiYlPgtrS+b#)18LmOd7|EhZQ!$wFL zUsV&!H$tN=RkcFKMtFXvs(yE?A+|rM%I9!H^eR|QbFOTNbe?LuE~O#X52&U!dNu?m zRMP|X8sfVx)wE8&hUkB`nr?gC0KYt`rbWMLfWZZ;>-g;ra4n>|-kH(>?FUqM^$_!$ zH$d?%)%8Zn21q$mUCX6ufbSkx*TFy5N67*;blKth7}2PPezmYZw)d-{Ph;xi-q;$N zzhiyQn>Dn0wfbm%x`w`=wLT&r)zJ3$>S1=?n%d=LJ#498Q#-A#hd}R|`r)X0_M+t5sD~rJ)zqJ!)Wy!6wRF!nb+M>+E%k4&i=^(gwE2{}=#o-P(+{nS z3ae^q>ic!^=doHkvP4}3?$pwJuj(KF;^aY@Ej=51$a)B=LS4S%5w#tGv&Dh&!O^M zg6C9uZozY`JlEhkcl9p37Qkyld2N8#i1JziuNmdF171VQYYDujl-Cw`jVZ4+@S0Oz zd*C&wycWT0Qh9BH*QoMZ1+Q7gzSg?;613k7r}c{d2fREsPbL~?^)%&3*N)Z zdl|f^mG?Gyk1OwW@Sb<|J)8@`IYBu$fOCX$t^nr@<=g?zAA44l)Ha~n9vDd#$H&U1A|oD0D@Q8_n) zbEI;v1m{fU+zHO1%DEJrQZ;4_2k>ayT7MENWMpDD^`3;2vt zK5M{dj`G<9K7*9cBJi1{d^Um4DCM&Xd}b-1UEniJ`78sUY076C_>5CN>%eE8tE1wx z5PT*opN-%%Qu(X|pP9;MC-@9iK1;!8s`A+iK4X>7TJV{xeD;FRVCAzId?qWO&EPXy z`K$(?*~(`(_zYJ*%fV;5^4ShP-xz+;LT*|c;2KZ4)&tjku3n96L2yl|TpNOGMCDo$ zTr(=yj^G+nxt0Xil*+XwxW-hjHNiEfa_tGOL6vJ!a80UQn}Tap+J&AH}0`5_i zdlhicqTIWHdl=*^r67Y6sl%DpkTM^^5Y z!9BBb?+ostm3wJ$Pp#ZrgL`b{UK`wVEBD^u9$dK>2lwR4y*ao?SMJrpJ-c%64({QV zdwFnAuiV>%dwk_yAKdf1`b%N~ASR&120)BJi4}mDff73aF$5)+0AdPCYyrd=lvo4T z)m@a>1BgK=u?P^8P+}7xMxn$iK+HmkU4R&d63YNF4JEb#VjN1W1H?RB-6ydS5ED^i zBOpei#7aQSM2Ve%7>W{0VF_tBCAI=$EJ~~e#9Wlv3y8reu^14OQDQS7Mx(@P_#E!0 z#BM+gM~UTtn2r+L0WlsW)&pWbuHKYb5QqsWu^|v6Qes6QW~9W9KnzKVC4rcd5?cZ> zCMDJcVoplz3B;h3SQLm!DX}RKqf%m3AZDe+u0RY+iDiM9mJ-_nF)k(61!7*V&Xrgg zh>0n&F%TnDVr3v^ro_%b3{8opftZ>STLUpRCDsOFZc6M8#Nd=z9Eiy&u{jW zW~apNKnzcb<$;)<659hYJ|)%%Vt%f^mRKN&2`aHc5F=D#g&=0A#126WQHdpjn4%I} z1TjV>)(B#bO6(EDAeC4oh)F83Nf4t{VwE6fsl+Zp3{#0^f|#Zf+XOLACDsXIp02K! zSSW~zDzQ-zBUNIhAZDt>PC*P+iKT*=suEi@#8{PBt0Cs9#9j?CSS1!~h{-CkSwoCg ziPainwo2^Q5W`hsxrUgo65BPzc$HYMA?EAqiHQXpV!}#n*bpODV#S7-u@XBr#E_L( zvPo{xPl+uXV$4dc*${J9V$V$9?5D({4KZmYHf;*+?We@54KZsac5R4ZE3s@tOk0U< z8)Do_tlJRtR;yzs7H)`%E3t7yj9iJ88)D{4?A#DTS7Pagn7R^MH^kVLSi2$SuEgFA zF?b~wZ-~h&v3Wy`UWwHkV)jbx-VnoAV)=%cz7pFv#Q2q1zai%D>Zi#C7;*wiZorTu zP;v!^oPm-%Fys)FT!JB|pyU<|IR+)yV8}Trxd%fILdiuKauP~z!jPj-autT0g_654 z+6h9Re+;T!|rPqU25tITR(AV#ui|xfMf> zMai`oaxO~l#gKzhaxsRSjFOu%UGT1sxqkmFKvU51>Ot5YWzX2^*txiLeIOv#lQa%M{I%#cG< za%qN~nvz>H^3qA?N4n&i=poTQSQG~_6iT%{prspKwAgAv1&T&5wXspK{dIZh?lX~=oHx_ok>hMcI98#Uxe zm0YPIXR72*4LMXLmukqVD!Eldj#bIE8gi~m?$wZkRdTV0oUD?YHRNb{oX;6@wo2~S zki%7SxrUsslG`=pc$HkQA?NG*0mua#a>7b(*pMSua>a(6v64GB_6kb_rp@rIndlAAZ= z=#^Z(A!o1T?hQG7C6{l==_|Q?Lylj`^&4{juK$5r07FfHQX62X5m0Ic3^fBv?SP?% zK&d4#)D$SS1%?^}rPjbubD-277-|rdS_DH)f>N7cs8LXA6$~{CO6`K7hC!)iFw`_C zwGDt(3Lp8EV*+S~f#X zn^N0msBu$j-3&Evu8)XXI73aGQX6NekyC2r3^j8~?VO>8PN}6c)YK`pb%q){rPj_+ zbEnka8EWv9T0BEdo>H4dm#76a z)C4NEfrc7ErB={TGpN)KnxeI1m0ChWO`%d-Xs9t%Y7GrFhf3|Cp$1W@MKshTDz%A* z8bzg6(NMFf)Giuo7?oN^LrtSn+i0k9RB9a!HIJ@uidslRO{7vAX{eD@Y9$RdlS=KR zp@vear8Lx3Dz%k{8cU_t(ol1$)Lt5DFqK+NLrtbqn`x-gRBAO1HJeK9rlE#YspT}( zbSkx-h8j<$*3(e)>H4*(1vS)!Dz%}88d0TI)KD|3)Q%czNR?VrLrtktTWY8=RccKQ zHK$7Lsi6i{sYNx^q$;(kh8k6+R@G3ms?@F;YFL$8RzppzQrl{%aaC$v4K=T>PmEev zLrttw8*8YMRcd7oHM2_XtT`a@N-eGF{S|+{?kGcztuET^H`LrJwYP>ET%{J*P?M|F z<{D~rm0Ddx&8||rYpCH>YIzMcy-IDbp~hFK^)=M|y8bk3fekgmN^P*AMp&s8Hq;C& zwZn!QVx^YYP*beb78`1em0Dv%&9PE@Y^Xt2YLN{!$x3aqp+;G$RW{TtE49mp8fK-I z*-+E0)HWMxoRwN-&9qWGZK$DEYN-u1)kK&+fb9O)MguMw3S+IL(R5QyKSi9R%*EoHQh>Wx1q*csr5G0e7k-; zYQYUP;Yw||p+;N>=jdyw8CPn@4K?ISExDnlT&XQL)R-%^=7yScrS{xVgRaz~8*0*( z+H^yWx>Bods99HP*9|r7N-evgrd_FRH`KT*weE(Rch?6L$B1*8*1v6+ImBcy;5s$sJT~a?+rEhN-e&jCSR$|H`M4WwfcsdeWiBaP{Xg( z@*8UUmD+wojlWXsZ>afq{fG1d7kGkAjkxHS{c~8E*_d3`#G9p{GIVZ7}pWD7_Abo(I?W zNH2t;Cqn6sF!V?$y%L6=38i$MkA>1}Vd%L~dM^w;7)mdOp(jJ> z%`o(6D7_kno(-jU!_dQ_^l}(_I+WfHLyw2j>tX2maQ&9_f*5*2l->|SkBHJMV(1xB zdPfXBBuX!dp{GRYEiv?%D7_|zo)e|_#L$DH^r9GgQk32lLywBmt77O`QF>PlJuFHu zi=n4Q>1{FexG23YhMpJK=SeS&p(jS^jWP7dD7`Xj0n=xe1H%Fq*~^hOzaq?BGML(i1b zJ7wshQhKQjJyl9?m7&K<>9sQSTq(U*h8`@X7t7F-#k88Y3_V&(ua==_OX=M*^l<6C ze*b#t=~8;TJoI=eyoy1?Q-drCqy>K3S;*{Pv4?S{9ubhXTIi+{bLl2$OOXs1dPU)@l&||0c+Ii@?Q+n?_ z^x!GIcpiH4l-@iKJ$g#7o`;@2rFYLm51-P@=b@)h>Fx9Q5Bro}KTom-{loMEdguvM zdILT52r9jT9(o3q-a!vNgi0@=hn_;6PRNKJL#5ZyL(ieod+4DDQRzkW(37b2CVJ>m zRC*OX^eig9iynFym0m^7hqb>6P>pdDpM> zPI~B}RC*~r^i(Rnm7a;^{7SE-hn`EN_tHZTrqYY)p(j)6&GgWtsdv09Jh6@ZO7EtJ z9!{l~(?d@uaka%BdOVe0PY*qxu3ws7P!Bz!N^ht~yZDt}Q4c+%O7E!WUT?qBOX{Jg zROv1C&||9fntJFtReDc7^q?xes2+M!mEKejJ*rBts)wFcrFYenDZ#JwvU=!gReD=J z^tdX$uAbSWgFbC~VLho6{Yr1FhaOp_SJorb{YvkwXZI|>(o5^1r&j5$^&~9d=cqT> z^U-2I`M-glg3J6$FRq84T%|YHLyxY~tLvd>SLxmL(8H_r@_Oj$ReF0p*|zzWUSH4L z9YKFMy}%xNf|cH24?V(KZ#F#i3@g3Eo)w4rxj$^+p{H2sE%wl3tn?at=s8w;k3IAt zE4|1bdXkmiWY6i({YtO0=Z7!+O7F7g=2w2Dm)S#4v(nq_p~qS2b@tHn?E2E_h4#=B zt@K8F=#f@>r9Ce$`<32l4?WaMFSV!l5A?17md-sNZaL+J5Vdc8yF`F8#A^n!;ZJ@6~N;UV;h zE4|_&^o%RL<015rE4}0)^pq>TWGhE{>l@{H?N@s38_{#G^xii*&XHdHM%n-ME4}%R+H#~)X%u_y2N1_#NK(@cCWe`0cH) z{{7$lZ}LK{Pu}|BdCuPW-WPuNzZ?->18;on*00WM>Wwem=8IULIj`k6esW&(Z+zp- zFnE(Y!h7g{KJZUC((lcC@{OeyzXP`gpBh*ZOj8K8p3(T0gDz&Dz`) z>w~p^SLxZ$xXnlz`-^Kb2t)Gy4o;SWhoBLvYfY$G4eSJ0$#`^TEAJ6*k zY)*{z(OJJ7_q6!W7iaThtk2E**{pBP=E_(fn)RDmUzyFDu|6^D2eZB}n?qxLT-L8; zeOWf2#`>(RpUV2CY;KM9L0P|(^)=Z%8|zad7WT%EWPL|A=f?VotY66bg8GjAU;d5t z`B*=X_3hYP9P7ieejDqnv3WVxCu99E*7ss_bcg}tKOc+rt5{!(&DXI$6YD3jz7dszq7KGug|{RY-oVDo;+ zF}?8#SU-T({aby%)$v=szSZU1d?2f{w|aW3o42_^RtInO?pD`s^MtHU-RjY;?%d`K zSsl66i(6f|%^$KlZ>#6Fx^0_FWOdk9Z*6teHm}I)q^%y>>YiO`#`)apKM4wKb!TD>MURc~~eHlNArEUli>>LzV&lhr|5y`$AN+B_$# zQ?zddU3%<9H$?v&MmS-qFlb=f>BtJAW2EUUY+IaO9iW%W{47iIIStj@{m znXGQf=2}@DlGPhoU6IYZvN|EF2eP^!n}cO_JXWt`bvZU4%j#^bp2q5CY;Km-!C1YE z)wS3>Evr+pdK9ZWu{m2-M`HCNRu^LPx2(>?>N%`#!{%~X9fs9gSY3t9>#{lttB0_< z2b<$%bqrRoV08&L-^=O@te(K?25jz^)d5((-}3r456trPmXEi*yXDs{k8b&L%ZuCm zFw1jWKHKuvHdoB@(3Wquyt2(3vpliogDvlCbI2@@Yx!Es%i4T0%d=WO)$*n`x6JaO zmhZH@rp+_6Jf-C$E$?V^&Mc2;`9jMJ+Wa%i^I1O6@^&^C&GK-TZ?n9b%}cX9ndQSQ z?`3n;ERSXRD$7gRd^O86Sw6|~MmBfN@<5jFvAmAWW3xPs5ZZ?(9p&8xFGsl`Jr z?rC%EERJdMN{dU{d^?LXT0GI>hBo)k;(!+Kv$&qk!?QS@#p5jQW^?i^j%M*Pi;LO( zJd1N#Jj>!%HdoK$P!?};ai#yy+p{>4#e*#FV{`Z{j$`o}i_6%2K8v$hJjLQBHn-2> zAQtbixQ5O1vp9vtBP{MKi8;K< z5j@TDQtwi!$2p#RP%Sl;<7r<=s>K~P^7WBbT~e2EJXB*~>THg?KMQkn2NU?3nX0KH zI5J~3wGT&TuDW@I;A>{GrdH?3jMmiR9GTggN=)QUPT?!!8q9P}z0Z*uuc?*gK)#hk-)U#AIN z=a~6%y1+?}@8^FzK+FdJ`lSSax7A3sjy zDH^!O@$Y&i+}y+!d_8zn*?^bhl64gVy*QpZRoTr`%+J?#a@7hvCSEhFPTjy6j!Swp zaB~*N@%8J~2=wJx?PSwHeUAO_H+S(XRH^z(|hWPi_m8=QyDI4mY221#>DRQ+5Zsb4Fo)yLgwNgl%cs8*$6NMgVBLRX)zg7a|BXk!4%l4G-S_!( zKYtVG%W-Smw}C7iH)lHU=4F0-&yO{gF9mXNTp^bOhnSzaxc&ETj%GH#o*DCFVBa0$ ziy40k^x-&W(RDXpbK5V>pA6gzbmaI++uMN`w|RW7|KjFuHsR~G>F)<_|IGVp!LNZy z9P5{V;O23Deanv$Z5{=}IOe(bM<55sj1f=VoX)n)>%2Gj&%lEloZrg42u$Vp<$;%O ze&@;S{61Iz2@K@8F!Xic^-s*x{P*7gF=qUi>sg!Q&e>_5GuQlB-}5bJD95Fx(z$t` zi+<$$_oa8LaZK`Ma8CZJ%+&*vqa8>jtvrSCZdIsQDUq?>O#;442qEnM2U{w1%QTcw@89DUo$xVfi2zTj~) z<(vzr{HXeNd8Y%%+~1UU^H5uU&ht8;qI2{l=jDo(oQ51%KB?s9q*gq^{M7MPoHfV& zXx_G}Q;1{P0@d97)bz)Ad^c5h5)$>Pq{7%<$T5@bMzqWHo z{V3kIj+?i-RQQ~HSl7wIao@puPLjj>baZ_;hqYV4kCu5FIww*&@Bh%ysmbx5b&cG7 z*35_f*iqNx#2)fv;=dl}r-RH_J!Rb7)=v*GhqY&8=UtAsOEz)F?q^QuuT9)M*ADyq z80vlBIk1=4Rf}d$QI0utGJyrr{!w;z3Ke&FW6M(*+>?eSL5 zw>vriP5aQP#c^$y)($zMH@UEnxAVTc)5ht*G54;IoSobJxRKD-&5QkHs~;(u+dC(> z`0?R)?Va~H=3myq&5^ydiQlhEC#MF-#6LSZQ#SJY(9UkYY@-dluG@EY=B)Q)b)jy~ zy>;XPZgz8XXXmZu{2SfFxwnSTsgRzI;W!~fFE@|&=T-b%3wt~DI9}@4$CSVy|;0A zcJU%VDx?|W{JfCY$*CbuRgUXt4|VfykIv`yP-?i7nd8-8hdUkTaem(WiJOCaeU2Yl zTa0wday*$m)EPOO^ZTVx$MPJ{X8Q4HSh&-GVx7j5`J9Q5b9|F{J{!k7;GJWQ=4PH zC5cYNc&;-BCb{{$zl`Pad7A7L=XfrV;`A89`)|D0AxHTpm-mZNJg)iu4wK_C_9wqn z&+kWp&ZFGC-nCxlLKhkBTu$M6A3fU1%JGxiqum_e=p;TbcZ_k?CvqK=d#rOQf!AZ) zSU2CdK|HTVjB|#^ah_c}&RG=8&!1_$oBR7Ln%Cnuw2R{Pvv`7I^ME%- za6TC@(fKyqkJ=|EI*;zHhk3i~VH$V9I;eK=* zH^s@zaoyc1PQzh5A8n?(xx!U<&5c#ML)17Jq zxz5Tw!)ZUjj}O9UxH-f#`*D7%H`CeC*N;-mW;&<)Fy}bUESJa1*qiIUQ?s0sy?CEh zneCXKeoUD?+s!SG?#|=gbB;5;8;_IBaW-`2^S0z%H_!M|XYy>n&UJq8#C1fwc}@n7 z`}WLpbB=3t;JlDB-)Y{S*WLB`PS19JeAaA%n}0m&BhF9R7CLj=@Owrsbk?`#^YOw$ z$L1oRY(@TW#Ukh82b@3NTI~GNlGo#q#cp15x)!|et1WSIHs{aJUE&mN#(lu^C2o## zou+;?J+jnk+=PF>^fKqe#ytL$mbv-LeGISX4$GY(9zP=XEqB5~{Mc4#g`2ya(vZ)` zn=70#4fuR%vC^4T-;eoQR=Ro2v+MeiDSDMNuZ|y$FRgMG*5*2@(P}rRd09wZ>_VeiXYEktaX-D=JD*a&dqh6SCN0O%z9^5 z1wX!+yxy5sp3kud>)pKPF=hFD*uTL^F2nZ~-sr@Z=J)q)baS8wm*o7>a+A~hJ+4o; zZgM)6;Q7t5*|9t&igDh#wAra$)Q>_TTb%Mmc>S!};^s!@D9r0}*j6WPA>N;-w>nP> z@H(r$&CQd(kdN2z%Wckyyu9xFY$z1W@cQ_++ z@ckWky7|-1vT^-Wc$ZTxE9ZaTE~iiyKmNM8%dxrCzh&a**}B`g@U|b}IX-oqjQpO_ zpSpR~Q`2+5*JzIunU3p+RePLnZ*e|Nzt_#NE|G@ogVTGR^#A%WzxqDs&MO}d&fDka zTW|f_hkttScc%U2L(!xAozRy)m@)_4-0RBEeegdx;AHvJhm{=;I`^LXAo~uwdD!b7 zGvC>J$QkvA4~1?Xa(X{v?sSX8j?Kx=^}7!d*;AcgfAe8lRH}3QS06TAOm!?D9DC1) zYbydyo4Y=|c*}80-SHv!P{*;k+Gl_Ep?NiN*4^@<&s=d5Zu$`WTpXLXUHrNa>r|b` z*L*l!>WFjfM<32jJmThX55CIp*Y2oO=X)P=?mg;cxZ*>Zf}gqh+-olS(B}GQPWS~M z`ZYV|gq-&wa?>$4xBL7#9=C|&&Z=*G*l_;1^T}Bs_SZk*=6Sz5&HU^%C!LdD`EdK= zlg^AUeRz86q?_|y^btuN|8sUU#n#o6mjiJpR;&9d*t)J9hi9XYm;~U%d2AA5sULb*^pqK~J1@7H;$5 zvkKq1x#O9(Ft_}VZ=55WeE7V}IVWx-bI1>!bMwe=uH);`-#QD|a=iVm(`F6d*Xlbr zr+m*!=A`F3?+jk?Umo~*r@(R_oGa(u{PM&lKI~h4!Ktv=$6U&b&Xt8eY#n~l%{8w( zpVwWDOU}=8eONUAk~4db53^rh3g(^9^kMYT%g($RJ|vX6;$XTDVUw@8Ip}ky_|UV% z_fDh9KD68Sy>n}#5APSc>gJ=@9PdM=8&{pnV|^&r{0GN3hUaVZ4{mPy=YAiaMEvNC z@cHob`5&F^ULVfazvkwtcS_>%O!JfTG{J{8AOGackN08Lsh`}O^$RgRd@}306BF%2 zx2M;g+)@1d-EX-0>mP;lzA16jxgY97x^Xw1@gseBaOb9DbJaPA_MV&jp1YF|uOHlV)^^~1+Tp%av%L?2 zefQlw`1T+1xO;zfuC?}|%Z*>15g+LHt)k?kDdE9dA*N$?B>uvtmZ@851%-ZRheVImo;eT8`cP%{GdH*Xekoqp!~S%JmgGEe`cLOp2_FVjf9~`x{=Yo?D@A>H z{`|SqsR-|zUN4-l3;QrtU${BW^)I|Ay*Z8KeC|cs zt7#dC{&$I%#{;iwc9%x%vHhe)8h#$#fF?qZfN$q?3zRy_jAx zy_@U5;4*XZXQY>B7rn@PB)xRL;Ki?h1oQrLe#_6-C4-Fo#*6TY8RUyI>;dq9 z<;9~S8Rh#gyg1P|qtrU(#gb7O-F|@E$GvF!b4KwT^CEx#w`JZ@FYdK`+wBc#B3{hg z`nD_xcroBd{`+AsYURk}_6f{A;KjwLO!CV`=3FoKPs%D4 z=6EscaIoKC&kQf}6w4+rrg`y0yKK^Esu$}=XLEZGj!yKV&h2cHZh{xD@@JQ3taJ-o>JB-qc8v#S@AyXKK5oxNx| zDUU>U^dkM?U~j|OwqE8j=9SlNylB)euT*aB#q&{l-9Cr$E!i{ib6(lqoY!^!eDcHl zUi{oLpWE|Lqp=s=x8{>xhP@6y=96(DUVN23zuW(CzP=YBQTgTXx?Vh8n_u3m(dJ#rkcofC_paMhQ7gR{7jC>Ot=?iE zS)L-&H;ot7n-_8WD<=Mvf+?Gd$dbR<6Y+f!+5RF0H?tIF4(tDVEzUhnL4)w3a`SNt zeqL2no;>2ee;e$($o+utuTxCk`!xkqhZd7+_fk-Maj*xY)ou1o{8LQ2+)6>^s>Nl% z4faa(D=t>&7x!Zd-aA%YMqN$8si(zd@|6^XmM!7-W-Pgof`gMw$m;J>&^xt+Y&w^M zv=4%P8hgKH|3&-vlgCmJ^Fc{Dbu63Ua<(+U@H& zv^@o_KPfGHx2E9E($cbXa|*_N9qjQ~vpxlZ>Sbi<+7xsfSVrcqW}nC0GGcX&qnD?k z?DH~`urvin%9oYU#VP2~v#i_u(QQ7@k5g7!&rLzehh@dgPQl?4<=j4yQqxm#cWgPy zJ2eHqedQ#>KQ@ zNL&K@>Y^*Sy&`R5Qt}tu+e0#KPzrhtsw9yEQgClxCF$BP1@R|?{Uk+urC@f2%95rBe^0Nf{PuixP2z2K1{*=eN`mw2PufYQ$?;dXD>>@s&3E8 z!X_!mmQq!sk%D>Kt4do>3f}!G*njd?gA|l+T1~Fj<>!yCCVOi0`dwd5Y%j{d>ij;L zs!M~aDfp~Gb;(gV19~ud}H&WTd?i>~+a+gfWHhW+Pv-xS%sjh#ZVyb}%gLC3te$*(AsLyT)stD@B_pY9eYYRx zowLd4JGs7`IL%(f!}VqKm&s`STd+6g&lAZg(XN5)JeG`^qZ-Jtqse%^JJ=_4IgpI+ z^EQ;3hm+B=MMG(EFd2K}8@fF+yZ0nx`u7cG$nIpk%+g2-?_@uWr;*z~GipmR8mww0 zH8-(G=3FEBd3`dnr3(?;OVfOHGOi5{k!LHC(PCkUtXszKcPiLdlXg)uQYv|5$NXg6 z?Cp_WbCdDG43FDmvu8#!a{u9xzSG!qQ_@JLDg3;hjN5P1YkV?R?>CZuY%f5V%&{W(kfC1dXCCepA^GJb#6gt_tT*{Rml?bXTCH5spF zH(JEPkqqhGi8<=qdHabVK>vae+_vL6oi@chy=8HbBB6K~^W z@q7*2~Rh zf5l|{^G*x5&*w^+WGo-qLWY-0#)IW8v1Y zofqu?X`P#&_jyaXm?IfI%YPsPvhhCY@qyT0px8{wXcYKBUS~+g_y-@zgmk=4i?wq5 zf)>0^!hq4Oq{u%>*!*cLS@SXpk8TBfgtk9Tg0IDgQsZ$Fj>mr}dmknt^X6c`(Bb<@ zn3tusgxpQS<&f6m+)hG~u-0zxkaIl=Yrf&@Yf1PyZ5s((O+wjPZQMSh0~eF9X?`22 zeLe|yPqvZW=aNwVMX;x6)9EB^==qV9{E|OE^&?sKIs1d0V1Ln!&yujLcw5PMBnemA zw-uk0gnVP#y1hmt4klsh&u!(#z9gK;*G{_bNy5J^+PQs4*pYnGjg|(N&)k&DJvc23}k%YiE!G5Gui~svR9i-mEB=r2agRGmEgc1F#Q6r0yo zy0uM0vlCrqZ)^56{Tb|c8rdQVd%Aa%&)-kNrODl-WRoQPeK^?rbfHla8W-&@RU0H> zVB798p>7h!`n$V*P_=9Dy1LO_rdH+o&D}$8R7yg+Wz@pQ0Ps!*;Z6tC7xhGl2JRsUYHKT8ri z%Qg+!bm($DR=`tfWc9-ita#lB9&KQH@9-!Bu9sZxKp|LTY1 zi6}O`zZCu~5f!Arbk{`Gde~oVFV?q*64AWF0LgYB5g&~iAg%T$qRXCOUzW2Y5rgs# zl;>L$F}%eqNfqSg?;P>zG80D>GO^{D~Odb+C*` zNrZ3WV7I61R2+}ry}|MdVTtH|ZHSy5oQU>0 zhPu68CHp4=kwc|*pG4GMGgP8`CZh6p!M?AfofA=@&M>*tArV=I43li_67lbXU=LW= zR*AU%VwfbgNW|p|!)5vViTI-DaJL`qrY8|w1H&aXEk{wwcrUy{pH{^eG8AIv`f2Oyu#J6YOUjGn#+@X{>mC3HYOQ zoWv(5Ahk=J+uQa@Yy#RIh?7B42`F$kPI`s&I24R```lU$Pe5o=ykH1>|2ok0nB zc{SMcR;&;E+dK)9yC*+?Sb}8emVkFw2K(Rcx98_clPFg|N+3R#D5pP6K+b`QVte7X zHRJg?mMBY`@c%zelqn_w*~%ojeQ|^9^LtN7k`8qe(ELD>cxomf?cHFHT;9qFh;NlF zugfQ(MpCleEt7y>wYq)KhB*`P z;NKJ}o-F}us(al&x;q*9edc)O%XI9m`^+ob(+F*b&*L#>yiaO8 zjYrM>!T!3357;kPz%OU+$HVi1U$)+f$FB)~x7Tj)jd(Qs-Y-qA#UmlZC@FF^9$yz7 z<@Vj3J0FkuwxeY0xp=R~b{{LN zM#SS_#8??JEFN!74)*vx8W4~9hsMg@zVZ0!+*nEI6_4`wgZ+N5I`iiWj}z$-k2JN$ ziN9?;K4=~6{Y&#fJT4}W6KxicqVvXyuSq;U-WKcweAzG_4}TaZ`|HJ{&a-h6RXZL@ z*~Ys)f%mG!Bb^y9>ng^hW!Lf2w_H4?h6VcrzbO%q+$+b+q@wZYa$vlma6A^C4fYCd z&%^VUW`YdL8IL{%CrH6;@mNuPg4;JZDq}o~511ge)5W8I;sp8S-#DzA9qb|e@MRq5 zqY3i&vpDqmeu8X!9EW9(gZ+eAev3oFQWNFS-8gh@G*O1$X3u@6U~l2kYjManZlZ); zjYF$t6Q$7QI84|Z>@y5M7l&6r^WV?Jq5i9h^4XVhh{`v~?K#YIJPvo7Pm;q&;_zPI zNix8RL(jNi|KaxiaX7tUl62e?hx9s0p6`r9$fZeQdlAj%IBa`+vRq#uhg-!b%h)w> zC{%y4*uKOQOZj<*O_srn;t&`$Su)Iz!yk)+J&Nzoh(oV0Cd-W}ahP>uviK&(;rPp7 zzv6*Wai~;rigfbEp>NYE@_S+&X7>#CE|!dr!?P(>Kli5i%fNU8n1SXLsFZm65cruTRxsD={m&Wa!RnjvBHOOsIz^l zq_&8|pc7N&qxbnae+>3IhK0o8ezs}yx_%t;mz^fl>%^g{ndbIAZmt@KC1KN~UZpsk zm@rL_m5al}6~P|Jt0m&l?CdldQZx>scc#f7h2pUA-(Wvv`aE&CS8cjX%MpiMA553L zS>w>4f3P>QWQI6Qnl)WEr;WqTP1B|7>sVYo66}+#|2!5Y|Cla;C$VVx&J4k$ScJYe z!|j=Db}ttDJIs(1w_~~Qogpo5#^UwpVE<%`tFdVQDgXbaSPc7ehBP}Li>WvH^WXfh zml9vc;%x4j68It(k1EcT`X^(N>;0K-UnP_I(J6YSY)*|u^wgPB@*w*y*9Lnm^X`tt zx$kDmwC())UuR1CEwRX+ewJ8Y?jLJn@nP**GGt{ehPIg{SC__O+{eM*%j5H6;mn&Q z^=8N7%C=duWqK^09S`oNQu*=9?)KNkJV%yxS+KT3$j+%B^v5EF}S zp|ho8WGqgM5B6uK|AfD9-)xB(5{qnSX3Gx)V^QXpV6W!xUa{zye~!G{Jr={O&XIAQ zW8rTx$L-tf@=+|d#LbaFt61oaIZ~=cEWXq8z@o#(CIT)9;_7CqX{mF5*27?^|e zL>|YW^*8gRz{41HyE{*8FX+iTF$gO-UyA-5gT(6dCHi^{#(og&3oUjf1`8AT?-ydQ zde(gT{9FvSYzp>>hJG1?)XVclPsZTbqxq8SSPZ_(w7~5b{WLWOSL!d2w+_bOdiw>^ zVQ&n685Zmv{e4>u9xqxTjW);N`K|>rX?+a-ITh?9EwLg7>0d685ldo_Dc3^TzaR!# zDlBw+N?Xm0L9QMPWzN(XZE2dcv*k3oM;?_r|lQZTb>yFJ}lUqnph_Ww-zmyJvCzR z!>+~hph^rboC@}-_AeWQlP?y_qLML?oJ-`JVlmiXeu>+&>M0O|b={XpbeD$rBGHa>)eIpvLHU@iKyME6e)=Nue%tiLLK3pn0zKw>yz0B=* zP5)IiR@7T2RX>l$^mfa*ekW2rG}!yPIW-#H7cP@?2cpqp=Q4S*CmOXrUnb1jd(#Ko zd|NcKK3^uEY>LKGH3T*NM@%UuA_9iHpX$<}2L3*{)&y{IM$} z>XT@Uo4!J342j0@^}!z6V}1GiF07CrdPbw*gB9{;*J%8cex=(_Tee*^j@4c%rgb#d zw^=EjTSjBj$HCs(QHVyHc`Idpqi9swwoWMxov6 zV2|#l>rqH^Zna$dAqto8u9n-Eqp&N@8n<8f(Kk`(TYZf@I~~RAYK^=+6@|?GgT1@| z9*M%fnQJ7i6NM=o*}r>;@7G`-Z-(7b$oO!LWY`{s?=!BI^qZrwz1Ui}r#J2DD0FDM zR{mWUg;GP-%0G*u@YEaZ?|nKe3JbQcm50-!FyzEqxj!iib$<-@`d%9qh4We0$)%Ji ztS!Ax&L%`5GGv|G_bU-m$U1VJ>>C+{D`VHm)?rcDur$~MJimVw%vbAVa_=a-b8DS= zyYu(`73>Ed)IJKsE3TK$ZP+i|biK6rAPWEV2=)e-YaE3clh;fBkSKIry}DGJePHb|gc6dDxVAhu_CZt*A_Z@EEy??z#AzYQ|HKor`>2m6OZ zazx?ch7D3WOB5E%2Fdz%6nbCWAhwtI``3}Ukzu18{VNh{i*A$+e@5ctIvd6I6-WFY ziC;e6D4p*|VnfPCsrO4HhRh5082|HQBz``&QLbI#&tKgrdLa@6o@{jcjs0Io;)jx( zq~8~jSln=vcuqv3YsX;k@ykFY&Wzq97Y{~a^5RYM>E1{*+a2sf9=#N&aRj`;oC(HZ6=qmu{P7)Z9p93lH`uSDhM( zjETgZuY@<{UjD@!;?lxz;%nE5F?$+uBE>{rzA+bIT7RvAfV#$=i&_rN&mdj!5Ke73^(} zs~3r|gssw~RwRnd+A3M9MdHhi!9M3@Wg}7g(pLGnWF*f0zEvt0i-b4hHn->bP`*f< zud_}3xgz2JXqz<47Kw_3gZr)7xa> z!w7tydAoG~H3H!!x4V7Omu^NN&|$mGzZQXk!?#Q4?<4T`=wOfZnR5~7uxqYWi78oEPzY>hys@jE2v zM)plF3-(c`tcbwfuXaeyB@vi-YlqyKAAz!e2Yag9P3PyTxKrMm9Dy`Vcgo&z5m??M z*k4^RB?1>G?UYmT5r|r~Qxc;iknLcw*ZR^Y5%fRolnFy3@Z;;9QhQ(o;`8rv`>tp7 zh`{FNyQE>42sG)li+#WmxDpfW!EW>cKli#_a{K)VtW4b{GZ29~-v#@zf2tdS{%`G; z2{n0q3hkCERU(unfADS-A}&`$E|vMWX2ca2y3@T%AE+u ziy?d59`9~}aAaAqM}9vLPX2k1jNcQEq9=m=-n+Miqsr4g(qaSuPL{p${pxTuDz#T^ z@Aq4a!_l(iUYR#99A6LLD`jVeqvPmcA9$;Y;pnw%FYnuMT>E^l4EKd&;7`Gx@QJbE z7@B>b!IaBXs0G`Ji7o9*o^5-}U6{rTg4o@w*-P{xA1Q zy$tq^XKoyhLFM<$oJQfej{Q=wUO0Mp3-*wgt{RR`6ZXrd3gI}j ze7{sF6OLB_LcvCZ+XMa;V9npfTU&!$HE>5 zq+!}{WRDE?nb&_2hQC)Hko`}>5OLsu)Or|(U(N)3&MW^ChO@5@$fg@%ct77kDfJ_J z$}1mq`_BuW55uxv2W9rzFl3KDD4D+s!>B0-#rC5Abu`VW4XBgfqa7bEi4a2Oeha`1F7+yC&{(wM>{lN) zH4Ia}JtUVWgyGq}L-N6xF!W1%*zH{}n;3>#)ep4&xl_&MXa5_HN>n_#8FlR%ml&Tblr%tL&EE|R{7gF86_qIjD*mDz*T?NAs|878X z=MBT9ngO>5{(R;z%pVYt+8O!t2?3d#HVhqS1^eOKzX(NE4aklsp%{KKAXy%U;>3es zZ~XDwp-3s>NQoPvxKzuLby>zI^?|<}&EGQF-8JCa9_a#Dc@!=7% zd071mgyQ33M`ca!P;9MpRDRADia**M6=vLnS@$v|J&%9#QQ7eCNF14SRBrz@5*fA} z6=vasnfNm3kCB*m`KYY=Z6wY-JSx}jj6|-tKNDu=gW37g_1Z|xtMi%6xiXTU_cQtW zJae}`{y(11GQNtd>*67h07)PTgcu1)2*llpueiIrdqSbbiWGbB7KcI$g$h<$+S1~3 z7Vhru?(XvLFZcb>U&_5RXU@pkvi98l-=;KuxFYwrVD^k{YRIk@ocMj4`gdy!I&Iyi zqz6Bw7r*E!Etv9nn=1UT1^acktEqprpk24^N_zD}diJY#i&`);WxMkHxdj`mx2x)T zEqFC#yON&%kly}k@AMWl{k~m&_^t(uwrp4K6IyWb^me7`|21`Z3sQA=C=PDHSnD0? zasL)<^4p<=5ddKYsFdawd2e8c8dBGSvLQRv(#jUhoW4T|O8~+YP+A2o_`n^?HM<2~ zr+28lv=&r9+M$Fw0AUZP}v7?o`4sfUpeI4eJ&pp4zF}TeM)%!=1|Aqy>xH>{7xyfG`hKKfM-w_SvPr z*O76PcB!>mEy%0frG$w9VI!!wubT1a)LqK*S+m5syHwD_W@xEhO4ILb;Pqx?J=mpY zU24YA*1OfeXPfb>j5 zjGxN(sGifBp$6N9gr%Xrzt#k;1@iY|6AV|&-!o0< zc0j&A-UMN8s9A@a5d3bxnz6SD@x}+#)E!O8b~>Ph$pK+=sEHez(42Qbja}V@fxQo? zk^eMd)R+TG)6Z_ek|xal_kjB1mnJOOdqCCCZ^F_m2b3^AAgm8nFrx`;Iv!N%lbfJ= z9#nA?ny@4Epb{1cgbAX&hs(U14l0MiO*lE~pz7McN%&C*l`umf>=32h)P!rh4yu^)vxe1Rl4k=-fKv*PdVx;^X zen<@pmG5UCQnkHg`#%pUVU<9bB?8ru@y;DmE>1H3(?iPCUXIu9uo9*TF4-Jb_swNK z0f*Je&N9E$!%B6O`PLj(n*M!L+sOIMIIISKZWKFwSe3qO#F{OKl`v8utQ6(^q!CLV z9abIhH{vIqBkK9hM$EE0qJ*UaVXCN&=NmCH>4;izsu2S!kEoGH8`1Rj5hctO2zy0E z?`}lak|V0ewnoHmKBC%eZbaaTBTCaZaQnZFu+l!Nep%6o4i-n%h-HoVe0lq* z5+)3U4WkSOG$OIfF?GF9BmCTssSQnyu!%mVH2n(eD;nkZHOEv~aU(8_Kcm-Az9A%z%eyBt`WnoA5#^Pji`EeObLqy!lY5Hdo{wt>9{)K-H6UOt`@sB z;&twECCnNKyGF%yZv_8$Ty?T;#IHXdS69tso-2Ge;f1-him@PpCPU8ep^H zgepJVfcM)^C}HYA*gERLp$7c>^o06%Zv!T`JE;ckXh4I_Nu}w}sI{R1T~kl0?W-E_ zy!xaX_jdyh3^}QU(F0-iD80oE7`p7FI_E|r%ozi`9PRH%3xXpj<-Ig z_D^cSQp;0n(pcHv`;-#q4}|@rbcQydd-*A~Z9oHF4mhQT_ie!L?@lRAU&xoW4QSeM zO8s5YfZ(I2RAX@i^zNKe!VrS6gw*+r2K?UTw3?ONfI)7jRdQSdVxvzhVGTi;Lu!3U z1FrNvt@;Es;Lq`=RZs5*e7)eb5+;%GtWT>c4h`sd;IxXeYrvUnr`5}@4fyr#>HqIX zS!CP*KgTo5z@Pyi!p^A8x((Qob4Cf{2*Ns2)*tGTHTsM?@Twl>Kb%oRpVrH|KBI(% z1Yshn)3@qTfANeObG06BFU~0M3-x%ccUB2A3BpcN6OPtnK;T*Bd!Qb@($A_(yXx_# z_N>zM!SvcxkHIs~sZ?~LP!eD~1nADLa^%(f*tQz=BJ$!Y}DXaPQ zc-r-x5>^w0*`(^G*P|)%oYMQQ9z840slUe6v&O&Z*f0>tVR@ zoa*&uJ@yXCfyyb|UVggvE>^sL9tP&rL23GadK=ZFZ_@>}Tdy8Aqb{g2oq8Oab3qBi3c|8d6W-OqdFKUX z{jv_H&RD4z?#Rir!F%-S;o5fq&JZMf;Kx#ukLNrKbK? zhqa!URM!P{^84dUYRTL>d@i}9gvAA6a;XiI>x6fFNySX4!|k6hse_~IFmdfACCo0k z9J-_~4ywbx8<$kgS9NH5e@WeMse@jp%SzMd^mSz&;&E9GE2+cH+{;QUU(T=PvJwUu zgaxMBrqp5M50}-XxH{zjb6FWg*5TQ%%Su>bn0)cFG7PALRnMru5~D~ zyP||C24Rb-j<$7}ly*f;wyZ<<+AB)0OC8n?y`nVzRom#vahF|DBiqzr2(PFQpK8(Z z)DS|Uk zw5MNJ$*Hv%xAeLa#v6q7rmUlC@$HH0YHVmN4DMf74+Cm3xz!CNEI0@gPHk|l6)xfp zW$RFj4zV}XINMr$SA0VWGY-OzQ|Vo5F=4_D^`BuabQa!Frh2s)z50gI^sznvsRl!? z-B4j~Yw+^T4YlBTjr`8~rV<97=oL3r*_|3xh2B(~uhrmu)=gz~u?E?VH- z=4g%B|C`GHKn>Rac~i~URRhoMHi|$^$#-cz*|Zfc@S2f>NKSWD}KAB8Yk4idc!Tn(KYz)$Sox- zJqS}zH4dslS}Czbyo?q5W+504}P!4K>K^jeNi=z z1l?1;7gWPJg5mA)DKnowB>>PeyR$>epHX2 zRAK7F2ddlsDx7NlP^I3ig0}(Z&k9(+29 zs$g3c)-Qah{`sltI(c)I108rHW8Zl@n9 zVO&C3mug#06@F>`SluYA!g-6wN~f?2CSH$~urMJ^OckG6g)t?MRb6})HhuM2jf_*MBdCNN?4r`W~b7AT!~eDqAc!K;@Zh4 z%JX_93?DpE!t{i&Jyr4PN;H^1Reg?DVwT5KHD-S$81qzV`d|OSN|=24RH^lq2pj)Y z9r>>kbw52-!U&b$kv&zby%O`uzA@UF}hcN&h@o!bF9zQPo}ZN~jCZ)x%DeIQ{IodSXzCC+%J+O~3CK zT9vTzf1zH!tAKy<3-#(n1(GY}@1qI`YgN6vQ-Oh#<@;+DnDpBV_2NPW7Oa>3PgOve ztm^TR3T(gmLOs}5AzbGd>h6vT+%|rxgxLyVx2h}aD$p+cr8@s_h4jsNsZRb`0f(lS zO4Db2&(9Uo*X*U*`eOw${(Py{&#FMlwwFp6un-okS~{Tu{U5zl3r1I9M4MM?*02gp zw0xz66$@d;N<3YG`EjpQzorT-DtV>qYAW#OSFe;XWg%=?l~PcF4GUhW@T>}KS@lYJ zrBqq1rEP@rL==9aNOXvdg@z&Q{7)HVbnrcwd$~A1e$#7J)Vcy^kG)ngAIl-^TjlY(949`#R_0I3 zan$6EYIVOH2VLGMO<(n+m&&m{?~Ph_rW~7F-l&Dg%CUCz8zl@~2uoKr?<&W#zuu_K zE#>%m#~bCpp&WD0y-~v2g)n#3#}(xmqx)7}Sz3<4R&UkzU&`@?&s!x-UI?34jhkJL zyt22derh=q`wMw~VmU%4y;Yii?z-QUquZLd>gK?5$rEJ%zUBCI^{o=dFNF20hS!wi zVuyFCxU3xe?cb?h1?5;5^iBy27{UZr50lF=qxPNJ6I+gNhQ3q3q8yFW->IQN4$p33uj>{(R)dZ7r>~eXpN;{V0&xrR*7{m}3 zv1+SbjzKN&)%o{jC?5S@{q?d8nEPG{s~Ey8RylXeptIw>a=2cG+h^aa*B8pL_wjor zOk)V!Sj|0BhDlvNsD^!IX!QP|dhIAfLi`7%qskyXl-2RIvVXr1>X(&exHjQ~`r?l= zaKQ&9jARHaS?Mk;!@zwX)Uml`$h`7F{WPNtuCG2QVJSnH%F26O87|s=RPRQVVNI`( zYWv_aOiul%gt-i1FRSd{We6GkQCZfP!FcLNb)}*Vw-$X=n!fohIc1o7M8-)gL)ER1 z>ScTx{6BnD!f=MLoYglWWjO2jNx@&vC+w5b_AJAY>`zKq&q!+gq{enHgT;tXD%PqD zcV>N3I;Jv@<)73}!!rDD%O^FaeHk)NeNxe_%V723lWO&`6n9#ER+@hOL!Xr58~4wu z*S%82MSoV$ub0BG@Us%eG=w#+8c&yE;h4{=$I(*M|M*#5+*b%=?%Ym-?2X{Y5Qm_ynIFO2KDZ zTy9&6A3tg_*Rm7?+O?uEx*@D?{@$S!&fQuut8FP-JGbI{tx{a@ZAD>uLzv!7eo=xc ziLLnTVF~JUT5;~}5=a4u!u*D?zj@ zF)4 zZfh~NWwhpr4aNAjxHT(R6(gsvHHGO8VY_qi(qh~k+L}7Q6yvXPtvT(-Vhotxni~GZ zqRGW*v$Qqc#}{M&%GO*nvKZ4hwWcuQA*^`r>L=qIYt7W&#khV!j#F2RWw%>XSn?32 zJg*cM!{=jb)@B#uRogbamr{%ko!U^C^U}AV4WFVIkxp&cKS++_+lH@wim^Ma4K>`0 zcRh>c{iHS=YEz63Wo`K0T+X{e{@tk{!)`wn;enqHXMJCUWzb>! zX+@|?(&6xlMX=7*;j__2(tl7#xRgbh)}+I;1B#F|K!+)PiqLwb4pl=DHcir@XH^mU z&(@)a^I@D@gd59sI4Z3O^H=NeNqiBqx9G4uvIu(nb$BSa2wP6-Fx0OI1Fz`tclRRc z_ohQr$0A&Nsl(B>MVOIxUH2#v0~ocp;DRsp(f z^|la)BXp_ZiyXUO2>(1?2Hz~i?FwD~a;XqMH0!eMnL;EF)Mf9Zh4?U1m&f-NV#T+* z4BSzOvhQ^{e{&%^{-R5*wT0jxx~%!95MQj(!m z*@bYqs>{@=g*bCxmm01~htY-bZPk`7Lkn?5zb*IoFT`ZiwsiiY5W#kBIljISw_Mxu zMnxfJ1hi#DQ6a)2+j4$(A?_r%<(rg3%*<=c?6^XNSGMI}kk6ajvR#mDKd>z;eF_mW zsx3FT7Rv8G+p<$n8UOpX)bLccnHA#FA8l!FT!?XN+Om&cAw0IW<<8cHIJv(qEk71u z*eUt^RROwRZOiSC3$XWoTbkZ2K%ZAK&b0!Vv}(sq=L@i2za2ZCEI^rQJ60SjKx?~p zT)DddOI_Phdusub1KKfbLjfK~w4;XO^5o9~x&G~lB?UNB(TH^sAZ^vOJ1>nhc+>tBuy3&pY=>_(hw5UACjSAq+0O0PY8`W2vGm-cLO zFMyG4d;aZEfInT@^SMm{68zgUz@h**(4K=k6<|bCdv4M%fMsrberi*I)#dGpPx(l1 zYR{3c^KrL-dv1M_FTdAp&sO*HVLhomBd+IT&8+s+aBDW7%*XBD+w=XQe2iGto`HMv zVaE0xur(il?QPGM8}bo*qCFq}myZjV+S6%8KKk8l&*~-lX#b);e_EI?^{VzfJvSeI z?e%ChBOiM^>oMWme3W(5HM;oUa}q56p*UxE?jUoRY?TL}u%8dR0D- zm+Em>aX#uA^!Pp}A8)?Wqi0$^CVivFs`z|#ouJ3r5&8IYh8}kZFNu=G!Ny*`h0&o4-dNP)A4E^20Q38>s%gmy!H9b@jOfm(dW_wd9aGp z=aHRxSel{Fw<-@l#ro{NE)Sb(^_jFX4{?3<`PK3~92ug|AAZY2;aGigejct()u)CJ zq&GDWFBa+3b3z`5{jJZOQF&;+L7!g_$-}oh^f|9z9y%S?mx6vC=APB(mD)Vm+|Z|X zc^(!&(x-hv9$eq*GbS?+|Fkw>O;R5GI~s6IbRIUC8}PT#JcQdDaGQS~wz(VdiigZA z(102)QCGV>q@)@!&@vB)^9`8OIS-jt2JCB)hvO{<{8lFqxq}S2_){)UjWQr#=OX_* z1D<`7i__m5@Y&s56#Qa9z3aI+^M?VuUy$$D7%=#xe80tjnTK+bx8H#EyK`~kqyfL# zl8dY>2GsD7mi?QHw3qS*#vi%Z|Ji^?7Ud#AuLH0Dl#87v9r)_|TtwP*5PP4C&CVTY zIWZT3ejVsGIv4+icVO7iTzDjQU~2zd{GQ!`rM+`uU)F&wb-DPdp#z7O=fbpK2Tm-= z#nf*)a870}+D+&{4TouEbS~b`@4(HWx%hHv2k!CD#hsNMc)}wW<(oS2lB1mWt`59o zn~RjA9r(;57u(Kv;QLN8k6Rts#vm7eJ?TIL9Xam%4($9X2Xk~f((-i<42(L`?nw?t zT6U!4-5k+#I@0Z04(dHSQp0}=IFW;tn2roSm;csaTwxMZA@{Iqgz5>{c3b z^yzGj-)PAGN3!v7ry*&_W6c4IcIZyM5nRW?RFmiey8#?7~e?6f2s ziEWIiwJ;kiIvVlOoNO3b81ekHZ1l4?qK32e-{@@g3N+$^q1pH$%7_#DXX9Op5&QSf zMsdCo%j&YRsnUq?<=L=mF``#NHiiu}qIqUEE{v4%ld=)=tr2fWW#h-$Mm!XfjkgPp zxY{op`OA&?qkA@1uQK9Dhir7F5o>L-(RZ&AHGD63<7_xzGNO@QHpbpD;&bh6TzzK5 zlkc+-_R)xIUu0o!TVu|Bn1$!Y#vFVr3#nGdEWDhBr4GgnI+KM~-o`XPnuVeeW4_*- zh5urWd2(A83^I&`|DJ`KB4bWlm4!_;#%x)U1(QC;)NsXmEX=~T{~7c1oGe&OG3L2x zS?Dv@n5!mcVdt;LoH9BKmMe@|KU6+nYfSXd!j7$Syxy|?0b@R{%|h=}#@tnwg{@bN z`BT1(f8Ut>GO|$rQjU|Dg$tWI3jE(PiV)1@gBhH}TBRAnMBu`^c}XX2;q&K#VRi5sPzso}S2#bu)J zSDm>%JQHh%b>_HUnRq|0GvmE75iz|p+dF4s?7Yt0XP1e+i#v0YWhOfO)0s(~Gm)`D zzBkCk%pIM%r%fhK9g_V&X29ZXXU4qBK=Jj?)P9_S`42l&-Oj+J*PS`^N(OASO{n3< zJv*9#pG{4;VqXTX*qX3@yL|6zLc2{FDDyYrxm6kR{;@BlIV}UnzA~ZX#0(gIW5SE0GLSspgfoU@VEl9w#`nv>_IW1!(42u! zi%qEE)m4{fp#KIFcFD`YUpq{=CoKba4w-Opds^pG`;ZS6!HOEFBYub>aJc>DV-`3m0uq$Kz>T zn6gQ>o7aUeR;43naTm^8k&bbHcVX0$bgW(9g?ARDq@oIEET7KggfcUn4<&UE4F z3F%U2>cU~8(y{zO7i#!?+rLUjyH=*GZB9ooeN(opNk?rLQ~q9(j+r*5OwLWmR%cV* zPff=oUsHY;myWLCrgTL*;uB1{zgM~}NmDj@rDI`{{*e)Hf`kFG@Qsz6< zl$SfDBYCVThv}zdz*JLexPbqCNW-4rOqu#J4Nq5?^3KCFSgbSUs9R}>+-AzIm($RA zz?A=;PQ&z5rc61KhILm=d1Fr+F5NTb(5-3Ed1=Z{8`9wV*_6xvO+!X|Glu_>hJl^U zc>K3C%(FIQ!~8VR(TpEvrQy1_88tjY`*E^goEg^)PeWRU850Jjp>L5H&-F>e%o;N` zH>6?p7qVYP8cuy}#_tN#@Mg3bt+LW!KG}?aB&8u}jv0fa(@^+}8TW*wVelVj%=1gb z+|_2h;g*KAG-KbMvj1K)ezZ=LI+PhT97GetGa|py>tW85=Th;~!Nj2w_ zO{pl&H|K!WsTfpg&UY(PF}2y8!1G_q~gp(bBS+K@pz^=znzc@-38|C zFe(++%gi}ta4LNNHK*ZMsYu*p&S_1lDBERDqv}-jJ7UhM#i^KZ&YT@{Qt{IbbAFeS zij|MdsTZ4y9dFDzAxy^CwxCWxD()LtaFj=?^l`M{|8pO0Qeo$6!53z79DfUbVI=d1 z1@E*=MQ)-6t6HU^Hrs;d-=<(dsRgs2rC?0G1^3@e!K^PW7=1kjzYVqEhVv;{Io5(+ zCsM$v7F=>51qXkypw-S4ocqm!(>JH!_6nKDniRZPYe5Zf^5K#c7#y%*#ljSrpR(Zb zIVrHeV!_yHDe$;w!8H?75ctA^PNPx~^~r*B2d5yVoh93Sm4e((mi)RY1!Y#2yj_)o zdIwA96{nz&mnC;(r(jU9C4Ev-Fg(VR3u96+F3pnqVJY~oK=$)bfv^F2-8}_Av{*9D zAq5KtT5^3iIiHc1v^Pt^vPqVlY?y)-vn=_lt(@NiOO|V;VD&Of?tYVub^lt@^Jy|R zZnEU}cax!ZS@Pr6WNbNN$?9{-*mlm6dyge!`wiJ{e=>GFvgFL|$=LbEk{Z5d@v3C( zGU!VFDW98mW%tFhoo!c+`APP3>B?KPWgNe*jGrRohIi$%adMo5u53R-j+@n$4TEGJ zC0)6vPcl~5b){oNGFJBO%CQy6STUq4uNNfa_c2`=nVF15Q@V0NVlo!Y?Me;TGcPz9 zGym+$e|?fMc}-V#a81UzEnQh}pNtXvx^ipRWDGjdm0eAe(dSZE_BTjI{hh8n&?Xt> z&$_b5$0X!^=*nR)laQio#p4f?5M^XVms?2)w6x;LOG)tPVa1cDl3?#4pC3+wd7u?F zJkjG!f>w$Z9oHq{MXnWx{F8*+&-Gv11w zCne$6=~k>BorIb5toYxMB>Zo&6}9^%q5t1j%xq3V^?EBVtWHAqb}K$CmU$htVsK6p zyiZ$E!!bP`lY|cUltR&HhQa^T~>9+>>y!oi()_lCZUtHIup}VTF}7XPPGA z2M23j=$M2tUe@f{HVJ)#t=ao?B8p7kl?eg2eURXuUT9dk=SG=GFvxZ=xH=u1~=5>)p6+ zrR?{x8}I#|0H4>g-LDBSXl28+9}{p>&xRvrBw(|N4gZ;xfbYB6@XF`}eBoq6qoE0i z^|2xPCBQ1whF>%%;CZYK=U2;d(ru{W)V|J6z<_ES_DD%UQg0h(#w5UIkPU~0%Jw5| zxXdpByC>Q3xLX3|&9dRg9y0y{8#-DiAaa=vGrAoT8P@p%8hh8jNZx2NLqqn0iIITSDNS=jQ#u6P8R*ovMI z58ZCIv|1aF6OOjT-|_gx+m=;JFap-542@M-*{+^v}IjGJoZhr75fkmVXgAFf_RktWXmlX@#wkKmKPJ^ z@#r60zKe**nhmxz4T{I`9k%rLjz{bvTc$Y2!{Cf9>+Rxk?5ZtCS;XUq`?mbiI38s$ zZTVmOc=Y&e%LA?AakrfvZ@i7eicWU?@H7rzTG_Gly*T(g*ipj+jyM;GO+j|dI~IrG z(ROU!7l+7HJC58Iht~OaoV6hiJ1XoXu870fCOd9i9*4O8c0BZJ9CU}<@yd^J*frjc z&t}A7+;ls(`8E!*^X%B=e{pED*p5Ai#$nrEcJ%KThmq^-7~33&@NIU~aEPml9IAA?^B>nZSQ&NaM*BFNw&>1X zUE?s#zB`X}jzf}rcb?OagLbd(yxuwv8zZ{&!TVVBOX|)S&trwt)}0^j$4Xw@of`hJ z-i26XeA%7GCt{&Hv^&iX#A4H!?zGwwi!Y~impD8Y4s*NHVO1>7|I(ch5%3 z6f5sncBl9JSiDl*={qYHzwhZz|L1$69zgRpDwHKW& z7C*(=)1gN!k~8et-6|Gu3hila5{t#v_B1nyMP_e%8n=nX$AR|L{}6*^BkkGdMGSH# z+4JN57<`&(PYv(+;rSS;)7taK@fdvg$DZf+$6(0@dmh~$gY+Ht+`TaduMgUD(|<8o zc-o#T|A;~SReLV}Ee4P7+4F~aF_`_ro|9+BAmo!hM}8ZFt8IJmtN+Ddym1fK42^+X z*B;F47lWfcdN95@1_L~LP{WyaERMnE$R0GyjzL9o59%hzpmlB!zKoK2l=a~C;20z{ z^x#pS7~K1^2bD_e8s#^8aQ)tBe0bD@KW~l3+&4Wq zetk6jw0pAm%4i(c@5$`nqtVo*Cj)&vQtJh-VE=_=kd{)GNC7r zAsRhq^yJE3(O5sPC#QKvBW-a{e&HC6>wooRicK^It?Nl=vuNmV>q%Y1Xe`*@lh<^k z;eE0v)u$-zxYUzBzKTNLou2IfC<=F;_GJ34C=7lt`(28HFr%q`Dhl&DI`I6#D7czC zaMjKzY_xOWcblV-=fIE^QD_Kvpz-1;yoz_=o%vB1lj*?Cv!Y;J?7*4d zMPWgW0~^N3IA1t0bXXMD4sxJT|0qO{a^UsmC>)yPz%|uTD4gX$4M)5n_K8?g43rC*26NyxNM=rh+iDPb#)bPtgjzr=d z9I3M>5~YcbJj_U3$#Ue}wUMYQab(5ck+@mwNT;QdsO#g%CkrBR=W9o<{XP;6qa8VX zN+j-n>&Vz~k!YOlNWJ0m?*)!LGC;mx=E&K-BXN7BBMWOIQM=KR)}@iSvBQxXZu+8> zNL)JY$hw$F6knC&ght}bJxAX2jYQ51NB-d&i6b8!*l%q&MoxUtDH0Ku zPW(eJQn)KlY|@UDzI9G?eiwli0ZzRAGy)D0PF!?10t*tISa~%9rrA#Hb~XZ2N}QfJn5y+nH#K46S*t5WiPrr{q=rSk% zJ|zPGtdw!bMZkWe6D@{EV9pLFIqwLxKjg%5y=C0fP7JM$z@sZpd{z>H@_SBPniGK| z&z-2@#2dv#V5P1zcZ5X1&d8aAd?PU3!kI3v5zw-C=7sJN_`=PZQ!FEJ(chWq6oDi- z^GW*%tV?i~dU6DMW;rwSEik>9|@)zXy+Rijv0<2%}%xynG`jb1e_iSL|0r`9~@Z_Xy zKL*IZ?93)Io>%K0G_Xgs^TzKCJSQh8PskVS#h6{boftErSo-zauR=M!&wtz>A3%h;} z$CLps-1I73ejnq)vPa=ao#4VxH^cGgbQdnX7!Lh;F2u=jG%j-Cr32yEy~2gx>;DVKrM)i9|05hB$6fg1*KmA)!G+U*49ByZE_9zE<34ub-ihH@`o@Jd zqr#!B?aI$zhoe~El|S?i$7&N-`Zk24V>eeGEDuMWqbuw3!=b!f`6(?NropcKJ}w-+ zqh09{9*!L;uH5M#j;?vGEO8IVm*uW})*~Fd8eBQSN+EtVQ87-$}gUUfj_%ST`dfqmb-H1)iBij=gOXE!?0$PE7u+gL%UtBOxP2K z!o#jS%P=fIcqbrxp4nwcDZuFZRhOtI& z+&U%<$1U8LHY^Ob_HI1iFATli+*scnhV}k#d|nj>UAS?0Q5Z54+}J)V3_oSMab{u| zZWp6{7@|4m$`Frb|_ZVyYp32 zC?526=T}joa2evxM?s;e|DQXXyhE|*J9pl23dPmg?ku+rh4n&ro;3@Ve8inuhM}0f z(w+NtLvdt-J7YeDh~0PRrk5dzIp|Kmhanh#%AJ4Q2*J9`?o!_h!IL}goO?V3&d=Q0 zaeoLZ-^;wWh2V!a9(=n#1V=h}h`$a&TQd({T^52cTMy>`9D;t%9^5l01i$-uFl1^7 zE`@k-#kdf3j`g6;@DRkOd2rf*5Dd-tkn;_ZKIR_$swMrep9izdLh$1z52}tK z*t^q%&blFZeaM5eJ_e)b84rGb5sd7s9&CINjFI;|c>H=WRy_A$==orr{oujH$AY1w z>&XuLg5hQ8DfQuC6q|eU;<{jrv-4!kKf(CN#gogI2IHKsCyf>cqji`k2Yw$6w>VFp zpB#+bbWcW%4aPSGo?J967>g@C*{**u4m5ePr8yYS`+4$kRWK~R@uYWAFfh)OGc$ux zJJpjf6M`{mt|#*%g7Nn+o?P227{`};(#$g$umAJpActUBZuaCU>tKZK@}z&4U{oCT zzN?L8G6zB zNDykxy*Oxh5XRVf@t6w2uP$D6TN8vWzFr)=A_$j4y?A+15Z=dnvDf?{n5TPj>dYYc z6?pOXq#$HedNF)-5Sp93ID2pq#`W{!gT6udWtbPE8iKHKtQY5$2jRpN`8+QOkLGwW zGEL_5i)unC=l=4c+>P&APhTtv-V;jx|@0PzY~G*xAkVL z1A$0z_GbF_Kot3SbN+@vG>3Te&dNZ16XQ+4-vi~nLT`@zIS>o-yt#i)AXb#icvAzh zxxrifa3BtR>CHdB3B>s!-h9zN5O@FQ&9Ih0y!y_Y+md8IcOMaVohc=KMbKtyc!rk7_Rk`H)uphKYi-rt)Wtpibh$(x@|0?}~Wo6!b= z`0|N2$F~l|khk94_pTR4Yx}UnvtF2_@579{y)fOxhcmA9!dz<~9zWd+3mklCa<~^3 zd-^bUS1&9N^x^Eyz3_LW4^OV@g;h!N{hz(CF58FMzxBeV5+CtHy|AU$hli*4!uBs@ z{E5A=bC3^{M)tz)kv<$hsF!dFeYpLLUf4Ioho5SDVgEcI2AB52fki$XkRyLr`0(#! z`FxEJ??%aX^r3yQ?6=2128?z zmzE5`q&Q!ut_i^CblGl20EQI!^4~=P__ETM*XISGp~;sfGXqfG&zG^20+2h*mjgxx zNZr7fi@y#)#1vni>=OY0IlgRD9{}f{ed$vc0PEj7xeV#uS_x9uM8UC0$(2x3){4schA3aC;qiTX5 zv%dC6@^n8A=;IIHAN@F|&L3TW^W*wbe`x>d$8$OUxVy@a@00y;c(Wg^qW!UYmmfoe z{W0&bpWIJ>j6CDVp-%p&z3RswZTyjVPv&dt5BKMOJk`M;Mj!n6yp2EPKg$0@KBIgG z*@m($WFN6devmOJV?oBGj14&kk%DsWyBg(yk+%w9(gWN;Py@cFT%Dsi$W6HgT+;hskhdcw6X94m|P@WCQ zGeUV*AkPft*?~MmlxGR@Oi`XK$TLQH)*#Ou<=KNggOq0x@=Q{mO~^A!c~&9MEalmi z-vtIxo@K~0O?kE<&p72-hdlF?XCJZ#C~E<-CMatIvPLLt1+r!+YX`E1C~FC_rYLI* zvc@QD4YKAaYY(ypDQgk3CMjzZvPLCt@PVvZ%G!mjVai&DtZB;HhOBYQT9^CTi?a41 zHh^LaAU1(w8z444#!_r8#O6|LFT@5@Y%#zE+QG6f72U2_?#3xdGBg98id?mzZ zQhX=Ghf;hg#HUhxE5yfAd@aQ1QhYDO2UC18#3xgHGsH(zd^N;pQ+zkXhf{nx#HY*q zCtku~3!?aXh|j0^en<>Ji3KEX4Wh&bkQjjyD?nlfO6&lMAtg2XL1HdS>;;LzD6tqMCZoh=kQj{; zt3hHmO6&%S;V7{jB&MUpc90m466--?K1%Edi2*6GAS5QF#Dq{Nnx7?TofLSjxz>iGeAxFeE0X#Kw>qnG!2QVrEM042hvBu{0#6ro`5e7+Z7)4@k^SiM=5) zI3*T`#N?FN91^2bVs%K&PKn(iF+3%fhs5-h*d7w&Q(}Ec%uk8^Avpjg7l7mhl-vN4 zBT#Y$NX|gX9UwUbC6|EY6qMWol4DSE4M@&G$vq%B2qhPRhB{ziRh?HCrk~30rM@SAy^IL9^oRX4TLUK$>t_jIGDY+*k2c_hq zkerl~n?iC_O0EjYSt+?IB!{KsvXGpXlG{RZTuQDB$$2TcFC+)1>;5KV%jO+YjXidF&9EGXIqM8lwH84yi_qHRDl4vN+R(L5;H2Sfv* zXdw_ygrbc=G!lwd0?|w;+6hEMp=c=(O@*SZKr|ML)&kL7DB24|gP~|K5KV@n%}5*^ zPSI*0nhiy}5kC}8(Q+V~4n^C6Xgn0H2cr2%8DMA3pEnh-@Bf@nk(tw;p3aEf*W z(U2%w5=2v?XiE@{iJ~<@G$)Go1ks=_iRwKI*4XR(e5A`9!1N8XnGWF52Eo=v_5&83KZ=Rq5)F0Kx{Y+ ziZ&>9HF;Hhkh8oe4vKaN(GV$GB1BW9Xp0byk)kz1G)Ic|2+<%ZS|mi1q-c{6jgq2O zN@NEJTx~XtNNFmZH@{G+T;x3(;^XS}sJ>rD(el zjhCYJLNs6M)Hy*kV2TzD(S#}5FhnDk_Y<5TnlVK?hG@tXEg7OIQ?zA>#!S(gA(}Hq zdxmJx6fIinJCPJ^8lq8Cv}%ZEP0_9)8a74ChG^OpZ5yI-Q?zb~=FQ4Ojt~u;qJ={= zaf&t$(a0%UIYcw3Xy>_ zLo|Deb`R0;DOx^6)0aHg5u))^w0?-@&%6LfNDY8e3xL!FD767djet@sfYb~qwF5{E zfl^C=)D$SS1xSs7Qfq+J94NI1NDYEgi-6Q5D76Vlje=6EfYdC+?mIwg7?fHDq^3cs zZ9r-qlv)R*<{|G_J3wk6lv)U+CPJx=Kx!nET8Z?Lh@#X^AT<<9Ed^3jq109&H5N*( zMf$-BjEe=wXqtxcaUq@4FbJ zrFI9Y;r$;)=N)eY{r_>5rj)c)R#Mt1isbcfm{Ad#|Npm(CoKc#y%HYh> zoLvTInC2`qIMXy|o52~UIqMA0Jbh_{n!y>UISUQWM9tY~a7N1cPR-!V)SR6LXQ<{Z zH3p4sV$N2BGgfof8l1VBv)AAZ)||x#XR_vOHaMd-XSKnZtvS05&T!3HZg8e+&US+{ zUUSwPocVgiyeon;U~?86oC%w=;oyweoD~OW#^&reI72pP$-$YjIa}ucv!>>(IXH7R zXV1YIv^k3o&ZN!RbZ|y(&Z>hmYjbuToMD@@?BGn>oNWhZ+~%x1IP*4V-@zHUISUWY z#Ld}wa7J#<%7Zg=b9Nq_p_{Yx;7r||tp{i9=Bzz9b2n%2!5O?cix1A^&Dnf#MsLpQ zgEM<`b|0MKo3s4jOy8XC2WR}|tUoyO_pC>21Pp*-0Rkq#umJ%hU|4~G88GZXzz`Ug zAYcj%TM#e?hBXM71H&E!41!@10w%$*2?3*EScQODFziCWFc_90U>XeD5HJpgbqJUT z|NZji0Rv%J2zsK;3>y(J5{8usm;F!CINF|*pq-k;ashHz@!*9C16wxs}e9PhFu957Q?axOp9S# z0>;I#E&=mm*q4BTF)R#wqvnQ<2^bl}$^^`eVP^t{#;`O2Q)AegfUz;GO~Bk3_9kF( z42u&mIfl&%7#+jv1k8?McLIjTusi|NW7wX6@iDAV!2I~-->L-+kYRxWCdjZs0VCut z?^X+#A&)*(EntWYOB66ghAj#hBf}a6%#mS_0tU&jNCA^%*rb3_GOSX-EE#qwV3-Wc z6fjMOZ3-AC7xk(ZFi&34nd|S`!mv;Q6Xl~R+88hryz>pc1EMUqETNW^8hBc$V-qNsV0fS~(w17!7Y+Asm8CES| z)(pEAFl>fp3z#;;wgrrvVci1e%{8i44H!7X!Uas6VdDZu&aiR;GiTVjfT1%iUBJ{C zwk}}o3~LuKcZR(S7(Bz`1x%h{^8!ZCuzCTrXV|@f;WI2>!1NimFJSx(>lZM8K0L5W zzyKN+Fkk`=8yGNxh7}B$LBkFP4548O1E$chg#lw|Si^uhH0)u(AQ~1iU=j_R7%+;4 zRScL#CWlo5hS9K$0n=#M#(;4&tYg4Dy4oj|0|wHtkO32E*vNp9G^}L6Od57FU?>es z88DTGtqd4T!&(N+rC~1v2Gg*Z0h4Li%z)7}tY*M$8g?^aI1S4gFr9|&3>Z(tdIrp= z&%Ud2z@5F2v@$Ghz|z_TQ}ys~j-PhFuOAX2UWEOtWE|1IF2~&H?jm*yn(OHY{|&L>o3bV5AKz z9Wc{|oemgk!%_!KwPC9R#@evf0dsBG>wv*FEOx+T8#X&&v<<5rFx!UR4j693atBPe zVY>sy+pyjN^X)QwF9{fM!-5A)xM9QbM71`oc)*Msc06Fn4ND#{<%TT}7<0p#2h6!) z&jSYCu;>AkZrJpIQD+B#Nx-Zdc0FL&4a*)d?S^d+7`ZX%o}z-VCW4?A29WXtq&M`!`cVTy5m@PoC2{7A$U?X6*0>Ng$YzKl3f!PuSn*y^f z2sQ?0YY=P>%=RGIAeb#eut_l6gkYm!whF;!!E6_T4TIS-1e*r4Z3s3FX6q1a9$fM0 z#lZ%`Y$1Y8gxN*}8ws(i(qqMwim$$!)!5vO@`TK z1RD*r)d)5lX1ft=ILwwK*mRg}N3iiQTaRG#;nQ!wIM{%gEl98lG24(}BVx89!Dhs4 zM}iHB*^=;m1)q1~qF`fUwkDCq_*`fuTG_y?$Hfm<87Hrncc8%}D+n6m|uxT^fwqWCCwr;`Z%^7E35NzPg7B1Mt znQdIKkuzJlU^8d7bHRqrZ0Ukco!Qm}8#}YL3pRIVdlzi*%oZ=$I^2OC4PH4HX~W_uWH5X}~m-g{fKO$;`QW~&%%7R`1s*f5$cW3Xv7+s0tyXts{Q z=FzkFRSY(eW(yf?BF#3E|A*U}tz@v7G~3BwLus~@!KTt|D}#-t*;)phOS8QUHkf9M z8Ei7mHZ$00nyqHA*@Ppl7;HGrmNVFNnr&yW@ibe{VDstqRVxM?P_qRMHlb!48f-+( zRy5d*n(b(?AvIglnAhrarebku_V{U^8pBv%!YeY-xi{t=ZNF z8(Xur4K}xCdmC(U%@#M<?aWp> z*i4)4bg-c|Tk2p_ZMN0H#@cMHgUz+sUI!a&v&9ZJ*?eDrZm`idTkT-8ZMNINhTCkp zgH5;F%{`ahV>`3;4mRH&HuBtH18%n9!6w{n!-I{u*^2Y}Y0uBa=LQ>c_^xwp2b*`l z|M5A&2HtGpgH62I#s?dDvy~4v^JY6AZ0OCFKG@WoZGEt@H(UE)b8oiy!3N)K@qGL{=w$o?=?IpZ~zz=K;Q&0Zh*iMU|a!# zGr+h50*8Qc2?S07;}!@U1I9Ig_v=C99ta!+yq{D)a1t0dLEtDbu7bc>VB7_P!vKD# zeBd-NZiB#aU|a`*^T30rln)#T#)S|#5sVula3mO4Lf}j=?u5XhU|b4;Q^B|u0>^@J zEd#^n$=9gN!{a6A~-1OJ~t=-0kE zJ8(c47ewHMFm4Fm4}Z|OA_8ZGaYqCW3FDIBeCt8umIxdZ#x)T*CyaX{a8MW*Mc||` zZi>KBVO$k~v%Ge9;QVm^+2sNUh;e}gP7vb;2^=BD6%sf@j5{Q7h!~eh;1n@#5#CSeU|b`C zbHunu0tbn4kpxZ><0c6lCB{_}I7^JXBygA*mr39>F>aHD*Tq}Wd#kf}j2a9pB1Wp#?W(gcE#?=xy zTa3FUaJaBHIxBFx7`IE{c)^o)R^WW`nigjT4jAKt37jy-4HGzGj4LK^#u#@@;E*vc znZPMy+%kb<#<*qz=ZtaB1P&VGq6wTd#!VAAYK*HUaMl=i4d=rhS^l0GIBksECUD#s z*G=HO@qG)<3>-Mdg%db&j2nk@wT{M>6F75>J121H7?%z}cSqya2^>4dwG%tbbu#Xq zz`Dg$efoI}Pv6gY^Cizqy-lW`LTjw0hK3YGZ(CWL!*vlgYT5@G*5VuBO1*WZX@G!^yauc>lVyaXST$C*yhw zoKL=G(dmH$%DA8cCzNqR1&%1=iVB=j#vK(nq>M`{a7r1sRN$C0uBpH|W!zJNgUYz5 z0w+pSK#O}uCBn@W!znX!^^n5 z0;iX8dj*a!p8wMV=a+}HIxTR385daK1T${1z!7F#VSzKuxWfX6m~n{(PBG&a3mjv{ zH5NF>jC(9_kQo?h71##^o0{{fyf$aQqq9U*P<6(6|W$N1<^Q z2F^m`E({!o#$^~d4UO9{a2y)fVcojv zmtx>lG;T$9Sq~Z4V&Ggf?nS)o4;dF@;AAvz#=y~NT#bRV(YPA}hof;h22Mxgb_^Vk z#`PFDAN}-QT&~AM#swKTA&na{a6}qcWZ;Z6?#RF)XG7X%j#%&rnPL1m{aGv_K z+sXtERO3PooT$c)8aPsoD>ZPY8h2{oP&F>qz^Up1Kb{bdRd0R&gmA9<=L08%gVi^z zKOvl~esuN;;b=9kR^e>*JJ~0M!_~N4h11o|?mi(LuO4v23E_P8hKo-K2dr_y3MVXI z&;NuY*0^GYGuF6cg+tc3WQ9}KxMhW7*0^ScbJn*0^dlpiwvD zt`!bj)~@UjN4eFF39jl7yPXamuBGc{7dgw&oC}zm93Rw+{n8A zh799MR{NVXIH&zfsfHQGrL4t~;Q^_?gk#ybmi2wB4C7u_#RoEsi&;3Cjhk6ryJh&p z@_*^^-WkT-tVNGy7?-p5a+nFzG2~?sx>sjxS-X1bcS(5>(PlB z#ucp*(=&`aT1)3-7?-s6Ey^%%X?^@uhH*{n-!&P=J*`VNWf&K=>Tl05ZffDEHm+*n ztTygyjd&%)xU99{^$hRI{6kyc$uO>K9X^`j7w-5&IIxWiTPJ;+VcgiN^kar`W$VV@ zGmJZ1P5#X=E^Xn|Hg0X<*fy?h;oLUvZQ_%^O@;r#Z?AO9vC;Kl_moZ!X{E*#;;6)v3N#vLvk;>IN|oZ`kUE*#^=H7=av z#yu_^w(67RQZd~ZX ziEiBJ!jW!V>B5%zHi-0Q-@&i@a;2q(L7vkOPNakUF) zyK%P*hr4mP3#Yqry9>v=alH%YyHBsi=bzTYxZs5o-nij~Bi^{;g)`o`&8wvVRs1dgG!OPI}{}7mj-4su#|B2KWr!trlh|HAq2Z@T;_8UUsRAesQC4Iml;rWGKX z0j3=w8Um&zAesWEEg%{LrZpg%1ExJ78U&_AAescGO&}Ttrd1%C1*Tmf8V06iAesiI zZ6F#4rgb2i2mbr_3#(ZK%~e17kqrrjVK4yNTGnhvJzAQ}&*^&pxLPE7kjG$2e1LNp;v z8$vW9Oe;b(BTPF&G$c$*LNp~zTS7D@Olv|kCro=nG$>4qLNqB%n?f`yOshgPD@?mW zG%QTZLNqN*+d?!hOzT24FWjrn_o9JeS{R~_A(?$`E6w^u(%@os4 z5e*g7QV~rR(^e6U71LS~%@xyL5e*j8Vi8Ri(`FHk7Sn1G%@)&c5e*m9auH1z({>S! z7t?wX%@=Pe^R;Nem==s^!f+0COf+KfL>&{&7}Jgs4H?st5ltD>mJy8^)0z>@8PlE- z4I0y;5ltG?rV))AIE!PVS!3EYqG4lNHlk@`+BTwbV_G+&dET1 zL}SRbhD3A7w1-54$h3$=lgPA*M5D;GibS)>w2MT;$h3?^)5x@qMB|8arq4z5$p5|k zxo9An7LsTpnKqJWB$-x{XeOCEa6@MTr`(Vdr35yOp8f0nM|8W zG@4ASNi>^GyGb;hOv_0$olM(FG@eZBNi?7QSFg`R1Io0ZL=(!ip+qCfw4y{a%Cw_I zL&~(IL{rMNr9@-Ow5CLJ%Cx6MgUYn1M3c(2sYIj7w5mk2%CxIQ!-{v+KNU?Y)3y?g zE7Q6X%_~3l_a~x(Wm;IGiDlYYqLF1P(d6=rmwX}`U8dC~nq8*dB^q9)m$)DbG4x#iH4bnWPT)?X8z*Ak3{3l&Eq4{JoAdHKN1Zz(?SzXG@g&6qLF4=X`-2C z+G(PpW?E{Zsb<=0qOry<@Tj(r?_=6)qQT}94;>XvHg|1yR5aR5t4%c9OuJ1q+)T?& zG~GrFJ@oOt#_(SS28I5pnS?M?nrG~!GvPE`-}G3_|fkTWeg(Udc7InkIi ztvS)0GwnIipffEx(WEnNI#v0#k7?D3W}Ru*iH4nN*@>o|Y1@g$ooU^P=AHMn`#?1C zObbsm@k|>}H1bRxssmY3+&To@wui2A>Cvd|x#AOq)+M z`b?`&H2eJU-S3NrpK1Atrk`p1iN>F4{fXwE2OWD)GyqKtP&5He8&EU?O)F3|15G0mz2TglWGzd+LP&5fmn@}_gO{-8e3r)LFGz?A4P&5rq+fXzP zP3urJ54|n@u4o{d7NTe(nl_?nB$`&DXeOF=qG%|ZmZE4Xnzo{7ESlD$XfB%eqG&Lh z7Nck~nl__oG@4eUXf~R5qi8sqmZNr^*4MNhMdQ)59!2xf{VTkq zO3|=1Elbg~G;K@KxHPRx(Y*AmCy$5*rfFgF{d8Z`#uSZA)5;XhOw-O34NcS16irRj z))b9R)7lixP1D{K4NlYI6irUk<`j)i)9Mt>PSfrb4NueZ6irXl_7sgz)A|(6Pv3dV zTcQDKTA-o{YTBTp5o%hYq8V!1p`sybTB4#UYTBZrG0MOHZ;IxqX^)BqscDglCaGzY zibknvm5OGmX_tzIscD&trm1P0ipHsFor>nEAAR8s(LgmVRMA8=ZB)@nHLX<9Of~IP z(NN`R@?(QGyCR?%=ZEmxh_p`U5H zipHyHy^7|m&+PKLXuz5lthPVa&$MAhBi6KHMKjj4V?{&Ov}Dy~AougN!=f?kncEJF z=B#PYiUzHBjy)`zw5Clf8nvcXE1I?Z`+Qh5Y)#8nG;K}WRy1x+>sB;xeeJiei3YA| z;ff}%Y2%7Uu4(0pX0B=HiiWOf>58VVY3pkKk$$GNE1J8ey(=2Lro}6oyr#`78oj2~ zE1JEg-76ZtrsXS|zNYOf8o#FXE1JK4DRoFRfK3ZnG=WVUSTur7D_AsxO*>dLgiT9W zG=)uDSTu%BYgjagO?y~0h)s)FG>J`{STu^+#~c*RV$&`b4P(fN- zW79qs4P?_o7ENT+Miz}^(@GZ2Wd2^iDjLdk5MC8cWz$v`jb+nX7R_bTUKR~z(_$7) zX47UCjb_to7R_eUZWaw^({k3Mb00HpXVG{zt!L4E_SiYEhz7K2L5n7|X+w)fv}r|) zX0&NXi-xpmNsFemX-kX7v}sL?=Co-~iw3o;zVfnYQkyolXjGe4wP;qGcC~0&o0hev ze#iap^s;DNo7S~xUVH7eFN+4YX<>^dwrOLFMz(2Xi)OZIXN!imX=#h5wr^Ybl4xw3 z*0yMFyF&g;qQPxi+@i^C+T5biZCc%;*=^e0qT$VX)r+F(ZQ9L6PH`Q zUvEB?>8X?V>!}`@?v~uIWS>l5-D|&E_s{fCt@f*GZl-tE+ppt=nI2w+ky|3u_nx+2 z6Ccm?g~#`)+t5sZ`1U^CFe=kacJI?a<1+o&ihX)r?Y zQ|*PB9@KiD{#ughCiVB}z=}+tQFWgtuFb?>vrnBjW_rT$y{fS_({10`t8aE@y5gR_ z+OQ|nZ?4#@$K zcI$~Nv*;=9R@-Z{{O^k0I=gn3H%-~C=WfpOW2xO5)F8{%d+%1m##!9o-TLXyERU(b zTPvGoSygwdN2@IVblPrJYLn%q$E}0yv)t(&Ygp$jm)m1C?3Ts9!`Ambvz#--^xs8`Qs{9m4R8Fc$)R<&@4AT{;UR!%JR2wlYSqc z<(a#m)%%mP+;qjW8uJ9VKlxeRIw#BXlh5k&1zB#{>sd`+lI34pJ*&nmvb><)vpTjW z%lA}yR#P`*`R7yl_?9fs`(c;9+QH+0dzU8d&hii5rG^Kx{KWEI`s77!ck(WcI+*3p z6T4LVjVzDtxl3=oo#nc%b}98imfya4m#Tk~<#gp;+W$qCFF$pc`hJt;1K;mdx#L;x zcVws5{+wk>8*1}Mme)PCQ$PKaY=@q$o$cBa zcc^o{Y`;>nLq9jjcE9dBG`?}RPi?tFSKXEEg>|`Hvuxjf=?-;hmF*)Z@6ZqTXFKoP z?HblT+vVQeu1h;-d&$o2TK{mi8!z3iraigb`0aYPPqwp*w=1hZ*O#$fC*@{)Ui0mm zTA1yd>ul%$scgSgX}h)z$acm_+tp%7wtxM4o8B3b?J=)!Q{S=KuDWBJ{+O8U4Nq>< zh-ukwHg20Pn3e5!3%6GgGd-ifVx zcvH6TKDJd~ZO!%@uWeP{u59<*wpD-a$@Y(nwra?8*&Z}ztIm2k+vgN))#O9jp4)Y+ zD!rNQYnyD<{C9XBuivUGKID2X+^XfDWc$#+TXg-G+3xz~7Onp#+g~2sqMMIrJ9o<# zZT>mie=pdg27hFG*r+Yq{twriw?(&|l;atlw`j+yIj(jWzdtL-PhHEOpOfR-=X3e< zbG-TQ&Dwl%jvIfzS@kOCc;73VwZ3|eTRyW{H(Z(HgY!0P`87FiH)6AD-k8Jr&1TKN zDaQ|W+^kBs=J?~-tSOCh-0SMiI_r)ce_3I(hBnD@-#?$xUoCR{%_q+&@7^5ztnd2ifH)-qG96vC4ldhVS z<5&A_(zIzgZvMa~ojfbYdv4pL?0GqEbj2pUwey&LrHXE~m=a)a(WmgBRhZqWMg za{PE|gDU=*y`lTlN?w`ksx6<^ zo7d!eOx>q-!;QKA^^&JG;-*}8Kly2WbW1M&_Vv28QLgL1v0f7**9&&6*B5u^`iv#( z)u=_T^Tw^$h;X^hySh9 zh(5W#`>S<&`>|XvKeSF)=j6Kl)^$o0m#GqsZu)Ex8ojL_uCMxgt-hL`>ye+W)lIW=eeC76O3%-A%S~(b z++uEL?pjrNiu*l$tvavD^`lv9wP;FSSrq-&?)?5#{YORWQ=K7;^)@tYO zT;Klt8l7|?*Rwuaqh>Gi{5-!#V_wZ=uf0YG59fOI%r!diNUl#GyhiQc<9_v9qv=O; zy|e8az5QvfFT8DyF8(UlIW^X()3>>P{;V~caXi=6e_pL4Kj*si{nfhQk6a(xw^|SU zlj~ZmS8HOKJP(+*TCbGN^PB0_I^)bdU;D^vH7TFxf%mS~!1MTc{ngrbVIJqmtM&6G zT>iAxy1r_j5C5=Ay=&yT=G&_@_o_UXc$MC~HqS3TwMyk`=ehEvRl4)$JZG1#Qt_>M zcK20U-6+o$TCUQ^k>?(DSLuQ#d4BqmRchWM&nKO{O3BuFZu8Abt!|U&1+TBv(e`=% ze)~$D+d0pTo?NMTIM1WUu2fEsJRd1osRfVZ`HF{D>eYUE&S|nze`n=+$Mq|9O@5wF zzi_2G6zBPYe^+QoGLMeW3ax!S&tJW|g1@(UuDf}K%8tx)YW@n{I5yAwN32lCiFq!c zvqFQW=J~;nE3|wDpBF3i+MGOpQEP>MUy$ePE38n}C3(*OW4W3v&-1pAm#g3EJpcE? za!pvDM;B?iHf-X4&RVV`Tl0Ky@N)gRGtU(tTdvFY*Tp2Is;qzRs zfv@JdTDj#~aG2-i=cnYi^8DocPwD8pdH#IgQ~Kw_JYTu`DP8($p8HIDO1FNQ=Vj@q z)c%`1f7$yf<^I5*-}{ut{gmh4^`FwR-}wA0PifCzdH&?or}W-`T>lTt^vlWle(1der~=iPF$u3&d>LKCCk+B;(U+JSf%lH1~%QUrGzE9L% zrsY@UyJ4ke+F2{#1!b1$&~^Ddt)1^LUR$bPZq9erZA*1(gM4>bv{V<}p6>~x zm#Wqs`96@hRJS(C_dlJNs#%MC-+b3nwQrs8e%CHluQvH!P;sep+voeuzm{k~r+lCJ z*%FO@DBpT{3Fl+^&fmC13w!5#*_)i>Yo4qc*WGV^_Q<`O-do9}49M9&xIJMZ=- zI#inPCu=Uz+i9-v>?JxnD4(6illpvEzHj;PNqsXaA5YGcIzBGnPpo-Tzf9u(O@C5< zOw0E#1D@1BGxL2#pC@%z_oPl*l<$GJJgHNb=6g-mCslSuzTZ3TNu9bT-=`g4 ztW%%n@w~lQWuM7+H!s#H+wwi;sl_^JSH7Q_xL7B4=lkQ5#rkJ|zR&8uSbx5d?|Lm3 z>(^Jfe4WMm-)s3ES!uDpeKX(d%PiIx@8tWPV~ce3gM61cyojIc^L_QUMSAV?eBZxl zkzP2K&w0`!`MZ42&0D0+|I7E@&Wp7AmwX?)bCDMPk?-=?F47bK+`_aO%^A$~&XL^Iux1-e(th?}mlyP@%wI%wDMG7ZmvPp$pZZQh~4Ozff0KE`U#3 zs7lofoYiQdPOn+u30ExCZ?y`%w%kH}eqDhN{=7hkYZv&3_ZR5dn+tr-{smfjYk_ZA zy+G3&6}a`Z1sW6ucwrZ)|J?;1)q8>3H!twg)(fOo1>RS0fv&p0z#mm!pmW+4_@A;1 z^jn7lSNeXwKIl^5o8OwReccLt|E~F3-m}2{md@9NJ_Q~&e!lV_<8c(tSBLBZZ+&>a z8s-=HaMSs!TwLI9ZkVtC5(PfxqWSuGK!Gp&Z=UuH=K8*zr$xgHe9yso8a%qdJvPr% z_wfb1uQyLIna4L`o~leQ@RIC#`fFx^w|AJQx91l4kmhOA!UBJG)jUmHQs6(%nWx8= z7x?Vo=c?)I0$2ZNuBxr)`k$YxKQUdgY4(Us5_p^S>@|t?qM_{e1zit2xq-1-`S+9F_mI!1q>~qYwTlaOW~} zwDO+(=RLZ=BsDxwW@`Fw!&=9tWoIa{+OliR~7o;$Fo%H+Csne!YqA%L!m!d zKT8|y7W%W9vy`Y`=&uLOk{TBJhrY9Pa^ph((q@(p+)?O18_d$ECWZd5`Yg3-QRtJ; zoTc)u3w_#;Gj;I(LZ9{SOigT8=<<7J>i&*}uCQXJ&goj{ij!yR)oz8pATd*8dlvel z9y8UlPoXbvIa8-SR_ID~XKG(op)a{)rUvHm>q#?pTM@s0Jwv~i^6TLlT9@W>+h(ZW zAU0DPZau$^Jb|3 z>_V6Q^9fa-U+6NQJfXK175bkSp3tbJh4?L=P@@%v{%PhD`eAjUzZ>*~7OpS!mwlg5 z+f9Z3xXlwfd26BHZSaIP>?ri>)t^vL7y9Khp3r&w3cc@t(~;y9ddEA{mGx4gH}0OU zOAi)$9cc-eDL?F8h(C}{n1p_y12;eo}a4c zFD>%?byL;1YLO?*n5xrj6nVhFsakerk^4V7RZXuca_9S}>a**M-2B$58dRsq^{Y)) zm3l?4ar#tkyS2#Y9-pH2jkw(-Q*>NK{_5E&8huxh-&i(9S2W}HCQQ-JmPKA!JVg)Q zTjXiors(@NMIP8}3O}zEx!;XbbXlh&KXB0$J>9j)xBoX;%`=L8<(HH7LC+$WKR8*r zeTv}mCadgYJf3-zH6yFY2Zm49wRuHeoi$lI3yVDU!O6O}w8)9ZlXWyzewRpQM%Ji~R2DNxF4%5kB}y+CQxbui7NFnOWpv zy(j7YIYoZ7^(6IKP~>~+P128xi+p|MNlGm%@;PNEsqD%k|L@z08n>p%hu@f}3!W~b zn>SH&Hx+rxlM{JArN{+iC-Uz~k=qqa)Qv8J$DgQ;dy9PD-4oT|IX?f|iQ4&Mkq=dz zsCc!=YyO&`y{{E{?57jd&1yAApL?~0st`2@xP_`01rK|6ou^L`w!2EP~ipLfP<<6lKSvU|L4{Eyec z^6^@6Qn5!(8m}6s7Q093c+EYd*bTdn*9B)6`@9z8HSXMEe_eaL%AQ~B-4~Bn@}gqT zI5AE?UQ+C=ug0lQm0~wJG!8DT*q3e@r#3Z~G4CQ}*q}-u3HP9gSj7`f#l7y}Q`G4vf`~X2q_* zW~{Ecr`V@YAFCPn7Wssu~Dv#CrZpHrg zl(D+BXR&vDJ4QnvDfXB*#^}4g#qPXgjM`@wyVjFqv?Hh3zm6HB8U@APmp?|Mii6#J^D zM{CLCV*faEv`(E~?45%~>yeqooVSeDfjPx)(`K}4E-3aT4MuC|;$nYRZL~gKTI|)Q zkCs*xyYToZ&0byX+ut6g-`5qptVijAjm3Ut*(i9GVo#kgN~doxc9-H&>anZXmv3hrD8Yuccd;kSnPj49|^-lH)c!ZQKb!dY zJH>7}ccil4FLwE1Bemyfv0v*yQWt*8?X(-IN53d`heji{?O3rZT`^MSzAN^7XN^?X zYY;JYCT41 z&}k+9sKp4qa%PF=*BPNoSBN<8DxaK)u1esIfh zjjB@OiVKG8wdy54IAXXiu36%-*~8VXR*9Q;7_KGPmiQD6*Vi|c*jEnMjde?$EI(ZN z^-5g-*J0XxYl)A4Fid~mR^pZWhv{~excBN|di>53SD7|UZc^eSsbMP9qQnz>4bvU1 zO5CE=Fb%w~#AR+Crf1uhcpltKR#aK<j8eZaao*1IZqe{Gczz`i6TjGL8hUm`; zCHy=wMAuK@`sxi)x9KH#=!a<1%n~;&J4Actl=z!(2kWQ#C7%7pVAWV$;(K-sR@{iVc1hCi;hznA!M`^T007q?sUaZUWU z#5q3?(3&!(-nn;xUOJ`JXHFTQuTCrFTwnkkMX49p8K7$AOa1+cv~H_V>IR3>dhq;G z51F4<&PAnuIV-JEmz4T~#%V38Tj$K*my2+IOySmgR zEmOMSdTy^$O4rmb^-0H)YJ5|vn{G*}ZT(V@8j;i^4Y=M1lPYOc>hf16HAbbr|Cfa3 z+*#^L`x08+q|~oXNoZ&DQdj7i&@1=w=XDc$|K3thD3j1PZA$&hp;Gog0RHt?< zb+hbJRqVq3Zd|IW510DcvrBbt_fr4)eu?V$D)r5)N(dX2IxAVCmii8D^{=kQs1|wSdSHzdiaQ9<&~Ct$AiTxNtOD?n#CIMc&V@YrAR{tm%7Wo zB8?cv{h3mvF(XU8r$>>-k16#pb&51`JeMm|q{)*?-SJSNrcUK?&o9)pCrZ67i(hAz z`q=G!d~T^Lon5FY3%LL97ijY0QWvf)(8Q&sUX&=%xaFlj*rGtAR+aj%iwiVtE!X>1 zz6L#A>b9HnmD*J5)bM;2Z7KEA_W8=*&gHMj*Q2{i{rgXO>b|>_e~!piM!!rAyfEQ)4KnperGyWh zo~c%sCH%pW{;E?o;UAaw*M*lSd|FX|{dq;gmo@3H53Wk^zHWc{nuPEA^f4{EK7n`U zF%7NF^$&VXy>Ci5asOj#Qa|A_RUcE$1_{skzMoEMl<=yZ{q$+$gtw3Fr`>lX{9>1W zns;}??_ASQ$z}5PDxMI zS&?wRWiF*ZV1L5rKh$0Go=^CU>$2;p}DUo{AQmFb$Kh{=jvyu(mM%nDVw3U-b;A-8{IVd!-Qup?xuS`=JDlq(;1)f z{N2$_d%sBdk#oB#eJtU2M<3QL-zI#=nuqnn_X*#Sept)?$Lq7z!|L{P!lz#PurBA^pD)dQy`{n*~FDtl(q zZ6|lt=5k3l=-yR*&q=yk?XJ4yyrfV4uM1pk(%-z&MTv`&J~XF`uD&GcO^lD=bEXN|ck=^90yb;~tLpVFkWKDjRG&ntG;*c+4H z|4Ap+tDE$a^_}$L%}Mr}oiyT>q5ZK_DzjPA6Ki!;g_b;y-#TbhtE8J8=%9}GC0%t|2mRS5=|6gQ(42NjAFkU$ zw|7W-MVSuzuoI8}(1RM#HR(?CA5`UTN!QMLP&>LOecJ60s&lWTKRD|_{r*VOPrut< z)A}YoVtISj>7R6$lJxL(JU-kj*8Oi^3@MNz#`zZlf8?lK!Mz8(q1A$N%2_+OR6=ycPE=*7Ef(ys~RuyJaoBN%U?JKyK?Pin2kN0VOsS}X1PIO&W9t4E%n5INmpvqQs)8uZE}GU{H(i{98)&X2m!$k&-R8Qu za>`@NG}oxADc^pmnf~OE`ulm!)bEOv=Vdn2yH}=sZ=+^vadpc7oY_p9uT6Q?J55#d zhLk%$)l^ezr+j*GQ~g&ralt$_c*_)j@*)R`A?hZj)p03Ti-;h8m0Wmz$Ust zDOb3!i3Z$}^7hJ2^yOVC_x|>7-Pe@+yZvrG(>&!Zqwdya_oSTB@oo)n&Glb(x4ybB z<#oT@rB-cI?y&DJt#6m|zmxCM`5jVzvin_dzA3k?eHWZj%0K*jr*3;V<*BdSsW}-b z-#X_`{nI1G&%Jl*q24JEY;dP`^hxo4#GSgdU&{O6x~h+`Im%N4@$Z0F{$j( zloxH5x(?^if4H<^B+qv{>5MTc7uS%wjZ3-WkBzl)Ldt90Sf@`;(R**Ku2WO~^r6OD zJ3Zy}b&Yk>%#<(u>vpx9o$}fjZr75zDL0#OyMCRY^3g|bSJOpYU%lHk{YjqhQ*PJi zOL;yHH_}bZQ*OAhkp`{gb(7slude2KZrn(hu1opPa*fpI>6FL6cblHxnDXT-Zqq-{ z@bxRXP0hBZ+`QRsnz)_&d%pDZu815YWEpmzuC8F(igmr z`rV>~U!{Ef)>~BWo0LmWyG6~vOZlX?>TAdke0`p*uU-F3`Mmu4`s1gRXWmg?b$?B{ z+PU@h*zf#3`LLdz{4?e2SJz|5mhy&VJyraV*GbEIYFQ@jofp^Bz?0LyOZ(pHH)~k=v=9AoleV0jcH3Py>DYN`zcKbEU3x*< z?YrEhdoD`*&8u%xvJ$`ly{=YX%I^=<)w`9`Za1y2POp~s>pknL-sNexsasb)u1Ndf zi8`8aW!kL|*3q_FX}>tPj=s1iO;5Cr&b>bEy$$QA;f-lGKBJC$)=7KYk=h!2Q`+^G z*4D;)X|FA)t@m$9`|7)D>*R)MFRoBqS2s%gvX5@meT~zcKi{Z=NV|OcM$Nc0?cw*_ zs2z8w{ZFMEb+l>P1z+8ulUk(x%`-RXihI)TG3*94X`S|w2X4?K_i?{2zd^&>q`l|( z^;-Hs+P6G=z4o_Hd*!(6^=XH+t9HF!Wjd!l`I_rhrEA({|G197k7<`Ycbz(9r2X}@ z>y+0c?XJD9)3{z~zf$))EqjE=Q|3DPQSSf2YxPb)u4mr0`mul7gWSFa^aPP@kOtJG?0+GBQIrH<3n{%P!0>Nz9r&Rwoj)~vL5UwxHI=cIkr z?^kN@ytKz1xKd*laJi{hYU-l2JNCR%bDrdNR_97BUYd6G6E(HsskDc^T2t#*r2W;L zn%cA~?N*P~)V4KguW3+IyVj*$;q;o?^K{zzZ(X7N8+n~Qd4-;PChhw9SLlT;X-~i7 z3ca{3?cdJ1LNDz|yTgYy^wKV#msK_NqSL-GSwk=ENxQH`4L!Gy*WE=mwEsZbb-uV< zyPr?9BfDI?UQGMj!Ix|6%RH}bF4v}4(_UKja;-g-_DSDY*Yd+@KeVH|7QK=7*3s29 z`>nLk?^In=-cCE~s_Gj3ZrU&WQcZ*2Pva-Ars5CNPED?+%#V29Gpeb_Cuv`QV>Lba z8Lzv4s;cD|X@B@qRo(s-uisf!Rr~9-$39wBmw%h~r}e9<;`eDcC|gyh9OwSMUPV9u zFYV74R?(+FrQI;6iVpw6#~W8+KgH$CRneM1cs;&XS+oD*>$AMFM*frb(c;P~_>afg zw6eOD8Q`JkS60iD2l%Z|F4N6r2e{Vy%l?m~Gl6rTDF1)j?vd?w+w@NF?48~1?xwr# zZo186gNg)22m%rjupnrW!vdm3Y#Tu!97>QYoL0^vS3!<)$OMEhL9U=21q3T+xukMP z1%dzg`+xVfeNUUoG0!~D%zU12H{s(WRd{?Y#t-9F_~+eX{JUdS7>&jFr^l=C@HeCU zJrh-U_Z?CGa!(aHPl@uXw+g?#ca%TUUxm%7D8Fa03P0{g_*}ROcZLx@5~;%9{3^nK z8m+?acOv|Y@hV(ijPNjt&NCqS233VSc96U>RfXR3NWM5zg$I0(ENZV1;;-MT!bjX8{+Ap&--|*1JA4(&*9G~EP=%KrALK{BRE4kZ z66F8(YGd_$_jp}YM2(ci4XT~t56)818h+PC~X@hxP}89)EhzE$Y@z{g+z?JE4neLi%% zf-3y=Sw8-&2UOwX2l#mZcdO8y_VF(jt8n*Ey!^EXSK+TrFMsSIRru)nULJfO+5J#2 zKT@i~UDv(*lz!L<2;E`2myNuvxepE$YrX%>b%2jy67QwfUslq#O zg8%W4tML72JbeBqRk(7MhyU+StMIU6J?MLqRe0r29{$7=s_-R`hyQZ53dxt;{7}6L zzj?ize^9ByGk)ggPd*WyM|AUF`DGQ|$I;C@PN~A&YZGW)T!lyeVS=xnR)tsnVuCN6 zQH6ioV}c)?S%v=O1e)Kg@N4h5_@lHcRPJ)|3%{wt+f^6;@;O!X95xq!$$3>cIqTy0 zzMu-f^}#srx)7c3zH$D6i>l~;l;ix*Ea(aQ>V-s&IHGoEPq_qUW#U z{M&a`;XyBs^5@@EMfal~<#)Qb3hz07lz$sm;hVdR^5@=Hg`vy;y-!@#l^3O(D$*c@X-B-_>Je0Jr;-f zXI`knTL%vQxEHJNg&hvw|Mx1ipXcCj?jpbbo`c{0XdgXa=8m_GMoaA2wi4`MzBuTV93-lP8pKbWdPv-EH9)^rU$&*P1jKV>qGGVLJbY&y-(L*>c$Vi(JM8$``11I@2%G0&tHEZ z9GR)XYfpS1ytP(?&m`XmKgiag{qBE(S8_GDvhTmZftxk>?GO6kIkpB*I;#)%+N!}D zmipkaLJdCq(0kykpa#GA-h1F)z6NRRJ+L9v;2xL!6Wp*<4gQ4vCz$?n4PN@xyWqmF zAUl=c1)i_gV9)g~IBAy}oVfNK@Ud8fnVsJOhkvaG_xZ=$;H9tEV5RytkiJoa7e(F% z_w8PT_uTdtSd(h-r9IyQSL})G{O+5;w-;*9>2HD)_pU*H?oH6&rv?wWzXuN77q#oa z9(Y7X`+xEVVE3z`=P17cuKW(_=e0KgaR9Q%<=I{I7z2N;L>?dIj8l7_!&bUjdVc z*WkNvybMl0q6Qtmd>OoTWDQ2Bm%%rFgzR_EKR~NogI|{a0er{Q;JzPr!H%zKjiP=!%7YQ0sA}H>t{9iz$Gt%n@>R3&AtTO)f#;D zsTaZFwHo^Snis)Cb<|H2FM{b`)X@Lm{|(emtij~Ye*>M9YH;ZvFMzd^YjCsr0yyIo zbpFT-;FVKRzufjbD4bS<`|bHW_|54xc*wiYfj7^n!J|%l4s8Dl*&RKE=G%g;BPa}f{pWP@T$k20qXfRc->*ofafl# zq3<(30~Rio54=x-Km4`^AH3nO z0Q+4HKD6s!!ETo$zkcm6;DRd<{k&{ z--7)8$;ZIPtu=VXk&l7nZ>zye#vTKA-(G{~U-c;X?2a1z^-hlh{>~aa<;6!p{jM6U z9sdY`ch}%?!AHR7_tfAKH~$%cdu#CEZ~PgY0BcZw^I_07YVaE;KMX#)5BbsL!yxmg z8r=A!366ZA1{c3=g64xL?mv16ys`uJ*Vzw&xQY62`5~~+!!`J!xdZ(A&uDx&WCz&s z2=Xgz2l(t!)XqyD1lh-H@OJh=@WUr+@am@?01XR`1LX(6Q%|CJbUgsZ{#t`aH~$2< zr%?QV?gNLuP=l|( zZGiLshQ_y34e+NIYv{Qv26+Fa8oUxhkm}apuh1=wcKZiv_s92w%F8Ie&bb#{`AQA$ zym~Kq;#D+0J@QBJpVw;8_k%xz={IU{VE-f7t%u_DvU|XBZ=!zQx(8hPRt+|vxf?w2 zb`73+%-!JacWSWgz8iS|iN?R*-vu_`Lw@?zyTJZ^6gMy536y`KajkkMxbpoPd@*t- zc<6%~y!W;?c=JQ#cYC(M_`hqg{_Y(h{V{6qX?K8c3{d>f-T{vM53=ulw}Uf3LG9cB zc5vONHTeACHt_I&Yp{LpZQza1klmQuz|a>pc+8`>0t&0c-AlIu&Q^zuL$`u`?R7ZZ z_yaiFQHR~aAHW$yb$Iu)w}2~$>+rl|ZvlTCsiVKMz6CrzT8H9wH-mTZI-K0)X5etv z;U_P*KxDiQ|59s#RaYHe8*PEFOw^%r`%OT0*Wte3ya^oPsl(-e-U#YM9Xd|G5uEL< z!{=si1XuX#@W%UY0Jr+<@T3E701pOG{r_AKo(|UG(s|c|S3`C9IdeVuAY6w}K6)Ln zMe6X%(sjTSt;3%TT?gVZbUlsV13F%Z5$^XOo2bLLp1l@qC+qO8W3L6frt0u?&$VDL zst)(Nt_k*^tiy#}n&8l>Ivl)w4LEYT4j-yr1CE+t?_ zuK<^>)Zv*7;%Xi4^XTQ^GNukwrOUyknL6w_E(e#a)nV(mzXKPo*I}jbJ8(g^4uxkM z;M`mt<$)UD?2S5n!rcI8Zld%3{*()~e+y2`BfGzR8Tk2D9llY$3>;Ue!|NlL zfup!OEZ=r1_&%t^+@6<$1Nb`p&pVfZy|?S|9`zFNHK7jcGnW8ir#k$SaWTk!3HA5> z7lVZ_qxOG%5lDQc4%Krm0>sXB__fuGfa9xmbbqxA!H0;CeE&l5`Yv^NhW$eDj97hRA`UjVN9I@B0dSu> zynN~$aP_z9@PK=N1Aet{9ftS&4LDY=L+hin!MDGS`uFU!0l!}zetG$9F!h}}{M6LI z$o_SB>meF=6Y&U41CJh1htrpw1#UdB4xisV3!L@cIz0QYzXm@lBLDf(uYq(B@-yeJ z!Ro{ltpe#t6feJ4 z!Q4^E?-y0@8De(Fso*a^s>4?gIu%?~uA}Exp8`%ex(>f`;VEE`W9sn3>?vUC*gCwz zIvIR~_{}3u1`qwX4sH0!KtHYyZ@S`_;IN+{J8l0Gp6_1sqvJ_TF0o zn{{-Zf3E{fsl#VOb?`9a((W~I_AlzNc5)Sb`$QC<_xv2BPO8JH4^IHEBmQ{l1aRFi z>+r#Ye+J4Y*J1FY<3aY6Iy~gb3K$^%0k43&Pes=+{1nvGI^5%@KLNsNb$H2*#{t{v zb@=9MKL+!C!T@Elf91xJDrLA@r+{t_A7L}KOGJ3MLh76GWhwg>qx(rLH;b% zAEh6Gj}Y0$QQ&3``Q5Wef+NnZ!yWD;!Q5}^(Dl_LKo@b(>fzwRbL#N?TYm_?d2SuP z@b+QAc^>NT>BGQ%hzIXi0+sXY@T#+a09GzQ{%C$5yo$JheIHz?BfD)L3chh+9sd5P zLxAlfH11sWJ#Z`H;)@4^A6#5V&;L6ZkeAfqHD5mn{2B4J6N}(ymm>Sz^1gHHL+4Z{zfXzl7`YzZXyo$Kni|E>;C8U7C7FRw#`+Yh{n_@86H z4bHuy4l~!uVEamRo|pFpZzBFKvM>0}Rdv{rz6AAx7gX)*Tp0}a+y!A`q zEyTOu-U*y^JF?%@P9Sy%YS(@OxCL?Z>}{}X8`;t1!QT;2{Q`jF?nLd|0Kj=y9X@>| z2QEYW@0A6xb~m#7-?qSmh`ac=z`pk&|NdGYyoq@BFIe!iKcaD{y$QzeMf1{o8{lHZ z|ITfIMTq?2z#O;}ai{aLU>5_;509>crw~tetb>E@tHZ0e*1$gzcO0Do$KQ|qq{)Dx zKh@!AcNLt4I2T?8kq7E<=iOJp<%oxzybKl}tiu!UNrPJufBV4_*xFHte_UJw_aQ!i z&?4C7p*sAxz5pIY^jS36)2zdlQ5rmrxGO&ozWp#d&T(_#Z-}+)XTgDguEPsonE_qI zTcR`Iphr-g>^TiyMtoJB0tY{e<}o-4{(%_$m;%Me(0sf?ftL`!a%c+d|2UdoE=hvt z5Rdt50_^hy8t0q|@Fe1;JH^3n7K+zO4D3KOZ;Arp$vS-T^$55V@n4AuSo;ea@Ao0W zwTR@IVKDhuG>-o%1TH|_{v-(8Poa3r1i?v&-zx>c0P(or`oR%TBmaKJ2fBzCO!&ZF z&!9N|iWfYH*gk;(o6n;2-QodF#Lk;;5a}TMQf_b>;=lKu00YF~vs~Z@&()!S$2fQz zaq=@K_|o%rxSDl>n-ICf$3W}_WVg$4a4O=ro*M=4BOXkQg8l!7#^qf`zz)Qp)rP_9 zi>P038v;6__KpK!FQNFHc7PusUbUYcJdSwN**1{r`*Cn(ENDEf4DOcpPwCY?;^f=&cC_cUq+eh3@h$H0>IL|BS z`d|7NcN8METc3LjF@4uRxusXpI7YwAsfb@b|84Fy#NCJ9;&yti4&`Hd+@**IbzkQO zh(Fx@HSU|Qqqw~174CY(pDn)34Znf>Oz(0BAgUvO=Wath>&Gv06FoG)y!-<9J;V#8 z=eau(FT1zHdEP|xZTea65X7r5dYWq^UW-4)jlWfg*Zt%#+<}NUylQbbBi{7QCpi1t zXdPob#_jb#t~|L9UB<-QEvy%kQG&-hV&$ zGsLTz`?wv5S6l`;-#<}2xbEc+K)m>8_i)!Bp5MER`xoNb-@23AdJnCu9=L-$5%H9@ z+qpj@)*H8S-acAKx&Oe)h)4hYX6`b?!``}ydj;_z`9_ZZ7qZum>$xKk_sCwywGh90 z`L)~!h#b-6a_`sSTJ37?r-<|KT*P1Y{=I%Nm-!HlfA3z%9fkP7cXaOeh_^p{KKDA}HJj&glOG{FUv&=m9mLc8zv0e9 z{Mj!w?s3E)zV~ZxzU*CWnfqjE1JhJvSZ;g9QZ=%kam z-4NgJpTsGMe?Ra#Ij| zFChNjIEowp51LmmIh@NQeydXAet@{N_o3Xmh+nK8%-x6h*YWRi?;>9P#&@{LCukn| zlgxbuakt;@!ySc~IN_Vz1&Hr`YY*-|L}P6??oC9^y({Pav<{1J?aZ-=t2@5L9fxZfjQ^zA(NIASTc!M%@|^R9ED|JI@X-Bm7+__&$ozJqwtl?z-I@la)s zy9|-pf10}&@zYI;dkOJDe}elA@vQeET`l$1v^_L}sr~3;xg1xa|C>u!Okl{r@a{8S&}kdxiZF zip2Ay*lN+}eK0|E2 zdsD&v1+vRk*A`NUx9xvLfk7+;E-h>$-uKA)h20UqdXiQ+0P&Hn(+h_qO7EXks32au z*9nD_5pTZ#sKVKZcV-SQT!Lsc_9%Uf?CKJ9sU>m9_uy?fKvzYt%3?DTyC=45-F)YAf*a(YZApyg1 z5yMCc!<;gPMT;2bDq&c>jA8Byh9woWUBv`K!vwpI3BCp<3^g$!(87d~HYS7&Ou$V{ zAT3OAb}%8@#ROLm6XJbLa1SsciP!`HAGLrt3zXxWUBw#^6`HUl?p z25H$0XUAqlyEensvl;Qe&2SHFMiR55^V=~mVaFV#9rIImY?!uVLB@`avUV&i*s(Fu zjzuIpHZI$-SkaD6l|>P&^ffl2RN7t~v~_<}e((!|*p8#&FYN1X~VcwCym$ zhQk;$9Y(}*7~>s>5$igPiJrqq^c{w0;4o6y5JuobI6(|yUUCTcQK(E0;Q?j{A7O{^ zkT8Vf;t)M9MZ@$#_ht_-V5Wmq89VUy5?g@`_E`WnL`*&H?l ztzmPdJ#2=IVG}opP0|`RotwTsNF(^TJc7rHBltvV1W%Mla8G3fPbnh`sg8(VZA6LaBci`C zqLR%KG1wXrN82M}*ccJV%n>nSjfmr&5i!;s5hr>hVxm7HdIlq63L7;Dd{p%kqlT9p zRsGbcNzkKekQr4+*-^hV7@f7J90M$HtCx}LxV zoWuzqg=1bCCjtzvcv+kXi8w(@IN_9WB3i@=R|zNLWt?zVa3ZPTm{Y|iLc_6f9hZC! z9CtQxDbT|4@is1n478t#OQeNM&JHd`ySU`);ZnShOYQ+KCGjzhAjXt2a!m74V_1Y9 z(*n$x5@E-*kT8agi(?uojcHDKOp6xBG*@X%iY4EMH?x zbT-GVKx<4KZ;x3aV@z_IV-{(RS?AxDCy`Q}l2>yomoyfi|~mql9XJ8Uv`nv zBC1nzk@2#NbXQztQgLBX)g=>}3ybM4+1GI4(WXldv|Mu zh~?H|9k(3oy7g$!EhqYJ*)wpQ|aF6aKJcgh2=zhv$`e=_HWIU#y_2^;2WBEjn z9+5njU-sy+qNn34dGtitqkAeIJ*9YzsOsr>HIEU~Jsp3;V@8{vPO#-MV{K0-YFGo)j}_~9IzFLh#B2 z6)h6DuS8JsGNJk^1eH_>%%`HyG(zy{MA6qk`!|VVpoPk9q8Ks=%x@A!(jo+ZhbTt7 z1nKJ$#dx34eFLJH#J!Y{@S^eC+wf6doTR;t0OM6j*4qe)-Ucaq8_}W{kCwcRc-gB) zE8a#D&3Hc5OZqggZ~Q^6F&U+YK3B!f$%Jq~(?T9d9?<^^(z^w;S(! z_2|IcO=3Qb#Cymq^mz@Kb(~r2UN`<2Omx-v|qSA|m=55y>w_WPc-8^o!AwzmX{W z&1l8nNGX0Is`|;O=9i+nzl)9_lTCj&*z$MCw!a%T{6x(3cO#Y``MSRw>-yzr&)-e- z{hjE*-%a5GDnJCVAQ?by4&XsHK!*hMUJTHr6d;0ffQ}Z?wo-tOmjh(55}=bx0E?>u zDy{{vgdU(0jQ}2RqV25!o@fV3AtOM<%|MB?0z{${C`G#gGTsZ6;{5=b7z9d5JV*tJ zpb#X3MO30mI!MQvpcrI>&5#&ul5(&aEe7dmDcFpcQMnRqCY7KNSA)g478DYCu$X8B z#dtGVinoGdq8;pojGz=ZgFVs;N{LRe7wrb+crVzC_k(g`5bPzf5EjQnc$^3caWW*v zsSp*XL+HGrVw?@pVIhPi#1I{kLPA0g(XnEPN|Zu$q8utFDj_rGy-A#){!mv=nY8%HdwL5^koHun||o-MAJu z5_-6sXoSspGu(@}!e*i!?uCu86*t4Zh!wUHop3MK4R_+ba4*phcM^keFGZ3?k|9Ns zC5v&HWTGXKiI+(-S|ORFLLwg~@u)^(F`X<%8YJ>zl8&}WD%K{834aXfcAvN|9E)98qJHNGqvC zgs2)3qgq6W>5*crf%a=g$V3a3+YvosM5L%0k)u`w`D>&f?MBF0FVc_qBYJEQ=_lD} zIW9+;SSiXR%26^_i83iIYDD#@8Er+o(RQ?l-YGFNs>ZCS5$iqW~6bhOwY zT29e1F~P>ngcvKvH|YS}84N#B@|{#^gjR){V7eokSnDkl#^CMN_7(DR5u|fdx=W2pO907#2|?$sU(?X zl47!$l#}ITCCR4LWFv`IKq)=hNVSq`s-0}64D{YaWh<$rI>}b5i?;R9=l!If8YC+z zJVm9*6q6ED#gv>Xrz)v-N=-FVTFOZ2scx#3GSMeJ^x92zQpi?F3lf-skx0`~n1a!m zVrMV|V=<&=Fw7=mm_xz@n~VvLBBt0%nBpj7hOL4b4h8M2Vz^yHb#zR$H&D5WsrD9T zVr|T{8yIdgG2CHcqOF68jxMI!dYJ0yW2S9@nGW1W*a@3pBW;qMvSAL|rr8;rXk%@b zU9=Gn*(N!PHqBPDX^yhZvQ=!B18G3JY9sBM4QVi&Y;V{^d()=dTQ=8zYdBhV)zP;1>;`&o+G&Sn*Bl*t$HRW>%~ddLL%}el>oHQpFj~hjwt@726Y2jJhAp-+Y|B7-02Ac_EDTF` zFpTS>d_WK71Ns=YGQcn%vtdKHO+dO{ph%m*P^gb+o8V(?!W3&0)&!d{B-(_4WD{m& zn~*Kqgpra>2$gNZT*W4ADF3JH1yZvKv~CmFhD~rbZ9=qV6BgSxVau=yF4HE&Et`<; z*aWU?6Wl$UknG!pm4Qv*vH#Qc3PIQvinJ>XWmiz&Dn7=pOtE%lO|UCNqFo6{c4bDk zE7_u587bM7P}#1`RqV=!@_)KsAvL=~>vn~0*cE5fu0&gQWwC8nwhX)CGVMy-vMcG1 zUE#WR#oeN6yW#BM)9O-$a=_kn{EJF=pE_w*_Geg)kJA|zZL)fr5gaxG`Y*rq^ za>XHRv^0c;%R|_FWeD3;hOjXe>3MAkThNEFd}9b3Zw_Ix))2PT9>NO75H?{BVF_yp zTkZ^DpgV+ldP7*MKZLCghOliMX?djQC&^(ULk(jS^swM(hJ|T%SXdW_g`hMn%*w+; zt~e}=mWG9Jd03dQ3=5meurQ_~9j^@w3;M8-Zww3L&0!(d8Wxt?!$QFr7ADMLAz=** z%bj5XbcY2`Z&*n6hlSO_u&|Adpj-;l@x+KSNscHPYQ(_l5yj7pDAVkSvM!7WNXsih zX+)WoN0eM~L>VoODB<#mGG7@{HkA=&Ohr0g8&MYY5hdRkQO27iN~|@aEVW0Jf-#~@ zm?KKU8c~)zBMRt_D4yPklIo8rtAi0`8ygi|IMVUNs4+>78X0QTaM7cNpBXi#*->L% z7!@YOQ6ngg8ng1Kkt>cGqoq+JTpl&%E2GAyGHQ&eNXKiV#)3X-LcyrW`;drQw<8u`p-%!xLDvpyHj?+4hvyK1L^mw#|#0LOW33=5!a3DWfSEieZW&J1WjfWk2GSs*dr^ihn zGj2|?pw;lhnpdS|2yr#<&`9 zj-&O_xVhLKH@A#&(`AmEackU6cg9VwJ8rsr<7ToyZmtZ*O&)Uz1nxq)EEhgWy6_C; zG6))Jf29AXSr@)8xCF20!h@0vpOsyBuIMtnB^MqpyYTsn3*S^+BB8qQh~~l)CdwMQB)py~m0~fxH^nU=K5WU2NI7v>3 z8EV1^&`A3u{Xfl4i0i_H5ELiGpfn-Q$`fL)IAH`!6JoeLANhtI$v?Cn~GZ`Rks?^ z-0FhvR`U%v%B3Og-*T%57&3epr!6PI@j~SFa=B(^7b48DlD0$3q*<;REJm#k25#y@I zjA$NnLHC&XhR2LIk@jzS%%!%+EEpa!VS3Dj`Ru5ZI(h5CMrGW@LiM771mtL=d4eLCjSMVnZQtN+k$V zBM4e22)03}RFfd0ErM8V6U3H5;FBgn#4UnIcL;*(66$1+Ad-E8SQ!umk9n~fP*usMO$8JvF(+%3@<)wdZoDKmC_xr#C5&uY|kqt`(9~f;FWmHhtar? zpb4Kwq09n9`4pP=X+FlMO|d?0P4Hn0qE8D*K5a(!Y1yJrSt$9mP}!%=Reaip;=^gx zr;(aZqjjIgHhe1G^l8zSPg`vJv@OGjFPJ_pZuzuy$ER^!pSsZVY017%TN(H?9`j>q z+)tzlzeSOLi=q5Vn)YjH#&1orerrweW6Pr73P^ryM)q6TqF-4q`K?gdZ_QQw)`sH8 z)2iPhHNQpcev57R)pXNuMO%JrvF*3E3_reX`mMO-x6&QI#dZDaa?fui`+jR>;J0`z zAW(QfqKE)7Nd|}v6)-3|U{Oqfm}UdSx)2a1MU)#r`GHwEK;()6W3m(=!sP%lUkMPK zNHF)01-XI2hMxnj_mEd`};IVjCn zg3_iE6lc_+6w!jxf*zFeji5Qx3`((9P+DpSrGgO@XHAqRu!7QZCn$k#(46fBrBpvC ztqy|HHWm_SJS5RXNSh=>T80W4G##>NCZtWXA#Gg<2@7IKT9888tQ^vE#gMU33TfeT zNSm*Ov`r->(rQSHXd!Ju4{7;E$fTPgE!GNYOYM+WFhb&jiSh(iNL%iNG|&y13%!t* z>W8$|K}g%i!a^DkOKBo(O_E_NLxqhr9k$X;*qUa;*18ZDmc_8NEQPIEIc(*MVPm-z zw!-DGHD3u^n@U(rt6?jmg{=iWY~>qaGu;eZu~yhxYKN_Y5f+zClqayl)^aCofo|Ab z?uD&XKWwcI!qzqtYz$5k3_+3~jB$g3LB7-tkGcrkLi=>h% zky-}j6Xq%;xuK9aqoVyZlB9K#WE-T)G*SMbMUsnclH4*#JY$k%+#<|Ns zv|KqN&s8Gwh7!TEYJ|*c5t-H_GTVr#*(S;qgXE zFCr)V5qV`0k$EhNv3L}vJfk{AMsO2<1I6OvhM65%Ru?|DU6poH*924tIv9ZpY5W|2NBY+g^%*e4$wir`D zDW-vPtTR`MbvBe3&Z#ky(_$T3k9F8aOy!y}oomH9i|trv%ZTB?jCJBxtds7guJOF#H^Z-vsyx4&=YdLkubB(L?_!y$V=^nTrd)1&P4lJ33<7b zkU=+L=6Wbs(oe{%gM_?|B?T5wN-UAoC&{Fqp^^qmCoPsq>eFmeUl)=>UQ9}PDXGuO zNj+Cg8u?Pv%9oS+d?l%GDoK%5lQOF%^#wht=Nn0rZ6-TxE2%HFlX}5Oig`0B=dGl^ z+)3)7n>6!1lw;{9_0>UA-^Nk`ho>YCWr`-rR3}5F4317&9Fyuyv#HLykP?8Hk^su~ z%*v@wu9z}FDP@6jsxx0nbvBih$f+rr(^8!UJ=MuKQYP0-b+}flv(!#?3Pwr|f*xW&)ma^+I@>ss2Q1}vPFuR zDNzPprl`3JMQx~*!e|sl>lDQ{D4c0h3frQn#WqE485ElHDTA>nD&3(du1n#W9%Zn7 zidq>^6pu}!Ie$`_BqoU&a1XwIKhGTLO3)+dW>V-n9cCzX6_vbfluEN&T-XwIKBGS*}<-I*+M z-AO#xn>6zM$>PdjvdCjoXv~{Z7-9-%$f*WHO%V(|rP9n)V~U+>tO-*BBTgBNG}V}q zryAMfl*E*#Ou9VPn5#@RHk2ufQKwW!n`+SdRD*3ykxX++Wm{8?#r9NV%a|%M=9I}; zQ;l?Is=;-q$V_j_WcyQ%mBCbl$EL9iKCNVkX*@$tcNuD$$k5a30y9l!*y-+?FpXkv z+Q>-L-5Ghhn=MXDnbNemP@eA2Ri?We$}~BnPOBMhx=ZWRUA8ezW}DM$zBS!lY)^N$ zjA?S#oHjGobT{3Z?sDB}GS{0n^Zn`W%3!+7<1@+(F+*B02E6o;X z<=JAcG;1uEXN&Wd+2W=;tK_uV;(|U~%r|DmY;#rtt=ZyId$w3GXN{aSTU_qU7D0Db z%=Kms(4Q@?4rYtn*c_Tq=9DZkhiA#TMuwUrvhY3*TbeV|<+;XuWv;QQ%u!i&PR(j_jRk$Kk#Ee&Omj}Wxl(q%u_jaUd?Iq-35KVn{Uj^+2*_oTJznd_I$Ts z%olU!yqUA+yUU&VF6hq7x!$}9`t#k@!F+ccr_u7AR%nu@8JgD6i%PRJy(Z9DTBND8 zL@Q~Trn5yFPnT$mF4JndLem>6tuZ=HvkkOglh)W4O)s`-ddr}Rv`JfxMbqgHO>Z1UI=nm?9`EU{#;t@VS6S+9C`%HnF6kL<$zt`T9@|)w+2)d-Z!LA$_EK-l zSdut%sgtpmdg;zmkLxbUTyLq9?=SUM21`92Pg7|kt)$5`ouSi6H>9-;o2J)=G|~-e zYFSDv%W|5|71Q`~DQ%_8X?3}hrZ?5JmetdAzL735&9ug~(j~T?rVB=zST@sE)=JaM zoiq))X>z%jwzz(pULBR`FFjjdpL ze1*yrD@vYRX=bPuJWsFCd1gh;vn$PYVFj&+(07}q6$QvE&0KK>2c;Dnlvh+xS!r%6 zD@0yh(X-l$me*IB`Nj&FZ?2&A(2AaKuQUtB3IWWOPS#q{Kxd^1x+^5;t#r8lN^^Cv z(%i;Yg*?7m%oD3do?Pu^s8umfua@%6s+nh3d+Wj~nvYkDKw33`yxPkZS4B`-ErIf? z2`a0-O=VTetE+lWTeb4~YA@edmGjM29kfZSd5nGFbvma)J%`*vVBI)4;Y5WGH7hf;8`L=WXTMfr7~0&c}n8~bLEVjtz^m@N=C`5nMMXhYgW&c*+xdqHZzTUE2DDl zOnJ-5C^<9J%~%;N*U6N*Zbr@ZGTnSXqk=)E%wuaPR@W4kSi@OzO=YPyf~D8cT6>LT z*|pZ1uqLqLn!!qIA}g=8vc)xtEv;E>c}-?3Ypo4sjbhcc2CJ>ntiIM_8*8ZjYfZMb zhGKQCwPmaoS#zz+T5Bb?v)1CeYh|{#)?@o?dVa9h;<0t)TkA@mSjY3^x|*lfi9Efo z<(YLd&#vovVI8gY){VThF6QO+ezv$Sy5m&PUrRYKHFH= zv(5EpzO}A%?e+eav0luZ>)pJyUdngY`&@Tj&-K=O`Tn{N2J3yE%pyBy$-Iz7cFrO@ zXOW$=Os<$kcFrO@XUSY8%WSIIMpn-<`DV7kwX!DL&N2lfi)@?iX00r;ZI%JuEV6C3 z%k{HnevoCh$sChob8=qJm2;I`c~i|ba(b?uZ{`}Hl{2|^u3Rv4-CQSE2EAMt^m8T{ zXkt$bsH;hGywuC;;2uZ>p0*eG)5MwhcTN?d271-ct$uD8+S z`Wv16V57B-ZDIi5Q~3o@G@)cI+kcY8tmfbQ~C2z87-eR?U zhh;gm^2#IcVh1eC_t|D1%OhLnagN9n9GNFMDo=5Ap5~Z5!?Agm6Y>}k^Ei<51d#J2 zDCQ|p%A>I>&wxt4!zp=%Q}ZgPl|8raLBvz?R;gcm2YxJUIAua1y&x7UHJ-! zRtEriSALMM@cn!f;9CUxp|;2^2E8g<^p=K7jV*SowIys}1#ycgNLy4v-eL;HEu~P} z(hB9RMgbkYprU#@s@Fun#ui>Mx5$FEMHf0-ZLYhe7J6HHp}*BE47S=lR={|?K=4F? z;>iNTQw0Ux3rOP`bkBdb(Bg#xwk;NjZK*(Q%LQh;SWvc01#P=rXlz#st!<@%^J;f!wwV^meB(;JO8MyI0V+`-SHApfKQB4*4aA zY{?;8a>$k(vL%OX$st>E$d;TAkOy*YuEiT1vKfbL#vz+=Ea-B`W?UcrG{Jylw^^Wr z3g`gjF`x}v+sHEj&MW)?RJI93l2>^Ok>*kRP?_cR|3}q*L&vGL;R0r6m|;&w8U-Yc zB$QD`8O6aFXPj}y8E2evrlh2#q@<*zq@<*zq@<*zyq_(f``^2~jz?jnv*b0Pz4_kv z;ebDYpYMR~h;XL@>A>#D2dJYQFdg;4=x7H{$2hRzSong7#$iOnU2|E;cc#Cb%c%xf8>tTQQ>dDqjW-eEAD8W z6rN$jGaUHib|QE`fR88eh+t+*!km_Z*)08c*2}{jp2s=JR`W2I7ho5>HFpRKaUhlxX-o^N$hw+3DbNc}1_93PhBTOe^nBONb zzfUp0m|;GF<*+=;A(+J@oXVjR4f$*a=IStu$GMzP;$b!~}rYgDDw&t&u|oGlz;+4iPpy*MWIF%;bw+P9S{vT#z$hCT|p@oI%9!c9IKVCLa{D zTtLA8IgjNr9MS+dl_yIy%xjsv2(x(+=kj8Shn%(m(|0j%;!@r$$$7n~KfDQ!qa9R)`3M>o|$i zIEB+C2G@%$F5?_7mv|g23AllaxQ$D=U6OIKq~JzT#baE<X6&b>YuXBnf;lkTqQ6c;yNd!f!6vD@% zqC><*ib#s^Gs1saF(IfDTjEM;i7&zThgqx$nQN)!mgEu%b6NPeEK!73N=rt`E?Fg( za7s4emJG;MtAt;oi2&XYOAHZ}Tq1_gCnbkSOYpr*DIpLd=nA$Zy0Lb~3@R>nVmk%`ogUmcyWDfl*`*W2hX)(K$?Da+t*CFonxu8lS@|LJk`g zbJ(1e!*=8xc1Fozx6~Z=Ld#*_^c+?*a#-8UVGC9c+p}}nIVXqRadX%!FNgi`b66wD zVIyGS9o}aYx{JNdzk2`t(s+;E@dwKq&pXW(t)%k!VH0uTKPo+1l8Llt^My~o7$NekE4ZCpR@;QCb;*B^Vh{?UhHJizt75Z9+8T;Ggw z{bYjc*Hc`7n&J9qtf(VY)G4y4GgMLM=%Ow#MO|Wxy22H8jW6mIp{NgvMSV^x>N|2# zKcf`&TWV2%p%wLSdQq<#MZIkn^#!Y_@7YEDoKw{AxJCVySJZ#_MZFOe^^vfsFGXOj z$3^`@Qq=FIMg2`y)PJFpPm(2{rb<3bmwcWn`665LWv=9_LdowIOa8c2@>k`Oe^e>? zm(`O0P%HWGjgsGEmi$Sp$={4i{>h}|Ur$T^ z)2!rw#t0uF!ly{WXDGtwXu=m5!k1XWS2)7gc*3s;gg+<}{+vYkJ2K&)Q3(H*O874{ z!vCg2PQxJlwn_L47UA#Ngn!N<{5vk;zw!wGhfny8fbd5`!e5FA{~#v(3kl)hO9}r? zM)shr}vBFID+nxyqkas{C!W%D>dA{CB;|*NrMaY*zV2tIF@&RsOtF05D4Kb6$<8);2{meuqxsICu?b$ynq>)Ui)Kh4zjn`~Ww&eip=LR}vc z>-xM@*LUT*epadLx7E7-QmgCVjk-Q;*7ZfJuJ7A*{k&7x@49vUwO7}F`gOe-)b-J@ zt}jP*y%X2X$dl!kvrZTOG0hX286_`PPspRyYMhTZT_I1T@r+wh-w4gXWn@cYAtKNB_lt+?Tz zN*ex+wBbL?8vYm5^aseMKT9?JZMx~7W}5y@w&_3Tn*LV-IuBygpO>2cuH5v`Doy{k z+Vo#)P5-+AISI4rFIr81-){Qnou+@+ZThdhrvEc&`lDgfUyho7CvN%|lcs+^ZTfGs zrvIBHAqPbw$Uz{UArV}DL2z*osRDEzL=uflBwCe8bW|bHWtBt^H4?oyNYrDJXwo9l zx=o_v4vDV1Bzo+T=wm>lzK}%I5s5Zq5}iy)bUh`}(~Lx)Q5Q^JyAVTlA&%}s0@H;g zwhJj-7t#diK8RgtPU=ECau+(IbfH^n7kZ&}p>IYPYMWhX!RkVLb{9J5bfG(L7kcG& zp&vmP8VS45Qq+YG;x2R{=|cC?F7zhrLchpv0WuB(WE=#Z=@vw`TadYKK^41&aj9Ea zmAi$bO1E%X?G_$t-NJjLTj(*ng-NShShu@{<4(75)$JA@d)>mvpj+q*yM^hfTiA@d zg_B9Qa6Ro7o@U*`XVem);~+3pOW^31ATTXKVq1d3wFFIoPJ`GI=A@ReBe#SzN=vw< zwuBd2OZaBAgtpld7Oa-AXSalNPD{AswuDz+OZXAAgpsf%EJZEhAZ`g4l9q5UZ3%C( zmhg-0F=(pCVCf!%XL<~g?J;Do$56!{V_fPnR^=Y!sM2FxR(p(xT95JG>@g;-9%J3^ zF^)Su##Oh+cy~Y`(*SMwj8ZWe7yVp49^cr{E zUgMS5Yy1d$jghd|Sc>2tIdQLXA?Y>lrMvja8&6FE~|aPL#;1(Z}tU~R$s7g_XWqDzTm3c7d-a*f{$TeFdg*;n{i)o zGU*Ghr+vZGtS|VC`U8sW4;ZRH;OPE9VEO}z?GF^LKhT8!U{LH2=A`~$NA3^KDE+}L zwLf^F^#|XK{s4Lj!GhHv?AiUnIj29kxJ1{lQYy9~{K}!G)whxR>?^ zZ?gX27fGQp3bFt+g^n;3y2MiG0Y{;CB84U-3a!Z$I;K$Qib|nJ8ihWX6q>Rqv|&@| zghQcgE`^?W6#5iWXeOf2R!pH&359N?6nd6X=nFZ3W~l+RO%I^c%mBK{4xs1U0QxFG zCqW!Q^U?s?l?TvSWdPk)2hdAx0DU*0!(a}eMQZ@<+XLvlGl1^81L(CkfPMx8Xfzx^ z%h3Sp!~^JJGJx)<1L$owfPRyM!WcCutk8qP5oS=h#10A%xIy8aI4Dd=gTk6TC>&D; zg)8cy@JJgJKA3~Tlr<=9*n`3eXHdB24hm1aLE%$4D9l8I!d5&eoJt0T8|k3%EE^QQ zkVC>OH6(1)L&9lhNVv%k3D3D9;j1_#%u7SUt~?~1RfdGy>X7hK8xp=7&~Y$_ghgve z*tds-^UjcP*BugGdqcv{U`QAZhlJ&5Na(~v!o_4rxStLQZ?hrcH`z8|=5N5v-#Egw zjZ19Xc)+!dcVgR^klMzY+%}FWZR3jCHXdnhkb>Qyy5!^UznY;@vb<6<&w+)sy% zx7o1qn;Z#XZXdwhJ~+aR1ee&6-~l%hyc0))327u)lShJM%1CfU9SI(3Bf$rAB$%>B zf(?5lIN^*0*W8idi8m5_3P*yOXe8K*M}kwyNN^(^37%ym!54Bgn59O8ZF)2~&5Q;& z+0o!RHyV5uM}v83G}x6#gR{zLa9bS>UTUMkcXKpYv_^w{do(!jj0Shz(crZ=8vG1L zgXL&6=)|MJ#bh+NpNkIhs^OnjDvCausIoM-`g9tkUE| zjV9llFoU;fa^0rM;|@(;b!qakN0T2znw*Ykax=>zVW27dIk#o`*xg(E}XOuDWmO4hh(8kDb<`}tPjgfoy7jLI!3<9#>ijPxCpazk!Qw5ksTLhZd_EQadA~17mq6A;$?MQ ze5j3!@6B;>(i#`n?Q!wAGcI0r$Hm9qxcD&~7pJ3faWftlPbTBy^>kc(nvIK}$qA96 zCPa>&5CvvJl-LPT;U+{)oDk=v32{fB5YH$R;w^PTe4$N<-^>Yd!I}{F>vo+lTC=fs7aHhCrzH2G(~pOl(|V$l_t$qdD1+p zOq!R~N%NsLX}-56&2@XyJnl@ISKUeTu{UXc3@6R$Xwuw_C(V<|q1Qxm7mIcdt=k*CZv%9MFaoibl&Q|32w%3QFf%sqR`Jm*ZA zcibuSl{aPn2&c@YXv#c@r_2kjLXnoWnF$(fL$ zWupglg)&`D28028S)6jke677e84f}JBcCJWQIJZ zFys}LAs=ZB`N3ky4VxiPI1G8sWymKULw<@Faw}%YQwc-fNEz~3#*kmAS#q16B~LT6 zB^Rw(a^IdM&pWf^U3Zpz?ah)u z!&!1Unk75&EO{}RCGV%RNJm!n0q6EB( zx@f-57R}$(QV28K@CdUMUSgNR2i#KlPFf1rNdQux7I3ODSf@PxAz zUUQeiC*D%{DOw7*;-&CZvJ~D(m%?Y+Quu{}IV!yzo@SQAo9uGJ4PqmlB^UiX3*If=@d&}X^XgTb}%i+ajIlP}Phi|jx@Hfp;Ji}5V z%ThAOQmVvKt1?R+Raok>%2E$CmU?f&jMZkT;|@z*by@1M$5J07mfDP2>SV%F*He~y znz7Vpn4xm?3MDWrl*F!33b#UO(h9XBuTW={73!9{LcP#dsBhK^wP&wT=bRPlj=Ms= z@>ZxH5qRwJ3Uwh_q3)$C)SGOD`bDowJhLi^?5ZSltCA|ON=KDd>9V>iJ=9jE_tvVk zZm&wmomJ_oyDB~QR;7>8s3X^YDUITa&(7Yto**CY^KEq&x1K^vYY4ene~1LA)kiNY6-K=Ta$j# z>lV+fTOzw|$=tf7%InrqW!<{0u3Hbab?d#oZXI{lt*h?3_1IgtK1S=-X1s2lOxCUI z>ALkaTem(_8x}`zSOT+QN$iHDa2u8;ZCE?JhK^z>}Di$n~^GSMn{#+=(4&QJ=8X% z_x5IV+}Vt-x|`8sZ!`KBZ$>AR&FFf%89mK5qtDb<#L-)kz-&blyA>(iR-{Q=(T=YRie7nJ(T`{=I*7NT3&~b=FWrjXWLwcMnxl>| z9CeB1s0SQJy^}fWn8Hz4RE~P2!40x)jymCR)HRo*o_HMfDdwnC2}j*XIqF%)QD5k7 z>NK-W-DJ0^=iD~+73PDx@-}r=*`{u*+tf>KoBD3S%+TJZ&O6)GU3Z&$?QK&(qiw1a zZ&MeOZR&oyO})*wso(UDbcETFF0nh(18zrpC+|qdlpX1cx+6W(cBBvXj&#D=k*>Kr z(i3k-`V{X-r;;7%M!F+C%iyMx^saQ8*_CdxyV7%RSNbaNN@tZ_>9)Enz0`K4@7Aug zZ|_Ryon7g!yDPo+cBP-uuGEQlrHjd~bU)pd-e$YfZ+g!*gfk3w`aYR_pD>e zo^?gtvmR-C)(3mfI^pbD*W5kpiMMBciubHj$)0s1-Lsx$d)60v-#X3gTQ}K#>p8b? zeU|1x;ee1QiZ~ct+txmjeT}<|^`{};*Hruy;(+ANJ z<{-Mn9z+kggXo=n5FJwvqATh_^hi61KG+A*3FjcX<{m^(yo2add=Q;V4x$_BLG&y; zh`!LB=rq%bZnB-|IoFB4%AM$}(ur=Xo#>_3iN4#N=)BX3?z)}mwbzM$#+~S5(uwY; zo#<`WiGDLYEwVfB}llKh${oz0K3d9iG1G^7Lbmr$5F#eKO(c>nTq^ z&3O7VeS{X6BecXGp%v~3t;t8|Gs+SAmU@JKp&g;W*+=Me&Jp^KdxU=F9ie~3N9YU5 z5&B+wgnpA9p?@()WsyB9%iK{}RgTJ+)uZx5?Wp|TJ}Mt~j>=cvqw-_#sQfWLDxXY_ z%GcAQ^3&|7{Fy!`3(PTDVvorRcTCpgWAYj0n0!k;Ccn^*$=~c_@;T?2e8)W|zw(aB zKjLHZh2)rgFFhu|$&SgtnB%s{9=B!gxUDM3?aS(M`=NH+e(xN&ue!(W$KG-KV|?5` znH;yTr^oH5*>U?beZm%)6Sl;juodovt;r|sGs+43mU_Z|p`Eb5*(dCC&I$XDd%}L@ zov?qzC+rK!3Hx4p!hVyTuzxWpW05@>%iPIWRZhm2)syiGdPsWeElkvyo zWPCk689&WV#-Hg^vA~>)CH7RTaHnETJ{6x)PQ|y>Q}GM!RQ%086`ylX#dq9O@hk6C z{3AXUUr0{H_tI1Go9tBlixKEctUy2D1p1vK&{tG}exwQX2S=cUzpSMP4+bXoI6c_l~2=WmDBWX^)&rbJ57JLPt)g})AU{UH2vB;P5+Ef(-)J| z^!@ZS{Wd#I|7Om}m)JA%1MZCcPB|lAQP0Sav@`Mt=Zt*KJtIHy&d8sVGxCk}jQlJ+ zBY$De$~W1w@^kL2{8c$C-&W7cFSWDscl)e--Z?AZb+)Go%~os02Z_hS6oyBPmWF2?uMi}Bm+V*HyG8JQCqRS}uXs>nRlMCQFCGFM%Z zdF+YI$3$eVry}z-6PeGK? zdF)+vJ|*-bJX?E55%v^IM_L`$`*Bni`=G;=RIWM$p&Nt_pbH}~ryz;I&Kay+C zz4V&%CcEbRVy`DMcRf+n>&Zjydh*`Ao;>!hCm+-6$##60mN=2I#$ z&oYVm!ro+_b2pi<%1!3BdXssn-DJKyH<`QcP3Ed%$Yy1NMdXfc@q^U|)F;*dOTw_D%MH{lz_0Rqdhr-hHS(_8zJq(}(KQ?4kOZ zeWWVfBUMu$sV}rg>Noe1`pSEx{zxCGZ?Z?~FYd9cYLDIb-edP;`q+J%J$65{Ph5q2 z;%e#>_l5Sv{pLP#UwKd5AL$eKP4>k7#XU_`?P>bndzyaCo~EDKXQ{$HOEvXb`a*k_ zesiCtue@jJkMvpkCVQ6t;uQ9srm!D8h5eK%>=*7i`&E6;zSN$x-`(fzYwtPxGkwm! z&7QNrxfkj??S=Zmd!c^HUZ`KVm+DvTrTX1{slN7Jsz1}0>f7w4`kQ;@zSCa0AG}xY zr|gycg?sIO)n2>bz1Qx~^tJmod+q+_-lXreH|YoOP5LQ&lYZgereC$U>38pK`ZIf* z{?=6Py{B>?GnMxK+eX5oQ(xJ8ynM+gXt9) z(`z24Hv-7qgpj$3AafIAK7tHQ1u`@>$j~$pWMs%3R-|$mLFceClf$ZP4y$uHtSNw1 zA?Em^l;a6G$Cs5HUsZE_UCZ%J1F|$`PKVr#4!Ieyvq0%T+aq~wK)nipzXUTBz* ziLvrV39>QB$r}|gENWifXoUFykMcn&&Ic&T2bDA*)UtfgAPcBSL2iXEpfXcHRkncY zTmd!3f>4wS0wEWKvQiMLYC))L1)*sc49LD1f3h!Sr(jgwf>HMhMl&n~ka-Cp^AeOn zwWy|rpq>?iCIwj*8YdBhlNA;xYaC8CBwU1yi-;6ltf;tH({Qn2;bzIkP2}Ka#l_8< zhntNE4@)r~q67~sDIV4`JZw;qKcS0cnJJQ0wn)~wBH5IRA|V&WvQiYQYEi6fMX_l? zKE*DYWyr2n-J)6die@t^hLBeY%Skb;rp2(H6~iW7qQDcNDr||WaV4rDmn5W=q>5US zYFbHZ*d+@&C9C3=teRJ{8gVH?NhzwNrKpybq6SS+Wrm=tEJ4*df@(rCrK}KARVAdl zMo3MYu*wc$Rb9fWdxX`DiKv_qQ8gu^dPYP|2GJE3(KQay4F$;+70ERX$qfhD6&Kkx z57~_b#g!DrwG71#rc77aGF|7&bWTFZ1t4*)&HnV!#L>T}7 zODBMJD*n$j1^Yw?`$Ye1ni@I1%Y@?|j{gBT{)X)Ya{5pV z=ZGYy_or}f$a4B9%JYA6Hi*je6b;!K2C_43o`>@Q-xdyYHWew)56Y06Q6M*?=J|$} z=SPe~!?bLHRchz?qH}1N);+LF{XAa?z%~v4XP6QR*rw?}!xSAlCx|Ne6kYIf23!*s zd=d_P5&_H;5$qBP>=OBZ#z{j1tHd~TOUoAcq;|po&n<;>gg+dBWg7m^EQM^G-=F?7 zOA$^(riMloPE!m{gH=kyxq@yBI1PCk8k|xZoKhNcade-G)8LfSBL+@)nK)gxaC*ST z>7s+vy)I7IJ)9m6aJm)ZbTz{1p%`*=2~PK?INi)}dK49Hut{x16>W+s+TfDfHLhs4 zg`(Xp7VU~uvlSS|r$C#rXt%u5igOc0|OL8?T$zYAjkcpG~(~{iGO7bWoVv;0cL=iE? z5OEJn#5InH+X4}Hi$q+Jh3{eG4QT3l6Y9O-9L}b}Qz*wQAH%FiU>}K*uz#tIRA-l zp(1um6>(6hh+u<=4Xq-M7+`){V0=1%-A}RZf$tfB1seV{KNE03)Bo#zh9p%DDW)3s zu+^}}Rl~MW4ZEdkIH*)Z@IJzZRt-lCFg`7?Je|L`X9(xga5w<(GXmQ)0p~OQ=X#pVm-EjE34}HPiv8q4s(W zbvS6Kt*D_6B@MMdZK&X7s-vixl2kLLm}c6;HPg1xOuMCKI;b?$KCPLK7|pcHYNi8D zGwt=7DcBcjD{7`gNi*%wn&~J-B8q{$21lZ{0GSSnM1u-sG&B;87$oYlNHpM(sMjOW za6qC~M53XDMEx0wMk(+qnJ%M;>oVFxm(eYOOR01jeOi|>Vs#kg0=+yqtXicv{o=;wSobs74&+oU^r?8LrE*>&sxDK1%@LBE~5m7qXMp@ z26m&>!wfh*Ot06&fX&DZB|S`k*29cay$;3oI&BHOMWxs2)4*J`dYu8U7n;+(&QQ|p z^k==!DAlJ>T%XdG`jkPfPZ_cLlmV|#`D-2~;2>sT9a8-Xn1)GP`fC>^BUXPh;Poee zUBV13LJqqB(qDU!8nGy9z@w<)h@yrviW=nxthO{@4Qd0{hzA~E^w<5fM!7+$tqn>e z-k>xb4NBnnNuwNe*fr>_dtmfsL(!<#=0?0WH=MP(ziwVO>>avwhwJqm1;1-)$mKGy z4nJHk=mp_$z5dUj^Z(1f!$ZPokd^iSdIOneim*tbc-Wz1Z3y13=8lzyU+4x4v#*pQdQc750f1vzXc%whde4%>=hAC%;<@^h(HVynW16(%~d^ZbhH~Y|Pn{&Zy^A4>x$O!Ax zA^2_)*lzKm)wYy^*Or0Rh6?%^2?je=&{rVm4|^MZmIZU2E9l!icPifb)|g&i6<-zb@lEnCtw4it}v^=l2Yp zA2)Hn+rs%(8|Nzy&d<3xKj`87j*s(@4d$mqobQWp9cLzivd1)I$~ zblD*1&(DNlxkcc(#fL82atbzE1}+;a`7~MbN$M~U40|Y_VM{*6m3&TsysudDdnCyG z$|b+1l>7y?DW% z=QH4zLp>Cj&TOWj{o!Bo@0Q!~J6Gr?=K zz-qG(?X`Iq{522kwE&E^5UjQcoVNJTU0Y7UUdzB;Lx`qHM3WSvS=gg7ut%d{kH!gz zo)i(?BOw~BH5&YMdO<~WTSN4of#`7)(cKoJS8dqWIf$Nf5k2T3dM7~ibcpD_2+^A{ z?DY~vFQtec$q;>j%Jdjnrn{&zy#o8YS=ir!nNDvDWqL|1)4fue-jHF>rN$LGCky#>D{1A&xB>VKPuB(G3*nQGQFIZ>CvoAcTmNq z$%+l@Bb#L^Hp5nIimTY1P_ZY)irphsY%tX9no_YB)Qa8KD)ydHvB%Ad-ECFuRi|Rl zxfOfRtJph1#hwl;c3)JnH{*&8ZkoN6R_u|iVjrNYJw{e-Fw*T6rfSc!RU3SCdt0d5 zQ)1Qbm8$lJT(!YRw-?o_J*-vjeWPkmm{q%FRqZvWYR|h>d&sNWyFt~S39EL0RJFI_ zs@+Vg_HtUaN3*KkK{c5sYci~*WR|JP3|o^at|oIrO`a5Ma*tG#*Oi*Qpw{HJR+IOP znmlgSs}Zj{jd;#&#DiWV-U%AdT{r5P`(&3IUA#`{Jyo-mtn%WB4JPBWf& zn=yFh@ovzJXToOOA2s8xq!}-#&3H6x#vSy}Cu2yGVM&tWNRku4Boo0VlfWfYNOD0X z$+kw4dj{BLCKzTG_+<`B&bcHx=#k`30A^VTc3A{&SwfOaDM^lGBzb_k$T6ymTw%J% zS+MIOmN1nE^^K3BIn&Ma>(lZfe|KvB_@I?CV?lWfD5LA52k?)W`H?n zfjQ=Y9p-`|=7Ap;fHM|?Hx_|4mVgJllZY3>qIc=GvS?}9HZVLnKlr+GCgT*eY1MILi!0sCZ?1VMIt~mqjygR^xug&fT1MEyR zz-}c2>~cE5j%EXF2MxM3=v*u_=rY`(%L#)nxK{4EGUzU-gD$MQ-92N_9k&MERcFuz z!^+(W2Hojs(A`W1-KBKU9mxjW12p80QA6$uGvv;4L+-XPblZa z7qqszXSCIEtF5j&ZFSCTt2;qkosQb-X3|!d(zZI1wbcVOtb!e-t}w&uEH|uf3&Sc{ zQ7Sl5>Y_HR?i<7Egf*Q*wWE~j8+q0xdyqdkL0;}(rp9U6hJgmwZNO-D4^OlY)}(dd90Lo3V}n&rmOwgC2# z1m2M{h8DFkv~P@|32O|kIb&$v8-rf=7@CR3&{i^rma{R`p};ZvV;^zg7YXBFoQ@mo z%DAzhjT?K`xUmYZ5tv5CPB3mjR@2x_#tkrxi~|b%p+9C32kwwC0XF7@v7tOWCAwKurl?1_`s=l&~#<_oGY+i`ta1Z%qkn&XfQqkN_r-FcVD) zTgjBLoJ|QGYC2$<>44#;15N_3N0|;5wCP~anhsW->0r*A4tApHU^AHxma^&KfSL(b zn3-Ufn+dih@O2b0c{Ff!teIfVnF+w&33j8IU@Mskmb00lLop1?F$^bxrK5n2qk)ZM zfwSZMb8{jvb&`KZ4mHcHaI?&|G|Ox#v&^D4%j{dT%$hUH%zLxYv7cqOl38Xsn`Jr_ z7&aU@G!j@f3Yaq*m@^hQHXc|s5qLGpKX-3{r0sCTw+P7AyHE)I5 zjaI0wY=!D@V0%cb*1EQ8?Rl%#PPA%mW~9|$Z!_A-HlqV>E85n;gz&ba z-E1rBXy7||U_NAEJ80Y7zPHWoX4_mx0}mks13}yM_Oo5DlkI7LtpEgjY!dd-6ox_X z9?LOs?Vp8f5FA|NKkNbPxCqxGq`$p;9p)8!QH3tO20eNMW{4(So3LPxXv2KNfxf*9 zy?YNj_W{faLzovvhqFSMVfe)qu2*Exw?{dceC6mom7_~cjxMq}y1?aVLde;;n6u$p zgbf{g8{B)lsOIc~ma_>XC*x*LhHDaX$;rt@HzyaooD6$xn1tnGxHb`&l3ZL&b8#Wd z#eX{Wf4lSybmCd)#&gh%7xE@9=FPkW9eM@2@G5lTHR!_|c@buVV#$HNJap#a`h`dY z(5;W4TMs??VhUaP40`gYz(PNsg>F1s{bor(J_?x&`+Ub8s*NaDj;Mpp@VN zbkzfbg049SJ#(q(z_oX$s6oHng08v;z4NG;lrrd-!;B94j&A@bth3hXIbhHJ`gzGOMT!C?+)16`#7X0mS!|Q>E*8>f&2N_-uB)lF( zcs;Q2dQf?|J|ke5AYvFJVVELg7^PsCq{6it4Z}1YUP}gawN1EYV?kHjhU+%YVQ+ig zJM3-O0t`DB9yt=G;Wj2Scayjfh zf7shTBOdm)U&zqmRt|gHJKAAyyJY0BlV%Q^wsP20JBRf-IqbTd!#2Gf_Srw|ZC?lv zd)sef=x`^8z3qeSZ*LnrLgukCDvv#&;XZjx9=pWmu@x?lz2gt>jdxniW3y5odoII$ z@{~MwQ_W-BS|0nV=dq%Z$4;1eY|6@GPi(lao|DI}xp{2E%VVE>xR+j#$Igd&Y%$7X zuVc8cUXsV|rg>~X%VR%L0Xs$(unDSwJ)#R(iz#4N*aEi36|fI{0jmlH?5tS8=A{Dm zQZ8UaN&&mA7O-8dfPL2s7`*PVQ)U61u?pBTyMXmO1?+}fz_z>s_Qfw?&7go?3=7zD zRKVWG1#C1aVE5Ak*2xOkZ-nbSiR(0l>oSe&a8Eq_Pj8#$a9!nb9qx&z3nH#F60R#U zu2TxGODe8&8m?;w^tDY~|I^)mY~y;5bJ*Qp_YS+;wE)-8g}A;D;rgo>*V_rM-$`+O zFT?d8sHh($i~2ZK)F0ACy_+fOm)WAe$`$qZ{9$kVjCk1Fej!7LTRH4)?`Vg;ZLk>h zlV(w$wu<^wyQud$Mg6*4)Hl7N{@Fk5ZC?lvd)sef=x`^8z3qeSZ*N;aLLS=r4`^`o znUa2q1xKGN>F;>3@r9CpS_B(kD(TN`rME9sy7LpT3?c(B~yWe<>6CkV5FURYKp@2>rW3=%-9VpRox2nN8^Z4x!(034O~W^e;Z4 zHv>Yy7!vw&MCfm0LLW^C{eDX5os7_bBgFG0;%N%;GL3k!@_CU(Jj)?o6%a3oh-W0k zD>C9K1@V%KcuqsSW+48!iTFti@sDl9_c(~Z>LPyKL*Nl0z7`<{)JrT2bD5^ zOD*#|TABZ5l=+ipnV+`G{8PKk_c>+$x?AQqy)ysVFY}F{%wGu0{8Cir-^68pBq{Uv z(lURLmHA%?y4qxg|I^!kKv#IU?;U@Mt?(<{VQ>4iSm9@-3jbWL@L=NeH`NNityTE1 z26VN}3je3K{lu>Dz0P58d&7g?wqN1vL4`jbR`|uJ!oQ9y{BTm?@1_-gKdbORQI$VN zR{064%0Hs3e2b~_SJ*1Q##Q+b0`#@T!|wJ=8G78xVRw61gYLFbByZs`-!Yn&0Ep{Ht!wU-xSM$Drn)3v2#D zRP$fOHNTzI{5xsQ-^*(L4^;P$l68Nas{0S=x)1le^Dnb?f0e8I?}fU5My&gDQr&+c z*L|3=`M1=%zoXUtZ${leY1aK|tL{Iw>wce8_piHkf77e`pZ&Vu2gZw}2y=in)_5S~xIcez-I;L|v(59s=>734UyE~`z?z}ti&b#xTH{ukL zgAq|9BIY1^;v5w*Dk36k4x+}16BRWoVpPPah!Iil7wY-_@4f$fAKWMRQGKr^Yw?7& ziYDLh`}KW&KFSKcTnW5w<%m(P3^2)+z}r@4TI5RLZ7b_-a%HkzuAFv&y?0KzvezY7 z7P#d~8tkqslW$bUC^jmGlwgmYYNN76y-}I2*{EEAHY#hi8$wZ&bz`HY&%A84de{gi1MKjl2+r>xQXDHCBo}tF8<4Q|97+N}YlnmHr zS}ylj#)3_V!zzDetJ+_gq48HPLjKA+t-o?J?5~_c{FPy-zp@AOSLWmXN=oOitk(N0 z6Ab>!aihO7*yOM5H2W)aEdI(>tG}|z=C9mh_gBt2{FPBof8~J7Us>$-S8}odV~IS# z2>K=?q6#nqZ`-KW1Q;hk64>01o0AqzdzzFow3&yU@UM47-?Ccu}mIlj8Oy{hg5;a7ImO8 zT@z?rfC7!R+CU@lwvCfWpb@Z8Bk;D3d3c}^c-zJ*eV{Sk5NI4T1{#A*fyNGVpfTGL zXk4)d8XIkaM&NB5XB~mYNN1oCc-zJzcc77#1sO}_LB?oBka18IWNcOk8PhaD#(5~n zSfdRxCc;6+2_(oEf(9A8upnbD9%LkRLB>jbka3eC$T(^WGPaw8j9Hc-<%_^G6hm1S0JFvLJ*Y#(W(`QTBATPNP$3F1)_o#2#P8Y7*ik`T!G*^ z1yZ3`AaMo-GGbC7ZDs|MX;C0cRs~XTQy^dlJTmP7d+D4Cq}QcD3fu~WmW3c?@(?5j z?3Ei*g&-~J5F}j_f-FEGNUb&mNrFR=Nd)YULqm{mECk8JLl9CIf>h~4ka$A~GG+=v zI?N$Rwj~5vv4$Xxwh$!M9)ip|LXb#j2-5EgL5kcV2rCOkO68#laJP{`RVdP|4n@*5 zp~yTGiqvRBkwiEYnLtC4E-Vzu#X}K77m8HsLlNL^BcrBJq}?2fWLZLyWoszXU<*Z3 z?4ihvBNT~nh9Z5gP^8cuiZHS;q+A|`#DYzs!>TZ(RUL+8Xu^<1C=997h9SV;MyAj( z1i0HsJ|2bucN?kJham}uFl5{mhIE?4kQ_@GvT6-OnrvYR@V1dTM;H?23`2mojTF1X z5Kb2ED3OOdKyT(iRN)S-I^3bwggY=O+yQCB9V$57fui9K7z=l3@NfsN3wKoL!yR#k zaL0%#+|gzZcVt?^9ZS}5N4+iFk!%llOgqCJy{>Rafjitm%OV_Q@(4$aBEm7Gig2{3 zBOK|P2*&~x;i%O{IFjH9$0Qoz=*A)(d3c0_)I~U|^bwADLxf|@6yfMFM>w)A5snpW zgrm_G;YhVdIA$FY4zQ=r(eH|I6uBcDtSr(|DvxvkciS8R00 zIuhYX#{?Sb=)xi$xp<_5&_y~b^^p$XZaYRzk&bqAq$A4`=~%W#IvQ+|4lrBYG2@JM z^tmD(h3-fPBa3pB%cC5ziYUjhD$3ESj&fvZq8y7*l%q}?pt}-1-`az&E1}Lu6f%dqV&z-xvGO@*tbD)~D=&7($~jq_ zzC;nHM^tOxwps(cZ75C;Y2)-NI8KkEae5ew(`)cJJ+1@ZwgEWXrZsmv(*oRWYn;B` z7N<|P$LXh?ar$0YoW8&vr>A9`^ks@o`XSXOeT#aNK3%g(zW@PWTf63NPoityb{-DA zZQUk)m41^x-mpnOX4<6hFmKXlTQ=!etiac{t-0H?&NXkl$PK)0S-ief5w9Oq#p|2Z z@%l7PynY^v*Vky{^@(u2egcixcVY4RTs&S+=;HO2hIsv`DPG@hj@M^d;`PhcczuH{ zUJquC>t~$t`aV~@zR(@7XJiTbaz%oESe2k}RVU~(Gzt1eC_!JRP0(+K6ZBJPg1!e! z(C6a`dP)+S{PGlHMmNP>r~nbgGxJMQfb@FDs84krCqYBwDmTX z7R(9PPCHfFUYAN+;8tmAS)#T~k*FO~C2CvLiQ05cqILmF)YfVfwMlTIb`nk0c4LX! zJUmfL>Jqh8hD7a{DN);DPSj>w616MVL~WxjQJZQ{)Xq8+wf(L{ZIL@s%gTVWtpL8Z zYR%hD(*SQ9O48QAN!kfCN!x`bX>;);EujO>wgLFsrZsOn%L2S@Ym&CXmZVLwCuwJ# zN!mVFlD5#Dq-A8AwdIP<+F{jZZL4~-Hbb*ny9fbq8wSocy5?@@pK_}aELcYDsc=4}_dfwwJ7wv{N7ZHOw_rd21~Kp$(vpkx~aC)-do z*#=|DHVvL^!*$8F3PZAO#FT7nGlLo2mSo$KHQ82gPqs}vlWn~&Fo)ZnY@=l~g;A^YayzMj%@V22;TMe9Qn?O@-U0A9u7f-bj zI^b*@fUj*@^R}}rz}vQ_+8XSswi#!ttwsF%ITc>%8EyuFOwrT~=wjKD|&NXkl*bTgGnOa=} za2f#cYOO}C#vrvCg4JpiRjXl4t=8abHLg>uD-3G&h)Jym-nKf^qE;_i)#`e?T0QMl zt9xBwCbnCxre$gBGDVttNR_5;QKzZXHEHSvC{0}pr>Q5=G&S(H)p>ZDn$)GKs|;!C zF;kkl!QY6zdQg?FZq}r$=b?0U4V$xtss8R|MXLp_CNsC%#sbv~YT&&2Qi?OmitW=SQ4XX06W=$S8 z59MJsa2_^+=3!lU9!BW$uu4N7HfqYl+AVq5vNaEDu;*bj&OEHom4_9&^Dsu1kCiL( zv0+s{)~d(0r^1&&McTK2~kW$Hqi;)$($`!?~VO6oKRa5L*go<5taItF&Eq3+b z#V$%$?5Z{tyT(n$u1-s_Yt>rpYO)u*=A6Z@0e7*BQ>vKCFLYym2j z)xxE+NwiefjhD(uU8$_fP%0ZUmC8CSrLq-ksjSgnDw}nd%KF`vNaM7)7~kSXC}- z)s)K?p>kOrTrQhJ%Vj-yxs1}4%c>3KvT;+ntkY61TeX(Un(XDWIcK?Sz+Eom6csu| zRiV>rDs&iBp@ZNG9g0@yV7x+y8!B`orV3q~r2@=JtI*ZkD|FM&3SF%}O5KXJQrBp&)Xh38b^Y#29jmC) z4XUbi&6+CRJXEEtfva>AXqB!DuhJ2QD&455O4n|w(k)x7bPe_@-HfwJ*XOR%F^X#4 zu&P?us;Sm3Le;uDxLP-bR_l83Y8_>$){UF0b)A-K-Kw=(*JQ8O%{i-e1MX@ar+^?t z1wmR31Ys})p(q5wI0WGa2pTa#P@4sUmaGs|Z-=01Cj|AnA&6GgKtrk;s6|r)EkHF; zEnEXlqBT%AUIUSa8feT^19ezxpcQKk)M&4PW}P)qzqOwJQBy6{ZmETqt+h~ty%w5r)a-St*l(O?}?HCS6T4b}y?!8(aHSiA8CD`{x3j+q*)9hL^`inYPo zXm7C2IvcG0?glHXXtWNh8m-NmM(aG>Xq`YCtzCGdl`u3~M@@~^c1xpm+1_ZKaW-1} z+>KU7(PSM~HCbCVP1Z%Y$vTBLS$ps%D`jZ1j+>gSot7r+s=diN=WMbLxSOn;;%{#o z)~ZlctAcT@3O4{}+XUQg3-Gq>TGg~utLk-YRkWg6HKb}*wP>1E3ovlDQQ&Ulz}q%7 ztHw;tst!xDYQ+wmZ6|QI-N4&cw5SF(Evk9AMKyu8sJieL6=7&mjhb3i?UokRvb{w$ z<7`p&xm#3>qE$7lX;m%4t*R-sRn>#HswhLNYTVSS>a?_~R_(2-IcKYCz}>3i6n}f$ zaGME5+e|RtX2K1ByW93Q)3meA)a!0D(TaA{kfzaet% zR_wspb^>?X4ZLkdhiOpLVVZ|KOcQ8_sSEEg5rz)asHMZSZ0|75I6F*z?hX^9=rj#$ zI!%jkr)di9H1*(}Cd$xh8n<+sR_&dpIcKM7z};!$6flZtU=)L46vbf_H^AtK1xAhc!LuBK)_zZRkPAEj{R}9XQ)p-EBAUwiUfjMAPfU z;9e(+_d0PyuXDuG>s+$;I;Y*ePFm6D9MbeT7vMhUB;MyF4SmirOP_Pa-shZk_Bs3A zeNI;Kx3>-VJ16jdCt>*8+qU;RXWacxMls+V)(kio;lI6Y!+>+#GT>ab|Btt=z+gmy z;)nt_APV4ZE0*ktV%m);XvLsnNHeHdfCm-8+g6ZutMP8DQ*kz|j@Jbx?wL87km3 zsKMI|4G(Pm1@AK;;Am>W8x0t^nFx5NfdVHJ18+5O;9}~4udQEmx4n$u&4y{s-IiE@ zyL}Y6r&iup4;y&DVdri2c7Qh=PTtlHF7S@S&D-iLc zuxlOy&bD^V-}Xj;%Z;x2+fw|RzkO7u=N}ar_(#2r{G$RB|EQ;#e^g@O1Fi#{ZQGi^ z?d2#h{ffziVzFoN9%MsJ6}D0B*p8(adT)GaXj z%7lnaE=0h)4Fv3@M?BR+M4}NQK9CUc&uTJQY>4gsPhQr}y z5;{E1LWjg6bbz_%4iB5q0bFi}w^Qf<9=Aj47CL-oz~NQ^e_OTYaZ5D7!}uN!TS%b4+LCp7>sfC$|P#wTdKWO61AsBqV|C#Y7bbV_C_V@4H(!bfJ@ZAI*D0kkeIzp z60@g8V)n60%pP`$+1n{GZ*YOV18#}gS0=@PQ;C6H@0h1XiupiN%mbEUz%9Tw;8M(2 zCw0jTQkR!W>hiQmU0{~D%fl{pc{`=94Q{E+R{{2_tH7>x4cMm+$z&d|Oy-TsWE*gq z%-0~(d6{H7Pm4_FW0mPV>@uCVQ>NSCmg#&IU>~{)>`2#uJ?O9p1m65Z8*mTE*Wh9G zGI>}%Egn`MyNA`=>0#aA_OSXY{`R|JPn9?7soH>hs(cN9JKlCrleg2;w88CZ@>Og= zfwPGEz<+z*h7C?H%Lb>9{eL`fg%9kd@W#Cqz7{WokKN1Q?e;SGYP@0K55mCrw)?of z?Y_8=26%oJ;C=J>@@sn)w(^zW-Hqy+_k9$+xj72{-&OLp;0+E894!>MSr~YSg99&1 z2b^yM@V!kuE#C~@w)4TCCztbh zG6j#f?tKeN*1hj_?|a?*UiZG&y>Gc}-TPkmzSq6)b?)!Xe_r30Y zuY2F?-uJrqz3zRld*AEccbggP?zXIZ-|OD@y7#^AeJ9)2z3+AJd)@n9_rBM??{)8c z-TPkmzSq6)b?623(-e$gW!2XdZVBp1jf za=u(F7s{o2o?fH}TQ&52y;v{QOSL>L*tDUQX!%;PR;ZQQcs7v@Y}2suZDO0yCROv) zBDFv*QS;SeHQ1zK=9xuifmveao5g0ZMFZnuB20iuFg^x0YhY3r&n0pRToM=GC3b-= z8Zw?tBooLaGQLbK6UwAIo=&6_=)m>|omeN-Ng*C2f&`ER;zMAgB?PvSSVdNWRbu5^ z#a5wJs^Y0cDuD`YA5n=_LY36SGl@(B6WA=Zhs3Z4Q?u24u6e1%vcR7edx1DHx-kQn#|u|a5%!aP_63t$P%hrxsiSZe3l z!8Q@Q#Ll;a2@-axhNlr}1R5}1LjyL6XrvaNMPw0Jz^A7LYz?u1X&$%;7vK_{kBf03 z4kmQCMQ(vx;^w=-77@2p#1n}`0+B?-7l}nek@N=M4Wb(aH%M;a-ypt0c!RWpS0Snp zR7fiL72*nEh4eV@xahdxxa2thxcIp6xHOIzCyEoqN#gi%;y7WP^Z@UG=z!pWwob7t~AY`Ss#@VZHPu z@1*FY;H2av|D^b&@T4@Emn=#aBukR{$>L;Tvh*?DW1`0dk4YZmKPG-m_?UE>H!YeL zOiQNu)8c92wDcVBoamh3oa7w;ocNsZoHU#lE(#ZfOTzi#;&5TObT4nOXs=+eWG{cO zc&~7;w3pW_>J{`#dilNLUSY5FH1D+NwBWSlH2<{twD7dFfL9)=iV?&}V)!xQ7-5WbKX1QizhJ*)KYzb?zi_{Fh&Ln}5)4U(_(S3$;gIx8-j|{; z1z$?Odq)XEI>Ed)@y7Xz@)1s#ZPfMQWKP`S* z__TC^w;);&EJzmk3*rUgg7jzJ&!V3NKTCe*|1ADl__NfL=PB|OcuG9^o?=g-r*u1S zyJ)*$yJS0myLh{ByR?>9E2eMlaN)jYV zlK4sDBw>>D5#A%BM+A>Z9^pSCenj|)bdonIniNb*Ci#=%N#UgQJKlGq?*!jTzTS z-p8Vk1s_X3=6@{ySopCtkC!LP6XZ$q_<7%CFRKk;pBm#*2` zNqCdAidQA75>!d5_*LR6VU_fC-s_^*1+Pn9=f5s~UHG~*o)<5Q7sN~A`SId-VZ8Jq z-b12?1P@6b;y)yQNcfO+j5j746O2j5_+#QR;h6L+@2u#o;H=~<|E&0|@T@e57bFT2 z1WAJULE<1`kn}FzU81`LcS-Kz-zC0Fc$c(;*CFZl0BbcMGfS`n;BR`@I872%5X zBJZN;qTr(BBLAZJqVS^Bhvy^m5%@@a_&#DEp^tPYZ>MOdV5ej!f2Vk-aHq79*C=Wf zG)fxzjp9aOqx5aw+oHDxZ%f|hzb$@S__j2amnupXq)Jlxsp3>&s`Lro6QU;sPe`8N zKOufX_=I$pH!GSI%t~hYv*KCdtn@tZyy(2(yyQIpy!gEEyfl&*DT)+CN+S7@;z(hn zbRTb@XrEx8WFLQ@c%N{ew4c{6>KF7&`uY9heqq1#Gu~&S&jg=IKI4BT{!I9pw1`(E zDiRb)iugt1B4LsA2=9pKh~S9i2>*!qi13J%<*_1Gz)Dy?D`thP^e^6DqQ3-xN&e#h zCH_nJmlQ0Y=KPs7s-G~dI+in+b}wAPR^~3wY?}_6dUm20^%_4udc#QlaQM(Kh;886 zeq-P5y}F(oyLDZ9cweWv!`gnPP29G*wY}x~=0nzuFh5)TZ`Ac z3#C9is(+|zuCi1{SN@~oa`|-m=Vk3>CrhhJkCl{^6uX3+a><{`{U(jteSbfZ_@`l2 zHQ`upXwO`#%iq0FviAy>##@=YXvo($ zj1>J^KitHI4-FRlf;@BHHgIF-v;E)a8~gq_e0%R%gRZCBbYu7Dh^}k#4n3^!-`8n5 zXztk1WNqL2!kM6{Pfa> zrGdpK7cR}0&R>tcGWW-B&DQLMGDDs`1XT;nC@l`QiDYxj_`^AJFy} z^(FSodw%Kq05*4S??Bo!+61j{H{Y%8Z;EdGqJCc;TCEtr#tm z7Cx9?l4sY<<%qKH%8bu=Hmy{BGPOPB^ya~&uT|p-&Q0TSU&jnapN{H?d?&m*?4^(l zg()a3aHl`tZ$bW*PpkK<8!|li%j8l{{DZJZ@NeD~?tjl;+*8jKm%vZ! zcMvzoZy*=BUqLQ#zkvMA{RDoJF78L}Jof{44&;08JMLS~$$i6}<-X?5a9?p>f}ga5 z`<(lfJI#H~|=5}#o|^MIEur$6>f=}=jON>ZjwW}QEr$+xPGpO>*6}NHm;d#;_A5?u9~ahO1WaL zfXn5wxlAsNOXW6mDsB@O%PF}CE|d%A0=SKw54VAnaUzb-{l)&ly4hdZpV;&4_pFmW z!+ybj#(vEHhy8%Hv2U^eW?yGtWnX4rWG(DL_9^yp_7V0Wc0YSRdoO!8yPMUsJ6Iii z1A86Iumroz&a*S@1Ut$OvVCk9+s-z#4Qvft$(FK(Y%ZJ0s@Y^##m2EwY#1BN`msK& zC-{KjvzHk+^9%DM^Br@R`GWbBu`?eq?=UBr*O^zC!;FP_hIxW{n0b&fGWRlfF}E{2 zn46hx49gJA5;Mn4GNTN_bTjRYmZ@W^m{O*I$!5}+WF~=$X2O|ZW+UUpNEtqJnZ8K> zM4zM2(qGV@&>zw^`UL$N{WASLeUN^FHqj5z_tAILx6?c5o9L}HNiWf}^aMRj_tBkn zGhIhl(#3Qxok6G2@wAc-r2}XmS_TeDe^9?tKT=NWOX@WBA@vURZ|WFzn0l6ak}^^I zse7qAshyOLx{e~LC2EEmrx2=(YN6_>N~(y;q0*=%DwYbT0x2I#O7W=Q$)CyZ$us1q z6Jp{|{8#)Oeg;2{e}KPierFR$p1QtUkH=(CU4wyH{^r-L^`sVyok; z{j2S(^{eHpd8=uw39FH-fvaAt!qwkbTr1zKe7f?%%9|^%tXNi_TzPP1@5-)~TUNN0 zm6hq0;gzlx?Ml^3!AizT;!4y?(25uMqW*pP$K|h=KUscv*}8mW`QY*+%f{uqmUk>~ zTgI1Xmq(Vnm$l1P%LU8n%c|wb<$z_647D~($1wD zmWZXfrIDrXrKY9IrMxBe(x#=bB{{eX{ITd-JiGYGqHXc@#TOUNiw`c|yQp8hagkh{ zTO3*JT5MXZSj=5aU5s5+EP5{r7JpkfxA4WnhYKebUS2r3@bJREg*z5*UZ5A|7seL4 z7n&9-7BmYf3o#2p3mX=$%wL%QcK*}(_vT-pe{ufF`3L3=^E>9Rn_r%vnD3u&nXj79 zpWiYcJ0CpnHP4&BfH|?#*t^(k*z?%q*gvs5v0E?(o5x16F0277#j>zOECQ2*E3A9& z+?-?X{kb>hUYvV!ZvWg}bKB>bx%s)#Ie4yqu6QnEE@3Wo&S#E4_v@^4_VnyKv&Uu+ z%|1N4cUC`p{p`x@PN)lR1+x6FTEHb7lJH>942l(^Xt?%Qy)#8oH{b~)YJo0cTMT0$f=pBfvM)HimB`=)l}$|_tcfipC-SW{BY7b z`NHI5llvz1liMbjCdVe>$=b<+$<#^Zq#rmeUz~7Gd_3{y#7h%TPW*G?j)@y5RwmGi z?uojI!ig;t(Gz|XqKRM8Z_tm>6X;>|arAyvk8VR3(NVMmh0t7dGa8P1qgTdV<6n%w zKYo1t+3|{ zv8J(-v9z(6F@JDey)gRq=&8{+MxPrsjovf5eUu!X8tomeA1xeB8I2tE9lbK*8gY!g zJMzlN(vM3|odx!-iqqFg`pn+%;S? zoI9L295U=N{QJ;%Lmv;F7!4-O zG{JUn0+xOrf8U~Hg$pkg3%Aa=lSfIr~s|GfX5{v-X5_wVh$wV&*t=!g5O z`?LEu^#}9|`+x5HqR-a%a^K^9d;4zfBl{-$;J&K9tiHHD|2}@7tM~KXw|fuwKH9sd zSJ%7RJJ#FQTi%=2tL*jZ{j=x$o{xL1JDrdthT59i3fdCeg4%>_uGUXmPqaSQdZ6|8 zRhC;O>d2A^=fsueBJV1%gZf~wcOKkW6MIzKudj#re#x$U(1!|@0;z-uQfl_ zys!Dz=GEqrW^Hp}b5e6qv#|L`?P;x5`>gh#+MQZbJFacj7HgBW3awcCQ`4tSCz=j5 z?QgoRiE0{eYHKQKN^Vj#iJN|E{Iv1kjfWcdH|}gC8^;=38jBi}8iN~!jXySg((p#Z zGY$7Q+}g0(Fx=48kl&Ed;NNhi{`>k<^~dU;sNYk6Q~g4He|=4TR(*86cm3~mXXf5Tx>e1@v>VoQoYQO3~tDIHuR~@N(xN3J5S2bDHUR6@HxhklNUv;kXKb6NSAFni2 zUSBy|*;QFlnOYfADXRRj;^T_fDxR#^Q*mPjR?%HiS)r~7s}NVX%0DT8t=wFGZ~2Yo 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